Skip to content

Instantly share code, notes, and snippets.

@patricknelson
Last active December 29, 2018 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patricknelson/a5f74fffbd4de6c3c395fca9496f3c26 to your computer and use it in GitHub Desktop.
Save patricknelson/a5f74fffbd4de6c3c395fca9496f3c26 to your computer and use it in GitHub Desktop.
Helper functions to cleanly alter versioned objects in SilverStripe
<?php
/**
* Helper functions to cleanly alter versioned objects in SilverStripe.
*
* Usage:
*
* whileDraft(function() {
* $page = Page::get()->byId(123);
* // ... with great power comes great responsibility...
* });
*
* @author Patrick Nelson, pat@catchyour.com
* @since 2018-12-28
*/
/**
* Synchronous way to temporarily change global state to the desired reading mode. Unfortunately these things aren't as
* easy in the framework as they should be...
*
* @param string $name
* @param callable $closure
* @return mixed
*/
function whileStage($name, callable $closure) {
// Normalize desired stage name.
$normName = strtolower(trim($name));
$readingMode = 'Stage.Live'; // Default to live, just in case.
if ($normName === 'draft') $readingMode = 'Stage.Stage'; // ... yes, the redundancy is an artifact of our dear friend SilverStripe.
// Don't normalize but pass through directly if 'Archive' is specified, given the possible variation.
if (substr($normName, 0, 8) === 'archive.') $readingMode = $name;
// Get global state.
$oldReadingMode = Versioned::get_reading_mode();
// Change global state temporarily to the mode we want to be in and run the code.
Versioned::set_reading_mode($readingMode);
$retval = call_user_func($closure);
// Clean up global state and return.
Versioned::set_reading_mode($oldReadingMode);
return $retval;
}
/**
* Allows you to read archived pages (i.e. from *_versions table) for a particular
*
* @param int $timestamp Specific UNIX timestamp to rewind in history back to. Versions of pages will be
* those at/before this particular point in time.
* @param callable $closure
* @return mixed
*/
function whileArchive($timestamp, callable $closure) {
return whileStage('Archive.' . date('Y-m-d H:i:s', $timestamp), $closure);
}
/**
* Shortcut to whileStage().
*
* @param callable $closure
* @return mixed
*/
function whileDraft(callable $closure) {
return whileStage('draft', $closure);
}
/**
* Shortcut to whileStage().
*
* @param callable $closure
* @return mixed
*/
function whileLive(callable $closure) {
return whileStage('live', $closure);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment