Needs work
Project:
Entity API
Version:
7.x-1.x-dev
Component:
Entity property wrapper
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
24 Mar 2014 at 14:14 UTC
Updated:
21 Dec 2018 at 17:25 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
neograph734Comment #2
dsdeiz commentedWanted to try my hands on this but I'm not sure if I am doing this right. E.g. for the picture, I got this working with:
The getter seems fine although setting it would be like so
$wrapper->picture->set(file_load($fid));. I wonder what might be a better approach.Comment #3
neograph734I guess that would actually be a good way. You can combine that with an upload (file_save_data() ) as well.
Comment #4
neograph734I've patched a simple extension against the user module including picture, password, signature & timezone.
The only thing I'm not sure of is setting the password. It injects the plaintext in the user database, so it doesn't get hashed. Should the module handle that or the implementation of it?
Comment #6
neograph734Added the properties to the callbacks as well.
Comment #7
neograph734Comment #9
dsdeiz commentedFor passwords, I guess you can use
entity_metadata_user_set_properties()and from there you can use,user_hash_password(). Hope that helps.Comment #10
neograph734Thanks dsdeiz, that does indeed seem to work.
I'll manually test all fields to validate they indeed work as expected, but simpletest is still throwing an exception for the picture I don't understand.
I thought the type 'file' would be better then using 'struct' and I was under the impression that file was a valid entity type like node and user. But it is not yet behaving as I expected. Requesting $user->picture->uri->value() for example fails, while $node->author->mail->value() does work. Perhaps any of you has an idea on this?
Comment #12
drunken monkey#2192593: User Picture missing in fields? is older than this issue, but since there's already a patch here I marked it as a duplicate.
Comment #13
neograph734Oke, it took me a while to realise I had to update the test as well. So here it is.
The test kept failing when I attempted to get and set the picture property, but then I found that the node test does not include the author property as well. So I suppose the test is incompatible with the entity metadatawrapper chaining.
The picture property return test is working and it returns a created file, so I guess this is already tested elsewhere. Perhaps someone could confirm this?
I've tested most of the properties successfully. The only thing I'm worried about is when a user picture is uploaded to another folder than the default user pictures folder, it might not pass hook_file_download(). Would it be the responsibility of this module to move the file or should the user do that?
Comment #14
neograph734Comment #15
dsdeiz commentedI think it would be better to just return the hashed password. Same as retrieving it via
$user->pass.I think it's better to follow how core includes
includes/password.inc. See some usage examples in the API.Change is probably unnecessary here if
$wrapper->pass->value()returns the hashed value.Hope this helps!
Comment #16
neograph734You are right. I was under the impression Drupal emptied the password after loading, but it is in the global user object as well so I'll just return the hashed pass (although I don't see a use case for it).
Do you perhaps have an idea on the picture folder as well?
Comment #17
dsdeiz commentedHm, I'm not sure yet. Can you perhaps explain further?
Comment #18
neograph734Yeah sure.
Since the image is a file now, it's access is checked by entity_metadata_file_access(), which in turn calls hook_file_download() to check if the user can access the file. That code looks like this:
So it basically checks if the image is in the user_picture_path (the default location for the user form to upload images). And returns true if the user profile is visbile. However with the patch provided any managed file can be set as a user image which might not even be visible.
Therefor, should I attempt to move the file to the correct folder in entity_metadata_user_set_properties(), should I throw an exception or should I do nothing and leave this responsibility to the person using the wrapper.
Comment #19
neograph734I suppose it would be best to implement a validation callback just like the mail property has. And check if the picture path is valid. Then we should document somewhere that the files have to be like:
public://pictures/picture-<uid>-<timestamp>.<ext>At that same validation we can check if the file is actually an image.
Moving files seems like a bad idea as we would to load the file with file_load(), then move it with file_move and save it again. Where the user might have already have used entity_load or an entity metadata wrapper to attach it to the user, so we would have to clear those caches as well to be sure. Seems like a potential lot of overhead to me.
Comment #20
dsdeiz commentedAh yeah, makes total sense.
I guess that'll work. Marking as "Needs work".
Comment #21
neograph734Thanks for your reply. I forgot to create a local commit last time, so I don't have an interdiff, but the callback is added and the test has been edited a bit.
On my test environment the file move in the following part failed, but that might be due a misconfigured wamp. (Simpletest doesn't work on my server due to a basedir restriction) I can't figure out what goes wrong and the code looks good to me:
Comment #23
neograph734Apparently I needed some extra streamwrapper functions, that I found in the user_save() function. Attached is a working patch and interdiff.
Comment #24
neograph734I recently figured there are still some issues with settings pictues and signatures. I will try to fix this in the upcoming days.
Comment #25
doors commentedI applied the patch in #23 and the author picture field comes up within my Search API view.
The problem is that the field is not being shown in the final website page view. What could be causing this?
Comment #26
neograph734Hi doors,
I've initially written this patch so the fields became available in Entity metatadata Wrappers and RestWS. So I have not tested it with other API's. I'd however expect that it should work. Could you describe a bit more what you are trying to do and with what modules?
have you cleared the caches? Have you enabled the picture field in admin/config/people/accounts ?
Please be as detailed as possible.
Comment #27
doors commentedI am using the Search API and Search API Views modules to create search pages. I have created the indexes within Search API and created the view but when I added the "Indexed Node: Author" relationship (See Image 1) which brings in the Author fields I wasn't seeing the "User:Picture" field in the Fields listing. I applied the patch and the fields come up now (Image 2).
On the page the view is attached the Image filed is still not coming up and you can see from Image 3 that firebug shows the container fields for the Picture Image but iot just does not have the inner image tag leading to the Author's picture image.
I have cleared the cache countless times.
Yes the picture field is enabled as all other views uses this field to show the user image.
Comment #28
doors commented@Neograph734 I just realized something. All the profile images were using the default avatar and not an uploaded avatar from the user. Once I uploaded an avatar to an account that picture cam up but the default images are not shown.
Could you help to rectify why the default image is not showing?
Comment #29
neograph734It was not showing because I have not thought of it. However when you change line 398 in entity/modules/callbacks.inc from
to
it should work.
Comment #30
neograph734Oh wait, probably not. I'll have to write some more code to do that. I'll do some tests and get back to you.
Comment #31
neograph734After looking into this I believe it is not related to this patch.
Drupal generates the picture in template_preprocess_user_picture() and then it displays it in user-picture.tpl.
These templates and processors are only used when displaying either the 'Rendered user', or the 'Rendered user picture'. (The last one in Views is called: 'User: Picture The user's picture, if allowed.' and I expect that one only to be available when a full user object is loaded (Search API loads only a selection of fields)).
What you could do is use Views' no result behavior, and when the user's picture is empty, rewrite the output to
<img src="path/to/default/picture" alt="Default user picture">. You could use some replacement patterns to get the user's name in the alt attribute.Hope this helps.
Comment #32
neograph734Well, I guess I finally have them all working.
The following is now possible:
Comment #33
neograph734Turned out the picture validation was still commented out due debugging. Also fixed some trailing whitespaces.
Comment #34
dsdeiz commentedI haven't totally tested it but probably just a few corrections. :D
Probably just coding standards.
Will try to help the best I can to test it once I get the time. Awesome job btw!
Comment #35
neograph734Thanks for the feedback, however I don't quite get what you mean. The signature as you describe here is like I have it. Or do you want me to remove the password?
Comment #36
dsdeiz commentedOh, my bad. I was in a hurry when I looked at it. It's very minimal :D Anyway probably just braces on the if statements as mentioned here.
Comment #37
neograph734Good point. Since the module is built with ternary operators, I've decided to use those here as well.
Comment #38
neograph734Just found out that my small change from 'pass' to 'password' was causing all passwords to get double hashed, so nobody could log in anymore. So that has been reverted in this patch.
Comment #40
polI'm waiting for this patch too, I need to access default's user profile picture.
Comment #41
neograph734Did you test this and confirm it worked? Then the status of the ticket can be set to 'reviewed and tested by the community' and we might get it in.
Comment #42
polHaven't the chance to test it yet unfortunately.
Reading the patch and tests, it seems to be very good !
Comment #43
tklawsuc commentedI could not get the code in #32 to work. The file gets created and stored in the file_managed table but not in the user's picture. I did some debugging and found that the picture value being passed to user_save in entity_metadata_user_save (callbacks.inc) is the fid instead of the stdClass that is expected. As a result the picture is not set for the user and remains as a temporary file with status 0 in the file_manage table.
The only way I could get this to work is to set the picture value on the user object (loaded with user_load) to the file object and then load the user into the entity_metadata_wrapper, set some other data and save the wrapper.
Comment #44
neograph734You can do it in function entity_metadata_user_save in modules/callbacks.inc
I once had this there, but my project did not require pictures anymore. Guess I rolled the patch from the wrong repository.
I'll reroll a patch including this in a few days.
Comment #45
tklawsuc commentedThanks! I added a check to only load file if picture has a value and it works great.
One note if creating a new user, you will need to save the user object first before you can set the picture. Without this extra step of saving the object, not only was the picture missing but I also got an error when loading the picture in a view:
Notice: Trying to get property of non-object in views_handler_field_user_picture->render()Hope this helps.
Comment #46
neograph734I noticed that earlier, and I suppose it is a flaw in Drupal (you can't set a picture during registratration as well). We could also handle that in entity_metadata_user_save, but I guess it is a bit hackish... It would be user friendly though...
I suppose it would become something like this, but I can't test right now:
Comment #47
neograph734It should be working without the additional save now.
The full example from #32 should be working now.
Comment #48
yesct commentedd.o issue #2516770: REST API is not providing user picture mentions this issue as a possible fix.
Comment #49
edaa commented!count(file_validate_is_image($picture)) === 0 always returns FALSE and !$picture->status == 0 also need to correct, see PHP Operator Precedence.
Changes:
!count(file_validate_is_image($picture)) === 0 --> count(file_validate_is_image($picture))
!$picture->status == 0 --> $picture->status != 0
Comment #53
neograph734Thanks for taking the time to correct some issues edwardaa. The patch attached to #47 was my latest attempt and that seems to be working (though our suggestions could improve it).
Did you create your patch based on that one?
Comment #56
edaa commentedSame as #49, but add some changes with entity.test:
1. Move created image file to user picture directory (e.g., public://pictures/...)
2. Return an image file for user picture when call createValue() in testCRUDfunctions() method
Comment #57
neograph734If I am not mistaken, the user_save function already moved the image to public://pictures (and renamed them if they existed). This was the reason for me to keep the pictures in temp and let user_save handle the rest, so the pictures folder won't contain two duplicates of every file.
In my opinion the tests should follow this behavior. But you might want to check above, as it has been a while sinds I worked on this.
Comment #58
edaa commentedsorry, it's my mistake, new patch rolled back user picture.
Comment #59
edaa commentedCheck picture before saving, now following example works:
Comment #60
edaa commentedRefine #59 code to avoid potential 'Undefined variable' notice.
Comment #61
neograph734Great, it would be nice to hear something from the maintainer(s) about wheter or not they would want to commit this.
Comment #62
heylookalive commented+1 on needing this!
Comment #63
drunken monkeyIf the code works for you and also looks fine, please set the status to "Reviewed & tested by the community". That greatly increases the chances a module maintainer will look at it.
Comment #64
heylookalive commentedK.
Comment #65
annya commented#60 works great! Thanks!
Comment #66
ifrik#60 works for me as well.
Comment #67
edaa commentedFix typo: change 'password' to 'pass'.
Comment #68
edaa commentedComment #69
edaa commentedComment #70
heylookalive commentedAny chance of committing this? :)
Comment #71
NerOcrO commentedHi guys,
I added a new field: init.
Comment #73
Anonymous (not verified) commented2224645-71-missing_user_properties.patch applies cleanly, does what it says, & rectifies the problem of the missing User entity property info. RTBC. It would be great to have this committed.
Comment #74
socialnicheguru commentedon admin/people
selected 'changed value'
got a WSOD
Call to undefined function entity_property_timezone_options() in modules/all/views_bulk_operations/actions/modify.action.inc on line 206
Where is 'entity_property_timezone_options' function defined?
Comment #75
dawehnerI think we should leave out the password from this issue. Passwords have to be handled with extra care, given it could be exposed via restWS and what not.
All the other information are not sensitive and conceptually less tricky to implement in the first place (the password has to be hashed for example before saving).
For the password case we should research how D8 solved it exactly and do some kind of parallel implementation of that, if possible.
Comment #76
markhalliwellAgreed. Password should be handled separately and tested thoroughly (regardless that there is existing tests).
@drumm also voiced this concern #2516770-2: REST API is not providing user picture and I'd rather d.o not be blocked by this issue.
Comment #77
markhalliwellComment #78
Anonymous (not verified) commentedWhy not also?:
Comment #79
aron novakIt might happen that for picture, the file Id is numeric, but not int, see https://pasteboard.co/GOA8Vqp.png from a debugging session.
I went ahead and updated https://www.drupal.org/files/issues/2224645-67-missing_user_properties.p... (not https://www.drupal.org/files/issues/2224645-71-missing_user_properties.p..., it seems init is not wanted).
Comment #80
lunatic commentedextending the last patch it seems only logical that integers should be accepted for picture property in the validate function
something like:
updated patch attached
Comment #81
naidim commentedSorry, wrong thread.