PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / trunk
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts vtrunk
2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 All 28 releases
← All changes | admin/includes/class.snippets.table.php +114 -52 2.4.4trunk View file →
@@ -1,13 +1,10 @@
1 1 <?php
2 2 /**
3 3 * This class is implemented page: snippet table
4 4 *
5 - * @author Webcraftic <wordpress.webraftic@gmail.com>
6 5 * @since 1.0.0
7 6 * @package core
8 - * @copyright (c) 2019, OnePress Ltd
9 - * s
10 7 */
11 8
12 9 // Exit if accessed directly
13 10 if ( ! defined( 'ABSPATH' ) ) {
@@ -14,13 +11,13 @@
14 11 exit;
15 12 }
16 13
17 14 if ( ! class_exists( 'WP_List_Table' ) ) {
18 - require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
15 + require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
19 16 }
20 17
21 18 /************************** CREATE A PACKAGE CLASS *****************************
22 - *******************************************************************************
19 + * ******************************************************************************
23 20 * Create a new list table package that extends the core WP_List_Table class.
24 21 * WP_List_Table contains most of the framework for generating the table, but we
25 22 * need to define and override some methods so that our data can be displayed
26 23 * exactly the way we need it to be.
@@ -63,9 +60,8 @@
63 60 /**
64 61 * @var array
65 62 *
66 63 * Array contains slug columns that you want hidden
67 - *
68 64 */
69 65 private $hidden_columns = [
70 66 'id',
71 67 ];
@@ -90,13 +86,15 @@
90 86 $this->modal = $modal;
91 87 $this->common = true;
92 88
93 89 // Set parent defaults
94 - parent::__construct( [
95 - 'singular' => 'snippet', // singular name of the listed records
96 - 'plural' => 'snippets', // plural name of the listed records
97 - 'ajax' => true, // does this table support ajax?
98 - ] );
90 + parent::__construct(
91 + [
92 + 'singular' => 'snippet', // singular name of the listed records
93 + 'plural' => 'snippets', // plural name of the listed records
94 + 'ajax' => true, // does this table support ajax?
95 + ]
96 + );
99 97 }
100 98
101 99 /** ************************************************************************
102 100 * Recommended. This method is called when the parent class can't find a method
@@ -151,24 +149,36 @@
151 149 * This example also illustrates how to implement rollover actions. Actions
152 150 * should be an associative array formatted as 'slug'=>'link html' - and you
153 151 * will need to generate the URLs yourself. You could even ensure the links
154 152 *
155 - *
156 153 * @param array $item A singular item (one full row's worth of data)
157 154 *
158 155 * @return string Text to be placed inside the column <td> (movie title only)
159 - **************************************************************************@see WP_List_Table::::single_row_columns()
156 + * *************************************************************************@see WP_List_Table::::single_row_columns()
160 157 */
161 158 public function column_title( $item ) {
162 - //Build row actions
163 - $actions = [/*'edit' => sprintf( '<a href="?page=%s&action=%s&movie=%s">Edit</a>', $_REQUEST['page'], 'edit', $item['ID'] ),
159 + // Build row actions
160 + $actions = [/*
161 + 'edit' => sprintf( '<a href="?page=%s&action=%s&movie=%s">Edit</a>', $_REQUEST['page'], 'edit', $item['ID'] ),
164 162 'delete' => sprintf( '<a href="?page=%s&action=%s&movie=%s">Delete</a>', $_REQUEST['page'], 'delete', $item['ID'] ),*/
165 163 ];
166 164
167 165 $url = admin_url() . 'post-new.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&winp_item=' . $item['type'] . '&snippet_id=' . $item['ID'] . ( $this->common ? '&common=1' : '' );
168 166
169 - //Return the title contents
170 - return sprintf( '<a href="%1$s"><b>%2$s</b></a>%3$s', /*$1%s*/ esc_url( $url ), /*$2%s*/ esc_html( $item['title'] ), /*$3%s*/ $this->row_actions( $actions ) );
167 + // Add premium badge if snippet is locked.
168 + $premium_badge = '';
169 + $is_locked = ! empty( $item['is_premium_locked'] );
170 +
171 + if ( $is_locked ) {
172 + $premium_badge = ' <span style="display:inline-block;background:#6366f1;color:#fff;font-size:11px;padding:2px 8px;border-radius:3px;font-weight:600;margin-left:6px;">PRO</span>';
173 + }
174 +
175 + // Return the title contents - no link for locked premium snippets.
176 + if ( $is_locked ) {
177 + return sprintf( '<b>%1$s</b>%2$s%3$s', /*$1%s*/ esc_html( $item['title'] ), /*$2%s*/ $premium_badge, /*$3%s*/ $this->row_actions( $actions ) );
178 + }
179 +
180 + return sprintf( '<a href="%1$s"><b>%2$s</b></a>%3$s%4$s', /*$1%s*/ esc_url( $url ), /*$2%s*/ esc_html( $item['title'] ), /*$3%s*/ $premium_badge, /*$4%s*/ $this->row_actions( $actions ) );
171 181 }
172 182
173 183 /** ************************************************************************
174 184 * REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column
@@ -177,13 +187,15 @@
177 187 *
178 188 * @param array $item A singular item (one full row's worth of data)
179 189 *
180 190 * @return string Text to be placed inside the column <td> (movie title only)
181 - **************************************************************************@see WP_List_Table::::single_row_columns()
191 + * *************************************************************************@see WP_List_Table::::single_row_columns()
182 192 */
183 193 public function column_cb( $item ) {
184 - return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', /*$1%s*/ esc_attr( $this->_args['singular'] ), //Let's simply repurpose the table's singular label ("movie")
185 - /*$2%s*/ esc_attr( $item['ID'] ) //The value of the checkbox should be the record's id
194 + return sprintf(
195 + '<input type="checkbox" name="%1$s[]" value="%2$s" />', /*$1%s*/
196 + esc_attr( $this->_args['singular'] ), // Let's simply repurpose the table's singular label ("movie")
197 + /*$2%s*/ esc_attr( $item['ID'] ) // The value of the checkbox should be the record's id
186 198 );
187 199 }
188 200
189 201 /** ************************************************************************
@@ -196,9 +208,9 @@
196 208 * column in your table you must create a column_cb() method. If you don't need
197 209 * bulk actions or checkboxes, simply leave the 'cb' entry out of your array.
198 210 *
199 211 * @return array An associative array containing column information: 'slugs'=>'Visible Titles'
200 - **************************************************************************@see WP_List_Table::::single_row_columns()
212 + * *************************************************************************@see WP_List_Table::::single_row_columns()
201 213 */
202 214 public function get_columns() {
203 215 $columns = [// 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
204 216 ];
@@ -235,9 +247,9 @@
235 247 * @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool)
236 248 **************************************************************************/
237 249 public function get_sortable_columns() {
238 250 $sortable_columns = [
239 - 'title' => [ 'title', false ], //true means it's already sorted
251 + 'title' => [ 'title', false ], // true means it's already sorted
240 252 'type' => [ 'type', false ],
241 253 'datetime' => [ 'datetime', false ],
242 254 ];
243 255
@@ -258,9 +270,9 @@
258 270 *
259 271 * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'
260 272 **************************************************************************/
261 273 public function get_bulk_actions() {
262 - $actions = [//'sync' => __( 'Synchronization', 'insert-php' ),
274 + $actions = [// 'sync' => __( 'Synchronization', 'insert-php' ),
263 275 ];
264 276
265 277 return $actions;
266 278 }
@@ -273,10 +285,11 @@
273 285 * @see $this->prepare_items()
274 286 **************************************************************************/
275 287 public function process_bulk_action() {
276 288
277 - //Detect when a bulk action is being triggered...
278 - /*if ( 'sync' === $this->current_action() ) {
289 + // Detect when a bulk action is being triggered...
290 + /*
291 + if ( 'sync' === $this->current_action() ) {
279 292 wp_die( 'Synchronization' );
280 293 }*/
281 294 }
282 295
@@ -288,9 +301,9 @@
288 301 * @return bool|string - если id сниппета не найден, то вернёт false
289 302 */
290 303 private function get_video_id( $video_link ) {
291 304 // youtube regex
292 - preg_match( "#([\/|\?|&]vi?[\/|=]|youtu\.be\/|embed\/)([a-zA-Z0-9_-]+)#", $video_link, $matches );
305 + preg_match( '#([\/|\?|&]vi?[\/|=]|youtu\.be\/|embed\/)([a-zA-Z0-9_-]+)#', $video_link, $matches );
293 306
294 307 return ! empty( $matches ) ? end( $matches ) : false;
295 308 }
296 309
@@ -302,11 +315,11 @@
302 315 public function get_data() {
303 316 $data = [];
304 317 $saved_data = [];
305 318
306 - $orderby = WINP_Plugin::app()->request->request( 'orderby', 'datetime', true );
307 - $order = WINP_Plugin::app()->request->request( 'order', 'desc', true );
308 - $paged = WINP_Plugin::app()->request->request( 'paged', 1, 'intval' );
319 + $orderby = WINP_HTTP::request( 'orderby', 'datetime', true );
320 + $order = WINP_HTTP::request( 'order', 'desc', true );
321 + $paged = WINP_HTTP::request( 'paged', 1, 'intval' );
309 322
310 323 $order_tags = [
311 324 'title' => 'title',
312 325 'type' => 'type_id',
@@ -322,16 +335,30 @@
322 335 $snippets = WINP_Plugin::app()->get_api_object()->get_all_snippets( $this->common, $args );
323 336
324 337 if ( ! empty( $snippets ) ) {
325 338 foreach ( (array) $snippets as $snippet ) {
339 + // Check if snippet is premium and user doesn't have license.
340 + $is_premium_locked = $this->common &&
341 + isset( $snippet->is_premium ) &&
342 + $snippet->is_premium &&
343 + ! WINP_Plugin::app()->get_api_object()->is_key();
344 +
345 + // Build Insert button - use different class for premium locked snippets.
346 + if ( $is_premium_locked ) {
347 + $insert_button = '<a class="wbcr-inp-premium-snippet-button button" href="javascript: void(0)" style="display:inline-flex;align-items:center;justify-content:center;"><span class="dashicons dashicons-plus"></span></a>';
348 + } else {
349 + $insert_button = '<a class="wbcr-inp-enable-snippet-button button" data-snippet="' . esc_attr( $snippet->id ) . '" data-common="' . ( $this->common ? 1 : 0 ) . '" href="javascript: void(0)" style="display:inline-flex;align-items:center;justify-content:center;"><span class="dashicons dashicons-plus"></span></a>';
350 + }
351 +
326 352 $_data = [
327 - 'ID' => (int) $snippet->id,
328 - 'title' => esc_html( $snippet->title ),
329 - 'desc' => esc_html( $snippet->description ),
330 - 'type' => $snippet->type->title,
331 - 'datetime' => date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $snippet->updated_at ),
332 - 'insert' => '<a class="wbcr-inp-enable-snippet-button button" data-snippet="' . esc_attr( $snippet->id ) . '" data-common="' . ( $this->common ? 1 : 0 ) . '" href="javascript: void(0)"><span class="dashicons dashicons-plus"></span></a>',
333 - 'delete' => '<a class="wbcr-inp-delete-snippet-button button" data-snippet="' . esc_attr( $snippet->id ) . '" href="javascript: void(0)"><span class="dashicons dashicons-no"></span></a>',
353 + 'ID' => (int) $snippet->id,
354 + 'title' => esc_html( $snippet->title ),
355 + 'desc' => esc_html( $snippet->description ),
356 + 'type' => $snippet->type->title,
357 + 'datetime' => gmdate( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $snippet->updated_at ),
358 + 'insert' => $insert_button,
359 + 'delete' => '<a class="wbcr-inp-delete-snippet-button button" data-snippet="' . esc_attr( $snippet->id ) . '" href="javascript: void(0)"><span class="dashicons dashicons-no"></span></a>',
360 + 'is_premium_locked' => $is_premium_locked,
334 361 ];
335 362
336 363 if ( $this->common ) {
337 364 $_data['preview'] = '';
@@ -339,9 +366,9 @@
339 366
340 367 $video_id = $this->get_video_id( $snippet->video_link );
341 368
342 369 if ( $video_id ) {
343 - $_data['preview'] = '<a class="thickbox" href="https://www.youtube.com/embed/' . esc_attr( $video_id ) . '?autoplay=1&rel=0&TB_iframe=true">' . '<img src="' . WINP_PLUGIN_URL . '/admin/assets/img/video.png" class="winp-library-image-preview" data-videoid="' . esc_attr( $video_id ) . '" alt="' . __( 'View the video', 'insert-php' ) . '">' . '</a>';
370 + $_data['preview'] = '<a class="thickbox" href="https://www.youtube.com/embed/' . esc_attr( $video_id ) . '?autoplay=1&rel=0&TB_iframe=true"><img src="' . WINP_PLUGIN_URL . '/admin/assets/img/video.png" class="winp-library-image-preview" data-videoid="' . esc_attr( $video_id ) . '" alt="' . __( 'Watch Tutorial Video', 'insert-php' ) . '"></a>';
344 371 }
345 372
346 373 $data[] = $_data;
347 374
@@ -354,9 +381,9 @@
354 381 'scope' => $snippet->execute_everywhere ? 'evrywhere' : 'shortcode',
355 382 ];
356 383 }
357 384
358 - update_user_meta( get_current_user_id(), WINP_Plugin::app()->getPrefix() . 'current_snippets', $saved_data );
385 + update_user_meta( get_current_user_id(), 'wbcr_inp_current_snippets', $saved_data );
359 386 }
360 387
361 388 return $data;
362 389 }
@@ -376,9 +403,9 @@
376 403 * get it ready to be displayed. At a minimum, we should set $this->items and
377 404 * $this->set_pagination_args(), although the following properties and methods
378 405 * are frequently interacted with here...
379 406 *
380 - * @param bool $common - если true, то выводить общие сниппеты без привязки к пользователю
407 + * @param bool $common - если true, то выводить общие сниппеты без привязки к пользователю
381 408 *
382 409 * @global WPDB $wpdb
383 410 * @uses $this->_column_headers
384 411 * @uses $this->items
@@ -445,9 +472,10 @@
445 472 * @param $a
446 473 * @param $b
447 474 *
448 475 * @return int
449 - */ /*function usort_reorder( $a, $b ) {
476 + */ /*
477 + function usort_reorder( $a, $b ) {
450 478 $orderby = ( ! empty( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : 'title'; // If no sort, default to title
451 479 $order = ( ! empty( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : 'asc'; // If no order, default to asc
452 480 $result = strcmp( $a[ $orderby ], $b[ $orderby ] ); // Determine sort order
453 481
@@ -466,9 +494,9 @@
466 494 * http://codex.wordpress.org/Class_Reference/wpdb
467 495 *
468 496 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
469 497 * ---------------------------------------------------------------------
470 - **********************************************************************/
498 + */
471 499
472 500 /**
473 501 * REQUIRED for pagination. Let's figure out what page the user is currently
474 502 * looking at. We'll need this later, so you should always include it in
@@ -497,15 +525,17 @@
497 525
498 526 /**
499 527 * REQUIRED. We also have to register our pagination options & calculations.
500 528 */
501 - $this->set_pagination_args( [
502 - 'total_items' => $total_items,
503 - 'per_page' => $this->per_page,
504 - 'total_pages' => ceil( $total_items / $this->per_page ),
505 - 'orderby' => WINP_Plugin::app()->request->request( 'orderby', 'title', true ),
506 - 'order' => WINP_Plugin::app()->request->request( 'order', 'asc', true ),
507 - ] );
529 + $this->set_pagination_args(
530 + [
531 + 'total_items' => $total_items,
532 + 'per_page' => $this->per_page,
533 + 'total_pages' => ceil( $total_items / $this->per_page ),
534 + 'orderby' => WINP_HTTP::request( 'orderby', 'title', true ),
535 + 'order' => WINP_HTTP::request( 'order', 'asc', true ),
536 + ]
537 + );
508 538 }
509 539
510 540 /**
511 541 * @Override of display method
@@ -527,8 +557,40 @@
527 557 */
528 558 echo '<input type="hidden" id="order" name="order" value="' . $this->_pagination_args['order'] . '" />';
529 559 echo '<input type="hidden" id="orderby" name="orderby" value="' . $this->_pagination_args['orderby'] . '" />';
530 560 parent::display();
561 +
562 + // Add premium upsell modal.
563 + if ( $this->common ) {
564 + ?>
565 + <div id="winp-premium-snippet-modal" style="display:none;">
566 + <div style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:100000;display:flex;align-items:center;justify-content:center;">
567 + <div style="background:#fff;border-radius:8px;padding:0;max-width:500px;width:90%;position:relative;">
568 + <button id="winp-modal-close" style="position:absolute;top:15px;right:15px;background:none;border:none;font-size:24px;cursor:pointer;color:#666;line-height:1;padding:0;width:30px;height:30px;">&times;</button>
569 + <div class="winp-upsell-container" style="margin:0;padding:0;">
570 + <div class="winp-upsell-card" style="box-shadow:none;">
571 + <div class="winp-upsell-icon">
572 + <span class="dashicons dashicons-star-filled"></span>
573 + </div>
574 + <div class="winp-upsell-title">
575 + <?php esc_html_e( 'Premium Snippet', 'insert-php' ); ?>
576 + </div>
577 + <p class="winp-upsell-badge">
578 + <?php esc_html_e( 'Pro feature', 'insert-php' ); ?>
579 + </p>
580 + <p class="winp-upsell-description">
581 + <?php esc_html_e( 'This is a premium snippet available only in the Pro version. Upgrade to unlock access to all premium code snippets and advanced features.', 'insert-php' ); ?>
582 + </p>
583 + <a href="<?php echo esc_url( tsdk_utmify( WINP_UPGRADE, 'snippet_library', 'premium_snippet_upsell' ) ); ?>" class="button button-primary button-large winp-upsell-button" target="_blank">
584 + <?php esc_html_e( 'Upgrade to Pro', 'insert-php' ); ?>
585 + </a>
586 + </div>
587 + </div>
588 + </div>
589 + </div>
590 + </div>
591 + <?php
592 + }
531 593 }
532 594
533 595 /**
534 596 * @Override ajax_response method
@@ -538,9 +600,9 @@
538 600 $this->prepare_items();
539 601 extract( $this->_args );
540 602 extract( $this->_pagination_args, EXTR_SKIP );
541 603 ob_start();
542 - $no_placeholder = WINP_Plugin::app()->request->request( 'no_placeholder', '' );
604 + $no_placeholder = WINP_HTTP::request( 'no_placeholder', '' );
543 605 if ( ! empty( $no_placeholder ) ) {
544 606 $this->display_rows();
545 607 } else {
546 608 $this->display_rows_or_placeholder();
@@ -559,9 +621,10 @@
559 621 $response['pagination']['top'] = $pagination_top;
560 622 $response['pagination']['bottom'] = $pagination_bottom;
561 623 $response['column_headers'] = $headers;
562 624 if ( isset( $total_items ) ) {
563 - $response['total_items_i18n'] = sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) );
625 + /* translators: %s: Number of items */
626 + $response['total_items_i18n'] = sprintf( _n( '%s item', '%s items', $total_items, 'insert-php' ), number_format_i18n( $total_items ) );
564 627 }
565 628 if ( isset( $total_pages ) ) {
566 629 $response['total_pages'] = $total_pages;
567 630 $response['total_pages_i18n'] = number_format_i18n( $total_pages );
@@ -567,6 +630,5 @@
567 630 $response['total_pages_i18n'] = number_format_i18n( $total_pages );
568 631 }
569 632 die( json_encode( $response ) );
570 633 }
571 -
572 -}
634 +}