Skip to content

Commit

Permalink
Merge pull request #95 from moderntribe/release/0.15.0
Browse files Browse the repository at this point in the history
Package version 0.15.0
  • Loading branch information
bookernath authored Nov 9, 2018
2 parents 9a82b99 + f10a78b commit ba5a099
Show file tree
Hide file tree
Showing 18 changed files with 278 additions and 37 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [0.15.0]

### Added

- Automatically add new products to the BigCommerce channel on next import

### Fixed

- Fixed an error in channel initialization that limited channels to the first 100 products

### Removed

- Removed the missing SSL notice from the admin. Instead, a smaller notice is
displayed next to the Embedded Checkout option, explaining why it is disabled.

## [0.14.0]

### Added
Expand Down Expand Up @@ -137,6 +152,7 @@


[Unreleased]: https://github.com/moderntribe/bigcommerce/compare/master...develop
[0.15.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/0.14.0...0.15.0
[0.14.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/0.13.0...0.14.0
[0.13.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/0.12.0...0.13.0
[0.12.0]: https://github.com/bigcommerce/bigcommerce-for-wordpress/compare/0.11.1...0.12.0
Expand Down
2 changes: 1 addition & 1 deletion bigcommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Plugin Name: BigCommerce for WordPress
Description: BigCommerce for WordPress
Author: Modern Tribe
Version: 0.14.0
Version: 0.15.0
Author URI: http://www.tri.be
Requires PHP: 5.6.24
Text Domain: bigcommerce
Expand Down
2 changes: 1 addition & 1 deletion build-timestamp.php
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?php
define('BIGCOMMERCE_ASSETS_BUILD_TIMESTAMP', '8.26.11.02.2018');
define('BIGCOMMERCE_ASSETS_BUILD_TIMESTAMP', '6.36.11.08.2018');
18 changes: 14 additions & 4 deletions src/BigCommerce/Checkout/Requirements_Notice.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ public function check_requirements() {
sprintf( '<a href="%s">%s</a>', esc_url( $this->get_payment_configuration_url() ), __( 'Configure Payment', 'bigcommerce' ) )
);
}
if ( empty( $status[ 'ssl' ] ) ) {
$notices[] = __( 'An SSL certificate on your domain is required.', 'bigcommerce' );
}
/* 2018-11-07: We have opted not to show a notification for a missing SSL certificate. It's not _really
* required unless embedded checkout is enabled */
//if ( empty( $status[ 'ssl' ] ) ) {
// $notices[] = __( 'An SSL certificate on your domain is required.', 'bigcommerce' );
//}

if ( empty( $notices ) ) {
return;
Expand Down Expand Up @@ -194,10 +196,18 @@ private function refresh_url( $redirect = '' ) {
* @filter pre_option_ . Cart::OPTION_EMBEDDED_CHECKOUT
*/
public function filter_embedded_checkout( $option ) {
if ( ! $this->get_ssl_status() ) {
if ( ! $this->can_enable_embedded_checkout() ) {
return 0; // not `false`, because WP would ignore it
}

return $option;
}

/**
* @return bool
* @filter bigcommerce/checkout/can_embed
*/
public function can_enable_embedded_checkout() {
return (bool) $this->get_ssl_status();
}
}
10 changes: 7 additions & 3 deletions src/BigCommerce/Container/Checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ private function requirements( Container $container ) {
$container[ self::REQUIREMENTS_NOTICE ]->refresh_status();
} ), 10, 0 );

add_filter( 'pre_option_' . \BigCommerce\Settings\Sections\Cart::OPTION_EMBEDDED_CHECKOUT, $this->create_callback( 'embedded_checkout_requirement_check', function( $value ) use ( $container ) {
add_filter( 'pre_option_' . \BigCommerce\Settings\Sections\Cart::OPTION_EMBEDDED_CHECKOUT, $this->create_callback( 'embedded_checkout_requirement_check', function ( $value ) use ( $container ) {
return $container[ self::REQUIREMENTS_NOTICE ]->filter_embedded_checkout( $value );
}), 10, 1 );
} ), 10, 1 );

add_filter( 'bigcommerce/checkout/can_embed', $this->create_callback( 'embedded_checkout_supported', function ( $supported ) use ( $container ) {
return $container[ self::REQUIREMENTS_NOTICE ]->can_enable_embedded_checkout();
} ), 1, 1 );
}

private function customer_login( Container $container ) {
$container[ self::LOGIN ] = function( Container $container ) {
$container[ self::LOGIN ] = function ( Container $container ) {
return new Customer_Login( $container[ Merchant::ONBOARDING_API ], $container[ Api::FACTORY ]->store() );
};

Expand Down
15 changes: 14 additions & 1 deletion src/BigCommerce/Container/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Import extends Provider {
const TIMEOUT = 'timeout';

const START = 'import.start';
const LISTING = 'import.listings';
const CHANNEL = 'import.channel';
const FETCH = 'import.fetch_ids';
const MARK = 'import.mark_deleted';
Expand Down Expand Up @@ -80,6 +81,10 @@ private function process( Container $container ) {
return new Processors\Start_Import();
};

$container[ self::LISTING ] = function ( Container $container ) {
return new Processors\Listing_ID_Fetcher( $container[ Api::FACTORY ]->channels() );
};

$container[ self::CHANNEL ] = function ( Container $container ) {
return new Processors\Channel_Initializer( $container[ Api::FACTORY ]->channels(), $container[ Api::FACTORY ]->catalog() );
};
Expand Down Expand Up @@ -113,12 +118,20 @@ private function process( Container $container ) {
} );
add_action( 'bigcommerce/import/start', $start, 10, 0 );

// Step: Get a list of all products already listed in the channel

$channel = $this->create_callback( 'process_listings', function () use ( $container ) {
$container[ self::LISTING ]->run();
} );
add_action( 'bigcommerce/import/run/status=' . Runner\Status::STARTED, $channel, 10, 0 );
add_action( 'bigcommerce/import/run/status=' . Runner\Status::FETCHING_LISTING_IDS, $channel, 10, 0 );

// Step: Make sure that the channel is fully initialized with products. May take multiple batches

$channel = $this->create_callback( 'process_channel', function () use ( $container ) {
$container[ self::CHANNEL ]->run();
} );
add_action( 'bigcommerce/import/run/status=' . Runner\Status::STARTED, $channel, 10, 0 );
add_action( 'bigcommerce/import/run/status=' . Runner\Status::FETCHED_LISTING_IDS, $channel, 10, 0 );
add_action( 'bigcommerce/import/run/status=' . Runner\Status::INITIALIZING_CHANNEL, $channel, 10, 0 );

// Step: Import product IDs. May take multiple batches
Expand Down
31 changes: 20 additions & 11 deletions src/BigCommerce/Import/Processors/Channel_Initializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use BigCommerce\Api\v3\Model\Variant;
use BigCommerce\Import\Runner\Status;
use BigCommerce\Settings\Sections\Channels;
use BigCommerce\Settings\Sections\Import;

/**
* Class Channel_Initializer
Expand Down Expand Up @@ -63,7 +64,7 @@ public function run() {

$page = $this->get_page();
if ( empty( $page ) ) {
if ( $this->channel_has_listings( $channel_id ) ) {
if ( ! get_option( Import::OPTION_NEW_PRODUCTS, 1 ) && $this->channel_has_listings( $channel_id ) ) {
$status->set_status( Status::INITIALIZED_CHANNEL );
$this->clear_state();

Expand Down Expand Up @@ -117,7 +118,13 @@ public function run() {
return;
}

$listing_requests = array_map( function ( Product $product ) use ( $channel_id ) {
$id_map = get_option( Listing_ID_Fetcher::PRODUCT_LISTING_MAP, [] ) ?: [];

$listing_requests = array_values( array_filter( array_map( function ( Product $product ) use ( $channel_id, $id_map ) {
if ( array_key_exists( $product->getId(), $id_map ) ) {
return false;
}

return new Listing( [
'channel_id' => (int) $channel_id,
'product_id' => (int) $product->getId(),
Expand All @@ -132,18 +139,20 @@ public function run() {
] );
}, $product->getVariants() ),
] );
}, $response->getData() );
}, $response->getData() ) ) );


try {
$response = $this->channels->createChannelListings( $channel_id, $listing_requests );
} catch ( ApiException $e ) {
do_action( 'bigcommerce/import/error', $e->getMessage(), [
'response' => $e->getResponseBody(),
'headers' => $e->getResponseHeaders(),
] );
if ( ! empty( $listing_requests ) ) {
try {
$this->channels->createChannelListings( $channel_id, $listing_requests );
} catch ( ApiException $e ) {
do_action( 'bigcommerce/import/error', $e->getMessage(), [
'response' => $e->getResponseBody(),
'headers' => $e->getResponseHeaders(),
] );

return;
return;
}
}

$total_pages = $response->getMeta()->getPagination()->getTotalPages();
Expand Down
133 changes: 133 additions & 0 deletions src/BigCommerce/Import/Processors/Listing_ID_Fetcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php


namespace BigCommerce\Import\Processors;


use BigCommerce\Api\v3\Api\ChannelsApi;
use BigCommerce\Api\v3\ApiException;
use BigCommerce\Api\v3\Api\CatalogApi;
use BigCommerce\Api\v3\Model\Listing;
use BigCommerce\Api\v3\Model\ListingCollectionResponse;
use BigCommerce\Import\Runner\Status;
use BigCommerce\Settings\Sections\Channels;

class Listing_ID_Fetcher implements Import_Processor {
const STATE_OPTION = 'bigcommerce_import_listing_id_fetcher_state';
const PRODUCT_LISTING_MAP = 'bigcommerce_product_listing_map';

/**
* @var ChannelsApi
*/
private $channels;

/**
* @var int
*/
private $limit;

/**
* Listing_ID_Fetcher constructor.
*
* @param ChannelsApi $channels The Channels API connection to use for the import
* @param int $limit Number of listing IDs to fetch per request
*/
public function __construct( ChannelsApi $channels, $limit = 100 ) {
$this->limit = $limit;
$this->channels = $channels;
}

public function run() {
$status = new Status();
$status->set_status( Status::FETCHING_LISTING_IDS );

$channel_id = get_option( Channels::CHANNEL_ID, 0 );
if ( empty( $channel_id ) ) {
do_action( 'bigcommerce/import/error', __( 'Channel ID is not set. Product import canceled.', 'bigcommerce' ) );

return;
}

$next = $this->get_next();
if ( empty( $next ) ) {
update_option( self::PRODUCT_LISTING_MAP, [], false );
}

try {
$response = $this->channels->listChannelListings( $channel_id, $this->limit, $next ?: null );
} catch ( ApiException $e ) {
do_action( 'bigcommerce/import/error', $e->getMessage(), [
'response' => $e->getResponseBody(),
'headers' => $e->getResponseHeaders(),
] );

return;
}

$id_map = get_option( self::PRODUCT_LISTING_MAP, [] ) ?: [];
foreach ( $response->getData() as $listing ) {
$id_map[ (int) $listing->getProductId() ] = (int) $listing->getListingId();
}
update_option( self::PRODUCT_LISTING_MAP, $id_map, false );

$next = $this->extract_next_from_response( $response );
if ( $next ) {
$this->set_next( $next );
} else {
$status->set_status( Status::FETCHED_LISTING_IDS );
$this->clear_state();
}
}

/**
* @param ListingCollectionResponse $response
*
* @return int The value for the parameter to use for the next page of results
*/
private function extract_next_from_response( ListingCollectionResponse $response ) {
$next_args = $response->getMeta()->getPagination()->getLinks()->getNext();
if ( empty( $next_args ) ) {
return 0;
}
$next_args = ltrim( $next_args, '?' );
parse_str( $next_args, $args );
// Eventually, the API should change to support the page parameter. Until then, use after.
if ( empty( $args[ 'after' ] ) ) {
return 0;
}

return (int) $args[ 'after' ];
}

private function get_next() {
$state = $this->get_state();
if ( ! array_key_exists( 'next', $state ) ) {
return 0;
}

return $state[ 'next' ];
}

private function set_next( $next ) {
$state = $this->get_state();
$state[ 'next' ] = (int) $next;
$this->set_state( $state );
}

private function get_state() {
$state = get_option( self::STATE_OPTION, [] );
if ( ! is_array( $state ) ) {
return [];
}

return $state;
}

private function set_state( array $state ) {
update_option( self::STATE_OPTION, $state, false );
}

private function clear_state() {
delete_option( self::STATE_OPTION );
}
}
2 changes: 1 addition & 1 deletion src/BigCommerce/Import/Processors/Product_ID_Fetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function run() {
global $wpdb;
$inserts = array_map( function ( Listing $listing ) {
$modified = $listing->getDateModified() ?: $listing->getDateCreated() ?: new \DateTime();
$action = ! in_array( $listing->getState(), [ 'DELETED_GROUP' ] ) ? 'update' : 'delete';
$action = ! in_array( $listing->getState(), [ 'DELETED_GROUP', 'deleted' ] ) ? 'update' : 'delete';

return sprintf( '( %d, %d, "%s", "%s", "%s" )', $listing->getProductId(), $listing->getListingId(), $modified->format( 'Y-m-d H:i:s' ), $action, date( 'Y-m-d H:i:s' ) );
}, $response->getData() );
Expand Down
2 changes: 2 additions & 0 deletions src/BigCommerce/Import/Runner/Status.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
class Status {
const NOT_STARTED = 'not_started';
const STARTED = 'started';
const FETCHING_LISTING_IDS = 'fetching_listing_ids';
const FETCHED_LISTING_IDS = 'fetched_listing_ids';
const INITIALIZING_CHANNEL = 'initializing_channel';
const INITIALIZED_CHANNEL = 'initialized_channel';
const FETCHING_PRODUCT_IDS = 'fetching_product_ids';
Expand Down
2 changes: 1 addition & 1 deletion src/BigCommerce/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace BigCommerce;

class Plugin {
const VERSION = '0.14.0';
const VERSION = '0.15.0';

protected static $_instance;

Expand Down
6 changes: 3 additions & 3 deletions src/BigCommerce/Post_Types/Product/Channel_Sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public function post_updated( $post_id, $post ) {
return;
}

$channel_id = get_option( Channels::CHANNEL_ID, 0 );
$listing_id = $this->get_listing_id( $post_id );
$channel_id = (int) get_option( Channels::CHANNEL_ID, 0 );
$listing_id = (int) $this->get_listing_id( $post_id );
if ( empty( $channel_id ) || empty( $listing_id ) ) {
return;
}
Expand All @@ -76,7 +76,7 @@ public function post_updated( $post_id, $post ) {
$update_request = new UpdateListingRequest( [
'channel_id' => $channel_id,
'listing_id' => $listing_id,
'product_id' => $listing->getProductId(),
'product_id' => (int) $listing->getProductId(),
'state' => $this->get_listing_state( $post_id, $listing ),
'name' => $this->get_listing_title( $post_id, $listing ),
'description' => $this->get_listing_description( $post_id, $listing ),
Expand Down
Loading

0 comments on commit ba5a099

Please sign in to comment.