Ejemplo n.º 1
0
 /**
  * Create an object from a string representation.  It treats it as a PHP constructor without the
  * 'new' keyword.  It also manages to construct the object without the use of eval().
  *
  * Construction itself is done with Object::create(), so that Object::useCustomClass() calls
  * are respected.
  *
  * `Object::create_from_string("Versioned('Stage','Live')")` will return the result of
  * `Versioned::create('Stage', 'Live);`
  *
  * It is designed for simple, cloneable objects.  The first time this method is called for a given
  * string it is cached, and clones of that object are returned.
  *
  * If you pass the $firstArg argument, this will be prepended to the constructor arguments. It's
  * impossible to pass null as the firstArg argument.
  *
  * `Object::create_from_string("Varchar(50)", "MyField")` will return the result of
  * `Varchar::create('MyField', '50');`
  *
  * Arguments are always strings, although this is a quirk of the current implementation rather
  * than something that can be relied upon.
  *
  * @param string $classSpec
  * @param mixed $firstArg
  * @return object
  */
 public static function create_from_string($classSpec, $firstArg = null)
 {
     if (!isset(self::$_cache_inst_args[$classSpec . $firstArg])) {
         // an $extension value can contain parameters as a string,
         // e.g. "Versioned('Stage','Live')"
         if (strpos($classSpec, '(') === false) {
             if ($firstArg === null) {
                 self::$_cache_inst_args[$classSpec . $firstArg] = Object::create($classSpec);
             } else {
                 self::$_cache_inst_args[$classSpec . $firstArg] = Object::create($classSpec, $firstArg);
             }
         } else {
             list($class, $args) = self::parse_class_spec($classSpec);
             if ($firstArg !== null) {
                 array_unshift($args, $firstArg);
             }
             array_unshift($args, $class);
             self::$_cache_inst_args[$classSpec . $firstArg] = call_user_func_array(array('SilverStripe\\Core\\Object', 'create'), $args);
         }
     }
     return clone self::$_cache_inst_args[$classSpec . $firstArg];
 }
 /**
  * @param DataObject|DataObjectInterface $record
  */
 public function saveInto(DataObjectInterface $record)
 {
     if (!isset($_FILES[$this->name])) {
         return;
     }
     $fileClass = File::get_class_for_file_extension(File::get_file_extension($_FILES[$this->name]['name']));
     /** @var File $file */
     if ($this->relationAutoSetting) {
         // assume that the file is connected via a has-one
         $objectClass = DataObject::getSchema()->hasOneComponent(get_class($record), $this->name);
         if ($objectClass === File::class || empty($objectClass)) {
             // Create object of the appropriate file class
             $file = Object::create($fileClass);
         } else {
             // try to create a file matching the relation
             $file = Object::create($objectClass);
         }
     } else {
         if ($record instanceof File) {
             $file = $record;
         } else {
             $file = Object::create($fileClass);
         }
     }
     $this->upload->loadIntoFile($_FILES[$this->name], $file, $this->getFolderName());
     if ($this->upload->isError()) {
         return;
     }
     if ($this->relationAutoSetting) {
         if (empty($objectClass)) {
             return;
         }
         $file = $this->upload->getFile();
         $record->{$this->name . 'ID'} = $file->ID;
     }
 }
