PluginProbe
Cool Timeline (Horizontal & Vertical Timeline) / trunk
Cool Timeline (Horizontal & Vertical Timeline) vtrunk
3.4.0 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 2.2.3 2.3.3 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.6.1 2.7.1 2.8.3 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 All 79 releases
cool-timeline / admin / class-migration.php

class-migration.php in Cool Timeline (Horizontal & Vertical Timeline) trunk, at admin/class-migration.php

486 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly.
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound
7 class CTL_free_migrations {
8
9
10 /**
11 * Constructor.
12 */
13 public function __construct() {
14
15 add_action( 'admin_init', array( $this, 'ctl_postmeta_migration' ) );
16 add_action( 'admin_init', array( $this, 'ctl_settings_migration' ) );
17 add_action( 'admin_enqueue_scripts', array( $this, 'ctl_enqueue_migration_assets' ) );
18 add_action( 'wp_ajax_ctl_migrate_stories', array( $this, 'ctl_migrate_stories' ) );
19 }
20
21 /**
22 * Enqueue Timeline Express migration UI script on plugin settings.
23 *
24 * @return void
25 */
26 public function ctl_enqueue_migration_assets() {
27 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only screen detection.
28 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
29 if ( 'cool_timeline_settings' !== $page ) {
30 return;
31 }
32
33 if ( ! defined( 'CTL_PLUGIN_URL' ) ) {
34 return;
35 }
36
37 wp_enqueue_script(
38 'ctl-migration-js',
39 CTL_PLUGIN_URL . 'admin/assets/js/migration.js',
40 array( 'jquery' ),
41 defined( 'CTL_V' ) ? CTL_V : '1.0',
42 true
43 );
44
45 wp_localize_script(
46 'ctl-migration-js',
47 'ctl_migration',
48 array(
49 'nonce' => wp_create_nonce( 'ctl_migrate_nonce' ),
50 'redirect_url' => esc_url( admin_url( 'edit.php?post_type=cool_timeline' ) ),
51 'ajax_url' => admin_url( 'admin-ajax.php' ),
52 )
53 );
54 }
55
56 function ctl_postmeta_migration() {
57
58 if ( ! current_user_can( 'manage_options' ) ) {
59 return;
60 }
61
62
63 if ( get_option( 'ctl-postmeta-migration' ) ) {
64 return;
65 }
66
67 if ( version_compare( get_option( 'cool-free-timeline-v' ), '2.1', '>' ) && ! ( get_option( 'cool-timelne-v' ) ) ) {
68 return;
69 }
70
71 $args = array(
72 'post_type' => 'cool_timeline',
73 'post_status' => array( 'publish', 'future' ),
74 'numberposts' => -1,
75 );
76 $posts = get_posts( $args );
77
78
79 $story_type_key = array(
80 'ctl_story_date',
81 );
82
83 $story_media_key = array(
84 'img_cont_size',
85 );
86 $story_icon_key = array(
87 'fa_field_icon',
88 );
89
90 if ( isset( $posts ) && is_array( $posts ) && ! empty( $posts ) ) {
91 foreach ( $posts as $post ) {
92
93 $post_id = intval( $post->ID );
94 $array_icon_type = array(
95 'story_icon_type' => 'fontawesome',
96 );
97 $array_story_type = array(
98 'story_based_on' => 'default',
99 );
100 $array_story_media = array(
101 'story_format' => 'default',
102 );
103
104 foreach ( $story_icon_key as $item ) {
105 $item_value = sanitize_text_field( get_post_meta( $post_id, $item, true ) );
106 $array_icon_type[ $item ] = $item_value;
107 }
108
109 foreach ( $story_type_key as $item ) {
110 $item_value = sanitize_text_field( get_post_meta( $post_id, $item, true ) );
111 $array_story_type[ $item ] = $item_value;
112 }
113
114 foreach ( $story_media_key as $item ) {
115 $item_value = sanitize_text_field( get_post_meta( $post_id, $item, true ) );
116 $array_story_media[ $item ] = $item_value;
117 }
118
119 update_post_meta( $post_id, 'story_type', $array_story_type );
120 update_post_meta( $post_id, 'story_media', $array_story_media );
121 update_post_meta( $post_id, 'story_icon', $array_icon_type );
122 }
123
124 update_option( 'ctl-postmeta-migration', 'done' );
125 }
126 }
127
128
129 function ctl_settings_migration() {
130 if ( ! current_user_can( 'manage_options' ) ) {
131 return;
132 }
133
134 if ( ! get_option( 'cool_timeline_options' ) ) {
135 return;
136 }
137
138 $old_settings = get_option( 'cool_timeline_options' );
139
140 if ( ! is_array( $old_settings ) ) {
141 return;
142 }
143
144 $old_settings = map_deep( $old_settings, 'sanitize_text_field' );
145
146 $new_settings = $this->ctl_save_settings(
147 $old_settings,
148 array(
149 'face' => 'font-family',
150 'size' => 'font-size',
151 'weight' => 'font-weight',
152 'src' => 'url',
153 )
154 );
155
156 $new_settings = map_deep( $new_settings, 'sanitize_text_field' );
157
158 update_option( 'cool_timeline_settings', $new_settings );
159 update_option( 'ctl_settings_migration_status', 'done' );
160 delete_option( 'cool_timeline_options' );
161 }
162
163 function ctl_recursive_change_key( $arr, $set ) {
164 if ( is_array( $arr ) && is_array( $set ) ) {
165 $newArr = array();
166 foreach ( $arr as $k => $v ) {
167 $key = array_key_exists( $k, $set ) ? $set[ $k ] : $k;
168 $newArr[ $key ] = is_array( $v ) ? $this->ctl_recursive_change_key( $v, $set ) : $v;
169 if ( 'font-size' === $key ) {
170 $newArr[ $key ] = str_replace( 'px', '', $v );
171 }
172 }
173
174 return $newArr;
175 }
176 return $arr;
177 }
178
179 function ctl_save_settings( $arr, $set ) {
180 if ( is_array( $arr ) && is_array( $set ) ) {
181 $newArr = array();
182 $timeline_header = array();
183 $story_date_settings = array();
184 $story_content_settings = array();
185
186 $timeline_header_key = array( 'title_text', 'user_avatar' );
187
188 $story_date_settings_key = array( 'year_label_visibility' );
189 $story_content_settings_key = array( 'content_length', 'display_readmore' );
190 $arr = $this->ctl_recursive_change_key( $arr, $set );
191 foreach ( $arr as $key => $value ) {
192 if ( in_array( $key, $timeline_header_key, true ) ) {
193 if ( $key === 'user_avatar' ) {
194 if ( ! empty( $value ) ) {
195 $value = $this->ctl_recursive_change_key( $value, array( 'src' => 'url' ) );
196 $thumbnail_img = wp_get_attachment_image_src( $value['id'], 'thumbnail' );
197 $value += array(
198 'thumbnail' => $thumbnail_img[0],
199 'width' => '843',
200 'height' => '450',
201 );
202 $timeline_header += array( $key => $value );
203 }
204 } else {
205 $timeline_header += array( $key => $value );
206 }
207 } elseif ( in_array( $key, $story_date_settings_key, true ) ) {
208 $story_date_settings += array( $key => $value );
209 } elseif ( in_array( $key, $story_content_settings_key, true ) ) {
210 $story_content_settings += array( $key => $value );
211 } elseif ( $key === 'main_title_typo' ) {
212 $title_alignment = isset( $arr['title_alignment'] ) ? $arr['title_alignment'] : 'center';
213 $value += array(
214 'text-align' => $title_alignment,
215 'type' => 'google',
216 );
217 $newArr['main_title_typo'] = $value;
218 } elseif ( $key === 'post_title_text_style' ) {
219 $newArr['post_title_typo']['text-transform'] = $value;
220 } elseif ( $key === 'background' ) {
221 if ( isset( $value['enabled'] ) ) {
222 $newArr['timeline_background'] = '1';
223 $newArr['timeline_bg_color'] = $value['bg_color'];
224 } else {
225 $newArr['timeline_background'] = '0';
226 }
227 } elseif ( $key === 'post_title_typo' ) {
228 $value += array( 'type' => 'google' );
229 $newArr['ctl_date_typo']['font-family'] = $value['font-family'];
230 $newArr['ctl_date_typo']['font-weight'] = $value['font-weight'];
231 $newArr['ctl_date_typo']['font-size'] = '21';
232 $newArr['ctl_date_typo']['type'] = 'google';
233 $newArr['post_title_typo'] = $value;
234 } elseif ( $key === 'post_content_typo' ) {
235 $value += array( 'type' => 'google' );
236 $newArr['post_content_typo'] = $value;
237 } else {
238 $newArr[ $key ] = $value;
239 }
240 }
241
242 $newArr['timeline_header'] = $timeline_header;
243 $newArr['story_date_settings'] = $story_date_settings;
244 $newArr['story_content_settings'] = $story_content_settings;
245 return $newArr;
246 }
247 return $arr;
248 }
249
250 /**
251 * Migrate data from Timeline Express to Cool Timeline
252 */
253 public function migrate_timeline_express_to_cool_timeline() {
254 if ( ! current_user_can( 'manage_options' ) ) {
255 return;
256 }
257
258 if ( get_option( 'timeline_express_migrated' ) ) {
259 return;
260 }
261
262 $timeline_express_posts = $this->fetch_timeline_express_stories();
263 if ( empty( $timeline_express_posts ) ) {
264 return;
265 }
266
267 $migrate_stories = 0;
268 $cooltimeline_settings = $this->prepare_timeline_express_settings();
269
270 foreach ( $timeline_express_posts as $old_post ) {
271 if ( empty( $old_post->ID ) ) {
272 continue;
273 }
274
275 $migrate_stories++;
276 $this->migrate_timeline_express_story( $old_post );
277 }
278
279 update_option( 'timeline_express_migrated', 1 );
280 update_option( 'cool_timeline_settings', $cooltimeline_settings );
281 return $migrate_stories;
282 }
283
284 /**
285 * Fetch published Timeline Express stories.
286 *
287 * @return array
288 */
289 private function fetch_timeline_express_stories() {
290 $args = array(
291 'post_type' => 'te_announcements',
292 'posts_per_page' => -1,
293 'post_status' => 'publish',
294 );
295
296 return get_posts( $args );
297 }
298
299 /**
300 * Map Timeline Express settings into Cool Timeline settings.
301 *
302 * @return array
303 */
304 private function prepare_timeline_express_settings() {
305 $timeline_settings = get_option( 'timeline_express_storage' );
306 $cooltimeline_settings = (array) get_option( 'cool_timeline_settings', [] );
307
308 if ( ! is_array( $timeline_settings ) ) {
309 $timeline_settings = array();
310 }
311
312 if ( ! isset( $cooltimeline_settings['story_content_settings'] ) || ! is_array( $cooltimeline_settings['story_content_settings'] ) ) {
313 $cooltimeline_settings['story_content_settings'] = array();
314 }
315
316 $cooltimeline_settings = array_merge(
317 array(
318 'story_content_settings' => array(),
319 'first_post' => '',
320 'content_bg_color' => '',
321 'line_color' => '',
322 ),
323 $cooltimeline_settings
324 );
325
326 if ( ! empty( $timeline_settings['excerpt-trim-length'] ) ) {
327 $cooltimeline_settings['story_content_settings']['content_length'] = (string) (int) $timeline_settings['excerpt-trim-length'];
328 }
329
330 if ( isset( $timeline_settings['read-more-visibility'] ) ) {
331 $cooltimeline_settings['story_content_settings']['display_readmore'] = $timeline_settings['read-more-visibility'] === '1' ? 'yes' : 'no';
332 }
333
334 if ( isset( $timeline_settings['default-announcement-color'] ) ) {
335 $default_announcement_color = sanitize_hex_color( $timeline_settings['default-announcement-color'] );
336 if ( $default_announcement_color ) {
337 $cooltimeline_settings['first_post'] = $default_announcement_color;
338 }
339 }
340
341 if ( isset( $timeline_settings['announcement-bg-color'] ) ) {
342 $announcement_bg_color = sanitize_hex_color( $timeline_settings['announcement-bg-color'] );
343 if ( $announcement_bg_color ) {
344 $cooltimeline_settings['content_bg_color'] = $announcement_bg_color;
345 }
346 }
347
348 if ( isset( $timeline_settings['announcement-background-line-color'] ) ) {
349 $announcement_line_color = sanitize_hex_color( $timeline_settings['announcement-background-line-color'] );
350 if ( $announcement_line_color ) {
351 $cooltimeline_settings['line_color'] = $announcement_line_color;
352 }
353 }
354
355 return $cooltimeline_settings;
356 }
357
358 /**
359 * Migrate one Timeline Express story into a Cool Timeline story.
360 *
361 * @param WP_Post $old_post Timeline Express post.
362 */
363 private function migrate_timeline_express_story( $old_post ) {
364 $story_meta = $this->map_timeline_express_story_meta( $old_post );
365 $new_post = array(
366 'post_title' => sanitize_text_field( $old_post->post_title ),
367 'post_content' => wp_kses_post( $old_post->post_content ),
368 'post_excerpt' => $story_meta['excerpt'],
369 'post_type' => 'cool_timeline',
370 'post_status' => $old_post->post_status,
371 'post_date' => $old_post->post_date,
372 'post_name' => sanitize_title( $old_post->post_title ),
373 );
374
375 $new_post_id = wp_insert_post( $new_post );
376
377 if ( is_wp_error( $new_post_id ) || $new_post_id <= 0 ) {
378 return;
379 }
380
381 $this->save_timeline_express_story_meta( $new_post_id, $story_meta );
382 }
383
384 /**
385 * Map Timeline Express post meta to sanitized Cool Timeline meta values.
386 *
387 * @param WP_Post $old_post Timeline Express post.
388 * @return array
389 */
390 private function map_timeline_express_story_meta( $old_post ) {
391 $event_timestamp = intval( get_post_meta( $old_post->ID, 'announcement_date', true ) );
392 $icon_raw = get_post_meta( $old_post->ID, 'announcement_icon', true );
393 $color_raw = get_post_meta( $old_post->ID, 'announcement_color', true );
394
395 if ( strpos( $icon_raw, 'fa-' ) === false ) {
396 $icon_class = 'fa fa-' . sanitize_html_class( $icon_raw );
397 } else {
398 $icon_class = 'fa ' . sanitize_html_class( $icon_raw );
399 }
400
401 return array(
402 'attachment_id' => intval( get_post_meta( $old_post->ID, 'announcement_image_id', true ) ),
403 'color' => sanitize_hex_color( $color_raw ),
404 'event_timestamp' => $event_timestamp,
405 'excerpt' => wp_kses_post( get_post_meta( $old_post->ID, 'announcement_custom_excerpt', true ) ),
406 'formatted_for_meta' => $event_timestamp ? gmdate( 'm/d/Y h:i A', $event_timestamp ) : '',
407 'icon_class' => $icon_class,
408 );
409 }
410
411 /**
412 * Save migrated story metadata on the new Cool Timeline post.
413 *
414 * @param int $new_post_id New Cool Timeline post ID.
415 * @param array $story_meta Mapped Timeline Express story meta.
416 */
417 private function save_timeline_express_story_meta( $new_post_id, $story_meta ) {
418 clean_post_cache( $new_post_id );
419
420 if ( $story_meta['attachment_id'] && get_post_type( $story_meta['attachment_id'] ) === 'attachment' ) {
421 set_post_thumbnail( $new_post_id, $story_meta['attachment_id'] );
422 }
423
424 wp_update_post(
425 array(
426 'ID' => $new_post_id,
427 'post_status' => 'publish',
428 )
429 );
430
431 update_post_meta( $new_post_id, '_ctl_visible', 'yes' );
432
433 if ( ! empty( $story_meta['formatted_for_meta'] ) ) {
434 $story_type_serialized = array(
435 'ctl_story_date' => $story_meta['formatted_for_meta'],
436 );
437
438 update_post_meta( $new_post_id, 'ctl_story_timestamp', $story_meta['event_timestamp'] );
439 update_post_meta( $new_post_id, 'story_date', $story_meta['formatted_for_meta'] );
440 update_post_meta( $new_post_id, 'story_type', $story_type_serialized );
441 }
442
443 if ( ! empty( $story_meta['color'] ) ) {
444 update_post_meta( $new_post_id, 'story_color', $story_meta['color'] );
445 }
446
447 if ( ! empty( $story_meta['icon_class'] ) ) {
448 $story_icon_serialized = array(
449 'fa_field_icon' => $story_meta['icon_class'],
450 );
451 update_post_meta( $new_post_id, 'story_icon', $story_icon_serialized );
452 }
453 }
454
455 public function ctl_migrate_stories() {
456
457 check_ajax_referer( 'ctl_migrate_nonce', 'nonce' );
458
459 if ( ! current_user_can( 'manage_options' ) ) {
460 return wp_send_json_error( array(
461 'message' => __( 'Unauthorized', 'cool-timeline' ),
462 ) );
463
464 }
465
466 $total_stories = $this->migrate_timeline_express_to_cool_timeline();
467
468 if ( empty( $total_stories ) || $total_stories === 0 ) {
469
470 return wp_send_json_error( array(
471 'status' => 'no_attachments',
472 'message' => __( 'No Attachment Found To Migrate.', 'cool-timeline' ),
473 ) );
474
475 }
476
477 wp_send_json_success([
478 'message' => __( 'Migration Completed', 'cool-timeline' ),
479 'total_stories' => $total_stories
480 ]);
481 }
482
483
484 }
485 new CTL_free_migrations();
486