Exemplo n.º 1
0
 /**
  * Insert module and return generated content.
  *
  * @param PageModuleWrapper $pageModuleWrapper
  * @return string
  */
 protected function insertModule(PageModuleWrapper $pageModuleWrapper)
 {
     $this->app->logger->debug(($pageModuleWrapper->getEnabled() ? 'Inserting' : 'Skipping') . ' module "' . $pageModuleWrapper->getName() . '" of type "' . $pageModuleWrapper->getClassName() . '" with target "' . $pageModuleWrapper->getTarget() . '"');
     /** @var PreModuleEvent $event */
     $event = $this->app->dispatcher->dispatch(GeneratorEvents::PRE_MODULE, new PreModuleEvent($pageModuleWrapper));
     if ($event->getContent() === null) {
         // TODO: how do we handle $event->isEnabled() ?
         /** @var \Curry\Module\AbstractModule $module */
         $module = $pageModuleWrapper->createObject();
         $template = null;
         if ($event->getTemplate() !== null) {
             $this->app->twig->loadTemplate($event->getTemplate());
         } else {
             if ($module->getDefaultTemplate()) {
                 $template = $this->app->loadTemplateString($module->getDefaultTemplate());
             }
         }
         if ($template && $template->getEnvironment()) {
             $twig = $template->getEnvironment();
             $twig->addGlobal('module', array('Id' => $pageModuleWrapper->getPageModuleId(), 'ClassName' => $pageModuleWrapper->getClassName(), 'Name' => $pageModuleWrapper->getName(), 'ModuleDataId' => $pageModuleWrapper->getModuleDataId(), 'Target' => $pageModuleWrapper->getTarget()));
         }
         $content = (string) $module->showFront($template);
     } else {
         $content = $event->getContent();
     }
     /** @var PostModuleEvent $postEvent */
     $postEvent = $this->app->dispatcher->dispatch(GeneratorEvents::POST_MODULE, new PostModuleEvent($pageModuleWrapper, $content, $event->getExtras()));
     return $postEvent->getContent();
 }
Exemplo n.º 2
0
 /**
  * If developmentMode is enabled, redirect mails to adminEmail.
  * 
  * {@inheritdoc}
  */
 public function send($transport = null)
 {
     if ($transport === null) {
         App::getInstance()->sendMail($this);
     }
     return parent::send($transport);
 }
Exemplo n.º 3
0
 /**
  * Get a list of all available modules.
  *
  * @return array
  */
 public static function getModuleList()
 {
     if (self::$modules) {
         return self::$modules;
     }
     // find all backend directories
     $dirs = glob(PathHelper::path(App::getInstance()['projectPath'], 'include', '*', 'Module'), GLOB_ONLYDIR);
     if (!$dirs) {
         $dirs = array();
     }
     $dirs[] = __DIR__;
     // find all php files in the directories
     $modules = array();
     foreach ($dirs as $dir) {
         $classes = ClassEnumerator::findClasses($dir);
         foreach ($classes as $className) {
             if (class_exists($className)) {
                 $r = new \ReflectionClass($className);
                 if ($r->isSubclassOf(__CLASS__) && !$r->isAbstract()) {
                     $modules[$className] = $className;
                 }
             }
         }
     }
     ksort($modules);
     self::$modules = $modules;
     return self::$modules;
 }
Exemplo n.º 4
0
 public function __construct($modelOrModelForm, $options = array())
 {
     if (is_string($modelOrModelForm)) {
         $this->modelForm = new \Curry\Form\ModelForm($modelOrModelForm, $options);
     } else {
         if ($modelOrModelForm instanceof \Curry\Form\ModelForm) {
             $this->modelForm = $modelOrModelForm;
         } else {
             throw new Exception('Expected string or Curry\\Form\\ModelForm');
         }
     }
     parent::__construct(App::getInstance());
 }
