views:

240

answers:

3

Okay,

I have read, and tried a lot of things on how to implement uploadify with Zend, and I'm probably overlooking something, but I'm completely stuck. It seems my action isn't called.

All the uploadify are placed in one directory inside the public folder.

The upload button is called in a fancybox instance and is loaded from a hidden div on the same page (admin/images/index) through the inline concept of Fancybox.

All the jquery stuff works great, the uploading works fine, and every file is completed. But the files aren't removed to the folder. When testing with the uploadify.php script everything works fine.

There are no errors in the console.

Tested on localhost Tested with Chrome 6.0.4 & Firefox 6.3.6 Tested with uploadify 2.1

This is my jquery init code: (I use loader for the use of jquery scripts)

// ImageUploader
   $('#uploaderImages').Loader({
      url: ['/dgpcms/public/uploadify/jquery.uploadify.v2.1.0.js', '/dgpcms/public/uploadify/swfobject.js', '/dgpcms/public/uploadify/uploadify.css'],
      //debug: [true],
      cache: [true],
      success: function(target){
         $(this).uploadify({
            'uploader'  : '../../uploadify/uploadify.swf',
            'script'   : '<?php echo $this->url(array(\'module\' => \'admin\', \'controller\' => \'images\', \'action\' => \'upload\')) ?>',
            'scriptData': {'PHPSESSID': '<?php echo session_id();?>'},
            'cancelImg' : '../../uploadify/cancel.png',
            'auto'      : true,
            'folder'    : '../../uploads/images/original/',
            'multi'     : true,
            'sizeLimit'   : '4194304',
            'queueSizeLimit' : 50,
            'buttonText': 'Select files',
            'fileDesc'   : '',
            'fileExt'   : '.jpg;*.jpeg;*.gif;*.png'
         });
      }
   });

I used different things to call the file, but none of them worked:

../../admin/images/upload
<?php echo $this->baseUrl().'/admin/images/upload'; ?>
<?php echo $this->baseUrl(); ?>/admin/images/upload
http://localhost/dgpcms/public/admin/images/upload

This is the code in my admin/images/upload

public function uploadAction()    {   
        if (!empty($_FILES)) {
           $tempFile = $_FILES['Filedata']['tmp_name'];
         $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
         $targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];

            // If the target directory isn't available, create it
            if (!is_dir($targetPath)) {
                mkdir($targetPath, 02775, true);
            }

            move_uploaded_file($tempFile, $targetFile);

            switch ($_FILES['Filedata']['error'])
            {
                case 0:
                    $msg = "No Error"; // comment this out if you don't want a message to appear on success.
                    break;
                case 1:
                    $msg = "The file is bigger than this PHP installation allows";
                    break;
                case 2:
                    $msg = "The file is bigger than this form allows";
                    break;
                case 3:
                    $msg = "Only part of the file was uploaded";
                    break;
                case 4:
                    $msg = "No file was uploaded";
                    break;
                case 6:
                    $msg = "Missing a temporary folder";
                    break;
                case 7:
                    $msg = "Failed to write file to disk";
                    break;
                case 8:
                    $msg = "File upload stopped by extension";
                    break;
                default:
                    $msg = "unknown error ".$_FILES['Filedata']['error'];
                    break;
            }

            if ($msg) {
                $stringData = "Error: ".$_FILES['Filedata']['error']." Error Info: ".$msg;
            } else {
                $stringData = "1"; // This is required for onComplete to fire on Mac OSX
            }

            echo $stringData;
      }
}

This is the code used in my bootstrap for the cookie problem:

protected function _initSession()
   {
      $sessName = "PHPSESSID";
      $sessOptions = array('name' => $sessName);

      // Flash has problems with cookies so we pass the PHPSESSID variable via get
      // it'll be injected if it doesn't exist in _SERVER["HTTP_COOKIE"] e.g. '; PHPSESSID=hdi5u83hfnu7ltlvp5q3bb53k4'
      if ((stripos($_SERVER['REQUEST_URI'], '__tkn') !== false)
      //    &amp;&amp; preg_match('#^[a-z\d]{25,32}$#si', $_GET[$sessName])
      && preg_match('#__tkn/([a-z\d]{25,32})#si', $_SERVER['REQUEST_URI'], $matches)
      && (stripos($_SERVER["HTTP_COOKIE"], $matches[1]) === false)) {
      $sid = $matches[1];

      $prefix = '';
      if (!empty($_SERVER["HTTP_COOKIE"])) {
      $prefix = '; ';
      }

      $_SERVER["HTTP_COOKIE"] .= $prefix . $sessName . '=' . $sid;
      $_COOKIE[$sessName] = $sid;

      Zend_Session::setId($sid);
      }

      Zend_Session::setOptions($sessOptions);
   }

