public function Form() { $fields = new FieldList(); $source = array(); $fields->push(new HeaderField('Header', _t('RemoveOrphanedPagesTask.HEADER', 'Remove all orphaned pages task'))); $fields->push(new LiteralField('Description', $this->description)); $orphans = $this->getOrphanedPages($this->orphanedSearchClass); if ($orphans) { foreach ($orphans as $orphan) { $latestVersion = Versioned::get_latest_version($this->orphanedSearchClass, $orphan->ID); $latestAuthor = DataObject::get_by_id('Member', $latestVersion->AuthorID); $stageRecord = Versioned::get_one_by_stage($this->orphanedSearchClass, 'Stage', sprintf("\"%s\".\"ID\" = %d", ClassInfo::baseDataClass($this->orphanedSearchClass), $orphan->ID)); $liveRecord = Versioned::get_one_by_stage($this->orphanedSearchClass, 'Live', sprintf("\"%s\".\"ID\" = %d", ClassInfo::baseDataClass($this->orphanedSearchClass), $orphan->ID)); $label = sprintf('<a href="admin/pages/edit/show/%d">%s</a> <small>(#%d, Last Modified Date: %s, Last Modifier: %s, %s)</small>', $orphan->ID, $orphan->Title, $orphan->ID, Date::create($orphan->LastEdited)->Nice(), $latestAuthor ? $latestAuthor->Title : 'unknown', $liveRecord ? 'is published' : 'not published'); $source[$orphan->ID] = $label; } } if ($orphans && $orphans->Count()) { $fields->push(new CheckboxSetField('OrphanIDs', false, $source)); $fields->push(new LiteralField('SelectAllLiteral', sprintf('<p><a href="#" onclick="javascript:jQuery(\'#Form_Form_OrphanIDs :checkbox\').attr(\'checked\', \'checked\'); return false;">%s</a> ', _t('RemoveOrphanedPagesTask.SELECTALL', 'select all')))); $fields->push(new LiteralField('UnselectAllLiteral', sprintf('<a href="#" onclick="javascript:jQuery(\'#Form_Form_OrphanIDs :checkbox\').attr(\'checked\', \'\'); return false;">%s</a></p>', _t('RemoveOrphanedPagesTask.UNSELECTALL', 'unselect all')))); $fields->push(new OptionSetField('OrphanOperation', _t('RemoveOrphanedPagesTask.CHOOSEOPERATION', 'Choose operation:'), array('rebase' => _t('RemoveOrphanedPagesTask.OPERATION_REBASE', sprintf('Rebase selected to a new holder page "%s" and unpublish. None of these pages will show up for website visitors.', $this->rebaseHolderTitle())), 'remove' => _t('RemoveOrphanedPagesTask.OPERATION_REMOVE', 'Remove selected from all stages (WARNING: Will destroy all selected pages from both stage and live)')), 'rebase')); $fields->push(new LiteralField('Warning', sprintf('<p class="message">%s</p>', _t('RemoveOrphanedPagesTask.DELETEWARNING', 'Warning: These operations are not reversible. Please handle with care.')))); } else { $fields->push(new LiteralField('NotFoundLabel', sprintf('<p class="message">%s</p>', _t('RemoveOrphanedPagesTask.NONEFOUND', 'No orphans found')))); } $form = new Form($this, 'Form', $fields, new FieldList(new FormAction('doSubmit', _t('RemoveOrphanedPagesTask.BUTTONRUN', 'Run')))); if (!$orphans || !$orphans->Count()) { $form->makeReadonly(); } return $form; }
/** * Modify the content to include subsite links * @global array $subsiteDomainIDs * @param array $arguments * @param string $content * @param type $parser * @return string links */ public static function link_shortcode_handler($arguments, $content = null, $parser = null) { if (!isset($arguments['id'])) { return; } $argumentarray = explode('-', $arguments['id']); if (count($argumentarray) != 2) { return; } $subsiteid = $argumentarray[0]; $id = $argumentarray[1]; $page = null; if ($id) { $page = DataObject::get_by_id('SiteTree', $id); // Get the current page by ID. if (!$page) { $page = Versioned::get_latest_version('SiteTree', $id); // Attempt link to old version. } } else { $page = DataObject::get_one('ErrorPage', '"ErrorPage"."ErrorCode" = \'404\''); // Link to 404 page. } if (!$page) { return; // There were no suitable matches at all. } $currentSubsite = Subsite::get()->byID((int) $subsiteid); $currenturl = null; if ($currentSubsite) { if (Director::isDev()) { $currenturl = $currentSubsite->DevDomainID ? $currentSubsite->DevDomain() : null; } if (Director::isTest()) { $currenturl = $currentSubsite->TestDomainID ? $currentSubsite->TestDomain() : null; } if (!$currenturl) { $currenturl = $currentSubsite->getPrimarySubsiteDomain(); } $currenturl = $currenturl->getFullProtocol() . $currenturl->Domain; // override if (Director::isDev() || Director::isTest()) { if (defined('DEV_SUBSITE_' . (int) $subsiteid)) { $subsiteurl = 'DEV_SUBSITE_' . (int) $subsiteid; $currenturl = constant($subsiteurl); } } } $link = Convert::raw2att($page->Link()); if ($content) { return sprintf('<a href="%s">%s</a>', $currenturl . $link, $parser->parse($content)); } else { return $currenturl . $link; } }
function testCanEditOnPageDeletedFromStageAndLiveReturnsFalse() { // Find a page that exists and delete it from both stage and published $this->logInWithPermission("ADMIN"); $page = $this->objFromFixture('Page', 'restrictedEditOnlySubadminGroup'); $pageID = $page->ID; $page->doUnpublish(); $page->delete(); // We'll need to resurrect the page from the version cache to test this case $page = Versioned::get_latest_version('SiteTree', $pageID); // subadmin had edit rights on that page, but now it's gone $member = $this->objFromFixture('Member', 'subadmin'); $member->logIn(); $this->assertFalse($page->canEdit()); }
public function handleItem($gridField, $request) { $controller = $gridField->getForm()->Controller(); if (is_numeric($request->param('ID')) && is_numeric($request->param('Version'))) { $record = Versioned::get_version($gridField->getModelClass(), $request->param('ID'), $request->param('Version')); } elseif (is_numeric($request->param('ID'))) { $record = Versioned::get_latest_version($gridField->getModelClass(), $request->param('ID')); } else { $record = Object::create($gridField->getModelClass()); } $class = $this->getItemRequestClass(); $handler = Object::create($class, $gridField, $this, $record, $controller, $this->name); $handler->setTemplate($this->template); return $handler->handleRequest($request, DataModel::inst()); }
/** * @param SS_HTTPRequest $request * * @return string|HTMLText */ public function preview(SS_HTTPRequest $request) { $key = $request->param('Key'); $token = $request->param('Token'); /** * @var ShareToken $shareToken */ $shareToken = ShareToken::get()->filter('token', $token)->first(); if (!$shareToken) { return $this->errorPage(); } $page = Versioned::get_one_by_stage('SiteTree', 'Stage', sprintf('"SiteTree"."ID" = \'%d\'', $shareToken->PageID)); $latest = Versioned::get_latest_version('SiteTree', $shareToken->PageID); $controller = $this->getControllerFor($page); if (!$shareToken->isExpired() && $page->generateKey($shareToken->Token) === $key) { Requirements::css(SHAREDRAFTCONTENT_DIR . '/css/top-bar.css'); // Temporarily un-secure the draft site and switch to draft $oldSecured = Session::get('unsecuredDraftSite'); $oldMode = Versioned::get_reading_mode(); $restore = function () use($oldSecured, $oldMode) { Session::set('unsecuredDraftSite', $oldSecured); Versioned::set_reading_mode($oldMode); }; // Process page inside an unsecured draft container try { Session::set('unsecuredDraftSite', true); Versioned::reading_stage('Stage'); // Create mock request; Simplify request to single top level reqest $pageRequest = new SS_HTTPRequest('GET', $page->URLSegment); $pageRequest->match('$URLSegment//$Action/$ID/$OtherID', true); $rendered = $controller->handleRequest($pageRequest, $this->model); // Render draft heading $data = new ArrayData(array('Page' => $page, 'Latest' => $latest)); $include = (string) $data->renderWith('Includes/TopBar'); } catch (Exception $ex) { $restore(); throw $ex; } $restore(); return str_replace('</body>', $include . '</body>', (string) $rendered->getBody()); } else { return $this->errorPage(); } }
/** * Restore a completely deleted page from the SiteTree_versions table. */ function restore($data, $form) { if (!isset($data['ID']) || !is_numeric($data['ID'])) { return new SS_HTTPResponse("Please pass an ID in the form content", 400); } $id = (int) $data['ID']; $restoredPage = Versioned::get_latest_version("SiteTree", $id); if (!$restoredPage) { return new SS_HTTPResponse("SiteTree #{$id} not found", 400); } $restoredPage = $restoredPage->doRestoreToStage(); $this->response->addHeader('X-Status', sprintf(_t('CMSMain.RESTORED', "Restored '%s' successfully", PR_MEDIUM, 'Param %s is a title'), $restoredPage->TreeTitle)); $form = $this->getEditForm($id); return $form->formHtmlContent(); }
/** * Determine if this page references a parent which is archived, and not available in stage * * @return bool True if there is an archived parent */ protected function isParentArchived() { if ($parentID = $this->ParentID) { $parentPage = Versioned::get_latest_version("SiteTree", $parentID); if (!$parentPage || $parentPage->IsDeletedFromStage) { return true; } } return false; }
public function testLazyLoadedFieldsOnVersionedRecords() { // Save another record, sanity check that we're getting the right one $obj2 = new VersionedTest_Subclass(); $obj2->Name = "test2"; $obj2->ExtraField = "foo2"; $obj2->write(); // Save the actual inspected record $obj1 = new VersionedTest_Subclass(); $obj1->Name = "test"; $obj1->ExtraField = "foo"; $obj1->write(); $version1 = $obj1->Version; $obj1->Name = "test2"; $obj1->ExtraField = "baz"; $obj1->write(); $version2 = $obj1->Version; $reloaded = Versioned::get_version('VersionedTest_Subclass', $obj1->ID, $version1); $this->assertEquals($reloaded->Name, 'test'); $this->assertEquals($reloaded->ExtraField, 'foo'); $reloaded = Versioned::get_version('VersionedTest_Subclass', $obj1->ID, $version2); $this->assertEquals($reloaded->Name, 'test2'); $this->assertEquals($reloaded->ExtraField, 'baz'); $reloaded = Versioned::get_latest_version('VersionedTest_Subclass', $obj1->ID); $this->assertEquals($reloaded->Version, $version2); $this->assertEquals($reloaded->Name, 'test2'); $this->assertEquals($reloaded->ExtraField, 'baz'); $allVersions = Versioned::get_all_versions('VersionedTest_Subclass', $obj1->ID); $this->assertEquals(2, $allVersions->Count()); $this->assertEquals($allVersions->First()->Version, $version1); $this->assertEquals($allVersions->First()->Name, 'test'); $this->assertEquals($allVersions->First()->ExtraField, 'foo'); $this->assertEquals($allVersions->Last()->Version, $version2); $this->assertEquals($allVersions->Last()->Name, 'test2'); $this->assertEquals($allVersions->Last()->ExtraField, 'baz'); $obj1->delete(); }
/** * Replace a "[sitetree_link id=n]" shortcode with a link to the page with the corresponding ID. * * @return string */ public static function link_shortcode_handler($arguments, $content = null, $parser = null) { if (!isset($arguments['id']) || !is_numeric($arguments['id'])) { return; } if (!($page = DataObject::get_by_id('SiteTree', $arguments['id'])) && !($page = Versioned::get_latest_version('SiteTree', $arguments['id'])) && !($page = DataObject::get_one('ErrorPage', '"ErrorCode" = \'404\''))) { return; // There were no suitable matches at all. } if ($content) { return sprintf('<a href="%s">%s</a>', $page->Link(), $parser->parse($content)); } else { return $page->Link(); } }
/** * Return a dataobject based on the `id` and `tree_class`. * * @param int $id * @return DataObject */ public function getRecord($id) { $treeClass = $this->stat('tree_class'); $record = DataObject::get_one($treeClass, "\"{$treeClass}\".\"ID\" = {$id}"); // Then, try getting a record from the live site if (!$record) { Versioned::reading_stage('Live'); singleton($treeClass)->flushCache(); $record = DataObject::get_one($treeClass, "\"{$treeClass}\".\"ID\" = {$id}"); if ($record) { Versioned::set_reading_mode(''); } } // Then, try getting a deleted record if (!$record) { $record = Versioned::get_latest_version($treeClass, $id); } return $record; }
function restorepage() { if ($id = $this->urlParams['ID']) { $restoredPage = Versioned::get_latest_version("SiteTree", $id); $restoredPage->ID = $restoredPage->RecordID; if (!DB::query("SELECT ID FROM SiteTree WHERE ID = {$restoredPage->ID}")->value()) { DB::query("INSERT INTO SiteTree SET ID = {$restoredPage->ID}"); } $restoredPage->forceChange(); $restoredPage->writeWithoutVersion(); Debug::show($restoredPage); } else { echo _t('CMSMain.VISITRESTORE', "visit restorepage/(ID)", PR_LOW, 'restorepage/(ID) should not be translated (is an URL)'); } }
/** * Creates array containg all unused thumbnails. * * Array is created in three steps: * 1. Scan assets folder and retrieve all thumbnails * 2. Scan all HTMLField in system and retrieve thumbnails from them. * 3. Count difference between two sets (array_diff) * * @return array */ private function getUnusedThumbnails() { $allThumbnails = array(); $usedThumbnails = array(); $dirIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(ASSETS_PATH)); $classes = ClassInfo::subclassesFor('SiteTree'); if ($dirIterator) { foreach ($dirIterator as $file) { if ($file->isFile()) { if (strpos($file->getPathname(), '_resampled') !== false) { $pathInfo = pathinfo($file->getPathname()); if (in_array(strtolower($pathInfo['extension']), array('jpeg', 'jpg', 'jpe', 'png', 'gif'))) { $path = str_replace('\\', '/', $file->getPathname()); $allThumbnails[] = substr($path, strpos($path, '/assets/') + 8); } } } } } if ($classes) { foreach ($classes as $className) { $SNG_class = singleton($className); $objects = DataObject::get($className); if ($objects !== NULL) { foreach ($objects as $object) { foreach ($SNG_class->db() as $fieldName => $fieldType) { if ($fieldType == 'HTMLText') { $url1 = HTTP::findByTagAndAttribute($object->{$fieldName}, array('img' => 'src')); if ($url1 != NULL) { $usedThumbnails[] = substr($url1[0], strpos($url1[0], '/assets/') + 8); } if ($object->latestPublished > 0) { $object = Versioned::get_latest_version($className, $object->ID); $url2 = HTTP::findByTagAndAttribute($object->{$fieldName}, array('img' => 'src')); if ($url2 != NULL) { $usedThumbnails[] = substr($url2[0], strpos($url2[0], '/assets/') + 8); } } } } } } } } return array_diff($allThumbnails, $usedThumbnails); }
/** * If current variation is enabled, checks lastest version of variation because status is saved * in versions. So a variation can be saved as enabled, the version can be added to cart, then * the variation is disabled but the previous version stays enabled. * * @return Boolean */ public function isEnabled() { $latestVersion = Versioned::get_latest_version('Variation', $this->ID); $enabled = $latestVersion->Status == 'Enabled'; $this->extend('isEnabled', $enabled); return $enabled; }
/** * Restore a completely deleted page from the SiteTree_versions table. */ function restore($data, $form) { if (($id = $_REQUEST['ID']) && is_numeric($id)) { $restoredPage = Versioned::get_latest_version("SiteTree", $id); if ($restoredPage) { $restoredPage = $restoredPage->doRestoreToStage(); FormResponse::get_page($id); $title = Convert::raw2js($restoredPage->TreeTitle()); FormResponse::add("\$('sitetree').setNodeTitle({$id}, '{$title}');"); FormResponse::status_message(sprintf(_t('CMSMain.RESTORED', "Restored '%s' successfully", PR_MEDIUM, 'Param %s is a title'), $title), 'good'); return FormResponse::respond(); } else { return new SS_HTTPResponse("SiteTree #{$id} not found", 400); } } else { return new SS_HTTPResponse("Please pass an ID in the form content", 400); } }
public function testGetVersionWhenClassnameChanged() { $obj = new VersionedTest_DataObject(); $obj->Name = "test"; $obj->write(); $obj->Name = "test2"; $obj->ClassName = "VersionedTest_Subclass"; $obj->write(); $subclassVersion = $obj->Version; $obj->Name = "test3"; $obj->ClassName = "VersionedTest_DataObject"; $obj->write(); // We should be able to pass the subclass and still get the correct class back $obj2 = Versioned::get_version("VersionedTest_Subclass", $obj->ID, $subclassVersion); $this->assertInstanceOf("VersionedTest_Subclass", $obj2); $this->assertEquals("test2", $obj2->Name); $obj3 = Versioned::get_latest_version("VersionedTest_Subclass", $obj->ID); $this->assertEquals("test3", $obj3->Name); $this->assertInstanceOf("VersionedTest_DataObject", $obj3); }
/** * Restore a previously deleted page. * Internal action which shouldn't be executed through URL-handlers. */ function restorepage() { if($id = $this->urlParams['ID']) { $restoredPage = Versioned::get_latest_version("SiteTree", $id); $restoredPage->ID = $restoredPage->RecordID; // if no record can be found on draft stage (meaning it has been "deleted from draft" before), // create an empty record if(!DB::query("SELECT ID FROM SiteTree WHERE ID = $restoredPage->ID")->value()) { DB::query("INSERT INTO SiteTree SET ID = $restoredPage->ID"); } $restoredPage->forceChange(); $restoredPage->writeWithoutVersion(); Debug::show($restoredPage); } else { echo _t('CMSMain.VISITRESTORE',"visit restorepage/(ID)",PR_LOW,'restorepage/(ID) should not be translated (is an URL)'); } }
/** * * @return DataObject (Any type of Data Object that is buyable) * @param Boolean $current - is this a current one, or an older VERSION ? **/ function Buyable($current = false) { if (!$this->BuyableID) { return null; } //start hack if (!$this->BuyableClassName) { $this->BuyableClassName = str_replace("_OrderItem", "", $this->ClassName); } $turnTranslatableBackOn = false; if (Object::has_extension($this->BuyableClassName, 'Translatable')) { Translatable::disable_locale_filter(); $turnTranslatableBackOn = true; } //end hack! $obj = null; if ($current) { $obj = DataObject::get_by_id($this->BuyableClassName, $this->BuyableID); } //run if current not available or current = false if (!$obj && $this->Version) { /* @TODO: check if the version exists?? - see sample below $versionTable = $this->BuyableClassName."_versions"; $dbConnection = DB::getConn(); if($dbConnection && $dbConnection instanceOf MySQLDatabase && $dbConnection->hasTable($versionTable)) { $result = DB::query(" SELECT COUNT(\"ID\") FROM \"$versionTable\" WHERE \"RecordID\" = ".intval($this->BuyableID)." AND \"Version\" = ".intval($this->Version)." "); if($result->value()) { */ $obj = OrderItem::get_version($this->BuyableClassName, $this->BuyableID, $this->Version); } //our last resort if (!$obj) { $obj = Versioned::get_latest_version($this->BuyableClassName, $this->BuyableID); } if ($turnTranslatableBackOn) { Translatable::enable_locale_filter(); } return $obj; }
/** * Handle the actions and apply any changes to the GridField * * @param GridField $gridField * @param string $actionName * @param mixed $arguments * @param array $data - form data * @return void */ public function handleAction(GridField $gridField, $actionName, $arguments, $data) { if ($actionName == 'unpublish' || $actionName == 'publish') { $item = Versioned::get_latest_version($gridField->getModelClass(), $arguments['RecordID']); if (!$item) { return; } if ($actionName == 'unpublish') { if (!$item->canPublish()) { throw new ValidationException(_t('GridFieldAction_Delete.DeletePermissionsFailure', "No delete permissions"), 0); } $item->doUnpublish(); } if ($actionName == 'publish') { if (!$item->canPublish()) { throw new ValidationException(_t('GridFieldAction_Delete.DeletePermissionsFailure', "No delete permissions"), 0); } $item->doPublish(); } } }
/** * If current variation is enabled, checks lastest version of variation because status is saved * in versions. So a variation can be saved as enabled, the version can be added to cart, then * the variation is disabled but the previous version stays enabled. * * @return Boolean */ public function isEnabled() { $latestVersion = Versioned::get_latest_version('Variation', $this->ID); return $latestVersion->Status == 'Enabled'; }
/** * * @param Boolean $current - is this a current one, or an older VERSION ? * @return DataObject (Any type of Data Object that is buyable) **/ function Buyable($current = false) { $tempBuyableStoreType = $current ? "current" : "version"; if (!isset($this->tempBuyableStore[$tempBuyableStoreType])) { if (!$this->BuyableID) { user_error("There was an error retrieving the product", E_USER_NOTICE); return null; } //start hack if (!$this->BuyableClassName) { $this->BuyableClassName = str_replace("_OrderItem", "", $this->ClassName); } $turnTranslatableBackOn = false; $className = $this->BuyableClassName; if ($className::has_extension($this->class, 'Translatable')) { Translatable::disable_locale_filter(); $turnTranslatableBackOn = true; } //end hack! $obj = null; if ($current) { $obj = $className::get()->byID($this->BuyableID); } //run if current not available or current = false if (!$obj || !$current) { if ((!$obj || !$obj->exists()) && $this->Version) { /* @TODO: check if the version exists?? - see sample below $versionTable = $this->BuyableClassName."_versions"; $dbConnection = DB::getConn(); if($dbConnection && $dbConnection instanceOf MySQLDatabase && $dbConnection->hasTable($versionTable)) { $result = DB::query(" SELECT COUNT(\"ID\") FROM \"$versionTable\" WHERE \"RecordID\" = ".intval($this->BuyableID)." AND \"Version\" = ".intval($this->Version)." "); if($result->value()) { */ $obj = OrderItem::get_version($this->BuyableClassName, $this->BuyableID, $this->Version); } //our second to last resort if (!$obj || !$obj->exists()) { $obj = Versioned::get_latest_version($this->BuyableClassName, $this->BuyableID); } } //our final backup if (!$obj || !$obj->exists()) { $obj = $className::get()->byID($this->BuyableID); } if ($turnTranslatableBackOn) { Translatable::enable_locale_filter(); } $this->tempBuyableStore[$tempBuyableStoreType] = $obj; } return $this->tempBuyableStore[$tempBuyableStoreType]; }
/** * Test that a page can be completely deleted and restored to the stage site */ public function testRestoreToStage() { $page = $this->objFromFixture('Page', 'about'); $pageID = $page->ID; $page->delete(); $this->assertTrue(!DataObject::get_by_id("Page", $pageID)); $deletedPage = Versioned::get_latest_version('SiteTree', $pageID); $resultPage = $deletedPage->doRestoreToStage(); $requeriedPage = DataObject::get_by_id("Page", $pageID); $this->assertEquals($pageID, $resultPage->ID); $this->assertEquals($pageID, $requeriedPage->ID); $this->assertEquals('About Us', $requeriedPage->Title); $this->assertEquals('Page', $requeriedPage->class); $page2 = $this->objFromFixture('Page', 'products'); $page2ID = $page2->ID; $page2->doUnpublish(); $page2->delete(); // Check that if we restore while on the live site that the content still gets pushed to // stage Versioned::reading_stage('Live'); $deletedPage = Versioned::get_latest_version('SiteTree', $page2ID); $deletedPage->doRestoreToStage(); $this->assertFalse((bool) Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = " . $page2ID)); Versioned::reading_stage('Stage'); $requeriedPage = DataObject::get_by_id("Page", $page2ID); $this->assertEquals('Products', $requeriedPage->Title); $this->assertEquals('Page', $requeriedPage->class); }
function LastEditedBy() { $latestVersion = Versioned::get_latest_version('SiteTree', $this->owner->ID); if (!$latestVersion || !$latestVersion->AuthorID) { return; } return DataObject::get_by_id('Member', $latestVersion->AuthorID); }
public function testRestoreFixesBrokenLinks() { // Create page and virtual 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); // Unpublish the source page, confirm that the page 2 and RP has a broken link on published $p->doUnpublish(); $p2Live = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $p2->ID); $rpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $rp->ID); $this->assertEquals(1, $p2Live->HasBrokenLink); $this->assertEquals(1, $rpLive->HasBrokenLink); // Delete the source page, confirm that the VP, RP and page 2 have broken links on draft $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); // Restore the page to stage, confirm that this fixes the links $p = Versioned::get_latest_version('SiteTree', $pageID); $p->doRestoreToStage(); $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); // Publish and confirm that the p2 and RP broken links are fixed on published $this->assertTrue($p->doPublish()); $p2Live = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $p2->ID); $rpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $rp->ID); $this->assertFalse((bool) $p2Live->HasBrokenLink); $this->assertFalse((bool) $rpLive->HasBrokenLink); }
public function testStatusDeletedFilter() { $deletedPage = $this->objFromFixture('Page', 'page7'); $deletedPage->publish('Stage', 'Live'); $deletedPageID = $deletedPage->ID; // Can't use straight $blah->delete() as that blows it away completely and test fails $deletedPage->deleteFromStage('Live'); $deletedPage->deleteFromStage('Draft'); $checkParentExists = Versioned::get_latest_version('SiteTree', $deletedPageID); // Check deleted page is included $f = new CMSSiteTreeFilter_StatusDeletedPages(array('Title' => 'Page')); $this->assertTrue($f->isPageIncluded($checkParentExists)); // Check filter is respected $f = new CMSSiteTreeFilter_StatusDeletedPages(array('Title' => 'Bobby')); $this->assertFalse($f->isPageIncluded($checkParentExists)); }
/** * Restore a completely deleted page from the SiteTree_versions table. */ public function restore($data, $form) { if (!isset($data['ID']) || !is_numeric($data['ID'])) { return new SS_HTTPResponse("Please pass an ID in the form content", 400); } $id = (int) $data['ID']; $restoredPage = Versioned::get_latest_version("ContentModule", $id); if (!$restoredPage) { return new SS_HTTPResponse("ContentModule #{$id} not found", 400); } $restoredPage = $restoredPage->doRestoreToStage(); $this->response->addHeader('X-Status', rawurlencode(_t('CMSMain.RESTORED', "Restored '{title}' successfully", array('title' => $restoredPage->Title)))); return $this->getResponseNegotiator()->respond($this->request); }
/** * Handle the actions and apply any changes to the GridField * * @param GridField $gridField * @param string $actionName * @param mixed $arguments * @param array $data - form data * @return void */ public function handleAction(GridField $gridField, $actionName, $arguments, $data) { if ($actionName == 'deletefromstage') { $item = Versioned::get_latest_version($gridField->getModelClass(), $arguments['RecordID']); if (!$item) { return; } if ($actionName == 'deletefromstage') { if (!$item->canDelete()) { throw new ValidationException(_t('PublishableGridFieldAction.DELETE_PERM', 'You do not have permission to delete this draft'), 0); } $item->doDeleteDraft(); } } }