Robin S Posted January 10, 2016 Share Posted January 10, 2016 I'm working on a simple fieldtype module and trying to understand the wakeupValue, sleepValue and sanitizeValue methods a bit better. This and this have been helpful but I still have a few questions. My module is for storing a reference to an image that is contained in one of the image fields in a page. I'm using a customised select inputfield to choose from the available images, and the reference to the image is stored in the database as a string in the form: field_name|image_name In the wakeupValue method I convert the reference string to an image object. public function ___wakeupValue(Page $page, Field $field, $value) { list($field_name, $image_name) = explode("|", $value); $image = $page->$field_name->get("name=$image_name"); return $image; } This is working fine, but at the moment I'm not doing anything in the sanitizeValue method. To get an idea of when sanitizeValue is called I have this... public function sanitizeValue(Page $page, Field $field, $value) { $type = gettype($value); $log = wire("log"); $log->save("debug", "Sanitized: $value, Type: $type"); return $value; } ...and it shows that for every Edit Page save in admin the sanitizeValue method receives both the image reference string and the image object. Sanitized: photoxpress_8083749.jpg, Type: object Sanitized: images_two|photoxpress_8083749.jpg, Type: string Why does sanitizeValue get both these types? I can understand why the image object goes through sanitizeValue because I am setting that to the page, but why does the string go through sanitizeValue? I'm not setting the string to the page, just saving it to the database. For modules like this that store data in a different type than they send to the page, will the sanitizeValue method always need to account for both variable types? That is, the method can't expect $value to always be a string or always an object - it will need to test the type of $value and apply different sanitizing checks accordingly? And is this true for sleepValue also? Ryan said in another post: sleepValue() does the opposite of wakeupValue() and translates a runtime value back to it's basic type for storage. That makes sense if I was saving to my field via the API and set an image object to the field - sleepValue needs to convert the object to a reference string for storage in the database. But at the moment I'm only saving to the field via the admin, and so the $value received by sleepValue is a string coming from the inputfield, not an object. So to cover both bases I will need to test for the type of $value at the start of the sleepValue method? I guess I'm asking if this is the normal/right way for such a module to work or if there is some better way to set it up so that sanitizeValue and sleepValue only have to handle one variable type. 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted January 10, 2016 Share Posted January 10, 2016 Isn't the string you're seeing in the log from your inputfield, which you said to be setting a string currently? Probably the sane way to handling the data would be that the runtime value is always the image obj. The sanitizeValue method will make sure any other valid (user) input, like the db string format, is converted to the runtime obj. sleepValue und wakeupValue will only handle the string to runtime obj conversion for both directions. 2 Link to comment Share on other sites More sharing options...
kixe Posted January 10, 2016 Share Posted January 10, 2016 @Cerulanyou could use http://modules.processwire.com/modules/fieldtype-select-ext-option/ which offers exactly what you want. No need to create a new module for this. 1 Link to comment Share on other sites More sharing options...
Robin S Posted January 10, 2016 Author Share Posted January 10, 2016 Probably the sane way to handling the data would be that the runtime value is always the image obj. The sanitizeValue method will make sure any other valid (user) input, like the db string format, is converted to the runtime obj. sleepValue und wakeupValue will only handle the string to runtime obj conversion for both directions. Thanks, I've taken that advice and everything works great. Sanitizing to an image object means I avoid having to check for object vs. string in the sleepValue method. For novice developers like myself I think it's a bit hard to grasp the sanitizeValue method because it's not obvious where the method is called. With some debugging it looks to me like sanitizeValue is called twice, with the flow being: inputfield > sanitizeValue > sleepValue > database and database > wakeupValue > sanitizeValue > page Is that correct? It's the first call that puzzles me a bit because the comment in Fieldtype.php for sanitizeValue says: * Sanitize the value for runtime storage. * * This method should remove anything that's invalid from the given value. If it can't be sanitized, it should be blanked. * This method filters every value set to a Page instance. And I can't see where the "Page instance" comes into inputfield > sanitizeValue > sleepValue > database @kixe Thanks for directing me to your module - I haven't tried it before and it looks like it's very flexible. It's not quite suitable for my purposes for a few reasons: I want my select dropdown to include the images from all the image fields assigned to the template. Because each image field is a separate table in the database I don't think Fieldtype Select External Option will allow this. I want to customise the select inputfield so it shows a thumbnail of the selected image (so it's easier for the user to select the image they want). I'm doing this by setting a thumbnail data attribute for each option in the options array. So my module needs to be something specific to images rather than Fieldtype Select External Option which has a broader application. When used for image fields, it seems that the value saved by Fieldtype Select External Option is quite fragile. Because the option value has to be an integer you have to use the Sort column for the value. This means that if the images are reordered in the image field the image referenced by Fieldtype Select External Option is changed. For an image reference you really want the image name to be the value that is stored. Also, I got some errors when attempting to install Fieldtype Select External Option. They are caused by the strings that are marked as translatable. I think lines like... $f->label = _('Usage'); ...need to be... $f->label = $this->_('Usage'); 1 Link to comment Share on other sites More sharing options...
LostKobrakai Posted January 10, 2016 Share Posted January 10, 2016 Yeah the whole wakeup/sleepValue topic is a bit hidden in the code. Here's wakeupValue https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/core/Page.php#L605 and here's sleepValue (kinda) https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/core/Pages.php#L1252. And sanitizeValue is always called when a value is set to the field, so it's also called when your inputfield's data are set to the field when saving the page. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now