function alterField(\Field $field, $add = false) { $q = $this->db->dsql()->expr('alter table [al_table] add [field_name] [type_expr]'); $q->setCustom('al_table', $this->table); $q->setCustom('field_name', $x = $field->actual_field ?: $field->short_name); $q->setCustom('type_expr', $this->db->dsql()->expr($this->resolveFieldType($field->type()))); $q->execute(); }
/** * Map field types Model Field --> DB field * * @param Field $field * * @return string */ protected function mapFieldType(\Field $field) { $type = $field->type(); // try to find mapping // if not found, then fall back to default type or model field type if (isset($this->mapping[$type])) { $db_type = $this->mapping[$type]; } else { $db_type = $this->default_type ?: $type; } // if no DB type found, then throw exception if (!$db_type) { throw $this->exception('No field type mapping found')->addMoreInfo('Model field type', $type); } // replace by template if any // template can be like varchar({length|255}) - $field->length() or $field->length or 255 preg_replace_callback('/{([^{]*?)}/i', function ($matches) use($field, &$db_type) { $vars = explode('|', $matches[1]); $vars = array_map('trim', $vars); for ($i = 0; $i < count($vars), $v = $vars[$i]; $i++) { if (method_exists($field, $v) && @$field->{$v}()) { // try to get from field method (surpress warnings because of setterGetter methods) $db_type = str_replace($matches[0], $field->{$v}(), $db_type); break; } elseif (property_exists($field, $v) && $field->{$v}) { // try to get from field property $db_type = str_replace($matches[0], $field->{$v}, $db_type); break; } elseif (is_numeric($v)) { // simply numeric constant $db_type = str_replace($matches[0], $v, $db_type); break; } elseif ($i == count($vars) - 1) { // if last variant, then simply use that as constant $db_type = str_replace($matches[0], $v, $db_type); break; } } }, $db_type); return $db_type; }
/** * Returns form field type associated with model field. * * Redefine this method to add special handling of your own fields. * * @param Field $field * * @return string */ public function getFieldType($field) { // default form field type $type = 'Line'; // try to find associated form field type if (isset($this->type_associations[$field->type()])) { $type = $this->type_associations[$field->type()]; } if ($field instanceof Field_Reference) { $type = 'DropDown'; } // if form field type explicitly set in model if ($field->display()) { $tmp = $field->display(); if (is_array($tmp)) { $tmp = $tmp['form']; } if ($tmp) { $type = $tmp; } } return $type; }
/** * Returns grid column type associated with model field. * * Redefine this method to add special handling of your own fields. * * @param Field $field * * @return string */ public function getFieldType($field) { // default column type $type = $field->type(); // try to find associated form field type if (isset($this->type_associations[$type])) { $type = $this->type_associations[$type]; } if ($type == 'text' && $field->allowHtml()) { $type = 'html'; } // if grid column type/formatter explicitly set in model if ($field->display()) { // @todo this is wrong and obsolete, as hasOne uses display for way different purpose $tmp = $field->display(); if (is_array($tmp)) { $tmp = $tmp['grid']; } if ($tmp) { $type = $tmp; } } return $type; }