plupload and CodeIgniter 1.7.2

CodeIgniter logo

Ако някога сте ползвали чудесният плъгин за качване на файлове на Moxiecode, plupload, то вероятно сте харесали решението за качване на много файлове наведнъж.

Ако пък сте ползвали CodeIgniter, би трябвало в момента, в който сте погледнали примера в download-натия файл от сайта на plupload, да сте забелязали променливите в URL-a (т.нар. query string). Точно те са причината връзката между CodeIgniter и plupload да не се получава.

CodeIgniter logo

Ако някога сте ползвали чудесният плъгин за качване на файлове на Moxiecode, plupload, то вероятно сте харесали решението за качване на много файлове наведнъж.

Ако пък сте ползвали CodeIgniter, би трябвало в момента, в който сте погледнали примера в download-натия файл от сайта на plupload, да сте забелязали променливите в URL-a (т.нар. query string). Точно те са причината връзката между CodeIgniter и plupload да не се получава.

Аз лично не понасям query_strings, а използването на $_GET параметри, поне според мен, трябва да става в URI. Това е и поведението на CodeIgniter, в документацията на който е написано следното:

GET, POST, and COOKIE Data

GET data is simply disallowed by CodeIgniter since the system utilizes URI segments rather than traditional URL query strings (unless you have the query string option enabled in your config file). The global GET array is unset by the Input class during system initialization.

Накратко, за да си решите проблема с интеграцията на plupload и CodeIgniter ще трябва малко повечко работа.

Първо – plupload изпраща името на файла, който се качва в момента като query string променлива, която би трябвало да получите като $_GET параметър. Input class-ът на CodeIgniter обаче маха целия $_GET, затова ще embed-нем името на файла в URI. Същото ще стане и с двете променливи chunk и chunks. Целта ни е да получим URL от сорта на:

http://example.com/uploader/upload_file/filename.ext/0/4

където 0 и 4 са стойностите съответно на chunk и chunks. Забележете, че тези стойности варират според големината на качвания файл и стойността на конфигурационния параметър chunk_size.

За пример ще взема html5 widget-ът. Малката промяна, която престои да направим, е във plupload.js, в частност във функцията :

buildUrl : function(url, items) {
  var query = '';
  plupload.each(items, function(value, name) {
    query += (query ? '&' : '') + encodeURIComponent(name) + 
    '=' + encodeURIComponent(value);
  });
 
  if (query) {
   url += (url.indexOf('?') > 0 ? '&' : '?') + query;
  }
 
	return url;
}

Крайната цел е да изглежда така:

buildUrl : function(url, items) {
  var query = '';
  plupload.each(items, function(value, name) {
    query += '/' + encodeURIComponent(value);
  });
 
  if (query) {
   url += query;
  }
 
	return url;
}

При това положение достатъчно е в controller-a да имаме следния метод:

<?php
class Uploader extends Controller {
  function Uploader()
  {
    parent::Controller();
  }
 
  function upload_file($fileName, $chunk, $chunks)
  {
    // Validate input
    if ((filter_var($chunk, FILTER_VALIDATE_INT) === TRUE) || 
    (filter_var($chunks, FILTER_VALIDATE_INT) === TRUE))
    {
       die('{"jsonrpc" : "2.0", "error" : {"code": 104, "message": "Incorrect upload data."}, "id" : "id"}');
    }
 
    // 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 = './some_target_dir_name';
    $cleanupTargetDir = false; // Remove old files
    $maxFileAge = 60 * 60; // Temp file age in seconds
 
    // 5 minutes execution time
    @set_time_limit(5 * 60);
 
    // Clean the fileName for security reasons
    $fileName = preg_replace ('/_(jpg|jpeg|png|gif)$/i', '.$1', $fileName);
    $fileName = preg_replace ('/[^\w\.\-_]+/', '', $fileName);
 
    // upload.php code from the plupload /example dir follows 
    // (from line 37 on)
  }
}

По този начин CodeIgniter извлича стойностите за chunk и chunks директно от URI-то и plupload започва да работи по очаквания начин. За flash-версията (заради IE и Opera) ще трябва да вземете нещата от src/flash директорията и да преправите src/com/plupload/File.as със следния patch:

Leave a Reply

Your email address will not be published. Required fields are marked *