Exemplo n.º 5
0
 /**
  * Wrap module with inline admin controls.
  *
  * @param string $content
  * @param PageModuleWrapper $pageModuleWrapper
  * @return string
  */
 protected function adminModule($content, PageModuleWrapper $pageModuleWrapper)
 {
     $user = \User::getUser();
     $pageId = $pageModuleWrapper->getPageRevision()->getPageId();
     $page = $pageModuleWrapper->getPageRevision()->getPage();
     $pageModuleId = $pageModuleWrapper->getPageModuleId();
     $commands = array();
     $templatePermission = $user->hasAccess('Curry_Backend_Template');
     $contentPermission = $user->hasPagePermission($page, \PageAccessPeer::PERM_CONTENT);
     $modulePermission = $user->hasPagePermission($page, \PageAccessPeer::PERM_MODULES);
     $createPermission = $user->hasPagePermission($page, \PageAccessPeer::PERM_CREATE_MODULE);
     if (!$user->hasModuleAccess($pageModuleWrapper)) {
         return $content;
     }
     if ($contentPermission || $modulePermission) {
         $url = url('/admin/curry_backend_page/', array('view' => 'Module', 'page_id' => $pageId, 'page_module_id' => $pageModuleId));
         if ($user->hasPagePermission($page, \PageAccessPeer::PERM_CONTENT)) {
             $commands['edit'] = array('Name' => 'Edit', 'Url' => $url, 'Class' => 'iframe');
         }
     }
     if ($pageModuleWrapper->getTemplate() && $templatePermission) {
         $url = url('/admin/curry_backend_template/', array('view' => 'Edit', 'file' => $pageModuleWrapper->getTemplate()));
         $commands['template'] = array('Name' => 'Edit template', 'Url' => $url, 'Class' => 'iframe');
     }
     if ($modulePermission) {
         $url = url('/admin/curry_backend_page/', array('view' => 'ModuleProperties', 'page_id' => $pageId, 'page_module_id' => $pageModuleId));
         $commands['properties'] = array('Name' => 'Properties', 'Url' => $url, 'Class' => 'iframe');
     }
     if ($createPermission && ($contentPermission && !$pageModuleWrapper->isInherited() || $modulePermission)) {
         $url = url('/admin/curry_backend_page/', array('view' => 'DeleteModule', 'page_id' => $pageId, 'page_module_id' => $pageModuleId));
         $commands['delete'] = array('Name' => 'Delete', 'Url' => $url, 'Class' => 'iframe');
     }
     $module = $pageModuleWrapper->createObject();
     $commands = $module->getInlineCommands($commands);
     if (!count($commands)) {
         return $content;
     }
     $tpl = $this->app->loadTemplateString($this->getAdminModuleTpl());
     return $tpl->render(array('Id' => $pageModuleId, 'Name' => $pageModuleWrapper->getName(), 'ClassName' => $pageModuleWrapper->getClassName(), 'Content' => $content, 'commands' => $commands));
 }
Exemplo n.º 6
0
 /**
  * Create a mail from a URL, Page or PageRevision.
  *
  * @param string|\Page|\PageRevision|Request $page
  * @param array $variables Additional template variables.
  * @return Mail
  */
 public static function createFromPage($page)
 {
     $app = \Curry\App::getInstance();
     // Make sure we have a request object
     if (is_string($page)) {
         $request = Request::create($page);
     } elseif ($page instanceof \Page) {
         $request = Request::create($page->getUrl());
     } elseif ($page instanceof \PageRevision) {
         $request = Request::create($page->getPage()->getUrl());
     } elseif ($page instanceof Request) {
         $request = $page;
     } else {
         throw new \Exception('Expected parameter $page to be one of string|Page|PageRevision|Request.');
     }
     // Generate page
     $response = $app->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST, false);
     // Create email
     $mail = new Mail();
     $mail->setBodyHtml($response->getContent());
     return $mail;
 }
