function testAccessChecksDontChangeCurrentSubsite()
 {
     $admin = $this->objFromFixture("Member", "admin");
     $this->loginAs($admin);
     $ids = array();
     $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
     $subsite2 = $this->objFromFixture('Subsite', 'domaintest2');
     $subsite3 = $this->objFromFixture('Subsite', 'domaintest3');
     $ids[] = $subsite1->ID;
     $ids[] = $subsite2->ID;
     $ids[] = $subsite3->ID;
     $ids[] = 0;
     // Enable session-based subsite tracking.
     Subsite::$use_session_subsiteid = true;
     foreach ($ids as $id) {
         Subsite::changeSubsite($id);
         $this->assertEquals($id, Subsite::currentSubsiteID());
         $left = new LeftAndMain();
         $this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '{$id}'");
         $this->assertEquals($id, Subsite::currentSubsiteID(), "The current subsite has not been changed in the process of checking permissions for admin user.");
     }
 }
 /**
  * Redirect the user to something accessible if the current section/subsite is forbidden.
  *
  * This is done via onBeforeInit as it needs to be done before the LeftAndMain::init has a
  * chance to forbids access via alternateAccessCheck.
  *
  * If we need to change the subsite we force the redirection to /admin/ so the frontend is
  * fully re-synchronised with the internal session. This is better than risking some panels
  * showing data from another subsite.
  */
 public function onBeforeInit()
 {
     // We are accessing the CMS, so we need to let Subsites know we will be using the session.
     Subsite::$use_session_subsiteid = true;
     // FIRST, check if we need to change subsites due to the URL.
     // Catch forced subsite changes that need to cause CMS reloads.
     if (isset($_GET['SubsiteID'])) {
         // Clear current page when subsite changes (or is set for the first time)
         if (!Session::get('SubsiteID') || $_GET['SubsiteID'] != Session::get('SubsiteID')) {
             Session::clear("{$this->owner->class}.currentPage");
         }
         // Update current subsite in session
         Subsite::changeSubsite($_GET['SubsiteID']);
         //Redirect to clear the current page
         if ($this->owner->canView(Member::currentUser())) {
             //Redirect to clear the current page
             return $this->owner->redirect($this->owner->Link());
         }
         //Redirect to the default CMS section
         return $this->owner->redirect('admin/');
     }
     // Automatically redirect the session to appropriate subsite when requesting a record.
     // This is needed to properly initialise the session in situations where someone opens the CMS via a link.
     $record = $this->owner->currentPage();
     if ($record && isset($record->SubsiteID) && is_numeric($record->SubsiteID) && isset($this->owner->urlParams['ID'])) {
         if ($this->shouldChangeSubsite($this->owner->class, $record->SubsiteID, Subsite::currentSubsiteID())) {
             // Update current subsite in session
             Subsite::changeSubsite($record->SubsiteID);
             if ($this->owner->canView(Member::currentUser())) {
                 //Redirect to clear the current page
                 return $this->owner->redirect($this->owner->getRequest()->getURL());
             }
             //Redirect to the default CMS section
             return $this->owner->redirect('admin/');
         }
     }
     // SECOND, check if we need to change subsites due to lack of permissions.
     if (!$this->owner->canAccess()) {
         $member = Member::currentUser();
         // Current section is not accessible, try at least to stick to the same subsite.
         $menu = CMSMenu::get_menu_items();
         foreach ($menu as $candidate) {
             if ($candidate->controller && $candidate->controller != $this->owner->class) {
                 $accessibleSites = singleton($candidate->controller)->sectionSites($member);
                 if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
                     // Section is accessible, redirect there.
                     return $this->owner->redirect(singleton($candidate->controller)->Link());
                 }
             }
         }
         // If no section is available, look for other accessible subsites.
         foreach ($menu as $candidate) {
             if ($candidate->controller) {
                 $accessibleSites = singleton($candidate->controller)->sectionSites($member);
                 if ($accessibleSites->count()) {
                     Subsite::changeSubsite($accessibleSites->First()->ID);
                     return $this->owner->redirect(singleton($candidate->controller)->Link());
                 }
             }
         }
         // We have not found any accessible section or subsite. User should be denied access.
         return Security::permissionFailure($this->owner);
     }
     // Current site is accessible. Allow through.
     return;
 }
 function setUp()
 {
     parent::setUp();
     Subsite::$use_session_subsiteid = true;
 }