/**
  * Create a new subsite from the template and verify that all the template's pages are copied
  */
 function testSubsiteCreation()
 {
     Subsite::$write_hostmap = false;
     // Create the instance
     $template = $this->objFromFixture('Subsite', 'main');
     // Test that changeSubsite is working
     Subsite::changeSubsite($template->ID);
     $tmplStaff = $this->objFromFixture('Page', 'staff');
     $tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
     // Publish all the pages in the template, testing that DataObject::get only returns pages from the chosen subsite
     $pages = DataObject::get("SiteTree");
     $totalPages = $pages->Count();
     foreach ($pages as $page) {
         $this->assertEquals($template->ID, $page->SubsiteID);
         $page->publish('Stage', 'Live');
     }
     // Create a new site
     $subsite = $template->duplicate();
     // Check title
     $this->assertEquals($subsite->Title, $template->Title);
     // Another test that changeSubsite is working
     $subsite->activate();
     $siteHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
     $this->assertNotEquals($siteHome, false, 'Home Page for subsite not found');
     $this->assertEquals($subsite->ID, $siteHome->SubsiteID, 'createInstance() copies existing pages retaining the same URLSegment');
     Subsite::changeSubsite(0);
 }
 /**
  * Create a new subsite from the template and verify that all the template's pages are copied
  */
 function testSubsiteCreation()
 {
     Subsite::$write_hostmap = false;
     // Create the instance
     $template = $this->objFromFixture('Subsite_Template', 'main');
     // Test that changeSubsite is working
     Subsite::changeSubsite($template->ID);
     $tmplHome = DataObject::get_one('SiteTree', "\"URLSegment\" = 'home'");
     // Publish all the pages in the template, testing that DataObject::get only returns pages from the chosen subsite
     $pages = DataObject::get("SiteTree");
     $totalPages = $pages->TotalItems();
     foreach ($pages as $page) {
         $this->assertEquals($template->ID, $page->SubsiteID);
         $page->publish('Stage', 'Live');
     }
     // Create a new site
     $subsite = $template->createInstance('My Site', 'something.test.com');
     // Check title
     $this->assertEquals($subsite->Title, 'My Site');
     // Check that domain generation is working
     $this->assertEquals('something.test.com', $subsite->domain());
     // Another test that changeSubsite is working
     $subsite->activate();
     $siteHome = DataObject::get_one('SiteTree', "\"URLSegment\" = 'home'");
     $this->assertNotNull($siteHome);
     $this->assertEquals($subsite->ID, $siteHome->SubsiteID, 'createInstance() copies existing pages retaining the same URLSegment');
     $this->assertEquals($siteHome->MasterPageID, $tmplHome->ID, 'Check master page value');
     // Check linking of child pages
     $tmplStaff = $this->objFromFixture('SiteTree', 'staff');
     $siteStaff = DataObject::get_one('SiteTree', "\"URLSegment\" = '" . Convert::raw2sql($tmplStaff->URLSegment) . "'");
     $this->assertEquals($siteStaff->MasterPageID, $tmplStaff->ID);
     Subsite::changeSubsite(0);
 }
 function testWritingSubsiteID()
 {
     $this->objFromFixture('Member', 'admin')->logIn();
     $subsite = $this->objFromFixture('Subsite', 'domaintest1');
     FileSubsites::$default_root_folders_global = true;
     Subsite::changeSubsite(0);
     $file = new File();
     $file->write();
     $file->onAfterUpload();
     $this->assertEquals((int) $file->SubsiteID, 0);
     Subsite::changeSubsite($subsite->ID);
     $this->assertTrue($file->canEdit());
     $file = new File();
     $file->write();
     $this->assertEquals((int) $file->SubsiteID, 0);
     $this->assertTrue($file->canEdit());
     FileSubsites::$default_root_folders_global = false;
     Subsite::changeSubsite($subsite->ID);
     $file = new File();
     $file->write();
     $this->assertEquals($file->SubsiteID, $subsite->ID);
     // Test inheriting from parent folder
     $folder = new Folder();
     $folder->write();
     $this->assertEquals($folder->SubsiteID, $subsite->ID);
     FileSubsites::$default_root_folders_global = true;
     $file = new File();
     $file->ParentID = $folder->ID;
     $file->onAfterUpload();
     $this->assertEquals($folder->SubsiteID, $file->SubsiteID);
 }
 function testEachSubsiteHasAUniqueSiteConfig()
 {
     $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
     $subsite2 = $this->objFromFixture('Subsite', 'domaintest2');
     $this->assertTrue(is_array(singleton('SiteConfigSubsites')->extraStatics()));
     Subsite::changeSubsite(0);
     $sc = SiteConfig::current_site_config();
     $sc->Title = 'RootSite';
     $sc->write();
     Subsite::changeSubsite($subsite1->ID);
     $sc = SiteConfig::current_site_config();
     $sc->Title = 'Subsite1';
     $sc->write();
     Subsite::changeSubsite($subsite2->ID);
     $sc = SiteConfig::current_site_config();
     $sc->Title = 'Subsite2';
     $sc->write();
     Subsite::changeSubsite(0);
     $this->assertEquals(SiteConfig::current_site_config()->Title, 'RootSite');
     Subsite::changeSubsite($subsite1->ID);
     $this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite1');
     Subsite::changeSubsite($subsite2->ID);
     $this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite2');
     $keys = SiteConfig::current_site_config()->extend('cacheKeyComponent');
     $this->assertContains('subsite-' . $subsite2->ID, $keys);
 }
 function activateState($state)
 {
     if (Controller::has_curr()) {
         Subsite::changeSubsite($state);
     } else {
         // TODO: This is a nasty hack - calling Subsite::changeSubsite after request ends
         // throws error because no current controller to access session on
         $_REQUEST['SubsiteID'] = $state;
     }
 }
 function run($request)
 {
     $subsiteFromId = $request->getVar('from');
     if (!is_numeric($subsiteFromId)) {
         throw new InvalidArgumentException('Missing "from" parameter');
     }
     $subsiteFrom = DataObject::get_by_id('Subsite', $subsiteFromId);
     if (!$subsiteFrom) {
         throw new InvalidArgumentException('Subsite not found');
     }
     $subsiteToId = $request->getVar('to');
     if (!is_numeric($subsiteToId)) {
         throw new InvalidArgumentException('Missing "to" parameter');
     }
     $subsiteTo = DataObject::get_by_id('Subsite', $subsiteToId);
     if (!$subsiteTo) {
         throw new InvalidArgumentException('Subsite not found');
     }
     $useVirtualPages = (bool) $request->getVar('virtual');
     Subsite::changeSubsite($subsiteFrom);
     // Copy data from this template to the given subsite. Does this using an iterative depth-first search.
     // This will make sure that the new parents on the new subsite are correct, and there are no funny
     // issues with having to check whether or not the new parents have been added to the site tree
     // when a page, etc, is duplicated
     $stack = array(array(0, 0));
     while (count($stack) > 0) {
         list($sourceParentID, $destParentID) = array_pop($stack);
         $children = Versioned::get_by_stage('SiteTree', 'Live', "\"ParentID\" = {$sourceParentID}", '');
         if ($children) {
             foreach ($children as $child) {
                 if ($useVirtualPages) {
                     $childClone = new SubsitesVirtualPage();
                     $childClone->writeToStage('Stage');
                     $childClone->CopyContentFromID = $child->ID;
                     $childClone->SubsiteID = $subsiteTo->ID;
                 } else {
                     $childClone = $child->duplicateToSubsite($subsiteTo->ID, true);
                 }
                 $childClone->ParentID = $destParentID;
                 $childClone->writeToStage('Stage');
                 $childClone->publish('Stage', 'Live');
                 array_push($stack, array($child->ID, $childClone->ID));
                 $this->log(sprintf('Copied "%s" (#%d, %s)', $child->Title, $child->ID, $child->Link()));
             }
         }
         unset($children);
     }
 }
Пример #7
0
 public function loadFixtures()
 {
     if (ClassInfo::exists('Subsite')) {
         $currentSubsite = Subsite::currentSubsiteID();
     }
     foreach (self::$preload_fixtures as $desc) {
         $fixtureFile = $desc['file'];
         if (file_exists(Director::baseFolder() . '/' . $fixtureFile)) {
             $siteID = null;
             if (isset($desc['subsite'])) {
                 $site = DataObject::get_one('Subsite', '"Title" = \'' . Convert::raw2sql($desc['subsite']) . '\'');
                 if ($site && $site->ID) {
                     $siteID = $site->ID;
                 }
                 if (!$siteID) {
                     // no site, so just skip this file load
                     continue;
                 }
             }
             // need to disable the filter when running dev/build so that it actually searches
             // within the relevant subsite, not the 'current' one.
             if (ClassInfo::exists('Subsite')) {
                 Subsite::$disable_subsite_filter = true;
             }
             $filter = $desc['filter'] . ($siteID ? ' AND "SubsiteID"=' . $siteID : '');
             $existing = DataObject::get_one($desc['type'], $filter);
             if (ClassInfo::exists('Subsite')) {
                 Subsite::$disable_subsite_filter = false;
             }
             if (!$existing) {
                 if ($siteID) {
                     Subsite::changeSubsite($siteID);
                 }
                 $fixture = new YamlFixture($fixtureFile);
                 $fixture->saveIntoDatabase();
                 DB::alteration_message('YAML bootstrap loaded from ' . $fixtureFile, 'created');
             }
         }
     }
     if (ClassInfo::exists('Subsite')) {
         Subsite::changeSubsite($currentSubsite);
     }
 }
 function testAlternateAccessCheck()
 {
     $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;
     foreach ($ids as $id) {
         Subsite::changeSubsite($id);
         //switch to main site (subsite ID zero)
         $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.");
     }
 }
 public function test_calc_directory_for_subsite()
 {
     //Template:
     $subsite = $this->objFromFixture('Subsite', 'main');
     //check calculation
     $this->assertEquals('template', SubsiteUploadDirRules::calc_directory_for_subsite($subsite));
     //check the generated folder
     Subsite::changeSubsite($subsite->ID);
     $this->assertEquals('template', SubsiteUploadDirRules::get_directory_for_current_subsite());
     //Subsite1 Template:
     $subsite = $this->objFromFixture('Subsite', 'subsite1');
     //check calculation
     $this->assertEquals('subsite1-template', SubsiteUploadDirRules::calc_directory_for_subsite($subsite));
     //check the generated folder
     Subsite::changeSubsite($subsite->ID);
     $this->assertEquals('subsite1-template', SubsiteUploadDirRules::get_directory_for_current_subsite());
     //Test 3:
     $subsite = $this->objFromFixture('Subsite', 'domaintest3');
     //check calculation
     $this->assertEquals('test-3', SubsiteUploadDirRules::calc_directory_for_subsite($subsite));
     //check the generated folder
     Subsite::changeSubsite($subsite->ID);
     $this->assertEquals('test-3', SubsiteUploadDirRules::get_directory_for_current_subsite());
     Subsite::changeSubsite(0);
     //		if (class_exists('Subsite') && Object::has_extension('Subsite', 'AssetsFolderExtension')) {
     //
     //			$subsite = Subsite::get()->first();
     //
     //
     //			//Setting subsite via $_GET
     //			//this is not bes practice, but this seems to be the only way that works
     //			//when running this over the command line
     //
     //			//Subsite::changeSubsite($subsite->ID);
     //			$_GET['SubsiteID'] = $subsite->ID;
     //
     //			$this->assertEquals('my-test-subsite', SubsiteUploadDirRules::calc_directory_for_subsite());
     //		}
 }
 function testAdminIsRedirectedToObjectsSubsite()
 {
     $member = $this->objFromFixture('Member', 'admin');
     Session::set("loggedInAs", $member->ID);
     $mainSubsitePage = $this->objFromFixture('Page', 'mainSubsitePage');
     $subsite1Home = $this->objFromFixture('Page', 'subsite1_home');
     Config::inst()->nest();
     Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', false);
     Subsite::changeSubsite(0);
     $this->getAndFollowAll("admin/pages/edit/show/{$subsite1Home->ID}");
     $this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading an object switches the subsite');
     $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
     Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', true);
     Subsite::changeSubsite(0);
     $this->getAndFollowAll("admin/pages/edit/show/{$subsite1Home->ID}");
     $this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global');
     $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
     $this->getAndFollowAll("admin/pages/edit/show/{$mainSubsitePage->ID}");
     $this->assertNotEquals(Subsite::currentSubsiteID(), $mainSubsitePage->SubsiteID, 'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global');
     $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
     Config::inst()->unnest();
 }
 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.");
     }
 }
 /**
  * Create a duplicate of this page and save it to another subsite
  * @param $subsiteID int|Subsite The Subsite to copy to, or its ID
  */
 public function duplicateToSubsite($subsiteID = null)
 {
     if (is_object($subsiteID)) {
         $subsite = $subsiteID;
         $subsiteID = $subsite->ID;
     } else {
         $subsite = DataObject::get_by_id('Subsite', $subsiteID);
     }
     $oldSubsite = Subsite::currentSubsiteID();
     if ($subsiteID) {
         Subsite::changeSubsite($subsiteID);
     } else {
         $subsiteID = $oldSubsite;
     }
     $page = $this->owner->duplicate(false);
     $page->CheckedPublicationDifferences = $page->AddedToStage = true;
     $subsiteID = $subsiteID ? $subsiteID : $oldSubsite;
     $page->SubsiteID = $subsiteID;
     // MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module
     $page->MasterPageID = $this->owner->ID;
     $page->write();
     Subsite::changeSubsite($oldSubsite);
     return $page;
 }
 function testPageTypesBlacklistInCMSMain()
 {
     $editor = $this->objFromFixture('Member', 'editor');
     Session::set("loggedInAs", $editor->ID);
     $cmsmain = new CMSMain();
     $s1 = $this->objFromFixture('Subsite', 'domaintest1');
     $s2 = $this->objFromFixture('Subsite', 'domaintest2');
     $s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
     $s1->write();
     Subsite::changeSubsite($s1);
     $hints = Convert::json2array($cmsmain->SiteTreeHints());
     $classes = $hints['Root']['disallowedChildren'];
     $this->assertContains('ErrorPage', $classes);
     $this->assertContains('SiteTreeSubsitesTest_ClassA', $classes);
     $this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
     Subsite::changeSubsite($s2);
     $hints = Convert::json2array($cmsmain->SiteTreeHints());
     $classes = $hints['Root']['disallowedChildren'];
     $this->assertNotContains('ErrorPage', $classes);
     $this->assertNotContains('SiteTreeSubsitesTest_ClassA', $classes);
     $this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
 }
 /**
  * Alternative security checker for LeftAndMain.
  * If security isn't found, then it will switch to a subsite where we do have access.
  */
 public function alternateAccessCheck()
 {
     $className = $this->owner->class;
     // Switch to the subsite of the current page
     if ($this->owner->class == 'CMSMain' && ($currentPage = $this->owner->currentPage())) {
         if (Subsite::currentSubsiteID() != $currentPage->SubsiteID) {
             Subsite::changeSubsite($currentPage->SubsiteID);
         }
     }
     // Switch to a subsite that this user can actually access.
     $member = Member::currentUser();
     if ($member && $member->isAdmin()) {
         return true;
     }
     //admin can access all subsites
     $sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}")->toDropdownMap();
     if ($sites && !isset($sites[Subsite::currentSubsiteID()])) {
         $siteIDs = array_keys($sites);
         Subsite::changeSubsite($siteIDs[0]);
         return true;
     }
     // Switch to a different top-level menu item
     $menu = CMSMenu::get_menu_items();
     foreach ($menu as $candidate) {
         if ($candidate->controller != $this->owner->class) {
             $sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}")->toDropdownMap();
             if ($sites && !isset($sites[Subsite::currentSubsiteID()])) {
                 $siteIDs = array_keys($sites);
                 Subsite::changeSubsite($siteIDs[0]);
                 $cClass = $candidate->controller;
                 $cObj = new $cClass();
                 Director::redirect($cObj->Link());
                 return null;
             }
         }
     }
     // If all of those fail, you really don't have access to the CMS
     return null;
 }
 /**
  * Similar to {@link SiteTreeSubsitesTest->testTwoPagesWithSameURLOnDifferentSubsites()}
  * and {@link SiteTreeSubsitesTest->testPagesInDifferentSubsitesCanShareURLSegment()}.
  */
 function testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()
 {
     Subsite::$write_hostmap = false;
     $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
     $subsite2 = $this->objFromFixture('Subsite', 'subsite2');
     Subsite::changeSubsite($subsite1->ID);
     $subsite1Page = $this->objFromFixture('Page', 'subsite1_staff');
     $subsite1Page->URLSegment = 'staff';
     $subsite1Page->write();
     // saving on subsite1, and linking to subsite1
     $subsite1Vp = new SubsitesVirtualPage();
     $subsite1Vp->CopyContentFromID = $subsite1Page->ID;
     $subsite1Vp->SubsiteID = $subsite1->ID;
     $subsite1Vp->write();
     $this->assertNotEquals($subsite1Vp->URLSegment, $subsite1Page->URLSegment, "Doesn't allow explicit URLSegment overrides when already existing in same subsite");
     //Change to subsite 2
     Subsite::changeSubsite($subsite2->ID);
     // saving in subsite2 (which already has a page with URLSegment 'contact-us'),
     // but linking to a page in subsite1
     $subsite2Vp = new SubsitesVirtualPage();
     $subsite2Vp->CopyContentFromID = $subsite1Page->ID;
     $subsite2Vp->SubsiteID = $subsite2->ID;
     $subsite2Vp->write();
     $this->assertEquals($subsite2Vp->URLSegment, $subsite1Page->URLSegment, "Does allow explicit URLSegment overrides when only existing in a different subsite");
 }
