Plugin Directory

Changeset 2622003


Ignore:
Timestamp:
10/29/2021 02:07:37 PM (4 years ago)
Author:
bigcommerce
Message:

Update to version 4.19.1 from GitHub

Location:
bigcommerce
Files:
28 edited
1 copied

Legend:

Unmodified
Added
Removed
  • bigcommerce/tags/4.19.1/CHANGELOG.md

    r2617240 r2622003  
    11# Changelog
     2
     3## [4.19.1]
     4
     5### Changed
     6- Added ability to set the max file size for the import log. Before each import starts the log size is measured and if the size exceeds the limit it will be truncated. The default log size is 25MB. In order to change defaults go to Setting > Diagnostics. Find and update the 'Log file max size' field
     7
     8### Fixed
     9
     10- Fixed the 'New/Updated since last sync' import. The import will pull new products as well as update existing ones. Previously the 'New/Updated since last sync' updated existing products only
     11- Added ability to see product sync log errors description on the 'Diagnostic' tab
     12- Settings > Diagnostics > Product Sync Log sync statistics are displayed in the table separately for multiple channels
     13- Fixed 'Auto' sync behavior with enabled multichannel support. Added a filter bigcommerce/channels/map-products-to-all-channels filter defaulted to false
     14  - When multi-channel is enabled and the filter is false, if the Auto sync is enabled, sync imports products that are connected to each channel only.
     15  - When that multi-channel is enabled and that filter is true, if the Auto sync is enabled, newly added products to the catalog will be synced to all connected channels.
    216
    317## [4.19.0]
     
    16281642
    16291643
     1644[4.19.1]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.19.0...4.19.1
    16301645[4.19.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.18.0...4.19.0
    16311646[4.18.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.17.1...4.18.0
  • bigcommerce/tags/4.19.1/bigcommerce.php

    r2617240 r2622003  
    44Description:  Scale your ecommerce business with WordPress on the front-end and BigCommerce on the back end. Free up server resources from things like catalog management, processing payments, and managing fulfillment logistics.
    55Author:       BigCommerce
    6 Version:      4.19.0
     6Version:      4.19.1
    77Author URI:   https://www.bigcommerce.com/wordpress
    88Requires PHP: 7.4.0
  • bigcommerce/tags/4.19.1/build-timestamp.php

    r2617240 r2622003  
    11<?php
    2 define('BIGCOMMERCE_ASSETS_BUILD_TIMESTAMP', '5.23.10.19.2021');
     2define('BIGCOMMERCE_ASSETS_BUILD_TIMESTAMP', '8.41.10.29.2021');
  • bigcommerce/tags/4.19.1/readme.txt

    r2617240 r2622003  
    44Requires at least: 5.2
    55Tested up to: 5.8.1
    6 Stable tag: 4.19.0
     6Stable tag: 4.19.1
    77Requires PHP: 7.4.0
    88License: GPLv2 or later
  • bigcommerce/tags/4.19.1/src/BigCommerce/Import/Import_Type.php

    r2574256 r2622003  
    3030    /**
    3131     * @return array
    32      * 
     32     *
    3333     * @filter bigcommerce_modified_product_ids
    3434     */
     
    5959    /**
    6060     * Filter task list for partial imports
    61      * 
     61     *
    6262     * @param array $task_list
    6363     * @return array
    64      * 
     64     *
    6565     * @filter bigcommerce/import/task_list
    6666     */
     
    7878
    7979                $task_state = $task->get_completion_state();
    80                 if ( in_array( $task_state, $states ) || strpos( $task_state, Status::FETCHED_LISTINGS ) !== false ) {
     80
     81                $is_fetched_listings    = strpos( $task_state, Status::FETCHED_LISTINGS ) !== false;
     82                $is_initialized_channel = strpos( $task_state, Status::INITIALIZED_CHANNEL ) !== false;
     83
     84                if ( in_array( $task_state, $states ) || $is_fetched_listings || $is_initialized_channel ) {
    8185                    return true;
    8286                }
  • bigcommerce/tags/4.19.1/src/BigCommerce/Import/Processors/Channel_Initializer.php

    r2342514 r2622003  
    1212use BigCommerce\Api\v3\Model\Variant;
    1313use BigCommerce\Api\v3\ObjectSerializer;
     14use BigCommerce\Exceptions\Product_Not_Found_Exception;
     15use BigCommerce\Import\Import_Type;
    1416use BigCommerce\Import\No_Cache_Options;
    1517use BigCommerce\Import\Runner\Status;
     
    1719use BigCommerce\Settings\Sections\Import;
    1820use BigCommerce\Taxonomies\Channel\Channel;
     21use \BigCommerce\Post_Types\Product\Product as Product_Post_Type;
    1922
    2023/**
     
    6366    }
    6467
     68    /**
     69     * Check if the product exists
     70     *
     71     * @param $product
     72     * @param $channel_id
     73     *
     74     * @return bool
     75     */
     76    private function is_existing_product( $product, $channel_id ): bool {
     77        try {
     78            $query_args = [ 'post_status' => [ 'publish', 'draft' ] ];
     79            Product_Post_Type::by_product_id( $product->getId(), $this->channel_term, $query_args );
     80
     81            do_action( 'bigcommerce/log', Error_Log::DEBUG, __( 'Product entity exists. Skipping.', 'bigcommerce' ), [
     82                    'product_id' => $product->getId(),
     83                    'channel_id' => $channel_id,
     84            ] );
     85
     86            return true;
     87        } catch ( Product_Not_Found_Exception $e ) {
     88            return false;
     89        }
     90    }
     91
    6592    public function run() {
    6693
     
    73100
    74101            return;
     102        }
     103
     104        $listing_ids = [];
     105        // Get the listings for this channel.
     106        if ( $this->multichannel_sync_channel_listings() ) {
     107            try {
     108                $listings    = $this->channels->listChannelListings( $channel_id );
     109                $listing_ids = array_map( function ( Listing $listing ) {
     110                    return $listing->getProductId();
     111                }, $listings->getData() );
     112            } catch ( ApiException $e ) {
     113                do_action( 'bigcommerce/import/error', $e->getMessage(), [
     114                    'response' => $e->getResponseBody(),
     115                    'headers'  => $e->getResponseHeaders(),
     116                ] );
     117                do_action( 'bigcommerce/log', Error_Log::DEBUG, $e->getTraceAsString(), [] );
     118
     119                return;
     120            }
    75121        }
    76122
     
    111157        $id_map = $this->get_option( Listing_Fetcher::PRODUCT_LISTING_MAP, [] ) ?: [];
    112158
    113         $listing_requests = array_values( array_filter( array_map( function ( Product $product ) use ( $channel_id, $id_map ) {
     159        $import_type = get_option( Import_Type::IMPORT_TYPE );
     160
     161        $listing_requests = array_values( array_filter( array_map( function ( Product $product ) use ( $channel_id, $id_map, $import_type, $listing_ids ) {
     162            /**
     163             * We will skip existing products listing creation for partial import
     164             */
     165            if ( $import_type === Import_Type::IMPORT_TYPE_PARTIAL && $this->is_existing_product( $product, $channel_id ) ) {
     166                return false;
     167            }
     168
    114169            if ( array_key_exists( $product->getId(), $id_map ) && array_key_exists( $this->channel_term->term_id, $id_map[ $product->getId() ] ) ) {
    115170                do_action( 'bigcommerce/log', Error_Log::DEBUG, __( 'Product already linked to channel. Skipping.', 'bigcommerce' ), [
     171                    'product_id' => $product->getId(),
     172                    'channel_id' => $channel_id,
     173                ] );
     174
     175                return false;
     176            }
     177
     178            // Return if this product should not be synced to this channel.
     179            if ( $this->multichannel_sync_channel_listings() && ! in_array( $product->getId(), $listing_ids ) ) {
     180                do_action( 'bigcommerce/log', Error_Log::DEBUG, __( 'Product does not belong in this channel. Skipping.', 'bigcommerce' ), [
    116181                    'product_id' => $product->getId(),
    117182                    'channel_id' => $channel_id,
     
    207272        return sprintf( '%s-%d', self::STATE_OPTION, $this->channel_term->term_id );
    208273    }
     274
     275    private function multichannel_sync_channel_listings() {
     276        return ( Channel::multichannel_enabled() && ! Channel::multichannel_sync_to_all_channels() );
     277    }
    209278}
  • bigcommerce/tags/4.19.1/src/BigCommerce/Logging/Error_Log.php

    r2034554 r2622003  
    44
    55use BigCommerce\Api\v3\Api\CatalogApi;
     6use BigCommerce\Settings\Sections\Troubleshooting_Diagnostics;
    67use Monolog\Logger;
    78use Monolog\Handler\StreamHandler;
     
    1314 */
    1415class Error_Log {
    15     const EMERGENCY = 'emergency';
    16     const ALERT     = 'alert';
    17     const CRITICAL  = 'critical';
    18     const ERROR     = 'error';
    19     const WARNING   = 'warning';
    20     const NOTICE    = 'notice';
    21     const INFO      = 'info';
    22     const DEBUG     = 'debug';
     16    const EMERGENCY    = 'emergency';
     17    const ALERT        = 'alert';
     18    const CRITICAL     = 'critical';
     19    const ERROR        = 'error';
     20    const WARNING      = 'warning';
     21    const NOTICE       = 'notice';
     22    const INFO         = 'info';
     23    const DEBUG        = 'debug';
     24    const MAX_SIZE     = 25;
    2325
    2426    /**
     
    168170
    169171    /**
    170      * Delete Log content
     172     * Clean log file if it has size more than set in Troubleshooting_Diagnostics::LOG_FILE_SIZE
    171173     */
    172174    public function truncate_log() {
    173         if ( file_exists( $this->log_path ) ) {
    174             // Truncate file
    175             $file = fopen( $this->log_path, "w" );
    176             fclose( $file );
    177         }
     175        if ( ! file_exists( $this->log_path ) ) {
     176            return;
     177        }
     178
     179        $log_size = $this->get_log_size_mb();
     180        $max_allowed_size = (int) get_option( Troubleshooting_Diagnostics::LOG_FILE_SIZE, self::MAX_SIZE );
     181
     182        /**
     183         * Exit from function if file size lower than set in settings
     184         */
     185        if ( $log_size < $max_allowed_size ) {
     186            return;
     187        }
     188
     189        /**
     190         * Clean log file contents
     191         */
     192        $file = fopen( $this->log_path, "w" );
     193        fclose( $file );
     194    }
     195
     196    /**
     197     * Get log file size in MB
     198     * @return float|int
     199     */
     200    public function get_log_size_mb() {
     201        if ( ! file_exists( $this->log_path ) ) {
     202            return 0;
     203        }
     204
     205        /**
     206         * Get log size in bytes
     207         */
     208        $file_size = filesize( $this->log_path );
     209
     210        /**
     211         * Return the size of log file in MB
     212         */
     213        return round( $file_size / 1024 / 1024, 1 );
    178214    }
    179215
  • bigcommerce/tags/4.19.1/src/BigCommerce/Plugin.php

    r2617240 r2622003  
    55
    66class Plugin {
    7     const VERSION = '4.19.0';
     7    const VERSION = '4.19.1';
    88
    99    protected static $_instance;
  • bigcommerce/tags/4.19.1/src/BigCommerce/Post_Types/Sync_Log/Sync_Log.php

    r2538746 r2622003  
    44namespace BigCommerce\Post_Types\Sync_Log;
    55
    6 use BigCommerce\Import\Runner\Status;
     6use BigCommerce\Post_Types\Product\Product;
    77use BigCommerce\Settings\Import_Status;
    8 use BigCommerce\Post_Types\Product\Product;
     8use BigCommerce\Taxonomies\Channel\Channel;
     9use BigCommerce\Taxonomies\Channel\Connections;
    910
    1011class Sync_Log {
     
    1213    const NAME = 'bigcommerce_sync_log';
    1314
    14     const META_STATUS   = 'status';
    15     const META_EVENT    = 'event';
    16     const META_ERRORS   = 'errors';
    17     const META_SUMMARY  = 'summary';
    18     const META_DURATION = 'duration';
     15    const META_STATUS          = 'status';
     16    const META_EVENT           = 'event';
     17    const META_ERRORS          = 'errors';
     18    const META_SUMMARY         = 'summary';
     19    const META_DURATION        = 'duration';
     20    const MULTICHANNEL_SUMMARY = 'multichannel_summary';
     21    // We need to know if multichannel was active during this log session.
     22    const MULTICHANNEL_ACTIVE = 'multichannel_active';
     23
     24    // Track the sync_id so we don't have to get_posts mulitple times.
     25    private $sync_id = 0;
    1926
    2027    /**
     
    2936
    3037        $post_id = wp_insert_post( [
    31             'post_title'   => __( 'Sync in progress', 'bigcommerce' ),
    32             'post_type'    => self::NAME,
    33             'post_status'  => 'draft',
     38            'post_title'  => __( 'Sync in progress', 'bigcommerce' ),
     39            'post_type'   => self::NAME,
     40            'post_status' => 'draft',
    3441        ] );
    3542        update_post_meta( $post_id, self::META_ERRORS, [] );
     
    3744            'count_before' => wp_count_posts( Product::NAME )->publish,
    3845        ] );
     46
     47        // Gather extra data for multichannel
     48        if ( Channel::multichannel_enabled() ) {
     49            update_post_meta( $post_id, self::MULTICHANNEL_ACTIVE, true );
     50            $connections = new Connections();
     51
     52            // Get the existing meta
     53            $multichannel_summary = get_post_meta( $post_id, self::MULTICHANNEL_SUMMARY, true );
     54            $multichannel_summary = is_array( $multichannel_summary ) ? $multichannel_summary : [];
     55
     56            foreach ( $connections->active() as $channel ) {
     57                $multichannel_summary[ $channel->term_id ] = [
     58                    'count_before' => $channel->count,
     59                ];
     60            }
     61
     62            // And update the meta
     63            update_post_meta(
     64                $post_id,
     65                self::MULTICHANNEL_SUMMARY,
     66                $multichannel_summary
     67            );
     68        }
    3969    }
    4070
     
    4373     *
    4474     * @param array $log The current log
     75     *
    4576     * @return void
    4677     *
     
    83114        update_post_meta( $post_id, self::META_SUMMARY, $summary );
    84115
     116        if ( Channel::multichannel_enabled() ) {
     117            // Get the existing meta
     118            $multichannel_summary = get_post_meta( $post_id, self::MULTICHANNEL_SUMMARY, true );
     119            $multichannel_summary = is_array( $multichannel_summary ) ? $multichannel_summary : [];
     120
     121            foreach ( $multichannel_summary as $term_id => $summary ) {
     122                $summary['count_after']  = get_term( $term_id )->count;
     123                $summary['channel_name'] = get_term( $term_id )->name;
     124
     125                $multichannel_summary[ $term_id ] = $summary;
     126            }
     127
     128            // And update the meta
     129            update_post_meta(
     130                $post_id,
     131                self::MULTICHANNEL_SUMMARY,
     132                $multichannel_summary
     133            );
     134        }
     135
    85136        $this->remove_old_syncs( 'publish', 10 );
    86137    }
     
    102153        $errors = get_post_meta( $post_id, self::META_ERRORS, true );
    103154
    104         if ( empty( $errors ) ) {
     155        if ( ! is_array ($errors) || empty( $errors ) ) {
    105156            $errors = [];
    106157        }
     
    108159        $errors[] = $error;
    109160
    110         update_post_meta( $post_id, self::META_ERRORS, $error );
     161        update_post_meta( $post_id, self::META_ERRORS, $errors );
    111162    }
    112163
     
    129180        $sync_log_data = [];
    130181        foreach ( $sync_logs as $index => $sync_log ) {
    131             $status  = $sync_log->{self::META_STATUS};
    132             $errors  = $sync_log->{self::META_ERRORS};
     182            $status = $sync_log->{self::META_STATUS};
     183            $errors = $sync_log->{self::META_ERRORS};
    133184
    134185            $sync_log_data[] = sprintf(
     
    143194                $index + 1,
    144195                ucfirst( $status ),
    145                 $this->get_summary_formatted( $sync_log ),
     196                $sync_log->{self::MULTICHANNEL_ACTIVE}
     197                    ? $this->get_multichannel_summary_formatted( $sync_log )
     198                    : $this->get_summary_formatted( $sync_log ),
    146199                is_array( $errors ) && count( $errors ) ? implode( '<br>', $errors ) : __( 'None', 'bigcommerce' ),
    147200                $sync_log->{self::META_DURATION},
     
    151204
    152205        $sync_log_data = sprintf(
    153             '<table class="bc-product-sync-data-table">
     206            '<style>
     207                .bc-product-sync-data-table tr:nth-child(odd) {
     208                    background-color: #f2f2f2;
     209                }
     210            </style>
     211            <table class="bc-product-sync-data-table">
    154212                <tr>
    155213                    <th>#</th>
     
    178236                    'label' => '',
    179237                    'key'   => 'sync_logs',
    180                     'value' => $sync_log_data
    181                 ]
     238                    'value' => $sync_log_data,
     239                ],
    182240            ],
    183241        ];
     
    190248     *
    191249     * @param \WP_Post $post
     250     *
    192251     * @return string
    193252     */
    194     private function get_post_date_formatted( $post )  {
     253    private function get_post_date_formatted( $post ) {
    195254        $date_format = sprintf(
    196255            '%s %s',
     
    198257            get_option( 'time_format', 'H:i' )
    199258        );
     259
    200260        return get_the_date( $date_format, $post );
    201261    }
     
    211271            $timezone = 'UTC' . $timezone;
    212272        }
     273
    213274        return $timezone;
    214275    }
     
    220281     */
    221282    private function get_current_sync_id() {
     283        // Track the sync id so we can write the error after post status update.
     284        if ( $this->sync_id ) {
     285            return $this->sync_id;
     286        }
     287
    222288        $draft = get_posts( [
    223289            'post_type'      => self::NAME,
     
    227293        ] );
    228294
    229         return reset( $draft );
     295        $this->sync_id = reset( $draft );
     296
     297        return $this->sync_id;
    230298    }
    231299
     
    239307            'post_type'      => self::NAME,
    240308            'post_status'    => $status,
    241             'posts_per_page' => -1,
     309            'posts_per_page' => - 1,
    242310            'fields'         => 'ids',
    243311        ] );
     
    247315        }
    248316
    249         foreach( $sync_logs as $index => $post_id ) {
     317        foreach ( $sync_logs as $index => $post_id ) {
    250318            if ( $index < $keep ) {
    251319                continue;
     
    259327     *
    260328     * @param \WP_Post $sync_log
     329     *
    261330     * @return string
    262331     */
     
    286355
    287356        $out = array_map( function ( $line ) {
    288             return sprintf( '<span class="bc-sync-summary-meta">%s</span>', $line );
     357            return sprintf( '<span class="bc-sync-summary-meta">%s</span><br />', $line );
    289358        }, $out );
    290359
     
    292361    }
    293362
     363    /**
     364     * Get formatted summary
     365     *
     366     * @param \WP_Post $sync_log
     367     *
     368     * @return string
     369     */
     370    private function get_multichannel_summary_formatted( $sync_log ) {
     371        $multichannel_summary = $sync_log->{self::MULTICHANNEL_SUMMARY};
     372
     373        $summary = [];
     374
     375        foreach ( $multichannel_summary as $channel ) {
     376            $count_before = $channel['count_before'] ?? 0;
     377            $count_after  = $channel['count_after'] ?? 0;
     378            $new          = $count_after - $count_before;
     379
     380            $summary[] = sprintf( __( '<br /><b>%s</b>', 'bigcommerce' ), $channel['channel_name'] );
     381            $summary[] = sprintf( __( '%d Synced', 'bigcommerce' ), $channel['count_after'] );
     382            if ( $new > 0  ) {
     383                $summary[] = sprintf( __( '%d Added', 'bigcommerce' ), $new );
     384            }
     385
     386            $summary = array_map( function ( $line ) {
     387                return sprintf( '<span class="bc-sync-summary-meta">%s</span>', $line );
     388            }, $summary );
     389        }
     390
     391        return implode( '<br />', $summary );
     392    }
    294393}
  • bigcommerce/tags/4.19.1/src/BigCommerce/Settings/Sections/Troubleshooting_Diagnostics.php

    r2617240 r2622003  
    2828    const TEXTBOX_NAME     = 'bigcommerce_diagnostics_output';
    2929    const LOG_ERRORS       = 'bigcommerce_diagnostics_log_import_errors';
     30    const LOG_FILE_SIZE    = 'bigcommerce_diagnostics_log_file_size';
    3031    const SYNC_SITE_URL    = 'bigcommerce_diagnostics_sync_site_url';
    3132
     
    9091        );
    9192
     93        register_setting(
     94            Settings_Screen::NAME,
     95            self::LOG_FILE_SIZE
     96        );
     97
     98        add_settings_field(
     99            self::LOG_FILE_SIZE,
     100            esc_html( __( 'Log file max size(MB)', 'bigcommerce' ) ),
     101            [ $this, 'render_log_file_size', ],
     102            Settings_Screen::NAME,
     103            self::NAME,
     104            [
     105                'min'         => 1,
     106                'max'         => 25,
     107                'type'        => 'number',
     108                'option'      => self::LOG_FILE_SIZE,
     109                'label'       => esc_html( __( 'Set log file size', 'bigcommerce' ) ),
     110                'description' => esc_html( __( 'Set log file max size in MB. If log file exceeds the limit it will be cleaned before new import', 'bigcommerce' ) ),
     111            ]
     112        );
     113
    92114        add_settings_field(
    93115            self::DIAGNOSTICS_NAME,
     
    136158    }
    137159
     160    public function render_log_file_size( $args ) {
     161        $value = get_option( $args[ 'option' ], 25 );
     162        $min   = isset( $args[ 'min' ] ) ? sprintf( 'min="%d"', $args[ 'min' ] ) : '';
     163        $max   = isset( $args[ 'max' ] ) ? sprintf( 'max="%d"', $args[ 'max' ] ) : '';
     164        $field = sprintf( '<input type="%1$s" value="%2$s" name="%3$s" id="%3$s" %4$s %5$s />', esc_attr( $args[ 'type' ] ), esc_attr( $value ), esc_attr( $args[ 'option' ] ), $min, $max );
     165        printf( '%s<p class="description">%s</p>', $field, esc_html( $args[ 'description' ] ) );
     166    }
     167
    138168    /**
    139169     * Sets a wp_send_json answer for the ajax call that holds
  • bigcommerce/tags/4.19.1/src/BigCommerce/Taxonomies/Channel/Channel.php

    r2141486 r2622003  
    3737
    3838    /**
     39     * Should product sync be to all channels?
     40     *
     41     * @return bool
     42     */
     43    public static function multichannel_sync_to_all_channels() {
     44        /**
     45         * Filter whether multi-channel sync should sync to all channels.
     46         * Enabling this feature allows site owners to
     47         * connect to sync products to all channels or
     48         * only the channel it is assigned to.
     49         *
     50         * @param bool $enabled
     51         */
     52        return (bool) apply_filters( 'bigcommerce/channels/map-products-to-all-channels', false );
     53    }
     54
     55    /**
    3956     * @param int $channel_id
    4057     *
  • bigcommerce/tags/4.19.1/vendor/autoload.php

    r2617240 r2622003  
    55require_once __DIR__ . '/composer/autoload_real.php';
    66
    7 return ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f::getLoader();
     7return ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119::getLoader();
  • bigcommerce/tags/4.19.1/vendor/composer/autoload_real.php

    r2617240 r2622003  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f
     5class ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119
    66{
    77    private static $loader;
     
    2020        }
    2121
    22         spl_autoload_register(array('ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f', 'loadClassLoader'), true, true);
     22        spl_autoload_register(array('ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119', 'loadClassLoader'), true, true);
    2323        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
    24         spl_autoload_unregister(array('ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f', 'loadClassLoader'));
     24        spl_autoload_unregister(array('ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119', 'loadClassLoader'));
    2525
    2626        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
     
    2828            require_once __DIR__ . '/autoload_static.php';
    2929
    30             call_user_func(\Composer\Autoload\ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::getInitializer($loader));
     30            call_user_func(\Composer\Autoload\ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::getInitializer($loader));
    3131        } else {
    3232            $classMap = require __DIR__ . '/autoload_classmap.php';
     
    4040
    4141        if ($useStaticLoader) {
    42             $includeFiles = Composer\Autoload\ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$files;
     42            $includeFiles = Composer\Autoload\ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$files;
    4343        } else {
    4444            $includeFiles = require __DIR__ . '/autoload_files.php';
    4545        }
    4646        foreach ($includeFiles as $fileIdentifier => $file) {
    47             composerRequire509873e0fe5d4df74a0ea698def2e38f($fileIdentifier, $file);
     47            composerRequire00d9fec88dbb4fdf0216f882209f6119($fileIdentifier, $file);
    4848        }
    4949
     
    5252}
    5353
    54 function composerRequire509873e0fe5d4df74a0ea698def2e38f($fileIdentifier, $file)
     54function composerRequire00d9fec88dbb4fdf0216f882209f6119($fileIdentifier, $file)
    5555{
    5656    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • bigcommerce/tags/4.19.1/vendor/composer/autoload_static.php

    r2617240 r2622003  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f
     7class ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119
    88{
    99    public static $files = array (
     
    11241124    {
    11251125        return \Closure::bind(function () use ($loader) {
    1126             $loader->prefixLengthsPsr4 = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$prefixLengthsPsr4;
    1127             $loader->prefixDirsPsr4 = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$prefixDirsPsr4;
    1128             $loader->prefixesPsr0 = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$prefixesPsr0;
    1129             $loader->classMap = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$classMap;
     1126            $loader->prefixLengthsPsr4 = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$prefixLengthsPsr4;
     1127            $loader->prefixDirsPsr4 = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$prefixDirsPsr4;
     1128            $loader->prefixesPsr0 = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$prefixesPsr0;
     1129            $loader->classMap = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$classMap;
    11301130
    11311131        }, null, ClassLoader::class);
  • bigcommerce/trunk/CHANGELOG.md

    r2617240 r2622003  
    11# Changelog
     2
     3## [4.19.1]
     4
     5### Changed
     6- Added ability to set the max file size for the import log. Before each import starts the log size is measured and if the size exceeds the limit it will be truncated. The default log size is 25MB. In order to change defaults go to Setting > Diagnostics. Find and update the 'Log file max size' field
     7
     8### Fixed
     9
     10- Fixed the 'New/Updated since last sync' import. The import will pull new products as well as update existing ones. Previously the 'New/Updated since last sync' updated existing products only
     11- Added ability to see product sync log errors description on the 'Diagnostic' tab
     12- Settings > Diagnostics > Product Sync Log sync statistics are displayed in the table separately for multiple channels
     13- Fixed 'Auto' sync behavior with enabled multichannel support. Added a filter bigcommerce/channels/map-products-to-all-channels filter defaulted to false
     14  - When multi-channel is enabled and the filter is false, if the Auto sync is enabled, sync imports products that are connected to each channel only.
     15  - When that multi-channel is enabled and that filter is true, if the Auto sync is enabled, newly added products to the catalog will be synced to all connected channels.
    216
    317## [4.19.0]
     
    16281642
    16291643
     1644[4.19.1]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.19.0...4.19.1
    16301645[4.19.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.18.0...4.19.0
    16311646[4.18.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/4.17.1...4.18.0
  • bigcommerce/trunk/bigcommerce.php

    r2617240 r2622003  
    44Description:  Scale your ecommerce business with WordPress on the front-end and BigCommerce on the back end. Free up server resources from things like catalog management, processing payments, and managing fulfillment logistics.
    55Author:       BigCommerce
    6 Version:      4.19.0
     6Version:      4.19.1
    77Author URI:   https://www.bigcommerce.com/wordpress
    88Requires PHP: 7.4.0
  • bigcommerce/trunk/build-timestamp.php

    r2617240 r2622003  
    11<?php
    2 define('BIGCOMMERCE_ASSETS_BUILD_TIMESTAMP', '5.23.10.19.2021');
     2define('BIGCOMMERCE_ASSETS_BUILD_TIMESTAMP', '8.41.10.29.2021');
  • bigcommerce/trunk/readme.txt

    r2617240 r2622003  
    44Requires at least: 5.2
    55Tested up to: 5.8.1
    6 Stable tag: 4.19.0
     6Stable tag: 4.19.1
    77Requires PHP: 7.4.0
    88License: GPLv2 or later
  • bigcommerce/trunk/src/BigCommerce/Import/Import_Type.php

    r2574256 r2622003  
    3030    /**
    3131     * @return array
    32      * 
     32     *
    3333     * @filter bigcommerce_modified_product_ids
    3434     */
     
    5959    /**
    6060     * Filter task list for partial imports
    61      * 
     61     *
    6262     * @param array $task_list
    6363     * @return array
    64      * 
     64     *
    6565     * @filter bigcommerce/import/task_list
    6666     */
     
    7878
    7979                $task_state = $task->get_completion_state();
    80                 if ( in_array( $task_state, $states ) || strpos( $task_state, Status::FETCHED_LISTINGS ) !== false ) {
     80
     81                $is_fetched_listings    = strpos( $task_state, Status::FETCHED_LISTINGS ) !== false;
     82                $is_initialized_channel = strpos( $task_state, Status::INITIALIZED_CHANNEL ) !== false;
     83
     84                if ( in_array( $task_state, $states ) || $is_fetched_listings || $is_initialized_channel ) {
    8185                    return true;
    8286                }
  • bigcommerce/trunk/src/BigCommerce/Import/Processors/Channel_Initializer.php

    r2342514 r2622003  
    1212use BigCommerce\Api\v3\Model\Variant;
    1313use BigCommerce\Api\v3\ObjectSerializer;
     14use BigCommerce\Exceptions\Product_Not_Found_Exception;
     15use BigCommerce\Import\Import_Type;
    1416use BigCommerce\Import\No_Cache_Options;
    1517use BigCommerce\Import\Runner\Status;
     
    1719use BigCommerce\Settings\Sections\Import;
    1820use BigCommerce\Taxonomies\Channel\Channel;
     21use \BigCommerce\Post_Types\Product\Product as Product_Post_Type;
    1922
    2023/**
     
    6366    }
    6467
     68    /**
     69     * Check if the product exists
     70     *
     71     * @param $product
     72     * @param $channel_id
     73     *
     74     * @return bool
     75     */
     76    private function is_existing_product( $product, $channel_id ): bool {
     77        try {
     78            $query_args = [ 'post_status' => [ 'publish', 'draft' ] ];
     79            Product_Post_Type::by_product_id( $product->getId(), $this->channel_term, $query_args );
     80
     81            do_action( 'bigcommerce/log', Error_Log::DEBUG, __( 'Product entity exists. Skipping.', 'bigcommerce' ), [
     82                    'product_id' => $product->getId(),
     83                    'channel_id' => $channel_id,
     84            ] );
     85
     86            return true;
     87        } catch ( Product_Not_Found_Exception $e ) {
     88            return false;
     89        }
     90    }
     91
    6592    public function run() {
    6693
     
    73100
    74101            return;
     102        }
     103
     104        $listing_ids = [];
     105        // Get the listings for this channel.
     106        if ( $this->multichannel_sync_channel_listings() ) {
     107            try {
     108                $listings    = $this->channels->listChannelListings( $channel_id );
     109                $listing_ids = array_map( function ( Listing $listing ) {
     110                    return $listing->getProductId();
     111                }, $listings->getData() );
     112            } catch ( ApiException $e ) {
     113                do_action( 'bigcommerce/import/error', $e->getMessage(), [
     114                    'response' => $e->getResponseBody(),
     115                    'headers'  => $e->getResponseHeaders(),
     116                ] );
     117                do_action( 'bigcommerce/log', Error_Log::DEBUG, $e->getTraceAsString(), [] );
     118
     119                return;
     120            }
    75121        }
    76122
     
    111157        $id_map = $this->get_option( Listing_Fetcher::PRODUCT_LISTING_MAP, [] ) ?: [];
    112158
    113         $listing_requests = array_values( array_filter( array_map( function ( Product $product ) use ( $channel_id, $id_map ) {
     159        $import_type = get_option( Import_Type::IMPORT_TYPE );
     160
     161        $listing_requests = array_values( array_filter( array_map( function ( Product $product ) use ( $channel_id, $id_map, $import_type, $listing_ids ) {
     162            /**
     163             * We will skip existing products listing creation for partial import
     164             */
     165            if ( $import_type === Import_Type::IMPORT_TYPE_PARTIAL && $this->is_existing_product( $product, $channel_id ) ) {
     166                return false;
     167            }
     168
    114169            if ( array_key_exists( $product->getId(), $id_map ) && array_key_exists( $this->channel_term->term_id, $id_map[ $product->getId() ] ) ) {
    115170                do_action( 'bigcommerce/log', Error_Log::DEBUG, __( 'Product already linked to channel. Skipping.', 'bigcommerce' ), [
     171                    'product_id' => $product->getId(),
     172                    'channel_id' => $channel_id,
     173                ] );
     174
     175                return false;
     176            }
     177
     178            // Return if this product should not be synced to this channel.
     179            if ( $this->multichannel_sync_channel_listings() && ! in_array( $product->getId(), $listing_ids ) ) {
     180                do_action( 'bigcommerce/log', Error_Log::DEBUG, __( 'Product does not belong in this channel. Skipping.', 'bigcommerce' ), [
    116181                    'product_id' => $product->getId(),
    117182                    'channel_id' => $channel_id,
     
    207272        return sprintf( '%s-%d', self::STATE_OPTION, $this->channel_term->term_id );
    208273    }
     274
     275    private function multichannel_sync_channel_listings() {
     276        return ( Channel::multichannel_enabled() && ! Channel::multichannel_sync_to_all_channels() );
     277    }
    209278}
  • bigcommerce/trunk/src/BigCommerce/Logging/Error_Log.php

    r2034554 r2622003  
    44
    55use BigCommerce\Api\v3\Api\CatalogApi;
     6use BigCommerce\Settings\Sections\Troubleshooting_Diagnostics;
    67use Monolog\Logger;
    78use Monolog\Handler\StreamHandler;
     
    1314 */
    1415class Error_Log {
    15     const EMERGENCY = 'emergency';
    16     const ALERT     = 'alert';
    17     const CRITICAL  = 'critical';
    18     const ERROR     = 'error';
    19     const WARNING   = 'warning';
    20     const NOTICE    = 'notice';
    21     const INFO      = 'info';
    22     const DEBUG     = 'debug';
     16    const EMERGENCY    = 'emergency';
     17    const ALERT        = 'alert';
     18    const CRITICAL     = 'critical';
     19    const ERROR        = 'error';
     20    const WARNING      = 'warning';
     21    const NOTICE       = 'notice';
     22    const INFO         = 'info';
     23    const DEBUG        = 'debug';
     24    const MAX_SIZE     = 25;
    2325
    2426    /**
     
    168170
    169171    /**
    170      * Delete Log content
     172     * Clean log file if it has size more than set in Troubleshooting_Diagnostics::LOG_FILE_SIZE
    171173     */
    172174    public function truncate_log() {
    173         if ( file_exists( $this->log_path ) ) {
    174             // Truncate file
    175             $file = fopen( $this->log_path, "w" );
    176             fclose( $file );
    177         }
     175        if ( ! file_exists( $this->log_path ) ) {
     176            return;
     177        }
     178
     179        $log_size = $this->get_log_size_mb();
     180        $max_allowed_size = (int) get_option( Troubleshooting_Diagnostics::LOG_FILE_SIZE, self::MAX_SIZE );
     181
     182        /**
     183         * Exit from function if file size lower than set in settings
     184         */
     185        if ( $log_size < $max_allowed_size ) {
     186            return;
     187        }
     188
     189        /**
     190         * Clean log file contents
     191         */
     192        $file = fopen( $this->log_path, "w" );
     193        fclose( $file );
     194    }
     195
     196    /**
     197     * Get log file size in MB
     198     * @return float|int
     199     */
     200    public function get_log_size_mb() {
     201        if ( ! file_exists( $this->log_path ) ) {
     202            return 0;
     203        }
     204
     205        /**
     206         * Get log size in bytes
     207         */
     208        $file_size = filesize( $this->log_path );
     209
     210        /**
     211         * Return the size of log file in MB
     212         */
     213        return round( $file_size / 1024 / 1024, 1 );
    178214    }
    179215
  • bigcommerce/trunk/src/BigCommerce/Plugin.php

    r2617240 r2622003  
    55
    66class Plugin {
    7     const VERSION = '4.19.0';
     7    const VERSION = '4.19.1';
    88
    99    protected static $_instance;
  • bigcommerce/trunk/src/BigCommerce/Post_Types/Sync_Log/Sync_Log.php

    r2538746 r2622003  
    44namespace BigCommerce\Post_Types\Sync_Log;
    55
    6 use BigCommerce\Import\Runner\Status;
     6use BigCommerce\Post_Types\Product\Product;
    77use BigCommerce\Settings\Import_Status;
    8 use BigCommerce\Post_Types\Product\Product;
     8use BigCommerce\Taxonomies\Channel\Channel;
     9use BigCommerce\Taxonomies\Channel\Connections;
    910
    1011class Sync_Log {
     
    1213    const NAME = 'bigcommerce_sync_log';
    1314
    14     const META_STATUS   = 'status';
    15     const META_EVENT    = 'event';
    16     const META_ERRORS   = 'errors';
    17     const META_SUMMARY  = 'summary';
    18     const META_DURATION = 'duration';
     15    const META_STATUS          = 'status';
     16    const META_EVENT           = 'event';
     17    const META_ERRORS          = 'errors';
     18    const META_SUMMARY         = 'summary';
     19    const META_DURATION        = 'duration';
     20    const MULTICHANNEL_SUMMARY = 'multichannel_summary';
     21    // We need to know if multichannel was active during this log session.
     22    const MULTICHANNEL_ACTIVE = 'multichannel_active';
     23
     24    // Track the sync_id so we don't have to get_posts mulitple times.
     25    private $sync_id = 0;
    1926
    2027    /**
     
    2936
    3037        $post_id = wp_insert_post( [
    31             'post_title'   => __( 'Sync in progress', 'bigcommerce' ),
    32             'post_type'    => self::NAME,
    33             'post_status'  => 'draft',
     38            'post_title'  => __( 'Sync in progress', 'bigcommerce' ),
     39            'post_type'   => self::NAME,
     40            'post_status' => 'draft',
    3441        ] );
    3542        update_post_meta( $post_id, self::META_ERRORS, [] );
     
    3744            'count_before' => wp_count_posts( Product::NAME )->publish,
    3845        ] );
     46
     47        // Gather extra data for multichannel
     48        if ( Channel::multichannel_enabled() ) {
     49            update_post_meta( $post_id, self::MULTICHANNEL_ACTIVE, true );
     50            $connections = new Connections();
     51
     52            // Get the existing meta
     53            $multichannel_summary = get_post_meta( $post_id, self::MULTICHANNEL_SUMMARY, true );
     54            $multichannel_summary = is_array( $multichannel_summary ) ? $multichannel_summary : [];
     55
     56            foreach ( $connections->active() as $channel ) {
     57                $multichannel_summary[ $channel->term_id ] = [
     58                    'count_before' => $channel->count,
     59                ];
     60            }
     61
     62            // And update the meta
     63            update_post_meta(
     64                $post_id,
     65                self::MULTICHANNEL_SUMMARY,
     66                $multichannel_summary
     67            );
     68        }
    3969    }
    4070
     
    4373     *
    4474     * @param array $log The current log
     75     *
    4576     * @return void
    4677     *
     
    83114        update_post_meta( $post_id, self::META_SUMMARY, $summary );
    84115
     116        if ( Channel::multichannel_enabled() ) {
     117            // Get the existing meta
     118            $multichannel_summary = get_post_meta( $post_id, self::MULTICHANNEL_SUMMARY, true );
     119            $multichannel_summary = is_array( $multichannel_summary ) ? $multichannel_summary : [];
     120
     121            foreach ( $multichannel_summary as $term_id => $summary ) {
     122                $summary['count_after']  = get_term( $term_id )->count;
     123                $summary['channel_name'] = get_term( $term_id )->name;
     124
     125                $multichannel_summary[ $term_id ] = $summary;
     126            }
     127
     128            // And update the meta
     129            update_post_meta(
     130                $post_id,
     131                self::MULTICHANNEL_SUMMARY,
     132                $multichannel_summary
     133            );
     134        }
     135
    85136        $this->remove_old_syncs( 'publish', 10 );
    86137    }
     
    102153        $errors = get_post_meta( $post_id, self::META_ERRORS, true );
    103154
    104         if ( empty( $errors ) ) {
     155        if ( ! is_array ($errors) || empty( $errors ) ) {
    105156            $errors = [];
    106157        }
     
    108159        $errors[] = $error;
    109160
    110         update_post_meta( $post_id, self::META_ERRORS, $error );
     161        update_post_meta( $post_id, self::META_ERRORS, $errors );
    111162    }
    112163
     
    129180        $sync_log_data = [];
    130181        foreach ( $sync_logs as $index => $sync_log ) {
    131             $status  = $sync_log->{self::META_STATUS};
    132             $errors  = $sync_log->{self::META_ERRORS};
     182            $status = $sync_log->{self::META_STATUS};
     183            $errors = $sync_log->{self::META_ERRORS};
    133184
    134185            $sync_log_data[] = sprintf(
     
    143194                $index + 1,
    144195                ucfirst( $status ),
    145                 $this->get_summary_formatted( $sync_log ),
     196                $sync_log->{self::MULTICHANNEL_ACTIVE}
     197                    ? $this->get_multichannel_summary_formatted( $sync_log )
     198                    : $this->get_summary_formatted( $sync_log ),
    146199                is_array( $errors ) && count( $errors ) ? implode( '<br>', $errors ) : __( 'None', 'bigcommerce' ),
    147200                $sync_log->{self::META_DURATION},
     
    151204
    152205        $sync_log_data = sprintf(
    153             '<table class="bc-product-sync-data-table">
     206            '<style>
     207                .bc-product-sync-data-table tr:nth-child(odd) {
     208                    background-color: #f2f2f2;
     209                }
     210            </style>
     211            <table class="bc-product-sync-data-table">
    154212                <tr>
    155213                    <th>#</th>
     
    178236                    'label' => '',
    179237                    'key'   => 'sync_logs',
    180                     'value' => $sync_log_data
    181                 ]
     238                    'value' => $sync_log_data,
     239                ],
    182240            ],
    183241        ];
     
    190248     *
    191249     * @param \WP_Post $post
     250     *
    192251     * @return string
    193252     */
    194     private function get_post_date_formatted( $post )  {
     253    private function get_post_date_formatted( $post ) {
    195254        $date_format = sprintf(
    196255            '%s %s',
     
    198257            get_option( 'time_format', 'H:i' )
    199258        );
     259
    200260        return get_the_date( $date_format, $post );
    201261    }
     
    211271            $timezone = 'UTC' . $timezone;
    212272        }
     273
    213274        return $timezone;
    214275    }
     
    220281     */
    221282    private function get_current_sync_id() {
     283        // Track the sync id so we can write the error after post status update.
     284        if ( $this->sync_id ) {
     285            return $this->sync_id;
     286        }
     287
    222288        $draft = get_posts( [
    223289            'post_type'      => self::NAME,
     
    227293        ] );
    228294
    229         return reset( $draft );
     295        $this->sync_id = reset( $draft );
     296
     297        return $this->sync_id;
    230298    }
    231299
     
    239307            'post_type'      => self::NAME,
    240308            'post_status'    => $status,
    241             'posts_per_page' => -1,
     309            'posts_per_page' => - 1,
    242310            'fields'         => 'ids',
    243311        ] );
     
    247315        }
    248316
    249         foreach( $sync_logs as $index => $post_id ) {
     317        foreach ( $sync_logs as $index => $post_id ) {
    250318            if ( $index < $keep ) {
    251319                continue;
     
    259327     *
    260328     * @param \WP_Post $sync_log
     329     *
    261330     * @return string
    262331     */
     
    286355
    287356        $out = array_map( function ( $line ) {
    288             return sprintf( '<span class="bc-sync-summary-meta">%s</span>', $line );
     357            return sprintf( '<span class="bc-sync-summary-meta">%s</span><br />', $line );
    289358        }, $out );
    290359
     
    292361    }
    293362
     363    /**
     364     * Get formatted summary
     365     *
     366     * @param \WP_Post $sync_log
     367     *
     368     * @return string
     369     */
     370    private function get_multichannel_summary_formatted( $sync_log ) {
     371        $multichannel_summary = $sync_log->{self::MULTICHANNEL_SUMMARY};
     372
     373        $summary = [];
     374
     375        foreach ( $multichannel_summary as $channel ) {
     376            $count_before = $channel['count_before'] ?? 0;
     377            $count_after  = $channel['count_after'] ?? 0;
     378            $new          = $count_after - $count_before;
     379
     380            $summary[] = sprintf( __( '<br /><b>%s</b>', 'bigcommerce' ), $channel['channel_name'] );
     381            $summary[] = sprintf( __( '%d Synced', 'bigcommerce' ), $channel['count_after'] );
     382            if ( $new > 0  ) {
     383                $summary[] = sprintf( __( '%d Added', 'bigcommerce' ), $new );
     384            }
     385
     386            $summary = array_map( function ( $line ) {
     387                return sprintf( '<span class="bc-sync-summary-meta">%s</span>', $line );
     388            }, $summary );
     389        }
     390
     391        return implode( '<br />', $summary );
     392    }
    294393}
  • bigcommerce/trunk/src/BigCommerce/Settings/Sections/Troubleshooting_Diagnostics.php

    r2617240 r2622003  
    2828    const TEXTBOX_NAME     = 'bigcommerce_diagnostics_output';
    2929    const LOG_ERRORS       = 'bigcommerce_diagnostics_log_import_errors';
     30    const LOG_FILE_SIZE    = 'bigcommerce_diagnostics_log_file_size';
    3031    const SYNC_SITE_URL    = 'bigcommerce_diagnostics_sync_site_url';
    3132
     
    9091        );
    9192
     93        register_setting(
     94            Settings_Screen::NAME,
     95            self::LOG_FILE_SIZE
     96        );
     97
     98        add_settings_field(
     99            self::LOG_FILE_SIZE,
     100            esc_html( __( 'Log file max size(MB)', 'bigcommerce' ) ),
     101            [ $this, 'render_log_file_size', ],
     102            Settings_Screen::NAME,
     103            self::NAME,
     104            [
     105                'min'         => 1,
     106                'max'         => 25,
     107                'type'        => 'number',
     108                'option'      => self::LOG_FILE_SIZE,
     109                'label'       => esc_html( __( 'Set log file size', 'bigcommerce' ) ),
     110                'description' => esc_html( __( 'Set log file max size in MB. If log file exceeds the limit it will be cleaned before new import', 'bigcommerce' ) ),
     111            ]
     112        );
     113
    92114        add_settings_field(
    93115            self::DIAGNOSTICS_NAME,
     
    136158    }
    137159
     160    public function render_log_file_size( $args ) {
     161        $value = get_option( $args[ 'option' ], 25 );
     162        $min   = isset( $args[ 'min' ] ) ? sprintf( 'min="%d"', $args[ 'min' ] ) : '';
     163        $max   = isset( $args[ 'max' ] ) ? sprintf( 'max="%d"', $args[ 'max' ] ) : '';
     164        $field = sprintf( '<input type="%1$s" value="%2$s" name="%3$s" id="%3$s" %4$s %5$s />', esc_attr( $args[ 'type' ] ), esc_attr( $value ), esc_attr( $args[ 'option' ] ), $min, $max );
     165        printf( '%s<p class="description">%s</p>', $field, esc_html( $args[ 'description' ] ) );
     166    }
     167
    138168    /**
    139169     * Sets a wp_send_json answer for the ajax call that holds
  • bigcommerce/trunk/src/BigCommerce/Taxonomies/Channel/Channel.php

    r2141486 r2622003  
    3737
    3838    /**
     39     * Should product sync be to all channels?
     40     *
     41     * @return bool
     42     */
     43    public static function multichannel_sync_to_all_channels() {
     44        /**
     45         * Filter whether multi-channel sync should sync to all channels.
     46         * Enabling this feature allows site owners to
     47         * connect to sync products to all channels or
     48         * only the channel it is assigned to.
     49         *
     50         * @param bool $enabled
     51         */
     52        return (bool) apply_filters( 'bigcommerce/channels/map-products-to-all-channels', false );
     53    }
     54
     55    /**
    3956     * @param int $channel_id
    4057     *
  • bigcommerce/trunk/vendor/autoload.php

    r2617240 r2622003  
    55require_once __DIR__ . '/composer/autoload_real.php';
    66
    7 return ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f::getLoader();
     7return ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119::getLoader();
  • bigcommerce/trunk/vendor/composer/autoload_real.php

    r2617240 r2622003  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f
     5class ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119
    66{
    77    private static $loader;
     
    2020        }
    2121
    22         spl_autoload_register(array('ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f', 'loadClassLoader'), true, true);
     22        spl_autoload_register(array('ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119', 'loadClassLoader'), true, true);
    2323        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
    24         spl_autoload_unregister(array('ComposerAutoloaderInit509873e0fe5d4df74a0ea698def2e38f', 'loadClassLoader'));
     24        spl_autoload_unregister(array('ComposerAutoloaderInit00d9fec88dbb4fdf0216f882209f6119', 'loadClassLoader'));
    2525
    2626        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
     
    2828            require_once __DIR__ . '/autoload_static.php';
    2929
    30             call_user_func(\Composer\Autoload\ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::getInitializer($loader));
     30            call_user_func(\Composer\Autoload\ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::getInitializer($loader));
    3131        } else {
    3232            $classMap = require __DIR__ . '/autoload_classmap.php';
     
    4040
    4141        if ($useStaticLoader) {
    42             $includeFiles = Composer\Autoload\ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$files;
     42            $includeFiles = Composer\Autoload\ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$files;
    4343        } else {
    4444            $includeFiles = require __DIR__ . '/autoload_files.php';
    4545        }
    4646        foreach ($includeFiles as $fileIdentifier => $file) {
    47             composerRequire509873e0fe5d4df74a0ea698def2e38f($fileIdentifier, $file);
     47            composerRequire00d9fec88dbb4fdf0216f882209f6119($fileIdentifier, $file);
    4848        }
    4949
     
    5252}
    5353
    54 function composerRequire509873e0fe5d4df74a0ea698def2e38f($fileIdentifier, $file)
     54function composerRequire00d9fec88dbb4fdf0216f882209f6119($fileIdentifier, $file)
    5555{
    5656    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • bigcommerce/trunk/vendor/composer/autoload_static.php

    r2617240 r2622003  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f
     7class ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119
    88{
    99    public static $files = array (
     
    11241124    {
    11251125        return \Closure::bind(function () use ($loader) {
    1126             $loader->prefixLengthsPsr4 = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$prefixLengthsPsr4;
    1127             $loader->prefixDirsPsr4 = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$prefixDirsPsr4;
    1128             $loader->prefixesPsr0 = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$prefixesPsr0;
    1129             $loader->classMap = ComposerStaticInit509873e0fe5d4df74a0ea698def2e38f::$classMap;
     1126            $loader->prefixLengthsPsr4 = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$prefixLengthsPsr4;
     1127            $loader->prefixDirsPsr4 = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$prefixDirsPsr4;
     1128            $loader->prefixesPsr0 = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$prefixesPsr0;
     1129            $loader->classMap = ComposerStaticInit00d9fec88dbb4fdf0216f882209f6119::$classMap;
    11301130
    11311131        }, null, ClassLoader::class);
Note: See TracChangeset for help on using the changeset viewer.