PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.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
← All changes | widgets/widget-mainwp-connection-status.php +508 -222 6.1.2 → 6.2.1 View file →
@@ -21,8 +21,47 @@
21 21 */
22 22 class MainWP_Connection_Status { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23 23
24 24 /**
25 + * Public variable to hold Items information.
26 + *
27 + * @var array
28 + */
29 + public $items;
30 +
31 + /**
32 + * Public variable to hold total items number.
33 + *
34 + * @var integer
35 + */
36 + public $total_items;
37 +
38 + /**
39 + * Private static variable to hold the single instance of the class.
40 + *
41 + * @static
42 + *
43 + * @var mixed Default null
44 + */
45 + private static $instance = null;
46 +
47 + /**
48 + * Method instance()
49 + *
50 + * Return public static instance.
51 + *
52 + * @static
53 + * @return self
54 + */
55 + public static function instance() {
56 + if ( null === static::$instance ) {
57 + static::$instance = new self();
58 + }
59 + return static::$instance;
60 + }
61 +
62 +
63 + /**
25 64 * Method get_class_name()
26 65 *
27 66 * @return string __CLASS__ Class Name
28 67 */
@@ -35,13 +74,13 @@
35 74 *
36 75 * @return mixed render_sites()
37 76 */
38 77 public static function render() {
39 - static::render_sites();
78 + static::render_widget_content();
40 79 }
41 80
42 81 /**
43 - * Method render_sites()
82 + * Method render_widget_content()
44 83 *
45 84 * Build the Connection Status Widget
46 85 * Displays $SYNCERRORS|$UP|$ALL.
47 86 *
@@ -54,96 +93,21 @@
54 93 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
55 94 * @uses \MainWP\Dashboard\MainWP_Utility::format_timestamp()
56 95 * @uses \MainWP\Dashboard\MainWP_Utility::get_timestamp()
57 96 */
58 - public static function render_sites() { // phpcs:ignore -- NOSONAR - current complexity required to achieve desired results. Pull request solutions appreciated.
97 + public static function render_widget_content() { // phpcs:ignore -- NOSONAR - current complexity required to achieve desired results. Pull request solutions appreciated.
59 98
60 - $wpsite_fields = array( 'id', 'name', 'url', 'adminname' );
61 - $sync_fields = array( 'sync_errors', 'dtsSync' );
62 - $websites = MainWP_DB::instance()->query(
63 - MainWP_DB::instance()->get_sql_websites_for_current_user_by_params(
64 - array(
65 - 'select_wp_fields' => $wpsite_fields,
66 - 'select_sync_fields' => $sync_fields,
67 - )
68 - )
69 - );
99 + $counts = MainWP_DB::instance()->get_sites_connections_status();
70 100
71 - $count_connected = 0;
72 - $count_disconnected = 0;
73 -
74 - // Loop 3 times.
75 - $SYNCERRORS = 0;
76 - $UP = 1;
77 - $ALL = 2;
78 -
79 - $html_online_sites = '';
80 - $html_other_sites = '';
81 - $html_all_sites = '';
82 -
83 - $disconnect_site_ids = array();
84 -
85 - for ( $j = 0; $j < 3; $j++ ) {
86 - MainWP_DB::data_seek( $websites, 0 );
87 - while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
88 - if ( empty( $website ) ) {
89 - continue;
90 - }
91 -
92 - $hasSyncErrors = ( '' !== $website->sync_errors );
93 - $isUp = ! $hasSyncErrors;
94 -
95 - if ( $j !== $ALL ) {
96 - if ( $j === $SYNCERRORS && ! $hasSyncErrors ) {
97 - continue;
98 - }
99 - if ( $j === $UP && ! $isUp ) {
100 - continue;
101 - }
102 - }
103 -
104 - $lastSyncTime = ! empty( $website->dtsSync ) ? MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $website->dtsSync ) ) : '';
105 -
106 - ob_start();
107 -
108 - if ( $j === $ALL ) {
109 - static::render_all_item( $website, $lastSyncTime, $hasSyncErrors );
110 - } elseif ( $j === $UP ) {
111 - static::render_up_item( $website, $lastSyncTime );
112 - } else {
113 - static::render_down_item( $website, $lastSyncTime );
114 - }
115 -
116 - /**
117 - * Action: mainwp_connection_status_widget_bottom
118 - *
119 - * Fires at the bottom of the Connection Status widget.
120 - *
121 - * @since 4.1
122 - */
123 - do_action( 'mainwp_connection_status_widget_bottom' );
124 -
125 - $output = ob_get_clean();
126 -
127 - if ( $j === $ALL ) {
128 - $html_all_sites .= $output;
129 - } elseif ( $j === $UP ) {
130 - $html_online_sites .= $output;
131 - ++$count_connected;
132 - } elseif ( ! in_array( $website->id, $disconnect_site_ids ) ) {
133 - $disconnect_site_ids[] = $website->id;
134 - $html_other_sites .= $output;
135 - ++$count_disconnected;
136 - }
137 - }
101 + if ( ! is_array( $counts ) ) {
102 + $counts = array();
138 103 }
139 104
140 - MainWP_DB::free_result( $websites );
105 + $count_connected = ! empty( $counts['connected_sites'] ) ? (int) $counts['connected_sites'] : 0;
106 + $count_disconnected = ! empty( $counts['disconnected_sites'] ) ? (int) $counts['disconnected_sites'] : 0;
141 107
142 - static::render_status( $count_connected, $count_disconnected );
108 + static::render_content( $count_connected, $count_disconnected );
143 109
144 - static::render_details( $html_all_sites, $html_online_sites, $html_other_sites );
145 -
146 110 MainWP_UI::render_modal_reconnect();
147 111 }
148 112
149 113 /**
@@ -151,9 +115,9 @@
151 115 *
152 116 * @param int $count_connected Number of connected sites.
153 117 * @param int $count_disconnected Number of disconnected sites.
154 118 */
155 - public static function render_status( $count_connected, $count_disconnected ) {
119 + public static function render_content( $count_connected, $count_disconnected ) {
156 120 ?>
157 121 <div class="mainwp-widget-header">
158 122 <div class="ui grid">
159 123 <div class="twelve wide column">
@@ -182,33 +146,14 @@
182 146 <a class="item" data-tab="no-sites" data-value="no-sites" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Hide the child sites list', 'mainwp' ); ?>" href="#"><?php esc_html_e( 'Hide Details', 'mainwp' ); ?></a>
183 147 </div>
184 148 </div>
185 149 </div>
186 -
187 -
188 - <script type="text/javascript">
189 - jQuery( document ).ready( function () {
190 - jQuery( '#widget-connect-status-dropdown-selector' ).dropdown( {
191 - onChange: function( val ) {
192 - if ( typeof( Storage ) !== 'undefined' ) {
193 - localStorage.setItem( 'lsWidgetConnectStatusDropdownVal', val );
194 - }
195 - }
196 - } );
197 - if ( typeof( Storage ) !== "undefined" ) {
198 - if ( val = localStorage.getItem( 'lsWidgetConnectStatusDropdownVal' ) ) {
199 - jQuery( '#widget-connect-status-dropdown-selector' ).dropdown( 'set selected',val );
200 - jQuery( '#widget-connect-status-dropdown-selector' ).closest( '.mainwp-widget' ).find( 'div[data-tab="' + val + '"]' ).addClass( 'active' );
201 - }
202 - }
203 - } );
204 - </script>
205 -
206 150 </div>
207 151 <div>
208 152 <?php static::render_multi_status( $count_connected, $count_disconnected ); ?>
209 153 </div>
210 154 </div>
155 +
211 156 <?php
212 157 /**
213 158 * Action: mainwp_connection_status_widget_top
214 159 *
@@ -216,127 +161,16 @@
216 161 *
217 162 * @since 4.1
218 163 */
219 164 do_action( 'mainwp_connection_status_widget_top' );
220 - }
221 -
222 - /**
223 - * Render connection status summary section.
224 - *
225 - * @param int $count_connected Connected Count.
226 - * @param int $count_disconnected Disconnected Count.
227 - */
228 - public static function render_multi_status( $count_connected, $count_disconnected ) {
229 - $count_total = $count_connected + $count_disconnected;
230 165 ?>
231 - <div class="ui mainwp-cards small cards">
232 - <div class="ui card">
233 - <div class="content">
234 - <div class="header">
235 - <span class="ui large text"><i class="ui een check icon"></i> <?php echo esc_html( MainWP_Utility::short_number_format( $count_connected ) ); ?></span>
236 - </div>
237 - <div class="description"><strong><?php esc_html_e( 'Connected Sites', 'mainwp' ); ?></strong></div>
238 - </div>
239 - </div>
240 - <div class="ui card">
241 - <div class="content">
242 - <div class="header">
243 - <span class="ui large text"><i class="ui unlink icon"></i> <?php echo esc_html( MainWP_Utility::short_number_format( $count_disconnected ) ); ?></span>
244 - </div>
245 - <div class="description"><strong><?php esc_html_e( 'Disconnected Sites', 'mainwp' ); ?></strong></div>
246 - </div>
247 - </div>
248 - </div>
249 - <?php
250 - }
251 166
252 - /**
253 - * Render See All Sites List.
254 - *
255 - * @param mixed $html_all_sites All sites html.
256 - * @param mixed $html_online_sites Online sites html.
257 - * @param mixed $html_other_sites Other sites html.
258 - */
259 - public static function render_details( $html_all_sites, $html_online_sites, $html_other_sites ) {
260 - ?>
261 - <div class="mainwp-scrolly-overflow">
262 - <div class="ui tab" data-tab="all-sites">
263 - <?php
264 - /**
265 - * Action: mainwp_connection_status_before_all_sites_list
266 - *
267 - * Fires before the list of all sites in the connection status widgets
268 - *
269 - * @since 4.1
270 - */
271 - do_action( 'mainwp_connection_status_before_all_sites_list' )
272 - ?>
273 - <div class="ui middle aligned divided list">
274 - <?php echo $html_all_sites; // phpcs:ignore WordPress.Security.EscapeOutput ?>
275 - </div>
276 - <?php
277 - /**
278 - * Action: mainwp_connection_status_after_all_sites_list
279 - *
280 - * Fires after the list of all sites in the connection status widgets
281 - *
282 - * @since 4.1
283 - */
284 - do_action( 'mainwp_connection_status_after_all_sites_list' )
285 - ?>
286 - </div>
287 -
288 - <div class="ui tab" data-tab="connected">
289 - <?php
290 - /**
291 - * Action: mainwp_connection_status_before_connected_sites_list
292 - *
293 - * Fires before the list of connected sites in the connection status widgets
294 - *
295 - * @since 4.1
296 - */
297 - do_action( 'mainwp_connection_status_before_connected_sites_list' )
298 - ?>
299 - <div class="ui middle aligned divided list">
300 - <?php echo $html_online_sites; // phpcs:ignore WordPress.Security.EscapeOutput ?>
301 - </div>
302 - <?php
303 - /**
304 - * Action: mainwp_connection_status_after_connected_sites_list
305 - *
306 - * Fires after the list of connected sites in the connection status widgets
307 - *
308 - * @since 4.1
309 - */
310 - do_action( 'mainwp_connection_status_after_connected_sites_list' )
311 - ?>
312 - </div>
313 -
314 - <div class="ui tab" data-tab="disconnected">
315 - <?php
316 - /**
317 - * Action: mainwp_connection_status_before_disconnected_sites_list
318 - *
319 - * Fires before the list of disconnected sites in the connection status widgets
320 - *
321 - * @since 4.1
322 - */
323 - do_action( 'mainwp_connection_status_before_disconnected_sites_list' )
324 - ?>
325 - <div class="ui middle aligned divided list">
326 - <?php echo $html_other_sites; // phpcs:ignore WordPress.Security.EscapeOutput ?>
327 - </div>
328 - <?php
329 - /**
330 - * Action: mainwp_connection_status_after_disconnected_sites_list
331 - *
332 - * Fires after the list of disconnected sites in the connection status widgets
333 - *
334 - * @since 4.1
335 - */
336 - do_action( 'mainwp_connection_status_after_disconnected_sites_list' )
337 - ?>
338 - </div>
167 + <div class="mainwp-scrolly-overflow" id="widget-connections-status-details">
168 + <?php
169 + foreach ( array( 'all-sites', 'connected', 'disconnected' ) as $tab ) {
170 + static::render_tab( $tab );
171 + }
172 + ?>
339 173 <div class="ui tab" data-tab="no-sites"></div>
340 174 </div>
341 175 <div class="ui two column grid mainwp-widget-footer">
342 176 <div class="left aligned middle aligned column">
@@ -363,11 +197,463 @@
363 197 do_action( 'mainwp_connection_status_widget_footer_right' )
364 198 ?>
365 199 </div>
366 200 </div>
201 + <script type="text/javascript">
202 +
203 + let mainwp_widgets_connections_status_get_table = function(tab){
204 + switch(tab){
205 + case 'all-sites':
206 + return $widget_connections_status_table_all_sites;
207 + case 'connected':
208 + return $widget_connections_status_table_connected;
209 + case 'disconnected':
210 + return $widget_connections_status_table_disconnected;
211 + default:
212 + return null;
213 + }
214 + };
215 +
216 + let mainwp_widgets_connections_status_tab_onchange = function( current_tab ){
217 + if( ! ['all-sites', 'connected', 'disconnected'].includes(current_tab) || jQuery('#widget-connections-status-details div[data-tab=' + current_tab +'][loaded-data="loaded"]').length > 0 ){
218 + return;
219 + }
220 + let current_page = jQuery('#widget-connections-status-details div[data-tab=' + current_tab + ']').attr('current-page');
221 + mainwp_widgets_connections_status_get_table(current_tab).ajax.reload();
222 + }
223 +
224 + jQuery( document ).ready( function () {
225 + setTimeout(() => {
226 + jQuery( '#widget-connect-status-dropdown-selector' ).dropdown( {
227 + onChange: function( val ) {
228 + if ( typeof( Storage ) !== 'undefined' ) {
229 + localStorage.setItem( 'lsWidgetConnectStatusDropdownVal', val );
230 + mainwp_widgets_connections_status_tab_onchange( val );
231 + }
232 + }
233 + } );
234 + jQuery( '#widget-connect-status-dropdown-selector .menu .item' ).tab();
235 + if ( typeof( Storage ) !== "undefined" ) {
236 + let val = localStorage.getItem( 'lsWidgetConnectStatusDropdownVal' );
237 + if(!['all-sites', 'connected', 'disconnected', 'no-sites'].includes(val)) {
238 + val = 'all-sites';
239 + }
240 + jQuery( '#widget-connect-status-dropdown-selector' ).dropdown( 'set selected',val );
241 + jQuery( '#widget-connect-status-dropdown-selector' ).closest( '.mainwp-widget' ).find( 'div.ui.tab' ).removeClass( 'active');
242 + jQuery( '#widget-connect-status-dropdown-selector' ).closest( '.mainwp-widget' ).find( 'div[data-tab="' + val + '"]' ).addClass( 'active' );
243 + mainwp_widgets_connections_status_tab_onchange( val );
244 + }
245 + }, 1000);
246 + } );
247 + </script>
367 248 <?php
368 249 }
369 250
251 + /**
252 + * The renders the connections status tab.
253 + *
254 + * @param string $tab The tab.
255 + */
256 + public static function render_tab( $tab ) {
257 + $sites_per_page = 25;
258 + $tbl_id = 'widget-connections-status-details-table-' . $tab;
259 +
260 + if ( 'all-sites' === $tab ) {
261 + $hook_before = 'mainwp_connection_status_before_all_sites_list';
262 + $hook_after = 'mainwp_connection_status_after_all_sites_list';
263 + } elseif ( 'connected' === $tab ) {
264 + $hook_before = 'mainwp_connection_status_before_connected_sites_list';
265 + $hook_after = 'mainwp_connection_status_after_connected_sites_list';
266 + } else {
267 + $hook_before = 'mainwp_connection_status_before_disconnected_sites_list';
268 + $hook_after = 'mainwp_connection_status_after_disconnected_sites_list';
269 + }
270 +
271 + ?>
272 +
273 + <div class="ui tab" data-tab="<?php echo esc_attr( $tab ); ?>" loaded-data="no" current-page="1">
274 + <div class="ui message widget-connections-status-message-zone" style="display:none;" ></div>
275 +
276 + <?php
277 + /**
278 + * Fires before the list of all sites in the connection status widgets
279 + *
280 + * @since 4.1
281 + */
282 + do_action( $hook_before );
283 + ?>
284 + <div class="widget-connections-status-details-table-list-container">
285 + <table id="<?php echo esc_attr( $tbl_id ); ?>" style="width:100%" class="ui single line unstackable table">
286 + <thead>
287 + <tr><?php static::print_column_headers(); ?></tr>
288 + </thead>
289 + </table>
290 + </div>
291 + <?php
292 + /**
293 + * Fires after the list of all sites in the connection status widgets
294 + *
295 + * @since 4.1
296 + */
297 + do_action( $hook_after );
298 + ?>
299 + </div>
300 + <?php
301 +
302 + $table_features = array(
303 + 'searching' => 'false',
304 + 'paging' => 'true',
305 + 'pagingType' => 'full_numbers',
306 + 'info' => 'false',
307 + 'colReorder' => '{columns:":not(.check-column):not(:last-child)"}',
308 + 'stateSave' => 'false',
309 + 'stateDuration' => '60 * 60 * 24 * 30',
310 + 'order' => '[]',
311 + 'scrollX' => 'true',
312 + 'responsive' => 'true',
313 + 'fixedColumns' => '',
314 + 'searchDelay' => 350,
315 + 'numbers' => 3,
316 + );
317 +
318 + $pages_length = array(
319 + 25 => '25',
320 + );
321 +
322 + $pagelength_val = implode( ',', array_keys( $pages_length ) );
323 + $pagelength_title = implode( ',', array_values( $pages_length ) );
324 +
325 + ?>
326 + <script type="text/javascript">
327 + let $widget_connections_status_table_<?php echo esc_js( str_replace( '-', '_', $tab ) ); ?> = null;
328 + jQuery( document ).ready( function ($) {
329 + let responsive = true;
330 + if( jQuery( window ).width() > 1140 ) {
331 + responsive = false;
332 + }
333 + let manage_tbl_id = '#<?php echo esc_js( $tbl_id ); ?>';
334 + $widget_connections_status_table_<?php echo esc_js( str_replace( '-', '_', $tab ) ); ?> = jQuery( manage_tbl_id ).on( 'processing.dt', function ( e, settings, processing ) {
335 + jQuery( '#mainwp-loading-sites' ).css( 'display', processing ? 'block' : 'none' );
336 + if (!processing) {
337 + $( manage_tbl_id + ' .ui.dropdown' ).dropdown();
338 + }
339 + } ).DataTable( {
340 + "ajax": {
341 + "url": ajaxurl,
342 + "type": "POST",
343 + "data": function ( d ) {
344 + let data = mainwp_secure_data( {
345 + action: 'mainwp_widgets_connections_status_details_display_rows',
346 + current_tab: '<?php echo esc_js( $tab ); ?>',
347 + } );
348 + return $.extend( {}, d, data );
349 + },
350 + "dataSrc": function ( json ) {
351 + for ( let i=0, ien=json.data.length ; i < ien ; i++ ) {
352 + json.data[i].rowClass = json.rowsInfo[i].rowClass;
353 + json.data[i].site_id = json.rowsInfo[i].site_id;
354 + }
355 + return json.data;
356 + }
357 + },
358 + "layout": {
359 + "topStart": null,
360 + "topEnd": null,
361 + "bottomEnd": {
362 + "paging": {
363 + "numbers": <?php echo intval( $table_features['numbers'] ); ?>
364 + }
365 + }
366 + },
367 + 'responsive': responsive,
368 + 'deferLoading': 0,
369 + 'searching' : <?php echo esc_js( $table_features['searching'] ); ?>,
370 + "paging" : <?php echo esc_js( $table_features['paging'] ); ?>,
371 + "pagingType" : "<?php echo esc_js( $table_features['pagingType'] ); ?>",
372 + "info" : <?php echo esc_js( $table_features['info'] ); ?>,
373 + "colReorder" : <?php echo $table_features['colReorder']; // phpcs:ignore -- specical chars. ?>,
374 + "scrollX" : <?php echo esc_js( $table_features['scrollX'] ); ?>,
375 + "stateSave" : <?php echo esc_js( $table_features['stateSave'] ); ?>,
376 + "order" : <?php echo $table_features['order']; // phpcs:ignore -- specical chars. ?>,
377 + "fixedColumns" : <?php echo ! empty( $table_features['fixedColumns'] ) ? esc_js( $table_features['fixedColumns'] ) : '""'; ?>,
378 + "lengthMenu" : [ [<?php echo esc_js( $pagelength_val ); ?>], [<?php echo esc_js( $pagelength_title ); ?>] ],
379 + "serverSide": true,
380 + "pageLength": <?php echo intval( $sites_per_page ); ?>,
381 + "columnDefs": "[]",
382 + "columns": [{"data":"status_details"}],
383 + "language": {
384 + "emptyTable": "<?php echo esc_html__( 'No sites found.', 'mainwp' ); ?>"
385 + },
386 + "drawCallback": function( settings ) {
387 + setTimeout(() => {
388 + jQuery( manage_tbl_id + ' .ui.dropdown').dropdown();
389 + mainwp_datatable_fix_menu_overflow(manage_tbl_id, -60, -30);
390 + }, 1000);
391 + },
392 + "initComplete": function( settings, json ) {
393 + },
394 + rowCallback: function (row, data) {
395 + jQuery( row ).addClass(data.rowClass);
396 + },
397 + orderMulti: false,
398 + searchDelay: <?php echo intval( $table_features['searchDelay'] ); ?>
399 + })
400 + } );
401 + </script>
402 + <?php
403 + }
404 +
405 +
406 + /**
407 + * Echo the column headers.
408 + *
409 + * @return void
410 + */
411 + public static function get_columns() {
412 + return array(
413 + 'status_details' => esc_html__( 'Detail', 'mainwp' ),
414 + );
415 + }
416 +
417 + /**
418 + * Echo the column headers.
419 + *
420 + * @return void
421 + */
422 + public static function print_column_headers() {
423 +
424 + $columns = static::get_columns();
425 +
426 + foreach ( $columns as $column_event_key => $column_display_name ) {
427 +
428 + $class = array( 'manage-' . $column_event_key . '-column' );
429 + $attr = '';
430 +
431 + $class[] = 'no-sort';
432 +
433 + $tag = 'th';
434 + $id = "id='$column_event_key'";
435 +
436 + if ( ! empty( $class ) ) {
437 + $class = "class='" . join( ' ', $class ) . "'";
438 + }
439 +
440 + echo "<$tag $id $class $attr style=\"display:none;\">$column_display_name</$tag>"; // phpcs:ignore WordPress.Security.EscapeOutput
441 + }
442 + }
443 +
444 + /**
445 + * The renders the connections status tab.
446 + *
447 + * @param string $current_tab The current tab.
448 + */
449 + public function prepare_items( $current_tab ) {
450 +
451 + // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
452 +
453 + if ( ! in_array( $current_tab, array( 'all-sites', 'connected', 'disconnected' ), true ) ) {
454 + wp_die( wp_json_encode( array( 'error' => __( 'The selected site\'s status is invalid. Please try again.', 'mainwp' ) ) ) );
455 + }
456 +
457 + $per_page = isset( $_POST['per_page'] ) ? intval( wp_unslash( $_POST['per_page'] ) ) : 25; // phpcs:ignore -- NOSONAR - ok.
458 + $page = isset( $_POST['page'] ) ? intval( wp_unslash( $_POST['page'] ) ) : 1; // phpcs:ignore -- NOSONAR - ok.
459 +
460 + $perPage = isset( $_REQUEST['length'] ) ? intval( $_REQUEST['length'] ) : 25;
461 + $start = isset( $_REQUEST['start'] ) ? intval( $_REQUEST['start'] ) : 0;
462 +
463 + // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
464 +
465 + $status = $current_tab;
466 +
467 + if ( 'all-sites' === $status ) {
468 + $status = 'any';
469 + }
470 +
471 + $wpsite_fields = array( 'id', 'name', 'url', 'adminname' );
472 + $sync_fields = array( 'sync_errors', 'dtsSync' );
473 +
474 + $args = array(
475 + 'select_wp_fields' => $wpsite_fields,
476 + 'select_sync_fields' => $sync_fields,
477 + 'status' => $status,
478 + 'offset' => $start,
479 + 'rowcount' => $perPage,
480 + 'orderby' => 'wp.url',
481 + 'view' => 'custom_view',
482 + 'others_fields' => array(),
483 + );
484 +
485 + $results = MainWP_DB::instance()->query(
486 + MainWP_DB::instance()->get_sql_websites_for_current_user_by_params(
487 + apply_filters(
488 + 'mainwp_connection_status_widget_get_sites_query_params',
489 + $args
490 + )
491 + )
492 + );
493 +
494 + $items = array();
495 +
496 + while ( $results && $website = MainWP_DB::fetch_object( $results ) ) {
497 + $items[] = $website;
498 + }
499 + MainWP_DB::free_result( $results );
500 +
501 + $args['count_sql'] = true;
502 +
503 + $total_sql = MainWP_DB::instance()->get_sql_websites_for_current_user_by_params(
504 + apply_filters(
505 + 'mainwp_connection_status_widget_get_sites_query_params',
506 + $args
507 + )
508 + );
509 +
510 + $total_items = MainWP_DB::instance()->get_var_field( $total_sql );
511 +
512 + $this->items = $items;
513 + $this->total_items = $total_items ? (int) $total_items : 0;
514 + unset( $items );
515 + }
516 +
517 +
518 + /**
519 + * Method ajax_display_rows()
520 + *
521 + * Display table rows.
522 + */
523 + public function ajax_display_rows() {
524 + MainWP_Post_Handler::instance()->check_security( 'mainwp_widgets_connections_status_details_display_rows' );
525 + $current_tab = isset( $_POST['current_tab'] ) ? sanitize_text_field( wp_unslash( $_POST['current_tab'] ) ) : ''; // phpcs:ignore -- NOSONAR - ok.
526 + $this->prepare_items( $current_tab );
527 + $output = $this->ajax_get_datatable_rows( $current_tab );
528 + wp_send_json( $output );
529 + }
530 +
531 + /**
532 + * Get table rows.
533 + *
534 + * @param string $current_tab The current tab.
535 + *
536 + * @return array Rows html.
537 + */
538 + public function ajax_get_datatable_rows( $current_tab ) {
539 +
540 + $all_rows = array();
541 + $info_rows = array();
542 +
543 + $columns = static::get_columns();
544 +
545 + if ( $this->items ) {
546 + foreach ( $this->items as $site ) {
547 + $rw_classes = 'mainwp-connect-status-item-' . intval( $site->id );
548 +
549 + $info_item = array(
550 + 'rowClass' => esc_html( $rw_classes ),
551 + 'site_id' => $site->id,
552 + );
553 +
554 + $cols_data = array();
555 + foreach ( $columns as $column_name => $column_display_name ) {
556 + ob_start();
557 + echo $this->column_default( $site, $column_name, $current_tab ); // phpcs:ignore WordPress.Security.EscapeOutput
558 + $cols_data[ $column_name ] = ob_get_clean();
559 + }
560 + $all_rows[] = $cols_data;
561 + $info_rows[] = $info_item;
562 + }
563 + }
564 + return array(
565 + 'data' => $all_rows,
566 + 'recordsTotal' => (int) $this->total_items,
567 + 'recordsFiltered' => (int) $this->total_items,
568 + 'rowsInfo' => $info_rows,
569 + );
570 + }
571 +
572 + /**
573 + * Returns the column content for the provided item and column.
574 + *
575 + * @param object $website Website data.
576 + * @param string $column_name Column name.
577 + * @param string $current_tab The current tab.
578 + *
579 + * @return string $out Output.
580 + */
581 + public function column_default( $website, $column_name, $current_tab ) { //phpcs:ignore -- NOSONAR -complex.
582 +
583 + $status = $current_tab;
584 +
585 + if ( 'all-sites' === $current_tab ) {
586 + $status = 'any';
587 + }
588 +
589 + $SYNCERRORS = 'disconnected';
590 + $UP = 'connected';
591 + $ALL = 'any';
592 +
593 + $output = '';
594 + if ( 'status_details' === $column_name ) {
595 + $hasSyncErrors = ( '' !== $website->sync_errors );
596 + $lastSyncTime = ! empty( $website->dtsSync ) ? MainWP_Utility::format_timestamp( MainWP_Utility::get_timestamp( $website->dtsSync ) ) : '';
597 +
598 + ob_start();
599 +
600 + if ( $status === $ALL ) {
601 + static::render_all_item( $website, $lastSyncTime, $hasSyncErrors );
602 + } elseif ( $status === $UP ) {
603 + static::render_up_item( $website, $lastSyncTime );
604 + } elseif ( $status === $SYNCERRORS ) {
605 + static::render_down_item( $website, $lastSyncTime );
606 + }
607 +
608 + /**
609 + * Action: mainwp_connection_status_widget_bottom
610 + *
611 + * Fires at the bottom of the Connection Status widget.
612 + *
613 + * @since 4.1
614 + */
615 + do_action( 'mainwp_connection_status_widget_bottom' );
616 +
617 + $output = ob_get_clean();
618 + }
619 +
620 + if ( empty( $output ) ) {
621 + return '';
622 + }
623 + return $output; //phpcs:ignore -- escaped.
624 + }
625 +
626 +
627 +
628 + /**
629 + * Render connection status summary section.
630 + *
631 + * @param int $count_connected Connected Count.
632 + * @param int $count_disconnected Disconnected Count.
633 + */
634 + public static function render_multi_status( $count_connected, $count_disconnected ) {
635 + ?>
636 + <div class="ui mainwp-cards small cards">
637 + <div class="ui card">
638 + <div class="content">
639 + <div class="header">
640 + <span class="ui large text"><i class="ui een check icon"></i> <?php echo esc_html( MainWP_Utility::short_number_format( $count_connected ) ); ?></span>
641 + </div>
642 + <div class="description"><strong><?php esc_html_e( 'Connected Sites', 'mainwp' ); ?></strong></div>
643 + </div>
644 + </div>
645 + <div class="ui card">
646 + <div class="content">
647 + <div class="header">
648 + <span class="ui large text"><i class="ui unlink icon"></i> <?php echo esc_html( MainWP_Utility::short_number_format( $count_disconnected ) ); ?></span>
649 + </div>
650 + <div class="description"><strong><?php esc_html_e( 'Disconnected Sites', 'mainwp' ); ?></strong></div>
651 + </div>
652 + </div>
653 + </div>
654 + <?php
655 + }
370 656
371 657 /**
372 658 * Render all items list.
373 659 *