Created
January 18, 2014 14:53
-
-
Save Finetuned/8491590 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Pull.php: | |
* Version control your MODX site using git. | |
* Pulls changes from git and processes database changes in changesets. | |
* | |
* Authors: | |
* Jeroen Kenters / www.kenters.com | |
* Bert Oost / www.oostdesign.com | |
* | |
* License: | |
* GPL | |
* | |
* Warning: | |
* This code is provided as is without any warranty! Use at your own risk! | |
* Always make backups! | |
* | |
* Some documentation: | |
* http://kenters.com/weblog/2013/12/09/my-modx-git-workflow/ | |
*/ | |
set_time_limit(3600); //1 hour should be enough to process all changes :-) | |
//Initialize MODX | |
require_once(dirname(dirname(__FILE__)).'/config.core.php'); | |
require_once MODX_CORE_PATH . 'model/modx/modx.class.php'; | |
$modx= new modX(); | |
$modx->initialize('mgr'); | |
$modx->setLogLevel(modX::LOG_LEVEL_INFO); | |
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'FILE'); | |
//Get new stuff from git (don't run when client is local or when told to in $_GET) | |
if(!isset($_GET['skipPull']) && $_SERVER['REMOTE_ADDR'] != '127.0.0.1') { | |
$pullResponse = `git pull`; | |
if(stristr($pullResponse, 'Already up-to-date') !== false) { | |
doLog('No changes to pull from git repo'); | |
die('Already up-to-date.'); | |
} | |
} | |
else { | |
doLog('Skipping git pull.'); | |
} | |
//Get database settings | |
$db_name = $modx->config['dbname']; | |
$db_user = $modx->config['username']; | |
$db_pass = $modx->config['password']; | |
$db_host = $modx->config['host']; | |
if(empty($db_name) || empty($db_user) || empty($db_pass)) { | |
doLog('Database name, user and/or password unknown.. Please check it out!'); | |
die(); | |
} | |
//Dump database file into MODX Core Export path (don't run when client is local or when told to in $_GET) | |
if(!isset($_GET['skipDump']) && $_SERVER['REMOTE_ADDR'] != '127.0.0.1') { | |
$exportPath = MODX_CORE_PATH.'export/sql/'; | |
if(!file_exists($exportPath)) { | |
`mkdir -p $exportPath`; | |
} | |
$backupPath = $exportPath.'dump.'.date('YmdHis').'.sql'; | |
`mysqldump -h $db_host --user=$db_user --password=$db_pass $db_name > $backupPath`; | |
doLog('Dumped database to '.$backupPath); | |
} | |
// define changesets path | |
$changesPath = dirname(__FILE__).'/changesets/'; | |
//Apply changes, starting after previous change | |
/** @var modSystemSetting $changeIndex */ | |
$changeIdxSetting = $modx->getObject('modSystemSetting', array('key' => 'git.pull_change_index')); | |
if(empty($changeIdxSetting) || !is_object($changeIdxSetting)) { | |
$changeIdxSetting = $modx->newObject('modSystemSetting'); | |
$changeIdxSetting->set('key', 'git.pull_change_index'); | |
$changeIdxSetting->set('value', '1'); | |
} | |
$changeIdx = isset($_GET['resetChangeIdx']) ? (int)$_GET['resetChangeIdx'] : (int) $changeIdxSetting->get('value'); //useful when doing initial dev without other environments like testing/production | |
while(isChangeSet($changeIdx)) { | |
//SQL before PHP changes | |
$pre_sql_file = $changesPath.'/'.$changeIdx.'/pre.sql'; | |
if(file_exists($pre_sql_file)) { | |
doLog('Running pe-SQL for changeset '.$changeIdx); | |
$error = `mysql -u $db_user --password=$db_pass -h $db_host $db_name < $pre_sql_file`; | |
if(!empty($error)) { doLog('pre-SQL Error: '.$error, modX::LOG_LEVEL_ERROR); } | |
} | |
//PHP changes (MODX API) | |
$php_file = $changesPath.'/'.$changeIdx.'/changes.php'; | |
if(file_exists($php_file)) { | |
doLog('Running PHP changeset '.$changeIdx); | |
include_once($php_file); | |
} | |
//SQL after PHP changes | |
$post_sql_file = $changesPath.'/'.$changeIdx.'/post.sql'; | |
if(file_exists($post_sql_file)) { | |
doLog('Running post-SQL for changeset '.$changeIdx); | |
$error = `mysql -u $db_user --password=$db_pass -h $db_host $db_name < $post_sql_file`; | |
if(!empty($error)) { doLog('post-SQL Error: '.$error, modX::LOG_LEVEL_ERROR); } | |
} | |
//Update index | |
$changeIdx++; | |
} | |
// Store index for next run | |
$changeIdxSetting->set('value', $changeIdx); | |
$changeIdxSetting->save(); | |
// Clear cache | |
doLog('Clearing cache'); | |
$modx->cacheManager->refresh(); | |
$modx->invokeEvent('OnSiteRefresh'); | |
doLog('Finished pulling new changes'); | |
/** | |
* Check if $idx is an existing changeset (either has a php or sql file) | |
* @param $idx The set index to check agains | |
* @return bool | |
*/ | |
function isChangeSet($idx) { | |
global $changesPath; | |
$path = $changesPath.$idx.'/'; | |
if(file_exists($path.'pre.sql') || file_exists($path.'changes.php') || file_exists($path.'post.sql')) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* modX::log wrapper to set target options once | |
* @param $level | |
* @param $msg | |
*/ | |
function doLog($msg, $level=modX::LOG_LEVEL_INFO) { | |
global $modx; | |
$targetOptions = array( | |
'target' => 'FILE', | |
'options' => array( | |
'filepath' => dirname(__FILE__).'/', | |
'filename' => 'pull.log', | |
) | |
); | |
return $modx->log($level, $msg, $targetOptions); | |
} | |
//prevent errors when using APC cache | |
session_write_close(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment