PluginProbe
YayMail – WooCommerce Email Customizer / 4.4.0
YayMail – WooCommerce Email Customizer v4.4.0
4.4.4 4.4.3 4.4.2 4.4.1 trunk 1.9.6 2.1.4 2.1.5 3.2.2 3.2.6 3.2.7.1 3.2.8.1 3.2.9 3.3 3.3.1 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4 3.4.1 3.4.2 3.4.3 All 55 releases
yaymail / src / Migrations / AbstractAddonMigrationManager.php

AbstractAddonMigrationManager.php in YayMail – WooCommerce Email Customizer 4.4.0, at src/Migrations/AbstractAddonMigrationManager.php

248 lines 7.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace YayMail\Migrations;
3
4 use YayMail\Utils\Logger;
5 use YayMail\SupportedPlugins;
6 use YayMail\YayMailTemplate;
7
8
9 /**
10 * AbstractAddonMigrationManager
11 */
12 abstract class AbstractAddonMigrationManager {
13
14 /**
15 * @var string $old_version
16 * @Example '3.9.9'
17 */
18 protected $old_version;
19
20 /**
21 * @var string $default_legacy_version
22 * @Example '3.9.9'
23 */
24 protected $default_legacy_version;
25
26 /**
27 * @var string $new_version
28 * @Example '4.0.0'
29 */
30 protected $new_version;
31
32
33 /** @var Logger */
34 protected $logger;
35
36 /**
37 * Addon Namespace, empty means core
38 *
39 * @var string $addon_namespace
40 */
41 protected $addon_namespace = '';
42
43 /**
44 * Addon name, empty means core
45 *
46 * @var string $addon_name
47 */
48 protected $addon_name = '';
49
50 /**
51 * Available migrations
52 *
53 * @var array $addon_migrations
54 */
55 protected $addon_migrations = [];
56
57 /**
58 * @var SupportedPlugins $supported_plugins_instance
59 */
60 protected $supported_plugins_instance;
61
62 /**
63 * @var array $supported_template_ids
64 */
65 protected $supported_template_ids;
66
67 /**
68 * Migration manager's constructor
69 *
70 * @param string $old_version
71 * @param string $new_version
72 * @param string $addon_namespace
73 * @param string $addon_name
74 */
75 protected function __construct( $old_version, $new_version, $addon_namespace, $addon_name ) {
76 $this->old_version = $old_version;
77 $this->new_version = $new_version;
78
79 $this->addon_namespace = $addon_namespace;
80 $this->addon_name = $addon_name;
81
82 $this->logger = new Logger();
83
84 $this->supported_plugins_instance = SupportedPlugins::get_instance();
85
86 $this->supported_template_ids = $this->supported_plugins_instance->get_addon_supported_template_ids( $addon_namespace );
87
88 $this->init_migrations();
89 $this->init_hooks();
90 }
91
92 protected function init_hooks() {
93 add_action( 'yaymail_run_addon_migrations', [ $this, 'execute_migrations' ] );
94 add_filter( 'yaymail_required_migration_names', [ $this, 'check_if_addon_migration_needed' ] );
95 add_filter( 'yaymail_migration_backup_data', [ $this, 'add_additional_backup_data' ] );
96 }
97
98 abstract protected function declare_migrations();
99
100 public function execute_migrations() {
101 $this->logger->log( "*Starting migrations for {$this->addon_namespace}*" );
102
103 if ( empty( $this->addon_migrations ) ) {
104 $this->logger->log( "No migrations available for {$this->addon_namespace}" );
105 } else {
106 MigrationHelper::perform_migrations( $this->addon_migrations );
107
108 // After migrations succeeded, update addon version
109 $addon_versions = get_option( 'yaymail_addon_versions', [] );
110 $addon_versions[ $this->addon_namespace ] = $this->new_version;
111 update_option( 'yaymail_addon_versions', $addon_versions );
112 }
113
114 $this->logger->log( "*Finished migrations for {$this->addon_namespace}*" );
115 }
116
117 public function check_if_addon_migration_needed( $needed_migrations ) {
118
119 if ( empty( $this->addon_migrations ) ) {
120 return $needed_migrations;
121 }
122
123 $successful_migrations = get_option( '_yaymail_successful_migrations', [] );
124
125 foreach ( $successful_migrations as $successful_migration ) {
126
127 if ( isset( $successful_migration['addon_namespace'] )
128 && $successful_migration['addon_namespace'] === $this->addon_namespace
129 && version_compare( $successful_migration['to_version'], $this->new_version, '>=' ) ) {
130
131 return $needed_migrations;
132 }
133 }
134
135 $needed_migrations[] = $this->addon_name;
136
137 return $needed_migrations;
138 }
139
140 // Add addon version to backup data if addon version does not exist (before 4.0.0)
141 public function add_additional_backup_data( $backup_data ) {
142 $options = $backup_data['options'];
143
144 $yaymail_addon_versions_option = null;
145
146 foreach ( $options as &$option ) {
147 if ( $option->option_name === 'yaymail_addon_versions' ) {
148 $yaymail_addon_versions_option = &$option;
149 break;
150 }
151 }
152
153 // If the option is found
154 if ( $yaymail_addon_versions_option ) {
155 $versions = maybe_unserialize( $yaymail_addon_versions_option->option_value );
156
157 // If the unserialized value is an array
158 if ( is_array( $versions ) ) {
159 // Add or update the addon version
160 $versions[ $this->addon_namespace ] = $versions[ $this->addon_namespace ] ?? $this->default_legacy_version;
161
162 // Serialize and update the option value
163 $yaymail_addon_versions_option->option_value = maybe_serialize( $versions );
164 } else {
165 throw new \Error( esc_html( "Error unserializing {$this->addon_namespace} version data" ), 500 );
166 }
167 } else {
168 // If 'yaymail_addon_versions' option does not exist, create it
169 $options[] = (object) [
170 'option_name' => 'yaymail_addon_versions',
171 'option_value' => maybe_serialize( [ $this->addon_namespace => $this->default_legacy_version ] ),
172 ];
173 }
174
175 // Update the backup_data with the modified options
176 $backup_data['options'] = $options;
177
178 return $backup_data;
179 }
180
181
182 private function init_migrations() {
183 $this->declare_migrations();
184 $this->filter_migrations();
185 }
186
187 protected function filter_migrations() {
188 $this->addon_migrations = MigrationHelper::filter_migrations( $this->addon_migrations, $this->old_version, $this->new_version );
189 $this->filter_migrations_by_v4_supported_status();
190 }
191
192 /**
193 * Filter migrations by the supported status and a specific version threshold.
194 *
195 * @param string $version_threshold The first addon version on newcore V4.
196 */
197 protected function filter_migrations_by_version_threshold( string $version_threshold ): void {
198 $is_v4_supported = $this->is_v4_supported();
199
200 $this->addon_migrations = array_filter(
201 $this->addon_migrations,
202 function ( $ver ) use ( $is_v4_supported, $version_threshold ) {
203 return ! ( version_compare( $ver, $version_threshold, '<=' ) && $is_v4_supported );
204 },
205 ARRAY_FILTER_USE_KEY
206 );
207 }
208
209 /**
210 * Filter migrations pre-4.0.0 if the addon is V4-supported.
211 */
212 protected function filter_migrations_by_v4_supported_status(): void {
213 $this->filter_migrations_by_version_threshold( '2.0.0' );
214 // Version should be replaced in implementation classes
215 }
216
217 /**
218 * Check if the current add-on is v4-supported
219 *
220 * @return bool
221 */
222 public function is_v4_supported() {
223 foreach ( $this->supported_template_ids as $template_id ) {
224 $args = [
225 'post_type' => 'yaymail_template',
226 'meta_key' => YayMailTemplate::META_KEYS['name'],
227 'meta_value' => $template_id,
228 'fields' => 'ids',
229 'numberposts' => -1,
230 'post_status' => [ 'publish', 'pending', 'future' ],
231 ];
232
233 $post_ids = get_posts( $args );
234 foreach ( $post_ids as $post_id ) {
235 $is_v4_supported = get_post_meta( $post_id, YayMailTemplate::META_KEYS['is_v4_supported'], true );
236 if ( ! $is_v4_supported ) {
237 return false;
238 }
239 }
240 }//end foreach
241 return true;
242 }
243
244 public function get_supported_template_ids() {
245 return $this->supported_template_ids;
246 }
247 }
248