Multi File upload - CFileValidator and CUploadedFile

Hi,

Some proposed changes to allow CFileValidator and CUploadedFile to work with multiple file uploads.

CUploaded file: The change is in getInstanceByName where an additional key is added to keep track of multiple files



  public static function getInstanceByName($name)


  {


    static $_key; // The new key


    static $files;


    if($files===null)


    {


      $files=array();


      if(isset($_FILES) && is_array($_FILES))


      {


        foreach($_FILES as $class=>$info)


        {


          if(is_array($info['name']))


          {


            $first=reset($info['name']);


            $keys=array_keys($info['name']);


            if(is_array($first))


            {


              foreach($keys as $key)


              {


                $subKeys=array_keys($info['name'][$key]);


                foreach($subKeys as $subKey)


                {


                  $files["{$class}[{$key}][{$subKey}]"]=new CUploadedFile($info['name'][$key][$subKey],$info['tmp_name'][$key][$subKey],$info['type'][$key][$subKey],$info['size'][$key][$subKey],$info['error'][$key][$subKey]);


                }


              }


            }


            else


            {


              foreach($keys as $key)


              {


                $files["{$class}[{$key}][0]"]=new CUploadedFile($info['name'][$key],$info['tmp_name'][$key],$info['type'][$key],$info['size'][$key],$info['error'][$key]); // Add key of 0


              }


            }


          }


          else


          {


            $files["{$class}[0]"]=new CUploadedFile($info['name'],$info['tmp_name'],$info['type'],$info['size'],$info['error']); // Add key of 0


          }


        }


      }


    }





    /*


     * Keeps track of which file we are to return


     * If this is the first iteration ever or we are at the end having iterated


     * through multiple files before in this request, reset the $_key to 0


     * Otherwise increment $_key.


    if ($_key===null || (sizeof($files)>1 && $_key===(sizeof($files)-1))) $_key=0;


    else ++$_key;





    /*


     * If we have iterated through all the files $_key will


     * "overflow" the $files array; reset $_key to null and return null


     * Otherwise return the file


     */


    $file = isset($files["{$name}[{$_key}]"]) ? $files["{$name}[{$_key}]"] : null;


    if ($file===null) $_key=null;


    return $file;


  }


When using CFileUpload you now need to loop until CFileUpload returns null, indicating there are no more files. This is true even for single file uploads.

So CFileValidator::validateAttribute (and any classes that extend it, such as EPhotoValidator) becomes:



  protected function validateAttribute($object,$attribute) {


    $file=$object->$attribute;


    if(!($file instanceof CUploadedFile)) {


      $file=CUploadedFile::getInstance($object,$attribute);





      do


      {


        if($this->allowEmpty && ($file===null || $file->getError()==UPLOAD_ERR_NO_FILE))


        return;





        /*


          * Validation


          */





      } while ($file=CUploadedFile::getInstance($object,$attribute));


    }


  }


Thank you for your investigation.

Could you please submit a ticket about this? Thanks.