Jump to content
horst

Beta testers wanted: CroppableImage with WebP support

Recommended Posts

Hi all,

I'm searching for Alpha/Beta tester of the new rewritten Croppable Image module. I opened a new repo on Github, with the name CroppableImage4: https://github.com/horst-n/CroppableImage4

It is a rewrite of the CAI3. I dropped all internal image manipulations, to be more future safe. Now I delegate all this to the parent core image fields methods. To be able to do this, I need to change some things and the module is no longer backwards compatible.

A) For the alpha & beta testing, there is a new crop method name: $image->getCrop4(), this may be changed later to the legacy $image->getCrop() method. But for the testing period to avoid conflicts with CAI3, it is named getCrop4().  <- OBSOLETE, see the next post here in thread

B) With the first param, you pass the cropname into the method. Optionally you can pass image processing options as a second param, like with the core image field. To do this, you may use an array or a selector string.

C) You can use every known options param. Width, Height, Size is ignored! If you also want create WebPs in one go, please add "webpAdd" => true to the options array, (or webpAdd=1 to the options selector string)!

D) The resulting image variation names will differ from those of the previous version 3!

Please refer to the readme of the repo and, maybe compare it against the version 3, if you not already know it.

Thats it so far. I have tested it a bit in the last days and haven't found any issues. But it would be nice if some of you can test it too.

 

  • Like 8

Share this post


Link to post
Share on other sites

Hey,
I've made good progress. I think I have solved the issue for updating / changing from CAI3 to CAI4! 🙂

- So, if you want to use a CroppableImage field for a fresh new site, simply go directly with CroppableImage4! (once it is officially released)

- And if you have the CroppableImage3 on an existing site, but want to upgrade to CroppableImage4, (because you need WebP support), follow these easy steps:

  • First update CroppableImage3 to the latest version 1.2.0!
     
  • After that, additionally install CroppableImage4.
     
  • Now you can use both modules with the same ->getCrop() method call on pageimages. The getCrop hook "knows" from which field and module version it comes. 🙂
     
  • Therefore, from now on, you are free to start using CAI4 for new created template calls to CAI4 fields, while the older CAI3 calls can stay in and are fully functional without any changes.
     
  • If you want to switch CAI3 fields to CAI4 fields, to benefit from the new functionalities, you can do that in the
    admin > setup > fields > YOURFIELDNAME editor, by changing the (field) type. (see screenshot beneath, & yes, KEEP SETTINGS!)

     
  • The only thing you have to check, before doing that, is: looking into your templates code, if you have made use of the optional second param in the old CAI3 ->getCrop() calls. If no, what I think is 99.9% the case, you have to do nothing. If you make use of it, you need to change / adapt your method call in the template file.
     
  • That's it.
     

Summary:

  1. update CAI3
  2. install CAI4
  3. change the fieldtype(s) from CAI3 to CAI4

 

When I've got some feedback from beta testers (and everything works out as expected) I will release the CAI4 through the modules directory. Until then, you get the RC2 version of it on GitHub: https://github.com/horst-n/CroppableImage4

 

cai3-to-cai4.png.8ff2d58415d6903c04267de787853343.png

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi @horst!

When saving Crop Settings with MAMP i get (square,200,200 for example) .

DB connect error 2006 - MySQL server has gone away

Everything else seems fine when saving.

  • Like 1

Share this post


Link to post
Share on other sites
48 minutes ago, Mats said:

Hi @horst!

When saving Crop Settings with MAMP i get (square,200,200 for example) .


DB connect error 2006 - MySQL server has gone away

Everything else seems fine when saving.

Hey Mats, thanks for testing.

I tested saving of different Crop Settings and also edited and or removed them later without issues. So, cannot reproduce. 

Have you tested it locally or on a online server?

Have you used CAI4 alone, or is CAI3 also installed there when you tested?

You mean, you are not able to store any settings, never? Or occurred the issue occasionally?

Share this post


Link to post
Share on other sites

@Mats, please can you verify that you are using the latest version of CAI3 that is: 1.2.0 ??

If you have used an automated update service, it potentially stuck with version 1.1.18. I now manually updated the record in the modules directory to 1.2.0! 

Share this post


Link to post
Share on other sites

Tested on local installation on MAMP.

No previous CroppableImage module installed.

