| @@ -31,12 +31,11 @@ | ||
| 31 | 31 | $this->process_bulk_action(); |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | public function column_default( $item, $column_name ) { |
| 35 | - return $item[ $column_name ]; | |
| 35 | + return $item[ $column_name ]; | |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | - // phpcs:disable WordPress.Security.NonceVerification.Recommended | |
| 39 | 38 | public function search_box( $text, $input_id ): void { |
| 40 | 39 | $input_id .= '-search-input'; |
| 41 | 40 | if ( ! empty( $_REQUEST['orderby'] ) ) { |
| 42 | 41 | $orderby = sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ); |
| @@ -41,9 +40,8 @@ | ||
| 41 | 40 | if ( ! empty( $_REQUEST['orderby'] ) ) { |
| 42 | 41 | $orderby = sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ); |
| 43 | 42 | echo '<input type="hidden" name="orderby" value="' . esc_attr( $orderby ) . '" />'; |
| 44 | 43 | } |
| 45 | - | |
| 46 | 44 | if ( ! empty( $_REQUEST['order'] ) ) { |
| 47 | 45 | $order = sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ); |
| 48 | 46 | echo '<input type="hidden" name="order" value="' . esc_attr( $order ) . '" />'; |
| 49 | 47 | } |
| @@ -58,10 +56,8 @@ | ||
| 58 | 56 | </p> |
| 59 | 57 | <?php |
| 60 | 58 | } |
| 61 | 59 | |
| 62 | - // phpcs:enable | |
| 63 | - | |
| 64 | 60 | public function column_title( $item ): string { |
| 65 | 61 | $title = ! empty( $item['title'] ) ? $item['title'] : __( 'Untitled', 'float-menu' ); |
| 66 | 62 | $param = DBManager::get_param_id( $item['ID'] ); |
| 67 | 63 | $actions = [ |
| @@ -181,14 +177,9 @@ | ||
| 181 | 177 | $link = add_query_arg( [ 'id' => $value->id ], $main_link ); |
| 182 | 178 | $data[] = array( |
| 183 | 179 | 'ID' => $value->id, |
| 184 | 180 | 'title' => '<a href="' . esc_url( $link ) . '">' . esc_attr( $title ) . '</a>', |
| 185 | - 'code' => '<div class="wpie-field"> | |
| 186 | - <label class="wpie-field__label has-icon"> | |
| 187 | - <span class="has-tooltip is-pointer on-right can-copy" data-tooltip="Copy"><span class="dashicons dashicons-shortcode is-pointer" ></span></span> | |
| 188 | - <input type="text" value="[' . esc_attr( $shortcode ) . ' id=\'' . absint( $value->id ) . '\']" readonly> | |
| 189 | - </label> | |
| 190 | - </div>', | |
| 181 | + 'code' => '<input type="text" value="[' . esc_attr( $shortcode ) . ' id=\'' . absint( $value->id ) . '\']" readonly>', | |
| 191 | 182 | 'tag' => $tag, |
| 192 | 183 | 'mode' => $mode, |
| 193 | 184 | 'status' => $status, |
| 194 | 185 | ); |
| @@ -201,9 +192,9 @@ | ||
| 201 | 192 | return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', 'ID', $item['ID'] ); |
| 202 | 193 | } |
| 203 | 194 | |
| 204 | 195 | public function get_paged(): int { |
| 205 | - return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 196 | + return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1; | |
| 206 | 197 | } |
| 207 | 198 | |
| 208 | 199 | public function get_search() { |
| 209 | 200 | $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' ); |
| @@ -211,11 +202,9 @@ | ||
| 211 | 202 | if ( ! $verify ) { |
| 212 | 203 | return false; |
| 213 | 204 | } |
| 214 | 205 | |
| 215 | - // phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verification is handled elsewhere. | |
| 216 | 206 | return ! empty( $_POST['s'] ) ? urldecode( trim( sanitize_text_field( wp_unslash( $_POST['s'] ) ) ) ) : false; |
| 217 | - // phpcs:enable | |
| 218 | 207 | } |
| 219 | 208 | |
| 220 | 209 | public function list_count(): int { |
| 221 | 210 | $result = $this->get_results(); |
| @@ -232,9 +221,8 @@ | ||
| 232 | 221 | global $wpdb; |
| 233 | 222 | |
| 234 | 223 | $search = $this->get_search(); |
| 235 | 224 | |
| 236 | - // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 237 | 225 | $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : ''; |
| 238 | 226 | $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search; |
| 239 | 227 | |
| 240 | 228 | |
| @@ -239,34 +227,27 @@ | ||
| 239 | 227 | |
| 240 | 228 | |
| 241 | 229 | $result = ''; |
| 242 | 230 | |
| 243 | - $table = esc_sql($wpdb->prefix . WOWP_Plugin::PREFIX); | |
| 231 | + $table = $wpdb->prefix . WOWP_Plugin::PREFIX; | |
| 244 | 232 | |
| 245 | - // Table name is sanitized elsewhere. | |
| 246 | 233 | if ( empty( $search ) ) { |
| 247 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 248 | 234 | $result = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY id DESC" ); |
| 249 | 235 | if ( ! empty( $tag_search ) ) { |
| 250 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 251 | 236 | $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE tag=%s ORDER BY id DESC", |
| 252 | 237 | $tag_search ) ); |
| 253 | 238 | } |
| 254 | 239 | } elseif ( trim( $search ) === 'UnTitle' ) { |
| 255 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 256 | 240 | $result = $wpdb->get_results( "SELECT * FROM {$table} WHERE title='' ORDER BY id DESC" ); |
| 257 | 241 | if ( ! empty( $tag_search ) ) { |
| 258 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 259 | 242 | $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title='' AND tag=%s ORDER BY id DESC", |
| 260 | 243 | $tag_search ) ); |
| 261 | 244 | } |
| 262 | 245 | } elseif ( is_numeric( $search ) ) { |
| 263 | 246 | if ( ! empty( $tag_search ) ) { |
| 264 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 265 | 247 | $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d AND tag=%s ORDER BY id DESC", |
| 266 | 248 | absint( $search ), $tag_search ) ); |
| 267 | 249 | } else { |
| 268 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 269 | 250 | $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE id=%d ORDER BY id DESC", |
| 270 | 251 | absint( $search ) ) ); |
| 271 | 252 | } |
| 272 | 253 | } else { |
| @@ -273,13 +254,11 @@ | ||
| 273 | 254 | $wild = '%'; |
| 274 | 255 | $find = sanitize_text_field( $search ); |
| 275 | 256 | $like = $wild . $wpdb->esc_like( $find ) . $wild; |
| 276 | 257 | if ( ! empty( $tag_search ) ) { |
| 277 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 278 | 258 | $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s AND tag=%s ORDER BY id DESC", |
| 279 | 259 | $like, $tag_search ) ); |
| 280 | 260 | } else { |
| 281 | - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 282 | 261 | $result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE title LIKE %s ORDER BY id DESC", |
| 283 | 262 | $like ) ); |
| 284 | 263 | } |
| 285 | 264 | } |
| @@ -289,9 +268,9 @@ | ||
| 289 | 268 | |
| 290 | 269 | |
| 291 | 270 | public function get_bulk_actions(): array { |
| 292 | 271 | $actions = [ |
| 293 | - 'delete' => __( 'Delete', 'float-menu' ), | |
| 272 | + 'delete' => __( 'Delate', 'float-menu' ), | |
| 294 | 273 | 'activate' => __( 'Activate', 'float-menu' ), |
| 295 | 274 | 'deactivate' => __( 'Deactivate', 'float-menu' ), |
| 296 | 275 | 'test_on' => __( 'Test mode ON', 'float-menu' ), |
| 297 | 276 | 'test_off' => __( 'Test mode OFF', 'float-menu' ), |
| @@ -300,14 +279,8 @@ | ||
| 300 | 279 | return $actions; |
| 301 | 280 | } |
| 302 | 281 | |
| 303 | 282 | public function process_bulk_action() { |
| 304 | - $verify = AdminActions::verify( WOWP_Plugin::PREFIX . '_list_action' ); | |
| 305 | - | |
| 306 | - if ( ! $verify ) { | |
| 307 | - return false; | |
| 308 | - } | |
| 309 | - // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 310 | 283 | $ids = isset( $_POST['ID'] ) ? ( map_deep( $_POST['ID'], 'absint' ) ) : false; |
| 311 | 284 | $action = $this->current_action(); |
| 312 | 285 | if ( ! is_array( $ids ) ) { |
| 313 | 286 | $ids = [ $ids ]; |
| @@ -315,8 +288,14 @@ | ||
| 315 | 288 | if ( empty( $action ) ) { |
| 316 | 289 | return false; |
| 317 | 290 | } |
| 318 | 291 | |
| 292 | + $verify = $this->verify(); | |
| 293 | + | |
| 294 | + if ( ! $verify ) { | |
| 295 | + return false; | |
| 296 | + } | |
| 297 | + | |
| 319 | 298 | foreach ( $ids as $id ) { |
| 320 | 299 | if ( 'delete' === $this->current_action() ) { |
| 321 | 300 | DBManager::delete( $id ); |
| 322 | 301 | } |
| @@ -338,10 +317,9 @@ | ||
| 338 | 317 | protected function extra_tablenav( $which ): void { |
| 339 | 318 | if ( 'top' === $which ) { |
| 340 | 319 | $tags = DBManager::get_tags_from_table(); |
| 341 | 320 | |
| 342 | - // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 343 | - $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['tag'] ) ) : ''; | |
| 321 | + $tag_search = ( ! empty( $_REQUEST['tag'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST ['tag'] ) ) : ''; | |
| 344 | 322 | $tag_search = ( $tag_search === 'all' ) ? '' : $tag_search; |
| 345 | 323 | |
| 346 | 324 | echo '<div class="alignleft actions"><label for="filter-by-tag" class="screen-reader-text">' . esc_html__( 'Filter by tag', |
| 347 | 325 | 'float-menu' ) . '</label>'; |
| @@ -364,24 +342,24 @@ | ||
| 364 | 342 | } |
| 365 | 343 | } |
| 366 | 344 | |
| 367 | 345 | private function sort_data( $a, $b ): int { |
| 368 | - // If no sort, default to ID | |
| 369 | - // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 370 | - $orderby = ( ! empty( $_GET['orderby'] ) ) ? sanitize_text_field( wp_unslash($_GET['orderby']) ) : 'ID'; | |
| 371 | - | |
| 372 | - // Only allow columns that are actually declared as sortable. | |
| 373 | - if ( ! array_key_exists( $orderby, $this->get_sortable_columns() ) ) { | |
| 374 | - $orderby = 'ID'; | |
| 375 | - } | |
| 376 | - | |
| 346 | + // If no sort, default to title | |
| 347 | + $orderby = ( ! empty( $_GET['orderby'] ) ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : 'ID'; | |
| 377 | 348 | // If no order, default to asc |
| 378 | - // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 379 | - $order = ( ! empty( $_GET['order'] ) ) ? sanitize_text_field( wp_unslash($_GET['order']) ) : 'desc'; | |
| 349 | + $order = ( ! empty( $_GET['order'] ) ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : 'desc'; | |
| 380 | 350 | // Determine sort order |
| 381 | - $result = strnatcmp( (string) ( $a[ $orderby ] ?? '' ), (string) ( $b[ $orderby ] ?? '' ) ); | |
| 351 | + $result = strnatcmp( $a[ $orderby ], $b[ $orderby ] ); | |
| 382 | 352 | |
| 383 | 353 | // Send final sort direction to usort |
| 384 | 354 | return ( $order === 'asc' ) ? $result : - $result; |
| 355 | + } | |
| 356 | + | |
| 357 | + private function verify(): bool { | |
| 358 | + $name = WOWP_Plugin::PREFIX . '_list_action'; | |
| 359 | + $nonce_action = WOWP_Plugin::PREFIX . '_nonce'; | |
| 360 | + | |
| 361 | + return ! ( ! isset( $_POST[ $name ] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $name ] ) ), | |
| 362 | + $nonce_action ) || ! current_user_can( 'manage_options' ) ); | |
| 385 | 363 | } |
| 386 | 364 | |
| 387 | 365 | } |