olafgleba Posted April 1, 2022 Share Posted April 1, 2022 Hi, depending on the status of a set checkbox (set_create_vcard) i generate VCF files on page save (admin). For this i have a hook (s. below) placed in admin.php. Everything behaves like it should. But when i try to integrate a image in the vcard i get the following message/error on page save (Returned data is not a image comes from the exception class of the VCard lib). ProcessPageEdit: Returned data is not an image. I am asking this question here in the PW Forum (and not on the github board of the lib), because integrating the (essentially) similiar code in a regular template file (e.g. outside the hook) works flawlessly (with the same images accepted, e.g do not trigger any error). I am rather a newbie when it comes to hooks. So its likely that i miss something. Any hints much appreciated, Olaf <?php // file: admin.php // get vcard lib (composer module) on top use JeroenDesloovere\VCard\VCard; /** * Admin template just loads the admin application controller, * and admin is just an application built on top of ProcessWire. * * This demonstrates how you can use ProcessWire as a front-end * to another application. * * Feel free to hook admin-specific functionality from this file, * but remember to leave the require() statement below at the end. * */ $wire->addHookBefore('Pages::saveReady', function($event){ $page = $event->arguments(0); if($page->hasField("set_create_vcard")) { if($page->set_create_vcard == 1) { $page->set_create_vcard = 0; // define vcard $vcard = new VCard(); // define variables $fullname = $page->combo_contact->name; // add personal data $vcard->addName($fullname); /* ... some other allocations ... */ // WHERE IT BREAKS... if($page->image_contact) { $vcard->addPhoto($page->image_contact->filename); } $vcard->setSavePath($this->wire('config')->paths->root.'process/public/vcard'); $vcard->save(); $this->message('VCF Datei für den Kontakt wurde erstellt'); } } }); // Do not touch... require($config->paths->adminTemplates . 'controller.php'); 1 Link to comment Share on other sites More sharing options...
horst Posted April 1, 2022 Share Posted April 1, 2022 I believe you are using a single images field, means the allowed amount of stored image is set to 1. If that is true, the scope where you calling it is important. Behind the scenes a single image field and a multiple images field are the same, they only behave different in template scope, where output formatting is set to true by default. For single image fields this reduces the code a bit so that you already act with a single image right after the field name. So in a function or method scope, this is not (cannot be) auto set to true, and your image field returns a collection from which you have to select the first item: $page->image_contact->first() So a working code then can be: if(0 < count($page->image_contact)) { $vcard->addPhoto($page->image_contact->first()->filename); } 3 Link to comment Share on other sites More sharing options...
bernhard Posted April 1, 2022 Share Posted April 1, 2022 And if you want to make things a little more obvious to anybody reading your code (or simply to yourself) you can use getUnformatted() to return the array version of the field no matter what the current outputformatting is: <?php $images = $page->getUnformatted('imagesfield'); if($images->count()) { $img = $images->first(); ... } 2 Link to comment Share on other sites More sharing options...
horst Posted April 1, 2022 Share Posted April 1, 2022 6 minutes ago, bernhard said: getUnformatted() Ha, that's what I use only and everywhere since a couple of years already. Because the code then is bulletproof, even if sometimes in the future a single image field need to be changed to a multiple one or vise versa. No changes in code are needed. First I thought to mention that too, but decided that it may be not close enough to the topic. So good that you brought it up! ? 1 Link to comment Share on other sites More sharing options...
Robin S Posted April 2, 2022 Share Posted April 2, 2022 1 hour ago, bernhard said: And if you want to make things a little more obvious to anybody reading your code (or simply to yourself) you can use getUnformatted() to return the array version of the field no matter what the current outputformatting is True, but just want to point out there can be occasional "gotchas" when doing this because PW sometimes returns things that may be unexpected in the unformatted value. For example, the unformatted value of a Page Reference field will include unpublished pages and the unformatted value of a Repeater field can include "ready" items that are not populated in Page Edit. And in the case being discussed here the unformatted value of an images field can include "temporary" images that have been uploaded in Page Edit but the page has not yet been saved. So in the example below the frog image is saved but the fish image has just been uploaded but not yet saved, and might yet be abandoned before saving because of being a mistake or unwanted. Yet it appears in the unformatted value: 3 1 Link to comment Share on other sites More sharing options...
horst Posted April 2, 2022 Share Posted April 2, 2022 7 minutes ago, Robin S said: And in the case being discussed here the unformatted value of an images field can include "temporary" images that have been uploaded in Page Edit but the page has not yet been saved. So in the example below the frog image is saved but the fish image has just been uploaded but not yet saved, and might yet be abandoned before saving because of being a mistake or unwanted. Yet it appears in the unformatted value: Very interesting details, that I haven't known. So my use cases for getUnformatted("imagesField") is in template / frontend context only. I haven't had a need to use this in the admin, but definitely will note that down for when this use case may arise. Link to comment Share on other sites More sharing options...
Robin S Posted April 2, 2022 Share Posted April 2, 2022 6 minutes ago, horst said: I haven't had a need to use this in the admin, but definitely will note that down for when this use case may arise. It's not different between frontend and admin - I just used that in my screenshot to show the as-yet-unsaved image. So you do have to watch out for it in template code too. Suppose you have a busy site and you're using getUnformatted() in your template code. If a website editor accidentally uploads the wrong image (you can imagine some worst-case scenarios here!) but then notices before they save the page, that temporary image might have already been displayed and viewed on the frontend via getUnformatted(). 3 Link to comment Share on other sites More sharing options...
horst Posted April 2, 2022 Share Posted April 2, 2022 Ok, I see. But I also every time use ProCache(d) sites and the authors do know that they can edit a page without changes on the front end as long as they do not save it. But I see, it isn't that "bullet-proof" I thought it is, (in the front end too). Thanks for pointing that out! 1 Link to comment Share on other sites More sharing options...
olafgleba Posted April 2, 2022 Author Share Posted April 2, 2022 10 hours ago, horst said: I believe you are using a single images field, means the allowed amount of stored image is set to 1. If that is true, the scope where you calling it is important. [...] @horst Your assumptions were all right. Argh, it happened quite more than once that i simply forgot about that. Thank you very much for your brief and clear explanation. @bernhard @Robin S Big thanks also for your advice and details. 3 Link to comment Share on other sites More sharing options...
bernhard Posted April 2, 2022 Share Posted April 2, 2022 Thx @Robin S I definitely didn't have that on my radar! Do you have a suggestion what to use if I just want to make sure to get the images' field data as array independently from the template context but not showing temporary or unpublished items? Link to comment Share on other sites More sharing options...
horst Posted April 2, 2022 Share Posted April 2, 2022 @bernhard At first glance this can work, but I need to do some thorough tests against different cases/situations/states a page and images can have. It's just the first shot that came to my mind: $page->getUnformatted('images')->find("created<{$page->modified}") 1 Link to comment Share on other sites More sharing options...
Robin S Posted April 2, 2022 Share Posted April 2, 2022 11 hours ago, bernhard said: Do you have a suggestion what to use if I just want to make sure to get the images' field data as array independently from the template context but not showing temporary or unpublished items? I think a couple of ways are possible. One is similar to what @horst suggested, but you can use the special created timestamp of 10 to more exactly identify temporary images: $page->getUnformatted('images')->find('created!=10') There are also the public Pagefile::isTemp() and Pagefiles::isTemp() methods that can be used to check if a particular Pagefile/Pageimage is temporary or not. Another way would be to set the outputFormat property of the images field to array before you get the field value so that the value is standardised for single and multiple image fields. $page->getField('image')->outputFormat = FieldtypeFile::outputFormatArray; // Now use $page->image 2 Link to comment Share on other sites More sharing options...
adrian Posted April 3, 2022 Share Posted April 3, 2022 Would $pagefile->isTemp() be of use here?https://github.com/processwire/processwire/blob/06325993851113436b20b375a6b08cbf38230657/wire/core/Pagefile.php#L1330 I use it in CustomUploadNames Link to comment Share on other sites More sharing options...
bernhard Posted September 3, 2022 Share Posted September 3, 2022 Just for reference Ryan was very quick on this one and we now have this selector to force return the array value of an image field: $page->get('image[]') 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