Jump to content

Custom image upload broken after upgrade to 2.5.3


chrizz
 Share

Recommended Posts

hi folks!

I just upgraded my DEV environment to PW 2.5.3 and tested if everything will work. Unfortunately my custom image upload in the admin interface is broken. It keeps telling me that the image is invalid.

As far as it worked with 2.4 I think it is a problem with the new version unless I haven't changed any code.

following situation / workflow

1) Upload an image to a temporary destination (because the image has to be modified before finally added to a page)

2) Process inputform with the "regular" processInput method. Here the error is thrown

3) Make some custom stuff (e.g. image transformation, changing page title)

4) add image from temporary path directly to the page

 I checked what has changed in the InputfieldImage.module and I found these lines (see at Github: https://github.com/ryancramerdesign/ProcessWire/commit/aa58e7b6d8e6c78d76a2efff4bd9e020682d8115)

if(!$pagefile->width) { 
$pagefile->unlink();
throw new WireException($this->_('Invalid image')); 
}

If I dump the pagefile object I see that it contains data about the uploaded image (e.g. basename) but no width. 

Unfortunately I have no idea why the pageimage does not contain the width at all. I can't even find where the width is set... :(

I hope someone has an idea.

Thanks in advance!

// EDIT

if I comment out the above mentioned lines it works perfectly as expected. But I am still searching for the best approach ;)

Link to comment
Share on other sites

Take a look at: https://github.com/ryancramerdesign/ProcessWire/blob/7b9730d43e6eda8bd27841a4811a1b9737bfe903/wire/core/Pageimage.php#L152

That is where the image dimensions are coming from. It is using the standard php getimagesize function. Unless you are uploading an SVG without width/height attributes, it should work fine if it is a legitimate image. I am actually just putting together a PR for sorting out the SVG image width issue and will send to Ryan tomorrow.

Can you try inserting a debug statement in the getImageInfo function to check the filename it is working with is correct and to see whether $this->imageInfo is getting populated at this point.

Also, can you explain your custom image upload - can you show us the code you have for it?

Link to comment
Share on other sites

