bmcclure / CakePHP-Media-Plugin

A CakePHP (2.0) plugin enabling transfer/manipulation/embedding of files in 23 ways.
Other
60 stars 24 forks source link

issue with generator behavior #63

Closed kinglouie closed 10 years ago

kinglouie commented 10 years ago

What I'm trying to do: I want to create a view where the user can re-crop images handled by the media plugin

Setup: All mediafiles are stored by the Attachment Model which is based of the one shipped with the Mediaplugin. Other Models can use the Attachment Model to store mediafiles.

My Attempt: Step 1 (View/Attachments/admin_edit.ctp): Gather cropdata, data will injected to the form via javascript Step 2 (Controller/AttachmentsController.php)         2.1: Save attachment data         2.2: if attachment data was saved: process cropdata with use of $this->Attachment->makeVersion($file, $instructions);         2.3: redirect to attachments indexview using  $this->redirect(array($admin = true, 'controller' => 'attachments', 'action' => 'index'));

Issue: My general attempt is working, so all images get croped like i want them to but the following redirect isn't fired, instead a weird redirect to current action is executed somewhere. I narrowed it down to the makeVersion() method, when i comment that out, the attachment gets still saved and the redirect is working like it's supposed to.

So it seems that makeVersion() has some weird sideeffect.

Since i get redirected it is really hard to debug because i cannot inspect the request or check for errors. I tried with using debug();exit; to narrow it further down inside of the makeVersion() method but i really don't get this, theres no redirects called anywhere inside.

Code: https://github.com/KingLoui/mediatest/blob/master/app/Controller/AttachmentsController.php

Thanks in advance for your effort! Cheers Matthias

BTW: I altered the crop function from the mediaplugin and added 4 optional parameters so i can crop the images with my data from jcrop, so don't get confused by the functioncall in makeversion. Since there wasn't a suitable cropfunction built in i assume no one ever tried what i do with the plugin??

ndm2 commented 10 years ago

Could you elaborate what exactly a "weird redirect" is? Are you talking about an actual redirect, ie a response with a Location header?

I can't test it right now, so I'm just shooting in the dark here, but could it be that there is actually no redirect happening, ie you are not being redirected so the same action, but you are staying on it?

The most obvious cause for this would be data being sent before your Controller::redirect() call, most of the times this happens it's whitespace before an opening <?php tag.

kinglouie commented 10 years ago

Thanks for your fast response, i will definitly check the whitespace thing.

The redirect is also happening, when i load attachment/admin_edit as an ajax view (e.g. in users/admin_edit) i still get redirected through the ajax response instead of just closing the overlay. the redirect is always to the same page. So i think it's not just staying on the same action.

EDIT: The whitespace thing you explained could only be true if there is no redirect happening right?

EDIT2: I uploaded my project so you can check the functionality. Strangely enough i can not reproduce the bug on my testserver, it's just happening on my local machine :( so it's seems this bug is hard to reproduce. I can't imagine what could possibly be different on my machine, so this is only happening locally.

http://dev.matthias-hollerbach.de/users/login username: admin password: 123 When you edit a user u use the ajax variant of attachment/admin_edit When you edit the attachment directly you're not using ajax.

EDIT3: I found out even locally this bug doesn't occur 100% of the time. When i upload a new image i can recrop it 10 times in a row without any problems. When i wait a few minutes without doing anything to the site suddenly the bug is there. If it's there for a specific image it wont go away. If i upload a second image i can again crop it a few times then when i wait this bug occurs to the second image as well. What could possibly change when I'm really doing nothing?! Furthermore i narrowed down the cause inside of makeVersion(). Its the last line return $Media->store($destination) && chmod($destination, $mode); if i replace that with return; the bug isn't happening, but logically my images aren't saved anymore. When i replace the return like above, then save the crop 1 time, then revert the change to the original line, it will work again a few times like on a freshly uploaded image, but then again, if i wait a minute, bug is there again.

I've never had a bug like this :( this is to meta for me xD If you're still interested in this pain in the ass bug i could install teamviewer so you can see for yourself.

ndm2 commented 10 years ago

The redirect is also happening, when i load attachment/admin_edit as an ajax view (e.g. in users/admin_edit) i still get redirected through the ajax response instead of just closing the overlay.

How would that even be possible? An AJAX request should be totally independent, and not affect the browsers state in any way, something like that would require an explicit JavaScript redirect (location.href = xyz). Have you assured that in that case there's really an AJAX request going on, and not just a normal submit (for whatever reason)?

The whitespace thing you explained could only be true if there is no redirect happening right?

