<?php
 namespace TCMS\Gen;
 class TCMSPublish {
 private $modelRegisterList = [];
 private $newLine = "\n";
 private $tab = "\t";
 private $isMinify = true;
 public function publish($options) {
 if (isset($options['help'])) {
 $this->showHelp();
 return true;
 }
 $appId = readAppId();
 if (!$appId) {
 showLogError("Không tìm thấy APP_ID trong file public/index.php");
 return false;
 }
 define("APP_ID", $appId);
 define("APP_PATH", ROOT_PATH . 'apps' . DIRECTORY_SEPARATOR . APP_ID . DIRECTORY_SEPARATOR);
 define("CONFIG_PATH", APP_PATH . 'config' . DIRECTORY_SEPARATOR);
 define("PUBLISH_PATH_2", APP_PATH . 'publish' . DIRECTORY_SEPARATOR);
 define("PUBLISH_PATH_APP_PATH", PUBLISH_PATH_2 . 'apps' . DIRECTORY_SEPARATOR . $appId . DIRECTORY_SEPARATOR);
 define("MODULE_PATH", ROOT_PATH . 'modules' . DIRECTORY_SEPARATOR);
 define("BIN_PATH_2", PUBLISH_PATH_2 . 'bin' . DIRECTORY_SEPARATOR);
 define("PUBLISHING", true);
 define("LIB_GEN_PATH", ROOT_PATH . 'libs' . DIRECTORY_SEPARATOR . 'gen');
 if (!file_exists(APP_PATH)) {
 showLogError("Không tìm thấy ứng dụng " . $appId);
 return;
 }
 showLogInfo("Đang publish...");
 $this->deleteDir(PUBLISH_PATH_2, !isset($options['publish']));
 showLogInfo("Xóa dữ liệu trong thư mục publish thành công...");
 if (!file_exists(PUBLISH_PATH_2)) {
 mkdir(PUBLISH_PATH_2);
 }
 if (!file_exists(BIN_PATH_2)) {
 mkdir(BIN_PATH_2);
 }
 if (!file_exists(PUBLISH_PATH_2 . 'apps')) {
 mkdir(PUBLISH_PATH_2 . 'apps');
 }
 if (!file_exists(PUBLISH_PATH_APP_PATH)) {
 mkdir(PUBLISH_PATH_APP_PATH);
 }
 if (!file_exists(PUBLISH_PATH_2 . 'data')) {
 mkdir(PUBLISH_PATH_2 . 'data');
 }
 if (!file_exists(PUBLISH_PATH_2 . 'data' . DIRECTORY_SEPARATOR . 'cache')) {
 mkdir(PUBLISH_PATH_2 . 'data' . DIRECTORY_SEPARATOR . 'cache');
 }
 if (!file_exists(PUBLISH_PATH_2 . 'data' . DIRECTORY_SEPARATOR . 'temp')) {
 mkdir(PUBLISH_PATH_2 . 'data' . DIRECTORY_SEPARATOR . 'temp');
 }
 if (!file_exists(PUBLISH_PATH_2 . 'data' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'views')) {
 mkdir(PUBLISH_PATH_2 . 'data' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'views');
 }
 $this->createAppData();
 showLogInfo("Publish thành công App Data.");
 $this->createModule();
 showLogInfo("Publish thành công Module.");
 $this->createExtension();
 showLogInfo("Publish thành công Extension.");
 $this->createModel();
 showLogInfo("Publish thành công Model.");
 $this->createConfig();
 showLogInfo("Publish thành công Config.");
 if(!isset($options['publish'])) {
 $this->createLib();
 showLogInfo("Publish thành công TCMS Lib.");
 }
 $this->recurse_copy(ROOT_PATH . 'langs', PUBLISH_PATH_2 . 'langs');
 showLogInfo("Hoàn thành publish. Đường dẫn là " . PUBLISH_PATH_2);
 }
 private function createModule() {
 if (!file_exists(PUBLISH_PATH_2 . 'modules')) {
 mkdir(PUBLISH_PATH_2 . 'modules');
 }
 $moduleConfigs = $this->getModuleConfigs();
 foreach($moduleConfigs as $kkk => $module) {
 if(isset($module['nat_name'])) {
 $k = $module['nat_name'];
 }
 else {
 $k = $kkk;
 }
 if(!isset($module['path'])) $areaPath = $module['area'] == '*' ? 'all' : $module['area'];
 if(!empty($module['private'])) {
 if(isset($module['path'])) $moduleDirPath = $module['path'] . $k;
 else $moduleDirPath = APP_PATH . 'modules' . DIRECTORY_SEPARATOR . $areaPath . DIRECTORY_SEPARATOR . $k;
 if(!file_exists($moduleDirPath)) continue;
 if (!file_exists(PUBLISH_PATH_APP_PATH . 'modules')) {
 mkdir(PUBLISH_PATH_APP_PATH . 'modules');
 }
 if(file_exists( PUBLISH_PATH_APP_PATH . 'modules' . DIRECTORY_SEPARATOR . $k)) continue;
 $this->recurse_copy($moduleDirPath, PUBLISH_PATH_APP_PATH . 'modules' . DIRECTORY_SEPARATOR . $k);
 $namespace = $module['namespace'];
 $content = "<?php return ['namespace' => '$namespace','private' => '1'];";
 $fp2 = fopen(PUBLISH_PATH_APP_PATH . 'modules' . DIRECTORY_SEPARATOR . $k . DIRECTORY_SEPARATOR . 'minfo.php', 'w');
 fwrite($fp2, $content);
 fclose($fp2);
 }
 else {
 if(isset($module['path'])) $moduleDirPath = $module['path'] . $k;
 else $moduleDirPath = ROOT_PATH . 'modules' . DIRECTORY_SEPARATOR . $areaPath . DIRECTORY_SEPARATOR . $k;
 if(!file_exists($moduleDirPath)) continue;
 if(file_exists(PUBLISH_PATH_2 . 'modules' . DIRECTORY_SEPARATOR . $k)) continue;
 $this->recurse_copy($moduleDirPath, PUBLISH_PATH_2 . 'modules' . DIRECTORY_SEPARATOR . $k);
 $namespace = $module['namespace'];
 $content = "<?php return ['namespace' => '$namespace','private' => '0'];";
 $fp2 = fopen(PUBLISH_PATH_2 . 'modules' . DIRECTORY_SEPARATOR . $k . DIRECTORY_SEPARATOR . 'minfo.php', 'w');
 fwrite($fp2, $content);
 fclose($fp2);
 }
 }
 }
 private function createExtension() {
 if (!file_exists(PUBLISH_PATH_2 . 'extensions')) {
 mkdir(PUBLISH_PATH_2 . 'extensions');
 }
 $extensions = $this->getExtensionConfigs();
 foreach($extensions as $area => $aextensions) {
 foreach($aextensions as $k => $exts) {
 $lastKey = array_key_last($exts);
 if(!$lastKey) continue;
 $ext = $exts[$lastKey];
 if(is_string($ext)) {
 $enamespace = $ext;
 $filePath = ROOT_PATH . 'extensions' . DIRECTORY_SEPARATOR . $lastKey;
 }
 else {
 if(empty($ext['namespace'])) continue;
 $enamespace = $ext['namespace'];
 if(isset($ext['path'])) {
 $filePath = str_replace(DIRECTORY_SEPARATOR . $lastKey . '.php', "", $ext['path']);
 }
else {
 if(isset($ext['private'])) {
 $filePath = APP_PATH . 'extensions' . DIRECTORY_SEPARATOR . $lastKey;
 }
 else {
 $filePath = ROOT_PATH . 'extensions' . DIRECTORY_SEPARATOR . $lastKey;
 }
 }
 }
 if(!file_exists($filePath)) continue;
 $p = str_replace(ROOT_PATH, '', $filePath);
 if(file_exists(PUBLISH_PATH_2 . $p)) continue;
 $fullFile = $filePath . DIRECTORY_SEPARATOR . $lastKey . '.php';
 if(file_exists($fullFile)) {
 include($fullFile);
 try {
 $extCls = new $enamespace();
 }
catch(\Exception $ex) {
 }
 }
 $this->recurse_copy($filePath . DIRECTORY_SEPARATOR, PUBLISH_PATH_2 . $p.DIRECTORY_SEPARATOR);
 }
 }
 }
 private function createModel() {
 if (!file_exists(PUBLISH_PATH_2 . 'models')) {
 mkdir(PUBLISH_PATH_2 . 'models');
 }
 foreach(\GlobalVars::$models as $mk => $model) {
 if(!file_exists($model[1])) continue;
 $p = str_replace(ROOT_PATH, '', $model[1]) . "\n";
 $fileName = basename($p);
 $paths = explode(DIRECTORY_SEPARATOR, dirname($p));
 $fullPath = PUBLISH_PATH_2;
 foreach($paths as $path) {
 $fullPath .= $path;
 if(!file_exists($fullPath)) {
 mkdir($fullPath);
 }
 $fullPath .= DIRECTORY_SEPARATOR;
 }
 copy(trim($model[1]), trim($fullPath . $fileName));
 }
 }
 private function createConfig() {
 if (!file_exists(PUBLISH_PATH_APP_PATH . 'config')) {
 mkdir(PUBLISH_PATH_APP_PATH . 'config');
 }
 $this->recurse_copy(APP_PATH . 'config', PUBLISH_PATH_APP_PATH . 'config');
 copy(APP_PATH . 'bootstrap.php', PUBLISH_PATH_APP_PATH . 'bootstrap.php');
 }
 private function createLib() {
 if (!file_exists(PUBLISH_PATH_2 . 'libs')) {
 mkdir(PUBLISH_PATH_2 . 'libs');
 }
 $this->recurse_copy(ROOT_PATH . 'libs', PUBLISH_PATH_2 . 'libs');
 copy(LIB_GEN_PATH . DIRECTORY_SEPARATOR . 'app.publish.php', PUBLISH_PATH_2 . 'libs' . DIRECTORY_SEPARATOR . 'app.publish.php');
 $lines = readConfigFile(PUBLISH_PATH_2 . 'libs' . DIRECTORY_SEPARATOR . 'app.php');
 $beginLineIndex = -1;
 foreach($lines as $line) {
 if(strpos($line, "global.class.php") !== false) {
 break;
 }
 else {
 $beginLineIndex++;
 }
 }
 $lines[$beginLineIndex] = $lines[$beginLineIndex] . "include_once(LIB_PATH . 'app.publish.php');\n";
 $content = '';
 foreach($lines as $line) {
 $content .= $line;
 }
 $fp2 = fopen(PUBLISH_PATH_2 . 'libs' . DIRECTORY_SEPARATOR . 'app.php', 'w');
 fwrite($fp2, $content);
 fclose($fp2);
 if($this->isMinify) $this->minify(PUBLISH_PATH_2 . 'libs');
 }
 private function minify($src) {
 $dir = opendir($src);
 while(false !== ( $file = readdir($dir)) ) {
 if (( $file != '.' ) && ( $file != '..' )) {
 if ( is_dir($src . DIRECTORY_SEPARATOR . $file) ) {
 $this->minify($src . DIRECTORY_SEPARATOR . $file);
 }
 else {
 if($this->isPHPFile($file)) {
 if($file == "error-view.php") continue;
 $path = $src . DIRECTORY_SEPARATOR . $file;
 $content = php_strip_whitespace($path);
 $fp2 = fopen($path, 'w');
 fwrite($fp2, $content);
 fclose($fp2);
 }
 }
 }
 }
 closedir($dir);
 }
 private function isPHPFile($file) {
 $len = strlen($file);
 if($len < 8) return false;
 $last = substr($file, $len - 4);
 return $last == ".php";
 }
 private function recurse_copy($src,$dst) {
 if($src == LIB_GEN_PATH) return;
 $dir = opendir($src);
 @mkdir($dst);
 while(false !== ( $file = readdir($dir)) ) {
 if (( $file != '.' ) && ( $file != '..' )) {
 if ( is_dir($src . DIRECTORY_SEPARATOR . $file) ) {
 $this->recurse_copy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
 }
 else {
 copy($src . DIRECTORY_SEPARATOR . $file,$dst . DIRECTORY_SEPARATOR . $file);
 }
 }
 }
 closedir($dir);
 }
 private function getModuleConfigs() {
 $areaCfg = include(CONFIG_PATH . "app.php");
 $_areas = $areaCfg['areas'];
 $moduleConfigs = [];
 $tIndex = 0;
 foreach($_areas as $a => $v) {
 if(!file_exists(CONFIG_PATH . $a . ".module.php")) continue;
 $modules = include(CONFIG_PATH . $a . ".module.php");
 foreach($modules as $k => $m) {
 if(isset($moduleConfigs[$k])) {
 $mct = $moduleConfigs[$k];
 if($mct['area'] != $a) {
 $m['area'] = $a;
 $m['nat_name'] = $k;
 $moduleConfigs[$k . '-' . (++$tIndex)] = $m;
 continue;
 }
 }
 $m['area'] = $a;
 $moduleConfigs[$k] = $m;
 }
 }
 return $moduleConfigs;
 }
 private function getExtensionConfigs() {
 $areaCfg = include(CONFIG_PATH . "app.php");
 $_areas = $areaCfg['areas'];
 $extensionConfigs = [];
 $tIndex = 0;
 foreach($_areas as $a => $v) {
 if(file_exists(CONFIG_PATH . $a . ".extension.php")) $extensionConfigs[$a] = include(CONFIG_PATH . $a . ".extension.php");
 }
 return $extensionConfigs;
 }
 private function createAppData() {
 include_once(LIB_PATH . 'global.class.php');
 include_once(LIB_PATH . 'modules' . DIRECTORY_SEPARATOR . 'TCmsModule.php');
 include_once(LIB_PATH . 'models' . DIRECTORY_SEPARATOR . 'TCmsModel.php');
 include_once(LIB_PATH . 'extensions' . DIRECTORY_SEPARATOR . 'TCmsExtension.php');
 $routesData = [];
 $layoutData = [];
 $areaList = [];
 $layoutModule = [];
 $eventData = [];
 include_once(APP_PATH . 'bootstrap.php');
 $appBootstrap = new \AppBootstrap();
 $appBootstrap->boot();
 $moduleConfigs = $this->getModuleConfigs();
 foreach ($moduleConfigs as $moduleName => $moduleConfig) {
 $areaKey = $moduleConfig['area'];
 if ($areaKey != '*') {
 if (!isset($areaList[$areaKey])) {
 $areaList[] = $areaKey;
 }
 if (!isset($routesData[$areaKey])) {
 $routesData[$areaKey] = [];
 }
 if (!isset($layoutData[$areaKey])) {
 $layoutData[$areaKey] = [];
 }
 if (!isset($layoutModule[$areaKey])) {
 $layoutModule[$areaKey] = [];
 }
 }
 }
 $layoutMenuDatas = [];
 $overrideModels = [];
 foreach ($moduleConfigs as $mmmmName => $moduleConfig) {
 $areaKey = $moduleConfig['area'];
 if(isset($moduleConfig['nat_name'])) {
 $moduleName = $moduleConfig['nat_name'];
 }
else {
 $moduleName = $mmmmName;
 }
 $m = $this->includeAndNewModule($moduleName, $moduleConfig);
 if(!$m) {
 showLogError("không tìm thấy module $moduleName namespace " . $moduleConfig['namespace']);
 exit();
 continue;
 }
 $m->registerComponent();
 if ($m->isLayout) {
 $m->moduleName = $moduleName;
 $m->moduleConfig = $moduleConfig;
 if ($areaKey != '*') {
 $layoutModule[$areaKey][] = $m;
 }
 else {
 foreach ($areaList as $a) {
 $layoutModule[$a][] = $m;
 }
 }
 continue;
 }
 $routes = $m->getRoutes();
 foreach(\LayoutData::$layoutMenuItem as $mmmmct => $vvvct) {
 $vvvct->area = $areaKey;
 $layoutMenuDatas[$areaKey . '_' . $mmmmct] = $vvvct;
 }
 foreach(\GlobalVars::$overrideModels as $mmmct => $vvvct) {
 if(!isset($overrideModels[$areaKey])) {
 $overrideModels[$areaKey] = [];
 }
 $overrideModels[$areaKey][$mmmct] = $vvvct;
 }
 \LayoutData::$layoutMenuItem = [];
 \GlobalVars::$overrideModels = [];
 if ($areaKey != '*') {
 foreach ($routes as &$r) {
 $isExist = false;
 $oldRouteData = $routesData[$areaKey];
 foreach ($oldRouteData as $rou) {
 if ($rou->url == $r->url && $rou->type == $r->type) {
 $isExist = true;
 break;
 }
 }
 if ($isExist) {
 continue;
 }
 $r->moduleConfig = $moduleConfig;
 $r->moduleName = $moduleName;
 $routesData[$areaKey][] = $r;
 }
 }
 else {
 foreach ($areaList as $a) {
 foreach ($routes as &$r) {
 $isExist = false;
 $oldRouteData = $routesData[$a];
 foreach ($oldRouteData as $rou) {
 if ($rou->url == $r->url && $rou->type == $r->type) {
 $isExist = true;
 break;
 }
 }
 if ($isExist) {
 continue;
 }
 $r->moduleConfig = $moduleConfig;
 $r->moduleName = $moduleName;
 $routesData[$a][] = $r;
 }
 }
 }
 }
 foreach ($layoutMenuDatas as $item) {
 if ($item->area != '*') {
 $layoutData[$item->area][$item->url] = $item;
 }
 else {
 foreach ($areaList as $a) {
 $layoutData[$a][$item->url] = $item;
 }
 }
 }
 $ct = '<?php return [';
 if (\GlobalVars::$eventLists) {
 foreach (\GlobalVars::$eventLists as $eventName => $event) {
 $c = new \ReflectionFunction($event);
 $filename = $c->getFileName();
 $start_line = $c->getStartLine() - 1;
 $end_line = $c->getEndLine();
 $fileContent = readConfigFile($filename);
 $fLine = $start_line;
 $mContent = '';
 while (true) {
 if ($start_line < $end_line) {
 if($start_line == $fLine) {
 $line = trim($fileContent[$start_line]);
 $startIndex = strpos($line, "function");
 if($startIndex === false) {
 $start_line++;
 $fLine = $start_line;
 continue;
 }
 $lll = substr($line, $startIndex);
 $lll = str_replace("function", "", $lll);
 $mContent .= $lll;
 $start_line++;
 continue;
 }
 if($start_line < $end_line - 1) {
 $llliness = trim($fileContent[$start_line]);
 if(strpos($llliness, "//") !== false) $mContent .= $llliness . ' ' . "\n";
 else $mContent .= $llliness . ' ';
 }
 else {
 $line = trim($fileContent[$start_line]);
 $startIndex = strripos($line, "};");
 if($startIndex !== false) {
 if($line != "};") $line = substr($line, 0, $startIndex);
 else $line = '';
 }
 $mContent .= $line;
 }
 $start_line++;
 }
 else {
 break;
 }
 }
 if($mContent) {
 if(substr($mContent, strlen($mContent) - 1) == ')') {
 $mContent = substr($mContent, 0, strlen($mContent) - 1);
 }
 else {
 if(substr($mContent, strlen($mContent) - 2) == ');') {
 $mContent = substr($mContent, 0, strlen($mContent) - 2);
 }
 }
 $mContent = str_replace("'", '&apos;', $mContent);
 $ct .= "'$eventName' => '$mContent'," . $this->newLine;
 }
 }
 }
 $ct .= '];';
 $fpEvent = fopen(BIN_PATH_2 . 'event-data.php', 'w');
 fwrite($fpEvent, $ct);
 fclose($fpEvent);
 $ct= null;
 foreach ($routesData as $area => $routes) {
 $contentRoute = '<?php return [ ';
 foreach ($routes as $k => $r) {
 $contentRoute .= "$k=>[" . $this->newLine;
 $contentRoute .= $this->tab . "'url'=>'$r->url'," . $this->newLine;
 $contentRoute .= $this->tab . "'type'=>$r->type," . $this->newLine;
 $contentRoute .= $this->tab . "'regex'=>'$r->regex'," . $this->newLine;
 $contentRoute .= $this->tab . "'n'=>'$r->moduleName'," . $this->newLine;
 $contentRoute .= $this->tab . "'p'=>" . (isset($r->moduleConfig['private']) ? '1' : '0') . $this->newLine;
 $contentRoute .= $this->tab . "]," . $this->newLine;
 }
 $contentRoute .= "];";
 $fp = fopen(BIN_PATH_2 . $area . '-route-data.php', 'w');
 fwrite($fp, $contentRoute);
 fclose($fp);
 $contentLayout = "<?php return [";
 foreach ($layoutModule as $marea => $modules) {
 if ($marea != $area) {
 continue;
 }
 foreach ($modules as $lk => $layout) {
 $contentLayout .= "$lk=>[" . $this->newLine;
 $contentLayout .= $this->tab . "'n'=>'$layout->moduleName'," . $this->newLine;
 $contentLayout .= $this->tab . "'namespace'=>'" . $layout->moduleConfig['namespace'] . "'," . $this->newLine;
 $contentLayout .= $this->tab . "'private'=>" . (isset($layout->moduleConfig['private']) ? '1' : '0') . $this->newLine;
 $contentLayout .= $this->tab . "]," . $this->newLine;
 }
 }
 $contentLayout .= "];";
 $fp = fopen(BIN_PATH_2 . $area . '-mlayout-data.php', 'w');
 fwrite($fp, $contentLayout);
 fclose($fp);
 }
 foreach ($layoutData as $area => $data) {
 $content = '<?php return [';
 foreach ($data as $k => $r) {
 $content .= "'$k'=>[" . $this->newLine;
 $content .= $this->tab . "'url'=>'$r->url'," . $this->newLine;
 $content .= $this->tab . "'id'=>'$r->id'," . $this->newLine;
 $content .= $this->tab . "'text'=>'$r->text'," . $this->newLine;
 $content .= $this->tab . "'layoutMenuId'=>'$r->layoutMenuId'," . $this->newLine;
 $content .= $this->tab . "'icon'=>'$r->icon'," . $this->newLine;
 $content .= $this->tab . "'class'=>'$r->class'," . $this->newLine;
 $content .= $this->tab . "'displayAfter'=>'$r->displayAfter'," . $this->newLine;
 $content .= $this->tab . "'parentMenuId'=>'$r->parentMenuId'," . $this->newLine;
 if ($r->middleware) {
 $mContent = '';
 $c = new \ReflectionFunction($r->middleware);
 $filename = $c->getFileName();
 $start_line = $c->getStartLine() - 1;
 $end_line = $c->getEndLine();
 $fileContent = readConfigFile($filename);
 $fLine = $start_line;
 while (true) {
 if ($start_line < $end_line) {
 if($start_line == $fLine) {
 $line = trim($fileContent[$start_line]);
 $startIndex = strpos($line, "function");
 if($startIndex === false) {
 $start_line++;
 $fLine = $start_line;
 continue;
 }
 $lll = substr($line, $startIndex);
 $lll = str_replace("function", "", $lll);
 $mContent .= $lll;
 $start_line++;
 continue;
 }
 if($start_line < $end_line - 1) {
 $llliness2 = trim($fileContent[$start_line]);
 if(strpos($llliness2, "//") !== false) $mContent .= $llliness2 . ' ' . "\n";
 else $mContent .= $llliness2 . ' ';
 }
 else {
 $line = trim($fileContent[$start_line]);
 $startIndex = strripos($line, "};");
 if($startIndex !== false) {
 if($line != "};") $line = substr($line, 0, $startIndex);
 else $line = '';
 }
 $mContent .= $line;
 }
 $start_line++;
 }
 else {
 break;
 }
 }
 if($mContent) {
 $mContent = str_replace("'", "&apos;", $mContent);
 $content .= $this->tab . "'middleware'=>'$mContent'," . $this->newLine;
 }
 else {
 $content .= $this->tab . "'middleware'=>''," . $this->newLine;
 }
 }
 else {
 $content .= $this->tab . "'middleware'=>''," . $this->newLine;
 }
 $content .= $this->tab . "'subMenuTitle'=>'$r->subMenuTitle'" . $this->newLine;
 $content .= "]," . $this->newLine;
 }
 $content .= "];";
 $fp = fopen(BIN_PATH_2 . $area . '-layout-data.php', 'w');
 fwrite($fp, $content);
 fclose($fp);
 }
 foreach ($overrideModels as $area => $modelss) {
 $contentRoute = '<?php return [ ';
 foreach ($modelss as $k => $r) {
 $contentRoute .= $this->tab . "'$k'=>'$r'," . $this->newLine;
 }
 foreach (\GlobalVars::$models as $k => $r) {
 if(isset($r['b'])) {
 $n = $r[0];
 $f = str_replace(ROOT_PATH,"", $r[1]);
 $contentRoute .= $this->tab . "'$k'=>['n' => '$n', 'p' => '$f']," . $this->newLine;
 }
 }
 $contentRoute .= "];";
 $fp = fopen(BIN_PATH_2 . $area . '-ext-model-data.php', 'w');
 fwrite($fp, $contentRoute);
 fclose($fp);
 }
 }
 private function includeAndNewModule($moduleName, $moduleConfig) {
 if(isset($moduleConfig['path'])) {
 $moduleFilePath = $moduleConfig['path'] . $moduleName . DIRECTORY_SEPARATOR . $moduleName . '.php';
 }
 else {
 $areaPath = $moduleConfig['area'] == '*' ? 'all' : $moduleConfig['area'];
 if (empty($moduleConfig['private'])) {
 $moduleFilePath = MODULE_PATH . $areaPath . DIRECTORY_SEPARATOR . $moduleName . DIRECTORY_SEPARATOR . $moduleName . '.php';
 }
 else {
 $moduleFilePath = APP_PATH . 'modules' . DIRECTORY_SEPARATOR . $areaPath . DIRECTORY_SEPARATOR . $moduleName . DIRECTORY_SEPARATOR . $moduleName . '.php';
 }
 }
 if (!file_exists($moduleFilePath)) {
 return false;
 }
 include_once($moduleFilePath);
 $moduleCls = "\\" . $moduleConfig['namespace'];
 return new $moduleCls();
 }
 private function deleteDir($dirPath, $isDelLib = true) {
 if (!is_dir($dirPath)) {
 return;
 }
 if($dirPath == PUBLISH_PATH_2 . 'public' . DIRECTORY_SEPARATOR) return;
 if (substr($dirPath, strlen($dirPath) - 1, 1) != DIRECTORY_SEPARATOR) {
 $dirPath .= DIRECTORY_SEPARATOR;
 }
 $files = glob($dirPath . '*', GLOB_MARK);
 foreach ($files as $file) {
 if (is_dir($file)) {
 $this->deleteDir($file, $isDelLib);
 }
 else {
 unlink($file);
 }
 }
 if(PUBLISH_PATH_2 != $dirPath) rmdir($dirPath);
 }
 public function showHelp() {
 drawLine();
 echo "Description:\n";
 showLogInfo("  Publish project để upload lên host");
 echo "\nFormat:\n";
 echo "  publish [options]\n\n";
 echo "Options:\n";
 showHelpTextColor("--user-data", "chỉ publish dữ liệu người dùng, không publish thư viện libs");
 drawLine();
 }
 }
 