PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
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 / widgets / widget-mainwp-recent-posts.php

widget-mainwp-recent-posts.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies trunk, at widgets/widget-mainwp-recent-posts.php

826 lines 43.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Recent Posts Widget
4 *
5 * Displays the Child Sites most recent published draft, pending, trash & future posts.
6 *
7 * @package MainWP/Widget_Recent_Posts
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class MainWP_Recent_Posts
19 *
20 * Displays the Child Sites most recent published draft, pending, trash & future posts.
21 */
22 class MainWP_Recent_Posts { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23
24 /**
25 * Method get_class_name()
26 *
27 * @return string __CLASS__ Class Name
28 */
29 public static function get_class_name() {
30 return __CLASS__;
31 }
32
33 /**
34 * Method render()
35 *
36 * Fire off render_sites().
37 */
38 public static function render() {
39 static::render_sites();
40 }
41
42 /**
43 * Method render_sites()
44 *
45 * Build the recent posts list.
46 *
47 * @uses \MainWP\Dashboard\MainWP_DB::query()
48 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
49 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
50 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
51 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_current_wpid()
52 */
53 public static function render_sites() { // phpcs:ignore -- NOSONAR - complex.
54
55 /**
56 * Sets number of recent posts & pages
57 *
58 * Limits the number of recent posts & pages to show in the widget. Min 0, Max 30, Default 5.
59 *
60 * @since 4.0
61 */
62 $recent_number = apply_filters( 'mainwp_recent_posts_pages_number', 5 );
63
64 $allPosts = array();
65
66 $current_wpid = MainWP_System_Utility::get_current_wpid();
67
68 if ( isset( $_GET['client_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
69 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
70 $data_fields[] = 'recent_posts';
71 $individual = false;
72 $client_id = isset( $_GET['client_id'] ) ? intval( $_GET['client_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
73 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids( $client_id, array( 'select_data' => $data_fields ) );
74
75 if ( $websites ) {
76 foreach ( $websites as $website ) {
77 if ( empty( $website->recent_posts ) ) {
78 continue;
79 }
80
81 $posts = json_decode( $website->recent_posts, 1 );
82 if ( empty( $posts ) ) {
83 continue;
84 }
85 foreach ( $posts as $post ) {
86 $post['website'] = (object) array(
87 'id' => $website->id,
88 'url' => $website->url,
89 'name' => $website->name,
90 );
91 $allPosts[] = $post;
92 }
93 }
94 }
95 } else {
96 if ( $current_wpid ) {
97 $sql = MainWP_DB::instance()->get_sql_website_by_id( $current_wpid );
98 $websites = MainWP_DB::instance()->query( $sql );
99 $individual = true;
100 } else {
101 $wpsite_fields = array( 'id', 'name', 'url' );
102 $websites = MainWP_DB::instance()->query(
103 MainWP_DB::instance()->get_sql_websites_for_current_user_by_params(
104 array(
105 'view' => 'custom_view',
106 'others_fields' => array( 'recent_posts' ),
107 'select_wp_fields' => $wpsite_fields,
108 )
109 )
110 );
111 $individual = false;
112 }
113
114 if ( $websites ) {
115 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
116 if ( empty( $website->recent_posts ) ) {
117 continue;
118 }
119
120 $posts = json_decode( $website->recent_posts, 1 );
121 if ( empty( $posts ) ) {
122 continue;
123 }
124 foreach ( $posts as $post ) {
125 $post['website'] = (object) array(
126 'id' => $website->id,
127 'url' => $website->url,
128 'name' => $website->name,
129 );
130 $allPosts[] = $post;
131 }
132 }
133 MainWP_DB::free_result( $websites );
134 }
135 }
136
137 static::render_top_grid();
138
139 /**
140 * Action: mainwp_recent_posts_widget_top
141 *
142 * Fires at the top of the Recent Posts widget.
143 *
144 * @since 4.1
145 */
146 do_action( 'mainwp_recent_posts_widget_top' );
147 ?>
148 <div class="mainwp-scrolly-overflow">
149 <?php
150 static::render_published_posts( $allPosts, $recent_number, $individual );
151 static::render_draft_posts( $allPosts, $recent_number, $individual );
152 static::render_pending_posts( $allPosts, $recent_number, $individual );
153 static::render_future_posts( $allPosts, $recent_number, $individual );
154 static::render_trash_posts( $allPosts, $recent_number, $individual );
155 ?>
156 </div>
157 <?php
158 /**
159 * Action: mainwp_recent_posts_after_lists
160 *
161 * Fires after the recent posts lists, before the bottom actions section.
162 *
163 * @since 4.1
164 */
165 do_action( 'mainwp_recent_posts_after_lists' );
166 ?>
167
168 <div class="ui stackable grid mainwp-widget-footer">
169 <div class="eight wide left aligned middle aligned column">
170 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkAdd' ) ); ?>" class="ui mini basic button"><?php esc_html_e( 'Create a New Post', 'mainwp' ); ?></a>
171 </div>
172 <div class="eight wide right aligned middle aligned column">
173 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PostBulkManage' ) ); ?>" class="ui mini basic button"><?php esc_html_e( 'Manage Posts', 'mainwp' ); ?></a>
174 </div>
175 </div>
176 <?php
177 /**
178 * Action: mainwp_recent_posts_widget_bottom
179 *
180 * Fires at the bottom of the Recent Posts widget.
181 *
182 * @since 4.1
183 */
184 do_action( 'mainwp_recent_posts_widget_bottom' );
185 }
186
187 /**
188 * Render MainWP Recent Posts Widget Header
189 */
190 public static function render_top_grid() {
191 ?>
192 <div class="ui grid mainwp-widget-header">
193 <div class="twelve wide column">
194 <h2 class="ui header handle-drag">
195 <?php
196 /**
197 * Filter: mainwp_recent_posts_widget_title
198 *
199 * Filters the recent posts widget title text.
200 *
201 * @since 4.1
202 */
203 echo esc_html( apply_filters( 'mainwp_recent_posts_widget_title', esc_html__( 'Recent Posts', 'mainwp' ) ) );
204 ?>
205 <?php if ( isset( $_GET['client_id'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing ?>
206 <div class="sub header"><?php esc_html_e( 'The most recent posts from the Client websites', 'mainwp' ); ?></div>
207 <?php else : ?>
208 <div class="sub header"><?php esc_html_e( 'The most recent posts from your websites', 'mainwp' ); ?></div>
209 <?php endif; ?>
210 </h2>
211 </div>
212 <div class="four wide column right aligned">
213 <div class="ui dropdown right tiny pointing mainwp-dropdown-tab">
214 <i class="vertical ellipsis icon"></i>
215 <div class="menu">
216 <a class="item recent_posts_published_lnk" data-tab="published" data-value="published" title="<?php esc_attr_e( 'Published', 'mainwp' ); ?>" href="#"><?php esc_html_e( 'Published', 'mainwp' ); ?></a>
217 <a class="item recent_posts_draft_lnk" data-tab="draft" data-value="draft" title="<?php esc_attr_e( 'Draft', 'mainwp' ); ?>" href="#"><?php esc_html_e( 'Draft', 'mainwp' ); ?></a>
218 <a class="item recent_posts_pending_lnk" data-tab="pending" data-value="pending" title="<?php esc_attr_e( 'Pending', 'mainwp' ); ?>" href="#"><?php esc_html_e( 'Pending', 'mainwp' ); ?></a>
219 <a class="item recent_posts_future_lnk" data-tab="future" data-value="future" title="<?php esc_attr_e( 'Scheduled', 'mainwp' ); ?>" href="#"><?php esc_html_e( 'Scheduled', 'mainwp' ); ?></a>
220 <a class="item recent_posts_trash_lnk" data-tab="trash" data-value="trash" title="<?php esc_attr_e( 'Trash', 'mainwp' ); ?>" href="#"><?php esc_html_e( 'Trash', 'mainwp' ); ?></a>
221 </div>
222 </div>
223 </div>
224 </div>
225 <?php
226 }
227
228 /**
229 * Render Published Posts.
230 *
231 * @param array $allPosts All posts data.
232 * @param int $recent_number Number of posts.
233 * @param bool $individual Determins if it's individual site dashboard.
234 *
235 * @uses \MainWP\Dashboard\MainWP_Utility::get_sub_array_having()
236 * @uses \MainWP\Dashboard\MainWP_Utility::sortmulti()
237 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
238 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
239 */
240 public static function render_published_posts( $allPosts, $recent_number, $individual ) { // phpcs:ignore -- NOSONAR - complex.
241 $recent_posts_published = MainWP_Utility::get_sub_array_having( $allPosts, 'status', 'publish' );
242 $recent_posts_published = MainWP_Utility::sortmulti( $recent_posts_published, 'dts', 'desc' );
243 $is_demo = MainWP_Demo_Handle::is_demo_mode();
244 ?>
245 <div class="recent_posts_published ui tab active" data-tab="published">
246 <?php
247 /**
248 * Action: mainwp_recent_posts_before_publised_list
249 *
250 * Fires before the list of recent published Posts.
251 *
252 * @param array $allPosts All posts data.
253 * @param int $recent_number Number of posts.
254 *
255 * @since 4.1
256 */
257 do_action( 'mainwp_recent_posts_before_publised_list', $allPosts, $recent_number );
258 if ( empty( $recent_posts_published ) ) {
259 MainWP_UI::render_empty_element_placeholder( __( 'No Recent Posts Found', 'mainwp' ), __( 'Recent post changes will appear here once activity is detected.', 'mainwp' ), '<em data-emoji=":pencil:" class="medium"></em>' );
260 }
261 ?>
262 <div class="ui middle aligned divided list">
263 <?php
264 $_count = count( $recent_posts_published );
265 for ( $i = 0; $i < $_count && $i < $recent_number; $i++ ) {
266 if ( ! isset( $recent_posts_published[ $i ]['title'] ) || empty( $recent_posts_published[ $i ]['title'] ) ) {
267 $recent_posts_published[ $i ]['title'] = '(No Title)';
268 }
269 if ( isset( $recent_posts_published[ $i ]['dts'] ) && ! stristr( $recent_posts_published[ $i ]['dts'], '-' ) ) {
270 $recent_posts_published[ $i ]['dts'] = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $recent_posts_published[ $i ]['dts'] ) );
271 }
272
273 $name = wp_strip_all_tags( $recent_posts_published[ $i ]['website']->name );
274
275 ?>
276 <div class="item">
277 <div class="ui grid">
278 <input class="postId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_published[ $i ]['id'] ); ?>"/>
279 <input class="websiteId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_published[ $i ]['website']->id ); ?>"/>
280 <div class="fourteen wide column middle aligned">
281 <div>
282 <a href="<?php echo esc_url( $recent_posts_published[ $i ]['website']->url ); ?>?p=<?php echo esc_attr( $recent_posts_published[ $i ]['id'] ); ?>" class="mainwp-may-hide-referrer" target="_blank"><?php echo esc_html( htmlentities( $recent_posts_published[ $i ]['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8' ) ); ?></a>
283 <?php if ( ! $individual ) : ?>
284 <?php esc_html_e( 'on', 'mainwp' ); ?> <a href="<?php echo esc_url( $recent_posts_published[ $i ]['website']->url ); ?>" target="_blank"><?php echo $name; // phpcs:ignore WordPress.Security.EscapeOutput ?></a>
285 <?php endif; ?>
286 </div>
287 <span class="ui small text"><?php echo esc_html( $recent_posts_published[ $i ]['dts'] ); ?></span>
288 </div>
289 <div class="two wide column right aligned">
290 <div class="ui right pointing dropdown" style="z-index:999">
291 <i class="ellipsis vertical icon"></i>
292 <div class="menu">
293 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-unpublish" href="#"><?php esc_html_e( 'Unpublish', 'mainwp' ); ?></a>
294 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item" href="<?php MainWP_Site_Open::get_open_site_admin_link( $recent_posts_published[ $i ]['website']->id, true ); ?>&location=<?php echo esc_attr( base64_encode( 'post.php?action=editpost&post=' . $recent_posts_published[ $i ]['id'] . '&action=edit' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. ?>" target="_blank"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
295 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-trash" href="#"><?php esc_html_e( 'Trash', 'mainwp' ); ?></a>
296 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item" href="<?php echo esc_url( $recent_posts_published[ $i ]['website']->url ) . ( '/' !== substr( $recent_posts_published[ $i ]['website']->url, - 1 ) ? '/' : '' ) . '?p=' . esc_attr( $recent_posts_published[ $i ]['id'] ); ?>" target="_blank"><?php esc_html_e( 'View', 'mainwp' ); ?></a>
297 </div>
298 </div>
299 </div>
300 </div>
301 <div class="mainwp-row-actions-working"><i class="notched circle loading icon"></i><?php esc_html_e( 'Please wait...', 'mainwp' ); ?></div>
302 </div>
303 <?php } ?>
304 </div>
305 <?php
306 /**
307 * Action: mainwp_recent_posts_after_publised_list
308 *
309 * Fires after the list of recent published Posts.
310 *
311 * @param array $allPosts All posts data.
312 * @param int $recent_number Number of posts.
313 *
314 * @since 4.1
315 */
316 do_action( 'mainwp_recent_posts_after_publised_list', $allPosts, $recent_number );
317 ?>
318 </div>
319 <?php
320 }
321
322 /**
323 * Render all draft posts.
324 *
325 * @param array $allPosts All posts data.
326 * @param int $recent_number Number of posts.
327 * @param bool $individual Determins if it's individual site dashboard.
328 *
329 * @uses \MainWP\Dashboard\MainWP_Utility::get_sub_array_having()
330 * @uses \MainWP\Dashboard\MainWP_Utility::sortmulti()
331 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
332 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
333 */
334 public static function render_draft_posts( $allPosts, $recent_number, $individual ) { // phpcs:ignore -- NOSONAR - complex.
335 $recent_posts_draft = MainWP_Utility::get_sub_array_having( $allPosts, 'status', 'draft' );
336 $recent_posts_draft = MainWP_Utility::sortmulti( $recent_posts_draft, 'dts', 'desc' );
337 $is_demo = MainWP_Demo_Handle::is_demo_mode();
338 ?>
339 <div class="recent_posts_draft ui tab" data-tab="draft">
340 <?php
341 /**
342 * Action: mainwp_recent_posts_before_draft_list
343 *
344 * Fires before the list of recent draft Posts.
345 *
346 * @param array $allPosts All posts data.
347 * @param int $recent_number Number of posts.
348 *
349 * @since 4.1
350 */
351 do_action( 'mainwp_recent_posts_before_draft_list', $allPosts, $recent_number );
352 if ( empty( $recent_posts_draft ) ) {
353 MainWP_UI::render_empty_element_placeholder( __( 'No Recent Posts Found', 'mainwp' ), __( 'Recent post changes will appear here once activity is detected.', 'mainwp' ), '<em data-emoji=":pencil:" class="medium"></em>' );
354 }
355 ?>
356 <div class="ui middle aligned divided list">
357 <?php
358 $_count = count( $recent_posts_draft );
359 for ( $i = 0; $i < $_count && $i < $recent_number; $i++ ) {
360 if ( ! isset( $recent_posts_draft[ $i ]['title'] ) || empty( $recent_posts_draft[ $i ]['title'] ) ) {
361 $recent_posts_draft[ $i ]['title'] = '(No Title)';
362 }
363 if ( isset( $recent_posts_draft[ $i ]['dts'] ) && ! stristr( $recent_posts_draft[ $i ]['dts'], '-' ) ) {
364 $recent_posts_draft[ $i ]['dts'] = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $recent_posts_draft[ $i ]['dts'] ) );
365 }
366 $name = wp_strip_all_tags( $recent_posts_draft[ $i ]['website']->name );
367 ?>
368 <div class="item">
369 <div class="ui grid">
370 <input class="postId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_draft[ $i ]['id'] ); ?>"/>
371 <input class="websiteId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_draft[ $i ]['website']->id ); ?>"/>
372 <div class="fourteen wide column middle aligned">
373 <div>
374 <a href="<?php echo esc_url( $recent_posts_draft[ $i ]['website']->url ); ?>?p=<?php echo esc_attr( $recent_posts_draft[ $i ]['id'] ); ?>" class="mainwp-may-hide-referrer" target="_blank"><?php echo esc_html( htmlentities( $recent_posts_draft[ $i ]['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8' ) ); ?></a>
375 <?php if ( ! $individual ) : ?>
376 <?php esc_html_e( 'on', 'mainwp' ); ?> <a href="<?php echo esc_url( $recent_posts_draft[ $i ]['website']->url ); ?>" target="_blank"><?php echo $name; // phpcs:ignore WordPress.Security.EscapeOutput ?></a>
377 <?php endif; ?>
378 </div>
379 <span class="ui small text"><?php echo esc_html( $recent_posts_draft[ $i ]['dts'] ); ?></span>
380 </div>
381 <div class="two wide column right aligned">
382 <div class="ui right pointing dropdown" style="z-index:999">
383 <i class="ellipsis vertical icon"></i>
384 <div class="menu">
385 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-publish" href="#"><?php esc_html_e( 'Publish', 'mainwp' ); ?></a>
386 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item" href="<?php MainWP_Site_Open::get_open_site_admin_link( $recent_posts_draft[ $i ]['website']->id, true ); ?>&location=<?php echo esc_attr( base64_encode( 'post.php?action=editpost&post=' . $recent_posts_draft[ $i ]['id'] . '&action=edit' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. ?>" target="_blank"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
387 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-trash" href="#"><?php esc_html_e( 'Trash', 'mainwp' ); ?></a>
388 </div>
389 </div>
390 </div>
391 </div>
392 <div class="mainwp-row-actions-working"><i class="notched circle loading icon"></i><?php esc_html_e( 'Please wait...', 'mainwp' ); ?></div>
393 </div>
394 <?php } ?>
395 </div>
396 <?php
397 /**
398 * Action: mainwp_recent_posts_after_draft_list
399 *
400 * Fires after the list of recent draft Posts.
401 *
402 * @param array $allPosts All posts data.
403 * @param int $recent_number Number of posts.
404 *
405 * @since 4.1
406 */
407 do_action( 'mainwp_recent_posts_after_draft_list', $allPosts, $recent_number );
408 ?>
409 </div>
410 <?php
411 }
412
413 /**
414 * Render all pending posts.
415 *
416 * @param array $allPosts All posts data.
417 * @param int $recent_number Number of posts.
418 * @param bool $individual Determins if it's individual site dashboard.
419 *
420 * @uses \MainWP\Dashboard\MainWP_Utility::get_sub_array_having()
421 * @uses \MainWP\Dashboard\MainWP_Utility::sortmulti()
422 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
423 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
424 */
425 public static function render_pending_posts( $allPosts, $recent_number, $individual ) { // phpcs:ignore -- NOSONAR - complex.
426 $recent_posts_pending = MainWP_Utility::get_sub_array_having( $allPosts, 'status', 'pending' );
427 $recent_posts_pending = MainWP_Utility::sortmulti( $recent_posts_pending, 'dts', 'desc' );
428 $is_demo = MainWP_Demo_Handle::is_demo_mode();
429 ?>
430 <div class="recent_posts_pending ui bottom attached tab" data-tab="pending">
431 <?php
432 /**
433 * Action: mainwp_recent_posts_before_pending_list
434 *
435 * Fires before the list of recent pending Posts.
436 *
437 * @param array $allPosts All posts data.
438 * @param int $recent_number Number of posts.
439 *
440 * @since 4.1
441 */
442 do_action( 'mainwp_recent_posts_before_pending_list', $allPosts, $recent_number );
443 if ( empty( $recent_posts_pending ) ) {
444 MainWP_UI::render_empty_element_placeholder( __( 'No Recent Posts Found', 'mainwp' ), __( 'Recent post changes will appear here once activity is detected.', 'mainwp' ), '<em data-emoji=":pencil:" class="medium"></em>' );
445 }
446 ?>
447 <div class="ui middle aligned divided list">
448 <?php
449 $_count = count( $recent_posts_pending );
450 for ( $i = 0; $i < $_count && $i < $recent_number; $i++ ) {
451 if ( ! isset( $recent_posts_pending[ $i ]['title'] ) || empty( $recent_posts_pending[ $i ]['title'] ) ) {
452 $recent_posts_pending[ $i ]['title'] = '(No Title)';
453 }
454 if ( isset( $recent_posts_pending[ $i ]['dts'] ) && ! stristr( $recent_posts_pending[ $i ]['dts'], '-' ) ) {
455 $recent_posts_pending[ $i ]['dts'] = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $recent_posts_pending[ $i ]['dts'] ) );
456 }
457 $name = wp_strip_all_tags( $recent_posts_pending[ $i ]['website']->name );
458 ?>
459 <div class="item">
460 <div class="ui grid">
461 <input class="postId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_pending[ $i ]['id'] ); ?>"/>
462 <input class="websiteId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_pending[ $i ]['website']->id ); ?>"/>
463 <div class="fourteen wide column middle aligned">
464 <div>
465 <a href="<?php echo esc_url( $recent_posts_pending[ $i ]['website']->url ); ?>?p=<?php echo esc_attr( $recent_posts_pending[ $i ]['id'] ); ?>" class="mainwp-may-hide-referrer" target="_blank"><?php echo esc_html( htmlentities( $recent_posts_pending[ $i ]['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8' ) ); ?></a>
466 <?php if ( ! $individual ) : ?>
467 <?php esc_html_e( 'on', 'mainwp' ); ?> <a href="<?php echo esc_url( $recent_posts_pending[ $i ]['website']->url ); ?>" target="_blank"><?php echo $name; // phpcs:ignore WordPress.Security.EscapeOutput ?></a>
468 <?php endif; ?>
469 </div>
470 <span class="ui small text"><?php echo esc_html( $recent_posts_pending[ $i ]['dts'] ); ?></span>
471 </div>
472 <div class="two wide column right aligned">
473 <div class="ui right pointing dropdown" style="z-index:999">
474 <i class="ellipsis vertical icon"></i>
475 <div class="menu">
476 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-publish" href="#"><?php esc_html_e( 'Publish', 'mainwp' ); ?></a>
477 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item" href="<?php MainWP_Site_Open::get_open_site_admin_link( $recent_posts_pending[ $i ]['website']->id, true ); ?>&location=<?php echo esc_attr( base64_encode( 'post.php?action=editpost&post=' . $recent_posts_pending[ $i ]['id'] . '&action=edit' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. ?>" target="_blank"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
478 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-trash" href="#"><?php esc_html_e( 'Trash', 'mainwp' ); ?></a>
479 </div>
480 </div>
481 </div>
482 </div>
483 <div class="mainwp-row-actions-working"><i class="notched circle loading icon"></i><?php esc_html_e( 'Please wait...', 'mainwp' ); ?></div>
484 </div>
485 <?php } ?>
486 </div>
487 <?php
488 /**
489 * Action: mainwp_recent_posts_after_pending_list
490 *
491 * Fires after the list of recent pending Posts.
492 *
493 * @param array $allPosts All posts data.
494 * @param int $recent_number Number of posts.
495 *
496 * @since 4.1
497 */
498 do_action( 'mainwp_recent_posts_after_pending_list', $allPosts, $recent_number );
499 ?>
500 </div>
501 <?php
502 }
503
504 /**
505 * Render all future posts.
506 *
507 * @param array $allPosts All posts data.
508 * @param int $recent_number Number of posts.
509 * @param bool $individual Determins if it's individual site dashboard .
510 *
511 * @uses \MainWP\Dashboard\MainWP_Utility::get_sub_array_having()
512 * @uses \MainWP\Dashboard\MainWP_Utility::sortmulti()
513 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
514 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
515 */
516 public static function render_future_posts( $allPosts, $recent_number, $individual ) { // phpcs:ignore -- NOSONAR - complex.
517 $recent_posts_future = MainWP_Utility::get_sub_array_having( $allPosts, 'status', 'future' );
518 $recent_posts_future = MainWP_Utility::sortmulti( $recent_posts_future, 'dts', 'desc' );
519 $is_demo = MainWP_Demo_Handle::is_demo_mode();
520 ?>
521 <div class="recent_posts_future ui tab" data-tab="future">
522 <?php
523 /**
524 * Action: mainwp_recent_posts_before_future_list
525 *
526 * Fires before the list of recent future Posts.
527 *
528 * @param array $allPosts All posts data.
529 * @param int $recent_number Number of posts.
530 *
531 * @since 4.1
532 */
533 do_action( 'mainwp_recent_posts_before_future_list', $allPosts, $recent_number );
534 if ( empty( $recent_posts_future ) ) {
535 MainWP_UI::render_empty_element_placeholder( __( 'No Recent Posts Found', 'mainwp' ), __( 'Recent post changes will appear here once activity is detected.', 'mainwp' ), '<em data-emoji=":pencil:" class="medium"></em>' );
536 }
537 ?>
538 <div class="ui middle aligned divided list">
539 <?php
540 $_count = count( $recent_posts_future );
541 for ( $i = 0; $i < $_count && $i < $recent_number; $i++ ) {
542 if ( ! isset( $recent_posts_future[ $i ]['title'] ) || empty( $recent_posts_future[ $i ]['title'] ) ) {
543 $recent_posts_future[ $i ]['title'] = '(No Title)';
544 }
545 if ( isset( $recent_posts_future[ $i ]['dts'] ) && ! stristr( $recent_posts_future[ $i ]['dts'], '-' ) ) {
546 $recent_posts_future[ $i ]['dts'] = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $recent_posts_future[ $i ]['dts'] ) );
547 }
548 $name = wp_strip_all_tags( $recent_posts_future[ $i ]['website']->name );
549 ?>
550 <div class="item">
551 <div class="ui grid">
552 <input class="postId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_future[ $i ]['id'] ); ?>"/>
553 <input class="websiteId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_future[ $i ]['website']->id ); ?>"/>
554 <div class="fourteen wide column middle aligned">
555 <div>
556 <a href="<?php echo esc_url( $recent_posts_future[ $i ]['website']->url ); ?>?p=<?php echo esc_attr( $recent_posts_future[ $i ]['id'] ); ?>" class="mainwp-may-hide-referrer" target="_blank"><?php echo esc_html( htmlentities( $recent_posts_future[ $i ]['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8' ) ); ?></a>
557 <?php if ( ! $individual ) : ?>
558 <?php esc_html_e( 'on', 'mainwp' ); ?> <a href="<?php echo esc_url( $recent_posts_future[ $i ]['website']->url ); ?>" target="_blank"><?php echo $name; // phpcs:ignore WordPress.Security.EscapeOutput ?></a>
559 <?php endif; ?>
560 </div>
561 <span class="ui small text"><?php echo esc_html( $recent_posts_future[ $i ]['dts'] ); ?></span>
562 </div>
563 <div class="two wide column right aligned">
564 <div class="ui right pointing dropdown" style="z-index:999">
565 <i class="ellipsis vertical icon"></i>
566 <div class="menu">
567 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-publish" href="#"><?php esc_html_e( 'Publish', 'mainwp' ); ?></a>
568 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item" href="<?php MainWP_Site_Open::get_open_site_admin_link( $recent_posts_future[ $i ]['website']->id, true ); ?>&location=<?php echo esc_attr( base64_encode( 'post.php?action=editpost&post=' . $recent_posts_future[ $i ]['id'] . '&action=edit' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. ?>" target="_blank"><?php esc_html_e( 'Edit', 'mainwp' ); ?></a>
569 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-trash" href="#"><?php esc_html_e( 'Trash', 'mainwp' ); ?></a>
570 <a class="<?php echo $is_demo ? 'disabled' : ''; ?> item" href="<?php MainWP_Site_Open::get_open_site_admin_link( $recent_posts_future[ $i ]['website']->id, true ); ?>&openUrl=yes&location=<?php echo esc_attr( base64_encode( '?p=' . $recent_posts_future[ $i ]['id'] . '&preview=true' ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible. ?>" target="_blank"><?php esc_html_e( 'Preview', 'mainwp' ); ?></a>
571 </div>
572 </div>
573 </div>
574 </div>
575 <div class="mainwp-row-actions-working"><i class="notched circle loading icon"></i><?php esc_html_e( 'Please wait...', 'mainwp' ); ?></div>
576 </div>
577 <?php } ?>
578 </div>
579 <?php
580 /**
581 * Action: mainwp_recent_posts_after_future_list
582 *
583 * Fires after the list of recent future Posts.
584 *
585 * @param array $allPosts All posts data.
586 * @param int $recent_number Number of posts.
587 *
588 * @since 4.1
589 */
590 do_action( 'mainwp_recent_posts_after_future_list', $allPosts, $recent_number );
591 ?>
592 </div>
593 <?php
594 }
595
596 /**
597 * Render all trashed posts.
598 *
599 * @param array $allPosts All posts data.
600 * @param int $recent_number Number of posts.
601 * @param bool $individual Determins if it's individual site dashboard .
602 *
603 * @uses \MainWP\Dashboard\MainWP_Utility::get_sub_array_having()
604 * @uses \MainWP\Dashboard\MainWP_Utility::sortmulti()
605 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
606 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
607 */
608 public static function render_trash_posts( $allPosts, $recent_number, $individual ) { // phpcs:ignore -- NOSONAR - complex.
609 $recent_posts_trash = MainWP_Utility::get_sub_array_having( $allPosts, 'status', 'trash' );
610 $recent_posts_trash = MainWP_Utility::sortmulti( $recent_posts_trash, 'dts', 'desc' );
611 $is_demo = MainWP_Demo_Handle::is_demo_mode();
612 ?>
613 <div class="recent_posts_trash ui tab" data-tab="trash">
614 <?php
615 /**
616 * Action: mainwp_recent_posts_before_trash_list
617 *
618 * Fires before the list of recent trash Posts.
619 *
620 * @param array $allPosts All posts data.
621 * @param int $recent_number Number of posts.
622 *
623 * @since 4.1
624 */
625 do_action( 'mainwp_recent_posts_before_trash_list', $allPosts, $recent_number );
626 if ( empty( $recent_posts_trash ) ) {
627 MainWP_UI::render_empty_element_placeholder( __( 'No Recent Posts Found', 'mainwp' ), __( 'Recent post changes will appear here once activity is detected.', 'mainwp' ), '<em data-emoji=":pencil:" class="medium"></em>' );
628 }
629 ?>
630 <div class="ui middle aligned divided list">
631 <?php
632 $_count = count( $recent_posts_trash );
633 for ( $i = 0; $i < $_count && $i < $recent_number; $i++ ) {
634 if ( ! isset( $recent_posts_trash[ $i ]['title'] ) || empty( $recent_posts_trash[ $i ]['title'] ) ) {
635 $recent_posts_trash[ $i ]['title'] = '(No Title)';
636 }
637 if ( isset( $recent_posts_trash[ $i ]['dts'] ) && ! stristr( $recent_posts_trash[ $i ]['dts'], '-' ) ) {
638 $recent_posts_trash[ $i ]['dts'] = MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $recent_posts_trash[ $i ]['dts'] ) );
639 }
640 $name = wp_strip_all_tags( $recent_posts_trash[ $i ]['website']->name );
641 ?>
642 <div class="item">
643 <div class="ui grid">
644 <input class="postId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_trash[ $i ]['id'] ); ?>"/>
645 <input class="websiteId" type="hidden" name="id" value="<?php echo esc_attr( $recent_posts_trash[ $i ]['website']->id ); ?>"/>
646 <div class="fourteen wide column middle aligned">
647 <div>
648 <a href="<?php echo esc_url( $recent_posts_trash[ $i ]['website']->url ); ?>?p=<?php echo esc_attr( $recent_posts_trash[ $i ]['id'] ); ?>" class="mainwp-may-hide-referrer" target="_blank"><?php echo esc_html( htmlentities( $recent_posts_trash[ $i ]['title'], ENT_COMPAT | ENT_HTML401, 'UTF-8' ) ); ?></a>
649 <?php if ( ! $individual ) : ?>
650 <?php esc_html_e( 'on', 'mainwp' ); ?> <a href="<?php echo esc_url( $recent_posts_trash[ $i ]['website']->url ); ?>" target="_blank"><?php echo $name; // phpcs:ignore WordPress.Security.EscapeOutput ?></a>
651 <?php endif; ?>
652 </div>
653 <span class="ui small text"><?php echo esc_html( $recent_posts_trash[ $i ]['dts'] ); ?></span>
654 </div>
655 <div class="two wide column right aligned">
656 <div class="ui right pointing dropdown" style="z-index:999">
657 <i class="ellipsis vertical icon"></i>
658 <div class="menu">
659 <a href="#" class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-restore" ><?php esc_html_e( 'Restore', 'mainwp' ); ?></a>
660 <a href="#" class="<?php echo $is_demo ? 'disabled' : ''; ?> item mainwp-post-delete"><?php esc_html_e( 'Delete permanently', 'mainwp' ); ?></a>
661 </div>
662 </div>
663 </div>
664 </div>
665 <div class="mainwp-row-actions-working"><i class="notched circle loading icon"></i><?php esc_html_e( 'Please wait...', 'mainwp' ); ?></div>
666 </div>
667 <?php } ?>
668 </div>
669 <?php
670 /**
671 * Action: mainwp_recent_posts_after_trash_list
672 *
673 * Fires after the list of recent trash Posts.
674 *
675 * @param array $allPosts All posts data.
676 * @param int $recent_number Number of posts.
677 *
678 * @since 4.1
679 */
680 do_action( 'mainwp_recent_posts_after_trash_list', $allPosts, $recent_number );
681 ?>
682 </div>
683 <?php
684 }
685
686 /**
687 * Method publish()
688 *
689 * Publish Post.
690 */
691 public static function publish() {
692 static::action( 'publish' );
693 die( wp_json_encode( array( 'result' => esc_html__( 'The post has been published.', 'mainwp' ) ) ) );
694 }
695
696 /**
697 * Method approve()
698 *
699 * Approve Post.
700 */
701 public static function approve() {
702 static::action( 'publish' );
703 die( wp_json_encode( array( 'result' => esc_html__( 'The post has been approved.', 'mainwp' ) ) ) );
704 }
705
706 /**
707 * Method unpublish()
708 *
709 * Unpublish Post.
710 */
711 public static function unpublish() {
712 static::action( 'unpublish' );
713 die( wp_json_encode( array( 'result' => esc_html__( 'The post has been unpublished.', 'mainwp' ) ) ) );
714 }
715
716 /**
717 * Method trash()
718 *
719 * Trash Post.
720 */
721 public static function trash() {
722 static::action( 'trash' );
723 die( wp_json_encode( array( 'result' => esc_html__( 'The post has been moved to the trash.', 'mainwp' ) ) ) );
724 }
725
726 /**
727 * Method delete()
728 *
729 * Delete Post.
730 */
731 public static function delete() {
732 static::action( 'delete' );
733 die( wp_json_encode( array( 'result' => esc_html__( 'The post has been permanently deleted.', 'mainwp' ) ) ) );
734 }
735
736 /**
737 * Method restore()
738 *
739 * Restore Post.
740 */
741 public static function restore() {
742 static::action( 'restore' );
743 die( wp_json_encode( array( 'result' => esc_html__( 'The post has been restored.', 'mainwp' ) ) ) );
744 }
745
746 /**
747 * Method action()
748 *
749 * Initiate try catch for chosen Action
750 *
751 * @param string $pAction Post Action.
752 * @param string $type Post type.
753 *
754 * @throws \MainWP_Exception Error message.
755 *
756 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
757 * @uses \MainWP\Dashboard\MainWP_Error_Helper::get_error_message()
758 * @uses \MainWP\Dashboard\MainWP_Exception
759 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
760 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
761 */
762 public static function action( $pAction, $type = 'post' ) {
763 $postId = isset( $_POST['postId'] ) ? intval( $_POST['postId'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
764 $websiteId = isset( $_POST['websiteId'] ) ? intval( $_POST['websiteId'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
765
766 if ( empty( $postId ) || empty( $websiteId ) ) {
767 die( wp_json_encode( array( 'error' => 'Post ID or site ID not found. Please, reload the page and try again.' ) ) );
768 }
769
770 $website = MainWP_DB::instance()->get_website_by_id( $websiteId );
771 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
772 die( wp_json_encode( array( 'error' => 'You can not edit this website!' ) ) );
773 }
774
775 if ( MainWP_System_Utility::is_suspended_site( $website ) ) {
776 die(
777 wp_json_encode(
778 array(
779 'error' => esc_html__( 'Suspended site.', 'mainwp' ),
780 'errorCode' => 'SUSPENDED_SITE',
781 )
782 )
783 );
784 }
785
786 /**
787 * Action: mainwp_before_post_action
788 *
789 * Fires before post/page publish/unpublish/trash/delete/restore actions.
790 *
791 * @since 4.1
792 */
793 do_action( 'mainwp_before_post_action', $type, $pAction, $postId, $website );
794 try {
795 $information = MainWP_Connect::fetch_url_authed(
796 $website,
797 'post_action',
798 array(
799 'action' => $pAction,
800 'id' => $postId,
801 )
802 );
803
804 } catch ( MainWP_Exception $e ) {
805 $information = array( 'error' => MainWP_Error_Helper::get_error_message( $e ) );
806
807 }
808
809 /**
810 * Action: mainwp_after_post_action
811 * Fires after post/page publish/unpublish/trash/delete/restore actions.
812 *
813 * @since 4.1
814 */
815 do_action( 'mainwp_after_post_action', $information, $type, $pAction, $postId, $website );
816
817 mainwp_get_actions_handler_instance()->do_action_mainwp_post_action( $website, $pAction, $information, $postId, $type );
818
819 if ( is_array( $information ) && isset( $information['error'] ) ) {
820 die( wp_json_encode( $information ) );
821 } elseif ( ! isset( $information['status'] ) || ( 'SUCCESS' !== $information['status'] ) ) {
822 die( wp_json_encode( array( 'error' => 'Unexpected error!' ) ) );
823 }
824 }
825 }
826