| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |