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