PluginProbe
YayMail – WooCommerce Email Customizer / 4.4.7
YayMail – WooCommerce Email Customizer v4.4.7
4.4.7 4.4.6 4.4.5 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 All 58 releases
yaymail / src / Migrations / AbstractAddonMigrationManager.php

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

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