Base.php
4 years ago
Field.php
4 years ago
Group.php
4 years ago
Playbook.php
3 years ago
Pod.php
4 years ago
Tools.php
3 years ago
Playbook.php
220 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Pods\CLI\Commands; |
| 4 | |
| 5 | use Exception; |
| 6 | use Pods_Migrate_Packages; |
| 7 | use PodsInit; |
| 8 | use PodsMigrate; |
| 9 | use WP_CLI; |
| 10 | use WP_CLI_Command; |
| 11 | use function WP_CLI\Utils\make_progress_bar; |
| 12 | |
| 13 | /** |
| 14 | * Pods Playbook commands. |
| 15 | * |
| 16 | * @since 2.8.11 |
| 17 | */ |
| 18 | class Playbook extends WP_CLI_Command { |
| 19 | |
| 20 | /** |
| 21 | * Run the playbook. |
| 22 | * |
| 23 | * ## OPTIONS |
| 24 | * |
| 25 | * <playbook> |
| 26 | * : The playbook .json file path. |
| 27 | * |
| 28 | * [--test] |
| 29 | * : Whether to run the playbook in test mode and not add/change/remove any data in the database. |
| 30 | * |
| 31 | * [--continue-on-error] |
| 32 | * : Whether to continue on errors when the playbook is run. |
| 33 | * |
| 34 | * ## EXAMPLES |
| 35 | * |
| 36 | * wp pods playbook run migration.json |
| 37 | * - Run the playbook of the migration.json file. |
| 38 | * |
| 39 | * wp pods playbook run upgrade.json |
| 40 | * - Run the playbook of the upgrade.json file. |
| 41 | * |
| 42 | * wp pods playbook run upgrade.json --test |
| 43 | * - Preview the playbook run of the upgrade.json file but without changing the database. |
| 44 | * |
| 45 | * @since 2.8.11 |
| 46 | * |
| 47 | * @param array $args The list of positional arguments. |
| 48 | * @param array $assoc_args The list of associative arguments. |
| 49 | */ |
| 50 | public function run( $args, $assoc_args ) { |
| 51 | $playbook_file = $args[0]; |
| 52 | |
| 53 | $test_mode = ! empty( $assoc_args['test'] ); |
| 54 | $continue_on_error = ! empty( $assoc_args['continue-on-error'] ); |
| 55 | |
| 56 | if ( ! file_exists( $playbook_file ) ) { |
| 57 | WP_CLI::error( __( 'Playbook file does not exist.', 'pods' ) ); |
| 58 | } |
| 59 | |
| 60 | $json = file_get_contents( $playbook_file ); |
| 61 | |
| 62 | if ( empty( $json ) ) { |
| 63 | WP_CLI::error( __( 'Playbook file is empty.', 'pods' ) ); |
| 64 | } |
| 65 | |
| 66 | $playbook_actions = json_decode( $json, true ); |
| 67 | |
| 68 | if ( ! is_array( $playbook_actions ) ) { |
| 69 | WP_CLI::error( __( 'Playbook file contains invalid JSON.', 'pods' ) ); |
| 70 | } |
| 71 | |
| 72 | if ( empty( $playbook_actions ) ) { |
| 73 | WP_CLI::error( __( 'Playbook file is empty.', 'pods' ) ); |
| 74 | } |
| 75 | |
| 76 | if ( $test_mode ) { |
| 77 | WP_CLI::line( __( 'Running playbook in test mode.', 'pods' ) ); |
| 78 | } else { |
| 79 | WP_CLI::line( __( 'Running playbook in live mode.', 'pods' ) ); |
| 80 | } |
| 81 | |
| 82 | $api = pods_api(); |
| 83 | |
| 84 | // Enforce exceptions for errors. |
| 85 | add_filter( 'pods_error_mode', static function() { return 'exception'; } ); |
| 86 | add_filter( 'pods_error_mode_force', '__return_true' ); |
| 87 | |
| 88 | $total_actions = count( $playbook_actions ); |
| 89 | |
| 90 | $progress_bar = make_progress_bar( |
| 91 | sprintf( |
| 92 | // translators: %1$d is the total number of actions to run; %2$s is the singular/plural name for action. |
| 93 | __( 'Running playbook of actions | %1$d %2$s', 'pods' ), |
| 94 | $total_actions, |
| 95 | _n( 'action', 'actions', $total_actions, 'pods' ) |
| 96 | ), |
| 97 | $total_actions |
| 98 | ); |
| 99 | |
| 100 | foreach ( $playbook_actions as $action ) { |
| 101 | if ( ! isset( $action['action'] ) ) { |
| 102 | WP_CLI::warning( __( 'Action is invalid.', 'pods' ) ); |
| 103 | |
| 104 | $progress_bar->tick(); |
| 105 | |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | $action_name = $action['action']; |
| 110 | |
| 111 | $action_comment = isset( $action['#'] ) ? $action['#'] : $action_name; |
| 112 | |
| 113 | $action_args = []; |
| 114 | |
| 115 | // Check which kind of arguments we will use. |
| 116 | if ( isset( $action['params'] ) ) { |
| 117 | $action_args = [ |
| 118 | $action['params'], |
| 119 | ]; |
| 120 | } elseif ( isset( $action['args'] ) ) { |
| 121 | $action_args = $action['args']; |
| 122 | } |
| 123 | |
| 124 | WP_CLI::debug( sprintf( '%1$s: %2$s > PodsAPI::%3$s( ...%4$s )', __( 'Running playbook action', 'pods' ), $action_comment, $action_name, wp_json_encode( $action_args ) ) ); |
| 125 | |
| 126 | // Run the action if not in test mode. |
| 127 | if ( ! $test_mode ) { |
| 128 | $this->run_action( $action_name, $action_args, $api, $continue_on_error ); |
| 129 | } |
| 130 | |
| 131 | $progress_bar->tick(); |
| 132 | } |
| 133 | |
| 134 | $progress_bar->finish(); |
| 135 | |
| 136 | WP_CLI::success( __( 'Playbook run completed.', 'pods' ) ); |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Handle running the action with a try/catch for error handling. |
| 141 | * |
| 142 | * @param string $action_name |
| 143 | * @param array $action_args |
| 144 | * @param PodsAPI $api |
| 145 | * @param bool $continue_on_error |
| 146 | * |
| 147 | * @throws WP_CLI\ExitException |
| 148 | */ |
| 149 | protected function run_action( $action_name, $action_args, $api, $continue_on_error ) { |
| 150 | try { |
| 151 | if ( 'run' !== $action_name && method_exists( $this, $action_name ) ) { |
| 152 | $this->$action_name( ...$action_args ); |
| 153 | } elseif ( method_exists( $api, $action_name ) ) { |
| 154 | $api->$action_name( ...$action_args ); |
| 155 | } else { |
| 156 | // translators: %s: The action name. |
| 157 | WP_CLI::warning( sprintf( __( 'Action not supported: %s', 'pods' ), $action_name ) ); |
| 158 | } |
| 159 | } catch ( Exception $exception ) { |
| 160 | // translators: %s: The exception error message. |
| 161 | $playbook_error_message = sprintf( __( 'Playbook error: %s', 'pods' ), $exception->getMessage() ); |
| 162 | |
| 163 | if ( $continue_on_error ) { |
| 164 | WP_CLI::warning( $playbook_error_message ); |
| 165 | } else { |
| 166 | WP_CLI::error( $playbook_error_message ); |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | /** |
| 172 | * Import the package file for the playbook. |
| 173 | * |
| 174 | * @since 2.8.11 |
| 175 | * |
| 176 | * @param string|array $data The JSON file location, the JSON encoded package string, or an associative array containing the package data. |
| 177 | * @param bool $replace Whether to replace existing items when found. |
| 178 | * |
| 179 | * @return array|bool |
| 180 | * |
| 181 | * @throws Exception |
| 182 | */ |
| 183 | protected function import_package( $data, $replace = false ) { |
| 184 | if ( ! PodsInit::$components->is_component_active( 'migrate-packages' ) ) { |
| 185 | // Attempt to include the Package component code manually. |
| 186 | include_once PODS_DIR . 'components/Migrate-Packages/Migrate-Packages.php'; |
| 187 | |
| 188 | if ( ! class_exists( 'Pods_Migrate_Packages' ) ) { |
| 189 | throw new Exception( sprintf( __( 'Migrate Package is not activated. Try activating it: %s', 'pods' ), 'wp pods-api activate-component --component=migrate-packages' ), 'pods-package-import-error' ); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | // Check that we have the file or package we expect. |
| 194 | if ( empty( $data ) ) { |
| 195 | throw new Exception( __( 'Playbook import package was not set.', 'pods' ), 'pods-package-import-error' ); |
| 196 | } |
| 197 | |
| 198 | $is_file = is_string( $data ) && '.json' === substr( $data, strrpos( $data, '.json' ) ); |
| 199 | |
| 200 | if ( $is_file ) { |
| 201 | // Get package file data. |
| 202 | if ( ! file_exists( $data ) ) { |
| 203 | throw new Exception( __( 'Playbook import package "file" does not exist.', 'pods' ), 'pods-package-import-error' ); |
| 204 | } |
| 205 | |
| 206 | // Load PodsMigrate class file for use. |
| 207 | pods_migrate(); |
| 208 | |
| 209 | $data = PodsMigrate::get_data_from_file( $data, true ); |
| 210 | } |
| 211 | |
| 212 | if ( empty( $data ) ) { |
| 213 | throw new Exception( __( 'No Pods Package data found.', 'pods' ), 'pods-package-import-error' ); |
| 214 | } |
| 215 | |
| 216 | return Pods_Migrate_Packages::import( $data, $replace ); |
| 217 | } |
| 218 | |
| 219 | } |
| 220 |