/** * @param string $fieldName * @param array|null|void $arguments * @param bool|void $forceReturnedObject * @param bool|void $cache * @param null|void $cacheName * @return mixed|null */ public function obj($fieldName, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) { // HACK: Don't call the deprecated FormField::Name() method $methodIsAllowed = true; if ($this instanceof \FormField && $fieldName == 'Name') { $methodIsAllowed = false; } if ($methodIsAllowed && $this->hasMethod($fieldName)) { $value = $arguments ? call_user_func_array(array($this, $fieldName), $arguments) : $this->{$fieldName}(); } else { $value = $this->{$fieldName}; } if (!$value instanceof \ViewableData && ($this->castingClass($fieldName) || $forceReturnedObject)) { if (!($castConstructor = $this->castingHelper($fieldName))) { $castConstructor = $this->stat('default_cast'); } $valueObject = \Object::create_from_string($castConstructor, $fieldName); $valueObject->setValue($value, $this); $value = $valueObject; } if (!$value instanceof \ViewableData && $forceReturnedObject) { $default = \Config::inst()->get('ViewableData', 'default_cast', \Config::FIRST_SET); $castedValue = new $default($fieldName); $castedValue->setValue($value); $value = $castedValue; } return $value; }
/** * @param string $dbFieldType * @return string */ public function getTagNameForDBField($dbFieldType) { // some fields in 3rd-party modules require a name... $fieldObj = Object::create_from_string($dbFieldType, 'DummyName'); foreach (self::$dbfield_tagnames as $dbClass => $tagName) { if (class_exists($dbClass)) { $obj = Object::create_from_string($dbClass); if ($fieldObj instanceof $obj) { return $tagName; } } } return 'string'; }
/** * @todo this is not really a readable code. * @todo Clean this to make it more readable. * @param $bool * @return array */ public function allMethodNames($bool) { $methods = array(); $classes = Config::inst()->get('EncryptDataObjectFieldsExtension', 'EncryptedDataObjects'); if (in_array($this->owner->ClassName, $classes)) { $fields = Config::inst()->get($this->owner->ClassName, 'db', Config::UNINHERITED); foreach ($fields as $fieldName => $fieldType) { $reflector = Object::create_from_string($fieldType, '')->is_encrypted; if ($reflector === true) { $callFunction = strtolower('get' . $fieldName); self::$db_mapping[$callFunction] = array($fieldName, $fieldType); $methods[] = strtolower('get' . $fieldName); } } } return $methods; }
/** * 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 $forceReturnedObject if TRUE, the value will ALWAYS be casted to an object before being returned, * even if there is no explicit casting information * @param string $cacheName a custom cache name */ public function obj($fieldName, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) { if (!$cacheName) { $cacheName = $arguments ? $fieldName . implode(',', $arguments) : $fieldName; } if (!isset($this->objCache[$cacheName])) { // HACK: Don't call the deprecated FormField::Name() method $methodIsAllowed = true; if ($this instanceof FormField && $fieldName == 'Name') { $methodIsAllowed = false; } if ($methodIsAllowed && $this->hasMethod($fieldName)) { $value = $arguments ? call_user_func_array(array($this, $fieldName), $arguments) : $this->{$fieldName}(); } else { $value = $this->{$fieldName}; } if (!is_object($value) && ($this->castingClass($fieldName) || $forceReturnedObject)) { if (!($castConstructor = $this->castingHelper($fieldName))) { $castConstructor = $this->config()->default_cast; } $valueObject = Object::create_from_string($castConstructor, $fieldName); $valueObject->setValue($value, $this); $value = $valueObject; } if ($cache) { $this->objCache[$cacheName] = $value; } } else { $value = $this->objCache[$cacheName]; } if (!is_object($value) && $forceReturnedObject) { $default = $this->config()->default_cast; $castedValue = new $default($fieldName); $castedValue->setValue($value); $value = $castedValue; } return $value; }
/** * 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 $forceReturnedObject if TRUE, the value will ALWAYS be casted to an object before being returned, * even if there is no explicit casting information * @param string $cacheName a custom cache name */ public function obj($fieldName, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) { if (isset($_REQUEST['debug_profile'])) { Profiler::mark("obj.{$fieldName}", "on a {$this->class} object"); } if (!$cacheName) { $cacheName = $arguments ? $fieldName . implode(',', $arguments) : $fieldName; } if (!isset($this->objCache[$cacheName])) { // HACK: Don't call the deprecated FormField::Name() method $methodIsAllowed = true; if ($this instanceof FormField && $fieldName == 'Name') { $methodIsAllowed = false; } if ($methodIsAllowed && $this->hasMethod($fieldName)) { $value = $arguments ? call_user_func_array(array($this, $fieldName), $arguments) : $this->{$fieldName}(); } else { $value = $this->{$fieldName}; } if (!is_object($value) && ($this->castingClass($fieldName) || $forceReturnedObject)) { if (!($castConstructor = $this->castingHelper($fieldName))) { $castConstructor = $this->stat('default_cast'); } $valueObject = Object::create_from_string($castConstructor, $fieldName); $valueObject->setValue($value, $this->hasMethod('toMap') ? $this->toMap() : null); $value = $valueObject; } if ($cache) { $this->objCache[$cacheName] = $value; } } else { $value = $this->objCache[$cacheName]; } if (isset($_REQUEST['debug_profile'])) { Profiler::unmark("obj.{$fieldName}", "on a {$this->class} object"); } if (!is_object($value) && $forceReturnedObject) { $default = Config::inst()->get('ViewableData', 'default_cast', Config::FIRST_SET); $value = new $default($fieldName); } return $value; }
public function getField($field) { // If we already have an object in $this->record, then we should just return that if (isset($this->record[$field]) && is_object($this->record[$field])) { return $this->record[$field]; } // Do we have a field that needs to be lazy loaded? if (isset($this->record[$field . '_Lazy'])) { $tableClass = $this->record[$field . '_Lazy']; $this->loadLazyFields($tableClass); } // Otherwise, we need to determine if this is a complex field if (self::is_composite_field($this->class, $field)) { $helper = $this->castingHelper($field); $fieldObj = Object::create_from_string($helper, $field); $compositeFields = $fieldObj->compositeDatabaseFields(); foreach ($compositeFields as $compositeName => $compositeType) { if (isset($this->record[$field . $compositeName . '_Lazy'])) { $tableClass = $this->record[$field . $compositeName . '_Lazy']; $this->loadLazyFields($tableClass); } } // write value only if either the field value exists, // or a valid record has been loaded from the database $value = isset($this->record[$field]) ? $this->record[$field] : null; if ($value || $this->exists()) { $fieldObj->setValue($value, $this->record, false); } $this->record[$field] = $fieldObj; return $this->record[$field]; } return isset($this->record[$field]) ? $this->record[$field] : null; }
/** * Update the SELECT clause of the query with the columns from the given table */ protected function selectColumnsFromTable(SQLQuery &$query, $tableClass, $columns = null) { // Add SQL for multi-value fields $databaseFields = DataObject::database_fields($tableClass); $compositeFields = DataObject::composite_fields($tableClass, false); if ($databaseFields) { foreach ($databaseFields as $k => $v) { if ((is_null($columns) || in_array($k, $columns)) && !isset($compositeFields[$k])) { // Update $collidingFields if necessary if ($expressionForField = $query->expressionForField($k)) { if (!isset($this->collidingFields[$k])) { $this->collidingFields[$k] = array($expressionForField); } $this->collidingFields[$k][] = "\"{$tableClass}\".\"{$k}\""; } else { $query->selectField("\"{$tableClass}\".\"{$k}\"", $k); } } } } if ($compositeFields) { foreach ($compositeFields as $k => $v) { if ((is_null($columns) || in_array($k, $columns)) && $v) { $dbO = Object::create_from_string($v, $k); $dbO->addToQuery($query); } } } }
/** * Generate the following table in the database, modifying whatever already exists * as necessary. * * @todo Change detection for CREATE TABLE $options other than "Engine" * * @param string $table The name of the table * @param array $fieldSchema A list of the fields to create, in the same form as DataObject::$db * @param array $indexSchema A list of indexes to create. See {@link requireIndex()} * The values of the array can be one of: * - true: Create a single column index on the field named the same as the index. * - array('fields' => array('A','B','C'), 'type' => 'index/unique/fulltext'): This gives you full * control over the index. * @param boolean $hasAutoIncPK A flag indicating that the primary key on this table is an autoincrement type * @param string $options SQL statement to append to the CREATE TABLE call. * @param array $extensions List of extensions */ public function requireTable($table, $fieldSchema = null, $indexSchema = null, $hasAutoIncPK = true, $options = array(), $extensions = false) { if (!isset($this->tableList[strtolower($table)])) { $this->transCreateTable($table, $options, $extensions); $this->alterationMessage("Table {$table}: created", "created"); } else { if (Config::inst()->get('DBSchemaManager', 'check_and_repair_on_build')) { $this->checkAndRepairTable($table, $options); } // Check if options changed $tableOptionsChanged = false; if (isset($options[get_class($this)]) || true) { if (isset($options[get_class($this)])) { if (preg_match('/ENGINE=([^\\s]*)/', $options[get_class($this)], $alteredEngineMatches)) { $alteredEngine = $alteredEngineMatches[1]; $tableStatus = $this->query(sprintf('SHOW TABLE STATUS LIKE \'%s\'', $table))->first(); $tableOptionsChanged = $tableStatus['Engine'] != $alteredEngine; } } } if ($tableOptionsChanged || $extensions && $this->database->supportsExtensions($extensions)) { $this->transAlterTable($table, $options, $extensions); } } //DB ABSTRACTION: we need to convert this to a db-specific version: $this->requireField($table, 'ID', $this->IdColumn(false, $hasAutoIncPK)); // Create custom fields if ($fieldSchema) { foreach ($fieldSchema as $fieldName => $fieldSpec) { //Is this an array field? $arrayValue = ''; if (strpos($fieldSpec, '[') !== false) { //If so, remove it and store that info separately $pos = strpos($fieldSpec, '['); $arrayValue = substr($fieldSpec, $pos); $fieldSpec = substr($fieldSpec, 0, $pos); } $fieldObj = Object::create_from_string($fieldSpec, $fieldName); $fieldObj->arrayValue = $arrayValue; $fieldObj->setTable($table); $fieldObj->requireField(); } } // Create custom indexes if ($indexSchema) { foreach ($indexSchema as $indexName => $indexDetails) { $this->requireIndex($table, $indexName, $indexDetails); } } }
/** * 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; }
/** * Update the SELECT clause of the query with the columns from the given table */ protected function selectAllFromTable(SQLQuery &$query, $tableClass) { // Add SQL for multi-value fields $databaseFields = DataObject::database_fields($tableClass); $compositeFields = DataObject::composite_fields($tableClass, false); if($databaseFields) foreach($databaseFields as $k => $v) { if(!isset($compositeFields[$k])) { // Update $collidingFields if necessary if(isset($query->select[$k])) { if(!isset($this->collidingFields[$k])) $this->collidingFields[$k] = array($query->select[$k]); $this->collidingFields[$k][] = "\"$tableClass\".\"$k\""; } else { $query->select[$k] = "\"$tableClass\".\"$k\""; } } } if($compositeFields) foreach($compositeFields as $k => $v) { if($v) { $dbO = Object::create_from_string($v, $k); $dbO->addToQuery($query); } } }
/** * Gets the field list for a record. * * @param GridField $grid * @param DataObjectInterface $record * @return FieldList */ public function getFields(GridField $grid, DataObjectInterface $record) { $cols = $this->getDisplayFields($grid); $fields = new FieldList(); $list = $grid->getList(); $class = $list ? $list->dataClass() : null; foreach ($cols as $col => $info) { $field = null; if ($info instanceof Closure) { $field = call_user_func($info, $record, $col, $grid); } elseif (is_array($info)) { if (isset($info['callback'])) { $field = call_user_func($info['callback'], $record, $col, $grid); } elseif (isset($info['field'])) { if ($info['field'] == 'LiteralField') { $field = new $info['field']($col, null); } else { $field = new $info['field']($col); } } if (!$field instanceof FormField) { throw new Exception(sprintf('The field for column "%s" is not a valid form field', $col)); } } if (!$field && $list instanceof ManyManyList) { $extra = $list->getExtraFields(); if ($extra && array_key_exists($col, $extra)) { $field = Object::create_from_string($extra[$col], $col)->scaffoldFormField(); } } if (!$field) { if ($class && ($obj = singleton($class)->dbObject($col))) { $field = $obj->scaffoldFormField(); } else { $field = new ReadonlyField($col); } } if (!$field instanceof FormField) { throw new Exception(sprintf('Invalid form field instance for column "%s"', $col)); } $fields->push($field); } return $fields; }
/** * Generate the $db property values. * * @param DataObject|DataExtension $className * @return string */ protected function generateORMDBProperties($className) { if ($fields = Config::inst()->get($className, 'db', Config::UNINHERITED)) { foreach ($fields as $fieldName => $dataObjectName) { $prop = 'string'; $fieldObj = Object::create_from_string($dataObjectName, $fieldName); if (is_a($fieldObj, 'Int')) { $prop = 'int'; } elseif (is_a($fieldObj, 'Boolean')) { $prop = 'boolean'; } elseif (is_a($fieldObj, 'Float') || is_a($fieldObj, 'Decimal')) { $prop = 'float'; } $this->resultString .= " * @property {$prop} {$fieldName}\n"; } } return true; }
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()); }
public function Backend() { return Object::create_from_string("SnowcakeDeploymentBackend"); }
/** * Get instances of all the environment checks. * * @return array */ protected function checkInstances() { $output = array(); foreach ($this->checks as $check) { list($checkClass, $checkTitle) = $check; if (is_string($checkClass)) { $checkInst = Object::create_from_string($checkClass); if ($checkInst instanceof EnvironmentCheck) { $output[] = array($checkInst, $checkTitle); } else { throw new InvalidArgumentException("Bad EnvironmentCheck: '{$checkClass}' - the named class doesn't implement EnvironmentCheck"); } } else { if ($checkClass instanceof EnvironmentCheck) { $output[] = array($checkClass, $checkTitle); } else { throw new InvalidArgumentException("Bad EnvironmentCheck: " . var_export($check, true)); } } } return $output; }
/** * Add an item to this many_many relationship * Does so by adding an entry to the joinTable. * * @param mixed $item * @param array $extraFields A map of additional columns to insert into the joinTable. * Column names should be ANSI quoted. */ public function add($item, $extraFields = array()) { // Ensure nulls or empty strings are correctly treated as empty arrays if (empty($extraFields)) { $extraFields = array(); } // Determine ID of new record if (is_numeric($item)) { $itemID = $item; } elseif ($item instanceof $this->dataClass) { $itemID = $item->ID; } else { throw new InvalidArgumentException("ManyManyList::add() expecting a {$this->dataClass} object, or ID value", E_USER_ERROR); } // Validate foreignID $foreignIDs = $this->getForeignID(); if (empty($foreignIDs)) { throw new Exception("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING); } // Apply this item to each given foreign ID record if (!is_array($foreignIDs)) { $foreignIDs = array($foreignIDs); } foreach ($foreignIDs as $foreignID) { // Check for existing records for this item if ($foreignFilter = $this->foreignIDWriteFilter($foreignID)) { // With the current query, simply add the foreign and local conditions // The query can be a bit odd, especially if custom relation classes // don't join expected tables (@see Member_GroupSet for example). $query = new SQLQuery("*", "\"{$this->joinTable}\""); $query->addWhere($foreignFilter); $query->addWhere(array("\"{$this->joinTable}\".\"{$this->localKey}\"" => $itemID)); $hasExisting = $query->count() > 0; } else { $hasExisting = false; } // Blank manipulation $manipulation = array($this->joinTable => array('command' => $hasExisting ? 'update' : 'insert', 'fields' => array())); if ($hasExisting) { $manipulation[$this->joinTable]['where'] = array("\"{$this->joinTable}\".\"{$this->foreignKey}\"" => $foreignID, "\"{$this->joinTable}\".\"{$this->localKey}\"" => $itemID); } if ($extraFields && $this->extraFields) { // Write extra field to manipluation in the same way // that DataObject::prepareManipulationTable writes fields foreach ($this->extraFields as $fieldName => $fieldSpec) { // Skip fields without an assignment if (array_key_exists($fieldName, $extraFields)) { $fieldObject = Object::create_from_string($fieldSpec, $fieldName); $fieldObject->setValue($extraFields[$fieldName]); $fieldObject->writeToManipulation($manipulation[$this->joinTable]); } } } $manipulation[$this->joinTable]['fields'][$this->localKey] = $itemID; $manipulation[$this->joinTable]['fields'][$this->foreignKey] = $foreignID; DB::manipulate($manipulation); } }
/** * 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) { $value = isset($this->record[$fieldName]) ? $this->record[$fieldName] : null; // If we have a DBField object in $this->record, then return that if (is_object($value)) { return $value; } // Build and populate new field otherwise $helper = $this->db($fieldName, true); if ($helper) { list($table, $spec) = explode('.', $helper); $obj = Object::create_from_string($spec, $fieldName); $obj->setTable($table); $obj->setValue($value, $this, false); return $obj; } }
/** * 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 $forceReturnedObject if TRUE, the value will ALWAYS be casted to an object before being returned, * even if there is no explicit casting information * @param string $cacheName a custom cache name */ public function obj($fieldName, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) { if (isset($_REQUEST['debug_profile'])) { Profiler::mark("obj.{$fieldName}", "on a {$this->class} object"); } if (!$cacheName) { $cacheName = $arguments ? $fieldName . implode(',', $arguments) : $fieldName; } if (!isset($this->objCache[$cacheName])) { if ($this->hasMethod($fieldName)) { $value = $arguments ? call_user_func_array(array($this, $fieldName), $arguments) : $this->{$fieldName}(); } else { $value = $this->{$fieldName}; } if (!is_object($value) && ($this->castingClass($fieldName) || $forceReturnedObject)) { if (!($castConstructor = $this->castingHelper($fieldName))) { $castConstructor = $this->stat('default_cast'); } $valueObject = Object::create_from_string($castConstructor, $fieldName); $valueObject->setValue($value, $this->hasMethod('getAllFields') ? $this->getAllFields() : null); $value = $valueObject; } if ($cache) { $this->objCache[$cacheName] = $value; } } else { $value = $this->objCache[$cacheName]; } if (isset($_REQUEST['debug_profile'])) { Profiler::unmark("obj.{$fieldName}", "on a {$this->class} object"); } if (!is_object($value) && $forceReturnedObject) { $default = Object::get_static('ViewableData', 'default_cast'); $value = new $default($fieldName); } return $value; }
/** * 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) { // If we have a CompositeDBField object in $this->record, then return that if (isset($this->record[$fieldName]) && is_object($this->record[$fieldName])) { return $this->record[$fieldName]; // Special case for ID field } else { if ($fieldName == 'ID') { return new PrimaryKey($fieldName, $this); // Special case for ClassName } else { if ($fieldName == 'ClassName') { $val = get_class($this); return DBField::create_field('Varchar', $val, $fieldName); } else { if (array_key_exists($fieldName, self::$fixed_fields)) { return DBField::create_field(self::$fixed_fields[$fieldName], $this->{$fieldName}, $fieldName); // General casting information for items in $db } else { if ($helper = $this->db($fieldName)) { $obj = Object::create_from_string($helper, $fieldName); $obj->setValue($this->{$fieldName}, $this->record, false); return $obj; // Special case for has_one relationships } else { if (preg_match('/ID$/', $fieldName) && $this->has_one(substr($fieldName, 0, -2))) { $val = $this->{$fieldName}; return DBField::create_field('ForeignKey', $val, $fieldName, $this); // has_one for polymorphic relations do not end in ID } else { if (($type = $this->has_one($fieldName)) && $type === 'DataObject') { $val = $this->{$fieldName}(); return DBField::create_field('PolymorphicForeignKey', $val, $fieldName, $this); } } } } } } } }
/** * Create a DataObject from the given SQL row. * * @param array $row * @return DataObject */ protected function createDataObject($row) { // remove any composed fields $add = array(); if ($this->_compositeExtraFields) { foreach ($this->_compositeExtraFields as $fieldName => $composed) { // convert joined extra fields into their composite field // types. $value = array(); foreach ($composed as $i => $k) { if (isset($row[$fieldName . $k])) { $value[$k] = $row[$fieldName . $k]; // don't duplicate data in the record unset($row[$fieldName . $k]); } } $obj = Object::create_from_string($this->extraFields[$fieldName], $fieldName); $obj->setValue($value, null, false); $add[$fieldName] = $obj; } } $dataObject = parent::createDataObject($row); foreach ($add as $fieldName => $obj) { $dataObject->{$fieldName} = $obj; } return $dataObject; }
/** */ public function dbObject($fieldName) { if ($helper = $this->db($fieldName)) { $obj = Object::create_from_string($helper, $fieldName); $obj->setValue($this->{$fieldName}, $this->dataSource, false); return $obj; // Special case for has_one relationships } else { if (preg_match('/ID$/', $fieldName) && $this->hasOne(substr($fieldName, 0, -2))) { $val = $this->{$fieldName}; return DBField::create_field('ForeignKey', $val, $fieldName, $this); } } }
/** * Return the value associated with a binding. * - if the binding is unbound, return null * - if the binding is a constant, return it * - if the binding is a reference within the context, attempt to retrieve that value. * @param $context * @return DBField Returns a subclass of DB field, as defined by getProperties for the class, * with the value assigned, or null if unbound. */ function getValue($context) { $type = $this->getBaseType($this->propertyDef['type']); $inst = Object::create_from_string($type, $this->propertyName); $inst->setValue($this->value); switch ($this->type) { case NLBindingDefinition::BIND_EMBEDDED: $value = $inst->getValue(); break; case NLBindingDefinition::BIND_CONTEXT: // @todo NLBindingDefinition: consider if BIND_CONTEXT could contain something other than a function or property // @todo on the context. Currently assumes instance only. What about statics? // $this->value contains the identifier within the context. $methodOrProp = $inst->getValue(); // If that identifier is a function, call it, otherwise just reference it as a property. if (method_exists($context, $methodOrProp)) { $value = $context->{$methodOrProp}(); } else { $value = $context->{$methodOrProp}; } break; case NLBindingDefinition::BIND_EVENT: // @todo Implement NLBindingDefinition::getValue BIND_EVENT case $value = null; break; case NLBindingDefinition::BIND_NONE: $value = null; break; } return $value; }
protected function constructExtensions() { $class = get_class($this); // Register this trait as a method source $this->registerExtraMethodCallback('defineExtensionMethods', function () { $this->defineExtensionMethods(); }); // Setup all extension instances for this instance foreach (ClassInfo::ancestry($class) as $class) { if (in_array($class, self::$unextendable_classes)) { continue; } $extensions = Config::inst()->get($class, 'extensions', Config::UNINHERITED | Config::EXCLUDE_EXTRA_SOURCES); if ($extensions) { foreach ($extensions as $extension) { $instance = \Object::create_from_string($extension); $instance->setOwner(null, $class); $this->extension_instances[$instance->class] = $instance; } } } if (!isset(self::$classes_constructed[$class])) { $this->defineMethods(); self::$classes_constructed[$class] = true; } }
/** * 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]; $fieldObject = Object::create_from_string($spec, $key); $fieldObject->setValue($this->getField($field), null, false); return $fieldObject; }
/** * 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) { // If we have a CompositeDBField object in $this->record, then return that if (isset($this->record[$fieldName]) && is_object($this->record[$fieldName])) { return $this->record[$fieldName]; // Special case for ID field } else { if ($fieldName == 'ID') { return new PrimaryKey($fieldName, $this); // General casting information for items in $db or $casting } else { if ($helper = $this->castingHelper($fieldName)) { $obj = Object::create_from_string($helper, $fieldName); $obj->setValue($this->{$fieldName}, $this->record, false); return $obj; // Special case for has_one relationships } else { if (preg_match('/ID$/', $fieldName) && $this->has_one(substr($fieldName, 0, -2))) { $val = $this->{$fieldName}; return DBField::create_field('ForeignKey', $val, $fieldName, $this); // Special case for ClassName } else { if ($fieldName == 'ClassName') { $val = get_class($this); return DBField::create_field('Varchar', $val, $fieldName, $this); } } } } } }
/** * Gets the field list for a record. * * @param GridField $grid * @param DataObjectInterface $record * @return FieldList */ public function getFields(GridField $grid, DataObjectInterface $record) { $cols = $this->getDisplayFields($grid); $fields = new FieldList(); $list = $grid->getList(); $class = $list ? $list->dataClass() : null; foreach ($cols as $col => $info) { $field = null; if ($info instanceof Closure) { $field = call_user_func($info, $record, $col, $grid); } elseif (is_array($info)) { if (isset($info['callback'])) { $field = call_user_func($info['callback'], $record, $col, $grid); } elseif (isset($info['field'])) { if ($info['field'] == 'LiteralField') { $field = new $info['field']($col, null); } else { $field = new $info['field']($col); } } if (!$field instanceof FormField) { throw new Exception(sprintf('The field for column "%s" is not a valid form field', $col)); } } if (!$field && $list instanceof ManyManyList) { $extra = $list->getExtraFields(); if ($extra && array_key_exists($col, $extra)) { $field = Object::create_from_string($extra[$col], $col)->scaffoldFormField(); } } if (!$field) { if (!$this->displayFields) { // If setDisplayFields() not used, utilize $summary_fields // in a way similar to base class // // Allows use of 'MyBool.Nice' and 'MyHTML.NoHTML' so that // GridFields not using inline editing still look good or // revert to looking good in cases where the field isn't // available or is readonly // $colRelation = explode('.', $col); if ($class && ($obj = singleton($class)->dbObject($colRelation[0]))) { $field = $obj->scaffoldFormField(); } else { $field = new ReadonlyField($colRelation[0]); } } else { if ($class && ($obj = singleton($class)->dbObject($col))) { $field = $obj->scaffoldFormField(); } else { $field = new ReadonlyField($col); } } } if (!$field instanceof FormField) { throw new Exception(sprintf('Invalid form field instance for column "%s"', $col)); } // Add CSS class for interactive fields if (!($field->isReadOnly() || $field instanceof LiteralField)) { $field->addExtraClass('editable-column-field'); } $fields->push($field); } return $fields; }