Anybody any clue? I'm completely lost....

==================================== EDIT ========================================

The problem is still that I can't reach the controller action. I have changed some things for easier testing. The current code is as follows:

ImagesController > indexAction

 public function indexAction()
    {
        $tempFile = $_FILES['Filedata']['tmp_name'];
        $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
        $targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
        move_uploaded_file($tempFile,$targetFile);
    }

index.phtml

<script type="text/javascript" src="<?php echo $this->baseUrl(); ?>/uploadify/jquery.uploadify.v2.1.0.min.js"></script>
<script type="text/javascript" src="<?php echo $this->baseUrl(); ?>/uploadify/swfobject.js"></script>
<link rel="stylesheet" type="text/css" href="<?php echo $this->baseUrl(); ?>/uploadify/uploadify.css" />

<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
    $('#uploaderImages').uploadify({
        'uploader'      : '../../uploadify/uploadify.swf',
        'script'        : '<?php echo $this->url(array("controller" => "images", "action" => "index")); ?>',
        'cancelImg'     : '../../uploadify/cancel.png',
        'auto'          : true,
        'scriptData'    : {'PHPSESSID': '<?php echo session_id();?>'},
        'scriptAccess'  : 'always',
        'queueID'       : 'fileQueue',
        'folder'        : '../../uploads/images/original/',
        'multi'         : true
    });
});
// ]]></script>

<a href="javascript:$('#uploaderImages').uploadifyClearQueue();"><?php echo $this->translate('Clear Queue'); ?></a>
<input type="file" name="uploaderImages" id="uploaderImages" />
<div id="fileQueue"></div>

And the source code looks like this:

<script type="text/javascript" src="/dgpcms/public/uploadify/jquery.uploadify.v2.1.0.min.js"></script> 
<script type="text/javascript" src="/dgpcms/public/uploadify/swfobject.js"></script> 
<link rel="stylesheet" type="text/css" href="/dgpcms/public/uploadify/uploadify.css" /> 

<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
    $('#uploaderImages').uploadify({
        'uploader'      : '../../uploadify/uploadify.swf',
        'script'        : '/dgpcms/public/admin/images/index',
        'cancelImg'     : '../../uploadify/cancel.png',
        'auto'          : true,
        'scriptData'    : {'PHPSESSID': 'il0900fifd0l3nte1q30658094'},
        'scriptAccess'  : 'always',
        'queueID'       : 'fileQueue',
        'folder'        : '../../uploads/images/original/',
        'multi'         : true
    });
});
// ]]></script>

I don't understand why the action isn't called..

Another edit:

Current scripts:

images/index.phtml

<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
    $('#uploaderImages').uploadify({
        'uploader'      : '../../uploadify/uploadify.swf',
        'script'        : '<?php echo $this->url(array('controller' => 'images', 'action' => 'upload')) ?>',
        'cancelImg'     : '../../uploadify/cancel.png',
        'auto'          : true,
        'scriptData': {'PHPSESSID': '<?php echo session_id();?>'},
        'scriptAccess'  : 'always',
        'queueID'       : 'fileQueue',
        'folder'        : '../../uploads/images/original/',
        'multi'         : true,
        'auto'          : true,
        onComplete: function (evt, queueID, fileObj, response, data) {
            alert(response);
        },
        onError: function (evt, queueID, fileObj, response, data) {
            alert(response);
        },
    });
});
// ]]></script>

imagesController:

public function uploadAction()
    {
        /*
        $tempFile = $_FILES['Filedata']['tmp_name'];
        $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
        $targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
        move_uploaded_file($tempFile,$targetFile);
        */

        echo '<script>alert("called for!"); </script>';
        echo 'I\'m being called, fucking briljant!';
    }

Using this setup will return the following error:

Fatal Error:
Uncaught exception 'Zend_Acl_Exception' with message 'Resource 'upload' not found' in C:\xampp\htdocs\dgpcms\library\Zend\Acl.php:365

Stack Trace:

C:\xampp\htdocs\dgpcms\library\Zend\Acl.php(777):
Zend_Acl->get('upload')

C:\xampp\htdocs\dgpcms\MyApp\Controller\Plugin\Acl.php(48):
Zend_Acl->isAllowed('administrator','upload','index')

C:\xampp\htdocs\dgpcms\library\Zend\Controller\Plugin\Broker.php(309):
MyApp_Controller_plugin_Acl->preDispatch(Object(Zend_Controller_Request_Http))

C:\xampp\htdocs\dgpcms\library\Zend\Controller\Front.php(941):
Zend_Controller_plugin_Broker->preDispatch(Object(Zend_Controller_Request_Http))

