PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.6.0.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.6.0.1
6.2.3 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 All 156 releases
mainwp / pages / page-mainwp-post-page-handler.php

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

1,267 lines 47.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 /**
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 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 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 = array( 'Uncategorized' );
233 if ( 0 < count( $websites ) ) {
234 foreach ( $websites as $website ) {
235 $cats = json_decode( $website->categories, true );
236 if ( is_array( $cats ) && ( 0 < count( $cats ) ) ) {
237 $allCategories = array_unique( array_merge( $allCategories, $cats ) );
238 }
239 }
240 }
241 $allCategories = array_unique( array_merge( $allCategories, $selectedCategories ) );
242
243 if ( 0 < count( $allCategories ) ) {
244 natcasesort( $allCategories );
245 foreach ( $allCategories as $category ) {
246 echo '<option value="' . esc_attr( $category ) . '" class="sitecategory">' . esc_html( $category ) . '</option>';
247 }
248 }
249 die();
250 // phpcs:enable
251 }
252
253 /**
254 * Method posting_bulk()
255 *
256 * Create bulk posts on sites.
257 */
258 public static function posting_bulk() {
259 $p_id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
260 $posting_bulk_sites = apply_filters( 'mainwp_posts_posting_bulk_sites', false );
261 ?>
262 <input type="hidden" name="bulk_posting_id" id="bulk_posting_id" value="<?php echo intval( $p_id ); ?>"/>
263 <?php
264 if ( ! $posting_bulk_sites ) {
265 self::posting( $p_id );
266 } else {
267 self::posting_prepare( $p_id );
268 }
269 }
270
271 /**
272 * Method posting()
273 *
274 * Create bulk posts on sites.
275 *
276 * @param int $post_id Post or Page ID.
277 *
278 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
279 * @uses \MainWP\Dashboard\MainWP_DB::query()
280 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
281 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
282 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
283 * @uses \MainWP\Dashboard\MainWP_System_Utility::maybe_unserialyze()
284 * @uses \MainWP\Dashboard\MainWP_Bulk_Add::get_class_name()
285 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
286 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
287 */
288 public static function posting( $post_id ) { // phpcs:ignore -- complex method. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
289 $p_id = $post_id;
290
291 $edit_id = get_post_meta( $post_id, '_mainwp_edit_post_id', true );
292
293 ?>
294 <div class="ui modal" id="mainwp-posting-post-modal">
295 <div class="header"><?php $edit_id ? esc_html_e( 'Edit Post', 'mainwp' ) : esc_html_e( 'New Post', 'mainwp' ); ?></div>
296 <div class="scrolling content">
297 <?php
298 /**
299 * Before Post post action
300 *
301 * Fires right before posting the 'bulkpost' to child sites.
302 *
303 * @param int $p_id Page ID.
304 *
305 * @since Unknown
306 */
307 do_action( 'mainwp_bulkpost_before_post', $p_id );
308
309 $skip_post = false;
310 if ( $p_id ) {
311 if ( 'yes' === get_post_meta( $p_id, '_mainwp_skip_posting', true ) ) {
312 $skip_post = true;
313 wp_delete_post( $p_id, true );
314 }
315 }
316
317 if ( ! $skip_post ) {
318 if ( $p_id ) {
319 self::posting_posts( $p_id, 'posting' );
320 } else {
321 ?>
322 <div class="error">
323 <p>
324 <strong><?php esc_html_e( 'ERROR', 'mainwp' ); ?></strong>: <?php esc_html_e( 'An undefined error occured!', 'mainwp' ); ?>
325 </p>
326 </div>
327 <?php
328 }
329 }
330 ?>
331 </div>
332 <div class="actions">
333 <a href="admin.php?page=PostBulkAdd" class="ui green button"><?php esc_html_e( 'New Post', 'mainwp' ); ?></a>
334 <div class="ui cancel button"><?php esc_html_e( 'Close', 'mainwp' ); ?></div>
335 </div>
336 </div>
337 <div class="ui active inverted dimmer" id="mainwp-posting-running">
338 <div class="ui indeterminate large text loader"><?php esc_html_e( 'Running ...', 'mainwp' ); ?></div>
339 </div>
340 <script type="text/javascript">
341 jQuery( document ).ready( function () {
342 jQuery( "#mainwp-posting-running" ).hide();
343 jQuery( "#mainwp-posting-post-modal" ).modal( {
344 closable: true,
345 onHide: function() {
346 location.href = 'admin.php?page=PostBulkManage';
347 }
348 } ).modal( 'show' );
349 } );
350 </script>
351 <?php
352 }
353
354 /**
355 * Method posting_prepare()
356 *
357 * Posting posts.
358 *
359 * @param int $post_id Post or Page ID.
360 */
361 public static function posting_prepare( $post_id ) {
362 $edit_id = get_post_meta( $post_id, '_mainwp_edit_post_id', true );
363 ?>
364 <div class="ui modal" id="mainwp-posting-post-modal">
365 <div class="header"><?php $edit_id ? esc_html_e( 'Edit Post', 'mainwp' ) : esc_html_e( 'New Post', 'mainwp' ); ?></div>
366 <div class="scrolling content">
367 <?php
368 if ( $post_id ) {
369 self::posting_posts( $post_id, 'preparing' );
370 } else {
371 ?>
372 <div class="error">
373 <p>
374 <strong><?php esc_html_e( 'ERROR', 'mainwp' ); ?></strong>: <?php esc_html_e( 'An undefined error occured!', 'mainwp' ); ?>
375 </p>
376 </div>
377 <?php
378 }
379 ?>
380 </div>
381 <div class="actions">
382 <a href="admin.php?page=PostBulkAdd" class="ui green button"><?php esc_html_e( 'New Post', 'mainwp' ); ?></a>
383 <div class="ui cancel button"><?php esc_html_e( 'Close', 'mainwp' ); ?></div>
384 </div>
385 </div>
386 <div class="ui active inverted dimmer" id="mainwp-posting-running">
387 <div class="ui indeterminate large text loader"><?php esc_html_e( 'Running ...', 'mainwp' ); ?></div>
388 </div>
389 <script type="text/javascript">
390 jQuery( document ).ready( function () {
391 jQuery( "#mainwp-posting-running" ).hide();
392 jQuery( "#mainwp-posting-post-modal" ).modal( {
393 closable: true,
394 onHide: function() {
395 location.href = 'admin.php?page=PostBulkManage';
396 }
397 } ).modal( 'show' );
398 mainwp_post_posting_start_next( true );
399 } );
400 </script>
401 <?php
402 }
403
404
405 /**
406 * Method ajax_posting_posts()
407 *
408 * Ajax Posting posts.
409 */
410 public static function ajax_posting_posts() {
411 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
412 MainWP_Post_Handler::instance()->secure_request( 'mainwp_post_postingbulk' );
413 $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : false;
414 if ( $post_id ) {
415 self::posting_posts( $post_id, 'ajax_posting' );
416 }
417 // phpcs:enable
418 die();
419 }
420
421 /**
422 * Method ajax_get_sites_of_groups()
423 *
424 * Ajax Get sites of groups.
425 */
426 public static function ajax_get_sites_of_groups() {
427 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
428 MainWP_Post_Handler::instance()->secure_request( 'mainwp_get_sites_of_groups' );
429 $groups = isset( $_POST['groups'] ) && is_array( $_POST['groups'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['groups'] ) ) : '';
430 $websites = MainWP_DB::instance()->get_websites_by_group_ids( $groups );
431 // phpcs:enable
432 $site_Ids = array();
433 if ( $websites ) {
434 foreach ( $websites as $website ) {
435 $site_Ids[] = $website->id;
436 }
437 }
438 die( wp_json_encode( $site_Ids ) );
439 }
440
441 /**
442 * Method posting_posts()
443 *
444 * Posting posts.
445 *
446 * @param int $post_id Post or Page ID.
447 * @param string $what What posting process.
448 */
449 public static function posting_posts( $post_id, $what ) { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
450
451 if ( empty( $post_id ) ) {
452 return false;
453 }
454
455 $succes_message = '';
456 $edit_id = get_post_meta( $post_id, '_mainwp_edit_post_id', true );
457 if ( $edit_id ) {
458 $succes_message = esc_html__( 'Post has been updated successfully', 'mainwp' );
459 } else {
460 $succes_message = esc_html__( 'New post created', 'mainwp' );
461 }
462
463 $id = $post_id;
464 $_post = get_post( $id );
465
466 if ( $_post ) {
467 $selected_by = 'site';
468 $selected_groups = array();
469 $selected_sites = array();
470 $selected_clients = array();
471
472 if ( 'posting' === $what || 'preparing' === $what ) {
473 $selected_by = get_post_meta( $id, '_selected_by', true );
474 $val = get_post_meta( $id, '_selected_sites', true );
475 $selected_sites = MainWP_System_Utility::maybe_unserialyze( $val );
476 $val = get_post_meta( $id, '_selected_groups', true );
477 $selected_groups = MainWP_System_Utility::maybe_unserialyze( $val );
478 $selected_clients = get_post_meta( $id, '_selected_clients', true );
479 $selected_by = apply_filters( 'mainwp_posting_post_selected_by', $selected_by, $id );
480 } elseif ( 'ajax_posting' === $what ) {
481 $site_id = isset( $_POST['site_id'] ) ? intval( $_POST['site_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
482 if ( $site_id ) {
483 $selected_sites = array( $site_id );
484 }
485 }
486
487 $selected_sites = apply_filters( 'mainwp_posting_post_selected_sites', $selected_sites, $id );
488 $selected_groups = apply_filters( 'mainwp_posting_selected_groups', $selected_groups, $id );
489 $selected_clients = apply_filters( 'mainwp_posting_selected_clients', $selected_clients, $id );
490
491 if ( 'preparing' !== $what ) {
492 $post_category = base64_decode( get_post_meta( $id, '_categories', true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
493
494 $post_tags = base64_decode( get_post_meta( $id, '_tags', true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
495 $post_slug = base64_decode( get_post_meta( $id, '_slug', true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
496 $post_custom = get_post_custom( $id );
497
498 $galleries = get_post_gallery( $id, false );
499 $post_gallery_images = array();
500
501 if ( is_array( $galleries ) && isset( $galleries['ids'] ) ) {
502 $attached_images = explode( ',', $galleries['ids'] );
503 foreach ( $attached_images as $attachment_id ) {
504 $attachment = get_post( $attachment_id );
505 if ( $attachment ) {
506 $post_gallery_images[] = array(
507 'id' => $attachment_id,
508 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
509 'caption' => MainWP_Utility::esc_content( $attachment->post_excerpt, 'mixed' ),
510 'description' => $attachment->post_content,
511 'src' => $attachment->guid,
512 'title' => htmlspecialchars( $attachment->post_title ),
513 );
514 }
515 }
516 }
517
518 include_once ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR . 'post-thumbnail-template.php';
519 $featured_image_id = get_post_thumbnail_id( $id );
520 $post_featured_image = null;
521 $featured_image_data = null;
522 $mainwp_upload_dir = wp_upload_dir();
523
524 // to fix.
525 $post_status = $_post->post_status;
526 if ( 'publish' === $post_status ) {
527 $post_status = get_post_meta( $id, '_edit_post_status', true );
528 }
529
530 /**
531 * Post status
532 *
533 * Sets post status when posting 'bulkpost' to child sites.
534 *
535 * @param int $id Post ID.
536 *
537 * @since Unknown
538 */
539 $post_status = apply_filters( 'mainwp_posting_bulkpost_post_status', $post_status, $id );
540 $new_post = array(
541 'post_title' => $_post->post_title,
542 'post_content' => $_post->post_content,
543 'post_status' => $post_status,
544 'post_date' => $_post->post_date,
545 'post_date_gmt' => $_post->post_date_gmt,
546 'post_tags' => $post_tags,
547 'post_name' => $post_slug,
548 'post_excerpt' => MainWP_Utility::esc_content( $_post->post_excerpt, 'mixed' ),
549 'post_password' => $_post->post_password,
550 'comment_status' => $_post->comment_status,
551 'ping_status' => $_post->ping_status,
552 'mainwp_post_id' => $_post->ID,
553 );
554
555 if ( ! empty( $featured_image_id ) ) {
556 $img = wp_get_attachment_image_src( $featured_image_id, 'full' );
557 $post_featured_image = $img[0];
558 $attachment = get_post( $featured_image_id );
559 $featured_image_data = array(
560 'alt' => get_post_meta( $featured_image_id, '_wp_attachment_image_alt', true ),
561 'caption' => MainWP_Utility::esc_content( $attachment->post_excerpt, 'mixed' ),
562 'description' => $attachment->post_content,
563 'title' => htmlspecialchars( $attachment->post_title ),
564 );
565 }
566 }
567
568 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
569
570 $dbwebsites = array();
571
572 if ( 'site' === $selected_by ) {
573 foreach ( $selected_sites as $k ) {
574 if ( MainWP_Utility::ctype_digit( $k ) ) {
575 $website = MainWP_DB::instance()->get_website_by_id( $k );
576 if ( empty( $website->sync_errors ) && ! MainWP_System_Utility::is_suspended_site( $website ) ) {
577 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
578 }
579 }
580 }
581 } elseif ( 'client' === $selected_by ) {
582 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
583 $selected_clients,
584 array(
585 'select_data' => $data_fields,
586 )
587 );
588 if ( $websites ) {
589 foreach ( $websites as $website ) {
590 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
591 continue;
592 }
593 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
594 }
595 }
596 } elseif ( 'group' === $selected_by ) {
597 foreach ( $selected_groups as $k ) {
598 if ( MainWP_Utility::ctype_digit( $k ) ) {
599 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $k ) );
600 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
601 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
602 continue;
603 }
604 $dbwebsites[ $website->id ] = MainWP_Utility::map_site( $website, $data_fields );
605 }
606 MainWP_DB::free_result( $websites );
607 }
608 }
609 }
610
611 if ( 'preparing' === $what ) {
612 ?>
613 <div class="ui relaxed list">
614 <?php
615 foreach ( $dbwebsites as $website ) {
616 ?>
617 <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>
618 <div class="right floated content progress"><i class="clock outline icon"></i></div>
619 </div>
620 <?php } ?>
621 </div>
622 <?php
623 } else {
624
625 $output = new \stdClass();
626 $output->ok = array();
627 $output->errors = array();
628 $startTime = time();
629
630 if ( 0 < count( $dbwebsites ) ) {
631
632 // prepare $post_custom values.
633 $new_post_custom = array();
634 foreach ( $post_custom as $meta_key => $meta_values ) {
635 $new_meta_values = array();
636 foreach ( $meta_values as $key_value => $meta_value ) {
637 if ( is_serialized( $meta_value ) ) {
638 $meta_value = unserialize( $meta_value ); // phpcs:ignore -- internal value safe.
639 }
640 $new_meta_values[ $key_value ] = $meta_value;
641 }
642 $new_post_custom[ $meta_key ] = $new_meta_values;
643 }
644
645 $post_data = array(
646 'new_post' => base64_encode( wp_json_encode( $new_post ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
647 'post_custom' => base64_encode( wp_json_encode( $new_post_custom ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
648 'post_category' => ! empty( $post_category ) ? base64_encode( $post_category ) : '', // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
649 '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.
650 'post_gallery_images' => base64_encode( wp_json_encode( $post_gallery_images ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
651 'mainwp_upload_dir' => base64_encode( wp_json_encode( $mainwp_upload_dir ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
652 '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.
653 );
654 MainWP_Connect::fetch_urls_authed(
655 $dbwebsites,
656 'newpost',
657 $post_data,
658 array(
659 MainWP_Bulk_Add::get_class_name(),
660 'posting_bulk_handler',
661 ),
662 $output
663 );
664 }
665
666 foreach ( $dbwebsites as $website ) {
667 if ( isset( $output->ok[ $website->id ] ) && ( 1 === (int) $output->ok[ $website->id ] ) && ( isset( $output->added_id[ $website->id ] ) ) ) {
668 $links = isset( $output->link[ $website->id ] ) ? $output->link[ $website->id ] : null;
669 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.
670 do_action_deprecated( 'mainwp-bulkposting-done', array( $_post, $website, $output ), '4.0.7.2', 'mainwp_bulkposting_done' ); // @deprecated Use 'mainwp_bulkposting_done' instead.
671
672 /**
673 * Posting post
674 *
675 * Fires while posting post.
676 *
677 * @param object $website Object containing child site data.
678 * @param int $output->added_id[ $website->id ] Child site ID.
679 * @param array $links Links.
680 *
681 * @since Unknown
682 */
683 do_action( 'mainwp_post_posting_post', $website, $output->added_id[ $website->id ], $links );
684
685 /**
686 * Posting post completed
687 *
688 * Fires after the post posting process is completed.
689 *
690 * @param array $_post Array containing the post data.
691 * @param object $website Object containing child site data.
692 * @param array $output Output data.
693 *
694 * @since Unknown
695 */
696 do_action( 'mainwp_bulkposting_done', $_post, $website, $output );
697 }
698 }
699
700 /**
701 * After posting a new post
702 *
703 * Sets data after the posting process to show the process feedback.
704 *
705 * @param array $_post Array containing the post data.
706 * @param array $dbwebsites Array containing processed sites.
707 * @param array $output Output data.
708 *
709 * @since Unknown
710 */
711 $newExtensions = apply_filters_deprecated( 'mainwp-after-posting-bulkpost-result', array( false, $_post, $dbwebsites, $output ), '4.0.7.2', 'mainwp_after_posting_bulkpost_result' );
712
713 $after_posting = false;
714 if ( 'posting' === $what ) {
715 // supported for bulk posting, not for ajax posting.
716 $after_posting = apply_filters( 'mainwp_after_posting_bulkpost_result', $newExtensions, $_post, $dbwebsites, $output );
717 }
718
719 $posting_succeed = false;
720
721 if ( false === $after_posting ) {
722 if ( 'posting' === $what ) {
723 ?>
724 <div class="ui relaxed list">
725 <?php
726 foreach ( $dbwebsites as $website ) {
727 ?>
728 <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>
729 :
730 <?php
731 if ( isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ) {
732 echo esc_html( $succes_message ) . ' <a href="' . esc_html( $output->link[ $website->id ] ) . '" class="mainwp-may-hide-referrer" target="_blank">View Post</a>';
733 $posting_succeed = true;
734 } else {
735 echo $output->errors[ $website->id ]; // phpcs:ignore WordPress.Security.EscapeOutput
736 }
737 ?>
738 </div>
739 <?php } ?>
740 </div>
741 <?php } ?>
742 <?php
743 } else {
744 $posting_succeed = true;
745 }
746
747 $ajax_result = '';
748 if ( 'ajax_posting' === $what ) {
749 if ( isset( $output->ok[ $website->id ] ) && 1 === (int) $output->ok[ $website->id ] ) {
750 $ajax_result = esc_html( $succes_message ) . ' <a href="' . esc_html( $output->link[ $website->id ] ) . '" class="mainwp-may-hide-referrer" target="_blank">View Post</a>';
751 $posting_succeed = true;
752 } else {
753 $ajax_result = $output->errors[ $website->id ];
754 }
755 }
756
757 $delete_bulk_post = apply_filters( 'mainwp_after_posting_delete_bulk_post', true, $posting_succeed );
758 $do_not_del = get_post_meta( $id, '_bulkpost_do_not_del', true );
759
760 $last_ajax_posting = false;
761 if ( 'ajax_posting' === $what ) {
762 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
763 $total = isset( $_POST['total'] ) ? intval( $_POST['total'] ) : 0;
764 $count = isset( $_POST['count'] ) ? intval( $_POST['count'] ) : 0;
765 $delete_bulkpost = isset( $_POST['delete_bulkpost'] ) && ! empty( $_POST['delete_bulkpost'] ) ? true : false;
766 // phpcs:enable
767 if ( $delete_bulkpost ) {
768 $last_ajax_posting = true;
769 }
770 }
771
772 $deleted_bulk_post = false;
773 if ( 'yes' !== $do_not_del && $delete_bulk_post && ( 'posting' === $what || $last_ajax_posting ) ) {
774 wp_delete_post( $id, true );
775 $deleted_bulk_post = true;
776 }
777
778 $edit_link = '';
779 if ( ! $deleted_bulk_post ) {
780 if ( 'posting' === $what ) {
781 ?>
782 <div class="item">
783 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkEdit&post_id=' . $id ) ); ?>"><?php esc_html_e( 'Edit Post', 'mainwp' ); ?></a>
784 </div>
785 <?php
786 } elseif ( $last_ajax_posting ) {
787 $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>';
788 }
789 }
790
791 if ( 'ajax_posting' === $what ) {
792 die(
793 wp_json_encode(
794 array(
795 'result' => $ajax_result,
796 'edit_link' => $edit_link,
797 )
798 )
799 );
800 }
801 }
802 }
803 }
804
805 /**
806 * Method get_post()
807 *
808 * Get post from child site to edit.
809 *
810 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
811 * @uses \MainWP\Dashboard\MainWP_Error_Helper::get_error_message()
812 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_by_id()
813 * @uses \MainWP\Dashboard\MainWP_Exception
814 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
815 */
816 public static function get_post() {
817 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
818 $postId = isset( $_POST['postId'] ) ? intval( $_POST['postId'] ) : false;
819 $postType = isset( $_POST['postType'] ) ? sanitize_text_field( wp_unslash( $_POST['postType'] ) ) : '';
820 $websiteId = isset( $_POST['websiteId'] ) ? intval( $_POST['websiteId'] ) : false;
821 $replaceadvImg = isset( $_POST['replace_advance_img'] ) && ! empty( $_POST['replace_advance_img'] ) ? true : true;
822 // phpcs:enable
823 if ( empty( $postId ) || empty( $websiteId ) ) {
824 die( wp_json_encode( array( 'error' => 'Post ID or site ID not found. Please, reload the page and try again.' ) ) );
825 }
826
827 $website = MainWP_DB::instance()->get_website_by_id( $websiteId );
828 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
829 die( wp_json_encode( array( 'error' => 'You can not edit this website!' ) ) );
830 }
831
832 try {
833 $information = MainWP_Connect::fetch_url_authed(
834 $website,
835 'post_action',
836 array(
837 'action' => 'get_edit',
838 'id' => $postId,
839 'post_type' => $postType,
840 )
841 );
842
843 } catch ( MainWP_Exception $e ) {
844 die( wp_json_encode( array( 'error' => MainWP_Error_Helper::get_error_message( $e ) ) ) );
845 }
846
847 if ( is_array( $information ) && isset( $information['error'] ) ) {
848 die( wp_json_encode( array( 'error' => esc_html( $information['error'] ) ) ) );
849 }
850
851 if ( ! isset( $information['status'] ) || ( 'SUCCESS' !== $information['status'] ) ) {
852 die( wp_json_encode( array( 'error' => 'Unexpected error.' ) ) );
853 } else {
854 $ret = self::new_post( $information['my_post'], $replaceadvImg, $website );
855 if ( is_array( $ret ) && isset( $ret['id'] ) ) {
856 // to support edit post.
857 update_post_meta( $ret['id'], '_selected_sites', array( $websiteId ) );
858 update_post_meta( $ret['id'], '_mainwp_edit_post_site_id', $websiteId );
859 }
860 $ret = apply_filters( 'mainwp_manageposts_get_post_result', $ret, $information['my_post'], $websiteId );
861 wp_send_json( $ret );
862 }
863 }
864
865 /**
866 * Method new_post()
867 *
868 * Create new post.
869 *
870 * @param array $post_data Array of post data.
871 * @param bool $replaceadvImg replace advanced images of post or not.
872 * @param mixed $website The website object.
873 *
874 * @return array result
875 */
876 public static function new_post( $post_data = array(), $replaceadvImg = false, $website = false ) {
877 $new_post = json_decode( base64_decode( $post_data['new_post'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
878 $post_custom = json_decode( base64_decode( $post_data['post_custom'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
879 $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.
880 $post_tags = rawurldecode( isset( $new_post['post_tags'] ) ? $new_post['post_tags'] : null );
881 $post_featured_image = base64_decode( $post_data['post_featured_image'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
882 $post_gallery_images = base64_decode( $post_data['post_gallery_images'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
883 $upload_dir = json_decode( base64_decode( $post_data['child_upload_dir'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
884 $post_gallery_images = base64_decode( $post_data['post_gallery_images'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
885 return self::create_post( $new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags, $post_gallery_images, $replaceadvImg, $website );
886 }
887
888 /**
889 * Method create_post()
890 *
891 * Create post.
892 *
893 * @param mixed $new_post Post type.
894 * @param mixed $post_custom Custom Post.
895 * @param mixed $post_category Post Category.
896 * @param mixed $post_featured_image Post Featured Image.
897 * @param mixed $upload_dir Child Site upload directory.
898 * @param mixed $post_tags Post tags.
899 * @param mixed $post_gallery_images Post Gallery Images.
900 * @param bool $replaceadvImg replace advanced images of post or not.
901 * @param mixed $website The website object.
902 *
903 * @return array result
904 */
905 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.
906
907 /**
908 * Current user global.
909 *
910 * @global string
911 */
912 global $current_user;
913
914 if ( ! isset( $new_post['edit_id'] ) ) {
915 return array( 'error' => 'Empty post id' );
916 }
917
918 $post_author = $current_user->ID;
919 $new_post['post_author'] = $post_author;
920 $post_type = isset( $new_post['post_type'] ) ? $new_post['post_type'] : '';
921 $new_post['post_type'] = 'page' === $post_type ? 'bulkpage' : 'bulkpost';
922
923 $foundMatches = preg_match_all( '/(<a[^>]+href=\"(.*?)\"[^>]*>)?(<img[^>\/]*src=\"((.*?)(png|gif|jpg|jpeg))\")/ix', $new_post['post_content'], $matches, PREG_SET_ORDER );
924 if ( 0 < $foundMatches ) {
925 foreach ( $matches as $match ) {
926 $hrefLink = $match[2];
927 $imgUrl = $match[4];
928
929 if ( ! isset( $upload_dir['baseurl'] ) || ( false === strripos( $imgUrl, $upload_dir['baseurl'] ) ) ) { // url of image is not in child site.
930 continue;
931 }
932
933 if ( preg_match( '/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $imgUrl, $imgMatches ) ) {
934 $search = $imgMatches[0];
935 $replace = '.' . $match[6];
936 $originalImgUrl = str_replace( $search, $replace, $imgUrl );
937 } else {
938 $originalImgUrl = $imgUrl;
939 }
940
941 try {
942 $downloadfile = self::upload_image( $originalImgUrl );
943 $localUrl = $downloadfile['url'];
944
945 $linkToReplaceWith = dirname( $localUrl );
946 if ( '' !== $hrefLink ) {
947 $server = $website->url;
948 $serverHost = wp_parse_url( $server, PHP_URL_HOST );
949 if ( ! empty( $serverHost ) && false !== strpos( $hrefLink, $serverHost ) ) {
950 $serverHref = 'href="' . $serverHost;
951 $replaceServerHref = 'href="' . wp_parse_url( $localUrl, PHP_URL_SCHEME ) . '://' . wp_parse_url( $localUrl, PHP_URL_HOST );
952 $new_post['post_content'] = str_replace( $serverHref, $replaceServerHref, $new_post['post_content'] );
953 }
954 }
955 $lnkToReplace = dirname( $imgUrl );
956 if ( 'http:' !== $lnkToReplace && 'https:' !== $lnkToReplace ) {
957 $new_post['post_content'] = str_replace( $imgUrl, $localUrl, $new_post['post_content'] ); // replace src image.
958 $new_post['post_content'] = str_replace( $lnkToReplace, $linkToReplaceWith, $new_post['post_content'] );
959 }
960 } catch ( \Exception $e ) {
961 // ok.
962 }
963 }
964 }
965
966 if ( has_shortcode( $new_post['post_content'], 'gallery' ) ) {
967 if ( preg_match_all( '/\[gallery[^\]]+ids=\"(.*?)\"[^\]]*\]/ix', $new_post['post_content'], $matches, PREG_SET_ORDER ) ) {
968 $replaceAttachedIds = array();
969 if ( is_array( $post_gallery_images ) ) {
970 foreach ( $post_gallery_images as $gallery ) {
971 if ( isset( $gallery['src'] ) ) {
972 try {
973 $upload = self::upload_image( $gallery['src'], $gallery, true );
974 if ( null !== $upload ) {
975 $replaceAttachedIds[ $gallery['id'] ] = $upload['id'];
976 }
977 } catch ( \Exception $e ) {
978 // ok.
979 }
980 }
981 }
982 }
983 if ( 0 < count( $replaceAttachedIds ) ) {
984 foreach ( $matches as $match ) {
985 $idsToReplace = $match[1];
986 $idsToReplaceWith = '';
987 $originalIds = explode( ',', $idsToReplace );
988 foreach ( $originalIds as $attached_id ) {
989 if ( ! empty( $originalIds ) && isset( $replaceAttachedIds[ $attached_id ] ) ) {
990 $idsToReplaceWith .= $replaceAttachedIds[ $attached_id ] . ',';
991 }
992 }
993 $idsToReplaceWith = rtrim( $idsToReplaceWith, ',' );
994 if ( ! empty( $idsToReplaceWith ) ) {
995 $new_post['post_content'] = str_replace( '"' . $idsToReplace . '"', '"' . $idsToReplaceWith . '"', $new_post['post_content'] );
996 }
997 }
998 }
999 }
1000 }
1001
1002 if ( $replaceadvImg && $website ) {
1003 $new_post['post_content'] = self::replace_advanced_image( $new_post['post_content'], $upload_dir, $website );
1004 $new_post['post_content'] = self::replace_advanced_image( $new_post['post_content'], $upload_dir, $website, true ); // to fix images url with slashes.
1005 }
1006
1007 $is_sticky = false;
1008 if ( isset( $new_post['is_sticky'] ) ) {
1009 $is_sticky = ! empty( $new_post['is_sticky'] ) ? true : false;
1010 unset( $new_post['is_sticky'] );
1011 }
1012 $edit_id = $new_post['edit_id'];
1013 unset( $new_post['edit_id'] );
1014
1015 if ( isset( $new_post['post_title'] ) ) {
1016 $new_post['post_title'] = MainWP_Utility::esc_content( $new_post['post_title'], 'mixed' );
1017 }
1018
1019 $wp_error = null;
1020 remove_filter( 'content_save_pre', 'wp_filter_post_kses' );
1021 $post_status = $new_post['post_status'];
1022 $new_post['post_status'] = 'auto-draft';
1023 $new_post_id = wp_insert_post( $new_post, $wp_error );
1024
1025 if ( is_wp_error( $wp_error ) ) {
1026 return array( 'error' => $wp_error->get_error_message() );
1027 }
1028
1029 if ( empty( $new_post_id ) ) {
1030 return array( 'error' => 'Undefined error' );
1031 }
1032
1033 wp_update_post(
1034 array(
1035 'ID' => $new_post_id,
1036 'post_status' => $post_status,
1037 )
1038 );
1039
1040 foreach ( $post_custom as $meta_key => $meta_values ) {
1041 foreach ( $meta_values as $meta_value ) {
1042 update_post_meta( $new_post_id, $meta_key, $meta_value );
1043 }
1044 }
1045
1046 update_post_meta( $new_post_id, '_mainwp_edit_post_id', $edit_id );
1047 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.
1048 if ( isset( $post_category ) && '' !== $post_category ) {
1049 update_post_meta( $new_post_id, '_categories', base64_encode( $post_category ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1050 }
1051
1052 if ( isset( $post_tags ) && '' !== $post_tags ) {
1053 update_post_meta( $new_post_id, '_tags', base64_encode( $post_tags ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1054 }
1055 if ( $is_sticky ) {
1056 update_post_meta( $new_post_id, '_sticky', base64_encode( 'sticky' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1057 }
1058
1059 if ( null !== $post_featured_image && ! empty( $post_featured_image ) ) {
1060 try {
1061 $upload = self::upload_image( $post_featured_image );
1062
1063 if ( null !== $upload ) {
1064 update_post_meta( $new_post_id, '_thumbnail_id', $upload['id'] );
1065 }
1066 } catch ( \Exception $e ) {
1067 // ok.
1068 }
1069 }
1070
1071 $ret = array();
1072 $ret['success'] = true;
1073 $ret['id'] = $new_post_id;
1074 return $ret;
1075 }
1076
1077 /**
1078 * Method replace_advanced_image()
1079 *
1080 * Handle upload advanced image.
1081 *
1082 * @param array $content post content data.
1083 * @param array $upload_dir upload directory info.
1084 * @param mixed $website The website.
1085 * @param bool $withslashes to use preg pattern with slashes.
1086 *
1087 * @return mixed array of result.
1088 */
1089 public static function replace_advanced_image( $content, $upload_dir, $website, $withslashes = false ) {
1090
1091 if ( empty( $upload_dir ) || ! isset( $upload_dir['baseurl'] ) ) {
1092 return $content;
1093 }
1094
1095 $dashboard_url = get_site_url();
1096 $site_url_source = $website->url;
1097
1098 // to fix url with slashes.
1099 if ( $withslashes ) {
1100 $site_url_source = str_replace( '/', '\/', $site_url_source );
1101 $dashboard_url = str_replace( '/', '\/', $dashboard_url );
1102 }
1103
1104 $foundMatches = preg_match_all( '#(' . preg_quote( $site_url_source, null ) . ')[^\.]*(\.(png|gif|jpg|jpeg))#ix', $content, $matches, PREG_SET_ORDER ); // phpcs:ignore -- Current complexity.
1105
1106 if ( 0 < $foundMatches ) {
1107
1108 $matches_checked = array();
1109 $check_double = array();
1110 foreach ( $matches as $match ) {
1111 // to avoid double images.
1112 if ( ! in_array( $match[0], $check_double ) ) {
1113 $check_double[] = $match[0];
1114 $matches_checked[] = $match;
1115 }
1116 }
1117 foreach ( $matches_checked as $match ) {
1118
1119 $imgUrl = $match[0];
1120 if ( false === strripos( wp_unslash( $imgUrl ), $upload_dir['baseurl'] ) ) {
1121 continue;
1122 }
1123
1124 if ( preg_match( '/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $imgUrl, $imgMatches ) ) {
1125 $search = $imgMatches[0];
1126 $replace = '.' . $match[3];
1127 $originalImgUrl = str_replace( $search, $replace, $imgUrl );
1128 } else {
1129 $originalImgUrl = $imgUrl;
1130 }
1131
1132 try {
1133 $downloadfile = self::upload_image( wp_unslash( $originalImgUrl ) );
1134 $localUrl = $downloadfile['url'];
1135 $linkToReplaceWith = dirname( $localUrl );
1136 $lnkToReplace = dirname( $imgUrl );
1137 if ( 'http:' !== $lnkToReplace && 'https:' !== $lnkToReplace ) {
1138 $content = str_replace( $imgUrl, $localUrl, $content ); // replace src image.
1139 $content = str_replace( $lnkToReplace, $linkToReplaceWith, $content );
1140 }
1141 } catch ( \Exception $e ) {
1142 // ok.
1143 }
1144 }
1145 if ( false === strripos( $site_url_source, $dashboard_url ) ) {
1146 // replace other images src outside upload folder.
1147 $content = str_replace( $site_url_source, $dashboard_url, $content );
1148 }
1149 }
1150 return $content;
1151 }
1152
1153 /**
1154 * Method upload_image()
1155 *
1156 * Handle upload image.
1157 *
1158 * @throws \Exception Error upload file.
1159 *
1160 * @param string $img_url URL for the image.
1161 * @param array $img_data Array of image data.
1162 *
1163 * @return mixed array of result or null.
1164 *
1165 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
1166 */
1167 public static function upload_image( $img_url, $img_data = array() ) {
1168 if ( ! is_array( $img_data ) ) {
1169 $img_data = array();
1170 }
1171 include_once ABSPATH . 'wp-admin/includes/file.php';
1172 $upload_dir = wp_upload_dir();
1173 $temporary_file = download_url( $img_url );
1174
1175 if ( is_wp_error( $temporary_file ) ) {
1176 throw new \Exception( 'Error: ' . $temporary_file->get_error_message() ); //phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
1177 } else {
1178 $upload_dir = wp_upload_dir();
1179 $local_img_path = $upload_dir['path'] . DIRECTORY_SEPARATOR . basename( $img_url );
1180 $local_img_url = $upload_dir['url'] . '/' . basename( $img_url );
1181 $moved = false;
1182 if ( MainWP_Utility::check_image_file_name( $local_img_path ) ) {
1183 global $wp_filesystem;
1184 if ( $wp_filesystem ) {
1185 $moved = $wp_filesystem->move( $temporary_file, $local_img_path );
1186 }
1187 }
1188 if ( $moved ) {
1189 $wp_filetype = wp_check_filetype( basename( $img_url ), null );
1190 $attachment = array(
1191 'post_mime_type' => $wp_filetype['type'],
1192 'post_title' => isset( $img_data['title'] ) && ! empty( $img_data['title'] ) ? $img_data['title'] : preg_replace( '/\.[^.]+$/', '', basename( $img_url ) ),
1193 'post_content' => isset( $img_data['description'] ) && ! empty( $img_data['description'] ) ? $img_data['description'] : '',
1194 'post_excerpt' => isset( $img_data['caption'] ) && ! empty( $img_data['caption'] ) ? MainWP_Utility::esc_content( $img_data['caption'] ) : '',
1195 'post_status' => 'inherit',
1196 );
1197 $attach_id = wp_insert_attachment( $attachment, $local_img_path );
1198 require_once ABSPATH . 'wp-admin/includes/image.php';
1199 $attach_data = wp_generate_attachment_metadata( $attach_id, $local_img_path );
1200 wp_update_attachment_metadata( $attach_id, $attach_data );
1201 if ( isset( $img_data['alt'] ) && ! empty( $img_data['alt'] ) ) {
1202 update_post_meta( $attach_id, '_wp_attachment_image_alt', $img_data['alt'] );
1203 }
1204 return array(
1205 'id' => $attach_id,
1206 'url' => $local_img_url,
1207 );
1208 }
1209 }
1210
1211 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
1212
1213 /**
1214 * WordPress files system object.
1215 *
1216 * @global object
1217 */
1218 global $wp_filesystem;
1219
1220 if ( $wp_filesystem->exists( $temporary_file ) ) {
1221 $wp_filesystem->delete( $temporary_file );
1222 }
1223
1224 return null;
1225 }
1226
1227 /**
1228 * Method add_sticky_handle()
1229 *
1230 * Add post meta.
1231 *
1232 * @param mixed $post_id Post ID.
1233 *
1234 * @return int $post_id Post ID.
1235 */
1236 public static function add_sticky_handle( $post_id ) {
1237 $_post = get_post( $post_id );
1238 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1239 if ( 'bulkpost' === $_post->post_type && isset( $_POST['sticky'] ) ) {
1240 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.
1241 return base64_encode( sanitize_text_field( wp_unslash( $_POST['sticky'] ) ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
1242 }
1243 // phpcs:enable
1244 return $post_id;
1245 }
1246
1247
1248 /**
1249 * Method add_status_handle()
1250 *
1251 * Add edit post status handle.
1252 *
1253 * @param int $post_id Post ID.
1254 *
1255 * @return int $post_id Post id with status handle added to it.
1256 */
1257 public static function add_status_handle( $post_id ) {
1258 $_post = get_post( $post_id );
1259 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1260 if ( ( 'bulkpage' === $_post->post_type || 'bulkpost' === $_post->post_type ) && isset( $_POST['mainwp_edit_post_status'] ) ) {
1261 update_post_meta( $post_id, '_edit_post_status', sanitize_text_field( wp_unslash( $_POST['mainwp_edit_post_status'] ) ) );
1262 }
1263 // phpcs:enable
1264 return $post_id;
1265 }
1266 }
1267