Plugin Updates
This commit is contained in:
@@ -2,13 +2,15 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\MarketingRecommendations;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RemoteSpecsEngine;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Marketing Recommendations engine.
|
||||
* This goes through the specs and gets marketing recommendations.
|
||||
*/
|
||||
class Init {
|
||||
class Init extends RemoteSpecsEngine {
|
||||
/**
|
||||
* Slug of the category specifying marketing extensions on the Woo.com store.
|
||||
*
|
||||
@@ -54,6 +56,29 @@ class Init {
|
||||
return $specs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process specs.
|
||||
*
|
||||
* @param array|null $specs Marketing recommendations spec array.
|
||||
* @return array
|
||||
*/
|
||||
protected static function evaluate_specs( array $specs = null ) {
|
||||
$suggestions = array();
|
||||
$errors = array();
|
||||
|
||||
foreach ( $specs as $spec ) {
|
||||
try {
|
||||
$suggestions[] = self::object_to_array( $spec );
|
||||
} catch ( \Throwable $e ) {
|
||||
$errors[] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'suggestions' => $suggestions,
|
||||
'errors' => $errors,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load recommended plugins from Woo.com
|
||||
@@ -61,14 +86,30 @@ class Init {
|
||||
* @return array
|
||||
*/
|
||||
public static function get_recommended_plugins(): array {
|
||||
$specs = self::get_specs();
|
||||
$result = array();
|
||||
$specs = self::get_specs();
|
||||
$results = self::evaluate_specs( $specs );
|
||||
|
||||
foreach ( $specs as $spec ) {
|
||||
$result[] = self::object_to_array( $spec );
|
||||
$specs_to_return = $results['suggestions'];
|
||||
$specs_to_save = null;
|
||||
|
||||
if ( empty( $specs_to_return ) ) {
|
||||
// When suggestions is empty, replace it with defaults and save for 3 hours.
|
||||
$specs_to_save = DefaultMarketingRecommendations::get_all();
|
||||
$specs_to_return = self::evaluate_specs( $specs_to_save )['suggestions'];
|
||||
} elseif ( count( $results['errors'] ) > 0 ) {
|
||||
// When suggestions is not empty but has errors, save it for 3 hours.
|
||||
$specs_to_save = $specs;
|
||||
}
|
||||
|
||||
return $result;
|
||||
if ( $specs_to_save ) {
|
||||
MarketingRecommendationsDataSourcePoller::get_instance()->set_specs_transient( $specs_to_save, 3 * HOUR_IN_SECONDS );
|
||||
}
|
||||
$errors = $results['errors'];
|
||||
if ( ! empty( $errors ) ) {
|
||||
self::log_errors( $errors );
|
||||
}
|
||||
|
||||
return $specs_to_return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,16 +180,22 @@ class Init {
|
||||
* This is used to convert the specs to an array so that they can be returned by the API.
|
||||
*
|
||||
* @param mixed $obj Object to convert.
|
||||
* @param array &$visited Reference to an array keeping track of all seen objects to detect circular references.
|
||||
* @return array
|
||||
*/
|
||||
protected static function object_to_array( $obj ) {
|
||||
public static function object_to_array( $obj, &$visited = array() ) {
|
||||
if ( is_object( $obj ) ) {
|
||||
$obj = (array) $obj;
|
||||
if ( in_array( $obj, $visited, true ) ) {
|
||||
// Circular reference detected.
|
||||
return null;
|
||||
}
|
||||
$visited[] = $obj;
|
||||
$obj = (array) $obj;
|
||||
}
|
||||
if ( is_array( $obj ) ) {
|
||||
$new = array();
|
||||
foreach ( $obj as $key => $val ) {
|
||||
$new[ $key ] = self::object_to_array( $val );
|
||||
$new[ $key ] = self::object_to_array( $val, $visited );
|
||||
}
|
||||
} else {
|
||||
$new = $obj;
|
||||
|
||||
@@ -168,7 +168,7 @@ class TaskList {
|
||||
* @return bool
|
||||
*/
|
||||
public function is_visible() {
|
||||
if ( ! $this->visible || ! count( $this->get_viewable_tasks() ) > 0 ) {
|
||||
if ( ! $this->visible || $this->is_hidden() || ! count( $this->get_viewable_tasks() ) > 0 ) {
|
||||
return false;
|
||||
}
|
||||
return ! $this->is_hidden();
|
||||
@@ -199,6 +199,7 @@ class TaskList {
|
||||
'action' => 'remove_card',
|
||||
'completed_task_count' => $completed_count,
|
||||
'incomplete_task_count' => count( $viewable_tasks ) - $completed_count,
|
||||
'tasklist_id' => $this->id,
|
||||
)
|
||||
);
|
||||
|
||||
@@ -324,11 +325,17 @@ class TaskList {
|
||||
* Track list completion of viewable tasks.
|
||||
*/
|
||||
public function possibly_track_completion() {
|
||||
if ( ! $this->is_complete() ) {
|
||||
if ( $this->has_previously_completed() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->has_previously_completed() ) {
|
||||
// If it's hidden, completion is tracked via hide method.
|
||||
if ( $this->is_hidden() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Expensive check, do it last.
|
||||
if ( ! $this->is_complete() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -336,7 +343,12 @@ class TaskList {
|
||||
$completed_lists[] = $this->get_list_id();
|
||||
update_option( self::COMPLETED_OPTION, $completed_lists );
|
||||
$this->maybe_set_default_layout( $completed_lists );
|
||||
$this->record_tracks_event( 'tasks_completed' );
|
||||
$this->record_tracks_event(
|
||||
'tasks_completed',
|
||||
array(
|
||||
'tasklist_id' => $this->id,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -407,7 +407,7 @@ class TaskLists {
|
||||
public static function setup_tasks_remaining() {
|
||||
$setup_list = self::get_list( 'setup' );
|
||||
|
||||
if ( ! $setup_list || $setup_list->is_hidden() || $setup_list->is_complete() ) {
|
||||
if ( ! $setup_list || $setup_list->is_hidden() || $setup_list->has_previously_completed() || $setup_list->is_complete() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,4 +30,31 @@ class EvaluateSuggestion {
|
||||
|
||||
return $suggestion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the specs and returns the visible suggestions.
|
||||
*
|
||||
* @param array $specs payment suggestion spec array.
|
||||
* @return array The visible suggestions and errors.
|
||||
*/
|
||||
public static function evaluate_specs( $specs ) {
|
||||
$suggestions = array();
|
||||
$errors = array();
|
||||
|
||||
foreach ( $specs as $spec ) {
|
||||
try {
|
||||
$suggestion = self::evaluate( $spec );
|
||||
if ( ! property_exists( $suggestion, 'is_visible' ) || $suggestion->is_visible ) {
|
||||
$suggestions[] = $suggestion;
|
||||
}
|
||||
} catch ( \Throwable $e ) {
|
||||
$errors[] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'suggestions' => $suggestions,
|
||||
'errors' => $errors,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,13 @@ defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\PaymentGatewaySuggestions\DefaultPaymentGateways;
|
||||
use Automattic\WooCommerce\Admin\Features\PaymentGatewaySuggestions\PaymentGatewaysController;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RemoteSpecsEngine;
|
||||
|
||||
/**
|
||||
* Remote Payment Methods engine.
|
||||
* This goes through the specs and gets eligible payment gateways.
|
||||
*/
|
||||
class Init {
|
||||
class Init extends RemoteSpecsEngine {
|
||||
/**
|
||||
* Option name for dismissed payment method suggestions.
|
||||
*/
|
||||
@@ -35,30 +36,31 @@ class Init {
|
||||
* @return array
|
||||
*/
|
||||
public static function get_suggestions( array $specs = null ) {
|
||||
$suggestions = array();
|
||||
if ( null === $specs ) {
|
||||
$specs = self::get_specs();
|
||||
$locale = get_user_locale();
|
||||
|
||||
$specs = is_array( $specs ) ? $specs : self::get_specs();
|
||||
$results = EvaluateSuggestion::evaluate_specs( $specs );
|
||||
$specs_to_return = $results['suggestions'];
|
||||
$specs_to_save = null;
|
||||
|
||||
if ( empty( $specs_to_return ) ) {
|
||||
// When suggestions is empty, replace it with defaults and save for 3 hours.
|
||||
$specs_to_save = DefaultPaymentGateways::get_all();
|
||||
$specs_to_return = EvaluateSuggestion::evaluate_specs( $specs_to_save )['suggestions'];
|
||||
} elseif ( count( $results['errors'] ) > 0 ) {
|
||||
// When suggestions is not empty but has errors, save it for 3 hours.
|
||||
$specs_to_save = $specs;
|
||||
}
|
||||
|
||||
foreach ( $specs as $spec ) {
|
||||
try {
|
||||
$suggestion = EvaluateSuggestion::evaluate( $spec );
|
||||
$suggestions[] = $suggestion;
|
||||
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
|
||||
} catch ( \Throwable $e ) {
|
||||
// Ignore errors.
|
||||
}
|
||||
if ( count( $results['errors'] ) > 0 ) {
|
||||
self::log_errors( $results['errors'] );
|
||||
}
|
||||
|
||||
return array_values(
|
||||
array_filter(
|
||||
$suggestions,
|
||||
function( $suggestion ) {
|
||||
return ! property_exists( $suggestion, 'is_visible' ) || $suggestion->is_visible;
|
||||
}
|
||||
)
|
||||
);
|
||||
if ( $specs_to_save ) {
|
||||
PaymentGatewaySuggestionsDataSourcePoller::get_instance()->set_specs_transient( array( $locale => $specs_to_save ), 3 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $specs_to_return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,11 +31,14 @@ class BlockRegistry {
|
||||
'woocommerce/product-pricing-field',
|
||||
'woocommerce/product-section',
|
||||
'woocommerce/product-section-description',
|
||||
'woocommerce/product-subsection',
|
||||
'woocommerce/product-subsection-description',
|
||||
'woocommerce/product-details-section-description',
|
||||
'woocommerce/product-tab',
|
||||
'woocommerce/product-toggle-field',
|
||||
'woocommerce/product-taxonomy-field',
|
||||
'woocommerce/product-text-field',
|
||||
'woocommerce/product-text-area-field',
|
||||
'woocommerce/product-number-field',
|
||||
'woocommerce/product-linked-list-field',
|
||||
);
|
||||
@@ -60,7 +63,6 @@ class BlockRegistry {
|
||||
'woocommerce/product-tag-field',
|
||||
'woocommerce/product-inventory-quantity-field',
|
||||
'woocommerce/product-variation-items-field',
|
||||
'woocommerce/product-variations-fields',
|
||||
'woocommerce/product-password-field',
|
||||
'woocommerce/product-list-field',
|
||||
'woocommerce/product-has-variations-notice',
|
||||
|
||||
@@ -34,6 +34,14 @@ interface ProductFormTemplateInterface extends BlockTemplateInterface {
|
||||
*/
|
||||
public function get_section_by_id( string $section_id ): ?SectionInterface;
|
||||
|
||||
/**
|
||||
* Gets subsection block by id.
|
||||
*
|
||||
* @param string $subsection_id subsection id.
|
||||
* @return SubsectionInterface|null
|
||||
*/
|
||||
public function get_subsection_by_id( string $subsection_id ): ?SubsectionInterface;
|
||||
|
||||
/**
|
||||
* Gets Block by id.
|
||||
*
|
||||
|
||||
@@ -15,9 +15,9 @@ interface SectionInterface extends BlockContainerInterface {
|
||||
* Adds a new sub-section to the section.
|
||||
*
|
||||
* @param array $block_config block config.
|
||||
* @return SectionInterface new block section.
|
||||
* @return SubsectionInterface new block sub-section.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface;
|
||||
public function add_subsection( array $block_config ): SubsectionInterface;
|
||||
|
||||
/**
|
||||
* Adds a new block to the section.
|
||||
@@ -25,4 +25,13 @@ interface SectionInterface extends BlockContainerInterface {
|
||||
* @param array $block_config block config.
|
||||
*/
|
||||
public function add_block( array $block_config ): BlockInterface;
|
||||
|
||||
/**
|
||||
* Adds a new sub-section to the section.
|
||||
*
|
||||
* @deprecated 8.6.0
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_section( array $block_config ): SubsectionInterface;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockContainerInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
|
||||
/**
|
||||
* Interface for subsection containers, which contain sub-sections and blocks.
|
||||
*/
|
||||
interface SubsectionInterface extends BlockContainerInterface {
|
||||
/**
|
||||
* Adds a new block to the sub-section.
|
||||
*
|
||||
* @param array $block_config block config.
|
||||
*/
|
||||
public function add_block( array $block_config ): BlockInterface;
|
||||
}
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ShippingPartnerSuggestions;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\RuleEvaluator;
|
||||
use Automattic\WooCommerce\Admin\Features\PaymentGatewaySuggestions\EvaluateSuggestion;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RemoteSpecsEngine;
|
||||
|
||||
/**
|
||||
* Class ShippingPartnerSuggestions
|
||||
*/
|
||||
class ShippingPartnerSuggestions {
|
||||
class ShippingPartnerSuggestions extends RemoteSpecsEngine {
|
||||
|
||||
/**
|
||||
* Go through the specs and run them.
|
||||
@@ -15,31 +16,34 @@ class ShippingPartnerSuggestions {
|
||||
* @param array|null $specs shipping partner suggestion spec array.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_suggestions( $specs = null ) {
|
||||
$suggestions = array();
|
||||
if ( null === $specs ) {
|
||||
$specs = self::get_specs_from_datasource();
|
||||
public static function get_suggestions( array $specs = null ) {
|
||||
$locale = get_user_locale();
|
||||
|
||||
$specs = is_array( $specs ) ? $specs : self::get_specs();
|
||||
$results = EvaluateSuggestion::evaluate_specs( $specs );
|
||||
$specs_to_return = $results['suggestions'];
|
||||
$specs_to_save = null;
|
||||
|
||||
if ( empty( $specs_to_return ) ) {
|
||||
// When suggestions is empty, replace it with defaults and save for 3 hours.
|
||||
$specs_to_save = DefaultShippingPartners::get_all();
|
||||
$specs_to_return = EvaluateSuggestion::evaluate_specs( $specs_to_save )['suggestions'];
|
||||
} elseif ( count( $results['errors'] ) > 0 ) {
|
||||
// When suggestions is not empty but has errors, save it for 3 hours.
|
||||
$specs_to_save = $specs;
|
||||
}
|
||||
|
||||
$rule_evaluator = new RuleEvaluator();
|
||||
foreach ( $specs as &$spec ) {
|
||||
$spec = is_array( $spec ) ? (object) $spec : $spec;
|
||||
if ( isset( $spec->is_visible ) ) {
|
||||
$is_visible = $rule_evaluator->evaluate( $spec->is_visible );
|
||||
if ( $is_visible ) {
|
||||
$spec->is_visible = true;
|
||||
$suggestions[] = $spec;
|
||||
}
|
||||
}
|
||||
if ( $specs_to_save ) {
|
||||
ShippingPartnerSuggestionsDataSourcePoller::get_instance()->set_specs_transient( array( $locale => $specs_to_save ), 3 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $suggestions;
|
||||
return $specs_to_return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specs or fetch remotely if they don't exist.
|
||||
*/
|
||||
public static function get_specs_from_datasource() {
|
||||
public static function get_specs() {
|
||||
if ( 'no' === get_option( 'woocommerce_show_marketplace_suggestions', 'yes' ) ) {
|
||||
/**
|
||||
* It can be used to modify shipping partner suggestions spec.
|
||||
|
||||
Reference in New Issue
Block a user