Exemplo n.º 7
0
 /**
  * Restore database from file.
  * 
  * @todo Fix $maxExecutionTime.
  *
  * @param string|resource $file
  * @param array|null $tables
  * @param float $maxExecutionTime
  * @param int $continueLine
  * @param AbstractLegacyBackend|null $backend
  * @return bool	True on success, false otherwise.
  */
 public static function restoreFromFile($file, $tables = null, $maxExecutionTime = 0, $continueLine = 0, AbstractLegacyBackend $backend = null)
 {
     global $CURRY_DATABASE_RESTORE;
     $CURRY_DATABASE_RESTORE = true;
     $fp = is_string($file) ? fopen($file, "r") : $file;
     $t = microtime(true);
     $total = 0;
     $skipped = 0;
     $failed = 0;
     $session = new \Zend\Session\Container(__CLASS__);
     $con = Propel::getConnection();
     $con->beginTransaction();
     $adapter = Propel::getDB();
     if ($adapter instanceof DBMySQL) {
         $con->exec("SET foreign_key_checks = 0");
     }
     // Read header
     $firstline = stream_get_line($fp, self::MAX_LINE_LENGTH, "\n");
     $header = json_decode($firstline, true);
     if (is_array($header) && isset($header['header'])) {
         $header = $header['header'];
         // Check header version
         $version = isset($header['version']) ? (int) $header['version'] : 0;
         if ($version > self::VERSION) {
             throw new Exception('Unsupported database version. The file you are trying to restore from is from a newer version of currycms.');
         }
         // Check page version
         $pageVersion = isset($header['page-version']) ? (int) $header['page-version'] : 0;
         if ($pageVersion > Page::VERSION) {
             throw new Exception('Unsupported page version. The file you are trying to restore from is from a newer version of currycms.');
         }
         if ($backend) {
             $backend->addMessage("Restoring from " . $header['date']);
         }
         if ($pageVersion !== Page::VERSION) {
             if ($backend) {
                 $backend->addMessage("Migrating data from version {$pageVersion} to " . Page::VERSION, AbstractBackend::MSG_WARNING);
             }
             Page::preMigrate($pageVersion);
         }
     } else {
         throw new Exception('Invalid header');
     }
     // Empty tables
     if ($continueLine == 0) {
         foreach (Propel::getModels() as $classes) {
             foreach ($classes as $table) {
                 try {
                     if (is_array($tables) && !in_array($table, $tables)) {
                         continue;
                     }
                     if (!method_exists($table, 'delete')) {
                         if ($backend) {
                             $backend->addMessage("Skipping read-only table: {$table}", AbstractBackend::MSG_WARNING);
                         }
                         continue;
                     }
                     $tableName = PropelQuery::from($table)->getTableMap()->getName();
                     // use basePeer to avoid foreign key emulation in Normal peer class
                     BasePeer::doDeleteAll($tableName, $con);
                 } catch (Exception $e) {
                     throw new Exception('Unable to empty table ' . $table . ': ' . $e->getMessage());
                 }
             }
         }
         if ($backend) {
             $backend->addMessage("Cleared tables in " . round(microtime(true) - $t, 2) . "s");
         }
         $t = microtime(true);
     } else {
         $total = $session->total;
         $skipped = $session->skipped;
         $failed = $session->failed;
         if ($backend) {
             $backend->addMessage("Continuing from line {$continueLine}.");
         }
         for ($i = 0; $i < $continueLine; ++$i) {
             stream_get_line($fp, self::MAX_LINE_LENGTH, "\n");
         }
     }
     $currentTable = null;
     $buffer = array();
     while (!feof($fp)) {
         // Read line
         $data = json_decode(stream_get_line($fp, self::MAX_LINE_LENGTH, "\n"), true);
         ++$total;
         if (is_array($data) && isset($data['table'])) {
             if (is_array($tables) && !in_array($data['table'], $tables) || !method_exists($data['table'], 'delete')) {
                 ++$skipped;
                 continue;
             }
             // Verify columns for new table
             if ($data['table'] !== $currentTable && $currentTable !== null && $backend) {
                 $backend->addMessage('Restoring rows for table ' . $data['table']);
                 $columns = ArrayHelper::objectsToArray(PropelQuery::from($data['table'])->getTableMap()->getColumns(), null, 'getPhpName');
                 $added = array_diff($columns, array_keys($data['values']));
                 $removed = array_diff(array_keys($data['values']), $columns);
                 if (count($added)) {
                     $backend->addMessage('New column(s): ' . join(', ', $added), AbstractBackend::MSG_WARNING);
                 }
                 if (count($removed)) {
                     $backend->addMessage('Removed column(s): ' . join(', ', $removed), AbstractBackend::MSG_WARNING);
                 }
             }
             // Flush buffer when changing tables
             if ($data['table'] !== $currentTable || count($buffer) >= self::MULTIINSERT_MAXBUFFER) {
                 if ($currentTable !== null && count($buffer)) {
                     Propel::doMultiInsert($currentTable, $buffer);
                 }
                 $currentTable = $data['table'];
                 $buffer = array();
             }
             // Migrate data
             if ($pageVersion !== Page::VERSION) {
                 if (!Page::migrateData($data['table'], $data['values'], $pageVersion)) {
                     continue;
                 }
             }
             $buffer[] = $data['values'];
         } else {
             if ($backend) {
                 $backend->addMessage('Unable to read data on line ' . $total, AbstractBackend::MSG_ERROR);
             }
             ++$failed;
         }
         // check execution time
         if ($maxExecutionTime && App::getInstance()->getExecutionTime() > $maxExecutionTime) {
             if ($currentTable !== null && count($buffer)) {
                 Propel::doMultiInsert($currentTable, $buffer);
             }
             $session->total = $total;
             $session->skipped = $skipped;
             $session->failed = $failed;
             $params = array('module' => 'Curry_Backend_Database', 'view' => 'ContinueRestore', 'file' => $file, 'tables' => $tables, 'line' => $total, 'max_execution_time' => $maxExecutionTime);
             AbstractLegacyBackend::redirect(url('', $params)->getAbsolute("&", true));
         }
     }
     // Flush buffer
     if ($currentTable !== null && count($buffer)) {
         Propel::doMultiInsert($currentTable, $buffer);
     }
     if ($pageVersion !== Page::VERSION) {
         Page::postMigrate($pageVersion);
     }
     if ($adapter instanceof DBMySQL) {
         $con->exec("SET foreign_key_checks = 1");
     }
     $con->commit();
     $CURRY_DATABASE_RESTORE = false;
     if ($backend) {
         if ($skipped) {
             $backend->addMessage("Skipped {$skipped} rows");
         }
         if ($failed) {
             $backend->addMessage("Failed to add {$failed} rows", AbstractBackend::MSG_ERROR);
         }
         $backend->addMessage("Added " . ($total - $skipped - $failed) . " / {$total} rows in " . round(microtime(true) - $t, 2) . "s", !$failed ? AbstractBackend::MSG_SUCCESS : AbstractBackend::MSG_ERROR);
     }
     if (is_string($file)) {
         fclose($fp);
     }
     return !$failed;
 }
