['regex:/^[A-Z]+[a-zA-Z0-9_]+$/'] ]; public function load($controller) { if (!$this->validateFileName($controller)) { throw new SystemException('Invalid controller file name: '.$language); } $this->controller = $this->trimExtension($controller); $this->loadControllerBehaviors(); $this->exists = true; } public function save() { if ($this->isNewModel()) { $this->generateController(); } else { $this->saveController(); } } public function fill(array $attributes) { parent::fill($attributes); if (!$this->isNewModel() && is_array($this->behaviors)) { foreach ($this->behaviors as $class=>&$configuration) { if (is_scalar($configuration)) { $configuration = json_decode($configuration, true); } } } } public static function listPluginControllers($pluginCodeObj) { $controllersDirectoryPath = $pluginCodeObj->toPluginDirectoryPath().'/controllers'; $controllersDirectoryPath = File::symbolizePath($controllersDirectoryPath); if (!File::isDirectory($controllersDirectoryPath)) { return []; } $result = []; foreach (new DirectoryIterator($controllersDirectoryPath) as $fileInfo) { if ($fileInfo->isDir()) { continue; } if ($fileInfo->getExtension() !== 'php') { continue; } $result[] = $fileInfo->getBasename('.php'); } return $result; } public function getBaseModelClassNameOptions() { $models = ModelModel::listPluginModels($this->getPluginCodeObj()); $result = []; foreach ($models as $model) { $result[$model->className] = $model->className; } return $result; } public function getBehaviorsOptions() { $library = ControllerBehaviorLibrary::instance(); $behaviors = $library->listBehaviors(); $result = []; foreach ($behaviors as $behaviorClass=>$behaviorInfo) { $result[$behaviorClass] = [ $behaviorInfo['name'], $behaviorInfo['description'] ]; } return $result; } public function getPermissionsOptions() { $model = new PermissionsModel(); $model->loadPlugin($this->getPluginCodeObj()->toCode()); $result = []; foreach ($model->permissions as $permissionInfo) { if (!isset($permissionInfo['label']) || !isset($permissionInfo['permission'])) { continue; } $result[$permissionInfo['permission']] = Lang::get($permissionInfo['label']); } return $result; } public function getMenuItemOptions() { $model = new MenusModel(); $model->loadPlugin($this->getPluginCodeObj()->toCode()); $result = []; foreach ($model->menus as $itemInfo) { if (!isset($itemInfo['label']) || !isset($itemInfo['code'])) { continue; } $itemCode = $itemInfo['code']; $result[$itemCode] = Lang::get($itemInfo['label']); if (!isset($itemInfo['sideMenu'])) { continue; } foreach ($itemInfo['sideMenu'] as $itemInfo) { if (!isset($itemInfo['label']) || !isset($itemInfo['code'])) { continue; } $subItemCode = $itemInfo['code']; $result[$itemCode.'||'.$subItemCode] = str_repeat(' ', 4).Lang::get($itemInfo['label']); } } return $result; } public function getControllerFilePath($controllerFilesDirectory = false) { $pluginCodeObj = $this->getPluginCodeObj(); $controllersDirectoryPath = File::symbolizePath($pluginCodeObj->toPluginDirectoryPath().'/controllers'); if (!$controllerFilesDirectory) { return $controllersDirectoryPath.'/'.$this->controller.'.php'; } return $controllersDirectoryPath.'/'.strtolower($this->controller); } public static function getPluginRegistryData($pluginCode, $subtype) { $pluginCodeObj = new PluginCode($pluginCode); $urlBase = $pluginCodeObj->toUrl().'/'; $controllers = self::listPluginControllers($pluginCodeObj); $result = []; foreach ($controllers as $controler) { $controllerPath = strtolower(basename($controler)); $url = $urlBase.$controllerPath; $result[$url] = $url; } return $result; } protected function saveController() { $this->validate(); $controllerPath = $this->getControllerFilePath(); if (!File::isFile($controllerPath)) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_controller_not_found')); } if (!is_array($this->behaviors)) { throw new SystemException('The behaviors data should be an array.'); } $fileContents = File::get($controllerPath); $parser = new ControllerFileParser($fileContents); $behaviors = $parser->listBehaviors(); if (!$behaviors) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_controller_has_no_behaviors')); } $library = ControllerBehaviorLibrary::instance(); foreach ($behaviors as $behaviorClass) { $behaviorInfo = $library->getBehaviorInfo($behaviorClass); if (!$behaviorInfo) { continue; } $propertyName = $behaviorInfo['configPropertyName']; $propertyValue = $parser->getStringPropertyValue($propertyName); if (!strlen($propertyValue)) { continue; } if (array_key_exists($behaviorClass, $this->behaviors)) { $this->saveBehaviorConfiguration($propertyValue, $this->behaviors[$behaviorClass], $behaviorClass); } } } protected function generateController() { $this->validationMessages = [ 'controller.regex' => Lang::get('rainlab.builder::lang.controller.error_controller_name_invalid') ]; $this->validationRules['controller'][] = 'required'; $this->validate(); $generator = new ControllerGenerator($this); $generator->generate(); } protected function loadControllerBehaviors() { $filePath = $this->getControllerFilePath(); if (!File::isFile($filePath)) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_controller_not_found')); } $fileContents = File::get($filePath); $parser = new ControllerFileParser($fileContents); $behaviors = $parser->listBehaviors(); if (!$behaviors) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_controller_has_no_behaviors')); } $library = ControllerBehaviorLibrary::instance(); $this->behaviors = []; foreach ($behaviors as $behaviorClass) { $behaviorInfo = $library->getBehaviorInfo($behaviorClass); if (!$behaviorInfo) { continue; } $propertyName = $behaviorInfo['configPropertyName']; $propertyValue = $parser->getStringPropertyValue($propertyName); if (!strlen($propertyValue)) { continue; } $configuration = $this->loadBehaviorConfiguration($propertyValue, $behaviorClass); if ($configuration === false) { continue; } $this->behaviors[$behaviorClass] = $configuration; } } protected function loadBehaviorConfiguration($fileName, $behaviorClass) { if (!preg_match('/^[a-z0-9\.\-_]+$/i', $fileName)) { return false; } $extension = pathinfo($fileName, PATHINFO_EXTENSION); if (strlen($extension) && $extension != 'yaml') { return false; } $controllerPath = $this->getControllerFilePath(true); $filePath = $controllerPath.'/'.$fileName; if (!File::isFile($filePath)) { return false; } try { return Yaml::parse(File::get($filePath)); } catch (Exception $ex) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_invalid_yaml_configuration', ['file'=>$fileName])); } } protected function saveBehaviorConfiguration($fileName, $configuration, $behaviorClass) { if (!preg_match('/^[a-z0-9\.\-_]+$/i', $fileName)) { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_invalid_config_file_name', ['file'=>$fileName, 'class'=>$behaviorClass])); } $extension = pathinfo($fileName, PATHINFO_EXTENSION); if (strlen($extension) && $extension != 'yaml') { throw new ApplicationException(Lang::get('rainlab.builder::lang.controller.error_file_not_yaml', ['file'=>$fileName, 'class'=>$behaviorClass])); } $controllerPath = $this->getControllerFilePath(true); $filePath = $controllerPath.'/'.$fileName; $fileDirectory = dirname($filePath); 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])); } } $dumper = new YamlDumper(); if ($configuration !== null) { $yamlData = $dumper->dump($configuration, 20, 0, false, true); } else { $yamlData = ''; } if (@File::put($filePath, $yamlData) === false) { throw new ApplicationException(Lang::get('rainlab.builder::lang.yaml.save_error', ['name'=>$filePath])); } @File::chmod($filePath); } protected function trimExtension($fileName) { if (substr($fileName, -4) == '.php') { return substr($fileName, 0, -4); } return $fileName; } protected function validateFileName($fileName) { if (!preg_match('/^[a-z0-9\.\-_]+$/i', $fileName)) { return false; } $extension = pathinfo($fileName, PATHINFO_EXTENSION); if (strlen($extension) && $extension != 'php') { return false; } return true; } }