C:\xampp\htdocs\dgpcms\library\Zend\Application\Bootstrap\Bootstrap.php(97):
Zend_Controller_front->dispatch()

C:\xampp\htdocs\dgpcms\library\Zend\Application.php(36):
Zend_Application_Bootstrap_Bootstrap->run()

C:\xampp\htdocs\dgpcms\public\index.php(27):
Zend_Application->run()

thrown in C:\xampp\htdocs\dgpcms\library\Zend\Acl.php on line 365

And checking the Acl.php:

$this->acl->addRole(new zend_Acl_Role('publisher'));
            $this->acl->addRole(new zend_Acl_Role('administrator'), 'publisher');

            $this->acl->add(new Zend_Acl_Resource('index'));
            $this->acl->add(new Zend_Acl_Resource('error'));
            $this->acl->add(new Zend_Acl_Resource('pages'));
            $this->acl->add(new Zend_Acl_Resource('images'));
            $this->acl->add(new Zend_Acl_Resource('upload'));
            $this->acl->add(new Zend_Acl_Resource('files'));
            $this->acl->add(new Zend_Acl_Resource('modules'));
            $this->acl->add(new Zend_Acl_Resource('users'));
            $this->acl->add(new Zend_Acl_Resource('statistics'));
            $this->acl->add(new Zend_Acl_Resource('settings'));
            $this->acl->add(new Zend_Acl_Resource('login'));

            $this->acl->allow(null, array('index', 'error', 'login'));

            $this->acl->allow('publisher', 'login', array('login', 'logout'));
            $this->acl->allow('publisher', 'pages', array('index', 'view', 'insert', 'update'));
            $this->acl->allow('publisher', 'users', array('index', 'update'));
            $this->acl->allow('publisher', 'images', array('index', 'upload'));
            $this->acl->allow('publisher', 'files', array('index'));
            $this->acl->allow('publisher', 'modules', array('index'));
            $this->acl->allow('publisher', 'statistics', array('index'));
            $this->acl->allow('administrator', null);

Creating the upload resources returns in a HTTP error by uploadify.js

I tried several session solutions found on the uploadify forum and more, but that didn't make any difference...

Another edit

I worked further, and adding the resource for upload

$this->acl->add(new Zend_Acl_Resource('upload'));

gave me the html output form the not logged in/ no role script, pointing to the known session issue. I'm going to try several solutions and will get back if the scripts works.

A: 

From what I have discovered, I was having some similar issues because the swf and upload.php files weren't in the same directory and directory permissions were off.

r0m4n
Permissions are OK
Rick de Graaf
A: 

I can't see where you're disabling the view renderer. Maybe this is the problem.

If you already have a view called upload or index (based on your edit) does you have a layout? The uploadfy need only a string as output.

So you have to add this lines to your action:

$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);

If this doesn't work I sugest you to test on an separated page without zend framework, so that you can know exactly what's going on.

Also, access the page via browser and tell us if it is working without erros (images/index or upload)

Finally, I also sugest you to use firebug and analyze the request.

Keyne
Didn't work unfortunately, the action isn't called for
Rick de Graaf
@Rick If you try to access this URL what's happening (images/index)? First you need to check if this page has any errors. Second, it works without zf?
Keyne
I'm getting no errors what so ever(php + jquery). I can get uploadify to work without zf, by using the uploadify.php file. When I want to use a action I can't get the action called, so no files are moved.
Rick de Graaf
A: 

Oke I fixed the whole thing. I discovered that the upload has to be added as a resource. The flash session problem was fixed with a plugin that can be found here

Note: This is tested localhost only for now

This is how the scripts look:

The index.phtml

<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
    $('#uploaderImages').uploadify({
        'uploader'      : '../../uploadify/uploadify.swf',
        'script'        : '<?php echo $this->baseUrl().'/admin/images/upload'; ?>',
        'cancelImg'     : '../../uploadify/cancel.png',
        'scriptAccess'  : 'always',
        'queueID'       : 'fileQueue',
        'folder'        : '../../uploads/images/original/',
        'multi'         : true,
        'auto'          : true,
    });
});
// ]]></script>

The imageController:

public function uploadAction()
    {
        $tempFile = $_FILES['Filedata']['tmp_name'];
        $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
        $targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
        move_uploaded_file($tempFile,$targetFile);
    }

And add the resource in your ACL:

$this->acl->add(new Zend_Acl_Resource('upload'));

If I encounter more problems, or if anybody else does, please let me now, and I will update this question/answer with needed additional info.

Tested in Firefox 3.6 & Chrome 6.0

Rick de Graaf