Exemplo n.º 8
0
 /**
  * Get property from object.
  * 
  * Tries to read a property from an object, in the following order:
  * * Array access $object[$name]
  * * Object property $object->$name
  * * Object magic property $object->$name through __get
  * * Method $object->$name()
  * * Get method $object->get$name()
  * * Propel virtual columns $object->getVirtualColumn($name)
  * * Magic method $object->get$name() __call
  * * Otherwise, return null.
  *
  * @param mixed $object
  * @param mixed $name
  * @return mixed
  */
 public static function getProperty($object, $name)
 {
     // Array
     if ((is_array($object) || is_object($object) && $object instanceof \ArrayAccess) && isset($object[$name])) {
         return $object[$name];
     }
     if (is_object($object)) {
         // Object property
         if (property_exists($object, $name)) {
             return $object->{$name};
         }
         if (method_exists($object, '__get') && isset($object->{$name})) {
             return $object->{$name};
         }
         // Method
         if (method_exists($object, $name)) {
             return $object->{$name}();
         }
         if (method_exists($object, 'get' . $name)) {
             return $object->{'get' . $name}();
         }
         // Propel virtual columns
         if ($object instanceof \BaseObject && $object->hasVirtualColumn($name)) {
             return $object->getVirtualColumn($name);
         }
         // Attempt to call function (__call)
         if (method_exists($object, '__call')) {
             try {
                 return $object->{$name}();
             } catch (\Exception $e) {
                 App::getInstance()->logger->error($e->getMessage());
             }
         }
     }
     return null;
 }
