/** * A key value pair of values that should be searched for. * The keys should match the field names specified in {@link self::$fields}. * Usually these values come from a submitted searchform * in the form of a $_REQUEST object. * CAUTION: All values should be treated as insecure client input. * * @param string $modelClass The base {@link DataObject} class that search properties related to. * Also used to generate a set of result objects based on this class. * @param FieldList $fields Optional. FormFields mapping to {@link DataObject::$db} properties * which are to be searched. Derived from modelclass using * {@link DataObject::scaffoldSearchFields()} if left blank. * @param array $filters Optional. Derived from modelclass if left blank */ public function __construct($modelClass, $fields = null, $filters = null) { $this->modelClass = $modelClass; $this->fields = $fields ? $fields : new FieldList(); $this->filters = $filters ? $filters : array(); parent::__construct(); }
public function __construct($content) { if (extension_loaded('tidy')) { // using the tidy php extension $tidy = new tidy(); $tidy->parseString($content, array('output-xhtml' => true, 'numeric-entities' => true, 'wrap' => 0), 'utf8'); $tidy->cleanRepair(); $tidy = str_replace('xmlns="http://www.w3.org/1999/xhtml"', '', $tidy); $tidy = str_replace(' ', '', $tidy); } elseif (@shell_exec('which tidy')) { // using tiny through cli $CLI_content = escapeshellarg($content); $tidy = `echo {$CLI_content} | tidy --force-output 1 -n -q -utf8 -asxhtml -w 0 2> /dev/null`; $tidy = str_replace('xmlns="http://www.w3.org/1999/xhtml"', '', $tidy); $tidy = str_replace(' ', '', $tidy); } else { // no tidy library found, hence no sanitizing $tidy = $content; } $this->simpleXML = @simplexml_load_string($tidy, 'SimpleXMLElement', LIBXML_NOWARNING); if (!$this->simpleXML) { throw new Exception('CSSContentParser::__construct(): Could not parse content.' . ' Please check the PHP extension tidy is installed.'); } parent::__construct(); }
/** * * @param integer $currentID - The ID of the current item; this button will find that item's parent */ public function __construct($currentID) { parent::__construct(); if ($currentID && is_numeric($currentID)) { $this->currentID = $currentID; } }
/** * @param $locale */ public function __construct($locale = null) { $this->defaultLocale = $locale ? $locale : i18n::get_lang_from_locale(i18n::config()->get('default_locale')); $this->basePath = Director::baseFolder(); $this->baseSavePath = Director::baseFolder(); parent::__construct(); }
/** * Create a new ValidationResult. * By default, it is a successful result. Call $this->error() to record errors. * * @param bool $valid * @param string $message */ public function __construct($valid = true, $message = null) { $this->isValid = $valid; if ($message) { $this->errorList[] = $message; } parent::__construct(); }
public function __construct(AssetContainer $assetContainer = null) { parent::__construct(); $this->cache = Cache::factory('GDBackend_Manipulations'); if ($assetContainer) { $this->loadFromContainer($assetContainer); } }
/** * Create a new CMS Menu Item * * @param string $title * @param string $url * @param string $controller Controller class name * @param integer $priority The sort priority of the item */ public function __construct($title, $url, $controller = null, $priority = -1) { $this->title = $title; $this->url = $url; $this->controller = $controller; $this->priority = $priority; parent::__construct(); }
public function __construct() { $this->options = array(); $class = get_class($this); // We build our options array ourselves, because possibly no class or config manifest exists at this point do { $this->options = array_merge(Object::static_lookup($class, 'default_options'), $this->options); } while ($class = get_parent_class($class)); }
/** * @param string $fullName Determines the name of the field, as well as the searched database * column. Can contain a relation name in dot notation, which will automatically join * the necessary tables (e.g. "Comments.Name" to join the "Comments" has-many relationship and * search the "Name" column when applying this filter to a SiteTree class). * @param mixed $value * @param array $modifiers */ public function __construct($fullName = null, $value = false, array $modifiers = array()) { parent::__construct(); $this->fullName = $fullName; // sets $this->name and $this->relation $this->addRelation($fullName); $this->value = $value; $this->setModifiers($modifiers); }
/** * @param array $config The configuration for the cleaner, if necessary */ public function __construct($config = null) { parent::__construct(); if ($config) { $config = array_merge($this->defaultConfig, $config); } else { $config = $this->defaultConfig; } $this->setConfig($config); }
public function testExtraFieldsViaExtension() { // This extends ManyManyListTest_Secondary with the secondary extension that adds the relationship back // to the primary. The instance from the fixture is ManyManyListTest_SecondarySub, deliberately a sub-class of // the extended class. Object::add_extension('ManyManyListTest_Secondary', 'ManyManyListTest_IndirectSecondaryExtension'); // Test from the primary (not extended) to the secondary (which is extended) $primary = $this->objFromFixture('ManyManyListTest_IndirectPrimary', 'manymany_extra_primary'); $secondaries = $primary->Secondary(); $extraFields = $secondaries->getExtraFields(); $this->assertTrue(count($extraFields) > 0, 'has extra fields'); $this->assertTrue(isset($extraFields['DocumentSort']), 'has DocumentSort'); // Test from the secondary (which is extended) to the primary (not extended) $secondary = $this->objFromFixture('ManyManyListTest_SecondarySub', 'manymany_extra_secondary'); $primaries = $secondary->Primary(); $extraFields = $primaries->getExtraFields(); $this->assertTrue(count($extraFields) > 0, 'has extra fields'); $this->assertTrue(isset($extraFields['DocumentSort']), 'has DocumentSort'); }
/** * 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]; }
/** * 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(); }
/** * Get a db object for the named field * * @param string $field Field name * @return DBField|null */ public function dbObject($field) { $fields = $this->compositeDatabaseFields(); if (!isset($fields[$field])) { return null; } // Build nested field $key = $this->getName() . $field; $spec = $fields[$field]; /** @var DBField $fieldObject */ $fieldObject = Object::create_from_string($spec, $key); $fieldObject->setValue($this->getField($field), null, false); return $fieldObject; }
/** * * @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()); }
/** * @param DateField $field */ public function __construct($field) { parent::__construct(); $this->field = $field; }
/** * Safely get a DataObject from a client-supplied ID and ClassName, checking: argument * validity; existence; and canView permissions. * * @param int $id The ID of the DataObject * @param string $class The Class of the DataObject * @return DataObject The referenced DataObject * @throws HTTPResponse_Exception */ protected function getObject($id, $class) { $id = (int) $id; $class = ClassInfo::class_name($class); if (!$class || !is_subclass_of($class, 'SilverStripe\\ORM\\DataObject') || !Object::has_extension($class, 'SilverStripe\\ORM\\Versioning\\Versioned')) { $this->controller->httpError(400, _t('AddToCampaign.ErrorGeneral', 'We apologise, but there was an error')); return null; } $object = DataObject::get($class)->byID($id); if (!$object) { $this->controller->httpError(404, _t('AddToCampaign.ErrorNotFound', 'That {Type} couldn\'t be found', '', ['Type' => $class])); return null; } if (!$object->canView()) { $this->controller->httpError(403, _t('AddToCampaign.ErrorItemPermissionDenied', 'It seems you don\'t have the necessary permissions to add {ObjectTitle} to a campaign', '', ['ObjectTitle' => $object->Title])); return null; } return $object; }
public function create($class, array $params = array()) { if (strpos($class, '(') === false) { return parent::create($class, $params); } else { list($class, $params) = Object::parse_class_spec($class); $params = $this->injector->convertServiceProperty($params); return parent::create($class, $params); } }
/** * @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; } }
public static function get_extra_config_sources($class = null) { if ($class === null) { $class = get_called_class(); } // If this class is unextendable, NOP if (in_array($class, self::$unextendable_classes)) { return null; } // Variable to hold sources in $sources = null; // Get a list of extensions $extensions = Config::inst()->get($class, 'extensions', Config::UNINHERITED | Config::EXCLUDE_EXTRA_SOURCES); if (!$extensions) { return null; } // Build a list of all sources; $sources = array(); foreach ($extensions as $extension) { list($extensionClass, $extensionArgs) = Object::parse_class_spec($extension); $sources[] = $extensionClass; if (!class_exists($extensionClass)) { throw new InvalidArgumentException("{$class} references nonexistent {$extensionClass} in \$extensions"); } call_user_func(array($extensionClass, 'add_to_class'), $class, $extensionClass, $extensionArgs); foreach (array_reverse(ClassInfo::ancestry($extensionClass)) as $extensionClassParent) { if (ClassInfo::has_method_from($extensionClassParent, 'get_extra_config', $extensionClassParent)) { $extras = $extensionClassParent::get_extra_config($class, $extensionClass, $extensionArgs); if ($extras) { $sources[] = $extras; } } } } return $sources; }
/** * Get the value of a field on this object, automatically inserting the value into any available casting objects * that have been specified. * * @param string $fieldName * @param array $arguments * @param bool $cache Cache this object * @param string $cacheName a custom cache name * @return Object|DBField */ public function obj($fieldName, $arguments = [], $cache = false, $cacheName = null) { if (!$cacheName && $cache) { $cacheName = $this->objCacheName($fieldName, $arguments); } // Check pre-cached value $value = $cache ? $this->objCacheGet($cacheName) : null; if ($value !== null) { return $value; } // Load value from record if ($this->hasMethod($fieldName)) { $value = call_user_func_array(array($this, $fieldName), $arguments ?: []); } else { $value = $this->{$fieldName}; } // Cast object if (!is_object($value)) { // Force cast $castingHelper = $this->castingHelper($fieldName); $valueObject = Object::create_from_string($castingHelper, $fieldName); $valueObject->setValue($value, $this); $value = $valueObject; } // Record in cache if ($cache) { $this->objCacheSet($cacheName, $value); } return $value; }
public function testExtendedCan() { $extensions = $this->removeExtensions(Object::get_extensions('SilverStripe\\Security\\Member')); $member = $this->objFromFixture('SilverStripe\\Security\\Member', 'test'); /* Normal behaviour is that you can't view a member unless canView() on an extension returns true */ $this->assertFalse($member->canView()); $this->assertFalse($member->canDelete()); $this->assertFalse($member->canEdit()); /* Apply a extension that allows viewing in any case (most likely the case for member profiles) */ Member::add_extension('MemberTest_ViewingAllowedExtension'); $member2 = $this->objFromFixture('SilverStripe\\Security\\Member', 'staffmember'); $this->assertTrue($member2->canView()); $this->assertFalse($member2->canDelete()); $this->assertFalse($member2->canEdit()); /* Apply a extension that denies viewing of the Member */ Member::remove_extension('MemberTest_ViewingAllowedExtension'); Member::add_extension('MemberTest_ViewingDeniedExtension'); $member3 = $this->objFromFixture('SilverStripe\\Security\\Member', 'managementmember'); $this->assertFalse($member3->canView()); $this->assertFalse($member3->canDelete()); $this->assertFalse($member3->canEdit()); /* Apply a extension that allows viewing and editing but denies deletion */ Member::remove_extension('MemberTest_ViewingDeniedExtension'); Member::add_extension('MemberTest_EditingAllowedDeletingDeniedExtension'); $member4 = $this->objFromFixture('SilverStripe\\Security\\Member', 'accountingmember'); $this->assertTrue($member4->canView()); $this->assertFalse($member4->canDelete()); $this->assertTrue($member4->canEdit()); Member::remove_extension('MemberTest_EditingAllowedDeletingDeniedExtension'); $this->addExtensions($extensions); }
/** * 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; }
/** * Helper method for applicablePages() methods. Acts as a skeleton implementation. * * @param array $ids The IDs passed to applicablePages * @param string $methodName The canXXX() method to call on each page to check if the action is applicable * @param bool $checkStagePages Set to true if you want to check stage pages * @param bool $checkLivePages Set to true if you want to check live pages (e.g, for deleted-from-draft) * @return array */ public function applicablePagesHelper($ids, $methodName, $checkStagePages = true, $checkLivePages = true) { if (!is_array($ids)) { user_error("Bad \$ids passed to applicablePagesHelper()", E_USER_WARNING); } if (!is_string($methodName)) { user_error("Bad \$methodName passed to applicablePagesHelper()", E_USER_WARNING); } $applicableIDs = array(); $managedClass = $this->managedClass; $draftPages = DataObject::get($managedClass)->byIDs($ids); // Filter out the live-only ids $onlyOnLive = array_fill_keys($ids, true); if ($checkStagePages) { foreach ($draftPages as $obj) { unset($onlyOnLive[$obj->ID]); if ($obj->{$methodName}()) { $applicableIDs[] = $obj->ID; } } } $onlyOnLive = array_keys($onlyOnLive); if ($checkLivePages && $onlyOnLive && Object::has_extension($managedClass, 'SilverStripe\\ORM\\Versioning\\Versioned')) { // Get the pages that only exist on live (deleted from stage) $livePages = Versioned::get_by_stage($managedClass, "Live")->byIDs($onlyOnLive); foreach ($livePages as $obj) { if ($obj->{$methodName}()) { $applicableIDs[] = $obj->ID; } } } return $applicableIDs; }
public function testCreate() { /** @var DBHTMLText $field */ $field = Object::create_from_string("HTMLFragment(['whitelist' => 'link'])", 'MyField'); $this->assertEquals(['link'], $field->getWhitelist()); $field = Object::create_from_string("HTMLFragment(['whitelist' => 'link,a'])", 'MyField'); $this->assertEquals(['link', 'a'], $field->getWhitelist()); $field = Object::create_from_string("HTMLFragment(['whitelist' => ['link', 'a']])", 'MyField'); $this->assertEquals(['link', 'a'], $field->getWhitelist()); $field = Object::create_from_string("HTMLFragment", 'MyField'); $this->assertEmpty($field->getWhitelist()); // Test shortcodes $field = Object::create_from_string("HTMLFragment(['shortcodes' => true])", 'MyField'); $this->assertEquals(true, $field->getProcessShortcodes()); $field = Object::create_from_string("HTMLFragment(['shortcodes' => false])", 'MyField'); $this->assertEquals(false, $field->getProcessShortcodes()); // Mix options $field = Object::create_from_string("HTMLFragment(['shortcodes' => true, 'whitelist' => ['a'])", 'MyField'); $this->assertEquals(true, $field->getProcessShortcodes()); $this->assertEquals(['a'], $field->getWhitelist()); }
/** * @param $name */ public function __construct($name = null) { $this->name = $name ? $name : self::get_default_name(); parent::__construct(); }
/** * Return the DBField object that represents the given field. * This works similarly to obj() with 2 key differences: * - it still returns an object even when the field has no value. * - it only matches fields and not methods * - it matches foreign keys generated by has_one relationships, eg, "ParentID" * * @param string $fieldName Name of the field * @return DBField The field as a DBField object */ public function dbObject($fieldName) { // Check for field in DB $helper = static::getSchema()->fieldSpec(static::class, $fieldName, DataObjectSchema::INCLUDE_CLASS); if (!$helper) { return null; } $value = isset($this->record[$fieldName]) ? $this->record[$fieldName] : null; // If we have a DBField object in $this->record, then return that if ($value instanceof DBField) { return $value; } list($table, $spec) = explode('.', $helper); /** @var DBField $obj */ $obj = Object::create_from_string($spec, $fieldName); $obj->setTable($table); $obj->setValue($value, $this, false); return $obj; }
public function __construct() { _t('i18nTestModule.OTHERENTITY', 'Other Entity'); parent::__construct(); }
protected function getUncached($class, $name, $sourceOptions, &$result, $suppress, &$tags) { $tags[] = "__{$class}"; $tags[] = "__{$class}__{$name}"; // If result is already not something to merge into, just return it if ($result !== null && !is_array($result)) { return $result; } // First, look through the override values foreach ($this->overrides as $k => $overrides) { if (isset($overrides[$class][$name])) { $value = $overrides[$class][$name]; self::merge_low_into_high($result, $value, $suppress); if ($result !== null && !is_array($result)) { return $result; } } if (isset($this->suppresses[$k][$class][$name])) { $suppress = $suppress ? array_merge($suppress, $this->suppresses[$k][$class][$name]) : $this->suppresses[$k][$class][$name]; } } $nothing = null; // Then the manifest values foreach ($this->manifests as $manifest) { $value = $manifest->get($class, $name, $nothing); if ($value !== $nothing) { self::merge_low_into_high($result, $value, $suppress); if ($result !== null && !is_array($result)) { return $result; } } } $sources = array($class); // Include extensions only if not flagged not to, and some have been set if (($sourceOptions & self::EXCLUDE_EXTRA_SOURCES) != self::EXCLUDE_EXTRA_SOURCES) { // If we don't have a fresh list of extra sources, get it from the class itself if (!array_key_exists($class, $this->extraConfigSources)) { $this->extraConfigSources[$class] = Object::get_extra_config_sources($class); } // Update $sources with any extra sources $extraSources = $this->extraConfigSources[$class]; if ($extraSources) { $sources = array_merge($sources, $extraSources); } } $value = $nothing = null; foreach ($sources as $staticSource) { if (is_array($staticSource)) { $value = isset($staticSource[$name]) ? $staticSource[$name] : $nothing; } else { foreach ($this->staticManifests as $i => $statics) { $value = $statics->get($staticSource, $name, $nothing); if ($value !== $nothing) { break; } } } if ($value !== $nothing) { self::merge_low_into_high($result, $value, $suppress); if ($result !== null && !is_array($result)) { return $result; } } } // Finally, merge in the values from the parent class if (($sourceOptions & self::UNINHERITED) != self::UNINHERITED && (($sourceOptions & self::FIRST_SET) != self::FIRST_SET || $result === null)) { $parent = get_parent_class($class); if ($parent) { $this->getUncached($parent, $name, $sourceOptions, $result, $suppress, $tags); } } return $result; }
public function testStaticLookup() { $this->assertEquals(Object::static_lookup('ConfigTest_DefinesFoo', 'foo'), 1); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesFoo', 'bar'), null); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesBar', 'foo'), null); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesBar', 'bar'), 2); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesFooAndBar', 'foo'), 3); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesFooAndBar', 'bar'), 3); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesFooDoesntExtendObject', 'foo'), 4); $this->assertEquals(Object::static_lookup('ConfigTest_DefinesFooDoesntExtendObject', 'bar'), null); }