[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActionView/helpers/ -> file_upload_helper.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  /**
  12   * @package ActionView
  13   * @subpackage Helpers
  14   * @author Bermi Ferrer <bermi a.t akelos c.om>
  15   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  16   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  17   */
  18  
  19  
  20  require_once (AK_LIB_DIR.DS.'AkActionView'.DS.'AkActionViewHelper.php');
  21  
  22  class FileUploadHelper extends AkActionViewHelper
  23  {
  24      function _instantiateCacheHandler()
  25      {
  26          if(empty($this->Cache)){
  27              require_once (AK_LIB_DIR.DS.'AkCache.php');
  28              $this->Cache =& new AkCache();
  29              $this->Cache->init(3600*2);
  30          }
  31      }
  32  
  33      /**
  34       * Handles a gmail-like file upload.
  35       * 
  36       * Just add this code at the beigining of the form action receiver.
  37       * 
  38       *  if($this->file_upload_helper->handle_partial_upload('/tmp')){ // where /tmp is the temporary directory for uploaded files
  39       *      return;
  40       *  }
  41       *
  42       * You must add this javascript to your view:
  43       * 
  44       * <script src="/javascripts/file_uploader.js" type="text/javascript"></script>
  45       * <script type="text/javascript">
  46       *  window.onload = function(){
  47       *     FileUploader.start('form_id', {partial:true}); // Change "form_id" for the id you supplied to your form
  48       *  }
  49       * </script>
  50       * 
  51       * @param bool $send_json_response
  52       */
  53      function handle_partial_upload($temporary_directory = AK_TMP_DIR, $send_json_response = true)
  54      {
  55          $this->_instantiateCacheHandler();
  56          
  57          $this->_setTempDir($temporary_directory);
  58  
  59          // Perform some garbage collection
  60          $this->clean_persisted_files();
  61  
  62          // If we are uploading files from the special iframe we store the file on the cache for using it later
  63          if($this->_controller->Request->isPost() && !empty($this->_controller->params['__iframe_file_uploader_call_from'])){
  64              $uploaded_files = $this->_handle_partial_files($this->_controller->params);
  65              if($send_json_response){
  66                  $this->_controller->layout = false;
  67                  $this->_controller->renderText(Ak::toJson($uploaded_files));
  68              }else{
  69                  $this->_controller->params = array_merge($this->_controller->params, $uploaded_files);
  70              }
  71              return true;
  72  
  73  
  74              // We are requesting the file for downloading
  75          }elseif (!$this->_controller->Request->isPost() && !empty($this->_controller->params['persistence_key'])){
  76              $this->_send_file($this->_controller->params['persistence_key']);
  77              return true;
  78  
  79  
  80              // We have "persisted_keys" into the post so lets look for them and populate the params with cached data
  81          }elseif ($this->_controller->Request->isPost() && !empty($this->_controller->params['persisted_keys'])){
  82              if(!empty($this->_controller->params['persisted_files'])){
  83                  $files = $this->_get_persisted_files_params($this->_controller->params['persisted_files']);
  84                  $this->_controller->params = array_merge_recursive($this->_controller->params, $files);
  85                  $this->_clean_up_persisted_on_shutdown($this->_controller->params['persisted_keys']);
  86                  unset($this->_controller->params['persisted_keys']);
  87                  unset($this->_controller->params['persisted_files']);
  88              }
  89              return false;
  90          }else{
  91              return false;
  92          }
  93          return true;
  94      }
  95  
  96      function _get_persisted_files_params($params)
  97      {
  98          $result = array();
  99          foreach ($params as $name=>$details){
 100              if(is_string($details)){
 101                  $result[$name] = $this->_get_file_details($details);
 102              }elseif(is_array($details)){
 103                  $_nested = $this->_get_persisted_files_params($details);
 104                  if(!empty($_nested)){
 105                      $result = array_merge(array($name=>$_nested), $result);
 106                  }
 107              }
 108          }
 109          return $result;
 110      }
 111  
 112      function _get_file_details($key)
 113      {
 114          $key = preg_replace('/[^A-Z^a-z^0-9]/','',$key);
 115          $file = $this->get_persisted_file($key);
 116          if(!empty($file)){
 117              Ak::file_put_contents($this->_getTempDir().DS.'_file_uploader_file_'.$key, base64_decode($file['contents']), array('ftp'=>false));
 118              return array('tmp_name'=>$this->_getTempDir().DS.'_file_uploader_file_'.$key,'size'=>$file['size'], 'name'=>$file['name'],'type'=>$file['type'], 'error'=>0);
 119          }else{
 120              return false;
 121          }
 122      }
 123  
 124      function _getTempDir()
 125      {
 126          return $this->temp_dir;
 127      }
 128  
 129      function _setTempDir($temp_dir)
 130      {
 131          $temp_dir = rtrim($temp_dir,'/\\');
 132          $tmp_file = @tempnam($temp_dir,'testing');
 133          if($tmp_file && @unlink($tmp_file)){
 134              $this->temp_dir = $temp_dir;
 135          }else{
 136              trigger_error(Ak::t("You cant use the directory %dir for temporary storing files uploaded",array('%dir'=>$temp_dir)), E_USER_ERROR);
 137          }
 138      }
 139  
 140      function _handle_partial_files($params)
 141      {
 142          $result = array();
 143          foreach ($params as $name=>$details){
 144              if(is_array($details) && !empty($details['name']) &&  !empty($details['tmp_name']) &&  !empty($details['size'])){
 145                  $details['persistence_key'] = md5($details['tmp_name']);
 146                  $details['human_size'] = $this->_controller->number_helper->human_size($details['size']);
 147                  $file = $this->Cache->get($details['persistence_key'], 'persistent_files');
 148                  if (empty($file)) {
 149                      $this->Cache->save(serialize(array_merge($details,array('contents'=>base64_encode(file_get_contents($details['tmp_name']))))));
 150                  }
 151                  $result[$name] = $details;
 152              }elseif(is_array($details)){
 153                  $_nested = $this->_handle_partial_files($details);
 154                  if(!empty($_nested)){
 155                      $result = array_merge(array($name=>$_nested), $result);
 156                  }
 157              }
 158          }
 159          return $result;
 160      }
 161  
 162      function get_persisted_file($persistence_key)
 163      {
 164          $file = $this->Cache->get($persistence_key, 'persistent_files');
 165          if (empty($file)) {
 166              return array();
 167          }
 168          return unserialize($file);
 169      }
 170  
 171      function delete_persisted_file($key)
 172      {
 173          $key = preg_replace('/[^A-Z^a-z^0-9]/','',$key);
 174          $this->Cache->remove($key, 'persistent_files');
 175      }
 176  
 177      function clean_persisted_files()
 178      {
 179          $this->Cache->clean('persistent_files', 'old');
 180      }
 181  
 182      function _send_file($key)
 183      {
 184          $key = preg_replace('/[^A-Z^a-z^0-9]/','',$key);
 185          $file = $this->get_persisted_file($key);
 186          if(!empty($file)){
 187              $send_method = $file['size'] >  1048576 ? 'sendDataAsStream' : 'sendData';
 188              $this->_controller->$send_method(base64_decode($file['contents']),array('length'=>$file['size'], 'filename'=>$file['name'],'type'=>$file['type']));
 189          }else{
 190              die('invalid file');
 191          }
 192  
 193      }
 194  
 195      function _clean_up_persisted_on_shutdown($keys = false)
 196      {
 197          static $key_cache;
 198          if($keys === false){
 199              foreach ($key_cache as $key){
 200                  @unlink($this->_getTempDir().DS.'_file_uploader_file_'.$key);
 201                  $this->delete_persisted_file($key);
 202              }
 203              return;
 204          }
 205          if(empty($key_cache)){
 206              register_shutdown_function(array(&$this,'_clean_up_persisted_on_shutdown'));
 207          }
 208          $key_cache = array_merge($key_cache, $keys);
 209      }
 210  }
 211  
 212  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6