I get the error only when trying to save with Crop Settings otherwise it saves as expected. 

Downloaded the module here: https://github.com/horst-n/CroppableImage4

 

Share this post


Link to post
Share on other sites

You mean, you cannot save a crop setting, only other field settings? So your cropsettings inputfield stays empty all the time?

Which PW version?

(I will try to reproduce.)

Share this post


Link to post
Share on other sites

Can't save Crop Settings (square,200,200 for example). Other settings saves.

ProcessWire 3.0.152 dev 

Share this post


Link to post
Share on other sites

@Mats I downloaded and installed the latest PW dev version with a blank profile, added the CAI4 module, created a new image filed and saved a crop setting "square,200,200" successfully.

Everything in this regard is working fine here. I can't reproduce!

Also nothing in regard of the cropsettings inputfield and its processing have changed, compared to the other versions that are in use for many years.??

Share this post


Link to post
Share on other sites

Perhaps a MAMP thing then. 

Share this post


Link to post
Share on other sites

Tested on another MAMP installation and it works as expected there. 

  • Like 1

Share this post


Link to post
Share on other sites

My short feedback: I have gradually changed everything from CAI3 to CAI4 2.0.0-RC02 (8 websites). Everything is going well so far.
Strangely enough I sometimes had to click 2x save in  the field settings when switching fields to V4 to avoid error messages there.
And of course the server works hard when recalculating the images.
Otherwise, I didn't notice anything else. The update instructions and the procedure were exemplary.

  • Thanks 1

Share this post


Link to post
Share on other sites
2 hours ago, ceberlin said:

My short feedback: I have gradually changed everything from CAI3 to CAI4 2.0.0-RC02 (8 websites). Everything is going well so far.
Strangely enough I sometimes had to click 2x save in  the field settings when switching fields to V4 to avoid error messages there.
And of course the server works hard when recalculating the images.
Otherwise, I didn't notice anything else. The update instructions and the procedure were exemplary.

@ceberlin Many thanks for testing and providing feedback! 👍

Good to hear that you successfully switched 8 websites from v3 to v4.

Share this post


Link to post
Share on other sites

I have successfully tested at Webfaction hosting, everything is working perfect.

PHP Version 7.4.5

Processwire: 3.0.148

CroppableImage: 2.0.0-RC02 (beta)

I just noticed a bit of slowness when generating the thumbnail before making the crop.

The image was 5.1 mb

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi @horst,

When using this module from the user profile, the InputfieldCroppableImage4.module cannot get the $pages_id, thus trowing an Exception.
With the addition below you can get the $pages_id from the Process running. I did not much testing so I Don't know if it is sufficient.

<?>php

// added at line 129, InputfieldCroppableImage4.module

/** @var integer $pages_id, Page ID for crop links, defaulting to 0 */
$pages_id = 0;
/** @var [ProcessPageEdit|ProcessUser|ProcessProfile] $process, Mixed processes maybee there are more */
$process = $this->wire("process");
if (method_exists($process , "getPage")) {
		$editPage = $process->getPage();
		if ($editPage->id) $pages_id = $editPage->id;
}
$pages_id = $pages_id ? $pages_id : (int) $this->input->get->id;

// And I Changed the of pages_id property of the $cropUrlWithParams to the var $pages_id

Thanks for being so active.

  • Like 1

Share this post


Link to post
Share on other sites
18 minutes ago, Martijn Geerts said:

When using this module from the user profile,

Hi Martijn, thanks for testing!

I think, I haven't tested as simple user. To be honest, I haven't tested much at all. So, "being so active" seems to be relative, depending on POV (point of view). 😉

Is everything ok on your side? The children are growing, (maybe way to fast)? 😊

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Horst,

Time flies, the oldest on secundary school now and the youngest just had her 6th birthday. Live is sweet.
How are you doing?

  • Like 1

Share this post


Link to post
Share on other sites
9 minutes ago, Martijn Geerts said:

Hi Horst,

Time flies, the oldest on secundary school now and the youngest just had her 6th birthday. Live is sweet.
How are you doing?

 Wow, the youngest is already 6. Really, time flies.

For me, most things are fine or ok.

