web/lib/Zend/File/Transfer/Adapter/Abstract.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category  Zend
       
    16  * @package   Zend_File_Transfer
       
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license   http://framework.zend.com/license/new-bsd     New BSD License
       
    19  * @version   $Id: Abstract.php 22371 2010-06-04 20:09:44Z thomas $
       
    20  */
       
    21 
       
    22 /**
       
    23  * Abstract class for file transfers (Downloads and Uploads)
       
    24  *
       
    25  * @category  Zend
       
    26  * @package   Zend_File_Transfer
       
    27  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    28  * @license   http://framework.zend.com/license/new-bsd     New BSD License
       
    29  */
       
    30 abstract class Zend_File_Transfer_Adapter_Abstract
       
    31 {
       
    32     /**@+
       
    33      * Plugin loader Constants
       
    34      */
       
    35     const FILTER    = 'FILTER';
       
    36     const VALIDATE  = 'VALIDATE';
       
    37     /**@-*/
       
    38 
       
    39     /**
       
    40      * Internal list of breaks
       
    41      *
       
    42      * @var array
       
    43      */
       
    44     protected $_break = array();
       
    45 
       
    46     /**
       
    47      * Internal list of filters
       
    48      *
       
    49      * @var array
       
    50      */
       
    51     protected $_filters = array();
       
    52 
       
    53     /**
       
    54      * Plugin loaders for filter and validation chains
       
    55      *
       
    56      * @var array
       
    57      */
       
    58     protected $_loaders = array();
       
    59 
       
    60     /**
       
    61      * Internal list of messages
       
    62      *
       
    63      * @var array
       
    64      */
       
    65     protected $_messages = array();
       
    66 
       
    67     /**
       
    68      * @var Zend_Translate
       
    69      */
       
    70     protected $_translator;
       
    71 
       
    72     /**
       
    73      * Is translation disabled?
       
    74      *
       
    75      * @var bool
       
    76      */
       
    77     protected $_translatorDisabled = false;
       
    78 
       
    79     /**
       
    80      * Internal list of validators
       
    81      * @var array
       
    82      */
       
    83     protected $_validators = array();
       
    84 
       
    85     /**
       
    86      * Internal list of files
       
    87      * This array looks like this:
       
    88      *     array(form => array( - Form is the name within the form or, if not set the filename
       
    89      *         name,            - Original name of this file
       
    90      *         type,            - Mime type of this file
       
    91      *         size,            - Filesize in bytes
       
    92      *         tmp_name,        - Internalally temporary filename for uploaded files
       
    93      *         error,           - Error which has occured
       
    94      *         destination,     - New destination for this file
       
    95      *         validators,      - Set validator names for this file
       
    96      *         files            - Set file names for this file
       
    97      *     ))
       
    98      *
       
    99      * @var array
       
   100      */
       
   101     protected $_files = array();
       
   102 
       
   103     /**
       
   104      * TMP directory
       
   105      * @var string
       
   106      */
       
   107     protected $_tmpDir;
       
   108 
       
   109     /**
       
   110      * Available options for file transfers
       
   111      */
       
   112     protected $_options = array(
       
   113         'ignoreNoFile'  => false,
       
   114         'useByteString' => true,
       
   115         'magicFile'     => null,
       
   116         'detectInfos'   => true,
       
   117     );
       
   118 
       
   119     /**
       
   120      * Send file
       
   121      *
       
   122      * @param  mixed $options
       
   123      * @return bool
       
   124      */
       
   125     abstract public function send($options = null);
       
   126 
       
   127     /**
       
   128      * Receive file
       
   129      *
       
   130      * @param  mixed $options
       
   131      * @return bool
       
   132      */
       
   133     abstract public function receive($options = null);
       
   134 
       
   135     /**
       
   136      * Is file sent?
       
   137      *
       
   138      * @param  array|string|null $files
       
   139      * @return bool
       
   140      */
       
   141     abstract public function isSent($files = null);
       
   142 
       
   143     /**
       
   144      * Is file received?
       
   145      *
       
   146      * @param  array|string|null $files
       
   147      * @return bool
       
   148      */
       
   149     abstract public function isReceived($files = null);
       
   150 
       
   151     /**
       
   152      * Has a file been uploaded ?
       
   153      *
       
   154      * @param  array|string|null $files
       
   155      * @return bool
       
   156      */
       
   157     abstract public function isUploaded($files = null);
       
   158 
       
   159     /**
       
   160      * Has the file been filtered ?
       
   161      *
       
   162      * @param array|string|null $files
       
   163      * @return bool
       
   164      */
       
   165     abstract public function isFiltered($files = null);
       
   166 
       
   167     /**
       
   168      * Retrieve progress of transfer
       
   169      *
       
   170      * @return float
       
   171      */
       
   172     public static function getProgress()
       
   173     {
       
   174         require_once 'Zend/File/Transfer/Exception.php';
       
   175         throw new Zend_File_Transfer_Exception('Method must be implemented within the adapter');
       
   176     }
       
   177 
       
   178     /**
       
   179      * Set plugin loader to use for validator or filter chain
       
   180      *
       
   181      * @param  Zend_Loader_PluginLoader_Interface $loader
       
   182      * @param  string $type 'filter', or 'validate'
       
   183      * @return Zend_File_Transfer_Adapter_Abstract
       
   184      * @throws Zend_File_Transfer_Exception on invalid type
       
   185      */
       
   186     public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader, $type)
       
   187     {
       
   188         $type = strtoupper($type);
       
   189         switch ($type) {
       
   190             case self::FILTER:
       
   191             case self::VALIDATE:
       
   192                 $this->_loaders[$type] = $loader;
       
   193                 return $this;
       
   194             default:
       
   195                 require_once 'Zend/File/Transfer/Exception.php';
       
   196                 throw new Zend_File_Transfer_Exception(sprintf('Invalid type "%s" provided to setPluginLoader()', $type));
       
   197         }
       
   198     }
       
   199 
       
   200     /**
       
   201      * Retrieve plugin loader for validator or filter chain
       
   202      *
       
   203      * Instantiates with default rules if none available for that type. Use
       
   204      * 'filter' or 'validate' for $type.
       
   205      *
       
   206      * @param  string $type
       
   207      * @return Zend_Loader_PluginLoader
       
   208      * @throws Zend_File_Transfer_Exception on invalid type.
       
   209      */
       
   210     public function getPluginLoader($type)
       
   211     {
       
   212         $type = strtoupper($type);
       
   213         switch ($type) {
       
   214             case self::FILTER:
       
   215             case self::VALIDATE:
       
   216                 $prefixSegment = ucfirst(strtolower($type));
       
   217                 $pathSegment   = $prefixSegment;
       
   218                 if (!isset($this->_loaders[$type])) {
       
   219                     $paths         = array(
       
   220                         'Zend_' . $prefixSegment . '_'     => 'Zend/' . $pathSegment . '/',
       
   221                         'Zend_' . $prefixSegment . '_File' => 'Zend/' . $pathSegment . '/File',
       
   222                     );
       
   223 
       
   224                     require_once 'Zend/Loader/PluginLoader.php';
       
   225                     $this->_loaders[$type] = new Zend_Loader_PluginLoader($paths);
       
   226                 } else {
       
   227                     $loader = $this->_loaders[$type];
       
   228                     $prefix = 'Zend_' . $prefixSegment . '_File_';
       
   229                     if (!$loader->getPaths($prefix)) {
       
   230                         $loader->addPrefixPath($prefix, str_replace('_', '/', $prefix));
       
   231                     }
       
   232                 }
       
   233                 return $this->_loaders[$type];
       
   234             default:
       
   235                 require_once 'Zend/File/Transfer/Exception.php';
       
   236                 throw new Zend_File_Transfer_Exception(sprintf('Invalid type "%s" provided to getPluginLoader()', $type));
       
   237         }
       
   238     }
       
   239 
       
   240     /**
       
   241      * Add prefix path for plugin loader
       
   242      *
       
   243      * If no $type specified, assumes it is a base path for both filters and
       
   244      * validators, and sets each according to the following rules:
       
   245      * - filters:    $prefix = $prefix . '_Filter'
       
   246      * - validators: $prefix = $prefix . '_Validate'
       
   247      *
       
   248      * Otherwise, the path prefix is set on the appropriate plugin loader.
       
   249      *
       
   250      * @param  string $prefix
       
   251      * @param  string $path
       
   252      * @param  string $type
       
   253      * @return Zend_File_Transfer_Adapter_Abstract
       
   254      * @throws Zend_File_Transfer_Exception for invalid type
       
   255      */
       
   256     public function addPrefixPath($prefix, $path, $type = null)
       
   257     {
       
   258         $type = strtoupper($type);
       
   259         switch ($type) {
       
   260             case self::FILTER:
       
   261             case self::VALIDATE:
       
   262                 $loader = $this->getPluginLoader($type);
       
   263                 $loader->addPrefixPath($prefix, $path);
       
   264                 return $this;
       
   265             case null:
       
   266                 $prefix = rtrim($prefix, '_');
       
   267                 $path   = rtrim($path, DIRECTORY_SEPARATOR);
       
   268                 foreach (array(self::FILTER, self::VALIDATE) as $type) {
       
   269                     $cType        = ucfirst(strtolower($type));
       
   270                     $pluginPath   = $path . DIRECTORY_SEPARATOR . $cType . DIRECTORY_SEPARATOR;
       
   271                     $pluginPrefix = $prefix . '_' . $cType;
       
   272                     $loader       = $this->getPluginLoader($type);
       
   273                     $loader->addPrefixPath($pluginPrefix, $pluginPath);
       
   274                 }
       
   275                 return $this;
       
   276             default:
       
   277                 require_once 'Zend/File/Transfer/Exception.php';
       
   278                 throw new Zend_File_Transfer_Exception(sprintf('Invalid type "%s" provided to getPluginLoader()', $type));
       
   279         }
       
   280     }
       
   281 
       
   282     /**
       
   283      * Add many prefix paths at once
       
   284      *
       
   285      * @param  array $spec
       
   286      * @return Zend_File_Transfer_Exception
       
   287      */
       
   288     public function addPrefixPaths(array $spec)
       
   289     {
       
   290         if (isset($spec['prefix']) && isset($spec['path'])) {
       
   291             return $this->addPrefixPath($spec['prefix'], $spec['path']);
       
   292         }
       
   293         foreach ($spec as $type => $paths) {
       
   294             if (is_numeric($type) && is_array($paths)) {
       
   295                 $type = null;
       
   296                 if (isset($paths['prefix']) && isset($paths['path'])) {
       
   297                     if (isset($paths['type'])) {
       
   298                         $type = $paths['type'];
       
   299                     }
       
   300                     $this->addPrefixPath($paths['prefix'], $paths['path'], $type);
       
   301                 }
       
   302             } elseif (!is_numeric($type)) {
       
   303                 if (!isset($paths['prefix']) || !isset($paths['path'])) {
       
   304                     foreach ($paths as $prefix => $spec) {
       
   305                         if (is_array($spec)) {
       
   306                             foreach ($spec as $path) {
       
   307                                 if (!is_string($path)) {
       
   308                                     continue;
       
   309                                 }
       
   310                                 $this->addPrefixPath($prefix, $path, $type);
       
   311                             }
       
   312                         } elseif (is_string($spec)) {
       
   313                             $this->addPrefixPath($prefix, $spec, $type);
       
   314                         }
       
   315                     }
       
   316                 } else {
       
   317                     $this->addPrefixPath($paths['prefix'], $paths['path'], $type);
       
   318                 }
       
   319             }
       
   320         }
       
   321         return $this;
       
   322     }
       
   323 
       
   324     /**
       
   325      * Adds a new validator for this class
       
   326      *
       
   327      * @param  string|array $validator           Type of validator to add
       
   328      * @param  boolean      $breakChainOnFailure If the validation chain should stop an failure
       
   329      * @param  string|array $options             Options to set for the validator
       
   330      * @param  string|array $files               Files to limit this validator to
       
   331      * @return Zend_File_Transfer_Adapter
       
   332      */
       
   333     public function addValidator($validator, $breakChainOnFailure = false, $options = null, $files = null)
       
   334     {
       
   335         if ($validator instanceof Zend_Validate_Interface) {
       
   336             $name = get_class($validator);
       
   337         } elseif (is_string($validator)) {
       
   338             $name      = $this->getPluginLoader(self::VALIDATE)->load($validator);
       
   339             $validator = new $name($options);
       
   340             if (is_array($options) && isset($options['messages'])) {
       
   341                 if (is_array($options['messages'])) {
       
   342                     $validator->setMessages($options['messages']);
       
   343                 } elseif (is_string($options['messages'])) {
       
   344                     $validator->setMessage($options['messages']);
       
   345                 }
       
   346 
       
   347                 unset($options['messages']);
       
   348             }
       
   349         } else {
       
   350             require_once 'Zend/File/Transfer/Exception.php';
       
   351             throw new Zend_File_Transfer_Exception('Invalid validator provided to addValidator; must be string or Zend_Validate_Interface');
       
   352         }
       
   353 
       
   354         $this->_validators[$name] = $validator;
       
   355         $this->_break[$name]      = $breakChainOnFailure;
       
   356         $files                    = $this->_getFiles($files, true, true);
       
   357         foreach ($files as $file) {
       
   358             if ($name == 'NotEmpty') {
       
   359                 $temp = $this->_files[$file]['validators'];
       
   360                 $this->_files[$file]['validators']  = array($name);
       
   361                 $this->_files[$file]['validators'] += $temp;
       
   362             } else {
       
   363                 $this->_files[$file]['validators'][] = $name;
       
   364             }
       
   365 
       
   366             $this->_files[$file]['validated']    = false;
       
   367         }
       
   368 
       
   369         return $this;
       
   370     }
       
   371 
       
   372     /**
       
   373      * Add Multiple validators at once
       
   374      *
       
   375      * @param  array $validators
       
   376      * @param  string|array $files
       
   377      * @return Zend_File_Transfer_Adapter_Abstract
       
   378      */
       
   379     public function addValidators(array $validators, $files = null)
       
   380     {
       
   381         foreach ($validators as $name => $validatorInfo) {
       
   382             if ($validatorInfo instanceof Zend_Validate_Interface) {
       
   383                 $this->addValidator($validatorInfo, null, null, $files);
       
   384             } else if (is_string($validatorInfo)) {
       
   385                 if (!is_int($name)) {
       
   386                     $this->addValidator($name, null, $validatorInfo, $files);
       
   387                 } else {
       
   388                     $this->addValidator($validatorInfo, null, null, $files);
       
   389                 }
       
   390             } else if (is_array($validatorInfo)) {
       
   391                 $argc                = count($validatorInfo);
       
   392                 $breakChainOnFailure = false;
       
   393                 $options             = array();
       
   394                 if (isset($validatorInfo['validator'])) {
       
   395                     $validator = $validatorInfo['validator'];
       
   396                     if (isset($validatorInfo['breakChainOnFailure'])) {
       
   397                         $breakChainOnFailure = $validatorInfo['breakChainOnFailure'];
       
   398                     }
       
   399 
       
   400                     if (isset($validatorInfo['options'])) {
       
   401                         $options = $validatorInfo['options'];
       
   402                     }
       
   403 
       
   404                     $this->addValidator($validator, $breakChainOnFailure, $options, $files);
       
   405                 } else {
       
   406                     if (is_string($name)) {
       
   407                         $validator = $name;
       
   408                         $options   = $validatorInfo;
       
   409                         $this->addValidator($validator, $breakChainOnFailure, $options, $files);
       
   410                     } else {
       
   411                         $file = $files;
       
   412                         switch (true) {
       
   413                             case (0 == $argc):
       
   414                                 break;
       
   415                             case (1 <= $argc):
       
   416                                 $validator  = array_shift($validatorInfo);
       
   417                             case (2 <= $argc):
       
   418                                 $breakChainOnFailure = array_shift($validatorInfo);
       
   419                             case (3 <= $argc):
       
   420                                 $options = array_shift($validatorInfo);
       
   421                             case (4 <= $argc):
       
   422                                 if (!empty($validatorInfo)) {
       
   423                                     $file = array_shift($validatorInfo);
       
   424                                 }
       
   425                             default:
       
   426                                 $this->addValidator($validator, $breakChainOnFailure, $options, $file);
       
   427                                 break;
       
   428                         }
       
   429                     }
       
   430                 }
       
   431             } else {
       
   432                 require_once 'Zend/File/Transfer/Exception.php';
       
   433                 throw new Zend_File_Transfer_Exception('Invalid validator passed to addValidators()');
       
   434             }
       
   435         }
       
   436 
       
   437         return $this;
       
   438     }
       
   439 
       
   440     /**
       
   441      * Sets a validator for the class, erasing all previous set
       
   442      *
       
   443      * @param  string|array $validator Validator to set
       
   444      * @param  string|array $files     Files to limit this validator to
       
   445      * @return Zend_File_Transfer_Adapter
       
   446      */
       
   447     public function setValidators(array $validators, $files = null)
       
   448     {
       
   449         $this->clearValidators();
       
   450         return $this->addValidators($validators, $files);
       
   451     }
       
   452 
       
   453     /**
       
   454      * Determine if a given validator has already been registered
       
   455      *
       
   456      * @param  string $name
       
   457      * @return bool
       
   458      */
       
   459     public function hasValidator($name)
       
   460     {
       
   461         return (false !== $this->_getValidatorIdentifier($name));
       
   462     }
       
   463 
       
   464     /**
       
   465      * Retrieve individual validator
       
   466      *
       
   467      * @param  string $name
       
   468      * @return Zend_Validate_Interface|null
       
   469      */
       
   470     public function getValidator($name)
       
   471     {
       
   472         if (false === ($identifier = $this->_getValidatorIdentifier($name))) {
       
   473             return null;
       
   474         }
       
   475         return $this->_validators[$identifier];
       
   476     }
       
   477 
       
   478     /**
       
   479      * Returns all set validators
       
   480      *
       
   481      * @param  string|array $files (Optional) Returns the validator for this files
       
   482      * @return null|array List of set validators
       
   483      */
       
   484     public function getValidators($files = null)
       
   485     {
       
   486         if ($files == null) {
       
   487             return $this->_validators;
       
   488         }
       
   489 
       
   490         $files      = $this->_getFiles($files, true, true);
       
   491         $validators = array();
       
   492         foreach ($files as $file) {
       
   493             if (!empty($this->_files[$file]['validators'])) {
       
   494                 $validators += $this->_files[$file]['validators'];
       
   495             }
       
   496         }
       
   497 
       
   498         $validators = array_unique($validators);
       
   499         $result     = array();
       
   500         foreach ($validators as $validator) {
       
   501             $result[$validator] = $this->_validators[$validator];
       
   502         }
       
   503 
       
   504         return $result;
       
   505     }
       
   506 
       
   507     /**
       
   508      * Remove an individual validator
       
   509      *
       
   510      * @param  string $name
       
   511      * @return Zend_File_Transfer_Adapter_Abstract
       
   512      */
       
   513     public function removeValidator($name)
       
   514     {
       
   515         if (false === ($key = $this->_getValidatorIdentifier($name))) {
       
   516             return $this;
       
   517         }
       
   518 
       
   519         unset($this->_validators[$key]);
       
   520         foreach (array_keys($this->_files) as $file) {
       
   521             if (empty($this->_files[$file]['validators'])) {
       
   522                 continue;
       
   523             }
       
   524 
       
   525             $index = array_search($key, $this->_files[$file]['validators']);
       
   526             if ($index === false) {
       
   527                 continue;
       
   528             }
       
   529 
       
   530             unset($this->_files[$file]['validators'][$index]);
       
   531             $this->_files[$file]['validated'] = false;
       
   532         }
       
   533 
       
   534         return $this;
       
   535     }
       
   536 
       
   537     /**
       
   538      * Remove all validators
       
   539      *
       
   540      * @return Zend_File_Transfer_Adapter_Abstract
       
   541      */
       
   542     public function clearValidators()
       
   543     {
       
   544         $this->_validators = array();
       
   545         foreach (array_keys($this->_files) as $file) {
       
   546             $this->_files[$file]['validators'] = array();
       
   547             $this->_files[$file]['validated']  = false;
       
   548         }
       
   549 
       
   550         return $this;
       
   551     }
       
   552 
       
   553     /**
       
   554      * Sets Options for adapters
       
   555      *
       
   556      * @param array $options Options to set
       
   557      * @param array $files   (Optional) Files to set the options for
       
   558      */
       
   559     public function setOptions($options = array(), $files = null) {
       
   560         $file = $this->_getFiles($files, false, true);
       
   561 
       
   562         if (is_array($options)) {
       
   563             if (empty($file)) {
       
   564                 $this->_options = array_merge($this->_options, $options);
       
   565             }
       
   566 
       
   567             foreach ($options as $name => $value) {
       
   568                 foreach ($file as $key => $content) {
       
   569                     switch ($name) {
       
   570                         case 'magicFile' :
       
   571                             $this->_files[$key]['options'][$name] = (string) $value;
       
   572                             break;
       
   573 
       
   574                         case 'ignoreNoFile' :
       
   575                         case 'useByteString' :
       
   576                         case 'detectInfos' :
       
   577                             $this->_files[$key]['options'][$name] = (boolean) $value;
       
   578                             break;
       
   579 
       
   580                         default:
       
   581                             require_once 'Zend/File/Transfer/Exception.php';
       
   582                             throw new Zend_File_Transfer_Exception("Unknown option: $name = $value");
       
   583                     }
       
   584                 }
       
   585             }
       
   586         }
       
   587 
       
   588         return $this;
       
   589     }
       
   590 
       
   591     /**
       
   592      * Returns set options for adapters or files
       
   593      *
       
   594      * @param  array $files (Optional) Files to return the options for
       
   595      * @return array Options for given files
       
   596      */
       
   597     public function getOptions($files = null) {
       
   598         $file = $this->_getFiles($files, false, true);
       
   599 
       
   600         foreach ($file as $key => $content) {
       
   601             if (isset($this->_files[$key]['options'])) {
       
   602                 $options[$key] = $this->_files[$key]['options'];
       
   603             } else {
       
   604                 $options[$key] = array();
       
   605             }
       
   606         }
       
   607 
       
   608         return $options;
       
   609     }
       
   610 
       
   611     /**
       
   612      * Checks if the files are valid
       
   613      *
       
   614      * @param  string|array $files (Optional) Files to check
       
   615      * @return boolean True if all checks are valid
       
   616      */
       
   617     public function isValid($files = null)
       
   618     {
       
   619         $check = $this->_getFiles($files, false, true);
       
   620         if (empty($check)) {
       
   621             return false;
       
   622         }
       
   623 
       
   624         $translator      = $this->getTranslator();
       
   625         $this->_messages = array();
       
   626         $break           = false;
       
   627         foreach($check as $key => $content) {
       
   628             if (array_key_exists('validators', $content) &&
       
   629                 in_array('Zend_Validate_File_Count', $content['validators'])) {
       
   630                 $validator = $this->_validators['Zend_Validate_File_Count'];
       
   631                 $count     = $content;
       
   632                 if (empty($content['tmp_name'])) {
       
   633                     continue;
       
   634                 }
       
   635 
       
   636                 if (array_key_exists('destination', $content)) {
       
   637                     $checkit = $content['destination'];
       
   638                 } else {
       
   639                     $checkit = dirname($content['tmp_name']);
       
   640                 }
       
   641 
       
   642                 $checkit .= DIRECTORY_SEPARATOR . $content['name'];
       
   643                     $validator->addFile($checkit);
       
   644             }
       
   645         }
       
   646 
       
   647         if (isset($count)) {
       
   648             if (!$validator->isValid($count['tmp_name'], $count)) {
       
   649                 $this->_messages += $validator->getMessages();
       
   650             }
       
   651         }
       
   652 
       
   653         foreach ($check as $key => $content) {
       
   654             $fileerrors  = array();
       
   655             if (array_key_exists('validators', $content) && $content['validated']) {
       
   656                 continue;
       
   657             }
       
   658 
       
   659             if (array_key_exists('validators', $content)) {
       
   660                 foreach ($content['validators'] as $class) {
       
   661                     $validator = $this->_validators[$class];
       
   662                     if (method_exists($validator, 'setTranslator')) {
       
   663                         $validator->setTranslator($translator);
       
   664                     }
       
   665 
       
   666                     if (($class === 'Zend_Validate_File_Upload') and (empty($content['tmp_name']))) {
       
   667                         $tocheck = $key;
       
   668                     } else {
       
   669                         $tocheck = $content['tmp_name'];
       
   670                     }
       
   671 
       
   672                     if (!$validator->isValid($tocheck, $content)) {
       
   673                         $fileerrors += $validator->getMessages();
       
   674                     }
       
   675 
       
   676                     if (!empty($content['options']['ignoreNoFile']) and (isset($fileerrors['fileUploadErrorNoFile']))) {
       
   677                         unset($fileerrors['fileUploadErrorNoFile']);
       
   678                         break;
       
   679                     }
       
   680 
       
   681                     if (($class === 'Zend_Validate_File_Upload') and (count($fileerrors) > 0)) {
       
   682                         break;
       
   683                     }
       
   684 
       
   685                     if (($this->_break[$class]) and (count($fileerrors) > 0)) {
       
   686                         $break = true;
       
   687                         break;
       
   688                     }
       
   689                 }
       
   690             }
       
   691 
       
   692             if (count($fileerrors) > 0) {
       
   693                 $this->_files[$key]['validated'] = false;
       
   694             } else {
       
   695                 $this->_files[$key]['validated'] = true;
       
   696             }
       
   697 
       
   698             $this->_messages += $fileerrors;
       
   699             if ($break) {
       
   700                 break;
       
   701             }
       
   702         }
       
   703 
       
   704         if (count($this->_messages) > 0) {
       
   705             return false;
       
   706         }
       
   707 
       
   708         return true;
       
   709     }
       
   710 
       
   711     /**
       
   712      * Returns found validation messages
       
   713      *
       
   714      * @return array
       
   715      */
       
   716     public function getMessages()
       
   717     {
       
   718         return $this->_messages;
       
   719     }
       
   720 
       
   721     /**
       
   722      * Retrieve error codes
       
   723      *
       
   724      * @return array
       
   725      */
       
   726     public function getErrors()
       
   727     {
       
   728         return array_keys($this->_messages);
       
   729     }
       
   730 
       
   731     /**
       
   732      * Are there errors registered?
       
   733      *
       
   734      * @return boolean
       
   735      */
       
   736     public function hasErrors()
       
   737     {
       
   738         return (!empty($this->_messages));
       
   739     }
       
   740 
       
   741     /**
       
   742      * Adds a new filter for this class
       
   743      *
       
   744      * @param  string|array $filter Type of filter to add
       
   745      * @param  string|array $options   Options to set for the filter
       
   746      * @param  string|array $files     Files to limit this filter to
       
   747      * @return Zend_File_Transfer_Adapter
       
   748      */
       
   749     public function addFilter($filter, $options = null, $files = null)
       
   750     {
       
   751         if ($filter instanceof Zend_Filter_Interface) {
       
   752             $class = get_class($filter);
       
   753         } elseif (is_string($filter)) {
       
   754             $class  = $this->getPluginLoader(self::FILTER)->load($filter);
       
   755             $filter = new $class($options);
       
   756         } else {
       
   757             require_once 'Zend/File/Transfer/Exception.php';
       
   758             throw new Zend_File_Transfer_Exception('Invalid filter specified');
       
   759         }
       
   760 
       
   761         $this->_filters[$class] = $filter;
       
   762         $files                  = $this->_getFiles($files, true, true);
       
   763         foreach ($files as $file) {
       
   764             $this->_files[$file]['filters'][] = $class;
       
   765         }
       
   766 
       
   767         return $this;
       
   768     }
       
   769 
       
   770     /**
       
   771      * Add Multiple filters at once
       
   772      *
       
   773      * @param  array $filters
       
   774      * @param  string|array $files
       
   775      * @return Zend_File_Transfer_Adapter_Abstract
       
   776      */
       
   777     public function addFilters(array $filters, $files = null)
       
   778     {
       
   779         foreach ($filters as $key => $spec) {
       
   780             if ($spec instanceof Zend_Filter_Interface) {
       
   781                 $this->addFilter($spec, null, $files);
       
   782                 continue;
       
   783             }
       
   784 
       
   785             if (is_string($key)) {
       
   786                 $this->addFilter($key, $spec, $files);
       
   787                 continue;
       
   788             }
       
   789 
       
   790             if (is_int($key)) {
       
   791                 if (is_string($spec)) {
       
   792                     $this->addFilter($spec, null, $files);
       
   793                     continue;
       
   794                 }
       
   795 
       
   796                 if (is_array($spec)) {
       
   797                     if (!array_key_exists('filter', $spec)) {
       
   798                         continue;
       
   799                     }
       
   800 
       
   801                     $filter = $spec['filter'];
       
   802                     unset($spec['filter']);
       
   803                     $this->addFilter($filter, $spec, $files);
       
   804                     continue;
       
   805                 }
       
   806 
       
   807                 continue;
       
   808             }
       
   809         }
       
   810 
       
   811         return $this;
       
   812     }
       
   813 
       
   814     /**
       
   815      * Sets a filter for the class, erasing all previous set
       
   816      *
       
   817      * @param  string|array $filter Filter to set
       
   818      * @param  string|array $files     Files to limit this filter to
       
   819      * @return Zend_File_Transfer_Adapter
       
   820      */
       
   821     public function setFilters(array $filters, $files = null)
       
   822     {
       
   823         $this->clearFilters();
       
   824         return $this->addFilters($filters, $files);
       
   825     }
       
   826 
       
   827     /**
       
   828      * Determine if a given filter has already been registered
       
   829      *
       
   830      * @param  string $name
       
   831      * @return bool
       
   832      */
       
   833     public function hasFilter($name)
       
   834     {
       
   835         return (false !== $this->_getFilterIdentifier($name));
       
   836     }
       
   837 
       
   838     /**
       
   839      * Retrieve individual filter
       
   840      *
       
   841      * @param  string $name
       
   842      * @return Zend_Filter_Interface|null
       
   843      */
       
   844     public function getFilter($name)
       
   845     {
       
   846         if (false === ($identifier = $this->_getFilterIdentifier($name))) {
       
   847             return null;
       
   848         }
       
   849         return $this->_filters[$identifier];
       
   850     }
       
   851 
       
   852     /**
       
   853      * Returns all set filters
       
   854      *
       
   855      * @param  string|array $files (Optional) Returns the filter for this files
       
   856      * @return array List of set filters
       
   857      * @throws Zend_File_Transfer_Exception When file not found
       
   858      */
       
   859     public function getFilters($files = null)
       
   860     {
       
   861         if ($files === null) {
       
   862             return $this->_filters;
       
   863         }
       
   864 
       
   865         $files   = $this->_getFiles($files, true, true);
       
   866         $filters = array();
       
   867         foreach ($files as $file) {
       
   868             if (!empty($this->_files[$file]['filters'])) {
       
   869                 $filters += $this->_files[$file]['filters'];
       
   870             }
       
   871         }
       
   872 
       
   873         $filters = array_unique($filters);
       
   874         $result  = array();
       
   875         foreach ($filters as $filter) {
       
   876             $result[] = $this->_filters[$filter];
       
   877         }
       
   878 
       
   879         return $result;
       
   880     }
       
   881 
       
   882     /**
       
   883      * Remove an individual filter
       
   884      *
       
   885      * @param  string $name
       
   886      * @return Zend_File_Transfer_Adapter_Abstract
       
   887      */
       
   888     public function removeFilter($name)
       
   889     {
       
   890         if (false === ($key = $this->_getFilterIdentifier($name))) {
       
   891             return $this;
       
   892         }
       
   893 
       
   894         unset($this->_filters[$key]);
       
   895         foreach (array_keys($this->_files) as $file) {
       
   896             if (empty($this->_files[$file]['filters'])) {
       
   897                 continue;
       
   898             }
       
   899 
       
   900             $index = array_search($key, $this->_files[$file]['filters']);
       
   901             if ($index === false) {
       
   902                 continue;
       
   903             }
       
   904 
       
   905             unset($this->_files[$file]['filters'][$index]);
       
   906         }
       
   907         return $this;
       
   908     }
       
   909 
       
   910     /**
       
   911      * Remove all filters
       
   912      *
       
   913      * @return Zend_File_Transfer_Adapter_Abstract
       
   914      */
       
   915     public function clearFilters()
       
   916     {
       
   917         $this->_filters = array();
       
   918         foreach (array_keys($this->_files) as $file) {
       
   919             $this->_files[$file]['filters'] = array();
       
   920         }
       
   921         return $this;
       
   922     }
       
   923 
       
   924     /**
       
   925      * Returns all set files
       
   926      *
       
   927      * @return array List of set files
       
   928      * @throws Zend_File_Transfer_Exception Not implemented
       
   929      */
       
   930     public function getFile()
       
   931     {
       
   932         require_once 'Zend/File/Transfer/Exception.php';
       
   933         throw new Zend_File_Transfer_Exception('Method not implemented');
       
   934     }
       
   935 
       
   936     /**
       
   937      * Retrieves the filename of transferred files.
       
   938      *
       
   939      * @param  string  $fileelement (Optional) Element to return the filename for
       
   940      * @param  boolean $path        (Optional) Should the path also be returned ?
       
   941      * @return string|array
       
   942      */
       
   943     public function getFileName($file = null, $path = true)
       
   944     {
       
   945         $files     = $this->_getFiles($file, true, true);
       
   946         $result    = array();
       
   947         $directory = "";
       
   948         foreach($files as $file) {
       
   949             if (empty($this->_files[$file]['name'])) {
       
   950                 continue;
       
   951             }
       
   952 
       
   953             if ($path === true) {
       
   954                 $directory = $this->getDestination($file) . DIRECTORY_SEPARATOR;
       
   955             }
       
   956 
       
   957             $result[$file] = $directory . $this->_files[$file]['name'];
       
   958         }
       
   959 
       
   960         if (count($result) == 1) {
       
   961             return current($result);
       
   962         }
       
   963 
       
   964         return $result;
       
   965     }
       
   966 
       
   967     /**
       
   968      * Retrieve additional internal file informations for files
       
   969      *
       
   970      * @param  string $file (Optional) File to get informations for
       
   971      * @return array
       
   972      */
       
   973     public function getFileInfo($file = null)
       
   974     {
       
   975         return $this->_getFiles($file);
       
   976     }
       
   977 
       
   978     /**
       
   979      * Adds one or more files
       
   980      *
       
   981      * @param  string|array $file      File to add
       
   982      * @param  string|array $validator Validators to use for this file, must be set before
       
   983      * @param  string|array $filter    Filters to use for this file, must be set before
       
   984      * @return Zend_File_Transfer_Adapter_Abstract
       
   985      * @throws Zend_File_Transfer_Exception Not implemented
       
   986      */
       
   987     public function addFile($file, $validator = null, $filter = null)
       
   988     {
       
   989         require_once 'Zend/File/Transfer/Exception.php';
       
   990         throw new Zend_File_Transfer_Exception('Method not implemented');
       
   991     }
       
   992 
       
   993     /**
       
   994      * Returns all set types
       
   995      *
       
   996      * @return array List of set types
       
   997      * @throws Zend_File_Transfer_Exception Not implemented
       
   998      */
       
   999     public function getType()
       
  1000     {
       
  1001         require_once 'Zend/File/Transfer/Exception.php';
       
  1002         throw new Zend_File_Transfer_Exception('Method not implemented');
       
  1003     }
       
  1004 
       
  1005     /**
       
  1006      * Adds one or more type of files
       
  1007      *
       
  1008      * @param  string|array $type Type of files to add
       
  1009      * @param  string|array $validator Validators to use for this file, must be set before
       
  1010      * @param  string|array $filter    Filters to use for this file, must be set before
       
  1011      * @return Zend_File_Transfer_Adapter_Abstract
       
  1012      * @throws Zend_File_Transfer_Exception Not implemented
       
  1013      */
       
  1014     public function addType($type, $validator = null, $filter = null)
       
  1015     {
       
  1016         require_once 'Zend/File/Transfer/Exception.php';
       
  1017         throw new Zend_File_Transfer_Exception('Method not implemented');
       
  1018     }
       
  1019 
       
  1020     /**
       
  1021      * Sets a new destination for the given files
       
  1022      *
       
  1023      * @deprecated Will be changed to be a filter!!!
       
  1024      * @param  string       $destination New destination directory
       
  1025      * @param  string|array $files       Files to set the new destination for
       
  1026      * @return Zend_File_Transfer_Abstract
       
  1027      * @throws Zend_File_Transfer_Exception when the given destination is not a directory or does not exist
       
  1028      */
       
  1029     public function setDestination($destination, $files = null)
       
  1030     {
       
  1031         $orig = $files;
       
  1032         $destination = rtrim($destination, "/\\");
       
  1033         if (!is_dir($destination)) {
       
  1034             require_once 'Zend/File/Transfer/Exception.php';
       
  1035             throw new Zend_File_Transfer_Exception('The given destination is not a directory or does not exist');
       
  1036         }
       
  1037 
       
  1038         if (!is_writable($destination)) {
       
  1039             require_once 'Zend/File/Transfer/Exception.php';
       
  1040             throw new Zend_File_Transfer_Exception('The given destination is not writeable');
       
  1041         }
       
  1042 
       
  1043         if ($files === null) {
       
  1044             foreach ($this->_files as $file => $content) {
       
  1045                 $this->_files[$file]['destination'] = $destination;
       
  1046             }
       
  1047         } else {
       
  1048             $files = $this->_getFiles($files, true, true);
       
  1049             if (empty($files) and is_string($orig)) {
       
  1050                 $this->_files[$orig]['destination'] = $destination;
       
  1051             }
       
  1052 
       
  1053             foreach ($files as $file) {
       
  1054                 $this->_files[$file]['destination'] = $destination;
       
  1055             }
       
  1056         }
       
  1057 
       
  1058         return $this;
       
  1059     }
       
  1060 
       
  1061     /**
       
  1062      * Retrieve destination directory value
       
  1063      *
       
  1064      * @param  null|string|array $files
       
  1065      * @return null|string|array
       
  1066      */
       
  1067     public function getDestination($files = null)
       
  1068     {
       
  1069         $orig  = $files;
       
  1070         $files = $this->_getFiles($files, false, true);
       
  1071         $destinations = array();
       
  1072         if (empty($files) and is_string($orig)) {
       
  1073             if (isset($this->_files[$orig]['destination'])) {
       
  1074                 $destinations[$orig] = $this->_files[$orig]['destination'];
       
  1075             } else {
       
  1076                 require_once 'Zend/File/Transfer/Exception.php';
       
  1077                 throw new Zend_File_Transfer_Exception(sprintf('The file transfer adapter can not find "%s"', $orig));
       
  1078             }
       
  1079         }
       
  1080 
       
  1081         foreach ($files as $key => $content) {
       
  1082             if (isset($this->_files[$key]['destination'])) {
       
  1083                 $destinations[$key] = $this->_files[$key]['destination'];
       
  1084             } else {
       
  1085                 $tmpdir = $this->_getTmpDir();
       
  1086                 $this->setDestination($tmpdir, $key);
       
  1087                 $destinations[$key] = $tmpdir;
       
  1088             }
       
  1089         }
       
  1090 
       
  1091         if (empty($destinations)) {
       
  1092             $destinations = $this->_getTmpDir();
       
  1093         } else if (count($destinations) == 1) {
       
  1094             $destinations = current($destinations);
       
  1095         }
       
  1096 
       
  1097         return $destinations;
       
  1098     }
       
  1099 
       
  1100     /**
       
  1101      * Set translator object for localization
       
  1102      *
       
  1103      * @param  Zend_Translate|null $translator
       
  1104      * @return Zend_File_Transfer_Abstract
       
  1105      */
       
  1106     public function setTranslator($translator = null)
       
  1107     {
       
  1108         if (null === $translator) {
       
  1109             $this->_translator = null;
       
  1110         } elseif ($translator instanceof Zend_Translate_Adapter) {
       
  1111             $this->_translator = $translator;
       
  1112         } elseif ($translator instanceof Zend_Translate) {
       
  1113             $this->_translator = $translator->getAdapter();
       
  1114         } else {
       
  1115             require_once 'Zend/File/Transfer/Exception.php';
       
  1116             throw new Zend_File_Transfer_Exception('Invalid translator specified');
       
  1117         }
       
  1118 
       
  1119         return $this;
       
  1120     }
       
  1121 
       
  1122     /**
       
  1123      * Retrieve localization translator object
       
  1124      *
       
  1125      * @return Zend_Translate_Adapter|null
       
  1126      */
       
  1127     public function getTranslator()
       
  1128     {
       
  1129         if ($this->translatorIsDisabled()) {
       
  1130             return null;
       
  1131         }
       
  1132 
       
  1133         return $this->_translator;
       
  1134     }
       
  1135 
       
  1136     /**
       
  1137      * Indicate whether or not translation should be disabled
       
  1138      *
       
  1139      * @param  bool $flag
       
  1140      * @return Zend_File_Transfer_Abstract
       
  1141      */
       
  1142     public function setDisableTranslator($flag)
       
  1143     {
       
  1144         $this->_translatorDisabled = (bool) $flag;
       
  1145         return $this;
       
  1146     }
       
  1147 
       
  1148     /**
       
  1149      * Is translation disabled?
       
  1150      *
       
  1151      * @return bool
       
  1152      */
       
  1153     public function translatorIsDisabled()
       
  1154     {
       
  1155         return $this->_translatorDisabled;
       
  1156     }
       
  1157 
       
  1158     /**
       
  1159      * Returns the hash for a given file
       
  1160      *
       
  1161      * @param  string       $hash  Hash algorithm to use
       
  1162      * @param  string|array $files Files to return the hash for
       
  1163      * @return string|array Hashstring
       
  1164      * @throws Zend_File_Transfer_Exception On unknown hash algorithm
       
  1165      */
       
  1166     public function getHash($hash = 'crc32', $files = null)
       
  1167     {
       
  1168         if (!in_array($hash, hash_algos())) {
       
  1169             require_once 'Zend/File/Transfer/Exception.php';
       
  1170             throw new Zend_File_Transfer_Exception('Unknown hash algorithm');
       
  1171         }
       
  1172 
       
  1173         $files  = $this->_getFiles($files);
       
  1174         $result = array();
       
  1175         foreach($files as $key => $value) {
       
  1176             if (file_exists($value['name'])) {
       
  1177                 $result[$key] = hash_file($hash, $value['name']);
       
  1178             } else if (file_exists($value['tmp_name'])) {
       
  1179                 $result[$key] = hash_file($hash, $value['tmp_name']);
       
  1180             } else if (empty($value['options']['ignoreNoFile'])) {
       
  1181                 require_once 'Zend/File/Transfer/Exception.php';
       
  1182                 throw new Zend_File_Transfer_Exception("The file '{$value['name']}' does not exist");
       
  1183             }
       
  1184         }
       
  1185 
       
  1186         if (count($result) == 1) {
       
  1187             return current($result);
       
  1188         }
       
  1189 
       
  1190         return $result;
       
  1191     }
       
  1192 
       
  1193     /**
       
  1194      * Returns the real filesize of the file
       
  1195      *
       
  1196      * @param string|array $files Files to get the filesize from
       
  1197      * @throws Zend_File_Transfer_Exception When the file does not exist
       
  1198      * @return string|array Filesize
       
  1199      */
       
  1200     public function getFileSize($files = null)
       
  1201     {
       
  1202         $files  = $this->_getFiles($files);
       
  1203         $result = array();
       
  1204         foreach($files as $key => $value) {
       
  1205             if (file_exists($value['name']) || file_exists($value['tmp_name'])) {
       
  1206                 if ($value['options']['useByteString']) {
       
  1207                     $result[$key] = self::_toByteString($value['size']);
       
  1208                 } else {
       
  1209                     $result[$key] = $value['size'];
       
  1210                 }
       
  1211             } else if (empty($value['options']['ignoreNoFile'])) {
       
  1212                 require_once 'Zend/File/Transfer/Exception.php';
       
  1213                 throw new Zend_File_Transfer_Exception("The file '{$value['name']}' does not exist");
       
  1214             } else {
       
  1215                 continue;
       
  1216             }
       
  1217         }
       
  1218 
       
  1219         if (count($result) == 1) {
       
  1220             return current($result);
       
  1221         }
       
  1222 
       
  1223         return $result;
       
  1224     }
       
  1225 
       
  1226     /**
       
  1227      * Internal method to detect the size of a file
       
  1228      *
       
  1229      * @param  array $value File infos
       
  1230      * @return string Filesize of given file
       
  1231      */
       
  1232     protected function _detectFileSize($value)
       
  1233     {
       
  1234         if (file_exists($value['name'])) {
       
  1235             $result = sprintf("%u", @filesize($value['name']));
       
  1236         } else if (file_exists($value['tmp_name'])) {
       
  1237             $result = sprintf("%u", @filesize($value['tmp_name']));
       
  1238         } else {
       
  1239             return null;
       
  1240         }
       
  1241 
       
  1242         return $result;
       
  1243     }
       
  1244 
       
  1245     /**
       
  1246      * Returns the real mimetype of the file
       
  1247      * Uses fileinfo, when not available mime_magic and as last fallback a manual given mimetype
       
  1248      *
       
  1249      * @param string|array $files Files to get the mimetype from
       
  1250      * @throws Zend_File_Transfer_Exception When the file does not exist
       
  1251      * @return string|array MimeType
       
  1252      */
       
  1253     public function getMimeType($files = null)
       
  1254     {
       
  1255         $files  = $this->_getFiles($files);
       
  1256         $result = array();
       
  1257         foreach($files as $key => $value) {
       
  1258             if (file_exists($value['name']) || file_exists($value['tmp_name'])) {
       
  1259                 $result[$key] = $value['type'];
       
  1260             } else if (empty($value['options']['ignoreNoFile'])) {
       
  1261                 require_once 'Zend/File/Transfer/Exception.php';
       
  1262                 throw new Zend_File_Transfer_Exception("The file '{$value['name']}' does not exist");
       
  1263             } else {
       
  1264                 continue;
       
  1265             }
       
  1266         }
       
  1267 
       
  1268         if (count($result) == 1) {
       
  1269             return current($result);
       
  1270         }
       
  1271 
       
  1272         return $result;
       
  1273     }
       
  1274 
       
  1275     /**
       
  1276      * Internal method to detect the mime type of a file
       
  1277      *
       
  1278      * @param  array $value File infos
       
  1279      * @return string Mimetype of given file
       
  1280      */
       
  1281     protected function _detectMimeType($value)
       
  1282     {
       
  1283         if (file_exists($value['name'])) {
       
  1284             $file = $value['name'];
       
  1285         } else if (file_exists($value['tmp_name'])) {
       
  1286             $file = $value['tmp_name'];
       
  1287         } else {
       
  1288             return null;
       
  1289         }
       
  1290 
       
  1291         if (class_exists('finfo', false)) {
       
  1292             $const = defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME;
       
  1293             if (!empty($value['options']['magicFile'])) {
       
  1294                 $mime = @finfo_open($const, $value['options']['magicFile']);
       
  1295             }
       
  1296 
       
  1297             if (empty($mime)) {
       
  1298                 $mime = @finfo_open($const);
       
  1299             }
       
  1300 
       
  1301             if (!empty($mime)) {
       
  1302                 $result = finfo_file($mime, $file);
       
  1303             }
       
  1304 
       
  1305             unset($mime);
       
  1306         }
       
  1307 
       
  1308         if (empty($result) && (function_exists('mime_content_type')
       
  1309             && ini_get('mime_magic.magicfile'))) {
       
  1310             $result = mime_content_type($file);
       
  1311         }
       
  1312 
       
  1313         if (empty($result)) {
       
  1314             $result = 'application/octet-stream';
       
  1315         }
       
  1316 
       
  1317         return $result;
       
  1318     }
       
  1319 
       
  1320     /**
       
  1321      * Returns the formatted size
       
  1322      *
       
  1323      * @param  integer $size
       
  1324      * @return string
       
  1325      */
       
  1326     protected static function _toByteString($size)
       
  1327     {
       
  1328         $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
       
  1329         for ($i=0; $size >= 1024 && $i < 9; $i++) {
       
  1330             $size /= 1024;
       
  1331         }
       
  1332 
       
  1333         return round($size, 2) . $sizes[$i];
       
  1334     }
       
  1335 
       
  1336     /**
       
  1337      * Internal function to filter all given files
       
  1338      *
       
  1339      * @param  string|array $files (Optional) Files to check
       
  1340      * @return boolean False on error
       
  1341      */
       
  1342     protected function _filter($files = null)
       
  1343     {
       
  1344         $check           = $this->_getFiles($files);
       
  1345         foreach ($check as $name => $content) {
       
  1346             if (array_key_exists('filters', $content)) {
       
  1347                 foreach ($content['filters'] as $class) {
       
  1348                     $filter = $this->_filters[$class];
       
  1349                     try {
       
  1350                         $result = $filter->filter($this->getFileName($name));
       
  1351 
       
  1352                         $this->_files[$name]['destination'] = dirname($result);
       
  1353                         $this->_files[$name]['name']        = basename($result);
       
  1354                     } catch (Zend_Filter_Exception $e) {
       
  1355                         $this->_messages += array($e->getMessage());
       
  1356                     }
       
  1357                 }
       
  1358             }
       
  1359         }
       
  1360 
       
  1361         if (count($this->_messages) > 0) {
       
  1362             return false;
       
  1363         }
       
  1364 
       
  1365         return true;
       
  1366     }
       
  1367 
       
  1368     /**
       
  1369      * Determine system TMP directory and detect if we have read access
       
  1370      *
       
  1371      * @return string
       
  1372      * @throws Zend_File_Transfer_Exception if unable to determine directory
       
  1373      */
       
  1374     protected function _getTmpDir()
       
  1375     {
       
  1376         if (null === $this->_tmpDir) {
       
  1377             $tmpdir = array();
       
  1378             if (function_exists('sys_get_temp_dir')) {
       
  1379                 $tmpdir[] = sys_get_temp_dir();
       
  1380             }
       
  1381 
       
  1382             if (!empty($_ENV['TMP'])) {
       
  1383                 $tmpdir[] = realpath($_ENV['TMP']);
       
  1384             }
       
  1385 
       
  1386             if (!empty($_ENV['TMPDIR'])) {
       
  1387                 $tmpdir[] = realpath($_ENV['TMPDIR']);
       
  1388             }
       
  1389 
       
  1390             if (!empty($_ENV['TEMP'])) {
       
  1391                 $tmpdir[] = realpath($_ENV['TEMP']);
       
  1392             }
       
  1393 
       
  1394             $upload = ini_get('upload_tmp_dir');
       
  1395             if ($upload) {
       
  1396                 $tmpdir[] = realpath($upload);
       
  1397             }
       
  1398 
       
  1399             foreach($tmpdir as $directory) {
       
  1400                 if ($this->_isPathWriteable($directory)) {
       
  1401                     $this->_tmpDir = $directory;
       
  1402                 }
       
  1403             }
       
  1404 
       
  1405             if (empty($this->_tmpDir)) {
       
  1406                 // Attemp to detect by creating a temporary file
       
  1407                 $tempFile = tempnam(md5(uniqid(rand(), TRUE)), '');
       
  1408                 if ($tempFile) {
       
  1409                     $this->_tmpDir = realpath(dirname($tempFile));
       
  1410                     unlink($tempFile);
       
  1411                 } else {
       
  1412                     require_once 'Zend/File/Transfer/Exception.php';
       
  1413                     throw new Zend_File_Transfer_Exception('Could not determine a temporary directory');
       
  1414                 }
       
  1415             }
       
  1416 
       
  1417             $this->_tmpDir = rtrim($this->_tmpDir, "/\\");
       
  1418         }
       
  1419         return $this->_tmpDir;
       
  1420     }
       
  1421 
       
  1422     /**
       
  1423      * Tries to detect if we can read and write to the given path
       
  1424      *
       
  1425      * @param string $path
       
  1426      */
       
  1427     protected function _isPathWriteable($path)
       
  1428     {
       
  1429         $tempFile = rtrim($path, "/\\");
       
  1430         $tempFile .= '/' . 'test.1';
       
  1431 
       
  1432         $result = @file_put_contents($tempFile, 'TEST');
       
  1433 
       
  1434         if ($result == false) {
       
  1435             return false;
       
  1436         }
       
  1437 
       
  1438         $result = @unlink($tempFile);
       
  1439 
       
  1440         if ($result == false) {
       
  1441             return false;
       
  1442         }
       
  1443 
       
  1444         return true;
       
  1445     }
       
  1446 
       
  1447     /**
       
  1448      * Returns found files based on internal file array and given files
       
  1449      *
       
  1450      * @param  string|array $files       (Optional) Files to return
       
  1451      * @param  boolean      $names       (Optional) Returns only names on true, else complete info
       
  1452      * @param  boolean      $noexception (Optional) Allows throwing an exception, otherwise returns an empty array
       
  1453      * @return array Found files
       
  1454      * @throws Zend_File_Transfer_Exception On false filename
       
  1455      */
       
  1456     protected function _getFiles($files, $names = false, $noexception = false)
       
  1457     {
       
  1458         $check = array();
       
  1459 
       
  1460         if (is_string($files)) {
       
  1461             $files = array($files);
       
  1462         }
       
  1463 
       
  1464         if (is_array($files)) {
       
  1465             foreach ($files as $find) {
       
  1466                 $found = array();
       
  1467                 foreach ($this->_files as $file => $content) {
       
  1468                     if (!isset($content['name'])) {
       
  1469                         continue;
       
  1470                     }
       
  1471 
       
  1472                     if (($content['name'] === $find) && isset($content['multifiles'])) {
       
  1473                         foreach ($content['multifiles'] as $multifile) {
       
  1474                             $found[] = $multifile;
       
  1475                         }
       
  1476                         break;
       
  1477                     }
       
  1478 
       
  1479                     if ($file === $find) {
       
  1480                         $found[] = $file;
       
  1481                         break;
       
  1482                     }
       
  1483 
       
  1484                     if ($content['name'] === $find) {
       
  1485                         $found[] = $file;
       
  1486                         break;
       
  1487                     }
       
  1488                 }
       
  1489 
       
  1490                 if (empty($found)) {
       
  1491                     if ($noexception !== false) {
       
  1492                         return array();
       
  1493                     }
       
  1494 
       
  1495                     require_once 'Zend/File/Transfer/Exception.php';
       
  1496                     throw new Zend_File_Transfer_Exception(sprintf('The file transfer adapter can not find "%s"', $find));
       
  1497                 }
       
  1498 
       
  1499                 foreach ($found as $checked) {
       
  1500                     $check[$checked] = $this->_files[$checked];
       
  1501                 }
       
  1502             }
       
  1503         }
       
  1504 
       
  1505         if ($files === null) {
       
  1506             $check = $this->_files;
       
  1507             $keys  = array_keys($check);
       
  1508             foreach ($keys as $key) {
       
  1509                 if (isset($check[$key]['multifiles'])) {
       
  1510                     unset($check[$key]);
       
  1511                 }
       
  1512             }
       
  1513         }
       
  1514 
       
  1515         if ($names) {
       
  1516             $check = array_keys($check);
       
  1517         }
       
  1518 
       
  1519         return $check;
       
  1520     }
       
  1521 
       
  1522     /**
       
  1523      * Retrieve internal identifier for a named validator
       
  1524      *
       
  1525      * @param  string $name
       
  1526      * @return string
       
  1527      */
       
  1528     protected function _getValidatorIdentifier($name)
       
  1529     {
       
  1530         if (array_key_exists($name, $this->_validators)) {
       
  1531             return $name;
       
  1532         }
       
  1533 
       
  1534         foreach (array_keys($this->_validators) as $test) {
       
  1535             if (preg_match('/' . preg_quote($name) . '$/i', $test)) {
       
  1536                 return $test;
       
  1537             }
       
  1538         }
       
  1539 
       
  1540         return false;
       
  1541     }
       
  1542 
       
  1543     /**
       
  1544      * Retrieve internal identifier for a named filter
       
  1545      *
       
  1546      * @param  string $name
       
  1547      * @return string
       
  1548      */
       
  1549     protected function _getFilterIdentifier($name)
       
  1550     {
       
  1551         if (array_key_exists($name, $this->_filters)) {
       
  1552             return $name;
       
  1553         }
       
  1554 
       
  1555         foreach (array_keys($this->_filters) as $test) {
       
  1556             if (preg_match('/' . preg_quote($name) . '$/i', $test)) {
       
  1557                 return $test;
       
  1558             }
       
  1559         }
       
  1560 
       
  1561         return false;
       
  1562     }
       
  1563 }