Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions app.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,11 @@ public static function boot() {
Router::get()->init();

if (Environment::getCurrentEnvironment() == Environment::DEVELOPMENT) {
// always check for changed migrations on development (except when resetting)
if (!(Router::get()->getCurrentModule() instanceof CoreRoutes_Reset))
// always check for changed migrations and reset callbacks on development (except when resetting)
if (!(Router::get()->getCurrentModule() instanceof CoreRoutes_Reset)) {
Core_MigrationsLoader::load();
CoreRoutes_Reset::executeCallbacksOnAfterReset();
}
}

Router::get()->runCurrentModule();
Expand Down Expand Up @@ -427,4 +429,4 @@ function backtrace() {
Core_Dump::backtrace();
}

?>
?>
69 changes: 62 additions & 7 deletions core/coreroutes/reset.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
* Resets the project.
*/
class CoreRoutes_Reset extends Module {

// path of reset callback logfile, relative to PROJECT_PATH
const RESET_CALLBACK_LOG_FILE = '/config/log/reset_callback.log.xml';

private static $callbacksOnAfterReset = array();

public function init() {
Expand All @@ -31,8 +35,12 @@ public function init() {
DB_Connection::get()->deleteTables();

// remove migrations log
$file = new IO_File(PROJECT_PATH.Core_MigrationsLoader::MIGRATION_LOG_FILE);
$file->delete();
$migrationFile = new IO_File(PROJECT_PATH.Core_MigrationsLoader::MIGRATION_LOG_FILE);
$migrationFile->delete();

// remove reset callbacks log
$resetCallbacksFile = new IO_File(PROJECT_PATH.self::RESET_CALLBACK_LOG_FILE);
$resetCallbacksFile->delete();

// clear global cache
$GLOBALS['cache']->clearAll();
Expand All @@ -46,17 +54,64 @@ public function init() {
// rebuild database
Core_MigrationsLoader::load();

if (defined('CALLBACK_ONAFTERRESET'))
self::addCallbackOnAfterReset(CALLBACK_ONAFTERRESET);
foreach (self::$callbacksOnAfterReset as $callback)
call_user_func($callback);
// execute registered callbacks
self::executeCallbacksOnAfterReset();

Scriptlet::redirect(PROJECT_ROOTURI);
}

public static function addCallbackOnAfterReset($callback) {
self::$callbacksOnAfterReset[] = $callback;
}

/**
* Executes the callbacks registered by addCallbackOnAfterReset
* or defined by the constant CALLBACK_ONAFTERRESET.
* Execution is only performed if the callbacks haven't been called
* since the last reset.
* This method is intended to be used when there's a reason to execute
* these callbacks once, even when there's no complete reset being performed.
* One such reason is the initial setup and running newly added callbacks
* in development mode.
* Callbacks that differ only in the instance of a class and not in the method called
* will be treated as if they were the same. So if more than one instance of a class
* is used for a callback, each instance needs its unique member function to be executed.
*/
public static function executeCallbacksOnAfterReset() {

if (defined('CALLBACK_ONAFTERRESET'))
self::addCallbackOnAfterReset(CALLBACK_ONAFTERRESET);

if (file_exists(PROJECT_PATH.self::RESET_CALLBACK_LOG_FILE))
$xml = simplexml_load_file(PROJECT_PATH.self::RESET_CALLBACK_LOG_FILE);
else {
$baseResetCallbackLog = '<?xml version=\'1.0\'?><content></content>';
$xml = new SimpleXMLElement($baseResetCallbackLog);
}

foreach (self::$callbacksOnAfterReset as $callback) {
if (is_array($callback) && isset($callback[0]) && isset($callback[1])) {
// different objects of the same class will be treated as if they were the same
$callbackIdentifier = get_class($callback[0]).'->'.$callback[1];
} else $callbackIdentifier = $callback;

// execute reset callbacks if they haven't been before
$result = $xml->xpath(sprintf('/content/callback[@identifier=\'%s\']', $callbackIdentifier));
if (empty($result)) {
$result = $xml->xpath('/content');
$child = $result[0]->addChild('callback');
$child->addAttribute('identifier', $callbackIdentifier);
call_user_func($callback);
}
}
// save reset callback logfile
$doc = new DOMDocument('1.0');
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml->asXML());
$doc->formatOutput = true;
$doc->save(PROJECT_PATH.self::RESET_CALLBACK_LOG_FILE);
}

}

?>
?>