Пример #16
0
 /**
  * Return an existing member with administrator privileges, or create one of necessary.
  *
  * Will create a default 'Administrators' group if no group is found
  * with an ADMIN permission. Will create a new 'Admin' member with administrative permissions
  * if no existing Member with these permissions is found.
  *
  * Important: Any newly created administrator accounts will NOT have valid
  * login credentials (Email/Password properties), which means they can't be used for login
  * purposes outside of any default credentials set through {@link Security::setDefaultAdmin()}.
  *
  * @return Member
  */
 public static function findAnAdministrator()
 {
     // coupling to subsites module
     $origSubsite = null;
     if (is_callable('Subsite::changeSubsite')) {
         $origSubsite = Subsite::currentSubsiteID();
         Subsite::changeSubsite(0);
     }
     $member = null;
     // find a group with ADMIN permission
     $adminGroup = Permission::get_groups_by_permission('ADMIN')->First();
     if (is_callable('Subsite::changeSubsite')) {
         Subsite::changeSubsite($origSubsite);
     }
     if ($adminGroup) {
         $member = $adminGroup->Members()->First();
     }
     if (!$adminGroup) {
         singleton('Group')->requireDefaultRecords();
         $adminGroup = Permission::get_groups_by_permission('ADMIN')->First();
     }
     if (!$member) {
         singleton('Member')->requireDefaultRecords();
         $member = Permission::get_members_by_permission('ADMIN')->First();
     }
     if (!$member) {
         $member = Member::default_admin();
     }
     if (!$member) {
         // Failover to a blank admin
         $member = Member::create();
         $member->FirstName = _t('Member.DefaultAdminFirstname', 'Default Admin');
         $member->write();
         // Add member to group instead of adding group to member
         // This bypasses the privilege escallation code in Member_GroupSet
         $adminGroup->DirectMembers()->add($member);
     }
     return $member;
 }
