PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.0.3.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.0.3.2
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
mainwp / pages / page-mainwp-post-page-handler.php

page-mainwp-post-page-handler.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 5.0.3.2, at pages/page-mainwp-post-page-handler.php

1,384 lines 51.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Post Page Handler.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 /**
11 * Class MainWP_Post_Page_Handler
12 *
13 * @uses MainWP_Bulk_Add
14 */
15 class MainWP_Post_Page_Handler {
16
17 /**
18 * Get Class Name
19 *
20 * @return string __CLASS__
21 */
22 public static function get_class_name() {
23 return __CLASS__;
24 }
25
26 /**
27 * Method add_meta()
28 *
29 * Add post meta data defined in $_POST superglobal for post with given ID.
30 *
31 * @since 1.2.0
32 *
33 * @param int $post_ID Post or Page ID.
34 * @return mixed False or add_post_meta()
35 */
36 public static function add_meta( $post_ID ) {
37 $post_ID = (int) $post_ID;
38
39 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
40 $metakeyselect = isset( $_POST['metakeyselect'] ) ? sanitize_text_field( wp_unslash( $_POST['metakeyselect'] ) ) : '';
41 $metakeyinput = isset( $_POST['metakeyinput'] ) ? sanitize_text_field( wp_unslash( $_POST['metakeyinput'] ) ) : '';
42 $metavalue = isset( $_POST['metavalue'] ) ? sanitize_text_field( wp_unslash( $_POST['metavalue'] ) ) : '';
43 if ( is_string( $metavalue ) ) {
44 $metavalue = trim( $metavalue );
45 }
46 // phpcs:enable
47
48 if ( ( ( '#NONE#' !== $metakeyselect ) && ! empty( $metakeyselect ) ) || ! empty( $metakeyinput ) ) {
49 if ( '#NONE#' !== $metakeyselect ) {
50 $metakey = $metakeyselect;
51 }
52
53 if ( $metakeyinput ) {
54 $metakey = $metakeyinput;
55 }
56
57 if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) ) {
58 return false;
59 }
60
61 $metakey = wp_slash( $metakey );
62
63 return add_post_meta( $post_ID, $metakey, $metavalue );
64 }
65
66 return false;
67 }
68
69 /**
70 * Method ajax_add_meta()
71 *
72 * Ajax process to add post meta data.
73 *
74 * @uses \MainWP\Dashboard\MainWP_Post_Handler::secure_request()
75 * @uses \MainWP\Dashboard\MainWP_Post::list_meta_row()
76 */
77 public static function ajax_add_meta() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
78
79 MainWP_Post_Handler::instance()->secure_request( 'mainwp_post_addmeta' );
80
81 $c = 0;
82 $pid = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
83
84 if ( isset( $_POST['metakeyselect'] ) || isset( $_POST['metakeyinput'] ) ) {
85 if ( ! current_user_can( 'edit_post', $pid ) ) {
86 wp_die( -1 );
87 }
88 if ( isset( $_POST['metakeyselect'] ) && '#NONE#' === $_POST['metakeyselect'] && empty( $_POST['metakeyinput'] ) ) {
89 wp_die( 1 );
90 }
91 $mid = self::add_meta( $pid );
92 if ( ! $mid ) {
93 wp_send_json( array( 'error' => esc_html__( 'Please provide a custom field value.', 'mainwp' ) ) );
94 }
95
96 $meta = get_metadata_by_mid( 'post', $mid );
97 $pid = (int) $meta->post_id;
98 $meta = get_object_vars( $meta );
99
100 $data = MainWP_Post::list_meta_row( $meta, $c );
101
102 } elseif ( isset( $_POST['delete_meta'] ) && 'yes' === $_POST['delete_meta'] ) {
103 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
104
105 check_ajax_referer( "delete-meta_$id", 'meta_nonce' );
106 $meta = get_metadata_by_mid( 'post', $id );
107 if ( ! $meta ) {
108 wp_send_json( array( 'ok' => 1 ) );
109 }
110
111 if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $meta->post_id, $meta->meta_key ) ) {
112 wp_die( -1 );
113 }
114
115 if ( delete_meta( $meta->meta_id ) ) {
116 wp_send_json( array( 'ok' => 1 ) );
117 }
118
119 wp_die( 0 );
120
121 } else {
122 $mid = isset( $_POST['meta'] ) ? (int) key( wp_unslash( $_POST['meta'] ) ) : 0; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
123 $key = isset( $_POST['meta'][ $mid ]['key'] ) ? sanitize_text_field( wp_unslash( $_POST['meta'][ $mid ]['key'] ) ) : '';
124 $value = isset( $_POST['meta'][ $mid ]['value'] ) ? sanitize_text_field( wp_unslash( $_POST['meta'][ $mid ]['value'] ) ) : '';
125 if ( '' === trim( $key ) ) {
126 wp_send_json( array( 'error' => esc_html__( 'Please provide a custom field name.', 'mainwp' ) ) );
127 }
128 $meta = get_metadata_by_mid( 'post', $mid );
129 if ( ! $meta ) {
130 wp_die( 0 );
131 }
132 if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
133 ! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
134 ! current_user_can( 'edit_post_meta', $meta->post_id, $key ) ) {
135 wp_die( -1 );
136 }
137 if ( $meta->meta_value !== $value || $meta->meta_key !== $key ) {
138 $u = update_metadata_by_mid( 'post', $mid, $value, $key );
139 if ( ! $u ) {
140 wp_die( 0 );
141 }
142 }
143
144 $data = MainWP_Post::list_meta_row(
145 array(
146 'meta_key' => $key, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- deprecated, compatible.
147 'meta_value' => $value, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- deprecated, compatible.
148 'meta_id' => $mid,
149 ),
150 $c
151 );
152 }
153
154 wp_send_json( array( 'result' => $data ) );
155 }
156
157
158 /**
159 * Method ajax_handle_get_categories()
160 *
161 * Get categories.
162 *
163 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_by_ids()
164 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_by_group_ids()
165 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
166 */
167 public static function ajax_handle_get_categories() { // phpcs:ignore -- complex method. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
168 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
169 $websites = array();
170 if ( isset( $_REQUEST['sites'] ) && ( '' !== $_REQUEST['sites'] ) ) {
171 $siteIds = explode( ',', urldecode( wp_unslash( $_REQUEST['sites'] ) ) ); // do not sanitize encoded values.
172 $siteIdsRequested = array();
173 foreach ( $siteIds as $siteId ) {
174 $siteId = $siteId;
175 if ( ! MainWP_Utility::ctype_digit( $siteId ) ) {
176 continue;
177 }
178 $siteIdsRequested[] = $siteId;
179 }
180
181 $websites = MainWP_DB::instance()->get_websites_by_ids( $siteIdsRequested );
182 } elseif ( isset( $_REQUEST['groups'] ) && ( '' !== $_REQUEST['groups'] ) ) {
183 $groupIds = explode( ',', sanitize_text_field( urldecode( wp_unslash( $_REQUEST['groups'] ) ) ) ); // sanitize ok.
184 $groupIdsRequested = array();
185 foreach ( $groupIds as $groupId ) {
186 $groupId = $groupId;
187
188 if ( ! MainWP_Utility::ctype_digit( $groupId ) ) {
189 continue;
190 }
191 $groupIdsRequested[] = $groupId;
192 }
193
194 $websites = MainWP_DB::instance()->get_websites_by_group_ids( $groupIdsRequested );
195 } elseif ( isset( $_REQUEST['clients'] ) && ( '' !== $_REQUEST['clients'] ) ) {
196 $clientIds = explode( ',', sanitize_text_field( urldecode( wp_unslash( $_REQUEST['clients'] ) ) ) ); // sanitize ok.
197 $clientIdsRequested = array();
198 foreach ( $clientIds as $clientId ) {
199
200 if ( ! MainWP_Utility::ctype_digit( $clientId ) ) {
201 continue;
202 }
203 $clientIdsRequested[] = $clientId;
204 }
205
206 $data_fields = array(
207 'id',
208 'url',
209 'name',
210 'categories',
211 'sync_errors',
212 );
213 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
214 $clientIdsRequested,
215 array(
216 'select_data' => $data_fields,
217 )
218 );
219 }
220
221 $selectedCategories = array();
222 $selectedCategories2 = array();
223
224 if ( isset( $_REQUEST['selected_categories'] ) && ( '' !== $_REQUEST['selected_categories'] ) ) {
225 $selectedCategories = explode( ',', sanitize_text_field( urldecode( wp_unslash( $_REQUEST['selected_categories'] ) ) ) );
226 }
227
228 if ( ! is_array( $selectedCategories ) ) {
229 $selectedCategories = array();
230 }
231
232 $allCategories_new_tree = array();
233 $allCategories = array( 'Uncategorized' );
234
235 if ( 0 < count( $websites ) ) {
236 foreach ( $websites as $website ) {
237 $new_cats = json_decode( $website->categories, true );
238 if ( is_array( $new_cats ) && ( 0 < count( $new_cats ) ) ) {
239 $current = current( $new_cats );
240 if ( is_array( $current ) && ! empty( $current ) ) { // new site's category format data.
241 self::arrange_categories_list( $new_cats, $allCategories_new_tree );
242 } elseif ( is_string( $current ) ) { // old format.
243 $allCategories = array_unique( array_merge( $allCategories, $new_cats ) );
244 }
245 }
246 }
247 }
248
249 $allCategories = array_unique( array_merge( $allCategories, $selectedCategories ) );
250
251 ob_start();
252 echo '<div class="item" data-value="Uncategorized" class="sitecategory-list">Uncategorized</div>';
253
254 if ( ! empty( $allCategories ) || ! empty( $allCategories_new_tree ) ) {
255 ?>
256 <?php
257 $check_printed_cats_names = array();
258
259 if ( ! empty( $allCategories_new_tree ) ) {
260 // print new casts list.
261 self::print_catergories_tree( $allCategories_new_tree, $check_printed_cats_names );
262 }
263
264 if ( 0 < count( $allCategories ) ) {
265 echo '<div class="ui horizontal divider"></div>';
266 natcasesort( $allCategories );
267 foreach ( $allCategories as $category ) {
268 if ( 'Uncategorized' === $category || isset( $check_printed_cats_names[ $category ] ) ) {
269 continue; // printed.
270 }
271 echo '<div class="item" data-value="' . esc_attr( $category ) . '" class="sitecategory-list">' . esc_html( $category ) . '</div>';
272 }
273 }
274 }
275 // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
276
277 $output = ob_get_clean();
278 wp_die( wp_json_encode( array( 'content' => $output ) ) );
279 }
280
281 /**
282 * Method print_catergories_tree()
283 *
284 * @param array $print_cats categories to print.
285 * @param array $check_printed_cats_names check printed cats slugs.
286 */
287 public static function print_catergories_tree( $print_cats, &$check_printed_cats_names = array() ) {
288 foreach ( $print_cats as $item ) {
289
290 $level = isset( $item['level'] ) ? $item['level'] : 0;
291
292 if ( 'Uncategorized' !== $item['name'] && ! isset( $check_printed_cats_names[ $item['slug'] ] ) ) {
293 $cls = 'category-select-item-sub' . ( ! empty( $level ) ? intval( $level ) : '' );
294
295 $check_printed_cats_names[ $item['slug'] ] = 1;
296 echo '<div class="item ' . esc_attr( $cls ) . '" data-value="' . esc_attr( $item['name'] ) . '" data-slug="' . esc_attr( $item['slug'] ) . '" class="sitecategory-list">' . esc_html( $item['name'] ) . '</div>';
297 }
298
299 if ( ! empty( $item['children'] ) ) {
300 self::print_catergories_tree( $item['children'], $check_printed_cats_names );
301 }
302 }
303 }
304
305 /**
306 * Method arrange_categories_list()
307 *
308 * Tweaked John#105641 at StackOver#4284616.
309 *
310 * @param array $categories categories.
311 * @param array $save_all_cats_tree all categories tree.
312 */
313 public static function arrange_categories_list( $categories, &$save_all_cats_tree ) {
314
315 if ( ! is_array( $save_all_cats_tree ) ) {
316 $save_all_cats_tree = array();
317 }
318 $tree_cats = $save_all_cats_tree;
319 $all_cats = array();
320 $child_cats = array();
321
322 foreach ( $categories as $cat ) {
323
324 if ( ! is_array( $cat ) || empty( $cat['name'] ) ) {
325 continue;
326 }
327
328 $cat['children'] = array();
329 $term_id = $cat['term_id'];
330
331 // If this is a top-level.
332 if ( empty( $cat['parent'] ) ) {
333 $cat['level'] = 0;
334 $all_cats[ $term_id ] = $cat;
335 $tree_cats[] =& $all_cats[ $term_id ];
336 // If this isn't a top-level.
337 } else {
338 $cat['level'] = isset( $all_cats[ $cat['parent'] ] ) && isset( $all_cats[ $cat['parent'] ]['level'] ) ? $all_cats[ $cat['parent'] ]['level'] + 1 : 1;
339 $child_cats[ $term_id ] = $cat;
340 }
341 }
342
343 $stop = count( $categories );
344 $limit = 0;
345 $count = count( $child_cats );
346 // Process child cats.
347 while ( $count > 0 && $limit < $stop ) {
348 foreach ( $child_cats as $cat ) {
349 $term_id = $cat['term_id'];
350 $pid = isset( $cat['parent'] ) ? $cat['parent'] : -1;
351
352 if ( isset( $all_cats[ $pid ] ) ) {
353 $cat['level'] = isset( $all_cats[ $pid ] ) && isset( $all_cats[ $pid ]['level'] ) ? $all_cats[ $pid ]['level'] + 1 : 1;
354 $all_cats[ $term_id ] = $cat;
355 $all_cats[ $pid ]['children'][] =& $all_cats[ $term_id ];
356 unset( $child_cats[ $cat['term_id'] ] );
357 }
358 }
359 ++$limit;
360 }
361 $save_all_cats_tree = $tree_cats; // to prevent it deleted by reference.
362 }
363
364 /**
365 * Method posting_bulk()
366 *
367 * Create bulk posts on sites.
368 */
369 public static function posting_bulk() {
370 $p_id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
371
372 if ( ! isset( $_GET['posting_nonce'] ) || ( isset( $_GET['posting_nonce'] ) && ! wp_verify_nonce( sanitize_key( $_GET['posting_nonce'] ), 'posting_nonce_' . $p_id ) ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
373 wp_die( 'Invalid request!' );
374 }
375
376 $posting_bulk_sites = apply_filters( 'mainwp_posts_posting_bulk_sites', false );
377 ?>
378 <input type="hidden" name="bulk_posting_id" id="bulk_posting_id" value="<?php echo intval( $p_id ); ?>"/>
379 <?php
380 if ( ! $posting_bulk_sites ) {
381 self::posting( $p_id );
382 } else {
383 self::posting_prepare( $p_id );
384 }
385 }
386
387 /**
388 * Method posting()
389 *
390 * Create bulk posts on sites.
391 *
392 * @param int $post_id Post or Page ID.
393 *
394 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
395 * @uses \MainWP\Dashboard\MainWP_DB::query()
396 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
397 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
398 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
399 * @uses \MainWP\Dashboard\MainWP_System_Utility::maybe_unserialyze()
400 * @uses \MainWP\Dashboard\MainWP_Bulk_Add::get_class_name()
401 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
402 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
403 */
404 public static function posting( $post_id ) { // phpcs:ignore -- complex method. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
405 $p_id = $post_id;
406
407 $edit_id = get_post_meta( $post_id, '_mainwp_edit_post_id', true );
408
409 ?>
410 <div class="ui modal" id="mainwp-posting-post-modal">
411 <i class="close icon"></i>
412 <div class="header"><?php $edit_id ? esc_html_e( 'Edit Post', 'mainwp' ) : esc_html_e( 'New Post', 'mainwp' ); ?></div>
413 <div class="scrolling content">
414 <?php
415 /**
416 * Before Post post action
417 *
418 * Fires right before posting the 'bulkpost' to child sites.
419 *
420 * @param int $p_id Page ID.
421 *
422 * @since Unknown
423 */
424 do_action( 'mainwp_bulkpost_before_post', $p_id );
425
426 $skip_post = false;
427 if ( $p_id ) {
428 if ( 'yes' === get_post_meta( $p_id, '_mainwp_skip_posting', true ) ) {
429 $skip_post = true;
430 wp_delete_post( $p_id, true );
431 }
432 }
433
434 if ( ! $skip_post ) {
435 if ( $p_id ) {
436 self::posting_posts( $p_id, 'posting' );
437 } else {
438 ?>
439 <div class="error">
440 <p>
441 <strong><?php esc_html_e( 'ERROR', 'mainwp' ); ?></strong>: <?php esc_html_e( 'An undefined error occured!', 'mainwp' ); ?>
442 </p>
443 </div>
444 <?php
445 }
446 }
447 ?>
448 </div>
449 <div class="actions">
450 <?php do_action( 'mainwp_posts_posting_popup_actions', $post_id ); ?>
451 <a href="admin.php?page=PostBulkAdd" class="ui green button new-bulk-post"><?php esc_html_e( 'New Post', 'mainwp' ); ?></a>
452 </div>
453 </div>
454 <div class="ui active inverted dimmer" id="mainwp-posting-running">
455 <div class="ui indeterminate large text loader"><?php esc_html_e( 'Running ...', 'mainwp' ); ?></div>
456 </div>
457 <script type="text/javascript">
458 jQuery( document ).ready( function () {
459 jQuery( "#mainwp-posting-running" ).hide();
460 jQuery( "#mainwp-posting-post-modal" ).modal( {
461 closable: true,
462 onHide: function() {
463 location.href = 'admin.php?page=PostBulkManage';
464 }
465 } ).modal( 'show' );
466 } );
467 </script>
468 <?php
469 }
470
471 /**
472 * Method posting_prepare()
473 *
474 * Posting posts.
475 *
476 * @param int $post_id Post or Page ID.
477 */
478 public static function posting_prepare( $post_id ) {
479 $edit_id = get_post_meta( $post_id, '_mainwp_edit_post_id', true );
480 ?>
481 <div class="ui modal" id="mainwp-posting-post-modal">
482 <i class="close icon"></i>
483 <div class="header"><?php $edit_id ? esc_html_e( 'Edit Post', 'mainwp' ) : esc_html_e( 'New Post', 'mainwp' ); ?></div>
484 <div class="scrolling content">
485 <?php
486 if ( $post_id ) {
487 self::posting_posts( $post_id, 'preparing' );
488 } else {
489 ?>
490 <div class="error">
491 <p>
492 <strong><?php esc_html_e( 'ERROR', 'mainwp' ); ?></strong>: <?php esc_html_e( 'An undefined error occured!', 'mainwp' ); ?>
493 </p>
494 </div>
495 <?php
496 }
497 ?>
498 </div>
499 <div class="actions">
500 <a href="admin.php?page=PostBulkAdd" class="ui green button"><?php esc_html_e( 'New Post', 'mainwp' ); ?></a>
501 </div>
502 </div>
503 <div class="ui active inverted dimmer" id="mainwp-posting-running">
504 <div class="ui indeterminate large text loader"><?php esc_html_e( 'Running ...', 'mainwp' ); ?></div>
505 </div>
506 <script type="text/javascript">
507 jQuery( document ).ready( function () {
508 jQuery( "#mainwp-posting-running" ).hide();
509 jQuery( "#mainwp-posting-post-modal" ).modal( {
510 closable: true,
511 onHide: function() {
512 location.href = 'admin.php?page=PostBulkManage';
513 }
514 } ).modal( 'show' );
515 mainwp_post_posting_start_next( true );
516 } );
517 </script>
518 <?php
519 }
520
521
522 /**
523 * Method ajax_posting_posts()
524 *
525 * Ajax Posting posts.
526 */
527 public static function ajax_posting_posts() {
528 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
529 MainWP_Post_Handler::instance()->secure_request( 'mainwp_post_postingbulk' );
530 $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : false;
531 if ( $post_id ) {
532 self::posting_posts( $post_id, 'ajax_posting' );
533 }
534 // phpcs:enable
535 die();
536 }
537
538 /**
539 * Method ajax_get_sites_of_groups()
540 *
541 * Ajax Get sites of groups.
542 */
543 public static function ajax_get_sites_of_groups() {
544 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
545 MainWP_Post_Handler::instance()->secure_request( 'mainwp_get_sites_of_groups' );
546 $groups = isset( $_POST['groups'] ) && is_array( $_POST['groups'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['groups'] ) ) : '';
547 $websites = MainWP_DB::instance()->get_websites_by_group_ids( $groups );
548 // phpcs:enable
549 $site_Ids = array();
550 if ( $websites ) {
551 foreach ( $websites as $website ) {
552 $site_Ids[] = $website->id;
553 }
554 }
555 die( wp_json_encode( $site_Ids ) );
556 }
557
558 /**
559 * Method posting_posts()
560 *
561 * Posting posts.
562 *
563 * @param int $post_id Post or Page ID.
564 * @param string $what What posting process.
565 */
566 public static function posting_posts( $post_id, $what ) { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
567
568 if ( empty( $post_id ) ) {
569 return false;
570 }
571
572 $succes_message = '';
573 $edit_id = get_post_meta( $post_id, '_mainwp_edit_post_id', true );
574 if ( $edit_id ) {
575 $succes_message = esc_html__( 'Post has been updated successfully', 'mainwp' );
576 } else {
577 $succes_message = esc_html__( 'New post created', 'mainwp' );
578 }
579
580 $id = $post_id;
581 $_post = get_post( $id );
582
583 if ( $_post ) {
584 $selected_by = 'site';
585 $selected_groups = array();
586 $selected_sites = array();
587 $selected_clients = array();
588
589 if ( 'posting' === $what || 'preparing' === $what ) {
590 $selected_by = get_post_meta( $id, '_selected_by', true );
591 $val = get_post_meta( $id, '_selected_sites', true );
592 $selected_sites = MainWP_System_Utility::maybe_unserialyze( $val );
593 $val = get_post_meta( $id, '_selected_groups', true );
594 $selected_groups = MainWP_System_Utility::maybe_unserialyze( $val );
595 $selected_clients = get_post_meta( $id, '_selected_clients', true );
596 $selected_by = apply_filters( 'mainwp_posting_post_selected_by', $selected_by, $id );
597 } elseif ( 'ajax_posting' === $what ) {
598 $site_id = isset( $_POST['site_id'] ) ? intval( $_POST['site_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
599 if ( $site_id ) {
600 $selected_sites = array( $site_id );
601 }
602 }
603
604 $selected_sites = apply_filters( 'mainwp_posting_post_selected_sites', $selected_sites, $id );
605 $selected_groups = apply_filters( 'mainwp_posting_selected_groups', $selected_groups, $id );
606 $selected_clients = apply_filters( 'mainwp_posting_selected_clients', $selected_clients, $id );
607
608 if ( 'preparing' !== $what ) {
609 $post_category = base64_decode( get_post_meta( $id, '_categories', true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
610
611 $post_tags = base64_decode( get_post_meta( $id, '_tags', true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
612 $post_slug = base64_decode( get_post_meta( $id, '_slug', true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
613 $post_custom = get_post_custom( $id );
614
615 $galleries = get_post_gallery( $id, false );
616 $post_gallery_images = array();
617
618 if ( is_array( $galleries ) && isset( $galleries['ids'] ) ) {
619 $attached_images = explode( ',', $galleries['ids'] );
620 foreach ( $attached_images as $attachment_id ) {
621 $attachment = get_post( $attachment_id );
622 if ( $attachment ) {
623 $post_gallery_images[] = array(
624 'id' => $attachment_id,
625 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
626 'caption' => MainWP_Utility::esc_content( $attachment->post_excerpt, 'mixed' ),
627 'description' => $attachment->post_content,
628 'src' => $attachment->guid,
629 'title' => htmlspecialchars( $attachment->post_title ),
630 );
631 }
632 }
633 }
634
635 include_once ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR . 'post-thumbnail-template.php';
636 $featured_image_id = get_post_thumbnail_id( $id );
637 $post_featured_image = null;
638 $featured_image_data = null;
639 $mainwp_upload_dir = wp_upload_dir();
640
641 // to fix.
642 $post_status = $_post->post_status;
643 if ( 'publish' === $post_status ) {
644 $post_status = get_post_meta( $id, '_edit_post_status', true );
645 }
646
647 /**
648 * Post status
649 *
650 * Sets post status when posting 'bulkpost' to child sites.
651 *
652 * @param int $id Post ID.
653 *
654 * @since Unknown
655 */
656 $post_status = apply_filters( 'mainwp_posting_bulkpost_post_status', $post_status, $id );
657 $new_post = array(
658 'post_title' => $_post->post_title,
659 'post_content' => $_post->post_content,
660 'post_status' => $post_status,
661 'post_date' => $_post->post_date,
662 'post_date_gmt' => $_post->post_date_gmt,
663 'post_tags' => $post_tags,
664 'post_name' => $post_slug,
665 'post_excerpt' => MainWP_Utility::esc_content( $_post->post_excerpt, 'mixed' ),
666 'post_password' => $_post->post_password,
667 'comment_status' => $_post->comment_status,
668 'ping_status' => $_post->ping_status,
669 'mainwp_post_id' => $_post->ID,
670 );
671
672 if ( ! empty( $featured_image_id ) ) {
673 $img = wp_get_attachment_image_src( $featured_image_id, 'full' );
674 $post_featured_image = $img[0];
675 $attachment = get_post( $featured_image_id );
676 $featured_image_data = array(
677 'alt' => get_post_meta( $featured_image_id, '_wp_attachment_image_alt', true ),
678 'caption' => MainWP_Utility::esc_content( $attachment->post_excerpt, 'mixed' ),
679 'description' => $attachment->post_content,
680 'title' => htmlspecialchars( $attachment->post_title ),
681 );
682 }
683 }
684
685 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
686
687 $dbwebsites = array();
688
689 if ( 'site' === $selected_by ) {
690 foreach ( $selected_sites as $k ) {
691 if ( MainWP_Utility::ctype_digit( $k ) ) {
692 $website = MainWP_DB::instance()->get_website_by_id( $k );
693 if ( empty( $website->sync_errors ) && ! MainWP_System_Utility::is_suspended_site( $website ) ) {
694 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
695 }
696 }
697 }
698 } elseif ( 'client' === $selected_by ) {
699 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
700 $selected_clients,
701 array(
702 'select_data' => $data_fields,
703 )
704 );
705 if ( $websites ) {
706 foreach ( $websites as $website ) {
707 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
708 continue;
709 }
710 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
711 }
712 }
713 } elseif ( 'group' === $selected_by ) {
714 foreach ( $selected_groups as $k ) {
715 if ( MainWP_Utility::ctype_digit( $k ) ) {
716 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $k ) );
717 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
718 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
719 continue;
720 }
721 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
722 }
723 MainWP_DB::free_result( $websites );
724 }
725 }
726 }
727
728 if ( 'preparing' === $what ) {
729 ?>
730 <div class="ui relaxed list">
731 <?php
732 foreach ( $dbwebsites as $website ) {
733 ?>
734 <div class="item site-bulk-posting" site-id="<?php echo intval( $website->id ); ?>" status="queue"><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a>
735 <div class="right floated content progress"><i class="clock outline icon"></i></div>
736 </div>
737 <?php } ?>
738 </div>
739 <?php
740 } else {
741
742 $output = new \stdClass();
743 $output->ok = array();
744 $output->errors = array();
745 $startTime = time();
746
747 if ( 0 < count( $dbwebsites ) ) {
748
749 // prepare $post_custom values.
750 $new_post_custom = array();
751 foreach ( $post_custom as $meta_key => $meta_values ) {
752 $new_meta_values = array();
753 foreach ( $meta_values as $key_value => $meta_value ) {
754 if ( is_serialized( $meta_value ) ) {
755 $meta_value = unserialize( $meta_value ); // phpcs:ignore -- internal value safe.
756 }
757 $new_meta_values[ $key_value ] = $meta_value;
758 }
759 $new_post_custom[ $meta_key ] = $new_meta_values;
760 }
761
762 $post_data = array(
763 'new_post' => base64_encode( wp_json_encode( $new_post ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
764 'post_custom' => base64_encode( wp_json_encode( $new_post_custom ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
765 'post_category' => ! empty( $post_category ) ? base64_encode( $post_category ) : '', // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
766 'post_featured_image' => ( null !== $post_featured_image ) ? base64_encode( $post_featured_image ) : null, // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
767 'post_gallery_images' => base64_encode( wp_json_encode( $post_gallery_images ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
768 'mainwp_upload_dir' => base64_encode( wp_json_encode( $mainwp_upload_dir ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
769 'featured_image_data' => ( null !== $featured_image_data ) ? base64_encode( wp_json_encode( $featured_image_data ) ) : null, // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
770 );
771 MainWP_Connect::fetch_urls_authed(
772 $dbwebsites,
773 'newpost',
774 $post_data,
775 array(
776 MainWP_Bulk_Add::get_class_name(),
777 'posting_bulk_handler',
778 ),
779 $output
780 );
781 }
782
783 foreach ( $dbwebsites as $website ) {
784 if ( isset( $output->ok[ $website->id ] ) && ( 1 === (int) $output->ok[ $website->id ] ) && ( isset( $output->added_id[ $website->id ] ) ) ) {
785 $links = isset( $output->link[ $website->id ] ) ? $output->link[ $website->id ] : null;
786 do_action_deprecated( 'mainwp-post-posting-post', array( $website, $output->added_id[ $website->id ], $links ), '4.0.7.2', 'mainwp_post_posting_post' ); // @deprecated Use 'mainwp_post_posting_page' instead.
787 do_action_deprecated( 'mainwp-bulkposting-done', array( $_post, $website, $output ), '4.0.7.2', 'mainwp_bulkposting_done' ); // @deprecated Use 'mainwp_bulkposting_done' instead.
788
789 /**
790 * Posting post
791 *
792 * Fires while posting post.
793 *
794 * @param object $website Object containing child site data.
795 * @param int $output->added_id[ $website->id ] Child site ID.
796 * @param array $links Links.
797 *
798 * @since Unknown
799 */
800 do_action( 'mainwp_post_posting_post', $website, $output->added_id[ $website->id ], $links );
801
802 /**
803 * Posting post completed
804 *
805 * Fires after the post posting process is completed.
806 *
807 * @param array $_post Array containing the post data.
808 * @param object $website Object containing child site data.
809 * @param array $output Output data.
810 *
811 * @since Unknown
812 */
813 do_action( 'mainwp_bulkposting_done', $_post, $website, $output );
814 }
815 }
816
817 /**
818 * After posting a new post
819 *
820 * Sets data after the posting process to show the process feedback.
821 *
822 * @param array $_post Array containing the post data.
823 * @param array $dbwebsites Array containing processed sites.
824 * @param array $output Output data.
825 *
826 * @since Unknown
827 */
828 $newExtensions = apply_filters_deprecated( 'mainwp-after-posting-bulkpost-result', array( false, $_post, $dbwebsites, $output ), '4.0.7.2', 'mainwp_after_posting_bulkpost_result' );
829
830 $after_posting = false;
831 if ( 'posting' === $what ) {
832 // supported for bulk posting, not for ajax posting.
833 $after_posting = apply_filters( 'mainwp_after_posting_bulkpost_result', $newExtensions, $_post, $dbwebsites, $output );
834 }
835
836 $posting_succeed = false;
837
838 if ( false === $after_posting ) {
839 if ( 'posting' === $what ) {
840 ?>
841 <div class="ui relaxed list">
842 <?php
843 foreach ( $dbwebsites as $website ) {
844 ?>
845 <div class="item"><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a>
846 :
847 <?php
848 if ( isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ) {
849 echo esc_html( $succes_message ) . ' <a href="' . esc_html( $output->link[ $website->id ] ) . '" class="mainwp-may-hide-referrer" target="_blank">View Post</a>';
850 $posting_succeed = true;
851 } else {
852 echo $output->errors[ $website->id ]; // phpcs:ignore WordPress.Security.EscapeOutput
853 }
854 ?>
855 </div>
856 <?php } ?>
857 </div>
858 <?php } ?>
859 <?php
860 } else {
861 $posting_succeed = true;
862 }
863
864 $ajax_result = '';
865 if ( 'ajax_posting' === $what ) {
866 if ( isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ) {
867 $ajax_result = esc_html( $succes_message ) . ' <a href="' . esc_html( $output->link[ $website->id ] ) . '" class="mainwp-may-hide-referrer" target="_blank">View Post</a>';
868 $posting_succeed = true;
869 } else {
870 $ajax_result = $output->errors[ $website->id ];
871 }
872 }
873
874 $delete_bulk_post = apply_filters( 'mainwp_after_posting_delete_bulk_post', true, $posting_succeed );
875 $do_not_del = get_post_meta( $id, '_bulkpost_do_not_del', true );
876
877 $last_ajax_posting = false;
878 if ( 'ajax_posting' === $what ) {
879 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
880 $total = isset( $_POST['total'] ) ? intval( $_POST['total'] ) : 0;
881 $count = isset( $_POST['count'] ) ? intval( $_POST['count'] ) : 0;
882 $delete_bulkpost = isset( $_POST['delete_bulkpost'] ) && ! empty( $_POST['delete_bulkpost'] ) ? true : false;
883 // phpcs:enable
884 if ( $delete_bulkpost ) {
885 $last_ajax_posting = true;
886 }
887 }
888
889 $deleted_bulk_post = false;
890 if ( 'yes' !== $do_not_del && $delete_bulk_post && ( 'posting' === $what || $last_ajax_posting ) ) {
891 wp_delete_post( $id, true );
892 $deleted_bulk_post = true;
893 }
894
895 $edit_link = '';
896 if ( ! $deleted_bulk_post ) {
897 if ( 'posting' === $what ) {
898 ?>
899 <div class="item">
900 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkEdit&post_id=' . $id ) ); ?>"><?php esc_html_e( 'Edit Post', 'mainwp' ); ?></a>
901 </div>
902 <?php
903 } elseif ( $last_ajax_posting ) {
904 $edit_link = '<div class="item"><a href="' . esc_url( admin_url( 'admin.php?page=PostBulkEdit&post_id=' . $id ) ) . '">' . esc_html__( 'Edit Post', 'mainwp' ) . '</a></div>';
905 }
906 }
907
908 if ( 'ajax_posting' === $what ) {
909 die(
910 wp_json_encode(
911 array(
912 'result' => $ajax_result,
913 'edit_link' => $edit_link,
914 )
915 )
916 );
917 }
918 }
919 }
920 }
921
922 /**
923 * Method get_post()
924 *
925 * Get post from child site to edit.
926 *
927 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
928 * @uses \MainWP\Dashboard\MainWP_Error_Helper::get_error_message()
929 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_by_id()
930 * @uses \MainWP\Dashboard\MainWP_Exception
931 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
932 */
933 public static function get_post() {
934 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
935 $postId = isset( $_POST['postId'] ) ? intval( $_POST['postId'] ) : false;
936 $postType = isset( $_POST['postType'] ) ? sanitize_text_field( wp_unslash( $_POST['postType'] ) ) : '';
937 $websiteId = isset( $_POST['websiteId'] ) ? intval( $_POST['websiteId'] ) : false;
938 $replaceadvImg = isset( $_POST['replace_advance_img'] ) && ! empty( $_POST['replace_advance_img'] ) ? true : true;
939 // phpcs:enable
940 if ( empty( $postId ) || empty( $websiteId ) ) {
941 die( wp_json_encode( array( 'error' => 'Post ID or site ID not found. Please, reload the page and try again.' ) ) );
942 }
943
944 $website = MainWP_DB::instance()->get_website_by_id( $websiteId );
945 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
946 die( wp_json_encode( array( 'error' => 'You can not edit this website!' ) ) );
947 }
948
949 try {
950 $information = MainWP_Connect::fetch_url_authed(
951 $website,
952 'post_action',
953 array(
954 'action' => 'get_edit',
955 'id' => $postId,
956 'post_type' => $postType,
957 )
958 );
959
960 } catch ( MainWP_Exception $e ) {
961 die( wp_json_encode( array( 'error' => MainWP_Error_Helper::get_error_message( $e ) ) ) );
962 }
963
964 if ( is_array( $information ) && isset( $information['error'] ) ) {
965 die( wp_json_encode( array( 'error' => esc_html( $information['error'] ) ) ) );
966 }
967
968 if ( ! isset( $information['status'] ) || ( 'SUCCESS' !== $information['status'] ) ) {
969 die( wp_json_encode( array( 'error' => 'Unexpected error.' ) ) );
970 } else {
971 $ret = self::new_post( $information['my_post'], $replaceadvImg, $website );
972 if ( is_array( $ret ) && isset( $ret['id'] ) ) {
973 // to support edit post.
974 update_post_meta( $ret['id'], '_selected_sites', array( $websiteId ) );
975 update_post_meta( $ret['id'], '_mainwp_edit_post_site_id', $websiteId );
976 }
977 $ret = apply_filters( 'mainwp_manageposts_get_post_result', $ret, $information['my_post'], $websiteId );
978 wp_send_json( $ret );
979 }
980 }
981
982 /**
983 * Method new_post()
984 *
985 * Create new post.
986 *
987 * @param array $post_data Array of post data.
988 * @param bool $replaceadvImg replace advanced images of post or not.
989 * @param mixed $website The website object.
990 *
991 * @return array result
992 */
993 public static function new_post( $post_data = array(), $replaceadvImg = false, $website = false ) {
994 $new_post = json_decode( base64_decode( $post_data['new_post'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
995 $post_custom = json_decode( base64_decode( $post_data['post_custom'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
996 $post_category = rawurldecode( isset( $post_data['post_category'] ) ? base64_decode( $post_data['post_category'] ) : null ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
997 $post_tags = rawurldecode( isset( $new_post['post_tags'] ) ? $new_post['post_tags'] : null );
998 $post_featured_image = base64_decode( $post_data['post_featured_image'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
999 $post_gallery_images = base64_decode( $post_data['post_gallery_images'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1000 $upload_dir = json_decode( base64_decode( $post_data['child_upload_dir'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1001 $post_gallery_images = base64_decode( $post_data['post_gallery_images'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1002 return self::create_post( $new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags, $post_gallery_images, $replaceadvImg, $website );
1003 }
1004
1005 /**
1006 * Method create_post()
1007 *
1008 * Create post.
1009 *
1010 * @param mixed $new_post Post type.
1011 * @param mixed $post_custom Custom Post.
1012 * @param mixed $post_category Post Category.
1013 * @param mixed $post_featured_image Post Featured Image.
1014 * @param mixed $upload_dir Child Site upload directory.
1015 * @param mixed $post_tags Post tags.
1016 * @param mixed $post_gallery_images Post Gallery Images.
1017 * @param bool $replaceadvImg replace advanced images of post or not.
1018 * @param mixed $website The website object.
1019 *
1020 * @return array result
1021 */
1022 public static function create_post( $new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags, $post_gallery_images, $replaceadvImg = false, $website = false ) { // phpcs:ignore -- complex method. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
1023
1024 /**
1025 * Current user global.
1026 *
1027 * @global string
1028 */
1029 global $current_user;
1030
1031 if ( ! isset( $new_post['edit_id'] ) ) {
1032 return array( 'error' => 'Empty post id' );
1033 }
1034
1035 $post_author = $current_user->ID;
1036 $new_post['post_author'] = $post_author;
1037 $post_type = isset( $new_post['post_type'] ) ? $new_post['post_type'] : '';
1038 $new_post['post_type'] = 'page' === $post_type ? 'bulkpage' : 'bulkpost';
1039
1040 $foundMatches = preg_match_all( '/(<a[^>]+href=\"(.*?)\"[^>]*>)?(<img[^>\/]*src=\"((.*?)(png|gif|jpg|jpeg))\")/ix', $new_post['post_content'], $matches, PREG_SET_ORDER );
1041 if ( 0 < $foundMatches ) {
1042 foreach ( $matches as $match ) {
1043 $hrefLink = $match[2];
1044 $imgUrl = $match[4];
1045
1046 if ( ! isset( $upload_dir['baseurl'] ) || ( false === strripos( $imgUrl, $upload_dir['baseurl'] ) ) ) { // url of image is not in child site.
1047 continue;
1048 }
1049
1050 if ( preg_match( '/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $imgUrl, $imgMatches ) ) {
1051 $search = $imgMatches[0];
1052 $replace = '.' . $match[6];
1053 $originalImgUrl = str_replace( $search, $replace, $imgUrl );
1054 } else {
1055 $originalImgUrl = $imgUrl;
1056 }
1057
1058 try {
1059 $downloadfile = self::upload_image( $originalImgUrl );
1060 $localUrl = $downloadfile['url'];
1061
1062 $linkToReplaceWith = dirname( $localUrl );
1063 if ( '' !== $hrefLink ) {
1064 $server = $website->url;
1065 $serverHost = wp_parse_url( $server, PHP_URL_HOST );
1066 if ( ! empty( $serverHost ) && false !== strpos( $hrefLink, $serverHost ) ) {
1067 $serverHref = 'href="' . $serverHost;
1068 $replaceServerHref = 'href="' . wp_parse_url( $localUrl, PHP_URL_SCHEME ) . '://' . wp_parse_url( $localUrl, PHP_URL_HOST );
1069 $new_post['post_content'] = str_replace( $serverHref, $replaceServerHref, $new_post['post_content'] );
1070 }
1071 }
1072 $lnkToReplace = dirname( $imgUrl );
1073 if ( 'http:' !== $lnkToReplace && 'https:' !== $lnkToReplace ) {
1074 $new_post['post_content'] = str_replace( $imgUrl, $localUrl, $new_post['post_content'] ); // replace src image.
1075 $new_post['post_content'] = str_replace( $lnkToReplace, $linkToReplaceWith, $new_post['post_content'] );
1076 }
1077 } catch ( \Exception $e ) {
1078 // ok.
1079 }
1080 }
1081 }
1082
1083 if ( has_shortcode( $new_post['post_content'], 'gallery' ) ) {
1084 if ( preg_match_all( '/\[gallery[^\]]+ids=\"(.*?)\"[^\]]*\]/ix', $new_post['post_content'], $matches, PREG_SET_ORDER ) ) {
1085 $replaceAttachedIds = array();
1086 if ( is_array( $post_gallery_images ) ) {
1087 foreach ( $post_gallery_images as $gallery ) {
1088 if ( isset( $gallery['src'] ) ) {
1089 try {
1090 $upload = self::upload_image( $gallery['src'], $gallery, true );
1091 if ( null !== $upload ) {
1092 $replaceAttachedIds[ $gallery['id'] ] = $upload['id'];
1093 }
1094 } catch ( \Exception $e ) {
1095 // ok.
1096 }
1097 }
1098 }
1099 }
1100 if ( 0 < count( $replaceAttachedIds ) ) {
1101 foreach ( $matches as $match ) {
1102 $idsToReplace = $match[1];
1103 $idsToReplaceWith = '';
1104 $originalIds = explode( ',', $idsToReplace );
1105 foreach ( $originalIds as $attached_id ) {
1106 if ( ! empty( $originalIds ) && isset( $replaceAttachedIds[ $attached_id ] ) ) {
1107 $idsToReplaceWith .= $replaceAttachedIds[ $attached_id ] . ',';
1108 }
1109 }
1110 $idsToReplaceWith = rtrim( $idsToReplaceWith, ',' );
1111 if ( ! empty( $idsToReplaceWith ) ) {
1112 $new_post['post_content'] = str_replace( '"' . $idsToReplace . '"', '"' . $idsToReplaceWith . '"', $new_post['post_content'] );
1113 }
1114 }
1115 }
1116 }
1117 }
1118
1119 if ( $replaceadvImg && $website ) {
1120 $new_post['post_content'] = self::replace_advanced_image( $new_post['post_content'], $upload_dir, $website );
1121 $new_post['post_content'] = self::replace_advanced_image( $new_post['post_content'], $upload_dir, $website, true ); // to fix images url with slashes.
1122 }
1123
1124 $is_sticky = false;
1125 if ( isset( $new_post['is_sticky'] ) ) {
1126 $is_sticky = ! empty( $new_post['is_sticky'] ) ? true : false;
1127 unset( $new_post['is_sticky'] );
1128 }
1129 $edit_id = $new_post['edit_id'];
1130 unset( $new_post['edit_id'] );
1131
1132 if ( isset( $new_post['post_title'] ) ) {
1133 $new_post['post_title'] = MainWP_Utility::esc_content( $new_post['post_title'], 'mixed' );
1134 }
1135
1136 $wp_error = null;
1137 remove_filter( 'content_save_pre', 'wp_filter_post_kses' );
1138 $post_status = $new_post['post_status'];
1139 $new_post['post_status'] = 'auto-draft';
1140 $new_post_id = wp_insert_post( $new_post, $wp_error );
1141
1142 if ( is_wp_error( $wp_error ) ) {
1143 return array( 'error' => $wp_error->get_error_message() );
1144 }
1145
1146 if ( empty( $new_post_id ) ) {
1147 return array( 'error' => 'Undefined error' );
1148 }
1149
1150 wp_update_post(
1151 array(
1152 'ID' => $new_post_id,
1153 'post_status' => $post_status,
1154 )
1155 );
1156
1157 foreach ( $post_custom as $meta_key => $meta_values ) {
1158 foreach ( $meta_values as $meta_value ) {
1159 update_post_meta( $new_post_id, $meta_key, $meta_value );
1160 }
1161 }
1162
1163 update_post_meta( $new_post_id, '_mainwp_edit_post_id', $edit_id );
1164 update_post_meta( $new_post_id, '_slug', base64_encode( $new_post['post_name'] ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1165 if ( isset( $post_category ) && '' !== $post_category ) {
1166 update_post_meta( $new_post_id, '_categories', base64_encode( $post_category ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1167 }
1168
1169 if ( isset( $post_tags ) && '' !== $post_tags ) {
1170 update_post_meta( $new_post_id, '_tags', base64_encode( $post_tags ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1171 }
1172 if ( $is_sticky ) {
1173 update_post_meta( $new_post_id, '_sticky', base64_encode( 'sticky' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1174 }
1175
1176 if ( null !== $post_featured_image && ! empty( $post_featured_image ) ) {
1177 try {
1178 $upload = self::upload_image( $post_featured_image );
1179
1180 if ( null !== $upload ) {
1181 update_post_meta( $new_post_id, '_thumbnail_id', $upload['id'] );
1182 }
1183 } catch ( \Exception $e ) {
1184 // ok.
1185 }
1186 }
1187
1188 $ret = array();
1189 $ret['success'] = true;
1190 $ret['id'] = $new_post_id;
1191 return $ret;
1192 }
1193
1194 /**
1195 * Method replace_advanced_image()
1196 *
1197 * Handle upload advanced image.
1198 *
1199 * @param array $content post content data.
1200 * @param array $upload_dir upload directory info.
1201 * @param mixed $website The website.
1202 * @param bool $withslashes to use preg pattern with slashes.
1203 *
1204 * @return mixed array of result.
1205 */
1206 public static function replace_advanced_image( $content, $upload_dir, $website, $withslashes = false ) {
1207
1208 if ( empty( $upload_dir ) || ! isset( $upload_dir['baseurl'] ) ) {
1209 return $content;
1210 }
1211
1212 $dashboard_url = get_site_url();
1213 $site_url_source = $website->url;
1214
1215 // to fix url with slashes.
1216 if ( $withslashes ) {
1217 $site_url_source = str_replace( '/', '\/', $site_url_source );
1218 $dashboard_url = str_replace( '/', '\/', $dashboard_url );
1219 }
1220
1221 $foundMatches = preg_match_all( '#(' . preg_quote( $site_url_source, null ) . ')[^\.]*(\.(png|gif|jpg|jpeg))#ix', $content, $matches, PREG_SET_ORDER ); // phpcs:ignore -- Current complexity.
1222
1223 if ( 0 < $foundMatches ) {
1224
1225 $matches_checked = array();
1226 $check_double = array();
1227 foreach ( $matches as $match ) {
1228 // to avoid double images.
1229 if ( ! in_array( $match[0], $check_double ) ) {
1230 $check_double[] = $match[0];
1231 $matches_checked[] = $match;
1232 }
1233 }
1234 foreach ( $matches_checked as $match ) {
1235
1236 $imgUrl = $match[0];
1237 if ( false === strripos( wp_unslash( $imgUrl ), $upload_dir['baseurl'] ) ) {
1238 continue;
1239 }
1240
1241 if ( preg_match( '/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $imgUrl, $imgMatches ) ) {
1242 $search = $imgMatches[0];
1243 $replace = '.' . $match[3];
1244 $originalImgUrl = str_replace( $search, $replace, $imgUrl );
1245 } else {
1246 $originalImgUrl = $imgUrl;
1247 }
1248
1249 try {
1250 $downloadfile = self::upload_image( wp_unslash( $originalImgUrl ) );
1251 $localUrl = $downloadfile['url'];
1252 $linkToReplaceWith = dirname( $localUrl );
1253 $lnkToReplace = dirname( $imgUrl );
1254 if ( 'http:' !== $lnkToReplace && 'https:' !== $lnkToReplace ) {
1255 $content = str_replace( $imgUrl, $localUrl, $content ); // replace src image.
1256 $content = str_replace( $lnkToReplace, $linkToReplaceWith, $content );
1257 }
1258 } catch ( \Exception $e ) {
1259 // ok.
1260 }
1261 }
1262 if ( false === strripos( $site_url_source, $dashboard_url ) ) {
1263 // replace other images src outside upload folder.
1264 $content = str_replace( $site_url_source, $dashboard_url, $content );
1265 }
1266 }
1267 return $content;
1268 }
1269
1270 /**
1271 * Method upload_image()
1272 *
1273 * Handle upload image.
1274 *
1275 * @throws \Exception Error upload file.
1276 *
1277 * @param string $img_url URL for the image.
1278 * @param array $img_data Array of image data.
1279 *
1280 * @return mixed array of result or null.
1281 *
1282 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
1283 */
1284 public static function upload_image( $img_url, $img_data = array() ) {
1285 if ( ! is_array( $img_data ) ) {
1286 $img_data = array();
1287 }
1288 include_once ABSPATH . 'wp-admin/includes/file.php';
1289 $upload_dir = wp_upload_dir();
1290 $temporary_file = download_url( $img_url );
1291
1292 if ( is_wp_error( $temporary_file ) ) {
1293 throw new \Exception( 'Error: ' . $temporary_file->get_error_message() ); //phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
1294 } else {
1295 $upload_dir = wp_upload_dir();
1296 $local_img_path = $upload_dir['path'] . DIRECTORY_SEPARATOR . basename( $img_url );
1297 $local_img_url = $upload_dir['url'] . '/' . basename( $img_url );
1298 $moved = false;
1299 if ( MainWP_Utility::check_image_file_name( $local_img_path ) ) {
1300 global $wp_filesystem;
1301 if ( $wp_filesystem ) {
1302 $moved = $wp_filesystem->move( $temporary_file, $local_img_path );
1303 }
1304 }
1305 if ( $moved ) {
1306 $wp_filetype = wp_check_filetype( basename( $img_url ), null );
1307 $attachment = array(
1308 'post_mime_type' => $wp_filetype['type'],
1309 'post_title' => isset( $img_data['title'] ) && ! empty( $img_data['title'] ) ? $img_data['title'] : preg_replace( '/\.[^.]+$/', '', basename( $img_url ) ),
1310 'post_content' => isset( $img_data['description'] ) && ! empty( $img_data['description'] ) ? $img_data['description'] : '',
1311 'post_excerpt' => isset( $img_data['caption'] ) && ! empty( $img_data['caption'] ) ? MainWP_Utility::esc_content( $img_data['caption'] ) : '',
1312 'post_status' => 'inherit',
1313 );
1314 $attach_id = wp_insert_attachment( $attachment, $local_img_path );
1315 require_once ABSPATH . 'wp-admin/includes/image.php';
1316 $attach_data = wp_generate_attachment_metadata( $attach_id, $local_img_path );
1317 wp_update_attachment_metadata( $attach_id, $attach_data );
1318 if ( isset( $img_data['alt'] ) && ! empty( $img_data['alt'] ) ) {
1319 update_post_meta( $attach_id, '_wp_attachment_image_alt', $img_data['alt'] );
1320 }
1321 return array(
1322 'id' => $attach_id,
1323 'url' => $local_img_url,
1324 );
1325 }
1326 }
1327
1328 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
1329
1330 /**
1331 * WordPress files system object.
1332 *
1333 * @global object
1334 */
1335 global $wp_filesystem;
1336
1337 if ( $wp_filesystem->exists( $temporary_file ) ) {
1338 $wp_filesystem->delete( $temporary_file );
1339 }
1340
1341 return null;
1342 }
1343
1344 /**
1345 * Method add_sticky_handle()
1346 *
1347 * Add post meta.
1348 *
1349 * @param mixed $post_id Post ID.
1350 *
1351 * @return int $post_id Post ID.
1352 */
1353 public static function add_sticky_handle( $post_id ) {
1354 $_post = get_post( $post_id );
1355 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1356 if ( 'bulkpost' === $_post->post_type && isset( $_POST['sticky'] ) ) {
1357 update_post_meta( $post_id, '_sticky', base64_encode( sanitize_text_field( wp_unslash( $_POST['sticky'] ) ) ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1358 return base64_encode( sanitize_text_field( wp_unslash( $_POST['sticky'] ) ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1359 }
1360 // phpcs:enable
1361 return $post_id;
1362 }
1363
1364
1365 /**
1366 * Method add_status_handle()
1367 *
1368 * Add edit post status handle.
1369 *
1370 * @param int $post_id Post ID.
1371 *
1372 * @return int $post_id Post id with status handle added to it.
1373 */
1374 public static function add_status_handle( $post_id ) {
1375 $_post = get_post( $post_id );
1376 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1377 if ( ( 'bulkpage' === $_post->post_type || 'bulkpost' === $_post->post_type ) && isset( $_POST['mainwp_edit_post_status'] ) ) {
1378 update_post_meta( $post_id, '_edit_post_status', sanitize_text_field( wp_unslash( $_POST['mainwp_edit_post_status'] ) ) );
1379 }
1380 // phpcs:enable
1381 return $post_id;
1382 }
1383 }
1384