Example #1
0
 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');
 }
Example #3
0
 /**
  * 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;
         }
     }
 }
Example #6
0
 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'));
 }