public static function changesetToMigration(array $changeGroup) { if (ArrayLib::isDeepEmpty($changeGroup)) { return true; } foreach ($changeGroup as $changesets) { foreach ($changesets as $changeset) { foreach ($changeset['changes'] as $change) { } } } // MigrationGenerator::update() }
/** * Handles module updates and creations */ public function postModule() { // Validate the input $validated = $this->passInputThroughModuleValidation(true); // If validation passed and there are actual changes... if ($validated['message_bag'] === true && !ArrayLib::isDeepEmpty($validated['changes'])) { // Apply all changes \Photon\ModuleCreator::applyModuleChanges(\Input::get('module'), $validated['changes']); // Run migrations if needed if (\Input::has('run_migrations') && \Input::get('run_migrations', false)) { \Artisan::call('migrate'); } } }
/** * Compares an input to an existing module * * @param array $input Input data * @param array $module Original module data * * @return array */ public function compare(array $input = array(), array $module = array()) { $inputModule = $input; $inputUpdatedFields = isset($input['fields']) ? $input['fields'] : array(); $inputNewFields = empty($inputUpdatedFields) ? array() : (isset($inputUpdatedFields['new']) ? $inputUpdatedFields['new'] : array()); $originalModule = $module; $origF = isset($module['fields']) ? $module['fields'] : array(); $originalFields = ArrayLib::index($origF); unset($originalModule['fields']); unset($inputModule['fields']); unset($inputUpdatedFields['new']); $changesets = array('module' => $this->createChangesets(array($inputModule), array($originalModule), empty($originalModule) ? 'create' : 'update', 'module', 'name'), 'updated_fields' => $this->createChangesets($inputUpdatedFields, $originalFields, 'update'), 'created_fields' => $this->createChangesets($inputNewFields, array(), 'create'), 'deleted_fields' => $this->createChangesets($originalFields, $inputUpdatedFields, 'delete')); return $changesets; }
/** * Take the module creator form input and apply changes * * @param array $input * @param array $changeGroups * * @todo Break this up into smaller parts */ public function applyModuleChanges(array $input = array(), array $changeGroups = array()) { // Initialize needed variables $tableName = $input['table_name']; // Module table name $moduleId = $input['id']; // Module ID $moduleChangeset = ArrayLib::getKey(array_shift($changeGroups), 0); // Get the module changeset // Initialize the generator map array $generatorMap = array('created_fields' => array(), 'deleted_fields' => array(), 'updated_fields' => array()); // Define artisan generator methods to be used with generator map keys $generatorMethods = array('created_fields' => 'add', 'deleted_fields' => 'remove'); // If there's no module id, spawn a migration for creation of a new module if (!$moduleId) { MigrationGenerator::create($tableName); sleep(1); // Pause a second so succeeding migrations are named (ordered) properly } // Gather fields foreach ($changeGroups as $groupType => $changesets) { // Skip if we're dealing with updates if ($groupType === 'updated_fields') { continue; } foreach ($changesets as $changeset) { // Skip if changeset is empty if (!is_array($changeset['changes']) || empty($changeset['changes'])) { continue; } // Retrieve the column type of a current changeset $columnType = ArrayLib::getKey(ArrayLib::findByKeyValue($changeset['changes'], 'name', 'column_type') ?: array(), 'new'); // Retrieve the column name of a current changeset $columnName = ArrayLib::getKey(ArrayLib::findByKeyValue($changeset['changes'], 'name', 'column_name') ?: array(), 'new'); $generatorMap[$groupType][$columnName] = $columnType; } } // Generate migrations for new fields foreach ($generatorMap as $key => $fields) { // Check if a migration should be generated if (array_key_exists($key, $generatorMethods) && !empty($fields)) { // Bam! MigrationGenerator::$generatorMethods[$key]($tableName, array_filter($fields, function ($value) { return !empty($value); })); } } // Update model if (!empty($moduleChangeset['changes'])) { // Map of field => value entries $changemap = []; // Fill the changemap foreach ($moduleChangeset['changes'] as $change) { $changemap[$change['name']] = $change['new']; } // If module already exists, update it with new entries if ($moduleChangeset['item_id']) { \DB::table(\Orangehill\Photon\Module::getTableName())->where('table_name', $tableName)->update($changemap); } else { // Module doesn't exist yet, it should be created // Create a new module based on an form input entry $newModule = new Module($changemap); // Generate a model file $modelName = ucfirst(camel_case(str_singular($tableName))); \Artisan::call('generate:model', array('modelName' => $modelName)); // Store the path to the model file $pathToModel = app_path('models') . '/' . $modelName . '.php'; // Open the newly created file and make the model extend Baum's Node instead of Eloquent $fileContent = file_get_contents($pathToModel); $replaced = str_replace('extends \\Eloquent', 'extends Baum\\Node', $fileContent); // Try to find a name of first added column, fallback to the id $toStringField = 'id'; if (is_array($changeGroups['created_fields'])) { $head = head($changeGroups['created_fields']); if (is_array($head['changes'])) { foreach ($head['changes'] as $fieldSegment) { if ($fieldSegment['name'] == 'column_name') { $toStringField = $fieldSegment['new']; } } } } // Create a __toString method stub $toStringStub = StubFactory::make('ModelToStringMethod', array('field' => $toStringField))->append("\n}")->get(); // Add the method to the model files $replaced = substr_replace($replaced, $toStringStub, strrpos($replaced, '}')); file_put_contents($pathToModel, $replaced); // Save a model and update the module id $newModule->save(); $moduleId = $newModule->id; } } // Add newborn fields foreach ($changeGroups['created_fields'] as $field) { $fieldData = array('module_id' => $moduleId); foreach ($field['changes'] as $element) { $fieldData[$element['name']] = $element['new']; } $field = FieldCreator::make($fieldData); $field->save(); } // Update fields foreach ($changeGroups['updated_fields'] as $field) { $fieldData = array(); foreach ($field['changes'] as $element) { $fieldData[$element['name']] = $element['new']; } \DB::table(Field::getTableName())->where('id', $field['item_id'])->update($fieldData); } // Delete fields $deletedFieldIds = array_fetch($changeGroups['deleted_fields'], 'item_id') + array(0); $moduleFields = Field::whereIn('id', $deletedFieldIds)->get(); foreach ($moduleFields as $moduleField) { FieldFactory::make($moduleField)->uninstall(); } foreach ($changeGroups['deleted_fields'] as $field) { \DB::table(Field::getTableName())->where('id', $field['item_id'])->delete(); } }