Ejemplo n.º 1
0
 public function actionCopy($id)
 {
     $module = Module::findOne($id);
     $formModel = new CopyModuleForm();
     if ($module === null) {
         $this->flash('error', 'Not found');
         return $this->redirect('/populac/modules');
     }
     if ($formModel->load(Yii::$app->request->post())) {
         if (Yii::$app->request->isAjax) {
             Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
             return ActiveForm::validate($formModel);
         } else {
             $reflector = new \ReflectionClass($module->class);
             $oldModuleFolder = dirname($reflector->getFileName());
             $oldNameSpace = $reflector->getNamespaceName();
             $oldModuleClass = $reflector->getShortName();
             $newModulesFolder = Yii::getAlias('@app') . DIRECTORY_SEPARATOR . 'modules';
             $newModuleFolder = Yii::getAlias('@app') . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $formModel->name;
             //$newNameSpace = 'app\modules\\'.$formModel->name;
             $newNameSpace = 'backend\\modules\\' . $formModel->name;
             $newModuleClass = ucfirst($formModel->name) . 'Module';
             if (!FileHelper::createDirectory($newModulesFolder, 0755)) {
                 $this->flash('error', 'Cannot create `' . $newModulesFolder . '`. Please check write permissions.');
                 return $this->refresh();
             }
             if (file_exists($newModuleFolder)) {
                 $this->flash('error', 'New module folder `' . $newModulesFolder . '` already exists.');
                 return $this->refresh();
             }
             //Copying module folder
             try {
                 FileHelper::copyDirectory($oldModuleFolder, $newModuleFolder);
             } catch (\Exception $e) {
                 $this->flash('error', 'Cannot copy `' . $oldModuleFolder . '` to `' . $newModuleFolder . '`. Please check write permissions.');
                 return $this->refresh();
             }
             //Renaming module file name
             $newModuleFile = $newModuleFolder . DIRECTORY_SEPARATOR . $newModuleClass . '.php';
             $oldModuleFile = $newModuleFolder . DIRECTORY_SEPARATOR . $reflector->getShortName() . '.php';
             if (!rename($oldModuleFile, $newModuleFile)) {
                 $this->flash('error', 'Cannot rename `' . $newModulesFolder . '`.');
                 return $this->refresh();
             }
             //Renaming module class name
             $moduleFileContent = file_get_contents($newModuleFile);
             $moduleFileContent = str_replace($oldModuleClass, $newModuleClass, $moduleFileContent);
             $moduleFileContent = str_replace('@easyii', '@app', $moduleFileContent);
             $moduleFileContent = str_replace('/' . $module->name, '/' . $formModel->name, $moduleFileContent);
             file_put_contents($newModuleFile, $moduleFileContent);
             //Replacing namespace
             foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($newModuleFolder)) as $file => $object) {
                 if (!$object->isDir()) {
                     $fileContent = file_get_contents($file);
                     $fileContent = str_replace($oldNameSpace, $newNameSpace, $fileContent);
                     $fileContent = str_replace("Yii::t('easyii/" . $module->name, "Yii::t('easyii/" . $formModel->name, $fileContent);
                     $fileContent = str_replace("'" . $module->name . "'", "'" . $formModel->name . "'", $fileContent);
                     file_put_contents($file, $fileContent);
                 }
             }
             //Copying module tables
             foreach (glob($newModuleFolder . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . '*.php') as $modelFile) {
                 $baseName = basename($modelFile, '.php');
                 $modelClass = $newNameSpace . '\\models\\' . $baseName;
                 $oldTableName = $modelClass::tableName();
                 $newTableName = str_replace($module->name, $formModel->name, $oldTableName);
                 $newTableName = str_replace('easyii', 'app', $newTableName);
                 //Yii::info($oldTableName, 'oldtb');
                 //Yii::info($newTableName, 'newtb');
                 try {
                     //Drop new table if exists
                     //如果有用到表前缀必须 ".$newTableName." 这样写
                     //如果没有用到表前缀则必须改为 "DROP TABLE IF EXISTS `$newTableName`;" 的写法。
                     Yii::$app->db->createCommand("DROP TABLE IF EXISTS " . $newTableName . ";")->execute();
                     //Copy new table
                     Yii::$app->db->createCommand("CREATE TABLE " . $newTableName . " LIKE " . $oldTableName . ";")->execute();
                 } catch (\yii\db\Exception $e) {
                     $this->flash('error', 'Copy table error. ' . $e);
                     FileHelper::removeDirectory($newModuleFolder);
                     return $this->refresh();
                 }
                 file_put_contents($modelFile, str_replace($oldTableName, $newTableName, file_get_contents($modelFile)));
             }
             $newModule = new Module(['name' => $formModel->name, 'class' => $newNameSpace . '\\' . $newModuleClass, 'title' => $formModel->title, 'icon' => $module->icon, 'settings' => $module->settings, 'status' => Module::STATUS_ON]);
             if ($newModule->save()) {
                 $this->flash('success', 'New module created');
                 return $this->redirect(['/populac/modules/edit', 'id' => $newModule->primaryKey]);
             } else {
                 $this->flash('error', 'Module create error. ' . $newModule->formatErrors());
                 FileHelper::removeDirectory($newModuleFolder);
                 return $this->refresh();
             }
         }
     }
     return $this->render('copy', ['model' => $module, 'formModel' => $formModel]);
 }