is_woocommerce_activated() ) { return; } $version_setting = 'wpo_wcpdf_version'; $installed_version = get_option( $version_setting ); // installed version lower than plugin version? if ( version_compare( $installed_version, WPO_WCPDF_VERSION, '<' ) ) { if ( ! $installed_version ) { try { $this->install(); } catch ( \Throwable $th ) { wcpdf_log_error( sprintf( "Plugin install procedure failed (version %s): %s", WPO_WCPDF_VERSION, $th->getMessage() ), 'critical', $th ); } } else { try { $this->upgrade( $installed_version ); } catch ( \Throwable $th ) { wcpdf_log_error( sprintf( "Plugin upgrade procedure failed (updating from version %s to %s): %s", $installed_version, WPO_WCPDF_VERSION, $th->getMessage() ), 'critical', $th ); } } // new version number update_option( $version_setting, WPO_WCPDF_VERSION ); } elseif ( $installed_version && version_compare( $installed_version, WPO_WCPDF_VERSION, '>' ) ) { try { $this->downgrade( $installed_version ); } catch ( \Throwable $th ) { wcpdf_log_error( sprintf( "Plugin downgrade procedure failed (downgrading from version %s to %s): %s", $installed_version, WPO_WCPDF_VERSION, $th->getMessage() ), 'critical', $th ); } // downgrade version number update_option( $version_setting, WPO_WCPDF_VERSION ); } // deactivate legacy addons add_action( 'admin_init', array( WPO_WCPDF(), 'deactivate_legacy_addons') ); } /** * Plugin install method. Perform any installation tasks here */ protected function install() { // only install when php version or higher if ( ! WPO_WCPDF()->is_dependency_version_supported( 'php' ) ) { return; } // check if upgrading from versionless (1.4.14 and older) if ( get_option( 'wpo_wcpdf_general_settings' ) ) { $this->upgrade( 'versionless' ); return; } // Get tmp folders $tmp_base = WPO_WCPDF()->main->get_tmp_base(); // check if tmp folder exists => if not, initialize if ( ! @is_dir( $tmp_base ) || ! wp_is_writable( $tmp_base ) ) { WPO_WCPDF()->main->init_tmp(); } // Unsupported currency symbols $unsupported_symbols = array ( 'AED', 'AFN', 'BDT', 'BHD', 'BTC', 'CRC', 'DZD', 'GEL', 'GHS', 'ILS', 'INR', 'IQD', 'IRR', 'IRT', 'JOD', 'KHR', 'KPW', 'KRW', 'KWD', 'LAK', 'LBP', 'LKR', 'LYD', 'MAD', 'MNT', 'MUR', 'MVR', 'NPR', 'OMR', 'PHP', 'PKR', 'PYG', 'QAR', 'RUB', 'SAR', 'SCR', 'SDG', 'SYP', 'THB', 'TND', 'TRY', 'UAH', 'YER', ); // set default settings $settings_defaults = array( 'wpo_wcpdf_settings_general' => array( 'download_display' => 'display', 'template_path' => WPO_WCPDF()->plugin_path() . '/templates/Simple', 'currency_font' => ( in_array( get_woocommerce_currency(), $unsupported_symbols ) ) ? 1 : '', 'paper_size' => 'a4', // 'header_logo' => '', // 'shop_name' => array(), // 'shop_address' => array(), // 'footer' => array(), // 'extra_1' => array(), // 'extra_2' => array(), // 'extra_3' => array(), ), 'wpo_wcpdf_documents_settings_invoice' => array( 'enabled' => 1, // 'attach_to_email_ids' => array(), // 'display_shipping_address' => '', // 'display_email' => '', // 'display_phone' => '', // 'display_date' => '', // 'display_number' => '', // 'number_format' => array(), // 'reset_number_yearly' => '', // 'my_account_buttons' => '', // 'invoice_number_column' => '', // 'invoice_date_column' => '', // 'disable_free' => '', ), 'wpo_wcpdf_documents_settings_packing-slip' => array( 'enabled' => 1, // 'display_billing_address' => '', // 'display_email' => '', // 'display_phone' => '', ), 'wpo_wcpdf_settings_debug' => array( // 'legacy_mode' => '', // 'enable_debug' => '', // 'html_output' => '', // 'html_output' => '', 'enable_cleanup' => 1, 'cleanup_days' => 7, ), ); foreach ($settings_defaults as $option => $defaults) { add_option( $option, $defaults ); } // set transient for wizard notification set_transient( 'wpo_wcpdf_new_install', 'yes', DAY_IN_SECONDS * 2 ); // schedule the yearly reset number action if ( ! empty( WPO_WCPDF()->settings ) && is_callable( array( WPO_WCPDF()->settings, 'schedule_yearly_reset_numbers' ) ) ) { WPO_WCPDF()->settings->schedule_yearly_reset_numbers(); } } /** * Plugin upgrade method. Perform any required upgrades here * * @param string $installed_version the currently installed ('old') version */ protected function upgrade( $installed_version ) { // only upgrade when php version or higher if ( ! WPO_WCPDF()->is_dependency_version_supported( 'php' ) ) { return; } // sync fonts on every upgrade! $tmp_base = WPO_WCPDF()->main->get_tmp_base(); // get fonts folder path $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' ); // check if tmp folder exists => if not, initialize if ( ! @is_dir( $tmp_base ) || ! wp_is_writable( $tmp_base ) || ! @is_dir( $font_path ) || ! wp_is_writable( $font_path ) ) { WPO_WCPDF()->main->init_tmp(); } else { // don't try merging fonts with local when updating pre 2.0 $pre_2 = ( $installed_version == 'versionless' || version_compare( $installed_version, '2.0-dev', '<' ) ); $merge_with_local = !$pre_2; WPO_WCPDF()->main->copy_fonts( $font_path, $merge_with_local ); } // to ensure fonts will be copied to the upload directory delete_transient( 'wpo_wcpdf_subfolder_fonts_has_files' ); // 1.5.28 update: copy next invoice number to separate setting if ( $installed_version == 'versionless' || version_compare( $installed_version, '1.5.28', '<' ) ) { $template_settings = get_option( 'wpo_wcpdf_template_settings' ); $next_invoice_number = isset($template_settings['next_invoice_number'])?$template_settings['next_invoice_number']:''; update_option( 'wpo_wcpdf_next_invoice_number', $next_invoice_number ); } // 2.0-dev update: reorganize settings if ( $installed_version == 'versionless' || version_compare( $installed_version, '2.0-dev', '<' ) ) { $old_settings = array( 'wpo_wcpdf_general_settings' => get_option( 'wpo_wcpdf_general_settings' ), 'wpo_wcpdf_template_settings' => get_option( 'wpo_wcpdf_template_settings' ), 'wpo_wcpdf_debug_settings' => get_option( 'wpo_wcpdf_debug_settings' ), ); // combine invoice number formatting in array $old_settings['wpo_wcpdf_template_settings']['invoice_number_formatting'] = array(); $format_option_keys = array('padding','suffix','prefix'); foreach ($format_option_keys as $format_option_key) { if (isset($old_settings['wpo_wcpdf_template_settings']["invoice_number_formatting_{$format_option_key}"])) { $old_settings['wpo_wcpdf_template_settings']['invoice_number_formatting'][$format_option_key] = $old_settings['wpo_wcpdf_template_settings']["invoice_number_formatting_{$format_option_key}"]; } } // convert abbreviated email_ids if (isset($old_settings['wpo_wcpdf_general_settings']['email_pdf'])) { foreach ($old_settings['wpo_wcpdf_general_settings']['email_pdf'] as $email_id => $value) { if ($email_id == 'completed' || $email_id == 'processing') { $old_settings['wpo_wcpdf_general_settings']['email_pdf']["customer_{$email_id}_order"] = $value; unset($old_settings['wpo_wcpdf_general_settings']['email_pdf'][$email_id]); } } } // Migrate template path // forward slash for consistency/compatibility if ( ! empty( $old_settings['wpo_wcpdf_template_settings']['template_path'] ) ) { $template_path = str_replace( '\\', '/', $old_settings['wpo_wcpdf_template_settings']['template_path'] ); // strip abspath (forward slashed) if included $template_path = str_replace( str_replace('\\','/', ABSPATH), '', $template_path ); // strip pdf subfolder from templates path $template_path = str_replace( '/templates/pdf/', '/templates/', $template_path ); $old_settings['wpo_wcpdf_template_settings']['template_path'] = $template_path; } // map new settings to old $settings_map = array( 'wpo_wcpdf_settings_general' => array( 'download_display' => array( 'wpo_wcpdf_general_settings' => 'download_display' ), 'template_path' => array( 'wpo_wcpdf_template_settings' => 'template_path' ), 'currency_font' => array( 'wpo_wcpdf_template_settings' => 'currency_font' ), 'paper_size' => array( 'wpo_wcpdf_template_settings' => 'paper_size' ), 'header_logo' => array( 'wpo_wcpdf_template_settings' => 'header_logo' ), 'shop_name' => array( 'wpo_wcpdf_template_settings' => 'shop_name' ), 'shop_address' => array( 'wpo_wcpdf_template_settings' => 'shop_address' ), 'footer' => array( 'wpo_wcpdf_template_settings' => 'footer' ), 'extra_1' => array( 'wpo_wcpdf_template_settings' => 'extra_1' ), 'extra_2' => array( 'wpo_wcpdf_template_settings' => 'extra_2' ), 'extra_3' => array( 'wpo_wcpdf_template_settings' => 'extra_3' ), ), 'wpo_wcpdf_documents_settings_invoice' => array( 'attach_to_email_ids' => array( 'wpo_wcpdf_general_settings' => 'email_pdf' ), 'display_shipping_address' => array( 'wpo_wcpdf_template_settings' => 'invoice_shipping_address' ), 'display_email' => array( 'wpo_wcpdf_template_settings' => 'invoice_email' ), 'display_phone' => array( 'wpo_wcpdf_template_settings' => 'invoice_phone' ), 'display_date' => array( 'wpo_wcpdf_template_settings' => 'display_date' ), 'display_number' => array( 'wpo_wcpdf_template_settings' => 'display_number' ), 'number_format' => array( 'wpo_wcpdf_template_settings' => 'invoice_number_formatting' ), 'reset_number_yearly' => array( 'wpo_wcpdf_template_settings' => 'yearly_reset_invoice_number' ), 'my_account_buttons' => array( 'wpo_wcpdf_general_settings' => 'my_account_buttons' ), 'invoice_number_column' => array( 'wpo_wcpdf_general_settings' => 'invoice_number_column' ), 'invoice_date_column' => array( 'wpo_wcpdf_general_settings' => 'invoice_date_column' ), 'disable_free' => array( 'wpo_wcpdf_general_settings' => 'disable_free' ), ), 'wpo_wcpdf_documents_settings_packing-slip' => array( 'display_billing_address' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_billing_address' ), 'display_email' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_email' ), 'display_phone' => array( 'wpo_wcpdf_template_settings' => 'packing_slip_phone' ), ), 'wpo_wcpdf_settings_debug' => array( 'enable_debug' => array( 'wpo_wcpdf_debug_settings' => 'enable_debug' ), 'html_output' => array( 'wpo_wcpdf_debug_settings' => 'html_output' ), ), ); // walk through map foreach ($settings_map as $new_option => $new_settings_keys) { ${$new_option} = array(); foreach ($new_settings_keys as $new_key => $old_setting ) { $old_key = reset($old_setting); $old_option = key($old_setting); if (!empty($old_settings[$old_option][$old_key])) { // turn translatable fields into array $translatable_fields = array('shop_name','shop_address','footer','extra_1','extra_2','extra_3'); if (in_array($new_key, $translatable_fields)) { ${$new_option}[$new_key] = array( 'default' => $old_settings[$old_option][$old_key] ); } else { ${$new_option}[$new_key] = $old_settings[$old_option][$old_key]; } } } // auto enable invoice & packing slip $enabled = array( 'wpo_wcpdf_documents_settings_invoice', 'wpo_wcpdf_documents_settings_packing-slip' ); if ( in_array( $new_option, $enabled ) ) { ${$new_option}['enabled'] = 1; } // merge with existing settings ${$new_option."_old"} = get_option( $new_option, ${$new_option} ); // second argument loads new as default in case the settings did not exist yet ${$new_option} = (array) ${$new_option} + (array) ${$new_option."_old"}; // duplicate options take new options as default // store new option values update_option( $new_option, ${$new_option} ); } } // 2.0-beta-2 update: copy next number to separate db store if ( version_compare( $installed_version, '2.0-beta-2', '<' ) ) { $next_number = get_option( 'wpo_wcpdf_next_invoice_number' ); if ( ! empty( $next_number ) ) { $number_store = new \WPO\IPS\Documents\SequentialNumberStore( 'invoice_number' ); $number_store->set_next( (int) $next_number ); } // we're not deleting this option yet to make downgrading possible // delete_option( 'wpo_wcpdf_next_invoice_number' ); // clean up after ourselves } // 2.1.9: set cleanup defaults if ( $installed_version == 'versionless' || version_compare( $installed_version, '2.1.9', '<' ) ) { $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() ); $debug_settings['enable_cleanup'] = 1; $debug_settings['cleanup_days'] = 7; update_option( 'wpo_wcpdf_settings_debug', $debug_settings ); } // 2.10.0-dev: migrate template path to template ID // 2.11.5: improvements to the migration procedure if ( version_compare( $installed_version, '2.11.5', '<' ) ) { if ( ! empty( WPO_WCPDF()->settings ) && is_callable( array( WPO_WCPDF()->settings, 'maybe_migrate_template_paths' ) ) ) { WPO_WCPDF()->settings->maybe_migrate_template_paths(); } } // 2.11.2: remove the obsolete .dist font cache file and mustRead.html from local fonts folder if ( version_compare( $installed_version, '2.11.2', '<' ) ) { wp_delete_file( trailingslashit( $font_path ) . 'dompdf_font_family_cache.dist.php' ); wp_delete_file( trailingslashit( $font_path ) . 'mustRead.html' ); } // 2.12.2-dev-1: change 'date' database table default value to '1000-01-01 00:00:00' if ( version_compare( $installed_version, '2.12.2-dev-1', '<' ) ) { global $wpdb; $documents = WPO_WCPDF()->documents->get_documents( 'all' ); foreach ( $documents as $document ) { $store_name = "{$document->slug}_number"; $method = WPO_WCPDF()->settings->get_sequential_number_store_method(); $table_name = apply_filters( 'wpo_wcpdf_number_store_table_name', sanitize_key( "{$wpdb->prefix}wcpdf_{$store_name}" ), $store_name, $method ); $table_name_exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery $wpdb->prepare( "SHOW TABLES LIKE %s", esc_sql( $table_name ) ) ) === $table_name; if ( ! $table_name_exists ) { continue; } if ( is_callable( array( $document, 'get_sequential_number_store' ) ) ) { $number_store = $document->get_sequential_number_store(); if ( ! empty( $number_store ) ) { $column_name = 'date'; $table_name_safe = sanitize_key( $number_store->table_name ); $column_name_safe = sanitize_key( $column_name ); $query_result = $wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery $wpdb->prepare( "ALTER TABLE `" . esc_sql( $table_name_safe ) . "` ALTER `" . esc_sql( $column_name_safe ) . "` SET DEFAULT %s", // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange '1000-01-01 00:00:00' ) ); if ( $query_result ) { wcpdf_log_error( "Default value changed for 'date' column to '1000-01-01 00:00:00' on database table: {$table_name_safe}", 'info' ); } else { wcpdf_log_error( "An error occurred! The default value for 'date' column couldn't be changed to '1000-01-01 00:00:00' on database table: {$table_name_safe}", 'critical' ); } } } } } // 3.0.0-dev-1: remove saved option 'use_html5_parser' if ( version_compare( $installed_version, '3.0.0-dev-1', '<' ) ) { // removes 'HTML5 parser' setting value $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() ); if ( ! empty( $debug_settings['use_html5_parser'] ) ) { unset( $debug_settings['use_html5_parser'] ); update_option( 'wpo_wcpdf_settings_debug', $debug_settings ); } } // 3.3.0-dev-1: schedule the yearly reset number action if ( version_compare( $installed_version, '3.3.0-dev-1', '<' ) ) { if ( ! empty( WPO_WCPDF()->settings ) && is_callable( array( WPO_WCPDF()->settings, 'schedule_yearly_reset_numbers' ) ) ) { WPO_WCPDF()->settings->schedule_yearly_reset_numbers(); } } // 3.5.7-dev-1: migrate 'guest_access' setting to 'document_link_access_type' if ( version_compare( $installed_version, '3.5.7-dev-1', '<' ) ) { $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() ); if ( ! empty( $debug_settings['guest_access'] ) ) { unset( $debug_settings['guest_access'] ); $debug_settings['document_link_access_type'] = 'guest'; update_option( 'wpo_wcpdf_settings_debug', $debug_settings ); } } // 3.6.3-dev-1: check if 'legacy_mode' is enabled, and disable it if ( version_compare( $installed_version, '3.6.3-dev-1', '<' ) ) { $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() ); $update = false; if ( ! empty( $debug_settings['legacy_mode'] ) ) { unset( $debug_settings['legacy_mode'] ); $update = true; } if ( ! empty( $debug_settings['legacy_textdomain'] ) ) { unset( $debug_settings['legacy_textdomain'] ); $update = true; } if ( $update ) { update_option( 'wpo_wcpdf_settings_debug', $debug_settings ); } } // 3.7.0-beta-4: migrate UBL legacy settings if ( version_compare( $installed_version, '3.7.0-beta-4', '<' ) ) { // legacy ubl general/invoice settings $legacy_ubl_general_settings = get_option( 'ubl_wc_general', [] ); $general_settings = get_option( 'wpo_wcpdf_settings_general', [] ); $invoice_ubl_settings = get_option( 'wpo_wcpdf_documents_settings_invoice_ubl', [] ); $settings_to_migrate = [ 'vat_number' => 'general', 'coc_number' => 'general', 'company_name' => 'general', // corresponds to 'shop_name' in the General Settings 'attach_to_email_ids' => 'invoice_ubl', 'include_encrypted_pdf' => 'invoice_ubl', ]; foreach ( $settings_to_migrate as $setting => $type ) { $update = []; switch ( $type ) { case 'general': if ( isset( $legacy_ubl_general_settings[$setting] ) ) { $legacy_ubl_setting_value = $legacy_ubl_general_settings[$setting]; $setting = ( 'company_name' === $setting && ! isset( $general_settings['shop_name'] ) ) ? 'shop_name' : $setting; if ( 'company_name' !== $setting ) { $general_settings[$setting] = $legacy_ubl_setting_value; $update[] = $type; } } break; case 'invoice_ubl': if ( isset( $legacy_ubl_general_settings[$setting] ) ) { $invoice_ubl_settings[$setting] = $legacy_ubl_general_settings[$setting]; $update[] = $type; } break; } if ( ! empty( $update ) ) { $update = array_unique( $update ); foreach ( $update as $type ) { switch ( $type ) { case 'general': update_option( 'wpo_wcpdf_settings_general', $general_settings ); break; case 'invoice_ubl': $invoice_ubl_settings['enabled'] = '1'; update_option( 'wpo_wcpdf_documents_settings_invoice_ubl', $invoice_ubl_settings ); break; } } } } // legacy ubl tax settings $legacy_ubl_tax_settings = get_option( 'ubl_wc_taxes', [] ); if ( ! empty( $legacy_ubl_tax_settings ) ) { update_option( 'wpo_wcpdf_settings_ubl_taxes', $legacy_ubl_tax_settings ); } // set transient to flush rewrite rules if pretty links are enabled if ( WPO_WCPDF()->endpoint->pretty_links_enabled() ) { set_transient( 'wpo_wcpdf_flush_rewrite_rules', 'yes', HOUR_IN_SECONDS ); } } // 3.9.5-beta-4: migrate UBL tax schemes/categories if ( version_compare( $installed_version, '3.9.5-beta-4', '<' ) ) { $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes', array() ); if ( ! empty( $ubl_tax_settings ) ) { array_walk_recursive( $ubl_tax_settings, function ( &$value, $key ) { if ( in_array( $key, array( 'scheme', 'category' ) ) && ! empty( $value ) ) { $value = strtoupper( $value ); } } ); update_option( 'wpo_wcpdf_settings_ubl_taxes', $ubl_tax_settings ); } } // 4.0.0-beta-3: Remove translatability from VAT and COC fields if ( version_compare( $installed_version, '4.0.0-beta-3', '<' ) ) { $general_settings = get_option( 'wpo_wcpdf_settings_general', array() ); if ( isset( $general_settings['vat_number']['default'] ) ) { $general_settings['vat_number'] = $general_settings['vat_number']['default']; } if ( isset( $general_settings['coc_number']['default'] ) ) { $general_settings['coc_number'] = $general_settings['coc_number']['default']; } update_option( 'wpo_wcpdf_settings_general', $general_settings ); } // 4.2.0-beta.3: migrate 'guest' access type to 'full' if ( version_compare( $installed_version, '4.2.0-beta.3', '<' ) ) { $debug_settings = get_option( 'wpo_wcpdf_settings_debug', array() ); if ( ! empty( $debug_settings['document_link_access_type'] ) && 'guest' === $debug_settings['document_link_access_type'] ) { $debug_settings['document_link_access_type'] = 'full'; update_option( 'wpo_wcpdf_settings_debug', $debug_settings ); } } } /** * Plugin downgrade method. Perform any required downgrades here * * * @param string $installed_version the currently installed ('old') version (actually higher since this is a downgrade) */ protected function downgrade( $installed_version ) { // make sure fonts match with version: copy from plugin folder $tmp_base = WPO_WCPDF()->main->get_tmp_base(); // make sure we have the fonts directory $font_path = WPO_WCPDF()->main->get_tmp_path( 'fonts' ); // don't continue if we don't have an upload dir if ($tmp_base === false) { return false; } // check if tmp folder exists => if not, initialize if ( ! @is_dir( $tmp_base ) || ! wp_is_writable( $tmp_base ) || ! @is_dir( $font_path ) || ! wp_is_writable( $font_path ) ) { WPO_WCPDF()->main->init_tmp(); } else { WPO_WCPDF()->main->copy_fonts( $font_path ); } } } endif; // class_exists