sourceModel = $source; } /** * generate */ public function inspect($blueprint) { $this->setBlueprintContext($blueprint); $result = [ 'controllerFile' => null, 'modelFiles' => [], 'migrationFiles' => [], 'errorMessage' => null ]; try { if ($model = $this->makeControllerModel()) { $result['controllerFile'] = $model->getControllerFilePath(); } if ($model = $this->makeModelModel()) { $result['modelFiles'][] = $model->getModelFilePath(); } foreach ($this->makeExpandoModels(true) as $model) { $result['modelFiles'][] = $model->getModelFilePath(); } $result['migrationFiles'] = array_keys($this->inspectMigrations()); } catch (Throwable $ex) { $result['errorMessage'] = $ex->getMessage(); } return $result; } /** * generate */ public function generate() { $this->templateVars = []; $this->filesGenerated = []; $this->filesValidated = []; $this->blueprintFiles = []; $this->migrationScripts = []; $this->sourceBlueprints = []; $this->loadSourceBlueprints(); $this->validateNavigation(); // Validate foreach ($this->sourceBlueprints as $blueprint) { $this->setBlueprintContext($blueprint); $this->validateModel(); $this->validateExpandoModels(); $this->validateController(); $this->validatePermission(); } // Generate try { foreach ($this->sourceBlueprints as $blueprint) { $this->setBlueprintContext($blueprint); $this->generateMigrations(); $this->generateModel(); $this->generateExpandoModels(); $this->generateController(); $this->generatePermission(); $this->blueprintFiles[] = $blueprint->getFilePath(); } } catch (Throwable $ex) { $this->rollback(); throw $ex; } $this->generateNavigation(); $this->generateVersionUpdate(); if ($this->sourceModel->deleteBlueprintData) { $this->deleteGeneratedBlueprintData(); } if ($this->sourceModel->disableBlueprints) { $this->disableGeneratedBlueprints(); } } /** * loadSourceBlueprints */ protected function loadSourceBlueprints() { $blueprintLib = TailorBlueprintLibrary::instance(); foreach ($this->sourceModel->blueprints as $uuid => $config) { $blueprint = $blueprintLib->getBlueprintObject($uuid); if ($blueprint) { $this->sourceBlueprints[$uuid] = $blueprint; } } } /** * setBlueprintContext */ protected function setBlueprintContext($blueprint) { $config = $this->sourceModel->blueprints[$blueprint->uuid] ?? []; $this->sourceModel->setBlueprintContext($blueprint, $config); $this->setTemplateVars(); } /** * disableGeneratedBlueprints */ protected function disableGeneratedBlueprints() { foreach ($this->blueprintFiles as $filePath) { File::move( $filePath, str_replace('.yaml', '.yaml.bak', $filePath) ); } } /** * deleteGeneratedBlueprintData */ protected function deleteGeneratedBlueprintData() { foreach ($this->sourceBlueprints as $blueprint) { $contentTable = $blueprint->getContentTableName(); Schema::dropIfExists($contentTable); $joinTable = $blueprint->getJoinTableName(); Schema::dropIfExists($joinTable); $repeaterTable = $blueprint->getRepeaterTableName(); Schema::dropIfExists($repeaterTable); } } /** * setTemplateVars */ protected function setTemplateVars() { $pluginCodeObj = $this->sourceModel->getPluginCodeObj(); $this->templateVars = $this->getConfig(); $this->templateVars['pluginNamespace'] = $pluginCodeObj->toPluginNamespace(); $this->templateVars['pluginCode'] = $pluginCodeObj->toCode(); } /** * getTemplatePath */ protected function getTemplatePath($template) { return __DIR__.'/blueprintgenerator/templates/'.$template; } /** * parseTemplate */ protected function parseTemplate($templatePath, $vars = []) { $template = File::get($templatePath); $vars = array_merge($this->templateVars, $vars); $code = Twig::parse($template, $vars); return $code; } /** * writeFile */ protected function writeFile($path, $data) { $fileDirectory = dirname($path); if (!File::isDirectory($fileDirectory)) { if (!File::makeDirectory($fileDirectory, 0777, true, true)) { throw new ApplicationException(Lang::get('rainlab.builder::lang.common.error_make_dir', [ 'name' => $fileDirectory ])); } } if (@File::put($path, $data) === false) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_save_file', [ 'file' => basename($path) ])); } @File::chmod($path); $this->filesGenerated[] = $path; } /** * rollback */ protected function rollback() { foreach ($this->filesGenerated as $path) { @unlink($path); } } /** * makeTabs */ protected function makeTabs($str) { return str_replace('\t', ' ', $str); } /** * getConfig */ protected function getConfig($key = null, $default = null) { return $this->sourceModel->getBlueprintConfig($key, $default); } /** * validateUniqueFiles */ protected function validateUniqueFiles(array $files) { if (!is_array($this->filesValidated)) { $this->filesValidated = []; } foreach ($files as $path) { if (File::isFile($path) || in_array($path, $this->filesValidated)) { throw new ValidationException([ 'modelClass' => __("File [:file] already exists when trying to import [:blueprint]", [ 'file' => basename(dirname($path)) . '/' . basename($path), 'blueprint' => $this->sourceModel->getBlueprintObject()->handle ?? 'unknown' ]) ]); } } $this->filesValidated = array_merge($this->filesValidated, $files); } }