Development

Changeset 6748

You must first sign up to be able to contribute.

Changeset 6748

Show
Ignore:
Timestamp:
12/27/07 11:24:07 (1 year ago)
Author:
fabien
Message:

added sfValidatorFile

  • added sfValidatorFile validator
  • added support for files in sfForm (second argument of bind())
  • deprecated all file related methods of sfWebRequest (see UPGRADE)
  • moved mime_types to sfCompat10Plugin (there are now part of the sfValidatorFile class)
  • small example on how to use the new validator with a form:

class TestForm? extends sfForm
{

public function configure()
{

$this->validatorSchema = new sfValidatorSchema(array(

'file' => new sfValidatorFile(),

));

$this->widgetSchema = new sfWidgetFormSchema(array(

'file' => new sfWidgetFormInputFile(),

));

$this->widgetSchema->setNameFormat('article[%s]');

}

}

class testActions extends sfActions
{

public function executeIndex($request)
{

$this->form = new TestForm?();
if ($request->isMethod('post'))
{

$this->form->bind($request->getParameter('article'), $request->getFiles('article'));
if ($this->form->isValid())
{

$file = $this->form->getValue('file');
$path = sfConfig::get('sf_web_dir').'/uploads/'.rand(1, 1000);
$extension = $file->getExtension($file->getOriginalExtension();

$file->save($path.'.'.$extension));

}

}

}

}

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.1/UPGRADE

    r6721 r6748  
    295295  * `->removeError()` 
    296296 
     297Deprecated methods in sfWebRequest 
     298---------------------------------- 
     299 
     300The following methods of `sfWebRequest` have been deprecated and throw 
     301a `sfConfigurationException` if `sf_compat_10` is set to `false`: 
     302 
     303  * `->getFile()` 
     304  * `->getFileError()` 
     305  * `->getFileName()` 
     306  * `->getFileNames()` 
     307  * `->getFilePath()` 
     308  * `->getFileSize()` 
     309  * `->getFileType()` 
     310  * `->hasFile()` 
     311  * `->hasFileError()` 
     312  * `->hasFileErrors()` 
     313  * `->hasFiles()` 
     314  * `->getFileValue()` 
     315  * `->getFileValues()` 
     316  * `->getFileExtension()` 
     317  * `->moveFile()` 
     318 
    297319sfValidator class 
    298320----------------- 
     
    358380--------------- 
    359381 
    360 The `sf_timeout` setting is not used anymore. To change the session timeout, you now have to edit the `factories.yml` instead if the `settings.yml`, and change the parameters of the `user` factory: 
     382The `sf_timeout` setting is not used anymore. To change the session timeout, you now have to edit the 
     383`factories.yml` instead if the `settings.yml`, and change the parameters of the `user` factory: 
    361384 
    362385    all: 
     
    365388        param: 
    366389          timeout:     1800     # session timeout in seconds 
    367  
  • branches/1.1/lib/form/sfForm.class.php

    r6670 r6748  
    3636    $isBound         = false, 
    3737    $taintedValues   = array(), 
     38    $taintedFiles    = array(), 
    3839    $values          = null, 
    3940    $defaults        = array(), 
     
    111112   * 
    112113   * @param array An array of input values 
    113    */ 
    114   public function bind($taintedValues) 
     114   * @param array An array of uploaded files (in the $_FILES or $_GET format) 
     115   */ 
     116  public function bind($taintedValues, $taintedFiles = array()) 
    115117  { 
    116118    $this->taintedValues = $taintedValues; 
     119    $this->taintedFiles  = $taintedFiles; 
    117120    $this->isBound = true; 
    118121    $this->resetFormFields(); 
     
    120123    try 
    121124    { 
    122       $this->values = $this->validatorSchema->clean($this->taintedValues); 
     125      $this->values = $this->validatorSchema->clean(array_merge($this->taintedValues, self::convertFileInformation($this->taintedFiles))); 
    123126      $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema); 
    124127 
     
    617620    } 
    618621  } 
     622 
     623  /** 
     624   * Converts uploaded file array to a format following the $_GET and $POST naming convention. 
     625   * 
     626   * It's safe to pass an already converted array, in which case this method just returns the original array unmodified. 
     627   * 
     628   * @param  array An array representing uploaded file information 
     629   * 
     630   * @return array An array of re-ordered uploaded file information 
     631   */ 
     632  static public function convertFileInformation($taintedFiles) 
     633  { 
     634    return self::pathsToArray(preg_replace('#^(/[^/]+)?(/name|/type|/tmp_name|/error|/size)([^\s]*)( = [^\n]*)#m', '$1$3$2$4', self::arrayToPaths($taintedFiles))); 
     635  } 
     636 
     637  /** 
     638   * Converts a string of paths separated by newlines into an array. 
     639   * 
     640   * Code adapted from http://www.shauninman.com/archive/2006/11/30/fixing_the_files_superglobal 
     641   * @author Shaun Inman (www.shauninman.com) 
     642   * 
     643   * @param  string A string representing an array 
     644   * 
     645   * @return Array  An array 
     646   */ 
     647  static public function pathsToArray($str) 
     648  { 
     649    $array = array(); 
     650    $lines = explode("\n", trim($str)); 
     651 
     652    if (!empty($lines[0])) 
     653    { 
     654      foreach ($lines as $line) 
     655      { 
     656        list($path, $value) = explode(' = ', $line); 
     657 
     658        $steps = explode('/', $path); 
     659        array_shift($steps); 
     660 
     661        $insertion =& $array; 
     662 
     663        foreach ($steps as $step) 
     664        { 
     665          if (!isset($insertion[$step])) 
     666          { 
     667            $insertion[$step] = array(); 
     668          } 
     669          $insertion =& $insertion[$step]; 
     670        } 
     671        $insertion = ctype_digit($value) ? (int) $value : $value; 
     672      } 
     673    } 
     674 
     675    return $array; 
     676  } 
     677 
     678  /** 
     679   * Converts an array into a string containing the path to each of its values separated by a newline. 
     680   * 
     681   * Code adapted from http://www.shauninman.com/archive/2006/11/30/fixing_the_files_superglobal 
     682   * @author Shaun Inman (www.shauninman.com) 
     683   * 
     684   * @param  Array  An array 
     685   * 
     686   * @return string A string representing the array 
     687   */ 
     688  static public function arrayToPaths($array = array(), $prefix = '') 
     689  { 
     690    $str = ''; 
     691    $freshPrefix = $prefix; 
     692 
     693    foreach ($array as $key => $value) 
     694    { 
     695      $freshPrefix .= "/{$key}"; 
     696 
     697      if (is_array($value)) 
     698      { 
     699        $str .= self::arrayToPaths($value, $freshPrefix); 
     700        $freshPrefix = $prefix; 
     701      } 
     702      else 
     703      { 
     704        $str .= "{$prefix}/{$key} = {$value}\n"; 
     705      } 
     706    } 
     707 
     708    return $str; 
     709  } 
    619710} 
  • branches/1.1/lib/request/sfRequest.class.php

    r5493 r6748  
    1212/** 
    1313 * sfRequest provides methods for manipulating client request information such 
    14  * as attributes, errors and parameters. It is also possible to manipulate the 
     14 * as attributes, and parameters. It is also possible to manipulate the 
    1515 * request method originally sent by the user. 
    1616 * 
  • branches/1.1/lib/request/sfWebRequest.class.php

    r6690 r6748  
    9595  public function getFile($name) 
    9696  { 
     97    if (!sfConfig::get('sf_compat_10')) 
     98    { 
     99      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     100    } 
     101 
    97102    return $this->hasFile($name) ? $this->getFileValues($name) : null; 
    98103  } 
     
    118123  public function getFileError($name) 
    119124  { 
     125    if (!sfConfig::get('sf_compat_10')) 
     126    { 
     127      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     128    } 
     129 
    120130    return $this->hasFile($name) ? $this->getFileValue($name, 'error') : UPLOAD_ERR_NO_FILE; 
    121131  } 
     
    130140  public function getFileName($name) 
    131141  { 
     142    if (!sfConfig::get('sf_compat_10')) 
     143    { 
     144      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     145    } 
     146 
    132147    return $this->hasFile($name) ? $this->getFileValue($name, 'name') : null; 
    133148  } 
     
    140155  public function getFileNames() 
    141156  { 
     157    if (!sfConfig::get('sf_compat_10')) 
     158    { 
     159      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     160    } 
     161 
    142162    return array_keys($_FILES); 
    143163  } 
     
    146166   * Retrieves an array of files. 
    147167   * 
    148    * @return array An associative array of files 
    149    */ 
    150   public function getFiles() 
    151   { 
    152     return $_FILES; 
     168   * @param  string A key 
     169   * @return array  An associative array of files 
     170   */ 
     171  public function getFiles($key = null) 
     172  { 
     173    return is_null($key) ? $_FILES : (isset($_FILES[$key]) ? $_FILES[$key] : array()); 
    153174  } 
    154175 
     
    162183  public function getFilePath($name) 
    163184  { 
     185    if (!sfConfig::get('sf_compat_10')) 
     186    { 
     187      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     188    } 
     189 
    164190    return $this->hasFile($name) ? $this->getFileValue($name, 'tmp_name') : null; 
    165191  } 
     
    174200  public function getFileSize($name) 
    175201  { 
     202    if (!sfConfig::get('sf_compat_10')) 
     203    { 
     204      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     205    } 
     206 
    176207    return $this->hasFile($name) ? $this->getFileValue($name, 'size') : null; 
    177208  } 
     
    189220  public function getFileType($name) 
    190221  { 
     222    if (!sfConfig::get('sf_compat_10')) 
     223    { 
     224      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     225    } 
     226 
    191227    return $this->hasFile($name) ? $this->getFileValue($name, 'type') : null; 
    192228  } 
     
    201237  public function hasFile($name) 
    202238  { 
     239    if (!sfConfig::get('sf_compat_10')) 
     240    { 
     241      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     242    } 
     243 
    203244    if (preg_match('/^(.+?)\[(.+?)\]$/', $name, $match)) 
    204245    { 
     
    220261  public function hasFileError($name) 
    221262  { 
     263    if (!sfConfig::get('sf_compat_10')) 
     264    { 
     265      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     266    } 
     267 
    222268    return $this->hasFile($name) ? ($this->getFileValue($name, 'error') != UPLOAD_ERR_OK) : false; 
    223269  } 
     
    230276  public function hasFileErrors() 
    231277  { 
     278    if (!sfConfig::get('sf_compat_10')) 
     279    { 
     280      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     281    } 
     282 
    232283    foreach ($this->getFileNames() as $name) 
    233284    { 
     
    248299  public function hasFiles() 
    249300  { 
     301    if (!sfConfig::get('sf_compat_10')) 
     302    { 
     303      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     304    } 
     305 
    250306    return (count($_FILES) > 0); 
    251307  } 
     
    261317  public function getFileValue($name, $key) 
    262318  { 
     319    if (!sfConfig::get('sf_compat_10')) 
     320    { 
     321      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     322    } 
     323 
    263324    if (preg_match('/^(.+?)\[(.+?)\]$/', $name, $match)) 
    264325    { 
     
    280341  public function getFileValues($name) 
    281342  { 
     343    if (!sfConfig::get('sf_compat_10')) 
     344    { 
     345      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     346    } 
     347 
    282348    if (preg_match('/^(.+?)\[(.+?)\]$/', $name, $match)) 
    283349    { 
     
    305371  public function getFileExtension($name) 
    306372  { 
     373    if (!sfConfig::get('sf_compat_10')) 
     374    { 
     375      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     376    } 
     377 
    307378    $fileType = $this->getFileType($name); 
    308379 
     
    312383    } 
    313384 
    314     $mimeTypes = unserialize(file_get_contents(sfConfig::get('sf_symfony_data_dir').'/data/mime_types.dat')); 
     385    $mimeTypes = unserialize(file_get_contents(sfConfig::get('sf_symfony_lib_dir').'/plugins/sfCompat10Plugin/data/mime_types.dat')); 
    315386 
    316387    return isset($mimeTypes[$fileType]) ? '.'.$mimeTypes[$fileType] : '.bin'; 
     
    451522  public function moveFile($name, $file, $fileMode = 0666, $create = true, $dirMode = 0777) 
    452523  { 
     524    if (!sfConfig::get('sf_compat_10')) 
     525    { 
     526      throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); 
     527    } 
     528 
    453529    if ($this->hasFile($name) && $this->getFileValue($name, 'error') == UPLOAD_ERR_OK && $this->getFileValue($name, 'size') > 0) 
    454530    { 
  • branches/1.1/test/unit/form/sfFormTest.php

    r6674 r6748  
    1111require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); 
    1212 
    13 $t = new lime_test(61, new lime_output_color()); 
     13$t = new lime_test(68, new lime_output_color()); 
    1414 
    1515class FormTest extends sfForm 
     
    212212  $t->is($w['authors'][$i][sfForm::getCSRFFieldName()], null, '->embedFormForEach() removes the CSRF token for the embedded forms'); 
    213213} 
     214 
     215// ::convertFileInformation() 
     216$t->diag('::convertFileInformation()'); 
     217$input = array( 
     218  'file' => array( 
     219    'name' => 'test1.txt', 
     220    'type' => 'text/plain', 
     221    'tmp_name' => '/tmp/test1.txt', 
     222    'error' => 0, 
     223    'size' => 100, 
     224  ), 
     225  'file1' => array( 
     226    'name' => 'test2.txt', 
     227    'type' => 'text/plain', 
     228    'tmp_name' => '/tmp/test1.txt', 
     229    'error' => 0, 
     230    'size' => 200, 
     231  ), 
     232); 
     233$t->is_deeply(sfForm::convertFileInformation($input), $input, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention'); 
     234 
     235$input = array( 
     236  'article' => array( 
     237    'name' => array( 
     238      'file1' => 'test1.txt', 
     239      'file2' => 'test2.txt', 
     240    ), 
     241    'type' => array( 
     242      'file1' => 'text/plain', 
     243      'file2' => 'text/plain', 
     244    ), 
     245    'tmp_name' => array( 
     246      'file1' => '/tmp/test1.txt', 
     247      'file2' => '/tmp/test2.txt', 
     248    ), 
     249    'error' => array( 
     250      'file1' => 0, 
     251      'file2' => 0, 
     252    ), 
     253    'size' => array( 
     254      'file1' => 100, 
     255      'file2' => 200, 
     256    ), 
     257  ), 
     258); 
     259$expected = array( 
     260  'article' => array( 
     261    'file1' => array( 
     262      'name' => 'test1.txt', 
     263      'type' => 'text/plain', 
     264      'tmp_name' => '/tmp/test1.txt', 
     265      'error' => 0, 
     266      'size' => 100, 
     267    ), 
     268    'file2' => array( 
     269      'name' => 'test2.txt', 
     270      'type' => 'text/plain', 
     271      'tmp_name' => '/tmp/test2.txt', 
     272      'error' => 0, 
     273      'size' => 200, 
     274    ), 
     275  ), 
     276); 
     277$t->is_deeply(sfForm::convertFileInformation($input), $expected, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention'); 
     278$t->is_deeply(sfForm::convertFileInformation($expected), $expected, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention'); 
     279 
     280$input = array( 
     281  'article' => array( 
     282    'name' => array( 
     283      'files' => array( 
     284        'file1' => 'test1.txt', 
     285        'file2' => 'test2.txt', 
     286      ), 
     287    ), 
     288    'type' => array( 
     289      'files' => array( 
     290        'file1' => 'text/plain', 
     291        'file2' => 'text/plain', 
     292      ), 
     293    ), 
     294    'tmp_name' => array( 
     295      'files' => array( 
     296        'file1' => '/tmp/test1.txt', 
     297        'file2' => '/tmp/test2.txt', 
     298      ), 
     299    ), 
     300    'error' => array( 
     301      'files' => array( 
     302        'file1' => 0, 
     303        'file2' => 0, 
     304      ), 
     305    ), 
     306    'size' => array( 
     307      'files' => array( 
     308        'file1' => 100, 
     309        'file2' => 200, 
     310      ), 
     311    ), 
     312  ), 
     313); 
     314$expected = array( 
     315  'article' => array( 
     316    'files' => array( 
     317      'file1' => array( 
     318        'name' => 'test1.txt', 
     319        'type' => 'text/plain', 
     320        'tmp_name' => '/tmp/test1.txt', 
     321        'error' => 0, 
     322        'size' => 100, 
     323      ), 
     324      'file2' => array( 
     325        'name' => 'test2.txt', 
     326        'type' => 'text/plain', 
     327        'tmp_name' => '/tmp/test2.txt', 
     328        'error' => 0, 
     329        'size' => 200, 
     330      ), 
     331    ) 
     332  ), 
     333); 
     334$t->is_deeply(sfForm::convertFileInformation($input), $expected, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention'); 
     335$t->is_deeply(sfForm::convertFileInformation($expected), $expected, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention'); 
     336 
     337$input = array( 
     338  'name' => array( 
     339    'file1' => 'test1.txt', 
     340    'file2' => 'test2.txt', 
     341  ), 
     342  'type' => array( 
     343    'file1' => 'text/plain', 
     344    'file2' => 'text/plain', 
     345  ), 
     346  'tmp_name' => array( 
     347    'file1' => '/tmp/test1.txt', 
     348    'file2' => '/tmp/test2.txt', 
     349  ), 
     350  'error' => array( 
     351    'file1' => 0, 
     352    'file2' => 0, 
     353  ), 
     354  'size' => array( 
     355    'file1' => 100, 
     356    'file2' => 200, 
     357  ), 
     358); 
     359$expected = array( 
     360  'file1' => array( 
     361    'name' => 'test1.txt', 
     362    'type' => 'text/plain', 
     363    'tmp_name' => '/tmp/test1.txt', 
     364    'error' => 0, 
     365    'size' => 100, 
     366  ), 
     367  'file2' => array( 
     368    'name' => 'test2.txt', 
     369    'type' => 'text/plain', 
     370    'tmp_name' => '/tmp/test2.txt', 
     371    'error' => 0, 
     372    'size' => 200, 
     373  ), 
     374); 
     375$t->is_deeply(sfForm::convertFileInformation($input), $expected, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention'); 
     376$t->is_deeply(sfForm::convertFileInformation($expected), $expected, '::convertFileInformation() converts $_FILES to be coherent with $_GET and $_POST naming convention');