Пример #17
0
 /**
  * Return an existing member with administrator privileges, or create one of necessary.
  * 
  * Will create a default 'Administrators' group if no group is found
  * with an ADMIN permission. Will create a new 'Admin' member with administrative permissions
  * if no existing Member with these permissions is found. 
  * 
  * Important: Any newly created administrator accounts will NOT have valid
  * login credentials (Email/Password properties), which means they can't be used for login
  * purposes outside of any default credentials set through {@link Security::setDefaultAdmin()}.
  * 
  * @return Member 
  */
 static function findAnAdministrator()
 {
     // coupling to subsites module
     $origSubsite = null;
     if (is_callable('Subsite::changeSubsite')) {
         $origSubsite = Subsite::currentSubsiteID();
         Subsite::changeSubsite(0);
     }
     $member = null;
     // find a group with ADMIN permission
     $adminGroup = DataObject::get('Group', "\"Permission\".\"Code\" = 'ADMIN'", "\"Group\".\"ID\"", "JOIN \"Permission\" ON \"Group\".\"ID\"=\"Permission\".\"GroupID\"", '1')->First();
     if (is_callable('Subsite::changeSubsite')) {
         Subsite::changeSubsite($origSubsite);
     }
     if ($adminGroup) {
         $member = $adminGroup->Members()->First();
     }
     if (!$adminGroup) {
         singleton('Group')->requireDefaultRecords();
     }
     if (!$member) {
         singleton('Member')->requireDefaultRecords();
         $member = Permission::get_members_by_permission('ADMIN')->First();
     }
     return $member;
 }
 /**
  * Make this subsite the current one
  */
 public function activate()
 {
     Subsite::changeSubsite($this);
 }
 function testUnpublishingParentPageUnpublishesSubsiteVirtualPages()
 {
     StaticPublisher::$disable_realtime = true;
     // Go to main site, get parent page
     $subsite = $this->objFromFixture('Subsite_Template', 'main');
     Subsite::changeSubsite($subsite->ID);
     $page = $this->objFromFixture('SiteTree', 'importantpage');
     // Create two SVPs on other subsites
     $subsite = $this->objFromFixture('Subsite_Template', 'subsite1');
     Subsite::changeSubsite($subsite->ID);
     $vp1 = new SubsitesVirtualPage();
     $vp1->CopyContentFromID = $page->ID;
     $vp1->write();
     $vp1->doPublish();
     $subsite = $this->objFromFixture('Subsite_Template', 'subsite2');
     Subsite::changeSubsite($subsite->ID);
     $vp2 = new SubsitesVirtualPage();
     $vp2->CopyContentFromID = $page->ID;
     $vp2->write();
     $vp2->doPublish();
     // Switch back to main site, unpublish source
     $subsite = $this->objFromFixture('Subsite_Template', 'main');
     Subsite::changeSubsite($subsite->ID);
     $page = $this->objFromFixture('SiteTree', 'importantpage');
     $page->doUnpublish();
     Subsite::changeSubsite($vp1->SubsiteID);
     $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = " . $vp1->ID);
     $this->assertFalse($onLive, 'SVP has been removed from live');
     $subsite = $this->objFromFixture('Subsite_Template', 'subsite2');
     Subsite::changeSubsite($vp2->SubsiteID);
     $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = " . $vp2->ID);
     $this->assertFalse($onLive, 'SVP has been removed from live');
 }
 /**
  * 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;
 }
Пример #21
0
 /**
  * Return an existing member with administrator privileges, or create one of necessary.
  *
  * Will create a default 'Administrators' group if no group is found
  * with an ADMIN permission. Will create a new 'Admin' member with administrative permissions
  * if no existing Member with these permissions is found.
  *
  * Important: Any newly created administrator accounts will NOT have valid
  * login credentials (Email/Password properties), which means they can't be used for login
  * purposes outside of any default credentials set through {@link Security::setDefaultAdmin()}.
  *
  * @return Member
  */
 public static function findAnAdministrator()
 {
     // coupling to subsites module
     $origSubsite = null;
     if (is_callable('Subsite::changeSubsite')) {
         $origSubsite = Subsite::currentSubsiteID();
         Subsite::changeSubsite(0);
     }
     $member = null;
     // find a group with ADMIN permission
     $adminGroup = DataObject::get('Group')->where(array('"Permission"."Code"' => 'ADMIN'))->sort('"Group"."ID"')->innerJoin("Permission", '"Group"."ID" = "Permission"."GroupID"')->First();
     if (is_callable('Subsite::changeSubsite')) {
         Subsite::changeSubsite($origSubsite);
     }
     if ($adminGroup) {
         $member = $adminGroup->Members()->First();
     }
     if (!$adminGroup) {
         singleton('Group')->requireDefaultRecords();
     }
     if (!$member) {
         singleton('Member')->requireDefaultRecords();
         $member = Permission::get_members_by_permission('ADMIN')->First();
     }
     return $member;
 }