The only annoying thing is that I don't have a good place to work right now. At home there is too much unrest, I don't want to visit the CoWorking place I rented since the end of last year so often. Cafes are closed, you are not allowed to sit in the park. I have no real idea about it. So I sit at home in the hustle and bustle and only get half as much done as usual, which seems to me twice as exhausting. 🙂 (It may also be that I am simply getting older and therefore have a greater wish for quietness.) 😉

 

  • Like 1

Share this post


Link to post
Share on other sites
On 4/21/2020 at 11:29 AM, Martijn Geerts said:

Hi @horst,

When using this module from the user profile, the InputfieldCroppableImage4.module cannot get the $pages_id, thus trowing an Exception.
With the addition below you can get the $pages_id from the Process running. I did not much testing so I Don't know if it is sufficient.


<?>php

// added at line 129, InputfieldCroppableImage4.module

/** @var integer $pages_id, Page ID for crop links, defaulting to 0 */
$pages_id = 0;
/** @var [ProcessPageEdit|ProcessUser|ProcessProfile] $process, Mixed processes maybee there are more */
$process = $this->wire("process");
if (method_exists($process , "getPage")) {
		$editPage = $process->getPage();
		if ($editPage->id) $pages_id = $editPage->id;
}
$pages_id = $pages_id ? $pages_id : (int) $this->input->get->id;

// And I Changed the of pages_id property of the $cropUrlWithParams to the var $pages_id

Thanks for being so active.

Hey Martijn,

I have tested the module with the latest stable, 3.0.148 as blank profile, added the field to it, made a role editor which only gets edit rights and the CAI4 permission. Everything seems to work as expected. I can upload, delete and process crops. When I remove the CAI4 permission from the editor role, I get a modal with a blank admin page and a link to the homepage. But I'm unable to do something that raises an exception or error.

Can you give me some infos about your setup and what you do or have done to run into the issue?

 

Share this post


Link to post
Share on other sites

Hi @horst,

On top of my head:

  1. Add the Croppable image field. (plain install, no update)
  2. Configure the field & attach to user template.
  3. Allow the field in ProcessProfile. (You should configure it in ProcessProfile)
  4. Go to your ProcessProfile and click the thumbnail button you configured.

As you can see in the browser input bar when ProcessProfile is open there is no get parameters present in the URL.
p.s. I'm open for a telephone call :-).... send you a PM with my mobile number.

 

 

  • Like 1

Share this post


Link to post
Share on other sites
5 hours ago, Martijn Geerts said:

attach to user template

Ah!

Share this post


Link to post
Share on other sites

Hi @Martijn Geerts (and others),

I updated the module and fixed the issue in context of the user template you reported. Many thanks!

I then faced an issue with edit permission in context of user template with the process module.

Example use case:

  • Given the case there is a CAI4 field added to the user template
  • A role, (we call it author here), has the permission to work with CAI4 fields: "croppable-image-4"
  • And the author role is allowed to manage the CAI4 image(s) on their own profile page, (besides password and email address or AdminTheme settings)
  • It does NOT have view and edit rights on the user template!

That's how I think it is or should be the common use case.

When I set it up like above, everything is working fine (now), except the CAI4 editor hasn't opened in a modal, but in a new tab.

When I gave view and edit rights for the user template to the author role, it loaded into the modal popup. But that is not what we want to do.

What seemed to be missing was the modal.js. It gets loaded for editpages where a user has regular edit rights via a pages template, but this is not the case when a user has rights to manage some profile properties.

It would be nice if someone can confirm that this is expected behavior and that my approach here (and here) is correct.

 

Updated the module on Github

Share this post


Link to post
Share on other sites
Quote

I then faced an issue with edit permission in context of user template with the process module.

yep I see, looks like PagePermissions::userEditable() returns false.

First of all, I don't see the whole context of the repeater page thing in ProcessCroppableImage4->___execute(), I also think the solution in there doesn't work when you have nested repeaters. In ProcessCroppableImage4->___execute(), you are checking for $page->editable(). In case of the user profile $page === $this->wire('user')

This is what I think:

   
/**
 * Is the Page|Page->field editable?
 *
 * @param integer $pages_id
 * @param string $field
 * @return boolean
 * @throws WireExeption When not ediable
 */
