Version: current

      1 <?php
      2 /**
      3  * A field that allows you to attach a file to a DataObject without submitting the form it is part of, through the use
      4  * of an iframe.
      5  *
      6  * If all you need is a simple file upload, it is reccomended you use {@link FileField}
      7  *
      8  * @package forms
      9  * @subpackage fields-files
     10  */
     11 class FileIFrameField extends FileField {
     12
     13     public static $allowed_actions = array (
     14         'iframe',
     15         'EditFileForm',
     16         'DeleteFileForm'
     17     );
     18
     19     /**
     20      * Flag that controls whether or not new files
     21      * can be uploaded by the user from their local computer.
     22      *
     23      * @var boolean
     24      */
     25     protected $canUploadNewFile = true;
     26
     27     /**
     28      * Индивидульаная максимальная ширина для изображения
     29      * Используется, если задано > 0, и наче - общее значение
     30      *
     31      * @var int
     32      */
     33     public $AutoresizeMaxWidth = 0;
     34
     35     /**
     36      * Индивидульаная максимальная высота для изображения
     37      * Используется, если задано > 0, и наче - общее значение
     38      *
     39      * @var int
     40      */
     41     public $AutoresizeMaxHeight = 0;
     42
     43     /**
     44      * Sets whether or not files can be uploaded into the CMS from the user's local computer
     45      * @param boolean $can
     46      */
     47     public function setCanUploadNewFile($can) {
     48         $this->canUploadNewFile = $can;
     49     }
     50
     51     /**
     52      * The data class that this field is editing.
     53      * @return string Class name
     54      */
     55     public function dataClass() {
     56         if($this->form && $this->form->getRecord()) {
     57             $class = $this->form->getRecord()->has_one($this->Name());
     58             return ($class) ? $class : 'File';
     59         } else {
     60             return 'File';
     61         }
     62     }
     63
     64     /**
     65      * @return string
     66      */
     67     public function Field() {
     68         if ($this->isReadonly()) {
     69             return ($this->AttachedFile() && $this->AttachedFile()->ID) ? $this->AttachedFile()->CMSThumbnail() : '';
     70         }
     71
     72         Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/base/jquery.ui.all.css');
     73         Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang');
     74         Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
     75         Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui-1.8rc3.custom.js');
     76
     77
     78         if($this->form->getRecord() && $this->form->getRecord()->exists()) {
     79             $record = $this->form->getRecord();
     80             if(Object::has_extension('SiteTree', 'Translatable') && $record->Locale){
     81                 $iframe = "iframe?locale={$record->Locale}&m=".time();
     82             }else{
     83                 $iframe = "iframe?m=".time();
     84             }
     85 file_put_contents(ASSETS_PATH . '/iframe.html', $this->createTag (
     86                 'iframe',
     87                 array (
     88                     'name'  => $this->Name() . '_iframe',
     89                     'src'   => Controller::join_links($this->Link(), $iframe),
     90                     'style' => 'height: 152px; width: 100%; border: none;'
     91                 ),
     92                 'vasya'
     93             ));
     94             return $this->createTag (
     95                 'iframe',
     96                 array (
     97                     'name'  => $this->Name() . '_iframe',
     98                     'src'   => Controller::join_links($this->Link(), $iframe),
     99                     'style' => 'height: 152px; width: 100%; border: none;'
    100                 )
    101             ) . $this->createTag (
    102                 'input',
    103                 array (
    104                     'type'  => 'hidden',
    105                     'id'    => $this->ID(),
    106                     'name'  => $this->Name() . 'ID',
    107                     'value' => $this->attrValue()
    108                 )
    109             );
    110         }
    111
    112         $this->setValue(sprintf(_t (
    113             'FileIFrameField.ATTACHONCESAVED', '%ss can be attached once you have saved the record for the first time.'
    114         ), $this->FileTypeName()));
    115
    116         return FormField::field();
    117     }
    118
    119     /**
    120      * Attempt to retreive a File object that has already been attached to this forms data record
    121      *
    122      * @return File|null
    123      */
    124     public function AttachedFile() {
    125         return $this->form->getRecord() ? $this->form->getRecord()->{$this->Name()}() : null;
    126     }
    127
    128     /**
    129      * @return string
    130      */
    131     public function iframe() {
    132         // clear the requirements added by any parent controllers
    133         Requirements::clear();
    134         Requirements::add_i18n_javascript('sapphire/javascript/lang');
    135         Requirements::javascript(THIRDPARTY_DIR . '/prototype/prototype.js');
    136         Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
    137         Requirements::javascript('sapphire/javascript/FileIFrameField.js');
    138
    139         Requirements::css('cms/css/typography.css');
    140         Requirements::css('sapphire/css/FileIFrameField.css');
    141
    142         return $this->renderWith('FileIFrameField_iframe');
    143     }
    144
    145     /**
    146      * @return Form
    147      */
    148     public function EditFileForm() {
    149         $uploadFile = _t('FileIFrameField.FROMCOMPUTER', 'From your Computer');
    150         $selectFile = _t('FileIFrameField.FROMFILESTORE', 'From the File Store');
    151
    152         if($this->AttachedFile() && $this->AttachedFile()->ID) {
    153             $title = sprintf(_t('FileIFrameField.REPLACE', 'Replace %s'), $this->FileTypeName());
    154         } else {
    155             $title = sprintf(_t('FileIFrameField.ATTACH', 'Attach %s'), $this->FileTypeName());
    156         }
    157
    158         $fileSources = array();
    159         if(singleton($this->dataClass())->canCreate()) {
    160             if($this->canUploadNewFile) {
    161                 $fileSources["new//$uploadFile"] = new FileField('Upload', '');
    162             }
    163         }
    164         // выставляем в дереве корневую папку, если указано
    165         $tdf = new TreeDropdownField('ExistingFile', '', 'File');
    166         $folderName = 'assets/' . $this->FolderName . '/';
    167         $fileFolder = DataObject::get_one('Folder', "Filename = '{$folderName}'");
    168         if ($fileFolder) {
    169             $tdf->setValue($fileFolder->ID);
    170         }
    171         $fileSources["existing//$selectFile"] = $tdf;
    172
    173         $fields = new FieldSet (
    174             new HeaderField('EditFileHeader', $title),
    175             new SelectionGroup('FileSource', $fileSources)
    176         );
    177
    178         // locale needs to be passed through from the iframe source
    179         if(isset($_GET['locale'])) {
    180             $fields->push(new HiddenField('locale', '', $_GET['locale']));
    181         }
    182
    183         return new Form (
    184             $this,
    185             'EditFileForm',
    186             $fields,
    187             new FieldSet(
    188                 new FormAction('save', $title)
    189             )
    190         );
    191     }
    192
    193     public function save($data, $form) {
    194         // check the user has entered all the required information
    195         if (
    196             !isset($data['FileSource'])
    197             || ($data['FileSource'] == 'new' && (!isset($_FILES['Upload']) || !$_FILES['Upload']))
    198             || ($data['FileSource'] == 'existing' && (!isset($data['ExistingFile']) || !$data['ExistingFile']))
    199         ) {
    200             $form->sessionMessage(_t('FileIFrameField.NOSOURCE', 'Please select a source file to attach'), 'required');
    201             Director::redirectBack();
    202             return;
    203         }
    204
    205         $desiredClass = $this->dataClass();
    206
    207         // upload a new file
    208         if($data['FileSource'] == 'new') {
    209             if (class_exists('ImageAutoResize')) {
    210                 $oldMaxSizes = ImageAutoResize::get_max_size();
    211                 $maxWidth = ($this->AutoresizeMaxWidth > 0) ? $this->AutoresizeMaxWidth : $oldMaxSizes['Width'];
    212                 $maxHeight = ($this->AutoresizeMaxHeight > 0) ? $this->AutoresizeMaxHeight : $oldMaxSizes['Height'];
    213                 ImageAutoResize::set_max_size($maxWidth, $maxHeight);
    214             }
    215
    216             $fileObject = Object::create($desiredClass);
    217
    218             $this->upload->loadIntoFile($_FILES['Upload'], $fileObject, $this->folderName);
    219
    220             if($this->upload->isError()) {
    221                 Director::redirectBack();
    222                 return;
    223             }
    224
    225             $this->form->getRecord()->{$this->Name() . 'ID'} = $fileObject->ID;
    226
    227             $fileObject->OwnerID = (Member::currentUser() ? Member::currentUser()->ID : 0);
    228             $fileObject->write();
    229             if (class_exists('ImageAutoResize')) {
    230                 ImageAutoResize::set_max_size($oldMaxSizes['Width'], $oldMaxSizes['Height']);
    231             }
    232         }
    233
    234         // attach an existing file from the assets store
    235         if($data['FileSource'] == 'existing') {
    236             $fileObject = DataObject::get_by_id('File', $data['ExistingFile']);
    237
    238             // dont allow the user to attach a folder by default
    239             if(!$fileObject || ($fileObject instanceof Folder && $desiredClass != 'Folder')) {
    240                 Director::redirectBack();
    241                 return;
    242             }
    243
    244             $this->form->getRecord()->{$this->Name() . 'ID'} = $fileObject->ID;
    245
    246             if(!$fileObject instanceof $desiredClass) {
    247                 $fileObject->ClassName = $desiredClass;
    248                 $fileObject->write();
    249             }
    250         }
    251
    252         $this->form->getRecord()->write();
    253         Director::redirectBack();
    254     }
    255
    256     /**
    257      * @return Form
    258      */
    259     public function DeleteFileForm() {
    260         $form = new Form (
    261             $this,
    262             'DeleteFileForm',
    263             new FieldSet (
    264                 new HiddenField('DeleteFile', null, false)
    265             ),
    266             new FieldSet (
    267                 $deleteButton = new FormAction (
    268                     'delete', sprintf(_t('FileIFrameField.DELETE', 'Delete %s'), $this->FileTypeName())
    269                 )
    270             )
    271         );
    272
    273         $deleteButton->addExtraClass('delete');
    274         return $form;
    275     }
    276
    277     public function delete($data, $form) {
    278         // delete the actual file, or just un-attach it?
    279         if(isset($data['DeleteFile']) && $data['DeleteFile']) {
    280             $file = DataObject::get_by_id('File', $this->form->getRecord()->{$this->Name() . 'ID'});
    281
    282             if($file) {
    283                 $file->delete();
    284             }
    285         }
    286
    287         // then un-attach file from this record
    288         $this->form->getRecord()->{$this->Name() . 'ID'} = 0;
    289         $this->form->getRecord()->write();
    290
    291         Director::redirectBack();
    292     }
    293
    294     /**
    295      * Get the type of file this field is used to attach (e.g. File, Image)
    296      *
    297      * @return string
    298      */
    299     public function FileTypeName() {
    300         return _t('FileIFrameField.FILE', 'File');
    301     }
    302
    303 }
    304

[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. -