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>&nbsp;', _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();
 }
Exemple #9
0
 /**
  * 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;
 }
Exemple #11
0
 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);
 }
Exemple #13
0
 /**
  * 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);
 }
Exemple #16
0
	/**
	 * 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();
         }
     }
 }