← All changes
|
class/class-mainwp-plugins-install-list-table.php
+566
-457
4.6.0.1
→
6.2.1
View file →
| @@ -6,11 +6,16 @@ | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | namespace MainWP\Dashboard; |
| 9 | 9 | |
| 10 | +// Exit if accessed directly. | |
| 11 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 12 | + exit; | |
| 13 | +} | |
| 14 | + | |
| 10 | 15 | // Include class-wp-list-table.php. |
| 11 | 16 | if ( ! class_exists( '\WP_List_Table' ) ) { |
| 12 | - require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; | |
| 17 | + require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; // NOSONAR - WP compatible. | |
| 13 | 18 | } |
| 14 | 19 | |
| 15 | 20 | /** |
| 16 | 21 | * Class MainWP_Plugins_Install_List_Table |
| @@ -19,537 +24,641 @@ | ||
| 19 | 24 | * @subpackage List_Table |
| 20 | 25 | * @since 3.1.0 |
| 21 | 26 | * @access private |
| 22 | 27 | */ |
| 23 | -class MainWP_Plugins_Install_List_Table extends \WP_List_Table { | |
| 28 | +class MainWP_Plugins_Install_List_Table extends \WP_List_Table { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR. | |
| 24 | 29 | |
| 25 | - /** | |
| 26 | - * Default direction. | |
| 27 | - * | |
| 28 | - * @var string $order | |
| 29 | - */ | |
| 30 | - public $order = 'ASC'; | |
| 30 | + /** | |
| 31 | + * Default direction. | |
| 32 | + * | |
| 33 | + * @var string $order | |
| 34 | + */ | |
| 35 | + public $order = 'ASC'; | |
| 31 | 36 | |
| 32 | - /** | |
| 33 | - * Default order. | |
| 34 | - * | |
| 35 | - * @var int $orderby | |
| 36 | - */ | |
| 37 | - public $orderby = null; | |
| 37 | + /** | |
| 38 | + * Default order. | |
| 39 | + * | |
| 40 | + * @var int $orderby | |
| 41 | + */ | |
| 42 | + public $orderby = null; | |
| 38 | 43 | |
| 39 | - /** | |
| 40 | - * Groups array. | |
| 41 | - * | |
| 42 | - * @var array $groups | |
| 43 | - */ | |
| 44 | - public $groups = array(); | |
| 44 | + /** | |
| 45 | + * Groups array. | |
| 46 | + * | |
| 47 | + * @var array $groups | |
| 48 | + */ | |
| 49 | + public $groups = array(); | |
| 45 | 50 | |
| 46 | - /** | |
| 47 | - * Error messages. | |
| 48 | - * | |
| 49 | - * @var mixed $error | |
| 50 | - */ | |
| 51 | - private $error; | |
| 51 | + /** | |
| 52 | + * Error messages. | |
| 53 | + * | |
| 54 | + * @var mixed $error | |
| 55 | + */ | |
| 56 | + private $error; | |
| 52 | 57 | |
| 53 | - /** | |
| 54 | - * Method ajax_user_can() | |
| 55 | - * | |
| 56 | - * Chck if the current user has the WP ability "install_plugins". | |
| 57 | - * | |
| 58 | - * @return boolean True|False. | |
| 59 | - */ | |
| 60 | - public function ajax_user_can() { | |
| 61 | - return current_user_can( 'install_plugins' ); | |
| 62 | - } | |
| 58 | + /** | |
| 59 | + * Method ajax_user_can() | |
| 60 | + * | |
| 61 | + * Chck if the current user has the WP ability "install_plugins". | |
| 62 | + * | |
| 63 | + * @return boolean True|False. | |
| 64 | + */ | |
| 65 | + public function ajax_user_can() { | |
| 66 | + return current_user_can( 'install_plugins' ); | |
| 67 | + } | |
| 63 | 68 | |
| 64 | - /** | |
| 65 | - * Method prepair_items() | |
| 66 | - * | |
| 67 | - * @global array $tabs | |
| 68 | - * @global string $tab | |
| 69 | - * @global int $paged | |
| 70 | - * @global string $type | |
| 71 | - * @global string $term | |
| 72 | - * @global string $wp_version | |
| 73 | - */ | |
| 74 | - public function prepare_items() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated. | |
| 75 | - include ABSPATH . 'wp-admin/includes/plugin-install.php'; | |
| 69 | + /** | |
| 70 | + * Method prepair_items() | |
| 71 | + * | |
| 72 | + * @global array $tabs | |
| 73 | + * @global string $tab | |
| 74 | + * @global int $paged | |
| 75 | + * @global string $type | |
| 76 | + * @global string $term | |
| 77 | + * @global string $wp_version | |
| 78 | + */ | |
| 79 | + public function prepare_items() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated. | |
| 80 | + include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // NOSONAR - WP compatible. | |
| 76 | 81 | |
| 77 | - global $tab; // required. | |
| 82 | + global $tab; // required. | |
| 78 | 83 | |
| 79 | - wp_reset_vars( array( 'tab' ) ); | |
| 84 | + wp_reset_vars( array( 'tab' ) ); | |
| 80 | 85 | |
| 81 | - $paged = $this->get_pagenum(); | |
| 86 | + $paged = $this->get_pagenum(); | |
| 82 | 87 | |
| 83 | - $per_page = 40; | |
| 88 | + $per_page = 40; | |
| 84 | 89 | |
| 85 | - // These are the tabs which are shown on the page. | |
| 86 | - $tabs = array(); | |
| 90 | + // These are the tabs which are shown on the page. | |
| 91 | + $tabs = array(); | |
| 87 | 92 | |
| 88 | - if ( 'search' === $tab ) { | |
| 89 | - $tabs['search'] = esc_html__( 'Search Results', 'mainwp' ); | |
| 90 | - } | |
| 91 | - $tabs['featured'] = _x( 'Featured', 'Plugin Installer' ); | |
| 92 | - $tabs['popular'] = _x( 'Popular', 'Plugin Installer' ); | |
| 93 | - $tabs['recommended'] = _x( 'Recommended', 'Plugin Installer' ); | |
| 94 | - if ( 'beta' === $tab || false !== strpos( $GLOBALS['wp_version'], '-' ) ) { | |
| 95 | - $tabs['beta'] = _x( 'Beta Testing', 'Plugin Installer' ); | |
| 96 | - } | |
| 97 | - if ( current_user_can( 'upload_plugins' ) ) { | |
| 98 | - // No longer a real tab. Here for filter compatibility. | |
| 99 | - // Gets skipped in get_views(). | |
| 100 | - $tabs['upload'] = esc_html__( 'Upload Plugin', 'mainwp' ); | |
| 101 | - } | |
| 93 | + if ( 'search' === $tab ) { | |
| 94 | + $tabs['search'] = esc_html__( 'Search Results', 'mainwp' ); | |
| 95 | + } | |
| 96 | + $tabs['featured'] = _x( 'Featured', 'Plugin Installer', 'mainwp' ); | |
| 97 | + $tabs['popular'] = _x( 'Popular', 'Plugin Installer', 'mainwp' ); | |
| 98 | + $tabs['recommended'] = _x( 'Recommended', 'Plugin Installer', 'mainwp' ); | |
| 99 | + if ( 'beta' === $tab || false !== strpos( $GLOBALS['wp_version'], '-' ) ) { | |
| 100 | + $tabs['beta'] = _x( 'Beta Testing', 'Plugin Installer', 'mainwp' ); | |
| 101 | + } | |
| 102 | + if ( current_user_can( 'upload_plugins' ) ) { | |
| 103 | + // No longer a real tab. Here for filter compatibility. | |
| 104 | + // Gets skipped in get_views(). | |
| 105 | + $tabs['upload'] = esc_html__( 'Upload Plugin', 'mainwp' ); | |
| 106 | + } | |
| 102 | 107 | |
| 103 | - $nonmenu_tabs = array( 'plugin-information' ); | |
| 104 | - // Valid actions to perform which do not have a Menu item. | |
| 105 | - // If a non-valid menu tab has been selected, And it's not a non-menu action. | |
| 106 | - if ( empty( $tab ) || ( ! isset( $tabs[ $tab ] ) && ! in_array( $tab, (array) $nonmenu_tabs ) ) ) { | |
| 108 | + $nonmenu_tabs = array( 'plugin-information' ); | |
| 109 | + // Valid actions to perform which do not have a Menu item. | |
| 110 | + // If a non-valid menu tab has been selected, And it's not a non-menu action. | |
| 111 | + if ( empty( $tab ) || ( ! isset( $tabs[ $tab ] ) && ! in_array( $tab, (array) $nonmenu_tabs ) ) ) { | |
| 107 | 112 | |
| 108 | - $tab = key( $tabs ); // phpcs:ignore -- required for custom bulk install plugins. | |
| 109 | - } | |
| 113 | + $tab = key( $tabs ); // phpcs:ignore -- required for custom bulk install plugins. | |
| 114 | + } | |
| 110 | 115 | |
| 111 | - $args = array( | |
| 112 | - 'page' => $paged, | |
| 113 | - 'per_page' => $per_page, | |
| 114 | - 'fields' => array( | |
| 115 | - 'last_updated' => true, | |
| 116 | - 'icons' => true, | |
| 117 | - 'active_installs' => true, | |
| 118 | - ), | |
| 119 | - 'locale' => get_locale(), | |
| 120 | - 'installed_plugins' => array(), | |
| 121 | - ); | |
| 116 | + $args = array( | |
| 117 | + 'page' => $paged, | |
| 118 | + 'per_page' => $per_page, | |
| 119 | + 'fields' => array( | |
| 120 | + 'last_updated' => true, | |
| 121 | + 'icons' => true, | |
| 122 | + 'active_installs' => true, | |
| 123 | + ), | |
| 124 | + 'locale' => get_locale(), | |
| 125 | + 'installed_plugins' => array(), | |
| 126 | + ); | |
| 122 | 127 | |
| 123 | - switch ( $tab ) { | |
| 124 | - case 'search': | |
| 125 | - $type = isset( $_REQUEST['type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) : 'term'; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 126 | - $term = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 128 | + switch ( $tab ) { | |
| 129 | + case 'search': | |
| 130 | + $type = isset( $_REQUEST['type'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) : 'term'; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 131 | + $term = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 127 | 132 | |
| 128 | - switch ( $type ) { | |
| 129 | - case 'tag': | |
| 130 | - $args['tag'] = sanitize_title_with_dashes( $term ); | |
| 131 | - break; | |
| 132 | - case 'term': | |
| 133 | - $args['search'] = $term; | |
| 134 | - break; | |
| 135 | - case 'author': | |
| 136 | - $args['author'] = $term; | |
| 137 | - break; | |
| 138 | - } | |
| 133 | + switch ( $type ) { | |
| 134 | + case 'tag': | |
| 135 | + $args['tag'] = sanitize_title_with_dashes( $term ); | |
| 136 | + break; | |
| 137 | + case 'term': | |
| 138 | + $args['search'] = $term; | |
| 139 | + break; | |
| 140 | + case 'author': | |
| 141 | + $args['author'] = $term; | |
| 142 | + break; | |
| 143 | + default: | |
| 144 | + break; | |
| 145 | + } | |
| 139 | 146 | |
| 140 | - break; | |
| 147 | + break; | |
| 141 | 148 | |
| 142 | - case 'featured': | |
| 143 | - $args['fields']['group'] = true; | |
| 144 | - $this->orderby = 'group'; | |
| 145 | - // no b r e a k! | |
| 146 | - case 'popular': | |
| 147 | - case 'new': | |
| 148 | - case 'beta': | |
| 149 | - case 'recommended': | |
| 150 | - $args['browse'] = $tab; | |
| 151 | - break; | |
| 149 | + case 'featured': | |
| 150 | + $args['fields']['group'] = true; | |
| 151 | + $this->orderby = 'group'; | |
| 152 | + // no b r e a k! | |
| 153 | + case 'popular': | |
| 154 | + case 'new': | |
| 155 | + case 'beta': | |
| 156 | + case 'recommended': | |
| 157 | + $args['browse'] = $tab; | |
| 158 | + break; | |
| 152 | 159 | |
| 153 | - case 'favorites': | |
| 154 | - $user = isset( $_GET['user'] ) ? sanitize_text_field( wp_unslash( $_GET['user'] ) ) : get_user_option( 'wporg_favorites' ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 155 | - update_user_meta( get_current_user_id(), 'wporg_favorites', $user ); | |
| 156 | - if ( $user ) { | |
| 157 | - $args['user'] = $user; | |
| 158 | - } else { | |
| 159 | - $args = false; | |
| 160 | - } | |
| 160 | + case 'favorites': | |
| 161 | + $user = isset( $_GET['user'] ) ? sanitize_text_field( wp_unslash( $_GET['user'] ) ) : get_user_option( 'wporg_favorites' ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 162 | + update_user_meta( get_current_user_id(), 'wporg_favorites', $user ); | |
| 163 | + if ( $user ) { | |
| 164 | + $args['user'] = $user; | |
| 165 | + } else { | |
| 166 | + $args = false; | |
| 167 | + } | |
| 161 | 168 | |
| 162 | - break; | |
| 169 | + break; | |
| 163 | 170 | |
| 164 | - default: | |
| 165 | - $args = false; | |
| 166 | - break; | |
| 167 | - } | |
| 171 | + default: | |
| 172 | + $args = false; | |
| 173 | + break; | |
| 174 | + } | |
| 168 | 175 | |
| 169 | - if ( ! $args ) { | |
| 170 | - return; | |
| 171 | - } | |
| 176 | + if ( ! $args ) { | |
| 177 | + return; | |
| 178 | + } | |
| 172 | 179 | |
| 173 | - $api = plugins_api( 'query_plugins', $args ); | |
| 180 | + $api = plugins_api( 'query_plugins', $args ); | |
| 174 | 181 | |
| 175 | - if ( is_wp_error( $api ) ) { | |
| 176 | - $this->error = $api; | |
| 177 | - return; | |
| 178 | - } | |
| 182 | + if ( is_wp_error( $api ) ) { | |
| 183 | + $this->error = $api; | |
| 184 | + return; | |
| 185 | + } | |
| 179 | 186 | |
| 180 | - $this->items = $api->plugins; | |
| 187 | + $this->items = $api->plugins; | |
| 181 | 188 | |
| 182 | - if ( $this->orderby ) { | |
| 183 | - uasort( $this->items, array( $this, 'order_callback' ) ); | |
| 184 | - } | |
| 189 | + if ( $this->orderby ) { | |
| 190 | + uasort( $this->items, array( $this, 'order_callback' ) ); | |
| 191 | + } | |
| 185 | 192 | |
| 186 | - $this->set_pagination_args( | |
| 187 | - array( | |
| 188 | - 'total_items' => $api->info['results'], | |
| 189 | - 'per_page' => $args['per_page'], | |
| 190 | - ) | |
| 191 | - ); | |
| 193 | + $this->set_pagination_args( | |
| 194 | + array( | |
| 195 | + 'total_items' => $api->info['results'], | |
| 196 | + 'per_page' => $args['per_page'], | |
| 197 | + ) | |
| 198 | + ); | |
| 192 | 199 | |
| 193 | - if ( isset( $api->info['groups'] ) ) { | |
| 194 | - $this->groups = $api->info['groups']; | |
| 195 | - } | |
| 196 | - } | |
| 200 | + if ( isset( $api->info['groups'] ) ) { | |
| 201 | + $this->groups = $api->info['groups']; | |
| 202 | + } | |
| 203 | + } | |
| 197 | 204 | |
| 198 | - /** | |
| 199 | - * Method no_items() | |
| 200 | - * | |
| 201 | - * Check for errors. | |
| 202 | - */ | |
| 203 | - public function no_items() { | |
| 204 | - if ( isset( $this->error ) ) { | |
| 205 | - $message = $this->error->get_error_message() . '<p class="hide-if-no-js"><a href="#" class="button" onclick="document.location.reload(); return false;">' . esc_html__( 'Try again', 'mainwp' ) . '</a></p>'; | |
| 206 | - } else { | |
| 207 | - $message = esc_html__( 'No plugins match your request.', 'mainwp' ); | |
| 208 | - } | |
| 209 | - echo '<div class="ui message yellow">' . $message . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput | |
| 210 | - } | |
| 205 | + /** | |
| 206 | + * Method no_items() | |
| 207 | + * | |
| 208 | + * Check for errors. | |
| 209 | + */ | |
| 210 | + public function no_items() { | |
| 211 | + echo '<div class="ui center aligned segment">'; | |
| 212 | + MainWP_UI::render_empty_page_placeholder( __( 'No plugins found.', 'mainwp' ), __( 'Please try a different search.', 'mainwp' ), '<em data-emoji=":mag:" class="big"></em>' ); | |
| 213 | + echo '</div>'; | |
| 214 | + } | |
| 211 | 215 | |
| 212 | - /** | |
| 213 | - * Method dislpay() | |
| 214 | - * | |
| 215 | - * Override the parent display() so we can provide a different container. | |
| 216 | - */ | |
| 217 | - public function display() { | |
| 218 | - ?> | |
| 219 | - <div id="mainwp-install-plugins-container" class="ui four cards"> | |
| 220 | - <?php $this->display_rows_or_placeholder(); ?> | |
| 221 | - </div> | |
| 222 | - <div class="ui hidden divider"></div> | |
| 223 | - <div class="ui column grid"> | |
| 224 | - <div class="column right aligned"> | |
| 225 | - <div class="inline field"> | |
| 226 | - <?php $this->display_tablenav( 'bottom' ); ?> | |
| 227 | - </div> | |
| 228 | - </div> | |
| 229 | - </div> | |
| 230 | - <?php | |
| 231 | - } | |
| 216 | + /** | |
| 217 | + * Method dislpay() | |
| 218 | + * | |
| 219 | + * Override the parent display() so we can provide a different container. | |
| 220 | + */ | |
| 221 | + public function display() { | |
| 222 | + $search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; | |
| 223 | + ?> | |
| 224 | + <div class="ui two column stackable grid"> | |
| 225 | + <div class="column left aligned middle aligned"> | |
| 226 | + <?php if ( ! empty( $search ) ) : ?> | |
| 227 | + <h3 class="ui header"><?php | |
| 228 | + /* translators: %s: Search term. */ | |
| 229 | + echo esc_html( sprintf( __( 'Search results for: %s', 'mainwp' ), $search ) ); ?></h3> | |
| 230 | + <?php endif; ?> | |
| 231 | + </div> | |
| 232 | + <div class="column right aligned middle aligned"> | |
| 233 | + <div class="inline field"> | |
| 234 | + <?php $this->display_tablenav( 'top' ); ?> | |
| 235 | + </div> | |
| 236 | + </div> | |
| 237 | + </div> | |
| 238 | + <div class="ui hidden divider"></div> | |
| 239 | + <div id="mainwp-install-plugins-container" class="ui three mainwp-cards cards"> | |
| 240 | + <?php $this->display_rows_or_placeholder(); ?> | |
| 241 | + </div> | |
| 242 | + <div class="ui hidden divider"></div> | |
| 243 | + <div class="ui two column stackable grid"> | |
| 244 | + <div class="column left aligned middle aligned"> | |
| 245 | + <?php if ( ! empty( $search ) ) : ?> | |
| 246 | + <?php | |
| 247 | + /* translators: %s: Search term. */ | |
| 248 | + echo esc_html( sprintf( __( 'Search results for: %s', 'mainwp' ), $search ) ); ?> | |
| 249 | + <?php endif; ?> | |
| 250 | + </div> | |
| 251 | + <div class="column right aligned middle aligned"> | |
| 252 | + <div class="inline field"> | |
| 253 | + <?php $this->display_tablenav( 'bottom' ); ?> | |
| 254 | + </div> | |
| 255 | + </div> | |
| 256 | + </div> | |
| 257 | + <?php | |
| 258 | + } | |
| 232 | 259 | |
| 233 | - /** | |
| 234 | - * Method display_tablenav() | |
| 235 | - * | |
| 236 | - * Displays the table Navigation. | |
| 237 | - * | |
| 238 | - * @param mixed $which Position information. | |
| 239 | - * | |
| 240 | - * @return mixed wp_referer_field(); | |
| 241 | - */ | |
| 242 | - protected function display_tablenav( $which ) { | |
| 260 | + /** | |
| 261 | + * Method display_tablenav() | |
| 262 | + * | |
| 263 | + * Displays the table Navigation. | |
| 264 | + * | |
| 265 | + * @param mixed $which Position information. | |
| 266 | + * | |
| 267 | + * @return mixed wp_referer_field(); | |
| 268 | + */ | |
| 269 | + protected function display_tablenav( $which ) { | |
| 243 | 270 | |
| 244 | - if ( 'featured' === $GLOBALS['tab'] ) { | |
| 245 | - return; | |
| 246 | - } | |
| 271 | + if ( 'featured' === $GLOBALS['tab'] ) { | |
| 272 | + return; | |
| 273 | + } | |
| 247 | 274 | |
| 248 | - if ( 'top' === $which ) { | |
| 249 | - wp_referer_field(); | |
| 250 | - $this->pagination( $which ); | |
| 251 | - } else { | |
| 252 | - $this->pagination( $which ); | |
| 253 | - } | |
| 254 | - } | |
| 275 | + if ( 'top' === $which ) { | |
| 276 | + wp_referer_field(); | |
| 277 | + $this->pagination( $which ); | |
| 278 | + } else { | |
| 279 | + $this->pagination( $which ); | |
| 280 | + } | |
| 281 | + } | |
| 255 | 282 | |
| 256 | - /** | |
| 257 | - * Method pagination() | |
| 258 | - * | |
| 259 | - * Build the pagination menu. | |
| 260 | - * | |
| 261 | - * @param mixed $which Position information. | |
| 262 | - * | |
| 263 | - * @return mixed Pagination HTML | |
| 264 | - */ | |
| 265 | - protected function pagination( $which ) { | |
| 266 | - if ( empty( $this->_pagination_args ) ) { | |
| 267 | - return; | |
| 268 | - } | |
| 283 | + /** | |
| 284 | + * Method pagination() | |
| 285 | + * | |
| 286 | + * Build the pagination menu. | |
| 287 | + * | |
| 288 | + * @param mixed $which Position information. | |
| 289 | + * | |
| 290 | + * @return mixed Pagination HTML | |
| 291 | + */ | |
| 292 | + protected function pagination( $which ) { //phpcs:ignore -- NOSONAR - complex. | |
| 293 | + if ( empty( $this->_pagination_args ) ) { | |
| 294 | + return; | |
| 295 | + } | |
| 269 | 296 | |
| 270 | - $total_items = $this->_pagination_args['total_items']; | |
| 271 | - $total_pages = (int) $this->_pagination_args['total_pages']; | |
| 297 | + $total_items = $this->_pagination_args['total_items']; | |
| 298 | + $total_pages = (int) $this->_pagination_args['total_pages']; | |
| 272 | 299 | |
| 273 | - $perpage_paging = '<span>' . sprintf( _n( '%s item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>'; | |
| 300 | + /* translators: %s: Number of items. */ | |
| 301 | + $perpage_paging = '<span>' . sprintf( _n( '%s item', '%s items', $total_items, 'mainwp' ), number_format_i18n( $total_items ) ) . '</span>'; | |
| 274 | 302 | |
| 275 | - $current = (int) $this->get_pagenum(); | |
| 276 | - $removable_query_args = wp_removable_query_args(); | |
| 303 | + $current = (int) $this->get_pagenum(); | |
| 304 | + $removable_query_args = wp_removable_query_args(); | |
| 277 | 305 | |
| 278 | - $current_url = set_url_scheme( 'http://' . ( isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '' ) . ( isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ) ); // phpcs:ignore WordPress.Security.NonceVerification | |
| 306 | + $current_url = set_url_scheme( 'http://' . ( isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '' ) . ( isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ) ); // phpcs:ignore WordPress.Security.NonceVerification -- NOSONAR - compatible with dashboard host. | |
| 279 | 307 | |
| 280 | - $current_url = remove_query_arg( $removable_query_args, $current_url ); | |
| 308 | + $current_url = remove_query_arg( $removable_query_args, $current_url ); | |
| 281 | 309 | |
| 282 | - $page_links = array(); | |
| 310 | + $page_links = array(); | |
| 283 | 311 | |
| 284 | - $disable_first = false; | |
| 285 | - $disable_last = false; | |
| 286 | - $disable_prev = false; | |
| 287 | - $disable_next = false; | |
| 312 | + $disable_first = false; | |
| 313 | + $disable_last = false; | |
| 314 | + $disable_prev = false; | |
| 315 | + $disable_next = false; | |
| 288 | 316 | |
| 289 | - if ( 1 === $current ) { | |
| 290 | - $disable_first = true; | |
| 291 | - $disable_prev = true; | |
| 292 | - } | |
| 293 | - if ( 2 === $current ) { | |
| 294 | - $disable_first = true; | |
| 295 | - } | |
| 296 | - if ( $current === $total_pages ) { | |
| 297 | - $disable_last = true; | |
| 298 | - $disable_next = true; | |
| 299 | - } | |
| 300 | - if ( $current === $total_pages - 1 ) { | |
| 301 | - $disable_last = true; | |
| 302 | - } | |
| 317 | + if ( 1 === $current ) { | |
| 318 | + $disable_first = true; | |
| 319 | + $disable_prev = true; | |
| 320 | + } | |
| 321 | + if ( 2 === $current ) { | |
| 322 | + $disable_first = true; | |
| 323 | + } | |
| 324 | + if ( $current === $total_pages ) { | |
| 325 | + $disable_last = true; | |
| 326 | + $disable_next = true; | |
| 327 | + } | |
| 328 | + if ( $current === $total_pages - 1 ) { | |
| 329 | + $disable_last = true; | |
| 330 | + } | |
| 303 | 331 | |
| 304 | - if ( $disable_first ) { | |
| 305 | - $page_links[] = '<a class="item disabled" aria-hidden="true"><i class="angle double left icon"></i></a>'; | |
| 306 | - } else { | |
| 307 | - $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'First page' ) . "' aria-hidden='true'>%s</a>", esc_url( remove_query_arg( 'paged', $current_url ) ), '<i class="angle double left icon"></i>' ); | |
| 308 | - } | |
| 332 | + if ( $disable_first ) { | |
| 333 | + $page_links[] = '<a class="item disabled" aria-hidden="true"><i class="angle double left icon"></i></a>'; | |
| 334 | + } else { | |
| 335 | + $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'First page', 'mainwp' ) . "' aria-hidden='true'>%s</a>", esc_url( remove_query_arg( 'paged', $current_url ) ), '<i class="angle double left icon"></i>' ); | |
| 336 | + } | |
| 309 | 337 | |
| 310 | - if ( $disable_prev ) { | |
| 311 | - $page_links[] = '<a class="item disabled" aria-hidden="true"><i class="angle left icon"></i></a>'; | |
| 312 | - } else { | |
| 313 | - $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'Previous page' ) . "' aria-hidden='true'>%s</a>", esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ), '<i class="angle left icon"></i>' ); | |
| 314 | - } | |
| 338 | + if ( $disable_prev ) { | |
| 339 | + $page_links[] = '<a class="item disabled" aria-hidden="true"><i class="angle left icon"></i></a>'; | |
| 340 | + } else { | |
| 341 | + $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'Previous page', 'mainwp' ) . "' aria-hidden='true'>%s</a>", esc_url( add_query_arg( 'paged', max( 1, $current - 1 ), $current_url ) ), '<i class="angle left icon"></i>' ); | |
| 342 | + } | |
| 315 | 343 | |
| 316 | - if ( $current - 1 > 0 ) { | |
| 317 | - $page_links[] = sprintf( "<a class='item' href='%s'>%s</a>", esc_url( add_query_arg( 'paged', $current - 1, $current_url ) ), $current - 1 ); | |
| 318 | - } | |
| 344 | + if ( $current - 1 > 0 ) { | |
| 345 | + $page_links[] = sprintf( "<a class='item' href='%s'>%s</a>", esc_url( add_query_arg( 'paged', $current - 1, $current_url ) ), $current - 1 ); | |
| 346 | + } | |
| 319 | 347 | |
| 320 | - $page_links[] = sprintf( "<a class='item active' href='%s'>%s</a>", esc_url( add_query_arg( 'paged', $current, $current_url ) ), $current ); | |
| 348 | + $page_links[] = sprintf( "<a class='item active' href='%s'>%s</a>", esc_url( add_query_arg( 'paged', $current, $current_url ) ), $current ); | |
| 321 | 349 | |
| 322 | - if ( $current + 1 <= $total_pages ) { | |
| 323 | - $page_links[] = sprintf( "<a class='item' href='%s'>%s</a>", esc_url( add_query_arg( 'paged', $current + 1, $current_url ) ), $current + 1 ); | |
| 324 | - } | |
| 350 | + if ( $current + 1 <= $total_pages ) { | |
| 351 | + $page_links[] = sprintf( "<a class='item' href='%s'>%s</a>", esc_url( add_query_arg( 'paged', $current + 1, $current_url ) ), $current + 1 ); | |
| 352 | + } | |
| 325 | 353 | |
| 326 | - if ( $disable_next ) { | |
| 327 | - $page_links[] = '<span class="item disabled " aria-hidden="true"><i class="right angle icon"></i></span>'; | |
| 328 | - } else { | |
| 329 | - $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'Next page', 'mainwp' ) . "'>%s</a>", esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ), '<i class="angle right icon"></i>' ); | |
| 330 | - } | |
| 354 | + if ( $disable_next ) { | |
| 355 | + $page_links[] = '<span class="item disabled " aria-hidden="true"><i class="right angle icon"></i></span>'; | |
| 356 | + } else { | |
| 357 | + $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'Next page', 'mainwp' ) . "'>%s</a>", esc_url( add_query_arg( 'paged', min( $total_pages, $current + 1 ), $current_url ) ), '<i class="angle right icon"></i>' ); | |
| 358 | + } | |
| 331 | 359 | |
| 332 | - if ( $disable_last ) { | |
| 333 | - $page_links[] = '<a class="item disabled" aria-hidden="true"><i class="right angle double icon"></i></a>'; | |
| 334 | - } else { | |
| 335 | - $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'Last page', 'mainwp' ) . "' aria-hidden='true'>%s</a>", esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ), '<i class="right angle double icon"></i>' ); | |
| 336 | - } | |
| 360 | + if ( $disable_last ) { | |
| 361 | + $page_links[] = '<a class="item disabled" aria-hidden="true"><i class="right angle double icon"></i></a>'; | |
| 362 | + } else { | |
| 363 | + $page_links[] = sprintf( "<a class='item' href='%s' title='" . esc_html__( 'Last page', 'mainwp' ) . "' aria-hidden='true'>%s</a>", esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ), '<i class="right angle double icon"></i>' ); | |
| 364 | + } | |
| 337 | 365 | |
| 338 | - if ( $total_pages > 1 ) { | |
| 339 | - $perpage_paging = $perpage_paging . " <div class='ui pagination menu'>" . join( "\n", $page_links ) . '</div>'; | |
| 340 | - } else { | |
| 341 | - $perpage_paging = $perpage_paging; | |
| 342 | - } | |
| 366 | + if ( $total_pages > 1 ) { | |
| 367 | + $perpage_paging = $perpage_paging . " <div class='ui mini pagination menu'>" . join( "\n", $page_links ) . '</div>'; | |
| 368 | + } | |
| 343 | 369 | |
| 344 | - ob_start(); | |
| 370 | + ob_start(); | |
| 345 | 371 | |
| 346 | - echo $perpage_paging; // phpcs:ignore WordPress.Security.EscapeOutput | |
| 372 | + echo $perpage_paging; // phpcs:ignore WordPress.Security.EscapeOutput | |
| 347 | 373 | |
| 348 | - $output = ob_get_clean(); | |
| 374 | + $output = ob_get_clean(); | |
| 349 | 375 | |
| 350 | - $this->_pagination = $output; | |
| 376 | + $this->_pagination = $output; | |
| 351 | 377 | |
| 352 | - echo $this->_pagination; // phpcs:ignore WordPress.Security.EscapeOutput | |
| 353 | - } | |
| 378 | + echo $this->_pagination; // phpcs:ignore WordPress.Security.EscapeOutput | |
| 379 | + } | |
| 354 | 380 | |
| 355 | - /** | |
| 356 | - * Method get_columns() | |
| 357 | - * | |
| 358 | - * Get the collumns to display. | |
| 359 | - * | |
| 360 | - * @return array List of collumns to display. | |
| 361 | - */ | |
| 362 | - public function get_columns() { | |
| 363 | - return array(); | |
| 364 | - } | |
| 381 | + /** | |
| 382 | + * Method get_columns() | |
| 383 | + * | |
| 384 | + * Get the collumns to display. | |
| 385 | + * | |
| 386 | + * @return array List of collumns to display. | |
| 387 | + */ | |
| 388 | + public function get_columns() { | |
| 389 | + return array(); | |
| 390 | + } | |
| 365 | 391 | |
| 366 | - /** | |
| 367 | - * Method order_callback() | |
| 368 | - * | |
| 369 | - * @param object $plugin_a Plugin A. | |
| 370 | - * @param object $plugin_b Plugin B. | |
| 371 | - * | |
| 372 | - * @return int 0|1 Default 0. | |
| 373 | - */ | |
| 374 | - private function order_callback( $plugin_a, $plugin_b ) { | |
| 375 | - $orderby = $this->orderby; | |
| 376 | - if ( ! isset( $plugin_a->$orderby, $plugin_b->$orderby ) ) { | |
| 377 | - return 0; | |
| 378 | - } | |
| 392 | + /** | |
| 393 | + * Method order_callback() | |
| 394 | + * | |
| 395 | + * @param object $plugin_a Plugin A. | |
| 396 | + * @param object $plugin_b Plugin B. | |
| 397 | + * | |
| 398 | + * @return int 0|1 Default 0. | |
| 399 | + */ | |
| 400 | + private function order_callback( $plugin_a, $plugin_b ) { | |
| 401 | + $orderby = $this->orderby; | |
| 402 | + if ( ! isset( $plugin_a->$orderby, $plugin_b->$orderby ) ) { | |
| 403 | + return 0; | |
| 404 | + } | |
| 379 | 405 | |
| 380 | - $a = $plugin_a->$orderby; | |
| 381 | - $b = $plugin_b->$orderby; | |
| 406 | + $a = $plugin_a->$orderby; | |
| 407 | + $b = $plugin_b->$orderby; | |
| 382 | 408 | |
| 383 | - if ( $a === $b ) { | |
| 384 | - return 0; | |
| 385 | - } | |
| 409 | + if ( $a === $b ) { | |
| 410 | + return 0; | |
| 411 | + } | |
| 386 | 412 | |
| 387 | - if ( 'DESC' === $this->order ) { | |
| 388 | - return ( $a < $b ) ? 1 : -1; | |
| 389 | - } else { | |
| 390 | - return ( $a < $b ) ? -1 : 1; | |
| 391 | - } | |
| 392 | - } | |
| 413 | + if ( 'DESC' === $this->order ) { | |
| 414 | + return ( $a < $b ) ? 1 : -1; | |
| 415 | + } else { | |
| 416 | + return ( $a < $b ) ? -1 : 1; | |
| 417 | + } | |
| 418 | + } | |
| 393 | 419 | |
| 394 | - /** | |
| 395 | - * Method display_rows() | |
| 396 | - * | |
| 397 | - * Build Plugin Cards. | |
| 398 | - * | |
| 399 | - * @return mixed Plugin cards. | |
| 400 | - */ | |
| 401 | - public function display_rows() { | |
| 402 | - $plugins_allowedtags = array( | |
| 403 | - 'a' => array( | |
| 404 | - 'href' => array(), | |
| 405 | - 'title' => array(), | |
| 406 | - 'target' => array(), | |
| 407 | - ), | |
| 408 | - 'abbr' => array( 'title' => array() ), | |
| 409 | - 'acronym' => array( 'title' => array() ), | |
| 410 | - 'code' => array(), | |
| 411 | - 'pre' => array(), | |
| 412 | - 'em' => array(), | |
| 413 | - 'strong' => array(), | |
| 414 | - 'ul' => array(), | |
| 415 | - 'ol' => array(), | |
| 416 | - 'li' => array(), | |
| 417 | - 'p' => array(), | |
| 418 | - 'br' => array(), | |
| 419 | - ); | |
| 420 | + /** | |
| 421 | + * Check if a search term matches mainwp or mainwp child (case-insensitive). | |
| 422 | + * | |
| 423 | + * @param string $term Search term. | |
| 424 | + * @return bool True if matches. | |
| 425 | + */ | |
| 426 | + private function is_mainwp_search( $term ) { | |
| 427 | + $normalized = strtolower( trim( $term ) ); | |
| 428 | + return (bool) preg_match( '/^mainwp(\s*-?\s*child)?$/i', $normalized ); | |
| 429 | + } | |
| 420 | 430 | |
| 421 | - $plugins_group_titles = array( | |
| 422 | - 'Performance' => _x( 'Performance', 'Plugin installer group title' ), | |
| 423 | - 'Social' => _x( 'Social', 'Plugin installer group title' ), | |
| 424 | - 'Tools' => _x( 'Tools', 'Plugin installer group title' ), | |
| 425 | - ); | |
| 431 | + /** | |
| 432 | + * Render hardcoded MainWP Child plugin card. | |
| 433 | + * | |
| 434 | + * @return void | |
| 435 | + */ | |
| 436 | + private function render_mainwp_child_card() { | |
| 437 | + $details_link = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=mainwp-child&name=' . rawurlencode( 'MainWP Child' ) ); | |
| 438 | + $icon_url = MAINWP_PLUGIN_URL . 'assets/images/mainwp-icon.svg'; | |
| 439 | + $plugin_name = esc_attr__( 'MainWP Child – Securely Connects to the MainWP Dashboard to Manage Multiple Sites', 'mainwp' ); | |
| 440 | + ?> | |
| 441 | + <div class="card plugin-card-mainwp-child" plugin-slug="mainwp-child" plugin-name="MainWP Child"> | |
| 442 | + <?php do_action( 'mainwp_install_plugin_card_top' ); ?> | |
| 443 | + <div class="content"> | |
| 444 | + <a class="right floated mini ui image open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>"><img src="<?php echo esc_url( $icon_url ); ?>" alt="<?php esc_attr_e( 'MainWP Child', 'mainwp' ); ?>" /></a> | |
| 445 | + <div class="header"> | |
| 446 | + <a class="open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>"><?php esc_html_e( 'MainWP Child', 'mainwp' ); ?></a> | |
| 447 | + </div> | |
| 448 | + <div class="meta"><cite><?php | |
| 449 | + /* translators: %s: Plugin author name. */ | |
| 450 | + printf( esc_html__( 'By %s', 'mainwp' ), '<a href="' . esc_url( 'https://profiles.wordpress.org/mainwp/' ) . '">mainwp</a>' ); // phpcs:ignore WordPress.Security.EscapeOutput ?></cite></div> | |
| 451 | + <div class="description"> | |
| 452 | + <p><?php esc_html_e( 'MainWP Child connects your WordPress sites to this Dashboard.', 'mainwp' ); ?></p> | |
| 453 | + <p><?php esc_html_e( 'Already managing a site here? Select Install Plugin, choose your sites in the right panel, and click Complete Installation.', 'mainwp' ); ?></p> | |
| 454 | + <p><?php esc_html_e( 'Setting up a new site? Download the plugin, then:', 'mainwp' ); ?></p> | |
| 455 | + <div class="ui list"> | |
| 456 | + <div class="item"><p>1. <?php esc_html_e( 'Log in to your WordPress site', 'mainwp' ); ?></p></div> | |
| 457 | + <div class="item"><p>2. <?php esc_html_e( 'Go to Plugins → Add New → Upload Plugin', 'mainwp' ); ?></p></div> | |
| 458 | + <div class="item"><p>3. <?php esc_html_e( 'Upload and activate the downloaded file', 'mainwp' ); ?></p></div> | |
| 459 | + <div class="item"><p>4. <?php esc_html_e( 'Return here to add the site to your Dashboard', 'mainwp' ); ?></p></div> | |
| 460 | + </div> | |
| 461 | + </div> | |
| 462 | + </div> | |
| 463 | + <div class="extra content"> | |
| 464 | + <div class="left aligned middle aligned column"> | |
| 465 | + <a href="<?php echo esc_url( 'https://downloads.wordpress.org/plugin/mainwp-child.latest-stable.zip' ); ?>" class="ui mini green basic fluid button"><i class="download icon"></i><?php esc_html_e( 'Download', 'mainwp' ); ?></a> | |
| 466 | + </div> | |
| 467 | + </div> | |
| 468 | + <div class="extra content"> | |
| 469 | + <div class="ui two column grid"> | |
| 470 | + <div class="left aligned middle aligned column"> | |
| 471 | + <a href="<?php echo esc_url( $details_link ); ?>" class="ui mini button open-plugin-details-modal"><?php esc_html_e( 'Plugin Details', 'mainwp' ); ?></a> | |
| 472 | + </div> | |
| 473 | + <div class="right aligned middle aligned column"> | |
| 474 | + <div class="ui radio checkbox"> | |
| 475 | + <input name="install-plugin" type="radio" id="install-plugin-mainwp-child" plugin-name="<?php echo esc_attr( $plugin_name ); ?>" plugin-version=""> | |
| 476 | + <label><?php esc_html_e( 'Install Plugin', 'mainwp' ); ?></label> | |
| 477 | + </div> | |
| 478 | + </div> | |
| 479 | + </div> | |
| 480 | + </div> | |
| 481 | + </div> | |
| 482 | + <?php | |
| 483 | + } | |
| 426 | 484 | |
| 427 | - $group = null; | |
| 485 | + /** | |
| 486 | + * Method display_rows() | |
| 487 | + * | |
| 488 | + * Build Plugin Cards. | |
| 489 | + * | |
| 490 | + * @return mixed Plugin cards. | |
| 491 | + */ | |
| 492 | + public function display_rows() { //phpcs:ignore -- NOSONAR - complex. | |
| 493 | + $search_term = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification | |
| 428 | 494 | |
| 429 | - foreach ( (array) $this->items as $plugin ) { | |
| 430 | - if ( is_object( $plugin ) ) { | |
| 431 | - $plugin = (array) $plugin; | |
| 432 | - } | |
| 495 | + if ( ! empty( $search_term ) && $this->is_mainwp_search( $search_term ) ) { | |
| 496 | + $this->render_mainwp_child_card(); | |
| 497 | + $this->items = array_filter( | |
| 498 | + $this->items, | |
| 499 | + function ( $plugin ) { | |
| 500 | + $slug = is_array( $plugin ) ? ( $plugin['slug'] ?? '' ) : ( $plugin->slug ?? '' ); | |
| 501 | + return 'mainwp-child' !== $slug; | |
| 502 | + } | |
| 503 | + ); | |
| 504 | + } | |
| 433 | 505 | |
| 434 | - // Display the group heading if there is one. | |
| 435 | - if ( isset( $plugin['group'] ) && $plugin['group'] != $group ) { //phpcs:ignore -- to valid. | |
| 436 | - if ( isset( $this->groups[ $plugin['group'] ] ) ) { | |
| 437 | - $group_name = $this->groups[ $plugin['group'] ]; | |
| 438 | - if ( isset( $plugins_group_titles[ $group_name ] ) ) { | |
| 439 | - $group_name = $plugins_group_titles[ $group_name ]; | |
| 440 | - } | |
| 441 | - } else { | |
| 442 | - $group_name = $plugin['group']; | |
| 443 | - } | |
| 506 | + $plugins_allowedtags = array( | |
| 507 | + 'a' => array( | |
| 508 | + 'href' => array(), | |
| 509 | + 'title' => array(), | |
| 510 | + 'target' => array(), | |
| 511 | + ), | |
| 512 | + 'abbr' => array( 'title' => array() ), | |
| 513 | + 'acronym' => array( 'title' => array() ), | |
| 514 | + 'code' => array(), | |
| 515 | + 'pre' => array(), | |
| 516 | + 'em' => array(), | |
| 517 | + 'strong' => array(), | |
| 518 | + 'ul' => array(), | |
| 519 | + 'ol' => array(), | |
| 520 | + 'li' => array(), | |
| 521 | + 'p' => array(), | |
| 522 | + 'br' => array(), | |
| 523 | + ); | |
| 444 | 524 | |
| 445 | - // Starting a new group, close off the divs of the last one. | |
| 446 | - if ( ! empty( $group ) ) { | |
| 447 | - echo '</div></div>'; | |
| 448 | - } | |
| 525 | + $plugins_group_titles = array( | |
| 526 | + 'Performance' => _x( 'Performance', 'Plugin installer group title', 'mainwp' ), | |
| 527 | + 'Social' => _x( 'Social', 'Plugin installer group title', 'mainwp' ), | |
| 528 | + 'Tools' => _x( 'Tools', 'Plugin installer group title', 'mainwp' ), | |
| 529 | + ); | |
| 449 | 530 | |
| 450 | - echo '<div class="plugin-group"><h3>' . esc_html( $group_name ) . '</h3>'; | |
| 451 | - // Needs an extra wrapping div for nth-child selectors to work. | |
| 452 | - echo '<div class="plugin-items">'; | |
| 531 | + $group = null; | |
| 453 | 532 | |
| 454 | - $group = $plugin['group']; | |
| 455 | - } | |
| 456 | - $title = wp_kses( $plugin['name'], $plugins_allowedtags ); | |
| 533 | + foreach ( (array) $this->items as $plugin ) { | |
| 534 | + if ( is_object( $plugin ) ) { | |
| 535 | + $plugin = (array) $plugin; | |
| 536 | + } | |
| 457 | 537 | |
| 458 | - // Remove any HTML from the description. | |
| 459 | - $description = wp_strip_all_tags( $plugin['short_description'] ); | |
| 460 | - $version = wp_kses( $plugin['version'], $plugins_allowedtags ); | |
| 538 | + // Display the group heading if there is one. | |
| 539 | + if ( isset( $plugin['group'] ) && $plugin['group'] != $group ) { //phpcs:ignore -- to valid. | |
| 540 | + if ( isset( $this->groups[ $plugin['group'] ] ) ) { | |
| 541 | + $group_name = $this->groups[ $plugin['group'] ]; | |
| 542 | + if ( isset( $plugins_group_titles[ $group_name ] ) ) { | |
| 543 | + $group_name = $plugins_group_titles[ $group_name ]; | |
| 544 | + } | |
| 545 | + } else { | |
| 546 | + $group_name = $plugin['group']; | |
| 547 | + } | |
| 461 | 548 | |
| 462 | - $name = wp_strip_all_tags( $title . ' ' . $version ); | |
| 549 | + // Starting a new group, close off the divs of the last one. | |
| 550 | + if ( ! empty( $group ) ) { | |
| 551 | + echo '</div></div>'; | |
| 552 | + } | |
| 463 | 553 | |
| 464 | - $author = wp_kses( $plugin['author'], $plugins_allowedtags ); | |
| 465 | - if ( ! empty( $author ) ) { | |
| 466 | - $author = ' <cite>' . sprintf( esc_html__( 'By %s', 'mainwp' ), $author ) . '</cite>'; | |
| 467 | - } | |
| 554 | + echo '<div class="plugin-group"><h3>' . esc_html( $group_name ) . '</h3>'; | |
| 555 | + // Needs an extra wrapping div for nth-child selectors to work. | |
| 556 | + echo '<div class="plugin-items">'; | |
| 468 | 557 | |
| 469 | - $details_link = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $plugin['slug'] . '&url=' . ( isset( $plugin['PluginURI'] ) ? rawurlencode( $plugin['PluginURI'] ) : '' ) . '&name=' . rawurlencode( $plugin['name'] ) ); | |
| 558 | + $group = $plugin['group']; | |
| 559 | + } | |
| 560 | + $title = wp_kses( $plugin['name'], $plugins_allowedtags ); | |
| 470 | 561 | |
| 471 | - if ( ! empty( $plugin['icons']['svg'] ) ) { | |
| 472 | - $plugin_icon_url = $plugin['icons']['svg']; | |
| 473 | - } elseif ( ! empty( $plugin['icons']['2x'] ) ) { | |
| 474 | - $plugin_icon_url = $plugin['icons']['2x']; | |
| 475 | - } elseif ( ! empty( $plugin['icons']['1x'] ) ) { | |
| 476 | - $plugin_icon_url = $plugin['icons']['1x']; | |
| 477 | - } else { | |
| 478 | - $plugin_icon_url = $plugin['icons']['default']; | |
| 479 | - } | |
| 562 | + // Remove any HTML from the description. | |
| 563 | + $description = wp_strip_all_tags( $plugin['short_description'] ); | |
| 564 | + $version = wp_kses( $plugin['version'], $plugins_allowedtags ); | |
| 480 | 565 | |
| 481 | - $last_updated_timestamp = strtotime( $plugin['last_updated'] ); | |
| 482 | - ?> | |
| 566 | + $author = wp_kses( $plugin['author'], $plugins_allowedtags ); | |
| 567 | + if ( ! empty( $author ) ) { | |
| 568 | + /* translators: %s: Plugin author name. */ | |
| 569 | + $author = ' <cite>' . sprintf( esc_html__( 'By %s', 'mainwp' ), $author ) . '</cite>'; | |
| 570 | + } | |
| 483 | 571 | |
| 484 | - <div class="card plugin-card-<?php echo sanitize_html_class( $plugin['slug'] ); ?>"> | |
| 485 | - <?php | |
| 486 | - /** | |
| 487 | - * Action: mainwp_install_plugin_card_top | |
| 488 | - * | |
| 489 | - * Fires at the plugin card at top on the Install Plugins page. | |
| 490 | - * | |
| 491 | - * @since 4.1 | |
| 492 | - */ | |
| 493 | - do_action( 'mainwp_install_plugin_card_top' ); | |
| 494 | - ?> | |
| 495 | - <div class="content"> | |
| 496 | - <a class="right floated mini ui image open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>"><img src="<?php echo esc_attr( $plugin_icon_url ); ?>" /></a> | |
| 497 | - <div class="header"> | |
| 498 | - <a class="open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>"><?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput ?></a> | |
| 499 | - </div> | |
| 500 | - <div class="meta"> | |
| 501 | - <?php echo $author; // phpcs:ignore WordPress.Security.EscapeOutput ?> | |
| 502 | - </div> | |
| 503 | - <div class="description"> | |
| 504 | - <?php echo esc_html( wp_strip_all_tags( $description ) ); ?> | |
| 505 | - </div> | |
| 506 | - </div> | |
| 507 | - <div class="extra content"> | |
| 508 | - <div class="ui stacking grid"> | |
| 509 | - <div class="four wide left aligned column"> | |
| 510 | - <?php | |
| 511 | - wp_star_rating( | |
| 512 | - array( | |
| 513 | - 'rating' => $plugin['rating'], | |
| 514 | - 'type' => 'percent', | |
| 515 | - 'number' => $plugin['num_ratings'], | |
| 516 | - ) | |
| 517 | - ); | |
| 518 | - ?> | |
| 519 | - </div> | |
| 520 | - <div class="twelve wide right aligned column"><strong><?php esc_html_e( 'Updated: ', 'mainwp' ); ?></strong><?php printf( esc_html__( '%s ago', 'mainwp' ), human_time_diff( $last_updated_timestamp ) ); // phpcs:ignore WordPress.Security.EscapeOutput ?></div> | |
| 521 | - </div> | |
| 522 | - </div> | |
| 523 | - <div class="extra content"> | |
| 524 | - <a href="<?php echo esc_attr( $details_link ); ?>" class="ui mini button open-plugin-details-modal"><?php echo esc_html( 'Plugin Details' ); ?></a> | |
| 525 | - <div class="ui radio checkbox right floated"> | |
| 526 | - <input name="install-plugin" type="radio" id="install-plugin-<?php echo sanitize_html_class( $plugin['slug'] ); ?>" plugin-name="<?php echo esc_attr( $title ); ?>" plugin-version="<?php echo esc_attr( $version ); ?>"> | |
| 527 | - <label><?php esc_html_e( 'Install Plugin', 'mainwp' ); ?></label> | |
| 528 | - </div> | |
| 529 | - </div> | |
| 530 | - <?php | |
| 531 | - /** | |
| 532 | - * Action: mainwp_install_plugin_card_bottom | |
| 533 | - * | |
| 534 | - * Fires at the plugin card at bottom on the Install Plugins page. | |
| 535 | - * | |
| 536 | - * @since 4.1 | |
| 537 | - */ | |
| 538 | - do_action( 'mainwp_install_plugin_card_bottom', $plugin ); | |
| 539 | - ?> | |
| 540 | - </div> | |
| 541 | - <?php | |
| 542 | - } | |
| 543 | - ?> | |
| 544 | - <script type="text/javascript"> | |
| 545 | - jQuery( document ).ready( function() { | |
| 546 | - jQuery( '.card .ui.star.rating' ).rating(); | |
| 547 | - } ); | |
| 548 | - </script> | |
| 549 | - <?php | |
| 550 | - // Close off the group divs of the last one. | |
| 551 | - if ( ! empty( $group ) ) { | |
| 552 | - echo '</div></div>'; | |
| 553 | - } | |
| 554 | - } | |
| 572 | + $details_link = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $plugin['slug'] . '&url=' . ( isset( $plugin['PluginURI'] ) ? rawurlencode( $plugin['PluginURI'] ) : '' ) . '&name=' . rawurlencode( $plugin['name'] ) ); | |
| 573 | + | |
| 574 | + if ( ! empty( $plugin['icons']['svg'] ) ) { | |
| 575 | + $plugin_icon_url = $plugin['icons']['svg']; | |
| 576 | + } elseif ( ! empty( $plugin['icons']['2x'] ) ) { | |
| 577 | + $plugin_icon_url = $plugin['icons']['2x']; | |
| 578 | + } elseif ( ! empty( $plugin['icons']['1x'] ) ) { | |
| 579 | + $plugin_icon_url = $plugin['icons']['1x']; | |
| 580 | + } else { | |
| 581 | + $plugin_icon_url = $plugin['icons']['default']; | |
| 582 | + } | |
| 583 | + | |
| 584 | + $last_updated_timestamp = strtotime( $plugin['last_updated'] ); | |
| 585 | + ?> | |
| 586 | + | |
| 587 | + <div class="card plugin-card-<?php echo sanitize_html_class( $plugin['slug'] ); ?>" plugin-slug="<?php echo esc_attr( $plugin['slug'] ); ?>" plugin-name="<?php echo esc_attr( $plugin['name'] ); ?>"> | |
| 588 | + <?php | |
| 589 | + /** | |
| 590 | + * Action: mainwp_install_plugin_card_top | |
| 591 | + * | |
| 592 | + * Fires at the plugin card at top on the Install Plugins page. | |
| 593 | + * | |
| 594 | + * @since 4.1 | |
| 595 | + */ | |
| 596 | + do_action( 'mainwp_install_plugin_card_top' ); | |
| 597 | + ?> | |
| 598 | + <div class="content"> | |
| 599 | + <a class="right floated mini ui image open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>"><img src="<?php echo esc_attr( $plugin_icon_url ); ?>" alt="<?php echo esc_attr( $plugin['name'] ); ?>" /></a> | |
| 600 | + <div class="header"> | |
| 601 | + <a class="open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>"><?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput ?></a> | |
| 602 | + </div> | |
| 603 | + <div class="meta"><?php echo $author; // phpcs:ignore WordPress.Security.EscapeOutput ?></div> | |
| 604 | + <div class="description"> | |
| 605 | + <?php echo esc_html( wp_strip_all_tags( $description ) ); ?> | |
| 606 | + </div> | |
| 607 | + </div> | |
| 608 | + <div class="extra content"> | |
| 609 | + <div class="ui stacking grid"> | |
| 610 | + <div class="four wide left aligned column"> | |
| 611 | + <?php | |
| 612 | + wp_star_rating( | |
| 613 | + array( | |
| 614 | + 'rating' => $plugin['rating'], | |
| 615 | + 'type' => 'percent', | |
| 616 | + 'number' => $plugin['num_ratings'], | |
| 617 | + ) | |
| 618 | + ); | |
| 619 | + ?> | |
| 620 | + </div> | |
| 621 | + <div class="twelve wide right aligned column"><span class="ui small text"><?php | |
| 622 | + /* translators: %s: Human-readable time difference. */ | |
| 623 | + printf( esc_html__( 'Updated %s ago', 'mainwp' ), human_time_diff( $last_updated_timestamp ) ); // phpcs:ignore WordPress.Security.EscapeOutput ?></span></div> | |
| 624 | + </div> | |
| 625 | + </div> | |
| 626 | + <div class="extra content"> | |
| 627 | + <div class="ui two column grid"> | |
| 628 | + <div class="left aligned middle aligned column"> | |
| 629 | + <a href="<?php echo esc_attr( $details_link ); ?>" class="ui mini button open-plugin-details-modal"><?php echo esc_html__( 'Plugin Details', 'mainwp' ); ?></a> | |
| 630 | + </div> | |
| 631 | + <div class="right aligned middle aligned column"> | |
| 632 | + <div class="ui radio checkbox"> | |
| 633 | + <input name="install-plugin" type="radio" id="install-plugin-<?php echo sanitize_html_class( $plugin['slug'] ); ?>" plugin-name="<?php echo esc_attr( $title ); ?>" plugin-version="<?php echo esc_attr( $version ); ?>"> | |
| 634 | + <label><?php esc_html_e( 'Install Plugin', 'mainwp' ); ?></label> | |
| 635 | + </div> | |
| 636 | + </div> | |
| 637 | + </div> | |
| 638 | + </div> | |
| 639 | + <?php | |
| 640 | + /** | |
| 641 | + * Action: mainwp_install_plugin_card_bottom | |
| 642 | + * | |
| 643 | + * Fires at the plugin card at bottom on the Install Plugins page. | |
| 644 | + * | |
| 645 | + * @since 4.1 | |
| 646 | + */ | |
| 647 | + do_action( 'mainwp_install_plugin_card_bottom', $plugin ); | |
| 648 | + ?> | |
| 649 | + </div> | |
| 650 | + <?php | |
| 651 | + } | |
| 652 | + ?> | |
| 653 | + <script type="text/javascript"> | |
| 654 | + jQuery( document ).ready( function() { | |
| 655 | + jQuery( '.card .ui.star.rating' ).rating(); | |
| 656 | + } ); | |
| 657 | + </script> | |
| 658 | + <?php | |
| 659 | + // Close off the group divs of the last one. | |
| 660 | + if ( ! empty( $group ) ) { | |
| 661 | + echo '</div></div>'; | |
| 662 | + } | |
| 663 | + } | |
| 555 | 664 | } |