Exemplo n.º 9
0
 public function __construct($modelClass)
 {
     $this->modelClass = $modelClass;
     parent::__construct(App::getInstance());
 }
Exemplo n.º 10
0
 /**
  * Redirect helper to create RedirectResponse with absolute url.
  *
  * @param string|mixed $url
  * @return RedirectResponse
  */
 public static function redirect($url)
 {
     $url = (string) $url;
     if ($url[0] !== '/') {
         // append base path
         $url = App::getInstance()->request->getBasePath() . '/' . $url;
     }
     return RedirectResponse::create($url);
 }
Exemplo n.º 11
0
 public function __toString()
 {
     $request = \Curry\App::getInstance()->request;
     if ($request->query->get('json')) {
         throw new \Curry\Exception\ResponseException($this->show($request));
     }
     return $this->getHtml($request->query->all());
 }
Exemplo n.º 12
0
 protected static function getReleases()
 {
     try {
         // Override user agent
         $opts = array('http' => array('header' => "User-Agent: CurryCMS/" . App::VERSION . " (http://currycms.com)\r\n"));
         $context = stream_context_create($opts);
         $tags = file_get_contents('https://api.github.com/repos/bombayworks/currycms/tags', null, $context);
         $tags = json_decode($tags);
         $versions = array();
         foreach ($tags as $tag) {
             if (preg_match('/^v?([\\d\\.]+.*)$/', strtolower($tag->name), $m)) {
                 $tag->version = $m[1];
                 $versions[$m[1]] = $tag;
             }
         }
         uksort($versions, 'version_compare');
         return $versions;
     } catch (\Exception $e) {
         App::getInstance()->logger->warning('Failed to fetch release list: ' . $e->getMessage());
         return null;
     }
 }
Exemplo n.º 13
0
 /**
  * Get template select options.
  *
  * @return array
  */
 public static function getTemplateSelect()
 {
     $backend = new self(\Curry\App::getInstance());
     $items = array_keys($backend->getFileList());
     return array_combine($items, $items);
 }
Exemplo n.º 14
0
 /**
  * Add Zend_Form_Element_Hash element to form for CSRF protection.
  */
 public function addCsrfProtection()
 {
     if ($this->getMethod() == "post" && isset($this->_elements['csrf']) == false) {
         $salt = md5($this->getAction() . $this->uniqueId . \Curry\App::getInstance()['secret']);
         $this->addElement('hash', 'csrf', array('timeout' => 3600, 'salt' => $salt, 'session' => new \Zend\Session\Container(__CLASS__ . '_' . $salt . '_csrf')));
     }
 }
Exemplo n.º 15
0
 /**
  * Find model from URL.
  *
  * @param string $url
  * @return string|null
  */
 protected static function findPageModel($url)
 {
     if (self::$urlToModel === null) {
         $cacheName = __CLASS__ . '_' . 'UrlToModel';
         if ((self::$urlToModel = App::getInstance()->cache->load($cacheName)) === false) {
             self::$urlToModel = \PageQuery::create()->filterByModelRoute(null, \Criteria::ISNOTNULL)->find()->toKeyValue('Url', 'ModelRoute');
             App::getInstance()->cache->save(self::$urlToModel, $cacheName);
         }
     }
     return isset(self::$urlToModel[$url]) ? self::$urlToModel[$url] : null;
 }
