1 <?php
  2 /**
  3  * Installation related functions and actions.
  4  *
  5  * @author      WooThemes
  6  * @category    Admin
  7  * @package     WooCommerce/Classes
  8  * @version     2.1.0
  9  */
 10 
 11 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 12 
 13 if ( ! class_exists( 'WC_Install' ) ) :
 14 
 15 /**
 16  * WC_Install Class
 17  */
 18 class WC_Install {
 19 
 20     /**
 21      * Hook in tabs.
 22      */
 23     public function __construct() {
 24         register_activation_hook( WC_PLUGIN_FILE, array( $this, 'install' ) );
 25 
 26         add_action( 'admin_init', array( $this, 'install_actions' ) );
 27         add_action( 'admin_init', array( $this, 'check_version' ), 5 );
 28         add_action( 'in_plugin_update_message-woocommerce/woocommerce.php', array( $this, 'in_plugin_update_message' ) );
 29     }
 30 
 31     /**
 32      * check_version function.
 33      *
 34      * @access public
 35      * @return void
 36      */
 37     public function check_version() {
 38         if ( ! defined( 'IFRAME_REQUEST' ) && ( get_option( 'woocommerce_version' ) != WC()->version || get_option( 'woocommerce_db_version' ) != WC()->version ) ) {
 39             $this->install();
 40 
 41             do_action( 'woocommerce_updated' );
 42         }
 43     }
 44 
 45     /**
 46      * Install actions such as installing pages when a button is clicked.
 47      */
 48     public function install_actions() {
 49         // Install - Add pages button
 50         if ( ! empty( $_GET['install_woocommerce_pages'] ) ) {
 51 
 52             self::create_pages();
 53 
 54             // We no longer need to install pages
 55             delete_option( '_wc_needs_pages' );
 56             delete_transient( '_wc_activation_redirect' );
 57 
 58             // What's new redirect
 59             wp_redirect( admin_url( 'index.php?page=wc-about&wc-installed=true' ) );
 60             exit;
 61 
 62         // Skip button
 63         } elseif ( ! empty( $_GET['skip_install_woocommerce_pages'] ) ) {
 64 
 65             // We no longer need to install pages
 66             delete_option( '_wc_needs_pages' );
 67             delete_transient( '_wc_activation_redirect' );
 68 
 69             // What's new redirect
 70             wp_redirect( admin_url( 'index.php?page=wc-about' ) );
 71             exit;
 72 
 73         // Update button
 74         } elseif ( ! empty( $_GET['do_update_woocommerce'] ) ) {
 75 
 76             $this->update();
 77 
 78             // Update complete
 79             delete_option( '_wc_needs_pages' );
 80             delete_option( '_wc_needs_update' );
 81             delete_transient( '_wc_activation_redirect' );
 82 
 83             // What's new redirect
 84             wp_redirect( admin_url( 'index.php?page=wc-about&wc-updated=true' ) );
 85             exit;
 86         }
 87     }
 88 
 89     /**
 90      * Install WC
 91      */
 92     public function install() {
 93         $this->create_options();
 94         $this->create_tables();
 95         $this->create_roles();
 96 
 97         // Register post types
 98         include_once( 'class-wc-post-types.php' );
 99         WC_Post_types::register_post_types();
100         WC_Post_types::register_taxonomies();
101 
102         // Also register endpoints - this needs to be done prior to rewrite rule flush
103         WC()->query->init_query_vars();
104         WC()->query->add_endpoints();
105 
106         $this->create_terms();
107         $this->create_cron_jobs();
108         $this->create_files();
109         $this->create_css_from_less();
110 
111         // Clear transient cache
112         wc_delete_product_transients();
113 
114         // Queue upgrades
115         $current_version = get_option( 'woocommerce_version', null );
116         $current_db_version = get_option( 'woocommerce_db_version', null );
117 
118         if ( version_compare( $current_db_version, '2.1.0', '<' ) && null !== $current_db_version ) {
119             update_option( '_wc_needs_update', 1 );
120         } else {
121             update_option( 'woocommerce_db_version', WC()->version );
122         }
123 
124         // Update version
125         update_option( 'woocommerce_version', WC()->version );
126 
127         // Check if pages are needed
128         if ( wc_get_page_id( 'shop' ) < 1 ) {
129             update_option( '_wc_needs_pages', 1 );
130         }
131 
132         // Flush rules after install
133         flush_rewrite_rules();
134 
135         // Redirect to welcome screen
136         set_transient( '_wc_activation_redirect', 1, 60 * 60 );
137     }
138 
139     /**
140      * Handle updates
141      */
142     public function update() {
143         // Do updates
144         $current_db_version = get_option( 'woocommerce_db_version' );
145 
146         if ( version_compare( $current_db_version, '1.4', '<' ) ) {
147             include( 'updates/woocommerce-update-1.4.php' );
148             update_option( 'woocommerce_db_version', '1.4' );
149         }
150 
151         if ( version_compare( $current_db_version, '1.5', '<' ) ) {
152             include( 'updates/woocommerce-update-1.5.php' );
153             update_option( 'woocommerce_db_version', '1.5' );
154         }
155 
156         if ( version_compare( $current_db_version, '2.0', '<' ) ) {
157             include( 'updates/woocommerce-update-2.0.php' );
158             update_option( 'woocommerce_db_version', '2.0' );
159         }
160 
161         if ( version_compare( $current_db_version, '2.0.9', '<' ) ) {
162             include( 'updates/woocommerce-update-2.0.9.php' );
163             update_option( 'woocommerce_db_version', '2.0.9' );
164         }
165 
166         if ( version_compare( $current_db_version, '2.0.14', '<' ) ) {
167             if ( 'HU' == get_option( 'woocommerce_default_country' ) ) {
168                 update_option( 'woocommerce_default_country', 'HU:BU' );
169             }
170 
171             update_option( 'woocommerce_db_version', '2.0.14' );
172         }
173 
174         if ( version_compare( $current_db_version, '2.1.0', '<' ) || WC_VERSION == '2.1-bleeding' ) {
175             include( 'updates/woocommerce-update-2.1.php' );
176             update_option( 'woocommerce_db_version', '2.1.0' );
177         }
178 
179         update_option( 'woocommerce_db_version', WC()->version );
180     }
181 
182     /**
183      * Create cron jobs (clear them first)
184      */
185     private function create_cron_jobs() {
186         // Cron jobs
187         wp_clear_scheduled_hook( 'woocommerce_scheduled_sales' );
188         wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
189         wp_clear_scheduled_hook( 'woocommerce_cleanup_sessions' );
190 
191         $ve = get_option( 'gmt_offset' ) > 0 ? '+' : '-';
192 
193         wp_schedule_event( strtotime( '00:00 tomorrow ' . $ve . get_option( 'gmt_offset' ) . ' HOURS' ), 'daily', 'woocommerce_scheduled_sales' );
194 
195         $held_duration = get_option( 'woocommerce_hold_stock_minutes', null );
196 
197         if ( is_null( $held_duration ) ) {
198             $held_duration = '60';
199         }
200 
201         if ( $held_duration != '' ) {
202             wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
203         }
204 
205         wp_schedule_event( time(), 'twicedaily', 'woocommerce_cleanup_sessions' );
206     }
207 
208     /**
209      * Create pages that the plugin relies on, storing page id's in variables.
210      *
211      * @access public
212      * @return void
213      */
214     public static function create_pages() {
215         $pages = apply_filters( 'woocommerce_create_pages', array(
216             'shop' => array(
217                 'name'    => _x( 'shop', 'Page slug', 'woocommerce' ),
218                 'title'   => _x( 'Shop', 'Page title', 'woocommerce' ),
219                 'content' => ''
220             ),
221             'cart' => array(
222                 'name'    => _x( 'cart', 'Page slug', 'woocommerce' ),
223                 'title'   => _x( 'Cart', 'Page title', 'woocommerce' ),
224                 'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']'
225             ),
226             'checkout' => array(
227                 'name'    => _x( 'checkout', 'Paeg slug', 'woocommerce' ),
228                 'title'   => _x( 'Checkout', 'Page title', 'woocommerce' ),
229                 'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']'
230             ),
231             'myaccount' => array(
232                 'name'    => _x( 'my-account', 'Page slug', 'woocommerce' ),
233                 'title'   => _x( 'My Account', 'Page title', 'woocommerce' ),
234                 'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']'
235             )
236         ) );
237 
238         foreach ( $pages as $key => $page ) {
239             wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' );
240         }
241     }
242 
243     /**
244      * Add the default terms for WC taxonomies - product types and order statuses. Modify this at your own risk.
245      *
246      * @access public
247      * @return void
248      */
249     private function create_terms() {
250 
251         $taxonomies = array(
252             'product_type' => array(
253                 'simple',
254                 'grouped',
255                 'variable',
256                 'external'
257             ),
258             'shop_order_status' => array(
259                 'pending',
260                 'failed',
261                 'on-hold',
262                 'processing',
263                 'completed',
264                 'refunded',
265                 'cancelled'
266             )
267         );
268 
269         foreach ( $taxonomies as $taxonomy => $terms ) {
270             foreach ( $terms as $term ) {
271                 if ( ! get_term_by( 'slug', sanitize_title( $term ), $taxonomy ) ) {
272                     wp_insert_term( $term, $taxonomy );
273                 }
274             }
275         }
276     }
277 
278     /**
279      * Default options
280      *
281      * Sets up the default options used on the settings page
282      *
283      * @access public
284      */
285     function create_options() {
286         // Include settings so that we can run through defaults
287         include_once( 'admin/class-wc-admin-settings.php' );
288 
289         $settings = WC_Admin_Settings::get_settings_pages();
290 
291         foreach ( $settings as $section ) {
292             foreach ( $section->get_settings() as $value ) {
293                 if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
294                     $autoload = isset( $value['autoload'] ) ? (bool) $value['autoload'] : true;
295                     add_option( $value['id'], $value['default'], '', ( $autoload ? 'yes' : 'no' ) );
296                 }
297             }
298 
299             // Special case to install the inventory settings.
300             if ( $section instanceof WC_Settings_Products ) {
301                 foreach ( $section->get_settings( 'inventory' ) as $value ) {
302                     if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
303                         $autoload = isset( $value['autoload'] ) ? (bool) $value['autoload'] : true;
304                         add_option( $value['id'], $value['default'], '', ( $autoload ? 'yes' : 'no' ) );
305                     }
306                 }
307             }
308         }
309     }
310 
311     /**
312      * Set up the database tables which the plugin needs to function.
313      *
314      * Tables:
315      *      woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined
316      *      woocommerce_termmeta - Term meta table - sadly WordPress does not have termmeta so we need our own
317      *      woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions.
318      *          KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page
319      *      woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports
320      *      woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data.
321      *      woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient.
322      *      woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table.
323      *
324      * @access public
325      * @return void
326      */
327     private function create_tables() {
328         global $wpdb, $woocommerce;
329 
330         $wpdb->hide_errors();
331 
332         $collate = '';
333 
334         if ( $wpdb->has_cap( 'collation' ) ) {
335             if ( ! empty($wpdb->charset ) ) {
336                 $collate .= "DEFAULT CHARACTER SET $wpdb->charset";
337             }
338             if ( ! empty($wpdb->collate ) ) {
339                 $collate .= " COLLATE $wpdb->collate";
340             }
341         }
342 
343         require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
344 
345         /**
346          * Update schemas before DBDELTA
347          *
348          * Before updating, remove any primary keys which could be modified due to schema updates
349          */
350         if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_downloadable_product_permissions';" ) ) {
351             if ( ! $wpdb->get_var( "SHOW COLUMNS FROM `{$wpdb->prefix}woocommerce_downloadable_product_permissions` LIKE 'permission_id';" ) ) {
352                 $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions DROP PRIMARY KEY, ADD `permission_id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT;" );
353             }
354         }
355 
356         // WooCommerce Tables
357         $woocommerce_tables = "
358     CREATE TABLE {$wpdb->prefix}woocommerce_attribute_taxonomies (
359       attribute_id bigint(20) NOT NULL auto_increment,
360       attribute_name varchar(200) NOT NULL,
361       attribute_label longtext NULL,
362       attribute_type varchar(200) NOT NULL,
363       attribute_orderby varchar(200) NOT NULL,
364       PRIMARY KEY  (attribute_id),
365       KEY attribute_name (attribute_name)
366     ) $collate;
367     CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
368       meta_id bigint(20) NOT NULL auto_increment,
369       woocommerce_term_id bigint(20) NOT NULL,
370       meta_key varchar(255) NULL,
371       meta_value longtext NULL,
372       PRIMARY KEY  (meta_id),
373       KEY woocommerce_term_id (woocommerce_term_id),
374       KEY meta_key (meta_key)
375     ) $collate;
376     CREATE TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions (
377       permission_id bigint(20) NOT NULL auto_increment,
378       download_id varchar(32) NOT NULL,
379       product_id bigint(20) NOT NULL,
380       order_id bigint(20) NOT NULL DEFAULT 0,
381       order_key varchar(200) NOT NULL,
382       user_email varchar(200) NOT NULL,
383       user_id bigint(20) NULL,
384       downloads_remaining varchar(9) NULL,
385       access_granted datetime NOT NULL default '0000-00-00 00:00:00',
386       access_expires datetime NULL default null,
387       download_count bigint(20) NOT NULL DEFAULT 0,
388       PRIMARY KEY  (permission_id),
389       KEY download_order_key_product (product_id,order_id,order_key,download_id),
390       KEY download_order_product (download_id,order_id,product_id)
391     ) $collate;
392     CREATE TABLE {$wpdb->prefix}woocommerce_order_items (
393       order_item_id bigint(20) NOT NULL auto_increment,
394       order_item_name longtext NOT NULL,
395       order_item_type varchar(200) NOT NULL DEFAULT '',
396       order_id bigint(20) NOT NULL,
397       PRIMARY KEY  (order_item_id),
398       KEY order_id (order_id)
399     ) $collate;
400     CREATE TABLE {$wpdb->prefix}woocommerce_order_itemmeta (
401       meta_id bigint(20) NOT NULL auto_increment,
402       order_item_id bigint(20) NOT NULL,
403       meta_key varchar(255) NULL,
404       meta_value longtext NULL,
405       PRIMARY KEY  (meta_id),
406       KEY order_item_id (order_item_id),
407       KEY meta_key (meta_key)
408     ) $collate;
409     CREATE TABLE {$wpdb->prefix}woocommerce_tax_rates (
410       tax_rate_id bigint(20) NOT NULL auto_increment,
411       tax_rate_country varchar(200) NOT NULL DEFAULT '',
412       tax_rate_state varchar(200) NOT NULL DEFAULT '',
413       tax_rate varchar(200) NOT NULL DEFAULT '',
414       tax_rate_name varchar(200) NOT NULL DEFAULT '',
415       tax_rate_priority bigint(20) NOT NULL,
416       tax_rate_compound int(1) NOT NULL DEFAULT 0,
417       tax_rate_shipping int(1) NOT NULL DEFAULT 1,
418       tax_rate_order bigint(20) NOT NULL,
419       tax_rate_class varchar(200) NOT NULL DEFAULT '',
420       PRIMARY KEY  (tax_rate_id),
421       KEY tax_rate_country (tax_rate_country),
422       KEY tax_rate_state (tax_rate_state),
423       KEY tax_rate_class (tax_rate_class),
424       KEY tax_rate_priority (tax_rate_priority)
425     ) $collate;
426     CREATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations (
427       location_id bigint(20) NOT NULL auto_increment,
428       location_code varchar(255) NOT NULL,
429       tax_rate_id bigint(20) NOT NULL,
430       location_type varchar(40) NOT NULL,
431       PRIMARY KEY  (location_id),
432       KEY tax_rate_id (tax_rate_id),
433       KEY location_type (location_type),
434       KEY location_type_code (location_type,location_code)
435     ) $collate;
436     ";
437         dbDelta( $woocommerce_tables );
438     }
439 
440     /**
441      * Create roles and capabilities
442      */
443     public function create_roles() {
444         global $wp_roles;
445 
446         if ( class_exists( 'WP_Roles' ) ) {
447             if ( ! isset( $wp_roles ) ) {
448                 $wp_roles = new WP_Roles();
449             }
450         }
451 
452         if ( is_object( $wp_roles ) ) {
453 
454             // Customer role
455             add_role( 'customer', __( 'Customer', 'woocommerce' ), array(
456                 'read'                      => true,
457                 'edit_posts'                => false,
458                 'delete_posts'              => false
459             ) );
460 
461             // Shop manager role
462             add_role( 'shop_manager', __( 'Shop Manager', 'woocommerce' ), array(
463                 'level_9'                => true,
464                 'level_8'                => true,
465                 'level_7'                => true,
466                 'level_6'                => true,
467                 'level_5'                => true,
468                 'level_4'                => true,
469                 'level_3'                => true,
470                 'level_2'                => true,
471                 'level_1'                => true,
472                 'level_0'                => true,
473                 'read'                   => true,
474                 'read_private_pages'     => true,
475                 'read_private_posts'     => true,
476                 'edit_users'             => true,
477                 'edit_posts'             => true,
478                 'edit_pages'             => true,
479                 'edit_published_posts'   => true,
480                 'edit_published_pages'   => true,
481                 'edit_private_pages'     => true,
482                 'edit_private_posts'     => true,
483                 'edit_others_posts'      => true,
484                 'edit_others_pages'      => true,
485                 'publish_posts'          => true,
486                 'publish_pages'          => true,
487                 'delete_posts'           => true,
488                 'delete_pages'           => true,
489                 'delete_private_pages'   => true,
490                 'delete_private_posts'   => true,
491                 'delete_published_pages' => true,
492                 'delete_published_posts' => true,
493                 'delete_others_posts'    => true,
494                 'delete_others_pages'    => true,
495                 'manage_categories'      => true,
496                 'manage_links'           => true,
497                 'moderate_comments'      => true,
498                 'unfiltered_html'        => true,
499                 'upload_files'           => true,
500                 'export'                 => true,
501                 'import'                 => true,
502                 'list_users'             => true
503             ) );
504 
505             $capabilities = $this->get_core_capabilities();
506 
507             foreach ( $capabilities as $cap_group ) {
508                 foreach ( $cap_group as $cap ) {
509                     $wp_roles->add_cap( 'shop_manager', $cap );
510                     $wp_roles->add_cap( 'administrator', $cap );
511                 }
512             }
513         }
514     }
515 
516     /**
517      * Get capabilities for WooCommerce - these are assigned to admin/shop manager during installation or reset
518      *
519      * @access public
520      * @return array
521      */
522     public function get_core_capabilities() {
523         $capabilities = array();
524 
525         $capabilities['core'] = array(
526             'manage_woocommerce',
527             'view_woocommerce_reports'
528         );
529 
530         $capability_types = array( 'product', 'shop_order', 'shop_coupon' );
531 
532         foreach ( $capability_types as $capability_type ) {
533 
534             $capabilities[ $capability_type ] = array(
535                 // Post type
536                 "edit_{$capability_type}",
537                 "read_{$capability_type}",
538                 "delete_{$capability_type}",
539                 "edit_{$capability_type}s",
540                 "edit_others_{$capability_type}s",
541                 "publish_{$capability_type}s",
542                 "read_private_{$capability_type}s",
543                 "delete_{$capability_type}s",
544                 "delete_private_{$capability_type}s",
545                 "delete_published_{$capability_type}s",
546                 "delete_others_{$capability_type}s",
547                 "edit_private_{$capability_type}s",
548                 "edit_published_{$capability_type}s",
549 
550                 // Terms
551                 "manage_{$capability_type}_terms",
552                 "edit_{$capability_type}_terms",
553                 "delete_{$capability_type}_terms",
554                 "assign_{$capability_type}_terms"
555             );
556         }
557 
558         return $capabilities;
559     }
560 
561     /**
562      * woocommerce_remove_roles function.
563      *
564      * @access public
565      * @return void
566      */
567     public function remove_roles() {
568         global $wp_roles;
569 
570         if ( class_exists( 'WP_Roles' ) ) {
571             if ( ! isset( $wp_roles ) ) {
572                 $wp_roles = new WP_Roles();
573             }
574         }
575 
576         if ( is_object( $wp_roles ) ) {
577 
578             $capabilities = $this->get_core_capabilities();
579 
580             foreach ( $capabilities as $cap_group ) {
581                 foreach ( $cap_group as $cap ) {
582                     $wp_roles->remove_cap( 'shop_manager', $cap );
583                     $wp_roles->remove_cap( 'administrator', $cap );
584                 }
585             }
586 
587             remove_role( 'customer' );
588             remove_role( 'shop_manager' );
589         }
590     }
591 
592     /**
593      * Create files/directories
594      */
595     private function create_files() {
596         // Install files and folders for uploading files and prevent hotlinking
597         $upload_dir =  wp_upload_dir();
598 
599         $files = array(
600             array(
601                 'base'      => $upload_dir['basedir'] . '/woocommerce_uploads',
602                 'file'      => '.htaccess',
603                 'content'   => 'deny from all'
604             ),
605             array(
606                 'base'      => $upload_dir['basedir'] . '/woocommerce_uploads',
607                 'file'      => 'index.html',
608                 'content'   => ''
609             ),
610             array(
611                 'base'      => WP_PLUGIN_DIR . "/" . plugin_basename( dirname( dirname( __FILE__ ) ) ) . '/logs',
612                 'file'      => '.htaccess',
613                 'content'   => 'deny from all'
614             ),
615             array(
616                 'base'      => WP_PLUGIN_DIR . "/" . plugin_basename( dirname( dirname( __FILE__ ) ) ) . '/logs',
617                 'file'      => 'index.html',
618                 'content'   => ''
619             )
620         );
621 
622         foreach ( $files as $file ) {
623             if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
624                 if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
625                     fwrite( $file_handle, $file['content'] );
626                     fclose( $file_handle );
627                 }
628             }
629         }
630     }
631 
632     /**
633      * Create CSS from LESS file
634      */
635     private function create_css_from_less() {
636         // Recompile LESS styles if they are custom
637         $colors = get_option( 'woocommerce_frontend_css_colors' );
638 
639         if ( ( ! empty( $colors['primary'] ) && ! empty( $colors['secondary'] ) && ! empty( $colors['highlight'] ) && ! empty( $colors['content_bg'] ) && ! empty( $colors['subtext'] ) ) && ( $colors['primary'] != '#ad74a2' || $colors['secondary'] != '#f7f6f7' || $colors['highlight'] != '#85ad74' || $colors['content_bg'] != '#ffffff' || $colors['subtext'] != '#777777' ) ) {
640             if ( ! function_exists( 'woocommerce_compile_less_styles' ) ) {
641                 include_once( 'admin/wc-admin-functions.php' );
642             }
643             woocommerce_compile_less_styles();
644         }
645     }
646 
647     /**
648      * Active plugins pre update option filter
649      *
650      * @param string $new_value
651      * @return string
652      */
653     function pre_update_option_active_plugins( $new_value ) {
654         $old_value = (array) get_option( 'active_plugins' );
655 
656         if ( $new_value !== $old_value && in_array( W3TC_FILE, (array) $new_value ) && in_array( W3TC_FILE, (array) $old_value ) ) {
657             $this->_config->set( 'notes.plugins_updated', true );
658             try {
659                 $this->_config->save();
660             } catch( Exception $ex ) {}
661         }
662 
663         return $new_value;
664     }
665 
666     /**
667      * Show plugin changes. Code adapted from W3 Total Cache.
668      *
669      * @return void
670      */
671     function in_plugin_update_message( $args ) {
672         $transient_name = 'wc_upgrade_notice_' . $args['Version'];
673 
674         if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
675 
676             $response = wp_remote_get( 'https://plugins.svn.wordpress.org/woocommerce/trunk/readme.txt' );
677 
678             if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
679 
680                 // Output Upgrade Notice
681                 $matches        = null;
682                 $regexp         = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( WC_VERSION ) . '\s*=|$)~Uis';
683                 $upgrade_notice = '';
684 
685                 if ( preg_match( $regexp, $response['body'], $matches ) ) {
686                     $version        = trim( $matches[1] );
687                     $notices        = (array) preg_split('~[\r\n]+~', trim( $matches[2] ) );
688                     
689                     if ( version_compare( WC_VERSION, $version, '<' ) ) {
690 
691                         $upgrade_notice .= '<div class="wc_plugin_upgrade_notice">';
692 
693                         foreach ( $notices as $index => $line ) {
694                             $upgrade_notice .= wp_kses_post( preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line ) );
695                         }
696 
697                         $upgrade_notice .= '</div> ';
698                     }
699                 }
700 
701                 set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
702             }
703         }
704 
705         echo wp_kses_post( $upgrade_notice );
706     }
707 }
708 
709 endif;
710 
711 return new WC_Install();
712 
WooCommerce API documentation generated by ApiGen 2.8.0