Ejemplo n.º 3
0
 /**
  * Create a DBField object that's not bound to any particular field.
  *
  * Useful for accessing the classes behaviour for other parts of your code.
  *
  * @param string $className class of field to construct
  * @param mixed $value value of field
  * @param string $name Name of field
  * @param mixed $object Additional parameter to pass to field constructor
  * @return DBField
  */
 public static function create_field($className, $value, $name = null, $object = null)
 {
     /** @var DBField $dbField */
     $dbField = Object::create($className, $name, $object);
     $dbField->setValue($value, null, false);
     return $dbField;
 }
 /**
  * Loads the temporary file data into a File object
  *
  * @param array $tmpFile Temporary file data
  * @param string $error Error message
  * @return AssetContainer File object, or null if error
  */
 protected function saveTemporaryFile($tmpFile, &$error = null)
 {
     // Determine container object
     $error = null;
     $fileObject = null;
     if (empty($tmpFile)) {
         $error = _t('UploadField.FIELDNOTSET', 'File information not found');
         return null;
     }
     if ($tmpFile['error']) {
         $error = $tmpFile['error'];
         return null;
     }
     // Search for relations that can hold the uploaded files, but don't fallback
     // to default if there is no automatic relation
     if ($relationClass = $this->getRelationAutosetClass(null)) {
         // Allow File to be subclassed
         if ($relationClass === 'SilverStripe\\Assets\\File' && isset($tmpFile['name'])) {
             $relationClass = File::get_class_for_file_extension(File::get_file_extension($tmpFile['name']));
         }
         // Create new object explicitly. Otherwise rely on Upload::load to choose the class.
         $fileObject = Object::create($relationClass);
         if (!$fileObject instanceof DataObject || !$fileObject instanceof AssetContainer) {
             throw new InvalidArgumentException("Invalid asset container {$relationClass}");
         }
     }
     // Get the uploaded file into a new file object.
     try {
         $this->upload->loadIntoFile($tmpFile, $fileObject, $this->getFolderName());
     } catch (Exception $e) {
         // we shouldn't get an error here, but just in case
         $error = $e->getMessage();
         return null;
     }
     // Check if upload field has an error
     if ($this->upload->isError()) {
         $error = implode(' ' . PHP_EOL, $this->upload->getErrors());
         return null;
     }
     // return file
     return $this->upload->getFile();
 }
 /**
  *
  * @param GridField $gridField
  * @param HTTPRequest $request
  * @return GridFieldDetailForm_ItemRequest
  */
 public function handleItem($gridField, $request)
 {
     // Our getController could either give us a true Controller, if this is the top-level GridField.
     // It could also give us a RequestHandler in the form of GridFieldDetailForm_ItemRequest if this is a
     // nested GridField.
     $requestHandler = $gridField->getForm()->getController();
     /** @var DataObject $record */
     if (is_numeric($request->param('ID'))) {
         $record = $gridField->getList()->byID($request->param("ID"));
     } else {
         $record = Object::create($gridField->getModelClass());
     }
     $handler = $this->getItemRequestHandler($gridField, $record, $requestHandler);
     // if no validator has been set on the GridField and the record has a
     // CMS validator, use that.
     if (!$this->getValidator() && (method_exists($record, 'getCMSValidator') || $record instanceof Object && $record->hasMethod('getCMSValidator'))) {
         $this->setValidator($record->getCMSValidator());
     }
     return $handler->handleRequest($request, DataModel::inst());
 }
