Yii extension for Plupload
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
assets
PluploadWidget.php
README

README

This is an update to the Yii plupload extension found here:
http://www.yiiframework.com/extension/pupload/

Here is the list of changes:

    * Updated Plupload to v1.3.0
    * Fixed the DIRECTORY_SEPARATOR problem (to be checked, I'm not working with Windows presently)
    * Added language option to config, to be used as 'language' => Yii::app()->language (see the example below). There are 3 supported languages in the i18n folder, but you can find more langauges in their forum http://www.plupload.com/punbb/viewforum.php?id=5
    * Added max_file_number option to config, to limit the number of files (implemented as suggested here http://www.plupload.com/punbb/viewtopic.php?id=113 )
    * Added autostart option to config, to autostart the upload after choosing files (implemented as suggested here http://www.plupload.com/punbb/viewtopic.php?id=90 )
    * Added reset_after_upload to config, option to reset the file dialog after the upload is complete (implemented as suggested here http://www.plupload.com/punbb/viewtopic.php?id=192 )
    * Added callbacks array, to be able to specify javascript callbacks for Plupload's Public Events (see documentation: http://www.plupload.com/plupload/docs/api/index.html#class_plupload.Uploader.html )
    * Added jquery_ui to config, option to enable the jQuery UI theme (see: http://www.plupload.com/example_jquery_ui.php)

Here is an example of use with the new options:

      $this->widget('application.extensions.plupload.PluploadWidget', array(
         'config' => array(
             //'runtimes' => 'gears,flash,silverlight,browserplus,html5',
             'url' => $this->createUrl('blob/uploadFilesPlupload'),
             //'max_file_size' => str_replace("M", "mb", ini_get('upload_max_filesize')),
             'max_file_size' => Yii::app()->params['maxFileSize'],
             'chunk_size' => '1mb',
             'unique_names' => true,
             'filters' => array(
                  array('title' => Yii::t('app', 'Images files'), 'extensions' => 'jpg,jpeg,gif,png'),
              ),
             'language' => Yii::app()->language,
             'max_file_number' => 1,
             'autostart' => true,
             'jquery_ui' => false,
             'reset_after_upload' => true,
         ),
         'callbacks' => array(
             'FileUploaded' => 'function(up,file,response){console.log(response.response);}',
         ),
         'id' => 'uploader'
      ));

And here's an example of the controller action, supporting chunked upload, adapted from upload.php example in the original Plupload package:

      public function actionUploadFilesPlupload()
      {
          // HTTP headers for no cache etc
          header('Content-type: text/plain; charset=UTF-8');
          header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
          header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
          header("Cache-Control: no-store, no-cache, must-revalidate");
          header("Cache-Control: post-check=0, pre-check=0", false);
          header("Pragma: no-cache");

          // Settings
          $targetDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "plupload";
          $cleanupTargetDir = false; // Remove old files
          $maxFileAge = 60 * 60; // Temp file age in seconds

          // 5 minutes execution time
          @set_time_limit(5 * 60);
          // usleep(5000);

          // Get parameters
          $chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
          $chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
          $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';

          // Clean the fileName for security reasons
          $fileName = preg_replace('/[^\w\._\s]+/', '', $fileName);

          // Create target dir
          if (!file_exists($targetDir))
                  @mkdir($targetDir);

          // Remove old temp files
          if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
                  while (($file = readdir($dir)) !== false) {
                          $filePath = $targetDir . DIRECTORY_SEPARATOR . $file;

                          // Remove temp files if they are older than the max age
                          if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
                                  @unlink($filePath);
                  }

                  closedir($dir);
          } else
                  throw new CHttpException (500, Yii::t('app', "Can't open temporary directory."));

          // Look for the content type header
          if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
                  $contentType = $_SERVER["HTTP_CONTENT_TYPE"];

          if (isset($_SERVER["CONTENT_TYPE"]))
                  $contentType = $_SERVER["CONTENT_TYPE"];

          if (strpos($contentType, "multipart") !== false) {
                  if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
                          // Open temp file
                          $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
                          if ($out) {
                                  // Read binary input stream and append it to temp file
                                  $in = fopen($_FILES['file']['tmp_name'], "rb");

                                  if ($in) {
                                          while ($buff = fread($in, 4096))
                                                  fwrite($out, $buff);
                                  } else
                                          throw new CHttpException (500, Yii::t('app', "Can't open input stream."));

                                  fclose($out);
                                  unlink($_FILES['file']['tmp_name']);
                          } else
                                  throw new CHttpException (500, Yii::t('app', "Can't open output stream."));
                  } else
                          throw new CHttpException (500, Yii::t('app', "Can't move uploaded file."));
          } else {
                  // Open temp file
                  $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
                  if ($out) {
                          // Read binary input stream and append it to temp file
                          $in = fopen("php://input", "rb");

                          if ($in) {
                                  while ($buff = fread($in, 4096))
                                          fwrite($out, $buff);
                          } else
                                  throw new CHttpException (500, Yii::t('app', "Can't open input stream."));

                          fclose($out);
                  } else
                          throw new CHttpException (500, Yii::t('app', "Can't open output stream."));
          }

          // After last chunk is received, process the file
          $ret = array('result' => '1');
          if (intval($chunk) + 1 >= intval($chunks)) {

              $originalname = $fileName;
              if (isset($_SERVER['HTTP_CONTENT_DISPOSITION'])) {
                  $arr = array();
                  preg_match('@^attachment; filename="([^"]+)"@',$_SERVER['HTTP_CONTENT_DISPOSITION'],$arr);
                  if (isset($arr[1]))
                      $originalname = $arr[1];
              }

              // **********************************************************************************************
              // Do whatever you need with the uploaded file, which has $originalname as the original file name
              // and is located at $targetDir . DIRECTORY_SEPARATOR . $fileName
              // **********************************************************************************************
          }

          // Return response
          die(json_encode($ret));
      }