Throw custom exception in NoteTraits if notes are disabled (https://github.com/woocommerce/woocommerce-admin/pull/6771)
A custom exception `NotesUnavailableException` will be thrown on attempts to load the "admin-note" data store using the `Notes::load_data_store()` method introduced in this PR. All calls to `\WC_Data_Store::load( 'admin-note' )` were replaced with calls to the above method.
This commit is contained in:
parent
7bed3d01e8
commit
4c17776815
|
@ -106,6 +106,7 @@ Release and roadmap notes are available on the [WooCommerce Developers Blog](htt
|
|||
- Fix: Parsing bad JSON string data from user WooCommerce meta. #6819
|
||||
- Fix: Remove PayPal for India #6828
|
||||
- Fix: Report filters expecting specific ordering. #6847
|
||||
- Fix: Throw exception if the data store cannot be loaded when trying to use notes. #6771
|
||||
- Performance: Avoid updating customer info synchronously from the front end. #6765
|
||||
- Tweak: Add settings_section event prop for CES #6762
|
||||
- Tweak: Refactor payments to allow management of methods #6786
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace Automattic\WooCommerce\Admin\Composer;
|
|||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\DeactivatePlugin;
|
||||
use Automattic\WooCommerce\Admin\Notes\Notes;
|
||||
use Automattic\WooCommerce\Admin\Notes\NotesUnavailableException;
|
||||
use Automattic\WooCommerce\Admin\FeaturePlugin;
|
||||
|
||||
/**
|
||||
|
@ -152,8 +154,8 @@ class Package {
|
|||
*/
|
||||
private static function is_notes_initialized() {
|
||||
try {
|
||||
\WC_Data_Store::load( 'admin-note' );
|
||||
} catch ( \Exception $e ) {
|
||||
Notes::load_data_store();
|
||||
} catch ( NotesUnavailableException $e ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -76,7 +76,7 @@ class InstallJPAndWCSPlugins {
|
|||
}
|
||||
|
||||
// Action any notes with a matching name.
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
|
||||
foreach ( $note_ids as $note_id ) {
|
||||
|
|
|
@ -69,7 +69,7 @@ class MerchantEmailNotifications {
|
|||
* Send all the notifications type `email`.
|
||||
*/
|
||||
public static function run() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$notes = $data_store->get_notes(
|
||||
array(
|
||||
'type' => array( Note::E_WC_ADMIN_NOTE_EMAIL ),
|
||||
|
|
|
@ -35,7 +35,7 @@ class NavigationFeedbackFollowUp {
|
|||
}
|
||||
|
||||
// Check that the first note was created.
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( 'wc-admin-navigation-feedback' );
|
||||
if ( empty( $note_ids ) ) {
|
||||
return;
|
||||
|
|
|
@ -68,7 +68,7 @@ class NavigationNudge {
|
|||
return;
|
||||
}
|
||||
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
|
||||
if ( ! empty( $note_ids ) ) {
|
||||
|
|
|
@ -84,7 +84,7 @@ class Note extends \WC_Data {
|
|||
$this->set_object_read( true );
|
||||
}
|
||||
|
||||
$this->data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$this->data_store = Notes::load_data_store();
|
||||
if ( $this->get_id() > 0 ) {
|
||||
$this->data_store->read( $this );
|
||||
}
|
||||
|
|
|
@ -27,9 +27,11 @@ trait NoteTraits {
|
|||
|
||||
/**
|
||||
* Check if the note has been previously added.
|
||||
*
|
||||
* @throws NotesUnavailableException Throws exception when notes are unavailable.
|
||||
*/
|
||||
public static function note_exists() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
return ! empty( $note_ids );
|
||||
}
|
||||
|
@ -38,6 +40,7 @@ trait NoteTraits {
|
|||
* Checks if a note can and should be added.
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotesUnavailableException Throws exception when notes are unavailable.
|
||||
*/
|
||||
public static function can_be_added() {
|
||||
$note = self::get_note();
|
||||
|
@ -62,6 +65,8 @@ trait NoteTraits {
|
|||
|
||||
/**
|
||||
* Add the note if it passes predefined conditions.
|
||||
*
|
||||
* @throws NotesUnavailableException Throws exception when notes are unavailable.
|
||||
*/
|
||||
public static function possibly_add_note() {
|
||||
$note = self::get_note();
|
||||
|
@ -75,6 +80,8 @@ trait NoteTraits {
|
|||
|
||||
/**
|
||||
* Alias this method for backwards compatibility.
|
||||
*
|
||||
* @throws NotesUnavailableException Throws exception when notes are unavailable.
|
||||
*/
|
||||
public static function add_note() {
|
||||
self::possibly_add_note();
|
||||
|
@ -84,9 +91,11 @@ trait NoteTraits {
|
|||
* Possibly delete the note, if it exists in the database. Note that this
|
||||
* is a hard delete, for where it doesn't make sense to soft delete or
|
||||
* action the note.
|
||||
*
|
||||
* @throws NotesUnavailableException Throws exception when notes are unavailable.
|
||||
*/
|
||||
public static function possibly_delete_note() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
|
||||
foreach ( $note_ids as $note_id ) {
|
||||
|
@ -102,9 +111,10 @@ trait NoteTraits {
|
|||
* Get if the note has been actioned.
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotesUnavailableException Throws exception when notes are unavailable.
|
||||
*/
|
||||
public static function has_note_been_actioned() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
|
||||
if ( ! empty( $note_ids ) ) {
|
||||
|
|
|
@ -34,7 +34,7 @@ class Notes {
|
|||
* @return array Array of arrays.
|
||||
*/
|
||||
public static function get_notes( $context = 'edit', $args = array() ) {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
$raw_notes = $data_store->get_notes( $args );
|
||||
$notes = array();
|
||||
foreach ( (array) $raw_notes as $raw_note ) {
|
||||
|
@ -90,7 +90,7 @@ class Notes {
|
|||
* @return int
|
||||
*/
|
||||
public static function get_notes_count( $type = array(), $status = array() ) {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
return $data_store->get_notes_count( $type, $status );
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Notes {
|
|||
return;
|
||||
}
|
||||
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
|
||||
foreach ( $names as $name ) {
|
||||
$note_ids = $data_store->get_notes_with_name( $name );
|
||||
|
@ -163,7 +163,7 @@ class Notes {
|
|||
* @return array Array of notes.
|
||||
*/
|
||||
public static function delete_all_notes() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
// Here we filter for the same params we are using to show the note list in client side.
|
||||
$raw_notes = $data_store->get_notes(
|
||||
array(
|
||||
|
@ -196,7 +196,7 @@ class Notes {
|
|||
* Clear note snooze status if the reminder date has been reached.
|
||||
*/
|
||||
public static function unsnooze_notes() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
$raw_notes = $data_store->get_notes(
|
||||
array(
|
||||
'status' => array( Note::E_WC_ADMIN_NOTE_SNOOZED ),
|
||||
|
@ -247,7 +247,7 @@ class Notes {
|
|||
return;
|
||||
}
|
||||
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
$notes = $data_store->get_notes(
|
||||
array(
|
||||
'type' => array( Note::E_WC_ADMIN_NOTE_MARKETING ),
|
||||
|
@ -266,7 +266,7 @@ class Notes {
|
|||
* Delete actioned survey notes.
|
||||
*/
|
||||
public static function possibly_delete_survey_notes() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
$notes = $data_store->get_notes(
|
||||
array(
|
||||
'type' => array( Note::E_WC_ADMIN_NOTE_SURVEY ),
|
||||
|
@ -290,7 +290,7 @@ class Notes {
|
|||
* @return string|bool The note status.
|
||||
*/
|
||||
public static function get_note_status( $note_name ) {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = self::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( $note_name );
|
||||
|
||||
if ( empty( $note_ids ) ) {
|
||||
|
@ -434,4 +434,25 @@ class Notes {
|
|||
}
|
||||
return $screen_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the data store.
|
||||
*
|
||||
* If the "admin-note" data store is unavailable, attempts to load it
|
||||
* will result in an exception.
|
||||
* This method catches that exception and throws a custom one instead.
|
||||
*
|
||||
* @return \WC_Data_Store The "admin-note" data store.
|
||||
* @throws NotesUnavailableException Throws exception if data store loading fails.
|
||||
*/
|
||||
public static function load_data_store() {
|
||||
try {
|
||||
return \WC_Data_Store::load( 'admin-note' );
|
||||
} catch ( \Exception $e ) {
|
||||
throw new NotesUnavailableException(
|
||||
'woocommerce_admin_notes_unavailable',
|
||||
__( 'Notes are unavailable because the "admin-note" data store cannot be loaded.', 'woocommerce-admin' )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* WooCommerce Admin Notes Unavailable Exception Class
|
||||
*
|
||||
* Exception class thrown when an attempt to use notes is made but notes are unavailable.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Notes;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Notes\NotesUnavailableException class.
|
||||
*/
|
||||
class NotesUnavailableException extends \WC_Data_Exception {}
|
|
@ -49,7 +49,7 @@ class WooCommercePayments {
|
|||
return;
|
||||
}
|
||||
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
|
||||
// We already have this note? Then mark the note as actioned.
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
|
|
|
@ -104,7 +104,7 @@ class WooSubscriptionsNotes {
|
|||
*/
|
||||
public function check_connection() {
|
||||
if ( ! $this->is_connected() ) {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::CONNECTION_NOTE_NAME );
|
||||
if ( ! empty( $note_ids ) ) {
|
||||
// We already have a connection note. Exit early.
|
||||
|
@ -216,7 +216,7 @@ class WooSubscriptionsNotes {
|
|||
public function prune_inactive_subscription_notes() {
|
||||
$active_product_ids = $this->get_subscription_active_product_ids();
|
||||
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::SUBSCRIPTION_NOTE_NAME );
|
||||
|
||||
foreach ( (array) $note_ids as $note_id ) {
|
||||
|
@ -239,7 +239,7 @@ class WooSubscriptionsNotes {
|
|||
public function find_note_for_product_id( $product_id ) {
|
||||
$product_id = intval( $product_id );
|
||||
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( self::SUBSCRIPTION_NOTE_NAME );
|
||||
foreach ( (array) $note_ids as $note_id ) {
|
||||
$note = Notes::get_note( $note_id );
|
||||
|
|
|
@ -21,7 +21,7 @@ class SpecRunner {
|
|||
* @param object $stored_state Stored state.
|
||||
*/
|
||||
public static function run_spec( $spec, $stored_state ) {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
|
||||
// Create or update the note.
|
||||
$existing_note_ids = $data_store->get_notes_with_name( $spec->slug );
|
||||
|
|
|
@ -39,7 +39,7 @@ class WC_Tests_Learn_More_About_Variable_Product extends WC_Unit_Test_Case {
|
|||
wp_insert_post( $product );
|
||||
|
||||
// Then we should have LearnMoreAboutVariableProducts note.
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$note_ids = $data_store->get_notes_with_name( LearnMoreAboutVariableProducts::NOTE_NAME );
|
||||
$this->assertNotEmpty( $note_ids );
|
||||
$this->assertCount( 1, $note_ids );
|
||||
|
@ -111,7 +111,7 @@ class WC_Tests_Learn_More_About_Variable_Product extends WC_Unit_Test_Case {
|
|||
* @return array
|
||||
*/
|
||||
protected function get_note_ids() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
return $data_store->get_notes_with_name( LearnMoreAboutVariableProducts::NOTE_NAME );
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class WC_Tests_Marketing_Notes extends WC_Unit_Test_Case {
|
|||
* Tests that a marketing note can be added.
|
||||
*/
|
||||
public function test_add_remove_marketing_note() {
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
|
||||
$note = new Note();
|
||||
$note->set_title( 'PHPUNIT_TEST_MARKETING_NOTE' );
|
||||
|
@ -64,7 +64,7 @@ class WC_Tests_Marketing_Notes extends WC_Unit_Test_Case {
|
|||
WooCommercePayments::possibly_add_note();
|
||||
|
||||
// Load all marketing notes and check that the note was not added.
|
||||
$data_store = \WC_Data_Store::load( 'admin-note' );
|
||||
$data_store = Notes::load_data_store();
|
||||
$notes = $data_store->get_notes(
|
||||
array(
|
||||
'type' => array( Note::E_WC_ADMIN_NOTE_MARKETING ),
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/**
|
||||
* NoteTraits tests
|
||||
*
|
||||
* @package WooCommerce\Admin\Tests\Notes
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\NotesUnavailableException;
|
||||
use Automattic\WooCommerce\Admin\Notes\Note;
|
||||
use Automattic\WooCommerce\Admin\Notes\Notes;
|
||||
use Automattic\WooCommerce\Admin\Notes\NoteTraits;
|
||||
|
||||
/**
|
||||
* Class WC_Tests_NoteTraits
|
||||
*/
|
||||
class WC_Tests_NoteTraits extends WC_Unit_Test_Case {
|
||||
|
||||
/** Host the traits class we are testing */
|
||||
use NoteTraits;
|
||||
|
||||
/**
|
||||
* Constant required to use NoteTraits.
|
||||
*/
|
||||
const NOTE_NAME = 'Test note';
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
* @dataProvider methods_causing_exception_if_data_store_cannot_be_loaded_provider
|
||||
* @dataProvider methods_never_causing_exception_provider
|
||||
*
|
||||
* @param callable $callback Tested NoteTraits method.
|
||||
*/
|
||||
public function test_no_exception_is_thrown_if_data_store_can_be_loaded( $callback ) {
|
||||
$callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider methods_causing_exception_if_data_store_cannot_be_loaded_provider
|
||||
*
|
||||
* @param callable $callback Tested NoteTraits method.
|
||||
*/
|
||||
public function test_exception_is_thrown_if_data_store_cannot_be_loaded( $callback ) {
|
||||
add_filter( 'woocommerce_data_stores', '__return_empty_array' );
|
||||
$this->expectException( NotesUnavailableException::class );
|
||||
$callback();
|
||||
remove_filter( 'woocommerce_data_stores', '__return_empty_array' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
* @dataProvider methods_never_causing_exception_provider
|
||||
*
|
||||
* @param callable $callback Tested NoteTraits method.
|
||||
*/
|
||||
public function test_no_exception_is_thrown_even_if_data_store_cannot_be_loaded( $callback ) {
|
||||
add_filter( 'woocommerce_data_stores', '__return_empty_array' );
|
||||
$callback();
|
||||
remove_filter( 'woocommerce_data_stores', '__return_empty_array' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Method required to use NoteTraits.
|
||||
*
|
||||
* @return Note
|
||||
*/
|
||||
public static function get_note() {
|
||||
return new Note();
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider providing methods that should throw an exception
|
||||
* only if the "admin-note" data store cannot be loaded.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function methods_causing_exception_if_data_store_cannot_be_loaded_provider() {
|
||||
return array(
|
||||
array(
|
||||
function () {
|
||||
self::note_exists();
|
||||
},
|
||||
),
|
||||
array(
|
||||
function () {
|
||||
self::can_be_added();
|
||||
},
|
||||
),
|
||||
array(
|
||||
function () {
|
||||
self::possibly_add_note();
|
||||
},
|
||||
),
|
||||
array(
|
||||
function () {
|
||||
self::add_note();
|
||||
},
|
||||
),
|
||||
array(
|
||||
function () {
|
||||
self::possibly_delete_note();
|
||||
},
|
||||
),
|
||||
array(
|
||||
function () {
|
||||
self::has_note_been_actioned();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider providing methods that should not throw
|
||||
* an exception regardless of the data store being available.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function methods_never_causing_exception_provider() {
|
||||
return array(
|
||||
array(
|
||||
function () {
|
||||
self::wc_admin_active_for( 123 );
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Notes tests
|
||||
*
|
||||
* @package WooCommerce\Admin\Tests\Notes
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\NotesUnavailableException;
|
||||
use Automattic\WooCommerce\Admin\Notes\Notes;
|
||||
|
||||
/**
|
||||
* Class WC_Tests_Notes
|
||||
*/
|
||||
class WC_Tests_Notes extends WC_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* If the "admin-note" data store exists, the data store should be
|
||||
* loaded and returned.
|
||||
*/
|
||||
public function test_loads_data_store_if_exists() {
|
||||
$this->assertInstanceOf( \WC_Data_Store::class, Notes::load_data_store() );
|
||||
}
|
||||
|
||||
/**
|
||||
* If the "admin-note" data store does not exist, a custom
|
||||
* exception should be thrown.
|
||||
*/
|
||||
public function test_exception_is_thrown_if_data_store_does_not_exist() {
|
||||
add_filter( 'woocommerce_data_stores', '__return_empty_array' );
|
||||
$this->expectException( NotesUnavailableException::class );
|
||||
Notes::load_data_store();
|
||||
remove_filter( 'woocommerce_data_stores', '__return_empty_array' );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue