/** * @access protected * @return array */ protected function defineAttributes() { $requiredTitle = isset($this->_requiredFields) && in_array('title', $this->_requiredFields); $attributes = array('id' => AttributeType::Number, 'elementId' => AttributeType::Number, 'locale' => AttributeType::Locale, 'title' => array(AttributeType::String, 'required' => $requiredTitle)); if (Craft::isInstalled() && !craft()->isConsole()) { $allFields = craft()->fields->getAllFields(); foreach ($allFields as $field) { $fieldType = craft()->fields->populateFieldType($field); if ($fieldType) { $attributeConfig = $fieldType->defineContentAttribute(); } // Default to Mixed if (!$fieldType || !$attributeConfig) { $attributeConfig = AttributeType::Mixed; } $attributeConfig = ModelHelper::normalizeAttributeConfig($attributeConfig); $attributeConfig['label'] = $field->name; if (isset($this->_requiredFields) && in_array($field->id, $this->_requiredFields)) { $attributeConfig['required'] = true; } $attributes[$field->handle] = $attributeConfig; } } return $attributes; }
/** * Returns this record's normalized attribute configs. * * @return array */ public function getAttributeConfigs() { if (!isset($this->_attributeConfigs)) { $this->_attributeConfigs = array(); foreach ($this->defineAttributes() as $name => $config) { $this->_attributeConfigs[$name] = ModelHelper::normalizeAttributeConfig($config); } } return $this->_attributeConfigs; }
/** * Checks whether the given field is saving data into a textual column, and saves it accordingly. * * @param FieldModel $field * @param string $fieldColumnPrefix * * @return bool */ private function _checkField(FieldModel $field, $fieldColumnPrefix) { if ($field->type == 'Matrix') { $this->_matrixFieldIds[] = $field->id; } else { $fieldType = $field->getFieldType(); if ($fieldType) { $attributeConfig = $fieldType->defineContentAttribute(); if ($attributeConfig && $attributeConfig != AttributeType::Number) { $attributeConfig = ModelHelper::normalizeAttributeConfig($attributeConfig); if ($attributeConfig['type'] == AttributeType::String) { $this->_textColumns[] = $fieldColumnPrefix . $field->handle; } } } } }
/** * Saves a field. * * @param FieldModel $field * @throws \Exception * @return bool */ public function saveField(FieldModel $field) { $fieldRecord = $this->_getFieldRecordById($field->id); $isNewField = $fieldRecord->isNewRecord(); if (!$isNewField) { $fieldRecord->oldHandle = $fieldRecord->handle; } $fieldRecord->groupId = $field->groupId; $fieldRecord->name = $field->name; $fieldRecord->handle = $field->handle; $fieldRecord->instructions = $field->instructions; $fieldRecord->translatable = $field->translatable; $fieldRecord->type = $field->type; $fieldType = $this->populateFieldType($field); $preppedSettings = $fieldType->prepSettings($field->settings); $fieldRecord->settings = $field->settings = $preppedSettings; $fieldType->setSettings($preppedSettings); $fieldType->model = $field; $recordValidates = $fieldRecord->validate(); $settingsValidate = $fieldType->getSettings()->validate(); if ($recordValidates && $settingsValidate) { $transaction = craft()->db->beginTransaction(); try { $fieldType->onBeforeSave(); $fieldRecord->save(false); // Now that we have a field ID, save it on the model if (!$field->id) { $field->id = $fieldRecord->id; } // Create/alter the content table column $column = $fieldType->defineContentAttribute(); if ($column) { $column = ModelHelper::normalizeAttributeConfig($column); if ($isNewField) { craft()->db->createCommand()->addColumn('content', $field->handle, $column); } else { // Existing field going from a field that did not define any content attributes to one that does. if (!craft()->db->schema->columnExists('content', $fieldRecord->oldHandle)) { craft()->db->createCommand()->addColumn('content', $field->handle, $column); } else { // Existing field that already had a column defined, just altering it. craft()->db->createCommand()->alterColumn('content', $fieldRecord->oldHandle, $column, $field->handle); } } } else { // Did the old field have a column we need to remove? if (!$isNewField) { if ($fieldRecord->oldHandle && craft()->db->schema->columnExists('content', $fieldRecord->oldHandle)) { craft()->db->createCommand()->dropColumn('content', $fieldRecord->oldHandle); } } } $fieldType->onAfterSave(); $transaction->commit(); } catch (\Exception $e) { $transaction->rollBack(); throw $e; } return true; } else { $field->addErrors($fieldRecord->getErrors()); $field->addSettingErrors($fieldType->getSettings()->getErrors()); return false; } }
/** * Saves a field. * * @param FieldModel $field * @param bool $validate * * @throws \Exception * @return bool */ public function saveField(FieldModel $field, $validate = true) { if (!$validate || $this->validateField($field)) { $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { $field->context = craft()->content->fieldContext; $fieldRecord = $this->_getFieldRecord($field); $isNewField = $fieldRecord->isNewRecord(); $fieldRecord->groupId = $field->groupId; $fieldRecord->name = $field->name; $fieldRecord->handle = $field->handle; $fieldRecord->context = $field->context; $fieldRecord->instructions = $field->instructions; $fieldRecord->translatable = $field->translatable; $fieldRecord->type = $field->type; // Get the field type $fieldType = $field->getFieldType(); // Give the field type a chance to prep the settings from post $preppedSettings = $fieldType->prepSettings($field->settings); // Set the prepped settings on the FieldRecord, FieldModel, and the field type $fieldRecord->settings = $field->settings = $preppedSettings; $fieldType->setSettings($preppedSettings); if ($fieldRecord->settings instanceof BaseModel) { // Call getAttributes() without passing 'true' so the __model__ isn't saved $fieldRecord->settings = $fieldRecord->settings->getAttributes(); } $fieldType->onBeforeSave(); $fieldRecord->save(false); // Now that we have a field ID, save it on the model if ($isNewField) { $field->id = $fieldRecord->id; } // Create/alter the content table column $columnType = $fieldType->defineContentAttribute(); $contentTable = craft()->content->contentTable; $oldColumnName = $this->oldFieldColumnPrefix . $fieldRecord->getOldHandle(); $newColumnName = craft()->content->fieldColumnPrefix . $field->handle; if ($columnType) { $columnType = ModelHelper::normalizeAttributeConfig($columnType); // Make sure we're working with the latest data in the case of a renamed field. craft()->db->schema->refresh(); if (craft()->db->columnExists($contentTable, $oldColumnName)) { craft()->db->createCommand()->alterColumn($contentTable, $oldColumnName, $columnType, $newColumnName); } else { if (craft()->db->columnExists($contentTable, $newColumnName)) { craft()->db->createCommand()->alterColumn($contentTable, $newColumnName, $columnType); } else { craft()->db->createCommand()->addColumn($contentTable, $newColumnName, $columnType); } } } else { // Did the old field have a column we need to remove? if (!$isNewField) { if ($fieldRecord->getOldHandle() && craft()->db->columnExists($contentTable, $oldColumnName)) { craft()->db->createCommand()->dropColumn($contentTable, $oldColumnName); } } } if (!$isNewField) { // Save the old field handle on the model in case the field type needs to do something with it. $field->oldHandle = $fieldRecord->getOldHandle(); unset($this->_fieldsByContextAndHandle[$field->context][$field->oldHandle]); } // Cache it $this->_fieldsById[$field->id] = $field; $this->_fieldsByContextAndHandle[$field->context][$field->handle] = $field; unset($this->_allFieldsInContext[$field->context]); unset($this->_fieldsWithContent[$field->context]); $fieldType->onAfterSave(); if ($transaction !== null) { $transaction->commit(); } } catch (\Exception $e) { if ($transaction !== null) { $transaction->rollback(); } throw $e; } return true; } else { return false; } }
/** * @inheritDoc BaseModel::defineAttributes() * * @return array */ protected function defineAttributes() { $requiredTitle = isset($this->_requiredFields) && in_array('title', $this->_requiredFields); $attributes = array('id' => AttributeType::Number, 'elementId' => AttributeType::Number, 'locale' => array(AttributeType::Locale, 'default' => craft()->i18n->getPrimarySiteLocaleId()), 'title' => array(AttributeType::String, 'required' => $requiredTitle, 'maxLength' => 255, 'label' => 'Title')); foreach (craft()->fields->getAllFields() as $field) { $fieldType = $field->getFieldType(); if ($fieldType) { $attributeConfig = $fieldType->defineContentAttribute(); } // Default to Mixed if (!$fieldType || !$attributeConfig) { $attributeConfig = AttributeType::Mixed; } $attributeConfig = ModelHelper::normalizeAttributeConfig($attributeConfig); $attributeConfig['label'] = $field->name != '__blank__' ? $field->name : StringHelper::uppercaseFirst($field->handle); if (isset($this->_requiredFields) && in_array($field->id, $this->_requiredFields)) { $attributeConfig['required'] = true; } $attributes[$field->handle] = $attributeConfig; } return $attributes; }