setBaseClass($baseClass); parent::__construct($name, null, null, $options); } /** * @return void */ public function requireField() { $parts = array( 'datatype' => 'enum', 'enums' => $this->getEnumObsolete(), 'character set' => 'utf8', 'collate' => 'utf8_general_ci', 'default' => $this->getDefault(), 'table' => $this->getTable(), 'arrayValue' => $this->arrayValue ); $values = array( 'type' => 'enum', 'parts' => $parts ); DB::require_field($this->getTable(), $this->getName(), $values); } /** * Get the base dataclass for the list of subclasses * * @return string */ public function getBaseClass() { // Use explicit base class if ($this->baseClass) { return $this->baseClass; } // Default to the basename of the record $schema = DataObject::getSchema(); if ($this->record) { return $schema->baseDataClass($this->record); } // During dev/build only the table is assigned $tableClass = $schema->tableClass($this->getTable()); if ($tableClass && ($baseClass = $schema->baseDataClass($tableClass))) { return $baseClass; } // Fallback to global default return DataObject::class; } /** * Assign the base class * * @param string $baseClass * @return $this */ public function setBaseClass($baseClass) { $this->baseClass = $baseClass; return $this; } /** * Get list of classnames that should be selectable * * @return array */ public function getEnum() { $classNames = ClassInfo::subclassesFor($this->getBaseClass()); $dataobject = strtolower(DataObject::class); unset($classNames[$dataobject]); return array_values($classNames); } /** * Get the list of classnames, including obsolete classes. * * If table or name are not set, or if it is not a valid field on the given table, * then only known classnames are returned. * * Values cached in this method can be cleared via `DBClassName::clear_classname_cache();` * * @return array */ public function getEnumObsolete() { // Without a table or field specified, we can only retrieve known classes $table = $this->getTable(); $name = $this->getName(); if (empty($table) || empty($name)) { return $this->getEnum(); } // Ensure the table level cache exists if (empty(self::$classname_cache[$table])) { self::$classname_cache[$table] = array(); } // Check existing cache if (!empty(self::$classname_cache[$table][$name])) { return self::$classname_cache[$table][$name]; } // Get all class names $classNames = $this->getEnum(); if (DB::get_schema()->hasField($table, $name)) { $existing = DB::query("SELECT DISTINCT \"{$name}\" FROM \"{$table}\"")->column(); $classNames = array_unique(array_merge($classNames, $existing)); } // Cache and return self::$classname_cache[$table][$name] = $classNames; return $classNames; } public function setValue($value, $record = null, $markChanged = true) { parent::setValue($value, $record, $markChanged); if ($record instanceof DataObject) { $this->record = $record; } } public function getDefault() { // Check for assigned default $default = parent::getDefault(); if ($default) { return $default; } // Allow classes to set default class $baseClass = $this->getBaseClass(); $defaultClass = Config::inst()->get($baseClass, 'default_classname'); if ($defaultClass && class_exists($defaultClass)) { return $defaultClass; } // Fallback to first option $enum = $this->getEnum(); return reset($enum); } }