Ejemplo n.º 6
0
 /**
  * Given a file and filename, ensure that file renaming / replacing rules are satisfied
  *
  * If replacing, this method may replace $this->file with an existing record to overwrite.
  * If renaming, a new value for $filename may be returned
  *
  * @param string $filename
  * @return string $filename A filename safe to write to
  * @throws Exception
  */
 protected function resolveExistingFile($filename)
 {
     // Create a new file record (or try to retrieve an existing one)
     if (!$this->file) {
         $fileClass = File::get_class_for_file_extension(File::get_file_extension($filename));
         $this->file = Object::create($fileClass);
     }
     // Skip this step if not writing File dataobjects
     if (!$this->file instanceof File) {
         return $filename;
     }
     // Check there is if existing file
     $existing = File::find($filename);
     // If replacing (or no file exists) confirm this filename is safe
     if ($this->replaceFile || !$existing) {
         // If replacing files, make sure to update the OwnerID
         if (!$this->file->ID && $this->replaceFile && $existing) {
             $this->file = $existing;
             $this->file->OwnerID = Member::currentUserID();
         }
         // Filename won't change if replacing
         return $filename;
     }
     // if filename already exists, version the filename (e.g. test.gif to test-v2.gif, test-v2.gif to test-v3.gif)
     $renamer = $this->getNameGenerator($filename);
     foreach ($renamer as $newName) {
         if (!File::find($newName)) {
             return $newName;
         }
     }
     // Fail
     $tries = $renamer->getMaxTries();
     throw new Exception("Could not rename {$filename} with {$tries} tries");
 }
 /**
  * Gets the form fields as defined through the metadata
  * on {@link $obj} and the custom parameters passed to FormScaffolder.
  * Depending on those parameters, the fields can be used in ajax-context,
  * contain {@link TabSet}s etc.
  *
  * @return FieldList
  */
 public function getFieldList()
 {
     $fields = new FieldList();
     // tabbed or untabbed
     if ($this->tabbed) {
         $fields->push(new TabSet("Root", $mainTab = new Tab("Main")));
         $mainTab->setTitle(_t('SiteTree.TABMAIN', "Main"));
     }
     // Add logical fields directly specified in db config
     foreach ($this->obj->config()->db as $fieldName => $fieldType) {
         // Skip restricted fields
         if ($this->restrictFields && !in_array($fieldName, $this->restrictFields)) {
             continue;
         }
         // @todo Pass localized title
         if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
             $fieldClass = $this->fieldClasses[$fieldName];
             $fieldObject = new $fieldClass($fieldName);
         } else {
             $fieldObject = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
         }
         // Allow fields to opt-out of scaffolding
         if (!$fieldObject) {
             continue;
         }
         $fieldObject->setTitle($this->obj->fieldLabel($fieldName));
         if ($this->tabbed) {
             $fields->addFieldToTab("Root.Main", $fieldObject);
         } else {
             $fields->push($fieldObject);
         }
     }
     // add has_one relation fields
     if ($this->obj->hasOne()) {
         foreach ($this->obj->hasOne() as $relationship => $component) {
             if ($this->restrictFields && !in_array($relationship, $this->restrictFields)) {
                 continue;
             }
             $fieldName = $component === 'SilverStripe\\ORM\\DataObject' ? $relationship : "{$relationship}ID";
             if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
                 $fieldClass = $this->fieldClasses[$fieldName];
                 $hasOneField = new $fieldClass($fieldName);
             } else {
                 $hasOneField = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
             }
             if (empty($hasOneField)) {
                 continue;
             }
             // Allow fields to opt out of scaffolding
             $hasOneField->setTitle($this->obj->fieldLabel($relationship));
             if ($this->tabbed) {
                 $fields->addFieldToTab("Root.Main", $hasOneField);
             } else {
                 $fields->push($hasOneField);
             }
         }
     }
     // only add relational fields if an ID is present
     if ($this->obj->ID) {
         // add has_many relation fields
         if ($this->obj->hasMany() && ($this->includeRelations === true || isset($this->includeRelations['has_many']))) {
             foreach ($this->obj->hasMany() as $relationship => $component) {
                 if ($this->tabbed) {
                     $fields->findOrMakeTab("Root.{$relationship}", $this->obj->fieldLabel($relationship));
                 }
                 $fieldClass = isset($this->fieldClasses[$relationship]) ? $this->fieldClasses[$relationship] : 'SilverStripe\\Forms\\GridField\\GridField';
                 /** @var GridField $grid */
                 $grid = Object::create($fieldClass, $relationship, $this->obj->fieldLabel($relationship), $this->obj->{$relationship}(), GridFieldConfig_RelationEditor::create());
                 if ($this->tabbed) {
                     $fields->addFieldToTab("Root.{$relationship}", $grid);
                 } else {
                     $fields->push($grid);
                 }
             }
         }
         if ($this->obj->manyMany() && ($this->includeRelations === true || isset($this->includeRelations['many_many']))) {
             foreach ($this->obj->manyMany() as $relationship => $component) {
                 if ($this->tabbed) {
                     $fields->findOrMakeTab("Root.{$relationship}", $this->obj->fieldLabel($relationship));
                 }
                 $fieldClass = isset($this->fieldClasses[$relationship]) ? $this->fieldClasses[$relationship] : 'SilverStripe\\Forms\\GridField\\GridField';
                 /** @var GridField $grid */
                 $grid = Object::create($fieldClass, $relationship, $this->obj->fieldLabel($relationship), $this->obj->{$relationship}(), GridFieldConfig_RelationEditor::create());
                 if ($this->tabbed) {
                     $fields->addFieldToTab("Root.{$relationship}", $grid);
                 } else {
                     $fields->push($grid);
                 }
             }
         }
     }
     return $fields;
 }