Version: current

      1 <?php
      2 /**
      3  * Represents a file type which can be added to a form.
      4  * Automatically tries to save has_one-relations on the saved
      5  * record.
      6  *
      7  * Please set a validator on the form-object to get feedback
      8  * about imposed filesize/extension restrictions.
      9  *
     10  * CAUTION: Doesn't work in the CMS due to ajax submission, please use {@link FileIFrameField} instead.
     11  *
     12  * @package forms
     13  * @subpackage fields-files
     14  */
     15 class FileField extends FormField {
     16
     17     /**
     18      * Restrict filesize for either all filetypes
     19      * or a specific extension, with extension-name
     20      * as array-key and the size-restriction in bytes as array-value.
     21      *
     22      * @deprecated 2.5
     23      * @var array
     24      */
     25     public $allowedMaxFileSize = array();
     26
     27     /**
     28      * @var array Collection of extensions.
     29      * Extension-names are treated case-insensitive.
     30      *
     31      * Example:
     32      * <code>
     33      *  array("jpg","GIF")
     34      * </code>
     35      */
     36     public $allowedExtensions = array();
     37
     38     /**
     39      * Flag to automatically determine and save a has_one-relationship
     40      * on the saved record (e.g. a "Player" has_one "PlayerImage" would
     41      * trigger saving the ID of newly created file into "PlayerImageID"
     42      * on the record).
     43      *
     44      * @var boolean
     45      */
     46     public $relationAutoSetting = true;
     47
     48     /**
     49      * Upload object (needed for validation
     50      * and actually moving the temporary file
     51      * created by PHP).
     52      *
     53      * @var Upload
     54      */
     55     protected $upload;
     56
     57     /**
     58      * Partial filesystem path relative to /assets directory.
     59      * Defaults to 'Uploads'.
     60      *
     61      * @var string
     62      */
     63     protected $folderName = 'Uploads';
     64
     65     /**
     66      * Create a new file field.
     67      *
     68      * @param string $name The internal field name, passed to forms.
     69      * @param string $title The field label.
     70      * @param int $value The value of the field.
     71      * @param Form $form Reference to the container form
     72      * @param string $rightTitle Used in SmallFieldHolder() to force a right-aligned label
     73      * @param string $folderName Folder to upload files to
     74      */
     75     function __construct($name, $title = null, $value = null, $form = null, $rightTitle = null, $folderName = null) {
     76         if(isset($folderName)) $this->folderName = $folderName;
     77         $this->upload = new Upload();
     78
     79         parent::__construct($name, $title, $value, $form, $rightTitle);
     80     }
     81
     82     public function Field() {
     83         if ($this->isReadonly()) {
     84             if ($this->form->getRecord()) {
     85                 $file = $this->form->getRecord()->{$this->Name()}();
     86                 if ($file->ID) return $file->CMSThumbnail();
     87             }
     88             return '';
     89         }
     90
     91         return $this->createTag(
     92             'input',
     93             array(
     94                 "type" => "file",
     95                 "name" => $this->name,
     96                 "id" => $this->id(),
     97                 "tabindex" => $this->getTabIndex()
     98             )
     99         ) .
    100         $this->createTag(
    101             'input',
    102             array(
    103                 "type" => "hidden",
    104                 "name" => "MAX_FILE_SIZE",
    105                 "value" => $this->getValidator()->getAllowedMaxFileSize(),
    106                 "tabindex" => $this->getTabIndex()
    107             )
    108         );
    109     }
    110
    111     public function saveInto(DataObject $record) {
    112         if(!isset($_FILES[$this->name])) return false;
    113
    114         if($this->relationAutoSetting) {
    115             // assume that the file is connected via a has-one
    116             $hasOnes = $record->has_one($this->name);
    117             // try to create a file matching the relation
    118             $file = (is_string($hasOnes)) ? Object::create($hasOnes) : new File();
    119         } else {
    120             $file = new File();
    121         }
    122
    123         $this->upload->loadIntoFile($_FILES[$this->name], $file, $this->folderName);
    124         if($this->upload->isError()) return false;
    125
    126         $file = $this->upload->getFile();
    127
    128         if($this->relationAutoSetting) {
    129             if(!$hasOnes) return false;
    130
    131             // save to record
    132             $record->{$this->name . 'ID'} = $file->ID;
    133         }
    134     }
    135
    136     public function Value() {
    137         return $_FILES[$this->Name()];
    138     }
    139
    140     /**
    141      * Get custom validator for this field
    142      *
    143      * @param object $validator
    144      */
    145     public function getValidator() {
    146         return $this->upload->getValidator();
    147     }
    148
    149     /**
    150      * Set custom validator for this field
    151      *
    152      * @param object $validator
    153      */
    154     public function setValidator($validator) {
    155         $this->upload->setValidator($validator);
    156     }
    157
    158     /**
    159      * Get maximum file size for all or specified file extension.
    160      * Falls back to the default filesize restriction ('*')
    161      * if the extension was not found.
    162      *
    163      * @deprecated 2.5
    164      * @param string $ext
    165      * @return int Filesize in bytes (0 means no filesize set)
    166      */
    167     public function getAllowedMaxFileSize($ext = null) {
    168         user_error('Upload::getAllowedMaxFileSize() is deprecated. Please use Upload_Validator::getAllowedMaxFileSize() instead', E_USER_NOTICE);
    169         $this->getValidator()->getAllowedMaxFileSize($ext);
    170     }
    171
    172     /**
    173      * Set filesize maximums (in bytes).
    174      * Automatically converts extensions to lowercase
    175      * for easier matching.
    176      *
    177      * Example:
    178      * <code>
    179      * array('*' => 200, 'jpg' => 1000)
    180      * </code>
    181      *
    182      * @deprecated 2.5
    183      * @param unknown_type $rules
    184      */
    185     public function setAllowedMaxFileSize($rules) {
    186         user_error('Upload::setAllowedMaxFileSize() is deprecated. Please use Upload_Validator::setAllowedMaxFileSize() instead', E_USER_NOTICE);
    187         $this->getValidator()->setAllowedMaxFileSize($rules);
    188     }
    189
    190     /**
    191      * @deprecated 2.5
    192      * @return array
    193      */
    194     public function getAllowedExtensions() {
    195         user_error('Upload::getAllowedExtensions() is deprecated. Please use Upload_Validator::getAllowedExtensions() instead', E_USER_NOTICE);
    196         return $this->getValidator()->getAllowedExtensions();
    197     }
    198
    199     /**
    200      * @deprecated 2.5
    201      * @param array $rules
    202      */
    203     public function setAllowedExtensions($rules) {
    204         user_error('Upload::setAllowedExtensions() is deprecated. Please use Upload_Validator::setAllowedExtensions() instead', E_USER_NOTICE);
    205         $this->getValidator()->setAllowedExtensions($rules);
    206     }
    207
    208     /**
    209      * @param string $folderName
    210      */
    211     public function setFolderName($folderName) {
    212         $this->folderName = $folderName;
    213     }
    214
    215     /**
    216      * @return string
    217      */
    218     public function getFolderName() {
    219         return $this->folderName;
    220     }
    221
    222     public function validate($validator) {
    223         if(!isset($_FILES[$this->name])) return true;
    224
    225         $tmpFile = $_FILES[$this->name];
    226
    227         $valid = $this->upload->validate($tmpFile);
    228         if(!$valid) {
    229             $errors = $this->upload->getErrors();
    230             if($errors) foreach($errors as $error) {
    231                 $validator->validationError($this->name, $error, "validation", false);
    232             }
    233             return false;
    234         }
    235
    236         return true;
    237     }
    238     /**
    239      * Returns a readonly version of this field.
    240      */
    241     function performReadonlyTransformation() {
    242         $clone = clone $this;
    243         $clone->setReadonly(true);
    244         return $clone;
    245     }
    246 }
    247 ?>

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -