PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.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 5.2.2 5.3 All 153 releases
mainwp / pages / page-mainwp-post-page-handler.php

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

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