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

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

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