protected function deleteVersionedObjects($tags, $obj, $stage, $pageID) { $tagsArray = array(); $tagsTempArray = array(); if ($tags) { foreach ($tags as $tag) { array_push($tagsArray, $tag->ID); } $versionedTags = Versioned::get_by_stage($obj, $stage)->filter(array('FaqPageID' => $pageID)); foreach ($versionedTags as $versionedTag) { array_push($tagsTempArray, $versionedTag->ID); } $tagsArrayDiff = array_diff($tagsTempArray, $tagsArray); if ($tagsArrayDiff) { foreach ($tagsArrayDiff as $key => $val) { $thisTag = Versioned::get_by_stage($obj, $stage)->byID($val); if ($thisTag) { $thisTag->deleteFromStage($stage); } } return true; } } return false; }
function republish($original) { if (self::$disable_realtime) { return; } $urls = array(); if ($this->owner->hasMethod('pagesAffectedByChanges')) { $urls = $this->owner->pagesAffectedByChanges($original); } else { $pages = Versioned::get_by_stage('SiteTree', 'Live', '', '', '', 10); if ($pages) { foreach ($pages as $page) { $urls[] = $page->AbsoluteLink(); } } } // Note: Similiar to RebuildStaticCacheTask->rebuildCache() foreach ($urls as $i => $url) { if (!is_string($url)) { user_error("Bad URL: " . var_export($url, true), E_USER_WARNING); continue; } // Remove leading slashes from all URLs (apart from the homepage) if (substr($url, -1) == '/' && $url != '/') { $url = substr($url, 0, -1); } $urls[$i] = $url; } $urls = array_unique($urls); $this->publishPages($urls); }
public function onAfterWrite() { parent::onAfterWrite(); if (in_array('Searchable', class_implements($this->owner->class))) { if ($this->owner->IncludeInSearch()) { if ($this->owner->hasExtension('Versioned')) { $filterID = array('ID' => $this->owner->ID); $filter = $filterID + $this->owner->getSearchFilter(); $do = Versioned::get_by_stage($this->owner->class, 'Live')->filter($filter)->first(); } else { $filterID = "`{$this->owner->class}`.`ID`={$this->owner->ID}"; $do = DataObject::get($this->owner->class, $filterID, false)->filter($this->owner->getSearchFilter())->first(); } if ($do) { PopulateSearch::insert($do); } else { $this->deleteDo($this->owner); } } else { $this->deleteDo($this->owner); } } else { if ($this->owner instanceof SiteTree) { if ($this->owner->ShowInSearch) { PopulateSearch::insertPage($this->owner); } else { $this->deleteDo($this->owner); } } } }
/** * If there are multiple @link NewsHolderPage available, add the field for multiples. * This includes translation options */ private function multipleNewsHolderPages() { $enabled = false; // If we have translations, disable translation filter to get all pages. if (class_exists('Translatable')) { $enabled = Translatable::disable_locale_filter(); } $pages = Versioned::get_by_stage('NewsHolderPage', 'Live'); // Only add the page-selection if there are multiple. Otherwise handled by onBeforeWrite(); if ($pages->count() > 1) { $pagelist = array(); if (class_exists('Translatable')) { foreach ($pages as $page) { $pagelist['Root.Main'][$page->ID] = $page->Title . ' ' . $page->Locale; } } else { $pagelist = $pages->map('ID', 'Title')->toArray(); } $this->field_list['Root.Main'][1] = ListboxField::create('NewsHolderPages', $this->owner->fieldLabel('NewsHolderPages'), $pagelist); $this->field_list['Root.Main'][1]->setMultiple(true); } if ($enabled) { Translatable::enable_locale_filter(); } }
/** * @param int $summit_id * @return SummitConfirmSpeakerPage */ public static function getBy($summit_id) { $page = Versioned::get_by_stage('SummitConfirmSpeakerPage', 'Live')->filter('SummitID', $summit_id)->first(); if (is_null($page)) { $page = Versioned::get_by_stage('SummitConfirmSpeakerPage', 'Stage')->filter('SummitID', $summit_id)->first(); } return $page; }
/** * @param ISummit $summit * @return SummitAppSchedPage */ public static function getBy(ISummit $summit) { $page = Versioned::get_by_stage('SummitAppSchedPage', 'Live')->filter('SummitID', $summit->getIdentifier())->first(); if (is_null($page)) { $page = Versioned::get_by_stage('SummitAppSchedPage', 'Stage')->filter('SummitID', $summit->getIdentifier())->first(); } return $page; }
public function sourceRecords($params = null) { $classes = ClassInfo::subclassesFor('RedirectorPage'); $classParams = DB::placeholders($classes); $classFilter = array("\"ClassName\" IN ({$classParams}) AND \"HasBrokenLink\" = 1" => $classes); $stage = isset($params['OnLive']) ? 'Live' : 'Stage'; return Versioned::get_by_stage('SiteTree', $stage, $classFilter); }
/** * Unpublishing Versioning support * * When unpublishing the field it has to remove all options attached * * @return void */ public function doDeleteFromStage($stage) { // Remove options $options = Versioned::get_by_stage('EditableOption', $stage)->filter('ParentID', $this->ID); foreach ($options as $option) { $option->deleteFromStage($stage); } parent::doDeleteFromStage($stage); }
protected function assertDataObjectsOnStage($class, $number, $stage = 'Live') { $objects = Versioned::get_by_stage($class, $stage); if (!$number) { $this->assertEmpty($objects); } else { $this->assertInstanceOf('DataObjectSet', $objects); $this->assertEquals($number, $objects->TotalItems()); } }
public function sourceRecords($params = null) { $classNames = "'" . join("','", ClassInfo::subclassesFor('RedirectorPage')) . "'"; if (isset($_REQUEST['OnLive'])) { $ret = Versioned::get_by_stage('SiteTree', 'Live', "\"ClassName\" IN ({$classNames}) AND \"HasBrokenLink\" = 1"); } else { $ret = DataObject::get('SiteTree', "\"ClassName\" IN ({$classNames}) AND \"HasBrokenLink\" = 1"); } return $ret; }
/** * Custom currentPage() method to handle opening the 'root' folder * * @return */ public function currentPage() { $id = $this->currentPageID(); if ($id && is_numeric($id) && $id > 0) { return Versioned::get_by_stage('SiteTree', 'Stage', sprintf('ID = %s', (int) $id))->first(); } else { // ID is either '0' or 'root' return singleton('SiteTree'); } }
public function getCMSFields() { $fields = parent::getCMSFields(); $gfConfig = GridFieldConfig_relationEditor::create(); $gfConfig->removeComponentsByType('GridFieldDeleteAction')->removeComponentsByType('GridFieldDetailForm')->addComponents(new VersionedGridFieldDetailForm()); $articles = Versioned::get_by_stage('NewsArticle', 'Stage'); $fields->insertAfter(Tab::create('Articles'), 'Main'); $fields->addFieldToTab('Root.Articles', GridField::create('Children', 'Articles', $articles, $gfConfig)); return $fields; }
public function Items() { $filter = ''; $bt = defined('DB::USE_ANSI_SQL') ? "\"" : "`"; if (self::$use_show_in_search) { $filter = "{$bt}ShowInSearch{$bt} = 1"; } $this->Pages = Versioned::get_by_stage('SiteTree', 'Live', $filter); $newPages = new DataObjectSet(); if ($this->Pages) { foreach ($this->Pages as $page) { // Only include pages from this host and pages which are not an instance of ErrorPage // We prefix $_SERVER['HTTP_HOST'] with 'http://' so that parse_url to help parse_url identify the host name component; we could use another protocol (like // 'ftp://' as the prefix and the code would work the same. if (parse_url($page->AbsoluteLink(), PHP_URL_HOST) == parse_url('http://' . $_SERVER['HTTP_HOST'], PHP_URL_HOST) && !$page instanceof ErrorPage) { // If the page has been set to 0 priority, we set a flag so it won't be included if ($page->canView() && (!isset($page->Priority) || $page->Priority > 0)) { // The one field that isn't easy to deal with in the template is // Change frequency, so we set that here. $properties = $page->toMap(); $created = new SS_Datetime(); $created->value = $properties['Created']; $now = new SS_Datetime(); $now->value = date('Y-m-d H:i:s'); $versions = $properties['Version']; $timediff = $now->format('U') - $created->format('U'); // Check how many revisions have been made over the lifetime of the // Page for a rough estimate of it's changing frequency. $period = $timediff / ($versions + 1); if ($period > 60 * 60 * 24 * 365) { // > 1 year $page->ChangeFreq = 'yearly'; } elseif ($period > 60 * 60 * 24 * 30) { // > ~1 month $page->ChangeFreq = 'monthly'; } elseif ($period > 60 * 60 * 24 * 7) { // > 1 week $page->ChangeFreq = 'weekly'; } elseif ($period > 60 * 60 * 24) { // > 1 day $page->ChangeFreq = 'daily'; } elseif ($period > 60 * 60) { // > 1 hour $page->ChangeFreq = 'hourly'; } else { // < 1 hour $page->ChangeFreq = 'always'; } $newPages->push($page); } } } return $newPages; } }
public function Items() { $this->Pages = Versioned::get_by_stage('SiteTree', 'Live'); $newPages = new DataObjectSet(); foreach ($this->Pages as $page) { // Only include pages from this host if (parse_url($page->AbsoluteLink(), PHP_URL_HOST) == $_SERVER['HTTP_HOST']) { // If the page has been set to 0 priority, we set a flag so it won't be included if (isset($page->Priority) && $page->Priority <= 0) { $page->Include = false; } else { $page->Include = true; } // The one field that isn't easy to deal with in the template is // Change frequency, so we set that here. $properties = $page->toMap(); $created = new Datetime($properties['Created']); $now = new Datetime(); $versions = $properties['Version']; $timediff = $now->format('U') - $created->format('U'); // Check how many revisions have been made over the lifetime of the // Page for a rough estimate of it's changing frequency. $period = $timediff / ($versions + 1); if ($period > 60 * 60 * 24 * 365) { // > 1 year $page->ChangeFreq = 'yearly'; } else { if ($period > 60 * 60 * 24 * 30) { // > ~1 month $page->ChangeFreq = 'monthly'; } else { if ($period > 60 * 60 * 24 * 7) { // > 1 week $page->ChangeFreq = 'weekly'; } else { if ($period > 60 * 60 * 24) { // > 1 day $page->ChangeFreq = 'daily'; } else { if ($period > 60 * 60) { // > 1 hour $page->ChangeFreq = 'hourly'; } else { // < 1 hour $page->ChangeFreq = 'always'; } } } } } $newPages->push($page); } } return $newPages; }
public function sourceRecords($params = null) { // Get class names for page types that are not virtual pages or redirector pages $classes = array_diff(ClassInfo::subclassesFor('SiteTree'), ClassInfo::subclassesFor('VirtualPage'), ClassInfo::subclassesFor('RedirectorPage')); $classNames = "'" . join("','", $classes) . "'"; if (isset($_REQUEST['OnLive'])) { $ret = Versioned::get_by_stage('SiteTree', 'Live', "\"ClassName\" IN ({$classNames}) AND \"HasBrokenFile\" = 1"); } else { $ret = DataObject::get('SiteTree', "\"ClassName\" IN ({$classNames}) AND \"HasBrokenFile\" = 1"); } return $ret; }
/** * Returns an array with 2 elements, one with a list of Page on the site (and all subsites if * applicable) and another with files. * * @return array */ public function sourceRecords() { if (class_exists('Subsite') && Subsite::get()->count() > 0) { $origMode = Versioned::get_reading_mode(); Versioned::set_reading_mode('Stage.Stage'); $items = array('Pages' => Subsite::get_from_all_subsites('SiteTree'), 'Files' => Subsite::get_from_all_subsites('File')); Versioned::set_reading_mode($origMode); return $items; } else { return array('Pages' => Versioned::get_by_stage('SiteTree', 'Stage'), 'Files' => File::get()); } }
/** * Publish the existing forms. * */ function run($request) { $forms = Versioned::get_by_stage('UserDefinedForm', 'Live'); if ($forms) { foreach ($forms as $form) { echo "Publishing {$form->Title} <br />"; $form->doPublish(); } echo "Complete"; } else { echo "No Forms Found"; } }
/** * @return Array */ public static function generate_homepage_domain_map() { $domainSpecificHomepages = Versioned::get_by_stage('Page', 'Live', "\"HomepageForDomain\" != ''", "\"URLSegment\" ASC"); if (!$domainSpecificHomepages) { return false; } $map = array(); foreach ($domainSpecificHomepages->map('URLSegment', 'HomepageForDomain') as $url => $domains) { foreach (explode(',', $domains) as $domain) { $map[$domain] = $url; } } return $map; }
/** * Publishing Versioning support. * * When publishing it needs to handle copying across / publishing * each of the individual field options * * @return void */ public function doPublish($fromStage, $toStage, $createNewVersion = false) { $live = Versioned::get_by_stage("EditableOption", "Live", "\"EditableOption\".\"ParentID\" = {$this->ID}"); if ($live) { foreach ($live as $option) { $option->delete(); } } if ($this->Options()) { foreach ($this->Options() as $option) { $option->publish($fromStage, $toStage, $createNewVersion); } } $this->publish($fromStage, $toStage, $createNewVersion); }
public function onBeforeVersionedPublish() { $staged = array(); foreach ($this->owner->Elements() as $widget) { $staged[] = $widget->ID; $widget->publish('Stage', 'Live'); } // remove any elements that are on live but not in draft. $widgets = Versioned::get_by_stage('BaseElement', 'Live', "ParentID = '" . $this->owner->ID . "' OR ListID = '" . $this->owner->ID . "'"); foreach ($widgets as $widget) { if (!in_array($widget->ID, $staged)) { $widget->deleteFromStage('Live'); } } }
public static function create_status() { // If the script is to be started create a new status $status = self::create(); $status->updateJobInfo('Creating new tracking object'); // Setup all pages to test $pageIDs = Versioned::get_by_stage('SiteTree', 'Stage')->column('ID'); foreach ($pageIDs as $pageID) { $trackPage = BrokenExternalPageTrack::create(); $trackPage->PageID = $pageID; $trackPage->StatusID = $status->ID; $trackPage->write(); } return $status; }
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); } }
function handleAction($request) { // This method can't be called without ajax. if (!Director::is_ajax()) { Director::redirectBack(); return; } // Protect against CSRF on destructive action if (!SecurityToken::inst()->checkRequest($request)) { return $this->httpError(400); } $actions = Object::get_static($this->class, 'batch_actions'); $actionClass = $actions[$request->param('BatchAction')]; $actionHandler = new $actionClass(); // Sanitise ID list and query the database for apges $ids = split(' *, *', trim($request->requestVar('csvIDs'))); foreach ($ids as $k => $v) { if (!is_numeric($v)) { unset($ids[$k]); } } if ($ids) { $pages = DataObject::get('SiteTree', "\"SiteTree\".\"ID\" IN (" . implode(", ", $ids) . ")"); // If we didn't query all the pages, then find the rest on the live site if (!$pages || $pages->Count() < sizeof($ids)) { foreach ($ids as $id) { $idsFromLive[$id] = true; } if ($pages) { foreach ($pages as $page) { unset($idsFromLive[$page->ID]); } } $idsFromLive = array_keys($idsFromLive); // Debug::message("\"SiteTree\".\"ID\" IN (" . implode(", ", $idsFromLive) . ")"); $livePages = Versioned::get_by_stage('SiteTree', 'Live', "\"SiteTree\".\"ID\" IN (" . implode(", ", $idsFromLive) . ")"); if ($pages) { $pages->merge($livePages); } else { $pages = $livePages; } } } else { $pages = new DataObjectSet(); } return $actionHandler->run($pages); }
/** * Publishing Versioning support. * * When publishing copy the editable form fields to the live database * Not going to version emails and submissions as they are likely to * persist over multiple versions * * @return void */ public function doPublish() { // remove fields on the live table which could have been orphaned. $live = Versioned::get_by_stage("EditableFormField", "Live", "\"EditableFormField\".\"ParentID\" = {$this->ID}"); if ($live) { foreach ($live as $field) { $field->doDeleteFromStage('Live'); } } // publish the draft pages if ($this->Fields()) { foreach ($this->Fields() as $field) { $field->doPublish('Stage', 'Live'); } } parent::doPublish(); }
public function run($request) { if (!(\Permission::check('ADMIN') || \Director::is_cli())) { exit("Invalid"); } $service = singleton('ElasticaService'); $items = explode(',', $request->getVar('ids')); if (!count($items)) { return; } $baseType = $request->getVar('base') ? $request->getVar('base') : 'SiteTree'; $recurse = $request->getVar('recurse') ? true : false; foreach ($items as $id) { $id = (int) $id; if (!$id) { continue; } \Versioned::reading_stage('Stage'); $item = $baseType::get()->byID($id); if ($item) { $this->reindex($item, $recurse, $baseType, $service, 'Stage'); } \Versioned::reading_stage('Live'); $item = $baseType::get()->byID($id); if ($item) { $this->reindex($item, $recurse, $baseType, $service, 'Live'); } } return; foreach ($this->getIndexedClasses() as $class) { $logFunc("Indexing items of type {$class}"); $this->startBulkIndex(); foreach ($class::get() as $record) { $logFunc("Indexing " . $record->Title); $this->index($record); } if (\Object::has_extension($class, 'Versioned')) { $live = \Versioned::get_by_stage($class, 'Live'); foreach ($live as $liveRecord) { $logFunc("Indexing Live record " . $liveRecord->Title); $this->index($liveRecord, 'Live'); } } $this->endBulkIndex(); } }
function run($request) { $stagingArray = array("Live", "Stage"); foreach ($stagingArray as $stage) { $products = Versioned::get_by_stage("Product", $stage); $count = 0; if ($products) { foreach ($products as $product) { if ($this->hasExtension("ProductWithVariationDecorator")) { if ($product->cleaningUpVariationData($verbose = true)) { $count++; } } } } DB::alteration_message("Updated {$count} Products (" . $products->count() . " products on {$stage})"); } }
public function run($request) { $cart = ShoppingCart::singleton(); $count = $request->getVar('count') ? $request->getVar('count') : 5; if ($products = Versioned::get_by_stage("Product", "Live", "", "RAND()", "", $count)) { foreach ($products as $product) { $variations = $product->Variations(); if ($variations->exists()) { $product = $variations->sort("RAND()")->first(); } $quantity = (int) rand(1, 5); if ($product->canPurchase(Member::currentUser(), $quantity)) { $cart->add($product, $quantity); } } } Controller::curr()->redirect(CheckoutPage::find_link()); }
public function getStatus($cached = true) { $status = null; $statusflag = null; if ($this->hasMethod("isPublished")) { $published = $this->isPublished(); if ($published) { $status = _t("GridFieldPage.StatusPublished", '<i class="btn-icon btn-icon-accept"></i> Published on {date}', "State for when a post is published.", array("date" => $this->dbObject("LastEdited")->Nice())); //$status = 'Published'; // Special case where sortorder changed $liveRecord = Versioned::get_by_stage(get_class($this), 'Live')->byID($this->ID); //return $this->Sort . ' - ' . $liveRecord->Sort; if ($liveRecord->Sort && $liveRecord->Sort != $this->Sort) { // override published status $status = _t("GridFieldPage.StatusDraftReordered", '<i class="btn-icon btn-icon-arrow-circle-double"></i> Draft modified (reordered)', "State for when a page has been reordered."); //$status = 'Draft modified (reordered)'; } // Special case where deleted from draft if ($this->IsDeletedFromStage) { // override published status $statusflag = "<span class='modified'>" . _t("GridFieldPage.StatusDraftDeleted", "draft deleted") . "</span>"; //$status = 'Draft deleted'; } // If modified on stage, add if ($this->IsModifiedOnStage) { // add to published status $statusflag = "<span class='modified'>" . _t("GridFieldPage.StatusModified", "draft modified") . "</span>"; //$status = 'Draft modified'; } // If same on stage... if ($this->IsSameOnStage) { // leave as is } } else { if ($this->IsAddedToStage) { $status = _t("GridFieldPage.StatusDraft", '<i class="btn-icon btn-icon-pencil"></i> Saved as Draft on {date}', "State for when a post is saved but not published.", array("date" => $this->dbObject("LastEdited")->Nice())); //$status = 'Draft'; } } } // allow for extensions $this->extend('updateStatus', $status, $statusflag); return DBField::create_field('HTMLVarchar', $status . $statusflag); }
public function run($request) { // output echo "<br />\n<br />\nPurging...<br />\n<br />\n"; flush(); ob_flush(); foreach (Tweet::get() as $page) { echo "Deleting " . $page->Title . "\n"; $page->delete(); } foreach (Versioned::get_by_stage('Tweet', 'Stage') as $page) { echo "Deleting From Stage: " . $page->Title . "\n"; $page->deleteFromStage('Stage'); } foreach (Versioned::get_by_stage('Tweet', 'Live') as $page) { echo "Deleting From Live: " . $page->Title . "\n"; $page->deleteFromStage('Live'); } }
public function run($request) { // eol $eol = php_sapi_name() == 'cli' ? "\n" : "<br>\n"; // output echo $eol . $eol . 'Purging...' . $eol . $eol; flush(); @ob_flush(); foreach (Tweet::get() as $page) { echo "Deleting " . $page->Title . $eol; $page->delete(); } foreach (Versioned::get_by_stage('Tweet', 'Stage') as $page) { echo "Deleting From Stage: " . $page->Title . $eol; $page->deleteFromStage('Stage'); } foreach (Versioned::get_by_stage('Tweet', 'Live') as $page) { echo "Deleting From Live: " . $page->Title . $eol; $page->deleteFromStage('Live'); } }