/** * Constructor. */ public function __construct() { parent::__construct(); BackendMenu::setContext('October.Cms', 'cms', true); try { if (!($theme = Theme::getEditTheme())) { throw new ApplicationException(Lang::get('cms::lang.theme.edit.not_found')); } $this->theme = $theme; new TemplateList($this, 'pageList', function () use($theme) { return Page::listInTheme($theme, true); }); new TemplateList($this, 'partialList', function () use($theme) { return Partial::listInTheme($theme, true); }); new TemplateList($this, 'layoutList', function () use($theme) { return Layout::listInTheme($theme, true); }); new TemplateList($this, 'contentList', function () use($theme) { return Content::listInTheme($theme, true); }); new ComponentList($this, 'componentList'); new AssetList($this, 'assetList'); } catch (Exception $ex) { $this->handleError($ex); } }
public function testLists() { // Default theme: test $pages = Page::lists('baseFileName'); sort($pages); $this->assertEquals(["404", "a/a-page", "ajax-test", "authors", "b/b-page", "blog-archive", "blog-post", "code-namespaces", "code-namespaces-aliases", "component-custom-render", "component-partial", "component-partial-nesting", "component-partial-override", "cycle-test", "index", "no-component", "no-component-class", "no-layout", "no-partial", "optional-full-php-tags", "optional-short-php-tags", "throw-php", "with-component", "with-components", "with-content", "with-layout", "with-partials", "with-placeholder"], $pages); $layouts = Layout::lists('baseFileName'); sort($layouts); $this->assertEquals(["a/a-layout", "ajax-test", "content", "cycle-test", "no-php", "partials", "php-parser-test", "placeholder", "sidebar"], $layouts); }
private function spoofPageCode() { // Spoof all the objects we need to make a page object $theme = Theme::load('test'); $page = Page::load($theme, 'index.htm'); $layout = Layout::load($theme, 'content.htm'); $controller = new Controller($theme); $parser = new CodeParser($page); $pageObj = $parser->source($page, $layout, $controller); return $pageObj; }
/** * Returns a list of layouts available in the theme. * This method is used by the form widget. * @return array Returns an array of strings. */ public function getLayoutOptions() { if (!($theme = Theme::getEditTheme())) { throw new ApplicationException(Lang::get('cms::lang.theme.edit.not_found')); } $layouts = Layout::listInTheme($theme, true); $result = []; $result[null] = Lang::get('cms::lang.page.no_layout'); foreach ($layouts as $layout) { $baseName = $layout->getBaseFileName(); $result[$baseName] = strlen($layout->name) ? $layout->name : $baseName; } return $result; }
/** * Scans the theme templates for message references. * @return void */ public function scanForMessages() { $messages = []; foreach (Layout::all() as $layout) { $messages = array_merge($messages, $this->parseContent($layout->markup)); } foreach (Page::all() as $page) { $messages = array_merge($messages, $this->parseContent($page->markup)); } foreach (Partial::all() as $partial) { $messages = array_merge($messages, $this->parseContent($partial->markup)); } Message::importMessages($messages); }
/** * Constructor. */ public function __construct() { parent::__construct(); BackendMenu::setContext('October.Cms', 'cms', 'pages'); try { if (!($theme = Theme::getEditTheme())) { throw new ApplicationException(Lang::get('cms::lang.theme.edit.not_found')); } $this->theme = $theme; new TemplateList($this, 'pageList', function () use($theme) { return Page::listInTheme($theme, true); }); new TemplateList($this, 'partialList', function () use($theme) { return Partial::listInTheme($theme, true); }); new TemplateList($this, 'layoutList', function () use($theme) { return Layout::listInTheme($theme, true); }); new TemplateList($this, 'contentList', function () use($theme) { return Content::listInTheme($theme, true); }); new ComponentList($this, 'componentList'); new AssetList($this, 'assetList'); } catch (Exception $ex) { $this->handleError($ex); } $this->addJs('/modules/cms/assets/js/october.cmspage.js', 'core'); $this->addJs('/modules/cms/assets/js/october.dragcomponents.js', 'core'); $this->addCss('/modules/cms/assets/css/october.components.css', 'core'); // Preload Ace editor modes explicitly, because they could be changed dynamically // depending on a content block type $this->addJs('/modules/backend/formwidgets/codeeditor/assets/vendor/ace/ace.js', 'core'); $aceModes = ['markdown', 'plain_text', 'html', 'less', 'css', 'scss', 'sass', 'javascript']; foreach ($aceModes as $mode) { $this->addJs('/modules/backend/formwidgets/codeeditor/assets/vendor/ace/mode-' . $mode . '.js', 'core'); } $this->bodyClass = 'compact-container side-panel-not-fixed'; $this->pageTitle = Lang::get('cms::lang.cms.menu_label'); }
/** * Runs a page directly from its object and supplied parameters. * @param \Cms\Classes\Page $page Specifies the CMS page to run. * @return string */ public function runPage($page, $useAjax = true) { $this->page = $page; /* * If the page doesn't refer any layout, create the fallback layout. * Otherwise load the layout specified in the page. */ if (!$page->layout) { $layout = Layout::initFallback($this->theme); } elseif (($layout = Layout::loadCached($this->theme, $page->layout)) === null) { throw new CmsException(Lang::get('cms::lang.layout.not_found_name', ['name' => $page->layout])); } $this->layout = $layout; /* * The 'this' variable is reserved for default variables. */ $this->vars['this'] = ['page' => $this->page, 'layout' => $this->layout, 'theme' => $this->theme, 'param' => $this->router->getParameters(), 'controller' => $this, 'environment' => App::environment(), 'session' => App::make('session')]; /* * Check for the presence of validation errors in the session. */ $this->vars['errors'] = Config::get('session.driver') && Session::has('errors') ? Session::get('errors') : new \Illuminate\Support\ViewErrorBag(); /* * Handle AJAX requests and execute the life cycle functions */ $this->initCustomObjects(); $this->initComponents(); /* * Give the layout and page an opportunity to participate * after components are initialized and before AJAX is handled. */ if ($this->layoutObj) { CmsException::mask($this->layout, 300); $this->layoutObj->onInit(); CmsException::unmask(); } CmsException::mask($this->page, 300); $this->pageObj->onInit(); CmsException::unmask(); /* * Extensibility */ if (($event = $this->fireEvent('page.init', [$page], true)) || ($event = Event::fire('cms.page.init', [$this, $page], true))) { return $event; } /* * Execute AJAX event */ if ($useAjax && ($ajaxResponse = $this->execAjaxHandlers())) { return $ajaxResponse; } /* * Execute postback handler */ if ($useAjax && ($handler = post('_handler')) && ($handlerResponse = $this->runAjaxHandler($handler)) && $handlerResponse !== true) { return $handlerResponse; } /* * Execute page lifecycle */ if ($cycleResponse = $this->execPageCycle()) { return $cycleResponse; } /* * Extensibility */ if (($event = $this->fireEvent('page.beforeRenderPage', [$page], true)) || ($event = Event::fire('cms.page.beforeRenderPage', [$this, $page], true))) { $this->pageContents = $event; } else { /* * Render the page */ CmsException::mask($this->page, 400); $this->loader->setObject($this->page); $template = $this->twig->loadTemplate($this->page->getFullPath()); $this->pageContents = $template->render($this->vars); CmsException::unmask(); } /* * Render the layout */ CmsException::mask($this->layout, 400); $this->loader->setObject($this->layout); $template = $this->twig->loadTemplate($this->layout->getFullPath()); $result = $template->render($this->vars); CmsException::unmask(); return $result; }
/** * Looks up the Layout Cms object for this page. * @return Cms\Classes\Layout */ public function getLayoutObject() { $viewBag = $this->getViewBag(); $layout = $viewBag->property('layout'); if (!$layout) { $layouts = $this->getLayoutOptions(); $layout = count($layouts) ? array_keys($layouts)[0] : null; } if (!$layout) { return null; } $layout = Layout::load($this->theme, $layout); if (!$layout) { return null; } return $layout; }
/** * Finds and serves the requested page. * If the page cannot be found, returns the page with the URL /404. * If the /404 page doesn't exist, returns the system 404 page. * @param string $url Specifies the requested page URL. * If the parameter is omitted, the current URL used. * @return string Returns the processed page content. */ public function run($url = '/') { if ($url === null) { $url = Request::path(); } if (!strlen($url)) { $url = '/'; } /* * Handle hidden pages */ $page = $this->router->findByUrl($url); if ($page && $page->hidden) { if (!BackendAuth::getUser()) { $page = null; } } /* * Extensibility */ if ($event = $this->fireEvent('page.beforeDisplay', [$url, $page], true)) { return $event; } if ($event = Event::fire('cms.page.beforeDisplay', [$this, $url, $page], true)) { return $event; } /* * If the page was not found, render the 404 page - either provided by the theme or the built-in one. */ if (!$page) { $this->setStatusCode(404); // Log the 404 request RequestLog::add(); if (!($page = $this->router->findByUrl('/404'))) { return Response::make(View::make('cms::404'), $this->statusCode); } } $this->page = $page; /* * If the page doesn't refer any layout, create the fallback layout. * Otherwise load the layout specified in the page. */ if (!$page->layout) { $layout = Layout::initFallback($this->theme); } elseif (($layout = Layout::loadCached($this->theme, $page->layout)) === null) { throw new CmsException(Lang::get('cms::lang.layout.not_found', ['name' => $page->layout])); } $this->layout = $layout; /* * The 'this' variable is reserved for default variables. */ $this->vars['this'] = ['controller' => $this, 'layout' => $this->layout, 'page' => $this->page, 'param' => $this->router->getParameters(), 'environment' => App::environment()]; /* * Handle AJAX requests and execute the life cycle functions */ $this->initCustomObjects(); $this->initComponents(); /* * Give the layout and page an opportunity to participate * after components are initialized and before AJAX is handled. */ if ($this->layoutObj) { CmsException::mask($this->layout, 300); $this->layoutObj->onInit(); CmsException::unmask(); } CmsException::mask($this->page, 300); $this->pageObj->onInit(); CmsException::unmask(); /* * Extensibility */ if ($event = $this->fireEvent('page.init', [$url, $page], true)) { return $event; } if ($event = Event::fire('cms.page.init', [$this, $url, $page], true)) { return $event; } /* * Execute AJAX event */ if ($ajaxResponse = $this->execAjaxHandlers()) { return $ajaxResponse; } /* * Execute postback handler */ if (($handler = post('_handler')) && ($handlerResponse = $this->runAjaxHandler($handler)) && $handlerResponse !== true) { return $handlerResponse; } /* * Execute page lifecycle */ if ($cycleResponse = $this->execPageCycle()) { return $cycleResponse; } /* * Render the page */ CmsException::mask($this->page, 400); $this->loader->setObject($this->page); $template = $this->twig->loadTemplate($this->page->getFullPath()); $this->pageContents = $template->render($this->vars); CmsException::unmask(); /* * Render the layout */ CmsException::mask($this->layout, 400); $this->loader->setObject($this->layout); $template = $this->twig->loadTemplate($this->layout->getFullPath()); $result = $template->render($this->vars); CmsException::unmask(); /* * Extensibility */ if ($event = $this->fireEvent('page.display', [$url, $page], true)) { return $event; } if ($event = Event::fire('cms.page.display', [$this, $url, $page], true)) { return $event; } if (!is_string($result)) { return $result; } return Response::make($result, $this->statusCode); }
public function testParseNoPhp() { $theme = Theme::load('test'); $layout = Layout::load($theme, 'no-php.htm'); $this->assertNotEmpty($layout); $parser = new CodeParser($layout); $info = $parser->parse(); $this->assertInternalType('array', $info); $this->assertArrayHasKey('filePath', $info); $this->assertArrayHasKey('className', $info); $this->assertArrayHasKey('source', $info); $this->assertFileExists($info['filePath']); $expectedContent = '<?php ' . PHP_EOL; $expectedContent .= 'class ' . $info['className'] . ' extends \\Cms\\Classes\\LayoutCode' . PHP_EOL; $expectedContent .= '{' . PHP_EOL; $expectedContent .= PHP_EOL; $expectedContent .= '}' . PHP_EOL; $this->assertEquals($expectedContent, file_get_contents($info['filePath'])); }
/** * Finds and serves the requested page. * If the page cannot be found, returns the page with the URL /404. * If the /404 page doesn't exist, returns the system 404 page. * @param string $url Specifies the requested page URL. * If the parameter is omitted, the current URL used. * @return string Returns the processed page content. */ public function run($url = null) { if (!$url) { $url = Request::path(); } if (!strlen($url)) { $url = '/'; } $this->router = new Router($this->theme); $page = $this->router->findByUrl($url); /* * Extensibility */ if ($event = Event::fire('cms.page.beforeDisplay', [$this, $url, $page], true)) { return $event; } if ($event = $this->fireEvent('page.beforeDisplay', [$this, $url, $page], true)) { return $event; } /* * If the page was not found, render the 404 page - either provided by the theme or the built-in one. */ if (!$page && !($page = $this->router->findByUrl('/404'))) { return Response::make(View::make('cms::404'), 404); } $this->page = $page; /* * If the page doesn't refer any layout, create the fallback layout. * Otherwise load the layout specified in the page. */ if (!$page->layout) { $layout = Layout::initFallback($this->theme); } elseif (($layout = Layout::loadCached($this->theme, $page->layout)) === null) { throw new CmsException(Lang::get('cms::lang.layout.not_found', ['name' => $page->layout])); } $this->layout = $layout; $this->initTwigEnvironment(); /* * The 'this' variable is reserved for default variables. */ $this->vars['this'] = ['layout' => $this->layout, 'page' => $this->page, 'param' => $this->router->getParameters(), 'environment' => App::environment()]; /* * Handle AJAX requests and execute the life cycle functions */ $this->initCustomObjects(); $this->initComponents(); /* * Execute AJAX event */ if ($ajaxResponse = $this->execAjaxHandlers()) { return $ajaxResponse; } /* * Execute postback handler */ if (($handler = post('_handler')) && ($handlerResponse = $this->runAjaxHandler($handler)) && $handlerResponse !== true) { return $handlerResponse; } /* * Execute page lifecycle */ if ($cycleResponse = $this->execPageCycle()) { return $cycleResponse; } /* * Render the page */ CmsException::capture($this->page, 400, function () { $this->loader->setObject($this->page); $template = $this->twig->loadTemplate($this->page->getFullPath()); $this->pageContents = $template->render($this->vars); }); /* * Render the layout */ $result = CmsException::capture($this->layout, 400, function () { $this->loader->setObject($this->layout); $template = $this->twig->loadTemplate($this->layout->getFullPath()); return $template->render($this->vars); }); /* * Extensibility */ if ($event = Event::fire('cms.page.display', [$this, $url, $page], true)) { return $event; } if ($event = $this->fireEvent('page.display', [$this, $url, $page], true)) { return $event; } return $result; }