private function isEditable($pages_id = 0, $field = '') {
    $editable = false;
    /** @var Pages $pages */
    $pages = $this->wire("pages");
    /** @var User $user */
    $user = $this->wire("user");
    /** @var User $user */
    $user = $this->wire("user");
    /** @var integer $pages_id, Page Id from page being edited */
    $pages_id = (int) $pages_id;
    /** @var string $field, Croppable image fieldname */
    $field = strval($field);

    if (!$pages_id || !$field) return $editable;

    /** @var Page|NullPage */
    $page = $pages->get($pages_id);

    if ($page instanceof RepeaterPage) {
        while (!($page instanceof RepeaterPage)) {
            $page = $page->getForPage();
        }
    }

    if (!($page instanceof Page)) throw new WireException("Not a valid page");
    if (!$page->id) throw new WireException("Not a valid page");

    // Set Page to WireData
    $this->set("page", $page);

    // Returns false for user template in: PagePermissions::userEditable()
    $editable = $page->editable();
    // We need to check if the field is also editable from Page context.
    if ($editable) $editable = $page->editable($field);
    // When comming from ProcessProfile, the $page === $this->wire('user')
    if (!$editable && $page === $user) {
        // User must have profile `profile-edit` permission
        $editable = $user->hasPermission("profile-edit");
        if ($editable) {
            $pagePermissions = $this->wire("modules")->get("PagePermissions");
            // Is the field actually in the profile?
            $editable = $pagePermissions->userFieldEditable($field, $user);
        }
    }

    return $editable;
}



// 
then in ProcessCroppableImage4::___execute() {
    public function ___execute() {

        //$this->config->scripts->add($this->config->urls->ProcessCroppableImage4 . "scripts/Jcrop/js/jquery.color.0-9-13.js");
        $this->config->scripts->add($this->config->urls->ProcessCroppableImage4 . "scripts/Jcrop/js/jquery.Jcrop.min.0-9-13.js");
        $this->config->styles->add($this->config->urls->ProcessCroppableImage4 . "scripts/Jcrop/css/jquery.Jcrop.min.0-9-13.css");
        $this->config->scripts->add($this->config->urls->ProcessCroppableImage4 . "scripts/ProcessCroppableImage4.js");
        $this->config->styles->add($this->config->urls->ProcessCroppableImage4 . "styles/ProcessCroppableImage4.css");

        $this->wire('processHeadline', 'Croppable Image 4');

        $field = $this->sanitizer->fieldName($this->input->get->field);

        if(preg_match("/_repeater[0-9]+$/", $field)) {
            $pages_id = (int) end((explode("_repeater", $field)));
            $field = str_replace("_repeater$pages_id", "", $field);
        } else {
            $pages_id = (int) $this->input->get->pages_id;
        }

        $filename = $this->sanitizer->name($this->input->get->filename);
        $height = (int) $this->input->get->height;
        $width = (int) $this->input->get->width;
        $suffix = $this->sanitizer->name($this->input->get->suffix);

        if($pages_id < 0 || strlen($filename) < 3) {
            $out = CroppableImage4Helpers::getTemplate("jcrop", array(
                'invalidFieldText' => $this->getText('invalidFieldText')
            ));
            return $out->render();
        }

		$editable = $this->isEditable($pages_id, $field);
		if ($editable) $page = $this->data("page");
		if (!$editable) throw new WireExeption("Page not editable");

......


// In ProcessCroppableImage4::___executeSave() :

    public function ___executeSave() {

        /** Checklist: sanitisation and validation of each post param
        *
        *   [x] - [x] pages_id
        *   [x] - [x] field
        *   [x] - [x] filename
        *   [x] - [x] suffix
        *   [x] - [ ] crop
        *   [x] - [x] targetWidth
        *   [x] - [x] targetHeight
        *   [x] - [x] quality
        *   [x] - [x] sharpening
        */

        // get page-id from post, sanitize, validate page and edit permission
        $pages_id = intval($this->input->post->pages_id);
        // $page = wire('pages')->get($pages_id);
        // if(!$page->id) throw new WireException("Invalid page");
        // $editable = $page instanceof RepeaterPage ? $page->getForPage()->editable() : $page->editable();
        // if(!$editable) throw new WirePermissionException("Not Editable");

        // get fieldname from post, sanitize and validate
        $field = wire('sanitizer')->fieldName($this->input->post->field);

		$editable = $this->editable($pages_id, $field);
		if ($editable) $page = $this->data("page");
		if (!$editable) throw new WireExeption("Page not editable");

.....

 


 

 

 

 

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...