/** * Creates a new custom module. * * This method allows for the creation of admin defined modules to use in the * software. These modules are more basic in functionality than most other X2 * modules, but are fully customizable from the studio. */ public function actionCreateModule() { $errors = array(); if (isset($_POST['moduleName'])) { $title = trim($_POST['title']); $recordName = trim($_POST['recordName']); $moduleName = trim($_POST['moduleName']); // are there any non-alphanumeric or _ chars? or non-alpha characters at the beginning? if (preg_match('/\\W/', $moduleName) || preg_match('/^[^a-zA-Z]+/', $moduleName)) { $errors[] = Yii::t('module', 'Invalid table name'); //$this->redirect('createModule'); } if ($moduleName == '') { // we will attempt to use the title as the backend name, if possible $moduleName = $title; } if ($recordName == '') { // use title for record name if none is provided $recordName = $title; } $trans = (include 'protected/data/transliteration.php'); // replace characters with their A-Z equivalent, if possible $moduleName = strtolower(strtr($moduleName, $trans)); // now remove all remaining non-alphanumeric or _ chars $moduleName = preg_replace('/\\W/', '', $moduleName); // remove any numbers or _ from the beginning $moduleName = preg_replace('/^[0-9_]+/', '', $moduleName); if ($moduleName == '') { // if there is nothing left of moduleName at this point, $moduleName = 'module' . substr(time(), 5); // just generate a random one } if (!is_null(Modules::model()->findByAttributes(array('title' => $title))) || !is_null(Modules::model()->findByAttributes(array('name' => $moduleName)))) { $errors[] = Yii::t('module', 'A module with that name already exists'); } if (empty($errors)) { $dirFlag = false; $configFlag = false; $tableFlag = false; try { $this->createSkeletonDirectories($moduleName); $dirFlag = true; // Try to create the fileset $this->writeConfig($title, $moduleName, $recordName); $configFlag = true; // Write the configuration $this->createNewTable($moduleName); $tableFlag = true; // Create the DB table } catch (Exception $e) { /* * If any of the operations in the try block fail, we need * to roll back whatever successfully happened before that. * The flag variables below indicate which rollback operations * to take. */ if ($dirFlag) { FileUtil::rrmdir('protected/modules/' . $moduleName); } else { $errors[] = Yii::t('module', 'Unable to create custom module directory.'); } if ($configFlag) { // Nothing, already taken care of by the file delete above } elseif ($dirFlag) { $errors[] = Yii::t('module', 'Unable to create config file for custom module.'); } if ($tableFlag) { $this->deleteTable($moduleName); } elseif ($dirFlag && $configFlag) { $errors[] = Yii::t('module', 'Unable to create table for custom module.'); } } if (empty($errors)) { $moduleRecord = new Modules(); $moduleRecord->name = $moduleName; $moduleRecord->title = $title; $moduleRecord->custom = 1; $moduleRecord->visible = 1; $moduleRecord->editable = $_POST['editable']; $moduleRecord->adminOnly = $_POST['adminOnly']; $moduleRecord->searchable = $_POST['searchable']; $moduleRecord->toggleable = 1; $moduleRecord->menuPosition = Modules::model()->count(); $moduleRecord->save(); Yii::import('application.modules.' . $moduleName . '.models.*'); $layoutModel = new FormLayout(); $layoutModel->model = ucfirst($moduleName); $layoutModel->version = "Default"; $layoutModel->layout = X2Model::getDefaultFormLayout($moduleName); $layoutModel->createDate = time(); $layoutModel->lastUpdated = time(); $layoutModel->defaultView = true; $layoutModel->defaultForm = true; $layoutModel->save(); $this->redirect(array('/' . $moduleName . '/index')); } } } $this->render('createModule', array('errors' => $errors)); }
/** * Returns fieldName, fieldLabel pairs for all fields for which the user has edit rights and * which are present in the layout. */ public function getEditableFieldsInLayout($modelName) { $editableFieldsFieldInfo = X2Model::model($modelName)->getEditableFieldNames(false); // Construct criteria for finding the right form layout. $attributes = array('model' => ucfirst($modelName), 'defaultForm' => 1); $layout = self::model()->findByAttributes($attributes); $layoutData = json_decode(isset($layout) ? $layout->layout : X2Model::getDefaultFormLayout($modelName), true); $editableFieldsInLayout = array(); if (isset($layoutData['sections']) && count($layoutData['sections']) > 0) { foreach ($layoutData['sections'] as &$section) { foreach ($section['rows'] as &$row) { if (isset($row['cols'])) { foreach ($row['cols'] as &$col) { if (isset($col['items'])) { foreach ($col['items'] as &$item) { if (isset($item['name'], $item['labelType'], $item['readOnly'], $item['height'], $item['width'])) { $fieldName = preg_replace('/^formItem_/u', '', $item['name']); if (in_array($fieldName, array_keys($editableFieldsFieldInfo))) { $editableFieldsInLayout[$fieldName] = $editableFieldsFieldInfo[$fieldName]; } } } } } } } } } return $editableFieldsInLayout; }