/**
  * Ensures that there is always a 404 page by checking if there's an
  * instance of ErrorPage with a 404 and 500 error code. If there is not,
  * one is created when the DB is built.
  */
 public function requireDefaultRecords()
 {
     parent::requireDefaultRecords();
     if ($this->class === 'ErrorPage' && SiteTree::config()->create_default_pages) {
         $defaultPages = $this->getDefaultRecords();
         foreach ($defaultPages as $defaultData) {
             $code = $defaultData['ErrorCode'];
             $page = ErrorPage::get()->filter('ErrorCode', $code)->first();
             $pageExists = !empty($page);
             if (!$pageExists) {
                 $page = new ErrorPage($defaultData);
                 $page->write();
                 $page->publish('Stage', 'Live');
             }
             // Check if static files are enabled
             if (!self::config()->enable_static_file) {
                 continue;
             }
             // Ensure this page has cached error content
             $success = true;
             if (!$page->hasStaticPage()) {
                 // Update static content
                 $success = $page->writeStaticPage();
             } elseif ($pageExists) {
                 // If page exists and already has content, no alteration_message is displayed
                 continue;
             }
             if ($success) {
                 DB::alteration_message(sprintf('%s error page created', $code), 'created');
             } else {
                 DB::alteration_message(sprintf('%s error page could not be created. Please check permissions', $code), 'error');
             }
         }
     }
 }
 /**
  * New tests require nested urls to be enabled, but the site might not 
  * support nested URLs. 
  * This setup will enable nested-urls for this test and resets the state
  * after the tests have been performed.
  */
 public function tearDown()
 {
     if (isset($this->orig['nested_urls']) && !$this->orig['nested_urls']) {
         SiteTree::config()->nested_urls = false;
     }
     parent::tearDown();
 }
 /**
  * Updates the CMS fields adding the fields defined in this extension
  * @param {FieldList} $fields Field List that new fields will be added to
  */
 public function updateCMSFields(FieldList $fields)
 {
     $urlSegmentField = $fields->dataFieldByName('URLSegment');
     if ($urlSegmentField) {
         $baseLink = Controller::join_links(Director::absoluteBaseURL(), (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL') ? $this->owner->Locale : i18n::get_lang_from_locale($this->owner->Locale)) . '/', SiteTree::config()->nested_urls && $this->owner->ParentID ? $this->owner->Parent()->RelativeLink(true) : null);
         $urlSegmentField->setURLPrefix($baseLink);
     }
 }
 public function testGetHomepageLink()
 {
     $default = $this->objFromFixture('Page', 'home');
     SiteTree::config()->nested_urls = false;
     $this->assertEquals('home', RootURLController::get_homepage_link());
     Config::inst()->update('SiteTree', 'nested_urls', true);
     $this->assertEquals('home', RootURLController::get_homepage_link());
 }
 public function updateCMSFields(FieldList $fields)
 {
     parent::updateCMSFields($fields);
     // Fix URLSegment field issue for root pages
     if (!SiteTree::config()->nested_urls || empty($this->owner->ParentID)) {
         $baseLink = Director::absoluteURL(Controller::join_links(Director::baseURL(), Fluent::alias(Fluent::current_locale()), '/'));
         $urlsegment = $fields->dataFieldByName('URLSegment');
         $urlsegment->setURLPrefix($baseLink);
     }
 }
 public function testDeepNestedURLs()
 {
     Config::inst()->update('SiteTree', 'nested_urls', true);
     $page = new Page();
     $page->URLSegment = 'base-page';
     $page->write();
     for ($i = 0; $i < 10; $i++) {
         $parentID = $page->ID;
         $page = new ContentControllerTest_Page();
         $page->ParentID = $parentID;
         $page->Title = "Page Level {$i}";
         $page->URLSegment = "level-{$i}";
         $page->write();
         $relativeLink = Director::makeRelative($page->Link());
         $this->assertEquals($page->Title, $this->get($relativeLink)->getBody());
     }
     SiteTree::config()->nested_urls = false;
 }
示例#7
0
 /**
  * Ensures that there is always a 404 page by checking if there's an
  * instance of ErrorPage with a 404 and 500 error code. If there is not,
  * one is created when the DB is built.
  */
 public function requireDefaultRecords()
 {
     parent::requireDefaultRecords();
     if ($this->class == 'ErrorPage' && SiteTree::config()->create_default_pages) {
         // Ensure that an assets path exists before we do any error page creation
         if (!file_exists(ASSETS_PATH)) {
             mkdir(ASSETS_PATH);
         }
         $defaultPages = $this->getDefaultRecords();
         foreach ($defaultPages as $defaultData) {
             $code = $defaultData['ErrorCode'];
             $page = DataObject::get_one('ErrorPage', sprintf("\"ErrorPage\".\"ErrorCode\" = '%s'", $code));
             $pageExists = $page && $page->exists();
             $pagePath = self::get_filepath_for_errorcode($code);
             if (!($pageExists && file_exists($pagePath))) {
                 if (!$pageExists) {
                     $page = new ErrorPage($defaultData);
                     $page->write();
                     $page->publish('Stage', 'Live');
                 }
                 // Ensure a static error page is created from latest error page content
                 $response = Director::test(Director::makeRelative($page->Link()));
                 $written = null;
                 if ($fh = fopen($pagePath, 'w')) {
                     $written = fwrite($fh, $response->getBody());
                     fclose($fh);
                 }
                 if ($written) {
                     DB::alteration_message(sprintf('%s error page created', $code), 'created');
                 } else {
                     DB::alteration_message(sprintf('%s error page could not be created at %s. Please check permissions', $code, $pagePath), 'error');
                 }
             }
         }
     }
 }
 /**
  * @return ContentController
  * @throws Exception If URLSegment not passed in as a request parameter.
  */
 public function getNestedController()
 {
     $request = $this->getRequest();
     if (!($URLSegment = $request->param('URLSegment'))) {
         throw new Exception('ModelAsController->getNestedController(): was not passed a URLSegment value.');
     }
     // Find page by link, regardless of current locale settings
     if (class_exists('Translatable')) {
         Translatable::disable_locale_filter();
     }
     // Select child page
     $conditions = array('"SiteTree"."URLSegment"' => rawurlencode($URLSegment));
     if (SiteTree::config()->nested_urls) {
         $conditions[] = array('"SiteTree"."ParentID"' => 0);
     }
     $sitetree = DataObject::get_one('SiteTree', $conditions);
     // Check translation module
     // @todo Refactor out module specific code
     if (class_exists('Translatable')) {
         Translatable::enable_locale_filter();
     }
     if (!$sitetree) {
         $response = ErrorPage::response_for(404);
         $this->httpError(404, $response ? $response : 'The requested page could not be found.');
     }
     // Enforce current locale setting to the loaded SiteTree object
     if (class_exists('Translatable') && $sitetree->Locale) {
         Translatable::set_current_locale($sitetree->Locale);
     }
     if (isset($_REQUEST['debug'])) {
         Debug::message("Using record #{$sitetree->ID} of type {$sitetree->class} with link {$sitetree->Link()}");
     }
     return self::controller_for($sitetree, $this->getRequest()->param('Action'));
 }
 /**
  * @covers SiteTree::validURLSegment
  */
 public function testValidURLSegmentURLSegmentConflicts()
 {
     $sitetree = new SiteTree();
     SiteTree::config()->nested_urls = false;
     $sitetree->URLSegment = 'home';
     $this->assertFalse($sitetree->validURLSegment(), 'URLSegment conflicts are recognised');
     $sitetree->URLSegment = 'home-noconflict';
     $this->assertTrue($sitetree->validURLSegment());
     $sitetree->ParentID = $this->idFromFixture('Page', 'about');
     $sitetree->URLSegment = 'home';
     $this->assertFalse($sitetree->validURLSegment(), 'Conflicts are still recognised with a ParentID value');
     Config::inst()->update('SiteTree', 'nested_urls', true);
     $sitetree->ParentID = 0;
     $sitetree->URLSegment = 'home';
     $this->assertFalse($sitetree->validURLSegment(), 'URLSegment conflicts are recognised');
     $sitetree->ParentID = $this->idFromFixture('Page', 'about');
     $this->assertTrue($sitetree->validURLSegment(), 'URLSegments can be the same across levels');
     $sitetree->URLSegment = 'my-staff';
     $this->assertFalse($sitetree->validURLSegment(), 'Nested URLSegment conflicts are recognised');
     $sitetree->URLSegment = 'my-staff-noconflict';
     $this->assertTrue($sitetree->validURLSegment());
 }
示例#10
0
 public function onBeforeDelete()
 {
     parent::onBeforeDelete();
     // If deleting this page, delete all its children.
     if (SiteTree::config()->enforce_strict_hierarchy && ($children = $this->AllChildren())) {
         foreach ($children as $child) {
             $child->delete();
         }
     }
 }
示例#11
0
 /**
  * @return ContentController
  */
 public function getNestedController()
 {
     $request = $this->request;
     if (!($URLSegment = $request->param('URLSegment'))) {
         throw new Exception('ModelAsController->getNestedController(): was not passed a URLSegment value.');
     }
     // Find page by link, regardless of current locale settings
     if (class_exists('Translatable')) {
         Translatable::disable_locale_filter();
     }
     $sitetree = DataObject::get_one('SiteTree', sprintf('"SiteTree"."URLSegment" = \'%s\' %s', Convert::raw2sql(rawurlencode($URLSegment)), SiteTree::config()->nested_urls ? 'AND "SiteTree"."ParentID" = 0' : null));
     if (class_exists('Translatable')) {
         Translatable::enable_locale_filter();
     }
     if (!$sitetree) {
         $response = ErrorPage::response_for(404);
         $this->httpError(404, $response ? $response : 'The requested page could not be found.');
     }
     // Enforce current locale setting to the loaded SiteTree object
     if (class_exists('Translatable') && $sitetree->Locale) {
         Translatable::set_current_locale($sitetree->Locale);
     }
     if (isset($_REQUEST['debug'])) {
         Debug::message("Using record #{$sitetree->ID} of type {$sitetree->class} with link {$sitetree->Link()}");
     }
     return self::controller_for($sitetree, $this->request->param('Action'));
 }
 /**
  * This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to
  * fall over to a child controller in order to provide functionality for nested URLs.
  *
  * @param SS_HTTPRequest $request
  * @param DataModel $model
  * @return SS_HTTPResponse
  * @throws SS_HTTPResponse_Exception
  */
 public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
 {
     $child = null;
     $action = $request->param('Action');
     $this->setDataModel($model);
     // If nested URLs are enabled, and there is no action handler for the current request then attempt to pass
     // control to a child controller. This allows for the creation of chains of controllers which correspond to a
     // nested URL.
     if ($action && SiteTree::config()->nested_urls && !$this->hasAction($action)) {
         // See ModelAdController->getNestedController() for similar logic
         if (class_exists('Translatable')) {
             Translatable::disable_locale_filter();
         }
         // look for a page with this URLSegment
         $child = $this->model->SiteTree->filter(array('ParentID' => $this->ID, 'URLSegment' => rawurlencode($action)))->first();
         if (class_exists('Translatable')) {
             Translatable::enable_locale_filter();
         }
     }
     // we found a page with this URLSegment.
     if ($child) {
         $request->shiftAllParams();
         $request->shift();
         $response = ModelAsController::controller_for($child)->handleRequest($request, $model);
     } else {
         // If a specific locale is requested, and it doesn't match the page found by URLSegment,
         // look for a translation and redirect (see #5001). Only happens on the last child in
         // a potentially nested URL chain.
         if (class_exists('Translatable')) {
             if ($request->getVar('locale') && $this->dataRecord && $this->dataRecord->Locale != $request->getVar('locale')) {
                 $translation = $this->dataRecord->getTranslation($request->getVar('locale'));
                 if ($translation) {
                     $response = new SS_HTTPResponse();
                     $response->redirect($translation->Link(), 301);
                     throw new SS_HTTPResponse_Exception($response);
                 }
             }
         }
         Director::set_current_page($this->data());
         try {
             $response = parent::handleRequest($request, $model);
             Director::set_current_page(null);
         } catch (SS_HTTPResponse_Exception $e) {
             $this->popCurrent();
             Director::set_current_page(null);
             throw $e;
         }
     }
     return $response;
 }
 /**
  * Try to determine the controller for the current request.
  *
  * @return type Controller
  */
 public function getNestedController()
 {
     $URLSegment = $this->request->param('URLSegment');
     if (empty($URLSegment)) {
         PrefixRootURLController::set_is_at_root();
         // get the homepage from the defaul homepage Translation Group
         $URLSegment = LanguagePrefix::get_homepage_link_by_locale($this->locale);
         // if no homepage is found in the default translation group for this locale
         // use the first page in the tree instead
         if (empty($URLSegment)) {
             //@TODO: make 3.0
             $sitetree = SiteTree::get()->filter(array('ParentID' => '0', 'Locale' => $this->locale))->sort('Sort')->First();
             if ($sitetree) {
                 $URLSegment = $sitetree->URLSegment;
             } else {
                 // last resort
                 $URLSegment = self::$default_homepage_link;
             }
         }
     }
     // We have an URLSegment: find the page with this segment - within the current locale
     // In the original ModelAsController the locale filter is disabled for this query,
     // meaning /nl/englishHomePage/ will be found and be redirected later on
     // to /en/englishHomePage/ where I'd rather have a 404!!
     Translatable::enable_locale_filter();
     // make sure multibyte urls are supported
     $sitetree = DataObject::get_one('SiteTree', sprintf('"SiteTree"."URLSegment" = \'%s\' %s', Convert::raw2sql(rawurlencode($URLSegment)), SiteTree::config()->nested_urls ? 'AND "SiteTree"."ParentID" = 0' : null));
     // As in the original ModelAsController: if no page can be found, check if it
     // has been renamed or relocated - again: within the current locale!!!
     // If the current $URLSegment refers to an 'old page', do a 302 redirect to the
     // current version (this works for bookmarked pages)
     // Note: for this the find_old_page() function needs to be localized as well to
     // find_old_page_localized()
     if (empty($sitetree)) {
         if ($redirect = self::find_old_page_localized($URLSegment)) {
             $params = $this->request->getVars();
             if (isset($params['url'])) {
                 unset($params['url']);
             }
             $this->response = new SS_HTTPResponse();
             $this->response->redirect(Controller::join_links($redirect->Link(Controller::join_links($this->request->param('Action'), $this->request->param('ID'), $this->request->param('OtherID'))), $params ? '?' . http_build_query($params) : null), 301);
             return $this->response;
         }
         // all is now lost!
         return $this->showPageNotFound();
     }
     // This we don't really need anymore...
     // Enforce current locale setting to the loaded SiteTree object
     // if($sitetree->Locale) Translatable::set_current_locale($sitetree->Locale);
     if (isset($_REQUEST['debug'])) {
         Debug::message("Using record #{$sitetree->ID} of type {$sitetree->class} with link {$sitetree->Link()}");
     }
     return self::controller_for($sitetree, $this->request->param('Action'));
 }