public function actionIndex() { try { // sart time measuremnt $start = microtime(true); if ($this->verbose) { $this->output('[==================== VERBOSE ====================]'); } $container = new CrawlContainer(['baseUrl' => $this->module->baseUrl, 'filterRegex' => $this->module->filterRegex, 'verbose' => $this->verbose, 'doNotFollowExtensions' => $this->module->doNotFollowExtensions, 'useH1' => $this->module->useH1]); if ($this->verbose) { $this->output('[================== VERBOSE END ==================]'); } $timeElapsed = round((microtime(true) - $start) / 60, 2); $this->outputInfo('CRAWLER REPORT:'); foreach ($container->getReport() as $type => $items) { if (count($items) > 0) { $this->outputInfo(PHP_EOL . ' ' . $type . ':'); foreach ($items as $message) { $this->output(' - ' . $message); } } } $this->outputInfo(PHP_EOL . 'memory usage: ' . FileHelper::humanReadableFilesize(memory_get_usage())); $this->outputInfo('memory peak usage: ' . FileHelper::humanReadableFilesize(memory_get_peak_usage())); return $this->outputSuccess(PHP_EOL . 'Crawler finished in ' . $timeElapsed . ' min.'); } catch (\Exception $e) { return $this->outputError('Exception in file "' . $e->getFile() . '" on line #' . $e->getLine() . ': ' . $e->getMessage()); } }
/** * Create new migration, first param the name, second param the module where the migration should be put in. * * @param string $name The name of the migration * @param string|boolean $module The module name where the migration should be placed in. * @todo replace module param with user teminal selection. * @see \yii\console\controllers\BaseMigrateController::actionCreate() */ public function actionCreate($name, $module = false) { if (!preg_match('/^\\w+$/', $name)) { throw new Exception('The migration name should contain letters, digits and/or underscore characters only.'); } $name = 'm' . gmdate('ymd_His') . '_' . $name; if (!$module) { $file = $this->migrationPath . DIRECTORY_SEPARATOR . $name . '.php'; } else { if (($folder = $this->getModuleMigrationDirectorie($module)) === false) { $this->stdout("\nModule '{$module}' does not exist.\n", Console::FG_RED); return self::EXIT_CODE_ERROR; } $file = $folder . DIRECTORY_SEPARATOR . $name . '.php'; } if ($this->confirm("Create new migration '{$file}'?")) { $content = $this->renderFile(Yii::getAlias($this->templateFile), ['className' => $name]); if (!file_exists($folder)) { FileHelper::createDirectory($folder, 0775, false); } file_put_contents($file, $content); $this->stdout("\nMigration created successfully.\n", Console::FG_GREEN); return self::EXIT_CODE_NORMAL; } }
public static function getFindFilesDirectory() { $path = Yii::$app->storage->serverPath; if (is_dir($path) && file_exists($path)) { return FileHelper::findFiles($path, ['except' => ['.*']]); } return false; }
public function actionIndex() { $hash = time(); $cacheFolder = Yii::getAlias('@runtime/exporter/' . $hash); FileHelper::createDirectory($cacheFolder); $dump = new Mysqldump\Mysqldump(Yii::$app->db->dsn, Yii::$app->db->username, Yii::$app->db->password); $dump->start($cacheFolder . '/mysql.sql'); FileHelper::copyDirectory(Yii::getAlias('@web/public_html/storage'), $cacheFolder . '/storage'); $save = Yii::getAlias($this->module->downloadFile); @unlink($save); ZipHelper::dir($cacheFolder . '/', $save); }
public function actionExportDownload($key) { $sessionkey = Yii::$app->session->get('tempNgRestKey'); $fileName = Yii::$app->session->get('tempNgRestFileName'); if ($sessionkey !== base64_decode($key)) { throw new Exception('Invalid Export download key.'); } $content = FileHelper::getFileContent('@runtime/' . $sessionkey . '.tmp'); Yii::$app->session->remove('tempNgRestKey'); Yii::$app->session->remove('tempNgRestFileName'); @unlink(Yii::getAlias('@runtime/' . $sessionkey . '.tmp')); return Yii::$app->response->sendContentAsFile($content, $fileName . '-export-' . date("Y-m-d-H-i") . '.csv', ['mimeType' => 'application/csv']); }
public function run() { $cmslayouts = Yii::getAlias('@app/views/cmslayouts'); $layoutFiles = []; if (file_exists($cmslayouts)) { $files = FileHelper::findFiles($cmslayouts, ['recursive' => false, 'filter' => function ($path) { return !in_array(substr(basename($path), 0, 1), $this->ignorePrefix); }]); foreach ($files as $file) { $fileinfo = FileHelper::getFileInfo($file); $fileBaseName = $fileinfo->name . '.' . $fileinfo->extension; $readableFileName = $this->generateReadableName($fileinfo->name); $oldTwigName = $fileinfo->name . '.twig'; if ($fileinfo->extension !== 'php') { throw new Exception("layout file '{$file}': Since 1.0.0-beta6, cms layouts must be a php file with '<?= \$placeholders['content']; ?>' instead of a twig '{{placeholders.content}}'"); } $layoutFiles[] = $fileBaseName; $layoutFiles[] = $oldTwigName; $content = file_get_contents($file); preg_match_all("/placeholders\\[[\\'\"](.*?)[\\'\"]\\]/", $content, $results); $_placeholders = []; foreach (array_unique($results[1]) as $holderName) { if (!$this->verifyVariable($holderName)) { throw new Exception("Wrong variable name detected '" . $holderName . "'. Special chars are not allowed in placeholder variables, allowed chars are a-zA-Z0-9"); } $_placeholders[] = ['label' => $this->generateReadableName($holderName), 'var' => $holderName]; } $_placeholders = ['placeholders' => $_placeholders]; $layoutItem = Layout::find()->where(['or', ['view_file' => $fileBaseName], ['view_file' => $oldTwigName]])->one(); if ($layoutItem) { $match = $this->comparePlaceholders($_placeholders, json_decode($layoutItem->json_config, true)); if ($match) { $layoutItem->updateAttributes(['name' => $readableFileName, 'view_file' => $fileBaseName]); } else { $layoutItem->updateAttributes(['name' => $readableFileName, 'view_file' => $fileBaseName, 'json_config' => json_encode($_placeholders)]); $this->addLog('existing cmslayout ' . $readableFileName . ' updated'); } } else { // add item into the database table $data = new Layout(); $data->scenario = 'restcreate'; $data->setAttributes(['name' => $readableFileName, 'view_file' => $fileBaseName, 'json_config' => json_encode($_placeholders)]); $data->save(false); $this->addLog('new cmslayout ' . $readableFileName . ' found and added to database.'); } } foreach (Layout::find()->where(['not in', 'view_file', $layoutFiles])->all() as $layoutItem) { $layoutItem->delete(); } } }
/** * Create a new ActiveWindow class based on you properties. */ public function actionCreate() { $name = $this->prompt("Please enter a name for the Active Window:", ['required' => true]); $className = $this->createClassName($name, $this->suffix); $moduleId = $this->selectModule(['text' => 'What module should ' . $className . ' belong to?', 'onlyAdmin' => true]); $module = Yii::$app->getModule($moduleId); $folder = $module->basePath . DIRECTORY_SEPARATOR . 'aws'; $file = $folder . DIRECTORY_SEPARATOR . $className . '.php'; $content = $this->renderWindowClassView($className, $module->getNamespace() . '\\aws', $moduleId); FileHelper::createDirectory($folder); if (FileHelper::writeFile($file, $content)) { return $this->outputSuccess("The Active Window file '{$file}' has been writtensuccessfull."); } return $this->outputError("Error while writing the Actice Window file '{$file}'."); }
/** * Create a new ActiveWindow class based on you properties. */ public function actionCreate() { $name = $this->prompt("Please enter a name for the Active Window:", ['required' => true]); $className = $this->createClassName($name, $this->suffix); $moduleId = $this->selectModule(['text' => 'What module should ' . $className . ' belong to?', 'onlyAdmin' => true]); $module = Yii::$app->getModule($moduleId); $folder = $module->basePath . DIRECTORY_SEPARATOR . 'aws'; $file = $folder . DIRECTORY_SEPARATOR . $className . '.php'; $content = $this->view->render('@luya/console/commands/views/aw/create.php', ['className' => $className, 'namespace' => $module->getNamespace() . '\\aws', 'luya' => $this->getLuyaVersion(), 'moduleId' => $moduleId, 'alias' => Inflector::humanize(Inflector::camel2words($className))]); FileHelper::createDirectory($folder); if (FileHelper::writeFile($file, $content)) { return $this->outputSuccess("The Active Window file '{$file}' has been writtensuccessfull."); } return $this->outputError("Error while writing the Actice Window file '{$file}'."); }
/** * Create a zip file with database dump and storage files/images and stores the zip in * the runtime folder. * * @return void */ public function actionIndex() { $hash = time(); $cacheFolder = Yii::getAlias('@runtime/exporter/' . $hash); $this->verbosePrint("cache folder {$cacheFolder}"); FileHelper::createDirectory($cacheFolder, 0777); $dump = new Mysqldump\Mysqldump(Yii::$app->db->dsn, Yii::$app->db->username, Yii::$app->db->password); $dump->start($cacheFolder . '/mysql.sql'); $source = Yii::getAlias('@web/public_html/storage'); $this->verbosePrint("storage source folder {$source}"); if (is_link($source)) { $source = readlink($source); $this->verbosePrint("source is a symlink, readlink output: " . $source); } FileHelper::copyDirectory($source, $cacheFolder . '/storage', ['dirMode' => 0777, 'fileMode' => 0775]); $save = Yii::getAlias($this->module->downloadFile); if (file_exists($save)) { $this->verbosePrint("a exporter file does already exists, unlink file: " . $save); @unlink($save); } ZipHelper::dir($cacheFolder . '/', $save); }
/** * Method to render twig files with theyr specific arguments, can be used inside the element closure depending * on where the closure was registered. Otherwhise the use of the element variable must be provided. * * @param string $file The name of the file to render. * @param array $args The parameters to pass in the render file. * * @return string The render value of the view file. */ public function render($file, array $args = []) { $twig = Yii::$app->twig->env(new Twig_Loader_Filesystem($this->getFolder())); return $twig->render(FileHelper::appendExtensionToString($file, 'twig'), $args); }
public function getSizeReadable() { return FileHelper::humanReadableFilesize($this->getSize()); }
public function testGetHashFile() { $this->assertSame(false, FileHelper::getFileHash('notexists.jpg')); $this->assertSame('7dff5cc5a1d8f04004b4a0075d3eeeae', FileHelper::getFileHash(__DIR__ . '/../../data/hashfile.txt')); }
/** * Create Ng-Rest-Model, Controller and Api for an existing Database-Table. * * @return number */ public function actionCreate() { if ($this->moduleName === null) { Console::clearScreenBeforeCursor(); $this->moduleName = $this->selectModule(['onlyAdmin' => true, 'hideCore' => true, 'text' => 'Select the Module where the CRUD files should be saved:']); } if ($this->modelName === null) { $modelSelection = true; while ($modelSelection) { $modelName = $this->prompt('Model Name (e.g. Album):', ['required' => true]); $camlizeModelName = Inflector::camelize($modelName); if ($modelName !== $camlizeModelName) { if ($this->confirm("We have camlized the model name to '{$camlizeModelName}' do you want to continue with this name?")) { $modelName = $camlizeModelName; $modelSelection = false; } } else { $modelSelection = false; } $this->modelName = $modelName; } } if ($this->apiEndpoint === null) { $this->apiEndpoint = $this->prompt('Api Endpoint:', ['required' => true, 'default' => $this->getApiEndpointSuggestion()]); } if ($this->dbTableName === null) { $sqlSelection = true; while ($sqlSelection) { $sqlTable = $this->prompt('Database Table name for the Model:', ['required' => true, 'default' => $this->getDatabaseNameSuggestion()]); if ($sqlTable == '?') { foreach ($this->getSqlTablesArray() as $table) { $this->outputInfo("- " . $table); } } if (isset($this->getSqlTablesArray()[$sqlTable])) { $this->dbTableName = $sqlTable; $sqlSelection = false; } else { $this->outputError("The selected database '{$sqlTable}' does not exists in the list of tables. Type '?' to see all tables."); } } } if ($this->enableI18n === null) { $this->enableI18n = $this->confirm("Would you like to enable i18n field input for text fields? Only required for multilingual pages."); } $this->ensureBasePathAndNamespace(); $files = []; // api content $files['api'] = ['path' => $this->getBasePath() . DIRECTORY_SEPARATOR . 'apis', 'fileName' => $this->getModelNameCamlized() . 'Controller.php', 'content' => $this->generateApiContent($this->getNamespace() . '\\apis', $this->getModelNameCamlized() . 'Controller', $this->getAbsoluteModelNamespace())]; // controller $files['controller'] = ['path' => $this->getBasePath() . DIRECTORY_SEPARATOR . 'controllers', 'fileName' => $this->getModelNameCamlized() . 'Controller.php', 'content' => $this->generateControllerContent($this->getNamespace() . '\\controllers', $this->getModelNameCamlized() . 'Controller', $this->getAbsoluteModelNamespace())]; // model $files['model'] = ['path' => $this->getModelBasePath() . DIRECTORY_SEPARATOR . 'models', 'fileName' => $this->getModelNameCamlized() . '.php', 'content' => $this->generateModelContent($this->getModelNamespace() . '\\models', $this->getModelNameCamlized(), $this->apiEndpoint, $this->getDbTableShema(), $this->enableI18n)]; foreach ($files as $file) { FileHelper::createDirectory($file['path']); if (file_exists($file['path'] . DIRECTORY_SEPARATOR . $file['fileName'])) { if (!$this->confirm("The File '{$file['fileName']}' already exists, do you want to override the existing file?")) { continue; } } if (FileHelper::writeFile($file['path'] . DIRECTORY_SEPARATOR . $file['fileName'], $file['content'])) { $this->outputSuccess("Wrote file '{$file['fileName']}'."); } else { $this->outputError("Error while writing file '{$file['fileName']}'."); } } return $this->outputSuccess($this->generateBuildSummery($this->apiEndpoint, $this->getNamespace() . '\\apis\\' . $this->getModelNameCamlized() . 'Controller', $this->getModelNameCamlized(), $this->getSummaryControllerRoute())); }
/** * Method to render twig files with theyr specific arguments, can be used inside the element closure depending * on where the closure was registered. Otherwhise the use of the element variable must be provided. * * @param string $file The name of the file to render. * @param array $args The parameters to pass in the render file. * * @return string The render value of the view file. */ public function render($file, array $args = []) { if ($this->renderEngine == 'php') { $view = new View(); return $view->renderPhpFile(rtrim($this->getFolder(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . FileHelper::ensureExtension($file, 'php'), $args); } elseif ($this->renderEngine == 'twig') { // @deprecated 1.0.0-RC2 Marked as deprecated and will be removed on 1.0.0 release. $twig = Yii::$app->twig->env(new Twig_Loader_Filesystem($this->getFolder())); return $twig->render(FileHelper::ensureExtension($file, 'twig'), $args); } throw new Exception('Not supported render engine: ' . $this->renderEngine); }
/** * @todo its a copy from the old colde, refactor code * @param string $fileSource * @param string $fileName * @param int $folderId */ public function addFile($fileSource, $fileName, $folderId = 0, $isHidden = false) { if (empty($fileSource) || empty($fileName)) { throw new Exception("Unable to create file where file source and/or file name is empty."); } $fileInfo = FileHelper::getFileInfo($fileName); $baseName = Inflector::slug($fileInfo->name, '-'); $fileHashName = Storage::createFileHash($fileName); $fileHash = FileHelper::getFileHash($fileSource); $mimeType = FileHelper::getMimeType($fileSource); $newName = implode([$baseName . '_' . $fileHashName, $fileInfo->extension], '.'); $savePath = $this->serverPath . '/' . $newName; if (is_uploaded_file($fileSource)) { if (!@move_uploaded_file($fileSource, $savePath)) { throw new Exception("error while moving uploaded file from {$fileSource} to {$savePath}"); } } else { if (!@copy($fileSource, $savePath)) { throw new Exception("error while copy file from {$fileSource} to {$savePath}."); } } $model = new StorageFile(); $model->setAttributes(['name_original' => $fileName, 'name_new' => $baseName, 'name_new_compound' => $newName, 'mime_type' => $mimeType, 'extension' => strtolower($fileInfo->extension), 'folder_id' => (int) $folderId, 'hash_file' => $fileHash, 'hash_name' => $fileHashName, 'is_hidden' => $isHidden ? 1 : 0, 'file_size' => @filesize($savePath)]); if ($model->validate()) { if ($model->save()) { $this->deleteHasCache($this->fileCacheKey); $this->_filesArray[$model->id] = $model->toArray(); return $this->getFile($model->id); } } return false; }
/** * Returns all controller files of this module from the `getControllerPath()` folder, where the key is the reusable * id of this controller and value the file on the server. * * @return array Returns an array where the key is the controller id and value the original file. * @since 1.0.0-beta5 */ public function getControllerFiles() { try { // https://github.com/yiisoft/yii2/blob/master/framework/base/Module.php#L233 $files = []; foreach (FileHelper::findFiles($this->controllerPath) as $file) { $value = ltrim(str_replace([$this->controllerPath, 'Controller.php'], '', $file), DIRECTORY_SEPARATOR); $files[Inflector::camel2id($value)] = $file; } return $files; } catch (InvalidParamException $e) { return []; } }
protected function getUploadFolder() { $folder = Yii::getAlias('@runtime/flow-upload'); if (!file_exists($folder)) { FileHelper::createDirectory($folder, 0777); } return $folder; }
/** * Prepare a temp file to * @todo added very basic csv support, must be stored as class, just a temp solution * @return array */ public function actionExport() { $tempData = null; // first row $header = []; $i = 0; foreach ($this->model->find()->all() as $key => $value) { $row = []; $attrs = $value->getAttributes(); foreach ($value->extraFields() as $field) { $attrs[$field] = $value->{$field}; } foreach ($attrs as $k => $v) { if (is_object($v)) { if ($v instanceof Arrayable) { $v = $v->toArray(); } else { continue; } } if ($i === 0) { $header[] = $this->model->getAttributeLabel($k); } if (is_array($v)) { $tv = []; foreach ($v as $kk => $vv) { if (is_object($vv)) { if ($vv instanceof Arrayable) { $tv[] = implode(" | ", $vv->toArray()); } else { continue; } } elseif (is_array($vv)) { $tv[] = implode(" | ", $vv); } else { $tv[] = $vv; } } $v = implode(" - ", $tv); } $row[] = '"' . str_replace('"', '\\"', $v) . '"'; } if ($i === 0) { $tempData .= implode(",", $header) . "\n"; } $tempData .= implode(",", $row) . "\n"; $i++; } $key = uniqid('ngre', true); $store = FileHelper::writeFile('@runtime/' . $key . '.tmp', $tempData); if ($store) { Yii::$app->session->set('tempNgRestFileName', Inflector::slug($this->model->tableName())); Yii::$app->session->set('tempNgRestKey', $key); return ['url' => Url::toRoute(['/admin/ngrest/export-download', 'key' => base64_encode($key)])]; } throw new ErrorException("Unable to write the temporary file for the csv export. Make sure the runtime folder is writeable."); }
/** * Returns all controller files of this module from the `getControllerPath()` folder, where the key is the reusable * id of this controller and value the file on the server. * * @return array Returns an array where the key is the controller id and value the original file. * @since 1.0.0-beta5 */ public function getControllerFiles() { $files = []; foreach (FileHelper::findFiles($this->controllerPath) as $file) { $value = ltrim(str_replace([$this->controllerPath, 'Controller.php'], '', $file), '/'); $files[Inflector::camel2id($value)] = $file; } return $files; }
/** * Wizzard to create a new CMS block. * * @return number */ public function actionCreate() { if (empty($this->type)) { Console::clearScreenBeforeCursor(); $this->type = $this->select('Do you want to create an app or module Block?', [self::TYPE_APP => 'Creates a project block inside your @app Namespace (casual).', self::TYPE_MODULE => 'Creating a block inside a later specified Module.']); } if ($this->type == self::TYPE_MODULE && count($this->getModuleProposal()) === 0) { return $this->outputError('Your project does not have Project-Modules registered!'); } if (empty($this->moduleName) && $this->type == self::TYPE_MODULE) { $this->moduleName = $this->select('Choose a module to create the block inside:', $this->getModuleProposal()); } if (empty($this->blockName)) { $this->blockName = $this->prompt('Insert a name for your Block (e.g. HeadTeaser):', ['required' => true]); } if ($this->isContainer === null) { $this->isContainer = $this->confirm("Do you want to add placeholders to your block that serve as a container for nested blocks?", false); } if ($this->cacheEnabled === null) { $this->cacheEnabled = $this->confirm("Do you want to enable the caching for this block or not?", true); } if ($this->config === null) { $this->config = ['vars' => [], 'cfgs' => [], 'placeholders' => []]; $doConfigure = $this->confirm('Would you like to configure this Block? (vars, cfgs, placeholders)', false); if ($doConfigure) { $doVars = $this->confirm('Add new Variable (vars)?', false); $i = 1; while ($doVars) { $item = $this->varCreator('Variabel (vars) #' . $i, 'var'); $this->phpdoc[] = '{{vars.' . $item['var'] . '}}'; $this->viewFileDoc[] = '$this->varValue(\'' . $item['var'] . '\');'; $this->config['vars'][] = $item; $doVars = $this->confirm('Add one more?', false); ++$i; } $doCfgs = $this->confirm('Add new Configuration (cgfs)?', false); $i = 1; while ($doCfgs) { $item = $this->varCreator('Configration (cfgs) #' . $i, 'cfg'); $this->phpdoc[] = '{{cfgs.' . $item['var'] . '}}'; $this->viewFileDoc[] = '$this->cfgValue(\'' . $item['var'] . '\');'; $this->config['cfgs'][] = $item; $doCfgs = $this->confirm('Add one more?', false); ++$i; } $doPlaceholders = $this->confirm('Add new Placeholder (placeholders)?', false); $i = 1; while ($doPlaceholders) { $item = $this->placeholderCreator('Placeholder (placeholders) #' . $i); $this->phpdoc[] = '{{placeholders.' . $item['var'] . '}}'; $this->viewFileDoc[] = '$this->placeholderValue(\'' . $item['var'] . '\');'; $this->config['placeholders'][] = $item; $doPlaceholders = $this->confirm('Add one more?', false); ++$i; } } } $folder = $this->getFileBasePath() . DIRECTORY_SEPARATOR . 'blocks'; $filePath = $folder . DIRECTORY_SEPARATOR . $this->blockName . '.php'; sort($this->phpdoc); $content = $this->view->render('@luya/console/commands/views/block/create_block.php', ['namespace' => $this->getFileNamespace(), 'className' => $this->blockName, 'name' => Inflector::camel2words($this->blockName), 'type' => $this->type, 'module' => $this->moduleName, 'isContainer' => $this->isContainer, 'cacheEnabled' => $this->cacheEnabled, 'config' => $this->config, 'phpdoc' => $this->phpdoc, 'extras' => $this->extras, 'luyaText' => $this->getGeneratorText('block/create')]); if ($this->dryRun) { return $content; } if (FileHelper::createDirectory($folder) && FileHelper::writeFile($filePath, $content)) { // generate view file based on block object view context $object = Yii::createObject(['class' => $this->getFileNamespace() . '\\' . $this->blockName]); $viewsFolder = Yii::getAlias($object->getViewPath()); $viewFilePath = $viewsFolder . DIRECTORY_SEPARATOR . $object->getViewFileName('php'); if (FileHelper::createDirectory($viewsFolder) && FileHelper::writeFile($viewFilePath, $this->generateViewFile($this->blockName))) { $this->outputInfo('View file for the block has been created: ' . $viewFilePath); } return $this->outputSuccess("Block {$this->blockName} has been created: " . $filePath); } return $this->outputError("Error while creating block '{$filePath}'"); }
/** * Create a new frontend/admin module. * * @return number */ public function actionCreate() { Console::clearScreenBeforeCursor(); $moduleName = $this->prompt("Enter the name of the module you like to generate:"); $newName = preg_replace("/[^a-z]/", "", strtolower($moduleName)); if ($newName !== $moduleName) { if (!$this->confirm("We have changed the name to '{$newName}'. Do you want to proceed with this name?")) { return $this->outputError('Abort by user.'); } else { $moduleName = $newName; } } $appModulesFolder = Yii::$app->basePath . DIRECTORY_SEPARATOR . 'modules'; $moduleFolder = $appModulesFolder . DIRECTORY_SEPARATOR . $moduleName; if (file_exists($moduleFolder)) { return $this->outputError("The folder " . $moduleFolder . " exists already."); } $folders = ['basePath' => $moduleFolder, 'adminPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'admin', 'adminPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . 'aws', 'frontendPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'frontend', 'blocksPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'frontend' . DIRECTORY_SEPARATOR . 'blocks', 'blocksPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'frontend' . DIRECTORY_SEPARATOR . 'controllers', 'blocksPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'frontend' . DIRECTORY_SEPARATOR . 'views', 'modelsPath' => $moduleFolder . DIRECTORY_SEPARATOR . 'models']; $ns = 'app\\modules\\' . $moduleName; foreach ($folders as $folder) { FileHelper::createDirectory($folder); } $contents = [$moduleFolder . DIRECTORY_SEPARATOR . 'README.md' => $this->renderReadme($folders, $moduleName, $ns), $moduleFolder . DIRECTORY_SEPARATOR . 'admin/Module.php' => $this->renderAdmin($folders, $moduleName, $ns), $moduleFolder . DIRECTORY_SEPARATOR . 'frontend/Module.php' => $this->renderFrontend($folders, $moduleName, $ns)]; foreach ($contents as $fileName => $content) { FileHelper::writeFile($fileName, $content); } return $this->outputSuccess("Module files has been created successfull. Check the README file to understand how to added the module to your config."); }