Exemplo n.º 16
0
 /**
  * @param \User|\UserRole $userOrRole
  * @param $name
  * @param $path
  * @param bool $write
  * @return \FilebrowserAccess
  * @throws \Exception
  */
 protected static function createFilebrowserAccess($userOrRole, $name, $path, $write = true)
 {
     $fba = new \FilebrowserAccess();
     $fba->setName($name);
     if ($userOrRole instanceof \User) {
         $fba->setUser($userOrRole);
     } else {
         if ($userOrRole instanceof \UserRole) {
             $fba->setUserRole($userOrRole);
         }
     }
     $fba->setPath($path);
     $fba->setWrite($write);
     @mkdir(PathHelper::path(\Curry\App::getInstance()['wwwPath'], $path), 0777, true);
     return $fba;
 }
Exemplo n.º 17
0
 public function __toString()
 {
     if (!array_key_exists('url', $this->options['initAjax'])) {
         $this->setAjaxUrl($this->parent ? $this->url() : array('url' => (string) url('', $_GET)->add(array('json' => '1'))));
     }
     if (isset($_GET['json'])) {
         throw new ResponseException($this->show(App::getInstance()->request));
     }
     return $this->getHtml();
 }
Exemplo n.º 18
0
<?php

if ($_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
    return false;
}
require __DIR__ . '/../vendor/autoload.php';
\Curry\App::create(__DIR__ . '/../cms/config/config.php')->run();
Exemplo n.º 19
0
 /**
  * Create the Curry\Module\AbstractModule instance from the serialized data.
  *
  * @param bool $inherited
  * @return AbstractModule
  */
 public function createObject($inherited = true)
 {
     // Make sure the module class exists
     $className = $this->getClassName();
     if (!class_exists($className)) {
         throw new \Exception("Module class '{$className}' not found.");
     }
     // Get the module data
     $moduleDataId = null;
     if (!$inherited) {
         $moduleData = $this->getModuleData();
         $data = $moduleData->getData();
         $moduleDataId = $moduleData->getModuleDataId();
     } else {
         $data = $this->data;
         $moduleDataId = $this->dataSourceId;
     }
     // Create instance
     $obj = null;
     if ($data !== null) {
         try {
             $obj = unserialize($data);
             if ($obj && !$obj instanceof $className) {
                 App::getInstance()->logger->warning('Module class mismatch ' . $className);
                 $obj = null;
             }
         } catch (\Exception $e) {
             App::getInstance()->logger->warning('Failed to unserialize module of class ' . $className);
         }
     }
     if (!$obj) {
         $obj = new $className();
     }
     $obj->setModuleDataId($moduleDataId);
     return $obj;
 }
Exemplo n.º 20
0
 protected static function handleRequest(Request $request)
 {
     return App::getInstance()->handle($request);
 }
Exemplo n.º 21
0
 public static function getTemplatePage()
 {
     $templatePage = \Curry\App::getInstance()['backend.templatePage'];
     return $templatePage ? PageQuery::create()->findPk($templatePage) : null;
 }
Exemplo n.º 22
0
 public function render(RenderEvent $event)
 {
     $appVars = App::getInstance()->globals;
     $htmlHead = App::getInstance()->generator->getHtmlHead();
     $appVars->HtmlHead = $htmlHead->getContent();
 }
Exemplo n.º 23
0
 /**
  * Map physical path to public path.
  *
  * @param string $physical
  * @return string
  */
 public static function physicalToPublic($physical)
 {
     $www = \Curry\App::getInstance()['wwwPath'];
     if (substr($physical, 0, strlen($www)) == $www) {
         return substr($physical, strlen($www) + 1);
     }
     throw new Curry_Exception('Unable to map "' . $physical . '" to public path');
 }
