public function getValidFieldTypes() { if (!isset($this->_validFieldTypes)) { $this->_validFieldTypes = array_keys(Fields::getFieldTypes()); } return $this->_validFieldTypes; }
protected function generateModuleSqlData($moduleName) { $sql = ""; $disallow = array("id", "assignedTo", "name", "nameId", "description", "createDate", "lastUpdated", "updatedBy"); $fields = Fields::model()->findAllByAttributes(array('modelName' => ucfirst($moduleName))); foreach ($fields as $field) { if (array_search($field->fieldName, $disallow) === false) { $fieldType = $field->type; $columnDefinitions = Fields::getFieldTypes('columnDefinition'); if (isset($columnDefinitions[$fieldType])) { $fieldType = $columnDefinitions[$fieldType]; } else { $fieldType = 'VARCHAR(250)'; } $linkType = $field->linkType; if ($field->type === 'dropdown') { // Export associated dropdown values $dropdown = Dropdowns::model()->findByPk($field->linkType); if ($dropdown) { $sql .= "/*&*/INSERT INTO x2_dropdowns " . "(name, options, multi, parent, parentVal) " . "VALUES " . "('{$dropdown->name}', '{$dropdown->options}', '{$dropdown->multi}', " . "'{$dropdown->parent}', '{$dropdown->parentVal}');"; // Temporarily set the linkType to the dropdowns name: this is to avoid // messy ID conflicts when importing a module to existing installations $linkType = $dropdown->name; } } $sql .= "/*&*/ALTER TABLE x2_{$moduleName} ADD COLUMN {$field->fieldName} {$fieldType};"; $sql .= "/*&*/INSERT INTO x2_fields " . "(modelName, fieldName, attributeLabel, modified, custom, type, linkType) " . "VALUES " . "('{$moduleName}', '{$field->fieldName}', '{$field->attributeLabel}', '1', '1', " . "'{$field->type}', '{$linkType}');"; } } $formLayouts = X2Model::model('FormLayout')->findAllByAttributes(array('model' => $moduleName)); foreach ($formLayouts as $layout) { $attributes = $layout->attributes; unset($attributes['id']); $attributeKeys = array_keys($attributes); $attributeValues = array_values($attributes); $keys = implode(", ", $attributeKeys); $values = "'" . implode("', '", $attributeValues) . "'"; $sql .= "/*&*/INSERT INTO x2_form_layouts ({$keys}) VALUES ({$values});"; } return $sql; }
public static function modelRules(&$fields, $model) { $fieldTypes = array('required', 'email', 'unique', 'int', 'numerical', 'boolean', 'safe', 'search', 'link', 'foreignKey', 'uniqueIndex'); $fieldRules = array_fill_keys($fieldTypes, array()); $validators = Fields::getFieldTypes('validator'); foreach ($fields as &$_field) { $fieldRules['search'][] = $_field->fieldName; if (isset($validators[$_field->type]) && $_field->safe) { $fieldRules[$validators[$_field->type]][] = $_field->fieldName; } if ($_field->required) { $fieldRules['required'][] = $_field->fieldName; } /* x2tempstart */ // see note above subScenario property if (!(property_exists($model, 'subScenario') && $model->subScenario === 'importOverwrite' && $_field->fieldName === 'id') && $_field->uniqueConstraint) { /* x2tempend */ $fieldRules['unique'][] = $_field->fieldName; } if ($_field->type == 'link' && $_field->required) { $fieldRules['link'][] = $_field->fieldName; } if ($_field->keyType === 'FOR') { $fieldRules['foreignKey'][] = $_field->fieldName; } if ($_field->keyType === 'UNI') { $fieldRules['uniqueIndex'][] = $_field->fieldName; } } $rules = array(array(implode(',', $fieldRules['foreignKey']), 'application.components.validators.X2ModelForeignKeyValidator'), array(implode(',', $fieldRules['uniqueIndex']), 'application.components.validators.X2ModelUniqueIndexValidator'), array(implode(',', $fieldRules['required']), 'required'), array(implode(',', $fieldRules['unique']), 'unique'), array(implode(',', $fieldRules['numerical']), 'numerical'), array(implode(',', $fieldRules['email']), 'email'), array(implode(',', $fieldRules['int']), 'numerical', 'integerOnly' => true), array(implode(',', $fieldRules['boolean']), 'boolean'), array(implode(',', $fieldRules['link']), 'application.components.ValidLinkValidator'), array(implode(',', $fieldRules['safe']), 'safe'), array(implode(',', $fieldRules['search']), 'safe', 'on' => 'search')); return $rules; }
/** * Parses text for short codes and returns an associative array of them. * Overrides parent method to add support for shortcodes, missing model param, and insertable * attributes referencing param names * * @param string $value The value to parse * @param X2Model $model The model on which to operate with attribute replacement * @param bool $renderFlag The render flag to pass to {@link X2Model::getAttribute()} * @param bool $makeLinks If the render flag is set, determines whether to render attributes * as links */ protected static function getReplacementTokens($value, array $params, $renderFlag, $makeLinks) { if (isset($params['model'])) { $model = $params['model']; } else { $model = null; } // Pattern will match {attr}, {attr1.attr2}, {attr1.attr2.attr3}, etc. $codes = array(); // Types of each value for the short codes: $codeTypes = array(); $fieldTypes = array_map(function ($f) { return $f['phpType']; }, Fields::getFieldTypes()); if ($model) { $fields = $model->getFields(true); } else { $fields = array(); } // check for variables preg_match_all('/{([a-z]\\w*)(\\.[a-z]\\w*)*?}/i', trim($value), $matches); $isRenderException = function ($match) use($fields) { return isset($fields[$match]) && $fields[$match]->fieldName === 'id'; }; if (!empty($matches[0])) { foreach ($matches[0] as $match) { $match = substr($match, 1, -1); // Remove the "{" and "}" characters $attr = $match; if (strpos($match, '.') !== false) { // We found a link attribute (i.e. {company.name}) $newModel = $model; $newModelFields = $fields; $pieces = explode('.', $match); $first = array_shift($pieces); // First check if the first piece is part of a short code, like "user" $tmpModel = self::parseShortCode($first, array_merge($params, array('model' => $newModel))); if (isset($tmpModel) && $tmpModel instanceof CActiveRecord) { // If we got a model from our short code, use that $newModel = $tmpModel; // Also, set the attribute to have the first item removed. $attr = implode('.', $pieces); if ($newModel instanceof X2Model) { $newModelFields = $newModel->getFields(true); } else { $newModelFields = array(); } } if ($newModel) { $codes['{' . $match . '}'] = $newModel->getAttribute($attr, $isRenderException($match) ? true : $renderFlag, $makeLinks); $codeTypes[$match] = isset($newModelFields[$attr]) && isset($fieldTypes[$newModelFields[$attr]->type]) ? $fieldTypes[$newModelFields[$attr]->type] : 'string'; } } else { // Standard attribute // First check if we provided a value for this attribute if (isset($params[$match]) && is_scalar($params[$match])) { $codes['{' . $match . '}'] = $params[$match]; $codeTypes[$match] = gettype($params[$match]); // Next check if the attribute exists on the model } elseif ($model && $model->hasAttribute($match)) { $codes['{' . $match . '}'] = $model->getAttribute($match, $isRenderException($match) ? true : $renderFlag, $makeLinks); $codeTypes[$match] = isset($fields[$match]) && isset($fieldTypes[$fields[$match]->type]) ? $fieldTypes[$fields[$match]->type] : 'string'; } else { // Finally, try to parse it as a short code if nothing else worked $shortCodeValue = self::parseShortCode($match, $params); if (!is_null($shortCodeValue) && is_scalar($shortCodeValue)) { $codes['{' . $match . '}'] = $shortCodeValue; $codeTypes[$match] = gettype($shortCodeValue); } } } } } $codes = self::castReplacementTokenTypes($codes, $codeTypes); return $codes; }
/** * Call render at least once for each field type */ public function testRender() { Yii::app()->cache->flush(); TestingAuxLib::suLogin('admin'); $contact = Contacts::model()->findByPk(12345); $fieldTypes = Fields::getFieldTypes(); foreach ($fieldTypes as $type => $info) { $fieldsOfType = $contact->getFields(false, function ($field) use($type) { return strtolower($field->type) === strtolower($type); }); VERBOSE_MODE && println('type=' . $type); $this->assertTrue(count($fieldsOfType) > 0); foreach ($fieldsOfType as $field) { $contact->formatter->renderAttribute($field->fieldName, true, true, true); } } }
/** * Modifies the data type of an existing column */ public function modifyColumn() { // Get the column definition. $fieldType = $this->type; $columnDefinitions = Fields::getFieldTypes('columnDefinition'); if (isset($columnDefinitions[$fieldType])) { $fieldType = $columnDefinitions[$fieldType]; } else { $fieldType = 'VARCHAR(250)'; } //Yii::app()->db->createCommand('set sql_mode=STRICT_ALL_TABLES;')->execute(); $sql = "ALTER TABLE `{$this->myTableName}` MODIFY COLUMN `{$this->fieldName}` {$fieldType}"; try { Yii::app()->db->createCommand($sql)->execute(); } catch (CDbException $e) { $this->addError('type', $e->getMessage()); return false; } return true; }
</div> <div class="row"> <?php echo $form->labelEx($model, 'type'); ?> <?php if (!$new && !$model->custom) { echo '<span style="color:red">' . Yii::t('admin', 'Changing the type of a default field is strongly discouraged.') . ' ' . Yii::t('admin', 'It may result in data loss or irregular application behavior.') . '</span><br>'; } if (!$new && $model->custom && $changedType) { echo '<span style="color:red">' . Yii::t('admin', 'Changing the type of a field may result in alteration of data. For ' . 'example, changing a field from type "{text}" to type "{varchar}" ' . 'shortens the field\'s width, potentially truncating field values.', array('{text}' => Yii::t('app', 'Multiple Line Text Area'), '{varchar}' => Yii::t('app', 'Single Line Text Area'))) . '</span><br>'; } $fieldTypes = Fields::getFieldTypes('title'); echo $form->dropDownList($model, 'type', ArrayUtil::asorti($fieldTypes), array('id' => 'fieldType', 'class' => $new ? 'new' : 'existing')); ?> <?php echo $form->error($model, 'type'); ?> </div> <div class="row"> <?php // Render a dropdown menu and any other fields // for the "linkType" field $genericLabel = CHtml::label(Yii::t('app', 'Type'), CHtml::resolveName($model, $assignTypeName)); switch ($model->type) { case "dropdown": $dropdowns = Dropdowns::model()->findAll(); $arr = array();
/** * Parses text for short codes and returns an associative array of them. * * @param string $value The value to parse * @param X2Model $model The model on which to operate with attribute replacement * @param bool $renderFlag The render flag to pass to {@link X2Model::getAttribute()} * @param bool $makeLinks If the render flag is set, determines whether to render attributes * as links */ protected static function getReplacementTokens($value, array $params, $renderFlag, $makeLinks) { if (!isset($params['model'])) { throw new CException('Missing model param'); } $model = $params['model']; // Pattern will match {attr}, {attr1.attr2}, {attr1.attr2.attr3}, etc. $codes = array(); // Types of each value for the short codes: $codeTypes = array(); $fieldTypes = array_map(function ($f) { return $f['phpType']; }, Fields::getFieldTypes()); $fields = $model->getFields(true); // check for variables preg_match_all('/{([a-z]\\w*)(\\.[a-z]\\w*)*?}/i', trim($value), $matches); if (!empty($matches[0])) { foreach ($matches[0] as $match) { $match = substr($match, 1, -1); // Remove the "{" and "}" characters $attr = $match; if (strpos($match, '.') !== false) { // We found a link attribute (i.e. {company.name}) $newModel = $model; $pieces = explode('.', $match); $first = array_shift($pieces); $codes['{' . $match . '}'] = $newModel->getAttribute($attr, $renderFlag, $makeLinks); $codeTypes[$match] = isset($fields[$attr]) && isset($fieldTypes[$fields[$attr]->type]) ? $fieldTypes[$fields[$attr]->type] : 'string'; } else { // Standard attribute // Check if the attribute exists on the model if ($model->hasAttribute($match)) { $codes['{' . $match . '}'] = $model->getAttribute($match, $renderFlag, $makeLinks); $codeTypes[$match] = isset($fields[$match]) && isset($fieldTypes[$fields[$match]->type]) ? $fieldTypes[$fields[$match]->type] : 'string'; } } } } $codes = self::castReplacementTokenTypes($codes, $codeTypes); return $codes; }
</div> <div class="row"> <?php echo $form->labelEx($model, 'type'); ?> <?php if (!$new && !$model->custom) { echo '<span style="color:red">' . Yii::t('admin', 'Changing the type of a default field is strongly discouraged.') . ' ' . Yii::t('admin', 'It may result in data loss or irregular application behavior.') . '</span><br>'; } if (!$new && $model->custom && $changedType) { echo '<span style="color:red">' . Yii::t('admin', 'Changing the type of a field may result in alteration of data. For ' . 'example, changing a field from type "{text}" to type "{varchar}" ' . 'shortens the field\'s width, potentially truncating field values.', array('{text}' => Yii::t('app', 'Multiple Line Text Area'), '{varchar}' => Yii::t('app', 'Single Line Text Area'))) . '</span><br>'; } echo $form->dropDownList($model, 'type', Fields::getFieldTypes('title'), array('id' => 'fieldType', 'class' => $new ? 'new' : 'existing')); ?> <?php echo $form->error($model, 'type'); ?> </div> <div class="row"> <?php // Render a dropdown menu and any other fields // for the "linkType" field $genericLabel = CHtml::label(Yii::t('app', 'Type'), CHtml::resolveName($model, $assignTypeName)); switch ($model->type) { case "dropdown": $dropdowns = Dropdowns::model()->findAll(); $arr = array(); foreach ($dropdowns as $dropdown) {