PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / trunk
Pods – Custom Content Types and Fields vtrunk
trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / src / Pods / CLI / Commands / Playbook.php
pods / src / Pods / CLI / Commands Last commit date
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