public static function disable_nested_urls() { self::$nested_urls = false; }
function setUp() { // Mark test as being run $this->originalIsRunningTest = self::$is_running_test; self::$is_running_test = true; // i18n needs to be set to the defaults or tests fail i18n::set_locale(i18n::default_locale()); i18n::set_date_format(null); i18n::set_time_format(null); // Remove password validation $this->originalMemberPasswordValidator = Member::password_validator(); $this->originalRequirements = Requirements::backend(); Member::set_password_validator(null); Cookie::set_report_errors(false); RootURLController::reset(); Translatable::reset(); Versioned::reset(); DataObject::reset(); SiteTree::reset(); Hierarchy::reset(); if (Controller::has_curr()) { Controller::curr()->setSession(new Session(array())); } $this->originalTheme = SSViewer::current_theme(); // Save nested_urls state, so we can restore it later $this->originalNestedURLsState = SiteTree::nested_urls(); $className = get_class($this); $fixtureFile = eval("return {$className}::\$fixture_file;"); $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; // Set up fixture if ($fixtureFile || $this->usesDatabase || !self::using_temp_db()) { if (substr(DB::getConn()->currentDatabase(), 0, strlen($prefix) + 5) != strtolower(sprintf('%stmpdb', $prefix))) { //echo "Re-creating temp database... "; self::create_temp_db(); //echo "done.\n"; } singleton('DataObject')->flushCache(); self::empty_temp_db(); foreach ($this->requireDefaultRecordsFrom as $className) { $instance = singleton($className); if (method_exists($instance, 'requireDefaultRecords')) { $instance->requireDefaultRecords(); } if (method_exists($instance, 'augmentDefaultRecords')) { $instance->augmentDefaultRecords(); } } if ($fixtureFile) { $fixtureFiles = is_array($fixtureFile) ? $fixtureFile : array($fixtureFile); $i = 0; foreach ($fixtureFiles as $fixtureFilePath) { $fixture = new YamlFixture($fixtureFilePath); $fixture->saveIntoDatabase(); $this->fixtures[] = $fixture; // backwards compatibility: Load first fixture into $this->fixture if ($i == 0) { $this->fixture = $fixture; } $i++; } } $this->logInWithPermission("ADMIN"); } // Set up email $this->originalMailer = Email::mailer(); $this->mailer = new TestMailer(); Email::set_mailer($this->mailer); Email::send_all_emails_to(null); // Preserve memory settings $this->originalMemoryLimit = ini_get('memory_limit'); }
/** * Extends the SiteTree::validURLSegment() method, to do checks appropriate * to Translatable * * @return bool */ public function augmentValidURLSegment() { if (self::locale_filter_enabled()) { self::disable_locale_filter(); $reEnableFilter = true; } $IDFilter = $this->owner->ID ? "AND \"SiteTree\".\"ID\" <> {$this->owner->ID}" : null; $parentFilter = null; if (SiteTree::nested_urls()) { if ($this->owner->ParentID) { $parentFilter = " AND \"SiteTree\".\"ParentID\" = {$this->owner->ParentID}"; } else { $parentFilter = ' AND "SiteTree"."ParentID" = 0'; } } $existingPage = DataObject::get_one('SiteTree', "\"URLSegment\" = '{$this->owner->URLSegment}' {$IDFilter} {$parentFilter}", false); if ($reEnableFilter) { self::enable_locale_filter(); } return !$existingPage; }
/** * 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. * * @return SS_HTTPResponse */ public function handleRequest(SS_HTTPRequest $request) { $child = null; $action = $request->param('Action'); // 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::nested_urls() && !$this->hasAction($action)) { // See ModelAdController->getNestedController() for similar logic Translatable::disable_locale_filter(); // look for a page with this URLSegment $child = DataObject::get_one('SiteTree', sprintf("\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action))); Translatable::enable_locale_filter(); // if we can't find a page with this URLSegment try to find one that used to have // that URLSegment but changed. See ModelAsController->getNestedController() for similiar logic. if (!$child) { $child = ModelAsController::find_old_page($action, $this->ID); if ($child) { $response = new SS_HTTPResponse(); $params = $request->getVars(); if (isset($params['url'])) { unset($params['url']); } $response->redirect(Controller::join_links($child->Link(Controller::join_links($request->param('ID'), $request->param('OtherID'))), $params ? '?' . http_build_query($params) : null), 301); return $response; } } } // we found a page with this URLSegment. if ($child) { $request->shiftAllParams(); $request->shift(); $response = ModelAsController::controller_for($child)->handleRequest($request); } 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 ($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()); $response = parent::handleRequest($request); Director::set_current_page(null); } return $response; }
/** * @param string $URLSegment A subset of the url. i.e in /home/contact/ home and contact are URLSegment. * @param int $parentID The ID of the parent of the page the URLSegment belongs to. * @return SiteTree */ static function find_old_page($URLSegment, $parentID = 0, $ignoreNestedURLs = false) { $URLSegment = Convert::raw2sql(rawurlencode($URLSegment)); $useParentIDFilter = SiteTree::nested_urls() && $parentID; // First look for a non-nested page that has a unique URLSegment and can be redirected to. if (SiteTree::nested_urls()) { $pages = DataObject::get('SiteTree', "\"URLSegment\" = '{$URLSegment}'" . ($useParentIDFilter ? ' AND "ParentID" = ' . (int) $parentID : '')); if ($pages && $pages->Count() == 1) { return $pages->First(); } } // Get an old version of a page that has been renamed. $query = new SQLQuery('"RecordID"', '"SiteTree_versions"', "\"URLSegment\" = '{$URLSegment}' AND \"WasPublished\" = 1" . ($useParentIDFilter ? ' AND "ParentID" = ' . (int) $parentID : ''), '"LastEdited" DESC', null, null, 1); $record = $query->execute()->first(); if ($record && ($oldPage = DataObject::get_by_id('SiteTree', $record['RecordID']))) { // Run the page through an extra filter to ensure that all extensions are applied. if (SiteTree::get_by_link($oldPage->RelativeLink())) { return $oldPage; } } }
public function setUp() { // We cannot run the tests on this abstract class. if (get_class($this) == "SapphireTest") { $this->skipTest = true; } if ($this->skipTest) { $this->markTestSkipped(sprintf('Skipping %s ', get_class($this))); return; } // Mark test as being run $this->originalIsRunningTest = self::$is_running_test; self::$is_running_test = true; // i18n needs to be set to the defaults or tests fail i18n::set_locale(i18n::default_locale()); i18n::set_date_format(null); i18n::set_time_format(null); // Set default timezone consistently to avoid NZ-specific dependencies date_default_timezone_set('UTC'); // Remove password validation $this->originalMemberPasswordValidator = Member::password_validator(); $this->originalRequirements = Requirements::backend(); Member::set_password_validator(null); Cookie::set_report_errors(false); if (class_exists('RootURLController')) { RootURLController::reset(); } if (class_exists('Translatable')) { Translatable::reset(); } Versioned::reset(); DataObject::reset(); if (class_exists('SiteTree')) { SiteTree::reset(); } Hierarchy::reset(); if (Controller::has_curr()) { Controller::curr()->setSession(new Session(array())); } Security::$database_is_ready = null; $this->originalTheme = SSViewer::current_theme(); if (class_exists('SiteTree')) { // Save nested_urls state, so we can restore it later $this->originalNestedURLsState = SiteTree::nested_urls(); } $className = get_class($this); $fixtureFile = eval("return {$className}::\$fixture_file;"); $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; // Todo: this could be a special test model $this->model = DataModel::inst(); // Set up fixture if ($fixtureFile || $this->usesDatabase || !self::using_temp_db()) { if (substr(DB::getConn()->currentDatabase(), 0, strlen($prefix) + 5) != strtolower(sprintf('%stmpdb', $prefix))) { //echo "Re-creating temp database... "; self::create_temp_db(); //echo "done.\n"; } singleton('DataObject')->flushCache(); self::empty_temp_db(); foreach ($this->requireDefaultRecordsFrom as $className) { $instance = singleton($className); if (method_exists($instance, 'requireDefaultRecords')) { $instance->requireDefaultRecords(); } if (method_exists($instance, 'augmentDefaultRecords')) { $instance->augmentDefaultRecords(); } } if ($fixtureFile) { $pathForClass = $this->getCurrentAbsolutePath(); $fixtureFiles = is_array($fixtureFile) ? $fixtureFile : array($fixtureFile); $i = 0; foreach ($fixtureFiles as $fixtureFilePath) { // Support fixture paths relative to the test class, rather than relative to webroot // String checking is faster than file_exists() calls. $isRelativeToFile = strpos('/', $fixtureFilePath) === false || preg_match('/^\\.\\./', $fixtureFilePath); if ($isRelativeToFile) { $resolvedPath = realpath($pathForClass . '/' . $fixtureFilePath); if ($resolvedPath) { $fixtureFilePath = $resolvedPath; } } $fixture = new YamlFixture($fixtureFilePath); $fixture->saveIntoDatabase($this->model); $this->fixtures[] = $fixture; // backwards compatibility: Load first fixture into $this->fixture if ($i == 0) { $this->fixture = $fixture; } $i++; } } $this->logInWithPermission("ADMIN"); } // Set up email $this->originalMailer = Email::mailer(); $this->mailer = new TestMailer(); Email::set_mailer($this->mailer); Email::send_all_emails_to(null); // Preserve memory settings $this->originalMemoryLimit = ini_get('memory_limit'); // turn off template debugging SSViewer::set_source_file_comments(false); // Clear requirements Requirements::clear(); }
/** * 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. */ function setUp() { parent::setUp(); $this->orig['nested_urls'] = SiteTree::nested_urls(); SiteTree::enable_nested_urls(); }
/** * This version takes into account that the old page must have the same locale as the new one * As aSQLQuery is used, that doesn't autmatically respond to the locale_filter, * the ModelAsController::find_old_page() function needed to be extended * * @param string $URLSegment A subset of the url. i.e in /home/contact/ home and contact are URLSegment. * @param int $parentID The ID of the parent of the page the URLSegment belongs to. * @return SiteTree * */ static function find_old_page_localized($URLSegment, $parentID = 0, $ignoreNestedURLs = false) { $URLSegment = Convert::raw2sql($URLSegment); $Locale = Translatable::get_current_locale(); $useParentIDFilter = SiteTree::nested_urls() && $parentID; // First look for a non-nested page that has a unique URLSegment and can be redirected to. if (SiteTree::nested_urls()) { $filter = array('URLSegment' => $URLSegment); if ($useParentIDFilter) { $filter['ParentID'] = (int) $parentID; } $pages = SiteTree::get()->filter($filter); if ($pages && $pages->Count() == 1) { return $pages->First(); } } // Get an old version of a page that has been renamed. Make it localized! $parentIDFilter = $useParentIDFilter ? ' AND "ParentID" = ' . (int) $parentID : ''; $query = new SQLQuery('"RecordID"', '"SiteTree_versions"', "\"URLSegment\" = '{$URLSegment}' AND \"Locale\" = '{$Locale}' AND \"WasPublished\" = 1" . $parentIDFilter, '"LastEdited" DESC', null, null, 1); $record = $query->execute()->first(); if ($record && ($oldPage = DataObject::get_by_id('SiteTree', $record['RecordID']))) { // Run the page through an extra filter to ensure that all decorators are applied. if (SiteTree::get_by_link($oldPage->RelativeLink())) { return $oldPage; } } }
/** * Overrides the default getNestedController() to maintain the language restrictions * @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 $sitetree = DataObject::get_one('SiteTree', sprintf('"URLSegment" = \'%s\' %s', Convert::raw2sql(rawurlencode($URLSegment)), SiteTree::nested_urls() ? 'AND "ParentID" = 0' : null)); if (!$sitetree) { $response = ErrorPage::response_for(404); $this->httpError(404, $response ? $response : 'The requested page could not be found.'); } // Enforce current language setting to the loaded SiteTree object if (class_exists('Translatable') && $sitetree->Locale) { if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) { Cookie::set('language', $sitetree->Locale); } else { Cookie::set('language', i18n::get_lang_from_locale($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')); }