Skip to content
Snippets Groups Projects
civicrm.php 44.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kevin Cristiano's avatar
    Kevin Cristiano committed
    <?php
    
    /*
     +--------------------------------------------------------------------+
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     | CiviCRM version 5                                                  |
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     +--------------------------------------------------------------------+
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     | Copyright CiviCRM LLC (c) 2004-2019                                |
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     +--------------------------------------------------------------------+
     | This file is a part of CiviCRM.                                    |
     |                                                                    |
     | CiviCRM is free software; you can copy, modify, and distribute it  |
     | under the terms of the GNU Affero General Public License           |
     | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
     |                                                                    |
     | CiviCRM is distributed in the hope that it will be useful, but     |
     | WITHOUT ANY WARRANTY; without even the implied warranty of         |
     | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
     | See the GNU Affero General Public License for more details.        |
     |                                                                    |
     | You should have received a copy of the GNU Affero General Public   |
     | License and the CiviCRM Licensing Exception along                  |
     | with this program; if not, contact CiviCRM LLC                     |
     | at info[AT]civicrm[DOT]org. If you have questions about the        |
     | GNU Affero General Public License or the licensing of CiviCRM,     |
     | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
     +--------------------------------------------------------------------+
     */
    
    if ( ! defined( 'CIVICRM_WPCLI_LOADED' ) ) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
      define( 'CIVICRM_WPCLI_LOADED', 1 );
    
      /**
       * WP-CLI port of drush-civicrm integration
       * andyw@circle, 08/03/2014
       *
       * Distributed under the GNU Affero General Public License, version 3
       * http://www.gnu.org/licenses/agpl-3.0.html
       */
    
      class CiviCRM_Command extends WP_CLI_Command {
    
        private $args, $assoc_args;
    
        /**
         * WP-CLI integration with CiviCRM.
         *
         * wp civicrm api
         * ===============
         * Command for accessing CiviCRM APIs. Syntax is identical to drush cvap.
         *
         * wp civicrm cache-clear
         * ===============
         * Command for accessing clearing cache.  Equivilant of running civicrm/admin/setting/updateConfigBackend&reset=1
         *
         * wp civicrm enable-debug
         * ===============
         * Command for to turn debug on.
         *
         * wp civicrm disable-debug
         * ===============
         * Command for to turn debug off.
         *
         * wp civicrm member-records
         * ===============
         * Run the CiviMember UpdateMembershipRecord cron ( civicrm member-records ).
         *
         * wp civicrm process-mail-queue
         * ===============
         * Process pending CiviMail mailing jobs.
         * Example:
         * wp civicrm process-mail-queue -u admin
         *
         * wp civicrm rest
         * ===============
         * Rest interface for accessing CiviCRM APIs. It can return xml or json formatted data.
         *
         * wp civicrm restore
         * ==================
         * Restore CiviCRM codebase and database back from the specified backup directory
         *
         * wp civicrm sql-conf
         * ===================
         * Show civicrm database connection details.
         *
         * wp civicrm sql-connect
         * ======================
         * A string which connects to the civicrm database.
         *
         * wp civicrm sql-cli
         * ==================
         * Quickly enter the mysql command line.
         *
         * wp civicrm sql-dump
         * ===================
         * Prints the whole CiviCRM database to STDOUT or save to a file.
         *
         * wp civicrm sql-query
         * ====================
         * Usage: wp civicrm sql-query <query> <options>...
         * <query> is a SQL statement, which can alternatively be passed via STDIN. Any additional arguments are passed to the mysql command directly.";
         *
         * wp civicrm update-cfg
         * =====================
         * Update config_backend to correct config settings, especially when the CiviCRM site has been cloned / migrated.
         *
         * wp civicrm upgrade
         * ==================
         * 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.
         *
         * wp civicrm upgrade-db
         * =====================
         * Run civicrm/upgrade?reset=1 just as a web browser would.
         *
         * wp civicrm install
         * ===============
         * Command for to install CiviCRM.  The install command requires that you have downloaded a tarball or zip file first.
         * Options:
         * --dbhost            MySQL host for your WordPress/CiviCRM database. Defaults to localhost.
         * --dbname            MySQL database name of your WordPress/CiviCRM database.
         * --dbpass            MySQL password for your WordPress/CiviCRM database.
         * --dbuser            MySQL username for your WordPress/CiviCRM database.
         * --lang              Default language to use for installation.
         * --langtarfile       Path to your l10n tar.gz file.
         * --site_url          Base Url for your WordPress/CiviCRM website without http ( e.g. mysite.com )
         * --ssl               Using ssl for your WordPress/CiviCRM website if set to on ( e.g. --ssl=on )
         * --tarfile           Path to your CiviCRM tar.gz file.
         *
         */
    
        public function __invoke( $args, $assoc_args ) {
    
          $this->args       = $args;
          $this->assoc_args = $assoc_args;
    
          # define command router
          $command_router = array(
            'api'                => 'api',
            'cache-clear'        => 'cacheClear',
            'enable-debug'       => 'enableDebug',
            'disable-debug'      => 'disableDebug',
            'install'            => 'install',
            'member-records'     => 'memberRecords',
            'process-mail-queue' => 'processMailQueue',
            'rest'               => 'rest',
            'restore'            => 'restore',
            'sql-cli'            => 'sqlCLI',
            'sql-conf'           => 'sqlConf',
            'sql-connect'        => 'sqlConnect',
            'sql-dump'           => 'sqlDump',
            'sql-query'          => 'sqlQuery',
            'update-cfg'         => 'updateConfig',
            'upgrade'            => 'upgrade',
            'upgrade-db'         => 'upgradeDB',
           );
    
          # get command
          $command = array_shift( $args );
    
          # check for existence of Civi ( except for command 'install' )
          if ( ! function_exists( 'civicrm_initialize' ) and 'install' != $command ) {
            return WP_CLI::error( 'Unable to find CiviCRM install.' );
          }
    
          # check existence of router entry / handler method
          if ( ! isset( $command_router[ $command ] ) or ! method_exists( $this, $command_router[ $command ] ) ) {
            return WP_CLI::error( "Unrecognized command - '$command'" );
          }
    
          # run command
          return $this->{$command_router[ $command ]}();
    
        }
    
        /**
         * Implementation of command 'api'
         */
        private function api() {
    
          $defaults = array( 'version' => 3 );
    
          array_shift( $this->args );
          list( $entity, $action ) = explode( '.', $this->args[0] );
          array_shift( $this->args );
    
          # parse $params
          $format = $this->getOption( 'in', 'args' );
          switch ( $format ) {
    
            # input params supplied via args ..
            case 'args':
              $params = $defaults;
              foreach ( $this->args as $arg ) {
                preg_match( '/^([^=]+)=(.*)$/', $arg, $matches );
                $params[ $matches[1] ] = $matches[2];
              }
              break;
    
            # input params supplied via json ..
            case 'json':
              $json   = stream_get_contents( STDIN );
              $params = ( empty( $json ) ? $defaults : array_merge( $defaults, json_decode( $json, true ) ) );
              break;
    
            default:
              WP_CLI::error( 'Unknown format: ' . $format );
              break;
          }
    
          civicrm_initialize();
    
          // CRM-18062: Set CiviCRM timezone if any
          $wp_base_timezone = date_default_timezone_get();
          $wp_user_timezone = $this->getOption( 'timezone', get_option( 'timezone_string' ) );
          if ( $wp_user_timezone ) {
            date_default_timezone_set( $wp_user_timezone );
            CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone();
          }
    
          $result = civicrm_api( $entity, $action, $params );
    
          // restore WP's timezone
          if ( $wp_base_timezone ) {
            date_default_timezone_set( $wp_base_timezone );
          }
    
          switch ( $this->getOption( 'out', 'pretty' ) ) {
    
            # pretty-print output ( default )
            case 'pretty':
              WP_CLI::line( print_r( $result, true ) );
              break;
    
            # display output as json
            case 'json':
              WP_CLI::line( json_encode( $result ) );
              break;
    
            default:
              return WP_CLI::error( 'Unknown format: ' . $format );
    
          }
    
        }
    
        /**
         * Implementation of command 'cache-clear'
         */
        private function cacheClear() {
    
          civicrm_initialize();
          require_once 'CRM/Core/Config.php';
          $config = CRM_Core_Config::singleton();
    
          # clear db caching
          $config->clearDBCache();
    
          # also cleanup the templates_c directory
          $config->cleanup( 1, false );
    
          # also cleanup the session object
          $session = CRM_Core_Session::singleton();
          $session->reset( 1 );
    
        }
    
        /**
         * Implementation of command 'enable-debug'
         */
        private function enableDebug() {
          civicrm_initialize();
          Civi::settings()->add( array(
            'debug_enabled' => 1,
            'backtrace' => 1,
          ) );
          WP_CLI::success( 'Debug setting enabled.' );
        }
    
        /**
         * Implementation of command 'disable-debug'
         */
        private function disableDebug() {
          civicrm_initialize();
          Civi::settings()->add( array(
            'debug_enabled' => 0,
            'backtrace' => 0,
          ) );
          WP_CLI::success( 'Debug setting disabled.' );
        }
    
        /**
         * Implementation of command 'install'
         */
        private function install() {
    
          # validate
    
          if ( ! $dbuser = $this->getOption( 'dbuser', false ) ) {
            return WP_CLI::error( 'CiviCRM database username not specified.' );
          }
    
          if ( ! $dbpass = $this->getOption( 'dbpass', false ) ) {
            return WP_CLI::error( 'CiviCRM database password not specified.' );
          }
    
          if ( ! $dbhost = $this->getOption( 'dbhost', false ) ) {
            return WP_CLI::error( 'CiviCRM database host not specified.' );
          }
    
          if ( ! $dbname = $this->getOption( 'dbname', false ) ) {
            return WP_CLI::error( 'CiviCRM database name not specified.' );
          }
    
          if ( $lang = $this->getOption( 'lang', false ) and ! $langtarfile = $this->getOption( 'langtarfile', false ) ) {
            return WP_CLI::error( 'CiviCRM language tarfile not specified.' );
          }
    
          # begin install
    
          if ( $plugin_path = $this->getOption( 'destination', false ) ) {
            $plugin_path = ABSPATH . $plugin_path;
          } else {
            $plugin_path = WP_PLUGIN_DIR . '/civicrm';
          }
    
          global $crmPath;
          $crmPath = "$plugin_path/civicrm";
          $crm_files_present = is_dir( $crmPath );
    
          # extract the archive
          if ( $this->getOption( 'tarfile', false ) ) {
            # should probably never get to here as Wordpress Civi comes in a zip file, but
            # just in case that ever changes ..
            if ( $crm_files_present ) {
              return WP_CLI::error( 'Existing CiviCRM found. No action taken.' );
            }
    
            if ( ! $this->untar( dirname( $plugin_path ) ) ) {
              return WP_CLI::error( 'Error extracting tarfile' );
            }
          } elseif ( $this->getOption( 'zipfile', false ) ) {
            if ( $crm_files_present ) {
              return WP_CLI::error( 'Existing CiviCRM found. No action taken.' );
            }
    
            if ( ! $this->unzip( dirname( $plugin_path ) ) ) {
              return WP_CLI::error( 'Error extracting zipfile' );
            }
          } elseif ( $crm_files_present ) {
            // Site is already extracted (which is how we're running this
            // script); we just need to run the installer.
    
          } else {
            return WP_CLI::error( 'No zipfile specified, use --zipfile=path/to/zipfile or extract file ahead of time' );
          }
    
          # include civicrm installer helper file
          $civicrm_installer_helper = "$crmPath/install/civicrm.php";
    
          if ( ! file_exists( $civicrm_installer_helper ) ) {
            return WP_CLI::error( 'Archive could not be unpacked OR CiviCRM installer helper file is missing.' );
          }
    
          if ( $crm_files_present ) {
            // We were using a directory that was already there.
            WP_CLI::success( 'Using installer files found on the site.' );
          } else {
            // We must've just unpacked the archive because it wasn't there
            // before.
            WP_CLI::success( 'Archive unpacked.' );
          }
          require_once $civicrm_installer_helper;
    
          if ( '' != $lang ) {
            if ( ! $this->untar( $plugin_path, 'langtarfile' ) ) {
              return WP_CLI::error( 'No language tarfile specified, use --langtarfile=path/to/tarfile' );
            }
          }
    
          # create files dirs
          $upload_dir = wp_upload_dir();
          $settings_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR;
          civicrm_setup( $upload_dir['basedir'] . DIRECTORY_SEPARATOR );
          WP_CLI::launch( "chmod 0755 $settings_dir -R" );
    
          # now we've got some files in place, require PEAR DB and check db setup
          $dsn = "mysql://{$dbuser}:{$dbpass}@{$dbhost}/{$dbname}?new_link=true";
          $dsn_nodb = "mysql://{$dbuser}:{$dbpass}@{$dbhost}";
    
          if ( ! defined( 'DB_DSN_MODE' ) ) {
            define( 'DB_DSN_MODE', 'auto' );
          }
    
          require_once "$crmPath/packages/DB.php";
    
          $db = DB::connect( $dsn );
          if ( DB::iserror( $db ) ) {
            $db = DB::connect( $dsn_nodb );
            if ( DB::iserror( $db ) ) {
              return WP_CLI::error( 'Unable to connect to database. Please re-check credentials.' );
            }
            $db->query( "CREATE DATABASE $dbname" );
            if ( DB::iserror( $db ) ) {
              return WP_CLI::error( 'CiviCRM database was not found. Failed to create one.' );
            }
            $db->disconnect();
          }
    
          # install db
          global $sqlPath;
    
          # setup database with civicrm structure and data
          WP_CLI::line( 'Loading CiviCRM database structure ..' );
          civicrm_source( $dsn, $sqlPath . '/civicrm.mysql' );
          WP_CLI::line( 'Loading CiviCRM database with required data ..' );
    
          # testing the translated sql files availability
          $data_file = $sqlPath . '/civicrm_data.mysql';
          $acl_file  = $sqlPath . '/civicrm_acl.mysql';
    
          if ( '' != $lang ) {
    
            if ( file_exists( $sqlPath . '/civicrm_data.' . $lang . '.mysql' )
              and file_exists( $sqlPath . '/civicrm_acl.' . $lang . '.mysql' )
              and '' != $lang
             ) {
              $data_file = $sqlPath . '/civicrm_data.' . $lang . '.mysql';
              $acl_file = $sqlPath . '/civicrm_acl.' . $lang . '.mysql';
            } else {
              WP_CLI::warning( "No sql files could be retrieved for '$lang' using default language." );
            }
          }
    
          civicrm_source( $dsn, $data_file );
          civicrm_source( $dsn, $acl_file );
    
          WP_CLI::success( 'CiviCRM database loaded successfully.' );
    
          # generate civicrm.settings.php file
          global $tplPath;
          if ( ! file_exists( $tplPath . 'civicrm.settings.php.template' ) ) {
            return WP_CLI::error( 'Could not find CiviCRM settings template and therefore could not create settings file.' );
          }
    
          WP_CLI::line( 'Generating civicrm settings file ..' );
    
          if ( $base_url = $this->getOption( 'site_url', false ) ) {
            $ssl      = $this->getOption( 'ssl', false );
            $protocol = ( 'on' == $ssl ? 'https' : 'http' );
          }
    
          $base_url = ! $base_url ? get_bloginfo( 'url' ) : $protocol . '://' . $base_url;
          if ( substr( $base_url, -1 ) != '/' ) {
            $base_url .= '/';
          }
          $params = array(
            'crmRoot'            => $crmPath . '/',
            'templateCompileDir' => "{$settings_dir}templates_c",
            'frontEnd'           => 0,
            'cms'                => 'WordPress',
            'baseURL'            => $base_url,
            'dbUser'             => $dbuser,
            'dbPass'             => $dbpass,
            'dbHost'             => $dbhost,
            'dbName'             => $dbname,
            'CMSdbUser'          => DB_USER,
            'CMSdbPass'          => DB_PASSWORD,
            'CMSdbHost'          => DB_HOST,
            'CMSdbName'          => DB_NAME,
            'siteKey'            => md5(rand() . mt_rand() . rand() . uniqid('', TRUE) . $params['baseURL']),
           );
    
          $str = file_get_contents( $tplPath . 'civicrm.settings.php.template' );
          foreach ( $params as $key => $value ) {
            $str = str_replace( '%%' . $key . '%%', $value, $str );
          }
    
          $str = trim( $str );
    
          $config_file = "{$settings_dir}civicrm.settings.php";
          civicrm_write_file( $config_file, $str );
          WP_CLI::launch( "chmod 0644 $config_file" );
          WP_CLI::success( sprintf( 'Settings file generated: %s', $config_file ) );
    
          # activate plugin and we're done
          @WP_CLI::run_command( array( 'plugin', 'activate', 'civicrm' ), array() );
          WP_CLI::success( 'CiviCRM installed.' );
    
        }
    
        /**
         * Implementation of command 'member-records'
         */
        private function memberRecords() {
    
          civicrm_initialize();
    
          if ( substr( CRM_Utils_System::version(), 0, 3 ) >= '4.3' ) {
    
            $job = new CRM_Core_JobManager();
            $job->executeJobByAction( 'job', 'process_membership' );
            WP_CLI::success( "Executed 'process_membership' job." );
    
          } else {
    
            $_REQUEST['name'] = $this->getOption( 'civicrm_cron_username', null );
            $_REQUEST['pass'] = $this->getOption( 'civicrm_cron_password', null );
            $_REQUEST['key']  = $this->getOption( 'civicrm_sitekey', null );
    
            global $argv;
            $argv = array(
              0 => 'drush',
              1 => '-u' . $_REQUEST['name'],
              2 => '-p' . $_REQUEST['pass'],
              3 => '-s' . $this->getOption( 'uri', false ),
             );
    
            # if ( !defined( 'CIVICRM_CONFDIR' ) ) {
            # $plugins_dir = plugin_dir_path( __FILE__ );
            #     define( 'CIVICRM_CONFDIR', $plugins_dir );
            # }
    
            include 'bin/UpdateMembershipRecord.php';
    
          }
    
        }
    
        /**
         * Implementation of command 'process-mail-queue'
         */
        private function processMailQueue() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          civicrm_initialize();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( substr( CRM_Utils_System::version(), 0, 3 ) >= '4.3' ) {
    
            $job = new CRM_Core_JobManager();
            $job->executeJobByAction( 'job', 'process_mailing' );
            WP_CLI::success( "Executed 'process_mailing' job." );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          } else {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $result = civicrm_api( 'Mailing', 'Process', array( 'version' => 3 ) );
            if ( $result['is_error'] ) {
              WP_CLI::error( $result['error_message'] );
            }
          }
    
        }
    
        /**
         * Implementation of command 'rest'
         */
        private function rest() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          civicrm_initialize();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! $query = $this->getOption( 'query', false ) ) {
            return WP_CLI::error( 'query not specified.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $query     = explode( '&', $query );
          $_GET['q'] = array_shift( $query );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          foreach ( $query as $key_val ) {
            list( $key, $val ) = explode( '=', $key_val );
            $_REQUEST[ $key ]  = $val;
            $_GET[ $key ]      = $val;
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          require_once 'CRM/Utils/REST.php';
          $rest = new CRM_Utils_REST();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          require_once 'CRM/Core/Config.php';
          $config = CRM_Core_Config::singleton();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          global $civicrm_root;
          // adding dummy script, since based on this api file path is computed.
          $_SERVER['SCRIPT_FILENAME'] = "$civicrm_root/extern/rest.php";
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( isset( $_GET['json'] ) && $_GET['json'] ) {
            header( 'Content-Type: text/javascript' );
          } else {
            header( 'Content-Type: text/xml' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          echo $rest->run( $config );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Implementation of command 'restore'
         */
        private function restore() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # validate ..
          $restore_dir = $this->getOption( 'restore-dir', false );
          $restore_dir = rtrim( $restore_dir, '/' );
          if ( ! $restore_dir ) {
            return WP_CLI::error( 'Restore-dir not specified.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $sql_file = $restore_dir . '/civicrm.sql';
          if ( ! file_exists( $sql_file ) ) {
            return WP_CLI::error( 'Could not locate civicrm.sql file in the restore directory.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $code_dir = $restore_dir . '/civicrm';
          if ( ! is_dir( $code_dir ) ) {
            return WP_CLI::error( 'Could not locate civicrm directory inside restore-dir.' );
          } elseif ( ! file_exists( "$code_dir/civicrm/civicrm-version.txt" ) and ! file_exists( "$code_dir/civicrm/civicrm-version.php" ) ) {
            return WP_CLI::error( 'civicrm directory inside restore-dir, doesn\'t look to be a valid civicrm codebase.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # prepare to restore ..
          $date = date( 'YmdHis' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          civicrm_initialize();
          global $civicrm_root;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $civicrm_root_base = explode( '/', $civicrm_root );
          array_pop( $civicrm_root_base );
          $civicrm_root_base = implode( '/', $civicrm_root_base ) . '/';
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $basepath = explode( '/', $civicrm_root );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! end( $basepath ) ) {
            array_pop( $basepath );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          array_pop( $basepath );
          $project_path = implode( '/', $basepath ) . '/';
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $wp_root = ABSPATH;
          $restore_backup_dir = $this->getOption( 'backup-dir', $wp_root . '/../backup' );
          $restore_backup_dir = rtrim( $restore_backup_dir, '/' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # get confirmation from user -
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! defined( 'CIVICRM_DSN' ) ) {
            WP_CLI::error( 'CIVICRM_DSN is not defined.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $db_spec = DB::parseDSN( CIVICRM_DSN );
          WP_CLI::line( '' );
          WP_CLI::line( 'Process involves:' );
          WP_CLI::line( sprintf( "1. Restoring '\$restore-dir/civicrm' directory to '%s'.", $civicrm_root_base ) );
          WP_CLI::line( sprintf( "2. Dropping and creating '%s' database.", $db_spec['database'] ) );
          WP_CLI::line( "3. Loading '\$restore-dir/civicrm.sql' file into the database." );
          WP_CLI::line( '' );
          WP_CLI::line( sprintf( "Note: Before restoring a backup will be taken in '%s' directory.", "$restore_backup_dir/plugins/restore" ) );
          WP_CLI::line( '' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::confirm( 'Do you really want to continue?' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $restore_backup_dir .= '/plugins/restore/' . $date;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! mkdir( $restore_backup_dir, 0755, true ) ) {
            return WP_CLI::error( 'Failed creating directory: ' . $restore_backup_dir );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # 1. backup and restore codebase
          WP_CLI::line( 'Restoring civicrm codebase ..' );
          if ( is_dir( $project_path ) && ! rename( $project_path, $restore_backup_dir . '/civicrm' ) ) {
            return WP_CLI::error( sprintf( "Failed to take backup for '%s' directory", $project_path ) );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! rename( $code_dir, $project_path ) ) {
            return WP_CLI::error( "Failed to restore civicrm directory '%s' to '%s'", $code_dir, $project_path );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::success( 'Codebase restored.' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # 2. backup, drop and create database
          WP_CLI::run_command(
            array( 'civicrm', 'sql-dump' ),
            array( 'result-file' => $restore_backup_dir . '/civicrm.sql' )
          );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::success( 'Database backed up.' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # prepare a mysql command-line string for issuing
          # db drop / create commands
          $command = sprintf(
            'mysql --user=%s --password=%s',
            $db_spec['username'],
            $db_spec['password']
          );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( isset( $db_spec['hostspec'] ) ) {
            $command .= ' --host=' . $db_spec['hostspec'];
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( isset( $dsn['port'] ) and ! mpty( $dsn['port'] ) ) {
            $command .= ' --port=' . $db_spec['port'];
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # attempt to drop old database
          if ( system( $command . sprintf( ' --execute="DROP DATABASE IF EXISTS %s"', $db_spec['database'] ) ) ) {
            return WP_CLI::error( 'Could not drop database: ' . $db_spec['database'] );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::success( 'Database dropped.' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # attempt to create new database
          if ( system( $command . sprintf( ' --execute="CREATE DATABASE %s"', $db_spec['database'] ) ) ) {
            WP_CLI::error( 'Could not create new database: ' . $db_spec['database'] );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::success( 'Database created.' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # 3. restore database
          WP_CLI::line( 'Loading civicrm.sql file from restore-dir ..' );
          system( $command . ' ' . $db_spec['database'] . ' < ' . $sql_file );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::success( 'Database restored.' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::line( 'Clearing caches..' );
          WP_CLI::run_command( array( 'civicrm', 'cache-clear' ) );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::success( 'Restore process completed.' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Implementation of command 'sql-conf'
         */
        private function sqlConf() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          civicrm_initialize();
          if ( ! defined( 'CIVICRM_DSN' ) ) {
            WP_CLI::error( 'CIVICRM_DSN is not defined.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          WP_CLI::line( print_r( DB::parseDSN( CIVICRM_DSN ), true ) );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Implementation of command 'sql-connect'
         */
        private function sqlConnect() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          civicrm_initialize();
          if ( ! defined( 'CIVICRM_DSN' ) ) {
            return WP_CLI::error( 'CIVICRM_DSN is not defined.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $dsn = DB::parseDSN( CIVICRM_DSN );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $command = sprintf(
            'mysql --database=%s --host=%s --user=%s --password=%s',
            $dsn['database'],
            $dsn['hostspec'],
            $dsn['username'],
            $dsn['password']
          );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( isset( $dsn['port'] ) and ! empty( $dsn['port'] ) ) {
            $command .= ' --port=' . $dsn['port'];
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          return WP_CLI::line( $command );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Implementation of command 'sql-dump'
         */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        private function sqlDump() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          # bootstrap Civi when we're not being called as part of an upgrade
          if ( ! defined( 'CIVICRM_UPGRADE_ACTIVE' ) ) {
            civicrm_initialize();
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! defined( 'CIVICRM_DSN' ) and ! defined( 'CIVICRM_OLD_DSN' ) ) {
            WP_CLI::error( 'DSN is not defined.' );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $dsn = self::parseDSN( defined( 'CIVICRM_DSN' ) ? CIVICRM_DSN : CIVICRM_OLD_DSN );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $assoc_args       = $this->assoc_args;
          $stdout           = ! isset( $assoc_args['result-file'] );
          $command          = "mysqldump --no-defaults --host={$dsn['hostspec']} --user={$dsn['username']} --password='{$dsn['password']}' %s";
          $command_esc_args = array( $dsn['database'] );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( isset( $assoc_args['tables'] ) ) {
            $tables = explode( ',', $assoc_args['tables'] );
            unset( $assoc_args['tables'] );
            $command .= ' --tables';
            foreach ( $tables as $table ) {
              $command .= ' %s';
              $command_esc_args[] = trim( $table );
            }
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $escaped_command = call_user_func_array(
            '\WP_CLI\Utils\esc_cmd',
            array_merge(
              array( $command ),
              $command_esc_args
            )
          );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          \WP_CLI\Utils\run_mysql_command( $escaped_command, $assoc_args );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! $stdout ) {
            WP_CLI::success( sprintf( 'Exported to %s', $assoc_args['result-file'] ) );
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Implementation of command 'sql-query'
         */
        private function sqlQuery() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! isset( $this->args[0] ) ) {
            WP_CLI::error( 'No query specified.' );
            return;
          }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $query = $this->args[0];
    
          civicrm_initialize();
          if ( ! defined( 'CIVICRM_DSN' ) ) {
            WP_CLI::error( 'CIVICRM_DSN is not defined.' );
          }
    
          $dsn = DB::parseDSN( CIVICRM_DSN );
    
          $mysql_args = array(
            'host'     => $dsn['hostspec'],
            'database' => $dsn['database'],
            'user'     => $dsn['username'],
            'password' => $dsn['password'],
            'execute'  => $query,
           );
    
          \WP_CLI\Utils\run_mysql_command( 'mysql --no-defaults', $mysql_args );
    
        }
    
        /**
         * Implementation of command 'sql-cli'
         */
        private function sqlCLI() {
    
          civicrm_initialize();
          if ( ! defined( 'CIVICRM_DSN' ) ) {
            WP_CLI::error( 'CIVICRM_DSN is not defined.' );
          }
    
          $dsn = DB::parseDSN( CIVICRM_DSN );
    
          $mysql_args = array(
            'host'     => $dsn['hostspec'],
            'database' => $dsn['database'],
            'user'     => $dsn['username'],
            'password' => $dsn['password'],
           );
    
          \WP_CLI\Utils\run_mysql_command( 'mysql --no-defaults', $mysql_args );
    
        }
    
        /**
         * Implementation of command 'update-cfg'
         */
        private function updateConfig() {
    
          civicrm_initialize();
    
          $default_values = array();
          $states        = array( 'old', 'new' );
    
          for ( $i = 1; $i <= 3; $i++ ) {
            foreach ( $states as $state ) {
              $name = "{$state}Val_{$i}";
              $value = $this->getOption( $name, null );
              if ( $value ) {
                $default_values[ $name ] = $value;
              }
            }
          }
    
          $webserver_user  = $this->getWebServerUser();
          $webserver_group = $this->getWebServerGroup();
    
          require_once 'CRM/Core/I18n.php';
          require_once 'CRM/Core/BAO/ConfigSetting.php';
          $result = CRM_Core_BAO_ConfigSetting::doSiteMove( $default_values );
    
          if ( $result ) {
    
            # attempt to preserve webserver ownership of templates_c, civicrm/upload
            if ( $webserver_user and $webserver_group ) {
              $upload_dir      = wp_upload_dir();
              $civicrm_files_dir      = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR;
              system( sprintf( 'chown -R %s:%s %s/templates_c', $webserver_user, $webserver_group, $civicrm_files_dir ) );
              system( sprintf( 'chown -R %s:%s %s/upload', $webserver_user, $webserver_group, $civicrm_files_dir ) );
            }
    
            WP_CLI::success( 'Config successfully updated.' );
    
          } else {
            WP_CLI::error( 'Config update failed.' );
          }
    
        }
    
        /**
         * Implementation of command 'upgrade'
         */
        private function upgrade() {
    
          # todo: use wp-cli to download tarfile.
          # todo: if tarfile is not specified, see if the code already exists and use that instead.
          if ( ! $this->getOption( 'tarfile', false ) and ! $this->getOption( 'zipfile', false ) ) {
            return WP_CLI::error( 'Must specify either --tarfile or --zipfile' );
          }
    
          # fixme: throw error if tarfile is not in a valid format.
          if ( ! defined( 'CIVICRM_UPGRADE_ACTIVE' ) ) {
            define( 'CIVICRM_UPGRADE_ACTIVE', 1 );
          }
    
          $wp_root       = ABSPATH;
          $plugins_dir = plugin_dir_path( __FILE__ );
          $legacy_settings_file = $plugins_dir . '/civicrm.settings.php';
          $upload_dir      = wp_upload_dir();
          $settings_file     = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm.settings.php';
          if ( ! file_exists( $legacy_settings_file ) || ! file_exists( $settings_file ) ) {
            return WP_CLI::error( 'Unable to locate settings file at ' . $legacy_settings_file . 'or at ' . $settings_file );
          }
    
          # nb: we don't want to require civicrm.settings.php here, because ..
          #
          # a ) this is the old environment we're going to replace
          # b ) upgrade-db needs to bootstrap the new environment, so requiring the file
          #    now will create multiple inclusion problems later on
          #
          # however, all we're really after is $civicrm_root and CIVICRM_DSN, so we're going to
          # pull out the lines we need using a regex and run them - yes, it's pretty silly ..
          # don't try this at home, kids.
    
          $legacy_settings = file_get_contents( $legacy_settings_file );
          $legacy_settings = str_replace( "\r", '', $legacy_settings );
          $legacy_settings = explode( "\n", $legacy_settings );
          $settings = file_get_contents( $settings_file );
          $settings = str_replace( "\r", '', $settings );
          $settings = explode( "\n", $settings );
    
          if ( $civicrm_root_code = reset( preg_grep( '/^\s*\$civicrm_root\s*=.*$/', $legacy_settings ) ) ) {
            eval( $civicrm_root_code );
          } elseif ( $civicrm_root_code = reset( preg_grep( '/^\s*\$civicrm_root\s*=.*$/', $settings ) ) ) {
            eval( $civicrm_root_code );
          } else {
            return WP_CLI::error( 'Unable to read $civicrm_root from civicrm.settings.php' );
          }
    
          if ( $civicrm_dsn_code = reset( preg_grep( '/^\s*define.*CIVICRM_DSN.*$/', $settings ) ) ) {
            $civicrm_dsn_code = str_replace( 'CIVICRM_DSN', 'CIVICRM_OLD_DSN', $civicrm_dsn_code );
            eval( $civicrm_dsn_code );
          } else {
            return WP_CLI::error( 'Unable to read CIVICRM_DSN from civicrm.settings.php' );
          }
    
          if ( ! defined( 'CIVICRM_OLD_DSN' ) ) {
            return WP_CLI::error( 'Unable to set CIVICRM_OLD_DSN' );
          }
    
          $date        = date( 'YmdHis' );
          $backup_file = 'civicrm';
    
          $basepath = explode( '/', $civicrm_root );
    
          if ( ! end( $basepath ) ) {
            array_pop( $basepath );
          }
    
          array_pop( $basepath );
          $project_path = implode( '/', $basepath ) . '/';
          array_pop( $basepath );
          $plugin_path = implode( '/', $basepath ) . '/';
    
          $backup_dir = $this->getOption( 'backup-dir', $wp_root . '../backup' );
          $backup_dir = rtrim( $backup_dir, '/' );
    
          WP_CLI::line( "\nThe upgrade process involves - " );
          WP_CLI::line( sprintf( '1. Backing up current CiviCRM code as => %s', "$backup_dir/plugins/$date/$backup_file" ) );
          WP_CLI::line( sprintf( '2. Backing up database as => %s', "$backup_dir/plugins/$date/$backup_file.sql" ) );
          WP_CLI::line( sprintf( '3. Unpacking tarfile to => %s', $plugin_path ) );
          WP_CLI::line( "4. Executing civicrm/upgrade?reset=1 just as a browser would.\n" );
    
          WP_CLI::confirm( 'Do you really want to continue?' );
    
          # begin upgrade