/**
  * Test that virtual pages get the content from the master page when they are created.
  */
 function testNewVirtualPagesGrabTheContentFromTheirMaster()
 {
     $vp = new VirtualPage();
     $vp->write();
     $vp->CopyContentFromID = $this->idFromFixture('Page', 'master');
     $vp->write();
     $this->assertEquals("My Page", $vp->Title);
     $this->assertEquals("My Page Nav", $vp->MenuTitle);
     $vp->CopyContentFromID = $this->idFromFixture('Page', 'master2');
     $vp->write();
     $this->assertEquals("My Other Page", $vp->Title);
     $this->assertEquals("My Other Page Nav", $vp->MenuTitle);
 }
 public function testFileLinkRewritingOnVirtualPages()
 {
     // Publish the source page
     $page = $this->objFromFixture('Page', 'page1');
     $this->assertTrue($page->doPublish());
     // Create a virtual page from it, and publish that
     $svp = new VirtualPage();
     $svp->CopyContentFromID = $page->ID;
     $svp->write();
     $svp->doPublish();
     // Rename the file
     $file = $this->objFromFixture('Image', 'file1');
     $file->Name = 'renamed-test-file.jpg';
     $file->write();
     // Verify that the draft and publish virtual pages both have the corrected link
     $this->assertContains('<img src="/assets/FileLinkTrackingTest/55b443b601/renamed-test-file.jpg"', DB::prepared_query("SELECT \"Content\" FROM \"SiteTree\" WHERE \"ID\" = ?", array($svp->ID))->value());
     $this->assertContains('<img src="/assets/FileLinkTrackingTest/55b443b601/renamed-test-file.jpg"', DB::prepared_query("SELECT \"Content\" FROM \"SiteTree_Live\" WHERE \"ID\" = ?", array($svp->ID))->value());
 }
	public function testWithOneOrphanedRow() {
		DataObjectOnDeleteDecorator::set_disabled(true);
		//JanitorDebug::set_verbose(true);
		$page = new VirtualPage();
		$page->Title = 'Page1';
		$page->write();
		$pageID = $page->ID;
		
		$page = $page->newClassInstance('RedirectorPage');
		$page->write();
		$page = DataObject::get_by_id('RedirectorPage', $pageID);
		$this->assertInstanceOf('RedirectorPage', $page);
		
		$page->delete();
		
		DataObjectOnDeleteDecorator::set_disabled(false);
		$task = new DataObjectRetroactiveCleanerTask();
		$task->run(null);
		$task->deleteBackup();
		
		$this->assertFalse((bool)DB::query("SELECT \"ID\" FROM \"VirtualPage\" WHERE \"ID\" = {$pageID}")->value(),
			"VirtualPage not cleaned properly (retroactively)");
		JanitorDebug::set_verbose(false);
	}
 public function testVirtualPageAsAnAllowedChild()
 {
     $parentPage = new VirtualPageTest_PageWithAllowedChildren();
     $parentPage->write();
     $childPage = new VirtualPageTest_ClassA();
     $childPage->ParentID = $parentPage->ID;
     $childPage->write();
     // Check we're allowed to create a VirtualPage without linking it to a page yet
     $childVirtualPage = new VirtualPage();
     $childVirtualPage->ParentID = $parentPage->ID;
     try {
         $childVirtualPage->write();
     } catch (ValidationException $e) {
         $this->fail('Failed to write VirtualPage when it is an allowed child');
     }
     // Check that we can link a VirtualPage to a page type that's an allowed child
     $childVirtualPage->CopyContentFromID = $childPage->ID;
     try {
         $childVirtualPage->write();
     } catch (ValidationException $e) {
         $this->fail('Failed to write VirtualPage when it is linked to an allowed child');
     }
     // Check that we CAN'T link a VirtualPage to a page that is NOT an allowed child
     $disallowedChild = new VirtualPageTest_ClassB();
     $disallowedChild->write();
     $childVirtualPage->CopyContentFromID = $disallowedChild->ID;
     $isDetected = false;
     try {
         $childVirtualPage->write();
     } catch (ValidationException $e) {
         $this->assertContains('not allowed as child of this parent page', $e->getMessage());
         $isDetected = true;
     }
     if (!$isDetected) {
         $this->fail("Shouldn't be allowed to write a VirtualPage that links to a disallowed child");
     }
 }
 function testPagesScheduledForDeletionReportIncludesVirtualPages()
 {
     $report = new PagesScheduledForDeletionReport();
     $this->logInAs($this->objFromFixture('Member', 'admin'));
     $page1 = $this->objFromFixture('SiteTree', 'pagedel1');
     $page1->doPublish();
     $page2 = $this->objFromFixture('SiteTree', 'pagedel2');
     $page2->doPublish();
     $page3 = $this->objFromFixture('SiteTree', 'pagedel3');
     $page3->doPublish();
     $virtualPage = new VirtualPage();
     $virtualPage->URLSegment = 'virtual';
     $virtualPage->CopyContentFromID = $page3->ID;
     $virtualPage->write();
     SS_Datetime::set_mock_now('2010-02-14 00:00:00');
     $results = $report->sourceRecords(array(), '"ID" DESC', false);
     // Can't test with titles as they'll be the same for virtual pages
     $this->assertEquals($results->column('ID'), array($page3->ID, $virtualPage->ID, $page2->ID));
     $this->assertEquals($results->column('ExpiryDate'), array($page3->ExpiryDate, $page3->ExpiryDate, $page2->ExpiryDate));
     SS_Datetime::clear_mock_now();
 }
 function testCanBeRoot()
 {
     $page = new SiteTree();
     $page->ParentID = 0;
     $page->write();
     $notRootPage = new VirtualPageTest_NotRoot();
     // we don't want the original on root, but rather the VirtualPage pointing to it
     $notRootPage->ParentID = $page->ID;
     $notRootPage->write();
     $virtual = new VirtualPage();
     $virtual->CopyContentFromID = $page->ID;
     $virtual->write();
     $virtual = DataObject::get_by_id('VirtualPage', $virtual->ID, false);
     $virtual->CopyContentFromID = $notRootPage->ID;
     $isDetected = false;
     try {
         $virtual->write();
     } catch (ValidationException $e) {
         $this->assertContains('is not allowed on the root level', $e->getMessage());
         $isDetected = true;
     }
     if (!$isDetected) {
         $this->fail('Fails validation with $can_be_root=false');
     }
 }
 public function testRevertToLiveFixesBrokenLinks()
 {
     // Create page and virutal page
     $p = new Page();
     $p->Title = "source";
     $p->write();
     $pageID = $p->ID;
     $this->assertTrue($p->doPublish());
     // Content links are one kind of link to pages
     $p2 = new Page();
     $p2->Title = "regular link";
     $p2->Content = "<a href=\"[sitetree_link,id={$p->ID}]\">test</a>";
     $p2->write();
     $this->assertTrue($p2->doPublish());
     // Virtual pages are another
     $vp = new VirtualPage();
     $vp->CopyContentFromID = $p->ID;
     $vp->write();
     // Redirector links are a third
     $rp = new RedirectorPage();
     $rp->Title = "redirector";
     $rp->LinkType = 'Internal';
     $rp->LinkToID = $p->ID;
     $rp->write();
     $this->assertTrue($rp->doPublish());
     // Confirm that there are no broken links to begin with
     $this->assertFalse($p2->HasBrokenLink);
     $this->assertFalse($vp->HasBrokenLink);
     $this->assertFalse($rp->HasBrokenLink);
     // Delete from draft and confirm that broken links are marked
     $pID = $p->ID;
     $p->delete();
     $vp->flushCache();
     $vp = DataObject::get_by_id('SiteTree', $vp->ID);
     $p2->flushCache();
     $p2 = DataObject::get_by_id('SiteTree', $p2->ID);
     $rp->flushCache();
     $rp = DataObject::get_by_id('SiteTree', $rp->ID);
     $this->assertEquals(1, $p2->HasBrokenLink);
     $this->assertEquals(1, $vp->HasBrokenLink);
     $this->assertEquals(1, $rp->HasBrokenLink);
     // Call doRevertToLive and confirm that broken links are restored
     $pLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $pID);
     $pLive->doRevertToLive();
     $p2->flushCache();
     $p2 = DataObject::get_by_id('SiteTree', $p2->ID);
     $vp->flushCache();
     $vp = DataObject::get_by_id('SiteTree', $vp->ID);
     $rp->flushCache();
     $rp = DataObject::get_by_id('SiteTree', $rp->ID);
     $this->assertFalse((bool) $p2->HasBrokenLink);
     $this->assertFalse((bool) $vp->HasBrokenLink);
     $this->assertFalse((bool) $rp->HasBrokenLink);
 }
	public function testNormalSiteTreeDeleteWithDirtyRelatedTables() {
		DataObjectOnDeleteDecorator::set_clean_versions_table(true);
		$page = new VirtualPage();
		$page->Title = 'Page';
		$page->write();
		$pageID = $page->ID;
		
		$page = $page->newClassInstance('RedirectorPage');
		$page->write();
		$page = DataObject::get_by_id('RedirectorPage', $pageID);
		$this->assertInstanceOf('RedirectorPage', $page);
		
		$this->assertTrue((bool)DB::query("SELECT \"ID\" FROM \"VirtualPage\" WHERE \"ID\" = {$pageID}")->value(),
			"VirtualPage row not found");
		$this->assertTrue((bool)DB::query("SELECT \"ID\" FROM \"RedirectorPage\" WHERE \"ID\" = {$pageID}")->value(),
			"RedirectorPage row not found");
		
		$page->delete();
		
		$this->assertVersionedTables('VirtualPage', $pageID, false);
		$this->assertVersionedTables('RedirectorPage', $pageID, false);
		
		DataObjectOnDeleteDecorator::set_clean_versions_table(false);
	}
 function testDeletingFromLiveSourcePageOfAVirtualPageAlsoUnpublishesVirtualPage()
 {
     // Create page and virutal page
     $p = new Page();
     $p->Title = "source";
     $p->write();
     $this->assertTrue($p->doPublish());
     $vp = new VirtualPage();
     $vp->CopyContentFromID = $p->ID;
     $vp->write();
     $this->assertTrue($vp->doPublish());
     // All is fine, the virtual page doesn't have a broken link
     $this->assertFalse($vp->HasBrokenLink);
     // Delete the source page from draft, confirm that this creates a broken link
     $pID = $p->ID;
     $p->delete();
     $vp->flushCache();
     $vp = DataObject::get_by_id('SiteTree', $vp->ID);
     $this->assertEquals(1, $vp->HasBrokenLink);
     // Delete the source page form live, confirm that the virtual page has also been unpublished
     $pLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $pID);
     $this->assertTrue($pLive->doDeleteFromLive());
     $vpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $vp->ID);
     $this->assertFalse($vpLive);
     // Delete from draft, confirm that the virtual page has a broken link on the draft site
     $pLive->delete();
     $vp->flushCache();
     $vp = DataObject::get_by_id('SiteTree', $vp->ID);
     $this->assertEquals(1, $vp->HasBrokenLink);
 }
 public function testVirtualPageFindsCorrectCasting()
 {
     $page = new VirtualPageTest_ClassA();
     $page->CastingTest = "Some content";
     $page->write();
     $virtual = new VirtualPage();
     $virtual->CopyContentFromID = $page->ID;
     $virtual->write();
     $this->assertEquals('VirtualPageTest_TestDBField', $virtual->castingHelper('CastingTest'));
     $this->assertEquals('SOME CONTENT', $virtual->obj('CastingTest')->forTemplate());
 }
 public function testVirtualPagePointingToRedirectorPage()
 {
     if (!class_exists('RedirectorPage')) {
         $this->markTestSkipped('RedirectorPage required');
     }
     $rp = new RedirectorPage(array('ExternalURL' => 'http://google.com', 'RedirectionType' => 'External'));
     $rp->write();
     $rp->doPublish();
     $vp = new VirtualPage(array('URLSegment' => 'vptest', 'CopyContentFromID' => $rp->ID));
     $vp->write();
     $vp->doPublish();
     $response = $this->get($vp->Link());
     $this->assertEquals(301, $response->getStatusCode());
     $this->assertEquals('http://google.com', $response->getHeader('Location'));
 }
 function testEmbargoExpiryWithVirtualPages()
 {
     $custompublisher = $this->objFromFixture('Member', 'custompublisher');
     $custompublisher->login();
     $sourcePage = new Page();
     $sourcePage->Content = '<p>Pre-embargo</p>';
     $sourcePage->write();
     $sourcePage->doPublish();
     $sourcePage->Content = '<p>Post-embargo</p>';
     $sourcePage->write();
     $request = $sourcePage->openOrNewWorkflowRequest('WorkflowPublicationRequest');
     $sourcePage->setEmbargo('01/06/2050', '3:00pm');
     $sourcePage->write();
     $request->approve('all good');
     $virtualPage = new VirtualPage();
     $virtualPage->CopyContentFromID = $sourcePage->ID;
     $virtualPage->write();
     $virtualPage->doPublish();
     $liveVirtualPage = Versioned::get_one_by_stage('VirtualPage', 'Live', '"SiteTree"."ID" = ' . $virtualPage->ID);
     $this->assertEquals($liveVirtualPage->Content, '<p>Pre-embargo</p>');
 }