thanks for the hint. It seems as if getImageInfo() never gets called. Even a "die()" never gets executed. :(

Here is the code I am currently using:

buildForm()
{
$obj_form = $this->modules->get("InputfieldForm");$obj_form->method = 'post';
$obj_form->action = './';

[...]
$obj_field = $this->modules->get('InputfieldImage');
        $obj_field->label = 'Upload Image (JPEG)';
        $obj_field->attr('id+name','ImageUploadJPEG');
$obj_field->required = 1;
        $obj_field->destinationPath = $this->config->paths->galleryTemp;
        $obj_field->maxFiles = 1;
        $obj_field->extensions = 'JPG JPEG';
        $obj_form->append($obj_field); 
[...]
return $obj_form;
}

if the form is send, this method is called:

processInput(Inputfield $obj_form)
{
$obj_form->processInput($this->input->post);

[...]
}

in the processInput method of the form object ___fileAdded() is called somewhere and that's where the exception came from (see Github link above).

Perhaps the image is accidentally treated as a file instead of an image? But why a method in the InputfieldImage.module is called then?

Link to comment
Share on other sites

Thanks for the code. Have you tried logging:

$pagefile->url

just before the 

if(!$pagefile->width) { 

just so you can know for certain what file it getting to that point.

I am also wondering about this custom upload form - what does it actually do when the image is uploaded? Seems to me that it might be easier to hook into fileAdded (or similar) and make the changes that way, rather than replace the upload form entirely.

Link to comment
Share on other sites

echo $pagefile->url 

prints the following

/site/assets/files/1046/nach-oben-1265-20.jpg

The directory exists but there is no image in it since it is uploaded to the temporary directory (where the image is available). The page with ID 1046 is my custom upload "add gallerypage" which is within the admin section. It seems as if PW tries to upload the picture into the wrong directory or even checks it in the wrong directory and ignores the given destination path.

$obj_field->destinationPath = $this->config->paths->galleryTemp;

The custom upload does a lot ;) I hope I can explain it in a few words:

After uploading and creating a new temporary page the page gets automatically renamed to the uploaded image title via its ITPC meta data. The uploaded image also gets transformed. This means that the script precaches different sizes of the image, copies the original image into a separate directory, creates an htaccess file in the /site/assets/files/#id#/ folder to refer to the original image (rel=canonical). Afterwards some fields of the gallery page were filled with ITPC data as well (e.g. creation date, description, ...).

Actually it was my first site I created with PW and I think that there are a lot of different approaches but I have tried to save as many time as I can when I upload images with ITPC data. I don't have to enter a page name, and this kind of data - it just uploading an image and my custom form do the rest. I only have to publish it afterwards. 

Link to comment
Share on other sites

That all sounds very cool, but I think you might avoid future issues with code changes by creating a module that hooks into the standard PW upload process, rather than having a custom upload form. Sorry, I don't have much time right now to investigate why the width is not being captured for your custom upload.

Pagefile::install or InputfieldFile::processInputAddFile might be appropriate methods to hook.

Link to comment
Share on other sites

  • 2 weeks later...

hm I am not sure if hooking is appropriate here. I saw a lot of questions around an upload form via API, so I though it would be a good way to realize a page within the admin section which does all that stuff instead of the regular /page/add/ plus hooks

Nevertheless: I just found a workaround for my problem. If I use 

$obj_field = $this->modules->get('InputfieldFile');

instead of 

$obj_field = $this->modules->get('InputfieldImage');

it'll work. I am sure that this is not the best solution so far, but I'm giving it up finding another solution. I have read a lot about custom upload forms via the API but they are all older than the last update of PW. 

I think here is an issue when calling the image info. If I am using "InputfieldImage" a Pagefile object is passed to "InputfieldImage.module" to this method

protected function ___fileAdded(Pagefile $pagefile) {

This seems correct so far, but although it is an image it has no width property

var_dump($pagefile->width);

returns NULL

Thanks anyway to Adrian for the support!

Link to comment
Share on other sites

  • 1 month later...

Any solution to fix the wrong page id / upload path described by chrizz?

Replaced InputfieldImage with InputfieldFile to get around the first problem, but after file uploaded (correct to temp directory) during form process the uploaded image is assumed in the current page directory...

Warning: filemtime(): stat failed for /volume1/web/pw/site/assets/files/1023/2015-02-07-16.jpg in /volume1/web/pw/wire/core/Pagefile.php on line 311 title

File uploaded to the correct location...

/volume1/web/pw/site/assets/files/.temp/2015-02-07-16.jpg
Link to comment
Share on other sites

Any solution to fix the wrong page id / upload path described by chrizz?

Looks like chrizz has disappeared from this topic - we PM'd a bit about it and I implemented a fix for his problem, but never heard back.

All that is needed is to add the following:

// make sure the value is of type Pageimages
$obj_field->attr("value", new Pageimages($this->page));

You can thank soma for that fix:

https://github.com/somatonic/ImagesManager/blob/master/ImagesManager.module#L173

Does that take care of your issues too?

  • Like 1
Link to comment
Share on other sites

Hi adrian,

thanks. This solution works with an existing page context ($page->getInputfields() the solution above).

But with an existing page context there is no need for that solution if the form is generated by $page->getInputfields() or $pageField->getInputfield($page).

I build my form from template fields without an existing page (context).

$tplFields = $pages->get('id=1024')->template->fields;

Some fields simply added to the form in context to an unsaved page object (fakePage).

$fakePage = new Page();
$fakePage->template = $template; // Template object fields based from

// InputfieldImage won't work?! So workaround use InputfieldFile...
$img = $modules->get('InputfieldFile');
$img->attr('id+name', 'image');
// image will be uploaded to the given path! Works correct.
$img->destinationPath = "{$config->paths->files}.temp/";
$img->extensions = 'JPG JPEG';

$form->add($img);

// Won't work because isn't an existing / saved page
//$img->attr("value", new Pageimages($fakePage));

Field is added without an error, but after submit form the image is expected in the current page ($page) path instead of defined destinationPath. Sounds like a bug ;)

Warning: filemtime(): stat failed for /volume1/web/pw/site/assets/files/1023/2015-02-07-4.jpg in /volume1/web/pw/wire/core/Pagefile.php on line 311 title

Use an existing page is ok, but I try to create a new page. That's why I upload to a temp dir.

After form submit and validation a page will be created and saved before the file is handled / moved to the correct location.

Form processing fails...

Maybe I have to skip the image field and handle the file upload without WireUpload?

Link to comment
Share on other sites

Why do you need to use a fake page? Why not use an existing one - could be any existing page, or one dedicated for the purpose.

$img = $modules->get('InputfieldImage'); does work if you use $img->attr("value", new Pageimages($this->page));

It would be helpful to see all your code - how are you using WireUpload?

I know you say it works, but I think ->destinationPath should be ->setDestinationPath - at least that is how I have always used it. On that note, I put that as part of the image upload processing, not the upload input field, eg:

// save image to page
//WireUpload stuff
$validExts = array('jpg', 'jpeg');

$imageProcess = new WireUpload("ImageUploadJPEG");//name of image file upload <input>
$imageProcess->setOverwrite(true);//overwrite files
$imageProcess->setMaxFiles(1);//only allow one file!
$imageProcess->setDestinationPath('/temppath/');
$imageProcess->setValidExtensions($validExts);//check for valid file extensions

//upload the image file
$arr_file = $imageProcess->execute();

Does any of that help?

  • Like 1
Link to comment
Share on other sites

setDestinationPath() is used by WireUpload object, but I added it to the form field as destinationPath (as variable. not method) and the upload works. Verified upload via console. Correct file, correct date / time and also correct directory.

ls -lh /volume1/web/pw/site/assets/files/.temp/2015-02-07-20.jpg
-rw-r--r--    1 http     http        2.9M Feb 20 14:29 /volume1/web/pw/site/assets/files/.temp/2015-02-07-20.jpg

So all should be fine, but... 1023 is the current page id and should be replaced with ".temp" as you can see above.

Warning: filemtime(): stat failed for /volume1/web/pw/site/assets/files/1023/2015-02-07-20.jpg in /volume1/web/pw/wire/core/Pagefile.php on line 311

ls -lh /volume1/web/pw/site/assets/files/1023/2015-02-07-20.jpg
ls: /volume1/web/pw/site/assets/files/1023/2015-02-07-20.jpg: No such file or directory

So the best way should be to set the correct path to Pagefile? Searching for that file at my ".temp" and not the current page and all should be fine?

Upload the file to "any page" could / should work, but it feels wrong. Why upload to any page instead a temp folder?

After the form is processed I create and save the needed page. Next step the file from temp folder will be added.

Or I have to create a hidden page to work with that context page if no page exists during upload. Tested with a simple page (template with title field only). Better upload all the files to an hidden "fileUpload" page instead of a random (current) page...

To post the full code I should clean it up first... To much comments, tests ... 

Edited by pwFoo
Link to comment
Share on other sites

Hi Adrian,

thank you for help with that problem. Solved it with the hidden page workaround. Should be fine for me. 

    protected function prepareTypeField($field) {
        if ($field->type == 'FieldtypeImage' || $field->type == 'FieldtypeFile') {
            return $this->prepareFieldTypeFile($field);
        }
        return $field->getInputfield($this->imgRefPage);
    }

    protected function prepareFieldTypeFile($field) {
        $f = $this->modules->get($field->inputfieldClass);
        $f->name = $field->name;
        $f->maxFiles = $field->maxFiles;
        $f->overwrite = $field->overwrite;
        $f->extensions = $field->extensions;
        $f->maxFilesize = $field->maxFilesize;
        $f->destinationPath = "{$this->config->paths->files}{$this->imgRefPage->id}/";
        $f->attr("value", new Pageimages($this->imgRefPage));
        return $f;
    }

Tested with a image field. Upload works without warnings or errors. 

$this->imgRefPage is a simple title only page (hidden).

Link to comment
Share on other sites

  • 3 years later...

I'm getting the same error message as pwFoo above, but I'm using* the regular image-upload in the backend.

Tracy reports:

PHP Warning: filemtime(): stat failed for foo/site/assets/files/1459/__filename___79169f6b6105acbc1299f65e8379b54c54ab3907.titelbild.jpg___description___bildbeschreibung_slide_bild_3___modified__1534175094__created__1518532723__tags_____ in /foo/wire/core/Pagefile.php:521  @  https://dev.foo.com/ 

That filename is weird. Does anyone know what could cause this?

* Actually, the client was uploading files, not me. I just got a notification via email today...

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...