Created
November 6, 2014 02:38
-
-
Save owldesign/545ac8eeb2d8450492a9 to your computer and use it in GitHub Desktop.
FormBuilder_FieldsService.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Craft; | |
class FormBuilder_FieldsService extends BaseApplicationComponent | |
{ | |
public $oldFieldColumnPrefix = 'field_'; | |
private $_fieldsById; | |
private $_allFieldsInContext; | |
private $_fieldsByContextAndHandle; | |
private $_fieldsWithContent; | |
/** | |
* Returns a field form by its ID. | |
* | |
* @param int $formId | |
* | |
* @return FieldGroupModel|null | |
*/ | |
public function getFormById($formId) | |
{ | |
if (!isset($this->_formsById) || !array_key_exists($formId, $this->_formsById)) | |
{ | |
$result = $this->_createGroupQuery() | |
->where('id = :id', array(':id' => $formId)) | |
->queryRow(); | |
if ($result) | |
{ | |
$form = new FormBuilder_FormModel($result); | |
} | |
else | |
{ | |
$form = null; | |
} | |
$this->_formsById[$formId] = $form; | |
} | |
return $this->_formsById[$formId]; | |
} | |
// Fields | |
// ------------------------------------------------------------------------- | |
/** | |
* Returns all fields. | |
* | |
* @param string|null $indexBy | |
* | |
* @return array | |
*/ | |
public function getAllFields($indexBy = null) | |
{ | |
$context = craft()->formBuilder->fieldContext; | |
if (!isset($this->_allFieldsInContext[$context])) | |
{ | |
$results = $this->_createFieldQuery() | |
->where('context = :context', array(':context' => $context)) | |
->queryAll(); | |
$this->_allFieldsInContext[$context] = array(); | |
foreach ($results as $result) | |
{ | |
$field = $this->_populateField($result); | |
$this->_allFieldsInContext[$context][] = $field; | |
$this->_fieldsById[$field->id] = $field; | |
$this->_fieldsByContextAndHandle[$context][$field->handle] = $field; | |
} | |
} | |
if (!$indexBy) | |
{ | |
$fields = $this->_allFieldsInContext[$context]; | |
} | |
else | |
{ | |
$fields = array(); | |
foreach ($this->_allFieldsInContext[$context] as $field) | |
{ | |
$fields[$field->$indexBy] = $field; | |
} | |
} | |
return $fields; | |
} | |
/** | |
* Validates a field's settings. | |
* | |
* @param FieldModel $field | |
* | |
* @return bool | |
*/ | |
public function validateField(FormBuilder_FieldModel $field) | |
{ | |
$fieldRecord = $this->_getFieldRecord($field); | |
if (!$field->context) | |
{ | |
$field->context = craft()->content->fieldContext; | |
} | |
$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 and the field type | |
$fieldRecord->settings = $preppedSettings; | |
$fieldType->setSettings($preppedSettings); | |
// Run validation | |
$recordValidates = $fieldRecord->validate(); | |
$settingsValidate = $fieldType->getSettings()->validate(); | |
if ($recordValidates && $settingsValidate) | |
{ | |
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(FormBuilder_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; | |
} | |
} | |
/** | |
* Populates a fieldtype by a field model. | |
* | |
* @param FieldModel $field | |
* @param BaseElementModel|null $element | |
* | |
* @return BaseFieldType|null | |
*/ | |
public function populateFieldType(FormBuilder_FieldModel $field, $element = null) | |
{ | |
$fieldType = craft()->components->populateComponentByTypeAndModel(ComponentType::Field, $field); | |
if ($fieldType) | |
{ | |
$fieldType->element = $element; | |
return $fieldType; | |
} | |
} | |
/** | |
* Returns a field record for a given model. | |
* | |
* @param FieldModel $field | |
* | |
* @throws Exception | |
* @return FieldRecord | |
*/ | |
private function _getFieldRecord(FormBuilder_FieldModel $field) | |
{ | |
if (!$field->isNew()) | |
{ | |
$fieldId = $field->id; | |
if (!isset($this->_fieldRecordsById) || !array_key_exists($fieldId, $this->_fieldRecordsById)) | |
{ | |
$this->_fieldRecordsById[$fieldId] = FormBuilder_FieldRecord::model()->findById($fieldId); | |
if (!$this->_fieldRecordsById[$fieldId]) | |
{ | |
throw new Exception(Craft::t('No field exists with the ID “{id}”', array('id' => $fieldId))); | |
} | |
} | |
return $this->_fieldRecordsById[$fieldId]; | |
} | |
else | |
{ | |
return new FormBuilder_FieldRecord(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment