private function sqlChange(ObjectParameter $instance, $mode = null) { $idObject = $instance->id_object; if ($idObject == null) { return false; } $isDelete = $mode == 'delete'; $isInsert = $mode == 'insert'; $objectCurrent = DaObject::getById($idObject); $table = $objectCurrent->table_name; $type = $instance->getDataType(); $fieldName = $instance->getFieldName(); if ($objectCurrent->object_type != DaObject::OBJECT_TYPE_TABLE) { return false; } if ($table == null) { if (Yii::app()->isBackend) { Yii::app()->addMessage('Свойство не было ' . ($isDelete ? 'удалено' : ($isInsert ? 'создано' : 'изменено')) . ' в базе данных, т.к. у объекта не указано имя таблицы', BackendApplication::MESSAGE_TYPE_ERROR, true); } return false; } $tableNotExists = Yii::app()->db->createCommand('SHOW TABLES LIKE :t')->queryScalar(array(':t' => $objectCurrent->table_name)) == null; $sqls = array(); $allowQuery = true; $abstractCurrent = DataType::getSqlType($type) == null; $instanceOld = null; if ($isDelete) { $instanceOld = $instance; } else { if (!$isInsert) { $instanceOld = ObjectParameter::model()->findByIdInstance($instance->getIdInstance()); if ($instanceOld == null) { // такой вариант может быть только в случае, если у параметра поменяли ИД. Тогда мы не можем найти старый параметр и не можем понять какие были данные. Поэтому ничего не делаем. return; } } } // Если поле меняется, загружаем старые данные и проверяем, поменялось ли что-то if (!$isInsert && !$isDelete) { $isTypeChange = DataType::getSqlType($instanceOld->getDataType()) != DataType::getSqlType($type); $allowQuery = $instanceOld->getFieldName() != $fieldName || $isTypeChange || $instanceOld->getDefaultValue() != $instance->getDefaultValue() || $instanceOld->isRequired() != $instance->isRequired(); if ($isTypeChange) { // если тип поля меняется с SQL на абстрактный - удаляем поле if ($abstractCurrent && DataType::getSqlType($instanceOld->getDataType()) != null) { $sqls[] = 'ALTER TABLE `' . $table . '` DROP `' . $instanceOld->getFieldName() . '`'; // наоборот, если тип поля меняется с абстрактного на SQL - добавляем поле } else { if (!$abstractCurrent && DataType::getSqlType($instanceOld->getDataType()) == null) { $isInsert = true; } } } } $msg = ''; // Составляем запросы if ($allowQuery && !$abstractCurrent) { $fieldExists = false; $countFields = 0; if (!$tableNotExists) { $columns = Yii::app()->db->createCommand('SHOW COLUMNS FROM ' . $table)->queryAll(); if ($instanceOld != null) { $fieldName = $instanceOld->getFieldName(); } foreach ($columns as $column) { if ($column['Field'] == $fieldName) { $fieldExists = true; } $countFields++; } } if ((!$isInsert || $isDelete) && !$fieldExists) { $allowQuery = false; $msg = 'В таблице ' . $table . ' не существует поля "' . $instanceOld->getFieldName() . '"'; } if ($isInsert && $fieldExists) { $allowQuery = false; $msg = 'В таблице ' . $table . ' уже существует поле "' . $instance->getFieldName() . '"'; } // TODO проверки еще [Field] => person_type [Type] => int(8) [Null] => YES [Key] => [Default] => [Extra] => if ($allowQuery) { if ($isDelete) { if ($countFields == 1) { $sqls[] = 'DROP TABLE `' . $table . '`'; } else { $sqls[] = 'ALTER TABLE `' . $table . '` DROP `' . $instance->getFieldName() . '`'; } } else { $definition = '`' . $instance->getFieldName() . '` ' . DataType::getSqlType($type); if ($instance->isRequired()) { $definition .= ' NOT NULL'; } if ($instance->getDefaultValue() != null && !in_array($type, array(DataType::TEXTAREA, DataType::EDITOR))) { $definition .= ' default \'' . $instance->getDefaultValue() . '\''; } if ($type == DataType::PRIMARY_KEY) { $definition .= ' AUTO_INCREMENT'; } $definition .= ' COMMENT ' . $this->dbConnection->quoteValue($instance->getCaption()); // Создаем таблицу с полем if ($tableNotExists) { $sqls[] = $objectCurrent->getCreateTableSql(); // Таблица уже существует } else { $sql = 'ALTER TABLE `' . $table . '`'; if ($isInsert) { $sql .= ' ADD ' . $definition . ' '; } else { $sql .= ' CHANGE `' . $instanceOld->getFieldName() . '` ' . $definition . ' '; } $sqls[] = $sql; if ($isInsert) { if ($type == DataType::PRIMARY_KEY) { $sqls[] = 'ALTER TABLE `' . $table . '` ADD PRIMARY KEY (`' . $fieldName . '`)'; } if ($instance->isUnique()) { $sqls[] = 'ALTER TABLE `' . $table . '` ADD UNIQUE (`' . $fieldName . '`)'; } } } } } } foreach ($sqls as $sql) { Yii::app()->db->createCommand($sql)->execute(); $msg .= 'Выполнено: ' . $sql . '<br>'; } if ($msg != '') { if (Yii::app()->isBackend) { Yii::app()->addMessage($msg); } } }
/** * @static * @param ObjectParameter $objectParameter * @param DaActiveRecord $model * @return VisualElementBaseWidget|null */ public static function getVisualElement(DaActiveRecord $model, ObjectParameter $objectParameter) { if (mb_strpos($objectParameter->widget, '.') !== false) { $className = Yii::import($objectParameter->widget, true); $visualElement = Yii::app()->controller->createWidget($className, array('model' => $model, 'objectParameter' => $objectParameter, 'attributeName' => $objectParameter->getFieldName())); return $visualElement; } $type = $objectParameter->getType(); $visualElement = null; switch ($type) { case DataType::HIDDEN: $visualElement = Yii::app()->controller->createWidget('backend.widgets.hiddenField.HiddenFieldWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::VARCHAR: case DataType::INT: $visualElement = Yii::app()->controller->createWidget('backend.widgets.textField.TextFieldWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::PRIMARY_KEY: if ($objectParameter->getAdditionalParameter() == 1 && Yii::app()->user->checkAccess(DaWebUser::ROLE_DEV)) { $objectParameter->setIsRequired(false); if ($model->isNewRecord) { //$objectParameter->caption .= " (НЕ заполнять - автозаполнение)"; if ($objectParameter->hint == null) { $objectParameter->hint = "Поле следует заполнять вручную в редких случаях, когда идет работа с первичным ключом строкой и нет автоинкремента"; } } else { //$objectParameter->caption .= " (НЕ изменять - зависимости)"; if ($objectParameter->hint == null) { $objectParameter->hint = "Поле следует менять крайне осторожно, т.к. не контролируются зависимости данных"; } } $visualElement = Yii::app()->controller->createWidget('backend.widgets.textField.TextFieldWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName(), 'objectParameter' => $objectParameter)); } break; case DataType::BOOLEAN: $visualElement = Yii::app()->controller->createWidget('backend.widgets.checkBox.CheckBoxWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::ABSTRACTIVE: $className = Yii::import($objectParameter->widget, true); $visualElement = Yii::app()->controller->createWidget($className, array('model' => $model, 'objectParameter' => $objectParameter, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::TEXTAREA: $visualElement = Yii::app()->controller->createWidget('backend.widgets.textarea.TextareaWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::EDITOR: $visualElement = Yii::app()->controller->createWidget('backend.widgets.tinymce.TinymceWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::ID_PARENT: $visualElement = Yii::app()->controller->createWidget('backend.widgets.dropDownList.DropDownParentWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::OBJECT: $visualElement = Yii::app()->controller->createWidget('backend.widgets.dropDownList.DropDownObjectWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName(), 'objectParameter' => $objectParameter)); break; case DataType::REFERENCE: $visualElement = Yii::app()->controller->createWidget('backend.widgets.dropDownList.DropDownReferenceWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::TIMESTAMP: $visualElement = Yii::app()->controller->createWidget('backend.widgets.dateTime.DateTimeWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::FILE: $visualElement = Yii::app()->controller->createWidget('backend.widgets.upload.singleFileUpload.SingleFileUploadWidget', array('model' => $model, 'attributeName' => $objectParameter->getFieldName())); break; case DataType::FILES: $visualElement = Yii::app()->controller->createWidget('backend.widgets.upload.listFileUpload.ListFileUploadWidget', array('model' => $model, 'objectParameter' => $objectParameter)); break; } return $visualElement; }