Right.

Furthermore i narrowed down the cause inside of makeVersion(). Its the last line ...

Which media ino/process adapters are you using on your servers? Check Media_Process::info() and Media_Process::config().

Also try it with authentication disabled to rule out that this is somehow session related.

kinglouie commented 10 years ago

How would that even be possible? An AJAX request should be totally independent, and not affect the browsers state in any way.

Until now i thought the same :(

Have you assured that in that case there's really an AJAX request going on, and not just a normal submit (for whatever reason)?

yes i checked that i put an alert into my ajax function to test if its fired. It gets fired but as soon as ajax gets the response its redirecting. so the second alert() inside success isn't fired because it gets redirected This is my ajax function

  function initAjaxForm() {
      $("#overlay_attachment form").submit(function(e){
          e.preventDefault();
          alert("test");
          var form = $(this);
          var id = form.serializeArray()[1].value ;
          var data = form.serialize();
          $.ajax({
              type: form.attr('method'),
              url: form.attr('action'),
              data: data,
              success: function (responseHtml) {
                  alert(responseHtml);
                  var responseObject = jQuery.parseJSON(responseHtml);
                  if(responseObject.saved == true) {
                      $("#overlay_attachment").dialog("close"); 
                      $("#attachment_"+id+" img").attr("src", $("#attachment_"+id+" img").attr("src")+"?"+ Math.random());
                  } else {
                      $("#attachment_"+id).effect("shake", { times:3 }, 250); 
                  }
              },
              error: function (jqXHR, textStatus, errorThrown) {

                      alert('Error!');

              }
          });
      });
  }

Which media ino/process adapters are you using on your servers? Check Media_Process::info() and Media_Process::config().

i don't know where exactly i can check that, i put the following into generatorBehavior debug(Media_Process::info());exit; output is the following

Fatal error: Call to undefined method Media_Process::info()

however when i insert debug(Media_Process::info());exit; i'll get

array( 'document' => null, 'image' => 'Gd' )

i'll try now to deactivate authentication

ndm2 commented 10 years ago

i don't know where exactly i can check that, i put the following into generatorBehavior debug(Media_Process::info());exit; output is the following

Fatal error: Call to undefined method Media_Process::info()

Sorry, my bad, what I wanted to write was Media_Process::config() and Media_Info::config(), looks like I'm not really awake yet :)

kinglouie commented 10 years ago

i've deactivated auth component, bug still there.

output of Media_Info::config() is the following

array( 'audio' => array( (int) 0 => 'NewWave' ), 'document' => array(), 'image' => array( (int) 0 => 'ImageBasic' ) )

EDIT i don't know if this link is working for you, when it's working, you're on my local machine and should be able to reproduce the bug visually http://home.matthias-hollerbach.de/timmy/users/login user: admin pw: 123

EDIT2 I just checked php error log, theres nothing added when the bug occurs so i assume there are no errors being echo'd before the redirect happens

EDIT3

How would that even be possible? An AJAX request should be totally independent, and not affect the browsers state in any way.

Apparently ajax request have the same redirect abilities as a normal pageload, furthermore it is not possible to suppress the redirect see http://stackoverflow.com/questions/9177252/detecting-a-redirect-in-jquery-ajax

So we can ignore the ajax method I'm using, because the bug also occurs in the normal edit view.

ndm2 commented 10 years ago

I think they are talking about the AJAX request itself following a redirect, not the browser changing the current window location in response to a redirect that the AJAX request received.

I've tried it with the link you've provided, but I wasn't able to reproduce it, I've cropped and cropped and cropped, but no unexpected redirect occurred.

This sounds all very weird, and I really have no clue how this could be related to the media library, I mean, even if something in there would cause a redirect, this still doesn't explain why this would affect an AJAX request in a way that it causes the current window location to change.

I'd suggest that you dig a little deeper into the image processing adapters store() call and check if something in there causes the problem.

Also in case Controller::redirect() is being used to issue the problematic redirect, try overwriting AppController::redirect() and debug its call stack to figure from where exactly it's being invoked.

kinglouie commented 10 years ago

since you cant reproduce it on my machine i just tested it with firefox instead of safari. It's working, no redirect happening BUT i had the safari window in the background and that one reloaded as soon as i saved it in firefox! What the hell?

EDIT: OH MY GAWD i figured that CodeKit my local less compiler was reloading the page as soon as a file was changed. Im such a retard. I'm so sorry i bothered you with my incapability, nontheless thank you very much that you looked into it!

I literally spent the last 2 days looking for the bug and didn't think of that, shame on me