Пример #22
0
 /**
  * This function ensures the file table is correct with the files in the assets folder.
  * 
  * If a Folder record ID is given, all of that folder's children will be synchronised.
  * If the given Folder ID isn't found, or not specified at all, then everything will
  * be synchronised from the root folder (singleton Folder).
  * 
  * See {@link File->updateFilesystem()} to sync properties of a single database record 
  * back to the equivalent filesystem record.
  * 
  * @param int $folderID Folder ID to sync along with all it's children
  * @param Boolean $syncLinkTracking Determines if the link tracking data should also 
  *        be updated via {@link SiteTree->syncLinkTracking()}. Setting this to FALSE
  *        means that broken links inside page content are not noticed, at least until the next
  *        call to {@link SiteTree->write()} on this page.
  * @return string Localized status message
  */
 public static function sync($folderID = null, $syncLinkTracking = true)
 {
     $folder = DataObject::get_by_id('Folder', (int) $folderID);
     if (!($folder && $folder->exists())) {
         $folder = singleton('Folder');
     }
     $results = $folder->syncChildren();
     $finished = false;
     while (!$finished) {
         $orphans = DB::query("SELECT \"C\".\"ID\" FROM \"File\" AS \"C\" \n\t\t\t\tLEFT JOIN \"File\" AS \"P\" ON \"C\".\"ParentID\" = \"P\".\"ID\" \n\t\t\t\tWHERE \"P\".\"ID\" IS NULL AND \"C\".\"ParentID\" > 0");
         $finished = true;
         if ($orphans) {
             foreach ($orphans as $orphan) {
                 $finished = false;
                 // Delete the database record but leave the filesystem alone
                 $file = DataObject::get_by_id("File", $orphan['ID']);
                 $file->deleteDatabaseOnly();
                 unset($file);
             }
         }
     }
     // Update the image tracking of all pages
     if ($syncLinkTracking) {
         if (class_exists('SiteTree')) {
             // if subsites exist, go through each subsite and sync each subsite's pages.
             // disabling the filter doesn't work reliably, because writing pages that share
             // the same URLSegment between subsites will break, e.g. "home" between two
             // sites will modify one of them to "home-2", thinking it's a duplicate. The
             // check before a write is done in SiteTree::validURLSegment()
             if (class_exists('Subsite')) {
                 // loop through each subsite ID, changing the subsite, then query it's pages
                 foreach (Subsite::get()->getIDList() as $id) {
                     Subsite::changeSubsite($id);
                     foreach (SiteTree::get() as $page) {
                         // syncLinkTracking is called by SiteTree::onBeforeWrite().
                         // Call it without affecting the page version, as this is an internal change.
                         $page->writeWithoutVersion();
                     }
                 }
                 // change back to the main site so the foreach below works
                 Subsite::changeSubsite(0);
             }
             foreach (SiteTree::get() as $page) {
                 // syncLinkTracking is called by SiteTree::onBeforeWrite().
                 // Call it without affecting the page version, as this is an internal change.
                 $page->writeWithoutVersion();
             }
         }
     }
     return _t('Filesystem.SYNCRESULTS', 'Sync complete: {createdcount} items created, {deletedcount} items deleted', array('createdcount' => (int) $results['added'], 'deletedcount' => (int) $results['deleted']));
 }
 /**
  * Process all jobs from a given queue
  *
  * @param string $name The job queue to completely process
  */
 public function processJobQueue($name)
 {
     // Start timer to measure lifetime
     $this->markStarted();
     // Begin main loop
     do {
         if (class_exists('Subsite')) {
             // clear subsite back to default to prevent any subsite changes from leaking to
             // subsequent actions
             Subsite::changeSubsite(0);
         }
         if (Controller::has_curr()) {
             Session::clear('loggedInAs');
         } else {
             unset($_SESSION['loggedInAs']);
         }
         if (class_exists('SecurityContext')) {
             singleton('SecurityContext')->setMember(null);
         }
         $job = $this->getNextPendingJob($name);
         if ($job) {
             $success = $this->runJob($job->ID);
             if (!$success) {
                 // make sure job is null so it doesn't continue the current
                 // processing loop. Next queue executor can pick up where
                 // things left off
                 $job = null;
             }
         }
     } while ($job);
 }
 function testTwoPagesWithSameURLOnDifferentSubsites()
 {
     // Set up a couple of pages with the same URL on different subsites
     $s1 = $this->objFromFixture('Subsite', 'domaintest1');
     $s2 = $this->objFromFixture('Subsite', 'domaintest2');
     $p1 = new SiteTree();
     $p1->Title = $p1->URLSegment = "test-page";
     $p1->SubsiteID = $s1->ID;
     $p1->write();
     $p2 = new SiteTree();
     $p2->Title = $p1->URLSegment = "test-page";
     $p2->SubsiteID = $s2->ID;
     $p2->write();
     // Check that the URLs weren't modified in our set-up
     $this->assertEquals($p1->URLSegment, 'test-page');
     $this->assertEquals($p2->URLSegment, 'test-page');
     // Check that if we switch between the different subsites, we receive the correct pages
     Subsite::changeSubsite($s1);
     $this->assertEquals($p1->ID, SiteTree::get_by_link('test-page')->ID);
     Subsite::changeSubsite($s2);
     $this->assertEquals($p2->ID, SiteTree::get_by_link('test-page')->ID);
 }