Exemplo n.º 24
0
 /**
  * Get language string from the specified language. If the string is not found, the variableName is returned.
  *
  * @param string $variableName
  * @param Language|string|null $language Language, langcode (string) or null for active language.
  * @return string
  */
 public static function get($variableName, $language = null)
 {
     if (\Curry\App::getInstance()['updateTranslationStrings']) {
         self::$used[] = $variableName;
     }
     $language = self::_getLanguage($language);
     if ($language && isset(self::$languageStrings[$language->getLangcode()][$variableName])) {
         return self::$languageStrings[$language->getLangcode()][$variableName];
     }
     return $variableName;
 }
Exemplo n.º 25
0
 /**
  * Should be called before calling doRebuild().
  */
 public static function initRebuild()
 {
     $models = array();
     foreach (Propel::getModels() as $classes) {
         foreach ($classes as $model) {
             if (in_array('Curry_ISearchable', class_implements($model))) {
                 $models[] = $model;
             }
         }
     }
     if (\Curry\App::getInstance()['indexerClass']) {
         $models[] = '@custom';
     }
     $ses = new \Zend\Session\Container(__CLASS__);
     $ses->models = $models;
     $ses->model = 0;
     $ses->offset = 0;
     $ses->limit = 10;
     $ses->failed = 0;
     $ses->success = 0;
 }
Exemplo n.º 26
0
 /**
  * Save new module.
  * 
  * @todo Set module position.
  *
  * @param PageRevision $pageRevision
  * @param array $values
  * @return PageModule
  */
 public static function saveNewModule(PageRevision $pageRevision, array $values)
 {
     $pageModule = new PageModule();
     $pageModule->setUid(Helper::getUniqueId());
     $pageModule->setPageId($pageRevision->getPageId());
     if (ctype_digit($values['module_class'])) {
         $module = ModuleQuery::create()->findPk($values['module_class']);
         $pageModule->setModuleClass($module->getModuleClass());
         $pageModule->setName($values['name']);
         $pageModule->setTarget($values['target']);
         $pageModule->setContentVisibility($module->getContentVisibility());
         $pageModule->setSearchVisibility($module->getSearchVisibility());
         $template = $module->getTemplate();
     } else {
         $template = null;
         if ($values['template'] == 'new' && $values['template_name']) {
             $className = $values['module_class'];
             $predefinedTemplates = call_user_func(array($className, 'getPredefinedTemplates'));
             $root = \Curry\App::getInstance()['template.root'];
             $template = $values['template_name'];
             $templateFile = $root . DIRECTORY_SEPARATOR . $template;
             if (!file_exists($templateFile)) {
                 $dir = dirname($templateFile);
                 if (!is_dir($dir)) {
                     mkdir($dir, 0777, true);
                 }
                 $code = $predefinedTemplates[$values['predefined_template']];
                 file_put_contents($templateFile, (string) $code);
             }
         } else {
             if ($values['template']) {
                 $template = $values['template'];
             }
         }
         $target = '';
         if (!empty($values['target'])) {
             $target = $values['target'];
         } else {
             if (!empty($values['target_name'])) {
                 $target = $values['target_name'];
             }
         }
         if (empty($target)) {
             throw new Exception('Module target not set');
         }
         $pageModule = new PageModule();
         $pageModule->setUid(Helper::getUniqueId());
         $pageModule->setPageId($pageRevision->getPageId());
         $pageModule->setModuleClass($values['module_class']);
         $pageModule->setName($values['name']);
         $pageModule->setTarget($target);
         $pageModule->setContentVisibility($values['content_visibility']);
         $pageModule->setSearchVisibility($values['search_visibility']);
     }
     $pageModule->save();
     $revisionModule = new RevisionModule();
     $revisionModule->setPageModule($pageModule);
     $revisionModule->setPageRevision($pageRevision);
     $revisionModule->save();
     $moduleData = new ModuleData();
     $moduleData->setPageRevision($pageRevision);
     $moduleData->setPageModule($pageModule);
     $moduleData->setEnabled(true);
     $moduleData->setTemplate($template);
     $moduleData->save();
     // create default data
     $wrapper = new PageModuleWrapper($pageModule, $pageRevision, null);
     $wrapper->createData();
     return $pageModule;
 }