Index: civicrm/trunk/sites/all/modules/civicrm/drush/civicrm.drush.inc |
— | — | @@ -0,0 +1,725 @@ |
| 2 | +<?php |
| 3 | +/* |
| 4 | + +--------------------------------------------------------------------+ |
| 5 | + | CiviCRM version 3.1 | |
| 6 | + +--------------------------------------------------------------------+ |
| 7 | + | Copyright CiviCRM LLC (c) 2004-2010 | |
| 8 | + +--------------------------------------------------------------------+ |
| 9 | + | This file is a part of CiviCRM. | |
| 10 | + | | |
| 11 | + | CiviCRM is free software; you can copy, modify, and distribute it | |
| 12 | + | under the terms of the GNU Affero General Public License | |
| 13 | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | |
| 14 | + | | |
| 15 | + | CiviCRM is distributed in the hope that it will be useful, but | |
| 16 | + | WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 17 | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| 18 | + | See the GNU Affero General Public License for more details. | |
| 19 | + | | |
| 20 | + | You should have received a copy of the GNU Affero General Public | |
| 21 | + | License and the CiviCRM Licensing Exception along | |
| 22 | + | with this program; if not, contact CiviCRM LLC | |
| 23 | + | at info[AT]civicrm[DOT]org. If you have questions about the | |
| 24 | + | GNU Affero General Public License or the licensing of CiviCRM, | |
| 25 | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | |
| 26 | + +--------------------------------------------------------------------+ |
| 27 | +*/ |
| 28 | + |
| 29 | +/** |
| 30 | + * |
| 31 | + * @package CRM |
| 32 | + * @copyright CiviCRM LLC (c) 2004-2010 |
| 33 | + * $Id$ |
| 34 | + * |
| 35 | + */ |
| 36 | + |
| 37 | +// $Id: example.drush.inc,v 1.5 2009/09/30 13:15:54 weitzman Exp $ |
| 38 | + |
| 39 | +/** |
| 40 | + * @file |
| 41 | + * Example drush command. |
| 42 | + * |
| 43 | + * Shows how to make your own drush command. |
| 44 | + * |
| 45 | + * You can copy this file to any of the following |
| 46 | + * 1. A .drush folder in your HOME folder. |
| 47 | + * 2. Anywhere in a folder tree below an active module on your site. |
| 48 | + * 3. In an arbitrary folder specified with the --include option. |
| 49 | + */ |
| 50 | + |
| 51 | +/** |
| 52 | + * Implementation of hook_drush_command(). |
| 53 | + * |
| 54 | + * In this hook, you specify which commands your |
| 55 | + * drush module makes available, what it does and |
| 56 | + * description. |
| 57 | + * |
| 58 | + * Notice how this structure closely resembles how |
| 59 | + * you define menu hooks. |
| 60 | + * |
| 61 | + * @See drush_parse_command() for a list of recognized keys. |
| 62 | + * |
| 63 | + * @return |
| 64 | + * An associative array describing your command(s). |
| 65 | + */ |
| 66 | +function civicrm_drush_command() { |
| 67 | + $items = array(); |
| 68 | + |
| 69 | + // the key in the $items array is the name of the command. |
| 70 | + $items['civicrm-install'] = |
| 71 | + array('callback' => 'civicrm_pkg_install', |
| 72 | + 'description' => "Install a new instance of CiviCRM.", |
| 73 | + 'options' => |
| 74 | + array('--dbuser' => 'MySQL username for your Drupal/CiviCRM database.', |
| 75 | + '--dbpass' => 'MySQL password for your Drupal/CiviCRM database.', |
| 76 | + '--dbhost' => 'MySQL host for your Drupal/CiviCRM database. Defaults to localhost.', |
| 77 | + '--dbname' => 'MySQL database name of your Drupal/CiviCRM database.', |
| 78 | + '--tarfile' => 'Path to your CiviCRM tar.gz file.', |
| 79 | + ), |
| 80 | + ); |
| 81 | + $items['civicrm-upgrade-db'] = |
| 82 | + array('callback' => 'civicrm_upgrade_db', |
| 83 | + 'description' => "Execute the civicrm/upgrade?reset=1 process from the command line.", |
| 84 | + ); |
| 85 | + $items['civicrm-update-cfg'] = |
| 86 | + array('callback' => 'civicrm_config_update', |
| 87 | + 'description' => "Update config_backend to correct config settings, especially when the CiviCRM site has been cloned / migrated.", |
| 88 | + 'examples' => |
| 89 | + array('drush -l http://example.com/civicrm civicrm-update-cfg' => |
| 90 | + 'Update config_backend to correct config settings for civicrm installation on example.com site.', |
| 91 | + ), |
| 92 | + ); |
| 93 | + $items['civicrm-cache-clear'] = |
| 94 | + array('callback' => 'civicrm_cache_clear', |
| 95 | + 'description' => "Clear all CiviCRM database and smarty caches.", |
| 96 | + ); |
| 97 | + $items['civicrm-upgrade'] = |
| 98 | + array('callback' => 'civicrm_upgrade', |
| 99 | + 'description' => "Replace CiviCRM codebase with new specified tarfile and upgrade database by executing the CiviCRM upgrade process - civicrm/upgrade?reset=1.", |
| 100 | + 'examples' => |
| 101 | + array('drush civicrm-upgrade --tarfile=~/tarballs/civicrm-3.1.4-drupal.tar.gz' => |
| 102 | + 'Replace old CiviCRM codebase with new v3.1.4 and run upgrade process.', |
| 103 | + ), |
| 104 | + 'options' => |
| 105 | + array('--tarfile' => |
| 106 | + 'Path of new CiviCRM tarfile, with which current CiviCRM codebase is to be replaced.', |
| 107 | + '--backup-dir' => |
| 108 | + 'Specify a directory to backup current CiviCRM codebase and database into, defaults to a backup directory above your Drupal root.' |
| 109 | + ), |
| 110 | + ); |
| 111 | + $items['civicrm-restore'] = |
| 112 | + array('callback' => 'civicrm_restore', |
| 113 | + 'description' => 'Restore CiviCRM codebase and database back from the specified backup directory.', |
| 114 | + 'examples' => |
| 115 | + array('drush civicrm-restore --restore-dir=../backup/modules/20100309200249' => |
| 116 | + 'Replace current civicrm codebase with the $restore-dir/civicrm codebase, and reload the database with $restore-dir/civicrm.sql file', |
| 117 | + ), |
| 118 | + 'options' => |
| 119 | + array('--restore-dir' => |
| 120 | + 'Path of directory having backed up CiviCRM codebase and database.', |
| 121 | + '--backup-dir' => |
| 122 | + 'Specify a directory to backup current CiviCRM codebase and database into, defaults to a backup directory above your Drupal root.' |
| 123 | + ), |
| 124 | + ); |
| 125 | + $items['civicrm-rest'] = |
| 126 | + array('callback' => 'civicrm_rest', |
| 127 | + 'description' => "Rest interface for accessing CiviCRM APIs. It can return xml or json formatted data.", |
| 128 | + 'examples' => |
| 129 | + array("drush civicrm-rest --query='civicrm/contact/search&json=1&key=7decb879f28ac4a0c6a92f0f7889a0c9&api_key=7decb879f28ac4a0c6a92f0f7889a0c9'" => |
| 130 | + 'Use contact search api to return data in json format.', |
| 131 | + ), |
| 132 | + 'options' => |
| 133 | + array('--query' => 'Query part of url. Refer CiviCRM wiki doc for more details.'), |
| 134 | + ); |
| 135 | + $items['civicrm-sql-conf'] = |
| 136 | + array('callback' => 'civicrm_sql_conf', |
| 137 | + 'description' => 'Print CiviCRM database connection details.', |
| 138 | + ); |
| 139 | + $items['civicrm-sql-connect'] = |
| 140 | + array('callback' => 'civicrm_sql_connect', |
| 141 | + 'description' => 'A string for connecting to the CiviCRM DB.', |
| 142 | + ); |
| 143 | + $items['civicrm-sql-dump'] = |
| 144 | + array('callback' => 'civicrm_sql_dump', |
| 145 | + 'description' => 'Exports the CiviCRM DB as SQL using mysqldump.', |
| 146 | + 'examples' => |
| 147 | + array('drush civicrm-sql-dump --result-file=../CiviCRM.sql' => |
| 148 | + 'Save SQL dump to the directory above Drupal root.', |
| 149 | + ), |
| 150 | + 'options' => |
| 151 | + array('--result-file' => 'Save to a file.'), |
| 152 | + ); |
| 153 | + $items['civicrm-sql-query'] = |
| 154 | + array('callback' => 'civicrm_sql_query', |
| 155 | + 'description' => 'Execute a query against the CiviCRM database.', |
| 156 | + 'examples' => |
| 157 | + array('drush civicrm-sql-query "SELECT * FROM civicrm_contact WHERE id=1"' => |
| 158 | + 'Browse user record', |
| 159 | + ), |
| 160 | + 'arguments' => |
| 161 | + array('query' => 'A SQL query. Mandatory.', |
| 162 | + ), |
| 163 | + ); |
| 164 | + $items['civicrm-sql-cli'] = |
| 165 | + array('callback' => 'civicrm_sql_cli', |
| 166 | + 'description' => "Open a SQL command-line interface using CiviCRM's credentials.", |
| 167 | + ); |
| 168 | + |
| 169 | + return $items; |
| 170 | +} |
| 171 | + |
| 172 | +function civicrm_pkg_install( ) { |
| 173 | + if ( !$dbuser = drush_get_option('dbuser', false) ) { |
| 174 | + drush_die(dt('CiviCRM database username not specified.')); |
| 175 | + } |
| 176 | + if ( !$dbpass = drush_get_option('dbpass', false) ) { |
| 177 | + drush_die(dt('CiviCRM database password not specified.')); |
| 178 | + } |
| 179 | + if ( !$dbhost = drush_get_option('dbhost', false) ) { |
| 180 | + drush_die(dt('CiviCRM database host not specified.')); |
| 181 | + } |
| 182 | + if ( !$dbname = drush_get_option('dbname', false) ) { |
| 183 | + drush_die(dt('CiviCRM database name not specified.')); |
| 184 | + } |
| 185 | + $drupalRoot = drush_get_context('DRUSH_DRUPAL_ROOT'); |
| 186 | + $siteRoot = drush_get_context('DRUSH_DRUPAL_SITE_ROOT', FALSE); |
| 187 | + $modPath = "$drupalRoot/$siteRoot/modules"; |
| 188 | + |
| 189 | + if ( !is_dir( "$modPath/civicrm" ) ) { |
| 190 | + // extract tarfile at right place |
| 191 | + _civicrm_extract_tarfile( $modPath ); |
| 192 | + |
| 193 | + // include civicrm installer helper file |
| 194 | + $civicrmInstallerHelper = "$drupalRoot/$siteRoot/modules/civicrm/install/civicrm.php"; |
| 195 | + if ( !file_exists($civicrmInstallerHelper) ) { |
| 196 | + drush_die(dt("Tarfile could not be unpacked OR CiviCRM installer helper file is missing.")); |
| 197 | + } |
| 198 | + drush_log(dt("Tarfile unpacked."), 'ok'); |
| 199 | + |
| 200 | + // setup all required files/civicrm/* directories |
| 201 | + _civicrm_create_files_dirs( ); |
| 202 | + |
| 203 | + // install database |
| 204 | + //_civicrm_install_db($dbuser, $dbpass, $dbhost, $dbname); |
| 205 | + |
| 206 | + // generate civicrm.settings.php file |
| 207 | + _civicrm_generate_settings_file($dbuser, $dbpass, $dbhost, $dbname); |
| 208 | + |
| 209 | + module_enable(array('CiviCRM')); |
| 210 | + |
| 211 | + drush_log(dt("CiviCRM installed."), 'ok'); |
| 212 | + } else { |
| 213 | + drush_log(dt("Existing CiviCRM found. No action taken."), 'ok'); |
| 214 | + } |
| 215 | +} |
| 216 | + |
| 217 | +function _civicrm_extract_tarfile( $destinationPath, $option = 'tarfile' ) { |
| 218 | + if ( !$tarfile = drush_get_option($option, false) ) { |
| 219 | + drush_die(dt('CiviCRM tarfile not specified.')); |
| 220 | + } |
| 221 | + $tarpath = $tarfile; |
| 222 | + if ( drush_shell_exec("gzip -d " . $tarfile) ) { |
| 223 | + $tarpath = substr($tarfile, 0, strlen($tarfile)-3); |
| 224 | + } |
| 225 | + drush_shell_exec("tar -xf $tarpath -C \"$destinationPath\""); |
| 226 | +} |
| 227 | + |
| 228 | +function _civicrm_install_db( $dbuser, $dbpass, $dbhost, $dbname ) { |
| 229 | + $drupalRoot = drush_get_context('DRUSH_DRUPAL_ROOT'); |
| 230 | + $siteRoot = drush_get_context('DRUSH_DRUPAL_SITE_ROOT', FALSE); |
| 231 | + $sqlPath = "$drupalRoot/$siteRoot/modules/civicrm/sql"; |
| 232 | + |
| 233 | + $conn = @mysql_connect($dbhost, $dbuser, $dbpass); |
| 234 | + if( !@mysql_select_db($dbname) && |
| 235 | + !@mysql_query("CREATE DATABASE $database") ) { |
| 236 | + drush_die(dt('CiviCRM database was not found. Failed to create one.')); |
| 237 | + } |
| 238 | + |
| 239 | + // setup database with civicrm structure and data |
| 240 | + $dsn = "mysql://{$dbuser}:{$dbpass}@{$dbhost}/{$dbname}?new_link=true"; |
| 241 | + drush_print(dt("Loading CiviCRM database structure ..")); |
| 242 | + civicrm_source($dsn, $sqlPath . '/civicrm.mysql' ); |
| 243 | + drush_print(dt("Loading CiviCRM database with required data ..")); |
| 244 | + civicrm_source($dsn, $sqlPath . '/civicrm_data.mysql'); |
| 245 | + civicrm_source($dsn, $sqlPath . '/civicrm_acl.mysql' ); |
| 246 | + drush_log(dt("CiviCRM database loaded successfully."), 'ok'); |
| 247 | +} |
| 248 | + |
| 249 | +function _civicrm_create_files_dirs( ) { |
| 250 | + $drupalRoot = drush_get_context('DRUSH_DRUPAL_ROOT' ); |
| 251 | + $siteRoot = drush_get_context('DRUSH_DRUPAL_SITE_ROOT', FALSE ); |
| 252 | + |
| 253 | + // include civicrm installer helper file |
| 254 | + $civicrmInstallerHelper = "$drupalRoot/$siteRoot/modules/civicrm/install/civicrm.php"; |
| 255 | + if ( !file_exists($civicrmInstallerHelper) ) { |
| 256 | + drush_die(dt("CiviCRM installer helper file is missing.")); |
| 257 | + } |
| 258 | + require_once "$civicrmInstallerHelper"; |
| 259 | + |
| 260 | + // create files/civicrm/* dirs |
| 261 | + global $crmPath; |
| 262 | + $crmPath = "$drupalRoot/$siteRoot/modules/civicrm"; |
| 263 | + civicrm_setup("$drupalRoot/$siteRoot/files"); |
| 264 | +} |
| 265 | + |
| 266 | +// generates civicrm.settings.php file |
| 267 | +function _civicrm_generate_settings_file( $dbuser, $dbpass, $dbhost, $dbname ) { |
| 268 | + $drupalRoot = drush_get_context('DRUSH_DRUPAL_ROOT'); |
| 269 | + $siteRoot = drush_get_context('DRUSH_DRUPAL_SITE_ROOT', FALSE); |
| 270 | + $crmPath = "$drupalRoot/$siteRoot/modules/civicrm"; |
| 271 | + |
| 272 | + $settingsTplFile = "$crmPath/templates/CRM/common/civicrm.settings.php.tpl"; |
| 273 | + if ( !file_exists($settingsTplFile) ) { |
| 274 | + drush_die(dt("Could not find CiviCRM settings template and therefore could not create settings file.")); |
| 275 | + } |
| 276 | + |
| 277 | + drush_print(dt("Generating civicrm settings file ..")); |
| 278 | + $baseUrl = drush_get_option('site_url', false); |
| 279 | + $baseUrl = !$baseUrl ? ($GLOBALS['base_url']) : ('http://' . $baseUrl); |
| 280 | + |
| 281 | + $db_spec = _drush_sql_get_db_spec(); |
| 282 | + $params = array( |
| 283 | + 'crmRoot' => $crmPath, |
| 284 | + 'templateCompileDir' => "$drupalRoot/$siteRoot/files/civicrm/templates_c", |
| 285 | + 'frontEnd' => 0, |
| 286 | + 'cms' => 'Drupal', |
| 287 | + 'baseURL' => $baseUrl, |
| 288 | + 'dbUser' => $dbuser, |
| 289 | + 'dbPass' => $dbpass, |
| 290 | + 'dbHost' => $dbhost, |
| 291 | + 'dbName' => $dbname, |
| 292 | + 'CMSdbUser' => $db_spec['username'], |
| 293 | + 'CMSdbPass' => $db_spec['password'], |
| 294 | + 'CMSdbHost' => $db_spec['host'], |
| 295 | + 'CMSdbName' => $db_spec['database'], |
| 296 | + ); |
| 297 | + $str = file_get_contents( $settingsTplFile ); |
| 298 | + foreach ( $params as $key => $value ) { |
| 299 | + $str = str_replace( '%%' . $key . '%%', $value, $str ); |
| 300 | + } |
| 301 | + $str = trim( $str ); |
| 302 | + |
| 303 | + $configFile = "$drupalRoot/$siteRoot/civicrm.settings.php"; |
| 304 | + civicrm_write_file( $configFile, $str ); |
| 305 | + drush_log(dt("Settings file generated."), 'ok'); |
| 306 | +} |
| 307 | + |
| 308 | +/** |
| 309 | + * Implementation of hook_drush_help(). |
| 310 | + * |
| 311 | + * This function is called whenever a drush user calls |
| 312 | + * 'drush help <name-of-your-command>' |
| 313 | + * |
| 314 | + * @param |
| 315 | + * A string with the help section (prepend with 'drush:') |
| 316 | + * |
| 317 | + * @return |
| 318 | + * A string with the help text for your command. |
| 319 | + */ |
| 320 | +function civicrm_drush_help($section) { |
| 321 | + switch ($section) { |
| 322 | + case 'drush:civicrm-upgrade-db': |
| 323 | + return dt("Run civicrm/upgrade?reset=1 just as a web browser would."); |
| 324 | + case 'drush:civicrm-update-cfg': |
| 325 | + return dt("Update config_backend to correct config settings, especially when the CiviCRM site has been cloned / migrated."); |
| 326 | + case 'drush:civicrm-cache-clear': |
| 327 | + return dt("Clear all CiviCRM database and smarty caches."); |
| 328 | + case 'drush:civicrm-upgrade': |
| 329 | + return dt("Take backups, replace CiviCRM codebase with new specified tarfile and upgrade database by executing the CiviCRM upgrade process - civicrm/upgrade?reset=1. Use civicrm-restore to revert to previous state in case anything goes wrong."); |
| 330 | + case 'drush:civicrm-restore': |
| 331 | + return dt("Restore CiviCRM codebase and database back from the specified backup directory."); |
| 332 | + case 'drush:civicrm-rest': |
| 333 | + return dt("Rest interface for accessing CiviCRM APIs. It can return xml or json formatted data."); |
| 334 | + case 'drush:civicrm-sql-conf': |
| 335 | + return dt('Show civicrm database connection details.'); |
| 336 | + case 'drush:civicrm-sql-connect': |
| 337 | + return dt('A string which connects to the civicrm database.'); |
| 338 | + case 'drush:civicrm-sql-cli': |
| 339 | + return dt('Quickly enter the mysql command line.'); |
| 340 | + case 'drush:civicrm-sql-dump': |
| 341 | + return dt('Prints the whole CiviCRM database to STDOUT or save to a file.'); |
| 342 | + case 'drush:civicrm-sql-query': |
| 343 | + return dt("Usage: drush [options] civicrm-sql-query <query>...\n<query> is a SQL statement, which can alternatively be passed via STDIN. Any additional arguments are passed to the mysql command directly."); |
| 344 | + } |
| 345 | +} |
| 346 | + |
| 347 | +/** |
| 348 | + * Example drush command callback. |
| 349 | + * |
| 350 | + * This is where the action takes place. |
| 351 | + * |
| 352 | + * In this function, all of Drupals API is (usually) available, including |
| 353 | + * any functions you have added in your own modules/themes. |
| 354 | + * |
| 355 | + * To print something to the terminal window, use drush_print(). |
| 356 | + * |
| 357 | + */ |
| 358 | +function civicrm_upgrade_db() { |
| 359 | + _civicrm_init(); |
| 360 | + |
| 361 | + require_once 'CRM/Core/Config.php'; |
| 362 | + require_once 'CRM/Core/Smarty.php'; |
| 363 | + $template =& CRM_Core_Smarty::singleton( ); |
| 364 | + |
| 365 | + require_once 'CRM/Utils/System.php'; |
| 366 | + require_once 'CRM/Core/BAO/Domain.php'; |
| 367 | + $codeVer = CRM_Utils_System::version(); |
| 368 | + $dbVer = CRM_Core_BAO_Domain::version(); |
| 369 | + if ( !$dbVer ) { |
| 370 | + drush_die(dt('Version information missing in civicrm database.')); |
| 371 | + } else if ( stripos($dbVer, 'upgrade') ) { |
| 372 | + drush_die(dt('Database check failed - the database looks to have been partially upgraded. You may want to reload the database with the backup and try the upgrade process again.')); |
| 373 | + } else if ( !$codeVer ) { |
| 374 | + drush_die(dt('Version information missing in civicrm codebase.')); |
| 375 | + } else if ( version_compare($codeVer, $dbVer) > 0 ) { |
| 376 | + drush_print(dt("Starting with v!dbVer -> v!codeVer upgrade ..", |
| 377 | + array('!dbVer' => $dbVer, '!codeVer' => $codeVer))); |
| 378 | + } else if ( version_compare($codeVer, $dbVer) < 0 ) { |
| 379 | + drush_die(dt("Database is marked with an unexpected version '!dbVer' which is higher than that of codebase version '!codeVer'.", array('!dbVer' => $dbVer, '!codeVer' => $codeVer))); |
| 380 | + } else { |
| 381 | + drush_print(dt("Starting with upgrade ..")); |
| 382 | + } |
| 383 | + |
| 384 | + $_POST['upgrade'] = 1; |
| 385 | + require_once( 'CRM/Upgrade/Page/Upgrade.php' ); |
| 386 | + $upgrade =& new CRM_Upgrade_Page_Upgrade( ); |
| 387 | + ob_start(); // to suppress html output /w source code. |
| 388 | + $upgrade->run( ); |
| 389 | + $result = $template->get_template_vars('message'); // capture the required message. |
| 390 | + ob_end_clean(); |
| 391 | + drush_print("Upgrade outputs: " . "\"$result\""); |
| 392 | +} |
| 393 | + |
| 394 | +function civicrm_config_update() { |
| 395 | + _civicrm_init(); |
| 396 | + |
| 397 | + $defaultValues = array( ); |
| 398 | + $states = array( 'old', 'new' ); |
| 399 | + for ( $i = 1 ; $i <= 3; $i++ ) { |
| 400 | + foreach ( $states as $state ) { |
| 401 | + $name = "{$state}Val_{$i}"; |
| 402 | + $value = drush_get_option( $name, null ); |
| 403 | + if ( $value ) { |
| 404 | + $defaultValues[$name] = $value; |
| 405 | + } |
| 406 | + } |
| 407 | + } |
| 408 | + |
| 409 | + require_once 'CRM/Core/I18n.php'; |
| 410 | + require_once 'CRM/Core/BAO/Setting.php'; |
| 411 | + $result = CRM_Core_BAO_Setting::doSiteMove( $defaultValues ); |
| 412 | + |
| 413 | + if ( $result ) |
| 414 | + drush_log(dt('Config successfully updated.'), 'completed'); |
| 415 | + else |
| 416 | + drush_log(dt('Config update failed.'), 'failed'); |
| 417 | +} |
| 418 | + |
| 419 | +function civicrm_cache_clear() { |
| 420 | + _civicrm_init(); |
| 421 | + |
| 422 | + require_once 'CRM/Core/Config.php'; |
| 423 | + $config = CRM_Core_Config::singleton( ); |
| 424 | + |
| 425 | + // clear db caching |
| 426 | + $config->clearDBCache( ); |
| 427 | + |
| 428 | + // also cleanup the templates_c directory |
| 429 | + $config =& CRM_Core_Config::singleton( ); |
| 430 | + $config->cleanup( 1 , false ); |
| 431 | + |
| 432 | + drush_log(dt('Cache cleared.'), 'ok'); |
| 433 | +} |
| 434 | + |
| 435 | +function civicrm_upgrade() { |
| 436 | + $tarfile = drush_get_option('tarfile', false); |
| 437 | + if ( !$tarfile ) { |
| 438 | + drush_die(dt('Tarfile not specified.')); |
| 439 | + } |
| 440 | + //FIXME: throw error if tarfile is not in a valid format. |
| 441 | + |
| 442 | + _civicrm_init(); |
| 443 | + |
| 444 | + global $civicrm_root; |
| 445 | + |
| 446 | + $date = date('YmdHis'); |
| 447 | + $backup_file = "civicrm"; |
| 448 | + |
| 449 | + $basepath = explode('/', $civicrm_root); |
| 450 | + array_pop($basepath); |
| 451 | + $project_path = implode('/', $basepath). '/'; |
| 452 | + |
| 453 | + $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT'); |
| 454 | + $backup_dir = drush_get_option('backup-dir', $drupal_root . '/../backup'); |
| 455 | + $backup_dir = rtrim($backup_dir, '/'); |
| 456 | + |
| 457 | + drush_print(dt("\nThe upgrade process involves - ")); |
| 458 | + drush_print(dt("1. Backing up current CiviCRM code as => !path", |
| 459 | + array('!path' => "$backup_dir/modules/$date/$backup_file"))); |
| 460 | + drush_print(dt("2. Backing up database as => !path", |
| 461 | + array('!path' => "$backup_dir/modules/$date/$backup_file.sql"))); |
| 462 | + drush_print(dt("3. Unpacking tarfile to => !path", |
| 463 | + array('!path' => "$project_path"))); |
| 464 | + drush_print(dt("4. Executing civicrm/upgrade?reset=1 just as a browser would.\n")); |
| 465 | + if( !drush_confirm(dt('Do you really want to continue?')) ) { |
| 466 | + drush_die('Aborting.'); |
| 467 | + } |
| 468 | + |
| 469 | + @drush_op('mkdir', $backup_dir, 0777); |
| 470 | + $backup_dir .= '/modules'; |
| 471 | + @drush_op('mkdir', $backup_dir, 0777); |
| 472 | + $backup_dir .= "/$date"; |
| 473 | + @drush_op('mkdir', $backup_dir, 0777); |
| 474 | + $backup_target = $backup_dir . '/'. $backup_file; |
| 475 | + if (!drush_op('rename', $civicrm_root, $backup_target)) { |
| 476 | + drush_die(dt('Failed to backup CiviCRM project directory !source to !backup_target', |
| 477 | + array('!source' => $civicrm_root, '!backup_target' => $backup_target))); |
| 478 | + } |
| 479 | + drush_log(dt("\n1. Code backed up."), 'ok'); |
| 480 | + |
| 481 | + drush_set_option('result-file', $backup_target . '.sql'); |
| 482 | + civicrm_sql_dump(); |
| 483 | + drush_log(dt('2. Database backed up.'), 'ok'); |
| 484 | + |
| 485 | + // Decompress |
| 486 | + drush_shell_exec("gzip -d " . $tarfile); |
| 487 | + $tarpath = substr($tarfile, 0, strlen($tarfile)-3); |
| 488 | + // Untar |
| 489 | + drush_shell_exec("tar -xf $tarpath -C \"$project_path\""); |
| 490 | + // drush: not using tar -xzf because that's not working on windows... |
| 491 | + drush_log(dt('3. Tarfile unpacked.'), 'ok'); |
| 492 | + |
| 493 | + drush_print(dt("4. ")); |
| 494 | + civicrm_upgrade_db(); |
| 495 | + drush_log(dt("\nProcess completed."), 'completed'); |
| 496 | +} |
| 497 | + |
| 498 | +function civicrm_restore() { |
| 499 | + _civicrm_dsn_init(); |
| 500 | + |
| 501 | + $restore_dir = drush_get_option('restore-dir', false); |
| 502 | + $restore_dir = rtrim($restore_dir, '/'); |
| 503 | + if ( !$restore_dir ) { |
| 504 | + drush_die(dt('restore-dir not specified.')); |
| 505 | + } |
| 506 | + $sql_file = $restore_dir . '/civicrm.sql'; |
| 507 | + if ( !file_exists($sql_file) ) { |
| 508 | + drush_die(dt('Could not locate civicrm.sql file in the restore directory.')); |
| 509 | + } |
| 510 | + $code_dir = $restore_dir . '/civicrm'; |
| 511 | + if ( !is_dir($code_dir) ) { |
| 512 | + drush_die(dt('Could not locate civicrm directory inside restore-dir.')); |
| 513 | + } else if ( !file_exists("$code_dir/civicrm-version.txt") ) { |
| 514 | + drush_die(dt('civicrm directory inside restore-dir, doesn\'t look to be a valid civicrm codebase.')); |
| 515 | + } |
| 516 | + |
| 517 | + $date = date('YmdHis'); |
| 518 | + |
| 519 | + global $civicrm_root; |
| 520 | + $civicrm_root_base = explode('/', $civicrm_root); |
| 521 | + array_pop($civicrm_root_base); |
| 522 | + $civicrm_root_base = implode('/', $civicrm_root_base). '/'; |
| 523 | + |
| 524 | + $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT'); |
| 525 | + $restore_backup_dir = drush_get_option('backup-dir', $drupal_root . '/../backup'); |
| 526 | + $restore_backup_dir = rtrim($restore_backup_dir, '/'); |
| 527 | + |
| 528 | + // get confirmation from user - |
| 529 | + $db_spec = _drush_sql_get_db_spec(); |
| 530 | + drush_print(dt("\nProcess involves :")); |
| 531 | + drush_print(dt("1. Restoring '\$restore-dir/civicrm' directory to '!toDir'.", array('!toDir' => $civicrm_root_base))); |
| 532 | + drush_print(dt("2. Dropping and creating '!db' database.", array('!db' => $db_spec['database']))); |
| 533 | + drush_print(dt("3. Loading '\$restore-dir/civicrm.sql' file into the database.")); |
| 534 | + drush_print(); |
| 535 | + drush_print(dt("Note: Before restoring a backup will be taken in '!path' directory.", |
| 536 | + array('!path' => "$restore_backup_dir/modules/restore"))); |
| 537 | + drush_print(); |
| 538 | + if( !drush_confirm(dt('Do you really want to continue?')) ) { |
| 539 | + drush_die('Aborting.'); |
| 540 | + } |
| 541 | + |
| 542 | + // create restore-backup-dir if not already exists |
| 543 | + @drush_op('mkdir', $restore_backup_dir, 0777); |
| 544 | + $restore_backup_dir .= '/modules'; |
| 545 | + @drush_op('mkdir', $restore_backup_dir, 0777); |
| 546 | + $restore_backup_dir .= '/restore'; |
| 547 | + @drush_op('mkdir', $restore_backup_dir, 0777); |
| 548 | + $restore_backup_dir .= "/$date"; |
| 549 | + @drush_op('mkdir', $restore_backup_dir, 0777); |
| 550 | + |
| 551 | + // 1. backup and restore codebase |
| 552 | + drush_print(dt('Restoring civicrm codebase ..')); |
| 553 | + if (is_dir($civicrm_root) && !drush_op('rename', $civicrm_root, $restore_backup_dir . '/civicrm')) { |
| 554 | + drush_die(dt("Failed to take backup for '!destination' directory", |
| 555 | + array('!destination' => $civicrm_root))); |
| 556 | + } |
| 557 | + if (!drush_op('rename', $code_dir, $civicrm_root)) { |
| 558 | + drush_die(dt("Failed to restore civicrm directory '!source' to '!dest'", |
| 559 | + array('!source' => $code_dir, '!dest' => $civicrm_root_base))); |
| 560 | + } |
| 561 | + drush_log(dt('Codebase restored.'), 'ok'); |
| 562 | + |
| 563 | + // 2. backup, drop and create database |
| 564 | + drush_set_option('result-file', $restore_backup_dir . '/civicrm.sql'); |
| 565 | + civicrm_sql_dump(); |
| 566 | + _civicrm_dsn_init();// reinitialize dsn |
| 567 | + |
| 568 | + drush_log(dt('Database backed up.'), 'ok'); |
| 569 | + |
| 570 | + $exec = 'mysql' . _drush_sql_get_credentials() . ' -e '; |
| 571 | + drush_print(dt("\nDropping database '!db' ..", array('!db' => $db_spec['database']))); |
| 572 | + if (drush_op('system', $exec . '"DROP DATABASE IF EXISTS ' . $db_spec['database'] . '"')) { |
| 573 | + drush_set_error(dt('Could not drop database: @name', array('@name' => $db_spec['database']))); |
| 574 | + return; |
| 575 | + } |
| 576 | + drush_log(dt('Database dropped.'), 'ok'); |
| 577 | + $exec = str_replace($db_spec['database'], '', $exec); |
| 578 | + if (drush_op('system', $exec . '"CREATE DATABASE ' . $db_spec['database'] . '"')) { |
| 579 | + drush_set_error(dt('Could not create new database: @name', array('@name' => $db_spec['database']))); |
| 580 | + return; |
| 581 | + } |
| 582 | + drush_log(dt('Database created.'), 'ok'); |
| 583 | + |
| 584 | + // 3. restore database |
| 585 | + switch (_drush_sql_get_scheme()) { |
| 586 | + case 'mysql': |
| 587 | + $send = 'mysql' . _drush_sql_get_credentials(); |
| 588 | + break; |
| 589 | + case 'pgsql': |
| 590 | + $send .= 'psql -d ' . _drush_sql_get_credentials() . ' --file -'; |
| 591 | + break; |
| 592 | + } |
| 593 | + $exec = "$send < $sql_file"; |
| 594 | + drush_print(dt('Loading civicrm.sql file from restore-dir ..')); |
| 595 | + drush_op('system', $exec); |
| 596 | + drush_log(dt('Database restored.'), 'ok'); |
| 597 | + |
| 598 | + drush_log(dt('Restore process completed.'), 'completed'); |
| 599 | + |
| 600 | + _civicrm_dsn_close(); |
| 601 | +} |
| 602 | + |
| 603 | +function civicrm_rest() { |
| 604 | + _civicrm_init(); |
| 605 | + |
| 606 | + $query = drush_get_option('query', false); |
| 607 | + if ( !$query ) { |
| 608 | + drush_die(dt('query not specified.')); |
| 609 | + } |
| 610 | + $query = explode( '&', $query ); |
| 611 | + $_GET['q'] = array_shift($query); |
| 612 | + foreach ( $query as $keyVal ) { |
| 613 | + list($key, $val) = explode( '=', $keyVal ); |
| 614 | + $_REQUEST[$key] = $val; |
| 615 | + $_GET [$key] = $val; |
| 616 | + } |
| 617 | + |
| 618 | + require_once 'CRM/Utils/REST.php'; |
| 619 | + $rest =& new CRM_Utils_REST(); |
| 620 | + |
| 621 | + require_once 'CRM/Core/Config.php'; |
| 622 | + $config =& CRM_Core_Config::singleton(); |
| 623 | + |
| 624 | + global $civicrm_root; |
| 625 | + // adding dummy script, since based on this api file path is computed. |
| 626 | + $_SERVER['SCRIPT_FILENAME'] = "$civicrm_root/extern/rest.php"; |
| 627 | + |
| 628 | + if ( isset( $_GET['json'] ) && |
| 629 | + $_GET['json'] ) { |
| 630 | + header( 'Content-Type: text/javascript' ); |
| 631 | + } else { |
| 632 | + header( 'Content-Type: text/xml' ); |
| 633 | + } |
| 634 | + echo $rest->run( $config ); |
| 635 | +} |
| 636 | + |
| 637 | +function civicrm_sql_dump() { |
| 638 | + _civicrm_dsn_init(); |
| 639 | + |
| 640 | + drush_sql_dump_execute(); |
| 641 | + |
| 642 | + _civicrm_dsn_close(); |
| 643 | +} |
| 644 | + |
| 645 | +function civicrm_sql_conf() { |
| 646 | + _civicrm_dsn_init(); |
| 647 | + |
| 648 | + drush_sql_conf(); |
| 649 | + |
| 650 | + _civicrm_dsn_close(); |
| 651 | +} |
| 652 | + |
| 653 | +function civicrm_sql_connect() { |
| 654 | + _civicrm_dsn_init(); |
| 655 | + |
| 656 | + drush_sql_connect(); |
| 657 | + |
| 658 | + _civicrm_dsn_close(); |
| 659 | +} |
| 660 | + |
| 661 | +function civicrm_sql_query( $query ) { |
| 662 | + _civicrm_dsn_init(); |
| 663 | + |
| 664 | + drush_sql_query( $query ); |
| 665 | + |
| 666 | + _civicrm_dsn_close(); |
| 667 | +} |
| 668 | + |
| 669 | +function civicrm_sql_cli( ) { |
| 670 | + _civicrm_dsn_init(); |
| 671 | + |
| 672 | + drush_sql_cli(); |
| 673 | + |
| 674 | + _civicrm_dsn_close(); |
| 675 | +} |
| 676 | + |
| 677 | +function _civicrm_dsn_init( $reset = false ) { |
| 678 | + static $globalDbUrl = null; |
| 679 | + |
| 680 | + _civicrm_init(); |
| 681 | + |
| 682 | + if ( !$globalDbUrl && CIVICRM_DSN ) { |
| 683 | + if ( array_key_exists('db_url', $GLOBALS) ) { |
| 684 | + $globalDbUrl = $GLOBALS['db_url']; // keep a copy so that we can put it back. |
| 685 | + } |
| 686 | + // now modify $GLOBALS['db_url'] so that drush works on CIVICRM_DSN instead of drupal's |
| 687 | + $GLOBALS['db_url'] = CIVICRM_DSN; |
| 688 | + } |
| 689 | + $dbUrl = $globalDbUrl; |
| 690 | + $globalDbUrl = $reset ? null : $globalDbUrl; |
| 691 | + |
| 692 | + return $dbUrl; |
| 693 | +} |
| 694 | + |
| 695 | +function _civicrm_dsn_close( ) { |
| 696 | + $globalDbUrl = _civicrm_dsn_init( true ); |
| 697 | + if ( $globalDbUrl ) { |
| 698 | + $GLOBALS['db_url'] = $globalDbUrl; |
| 699 | + } |
| 700 | +} |
| 701 | + |
| 702 | +function _civicrm_init( ) { |
| 703 | + static $init = null; |
| 704 | + |
| 705 | + if ( $init ) return $init; // return if already initialized |
| 706 | + |
| 707 | + $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT'); |
| 708 | + $site_root = drush_get_context('DRUSH_DRUPAL_SITE_ROOT', FALSE); |
| 709 | + $civicrmSettingsFile = "$drupal_root/$site_root/civicrm.settings.php"; |
| 710 | + |
| 711 | + if ( !file_exists( $civicrmSettingsFile ) ) { |
| 712 | + $sites_subdir = drush_get_option('sites-subdir', 'default'); |
| 713 | + $civicrmSettingsFile = "$drupal_root/sites/$sites_subdir/civicrm.settings.php"; |
| 714 | + if ( !file_exists( $civicrmSettingsFile ) ) { |
| 715 | + drush_die(dt("Could not locate civicrm settings file.")); |
| 716 | + } |
| 717 | + } |
| 718 | + include_once $civicrmSettingsFile; // include settings file |
| 719 | + global $civicrm_root; |
| 720 | + if ( ! is_dir($civicrm_root) ) { |
| 721 | + drush_die(dt('Could not locate CiviCRM codebase. Make sure CiviCRM settings file has correct information.')); |
| 722 | + } |
| 723 | + |
| 724 | + $init = true; |
| 725 | + return $init; |
| 726 | +} |