Add store notice around processing historical data. (https://github.com/woocommerce/woocommerce-admin/pull/1763)
* Add store notice around processing historical data. * Cleanup * Handle PR feedback. * Clean up `add` logic and add empty content_data. Also add logic to get_notes_count so that we can hide unactioned statuses. * Add the ability to update a note, and to also mark a status when an alert is clicked. * Remove mark_actioned call on sync * add missing todo
This commit is contained in:
parent
6c9b96f49a
commit
1348245406
|
@ -37,6 +37,38 @@ const orderStatuses = Object.keys( wcSettings.orderStatuses )
|
|||
} );
|
||||
|
||||
export const analyticsSettings = applyFilters( SETTINGS_FILTER, [
|
||||
{
|
||||
name: 'woocommerce_rebuild_reports_data',
|
||||
label: __( 'Rebuild reports data:', 'wc-admin' ),
|
||||
inputType: 'button',
|
||||
inputText: __( 'Rebuild reports', 'wc-admin' ),
|
||||
helpText: __(
|
||||
'This tool will rebuild all of the information used by the reports. ' +
|
||||
'Data will be processed in the background and may take some time depending on the size of your store.',
|
||||
'wc-admin'
|
||||
),
|
||||
callback: ( resolve, reject, addNotice ) => {
|
||||
const errorMessage = __( 'There was a problem rebuilding your report data.', 'wc-admin' );
|
||||
|
||||
apiFetch( { path: '/wc/v3/system_status/tools/rebuild_stats', method: 'PUT' } )
|
||||
.then( response => {
|
||||
if ( response.success ) {
|
||||
addNotice( { status: 'success', message: response.message } );
|
||||
// @todo This should be changed to detect when the lookup table population is complete.
|
||||
setTimeout( () => resolve(), 300000 );
|
||||
} else {
|
||||
addNotice( { status: 'error', message: errorMessage } );
|
||||
reject();
|
||||
}
|
||||
} )
|
||||
.catch( error => {
|
||||
if ( error && error.message ) {
|
||||
addNotice( { status: 'error', message: error.message } );
|
||||
}
|
||||
reject();
|
||||
} );
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'woocommerce_excluded_report_order_statuses',
|
||||
label: __( 'Excluded Statuses:', 'wc-admin' ),
|
||||
|
@ -89,36 +121,4 @@ export const analyticsSettings = applyFilters( SETTINGS_FILTER, [
|
|||
initialValue: wcSettings.wcAdminSettings.woocommerce_actionable_order_statuses || [],
|
||||
defaultValue: [ 'processing', 'on-hold' ],
|
||||
},
|
||||
{
|
||||
name: 'woocommerce_rebuild_reports_data',
|
||||
label: __( 'Rebuild reports data:', 'wc-admin' ),
|
||||
inputType: 'button',
|
||||
inputText: __( 'Rebuild reports', 'wc-admin' ),
|
||||
helpText: __(
|
||||
'This tool will rebuild all of the information used by the reports. ' +
|
||||
'Data will be processed in the background and may take some time depending on the size of your store.',
|
||||
'wc-admin'
|
||||
),
|
||||
callback: ( resolve, reject, addNotice ) => {
|
||||
const errorMessage = __( 'There was a problem rebuilding your report data.', 'wc-admin' );
|
||||
|
||||
apiFetch( { path: '/wc/v3/system_status/tools/rebuild_stats', method: 'PUT' } )
|
||||
.then( response => {
|
||||
if ( response.success ) {
|
||||
addNotice( { status: 'success', message: response.message } );
|
||||
// @todo This should be changed to detect when the lookup table population is complete.
|
||||
setTimeout( () => resolve(), 300000 );
|
||||
} else {
|
||||
addNotice( { status: 'error', message: errorMessage } );
|
||||
reject();
|
||||
}
|
||||
} )
|
||||
.catch( error => {
|
||||
if ( error && error.message ) {
|
||||
addNotice( { status: 'error', message: error.message } );
|
||||
}
|
||||
reject();
|
||||
} );
|
||||
},
|
||||
},
|
||||
] );
|
||||
|
|
|
@ -8,6 +8,8 @@ import { IconButton, Button, Dashicon } from '@wordpress/components';
|
|||
import classnames from 'classnames';
|
||||
import interpolateComponents from 'interpolate-components';
|
||||
import { compose } from '@wordpress/compose';
|
||||
import { noop } from 'lodash';
|
||||
import { withDispatch } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* WooCommerce dependencies
|
||||
|
@ -64,7 +66,7 @@ class StoreAlerts extends Component {
|
|||
const alerts = this.props.alerts || [];
|
||||
const preloadAlertCount = wcSettings.alertCount && parseInt( wcSettings.alertCount );
|
||||
|
||||
if ( preloadAlertCount > 0 && 0 === alerts.length ) {
|
||||
if ( preloadAlertCount > 0 && this.props.isLoading ) {
|
||||
return <StoreAlertsPlaceholder hasMultipleAlerts={ preloadAlertCount > 1 } />;
|
||||
} else if ( 0 === alerts.length ) {
|
||||
return null;
|
||||
|
@ -78,11 +80,22 @@ class StoreAlerts extends Component {
|
|||
'is-alert-error': 'error' === type,
|
||||
'is-alert-update': 'update' === type,
|
||||
} );
|
||||
const actions = alert.actions.map( action => (
|
||||
<Button key={ action.name } isDefault href={ action.url }>
|
||||
{ action.label }
|
||||
</Button>
|
||||
) );
|
||||
|
||||
const actions = alert.actions.map( action => {
|
||||
const markStatus = () => {
|
||||
this.props.updateNote( alert.id, { status: action.status } );
|
||||
};
|
||||
return (
|
||||
<Button
|
||||
key={ action.name }
|
||||
isDefault
|
||||
href={ action.url }
|
||||
onClick={ '' === action.status ? noop : markStatus }
|
||||
>
|
||||
{ action.label }
|
||||
</Button>
|
||||
);
|
||||
} );
|
||||
|
||||
return (
|
||||
<Card
|
||||
|
@ -135,15 +148,29 @@ class StoreAlerts extends Component {
|
|||
|
||||
export default compose(
|
||||
withSelect( select => {
|
||||
const { getNotes } = select( 'wc-api' );
|
||||
const { getNotes, isGetNotesRequesting } = select( 'wc-api' );
|
||||
const alertsQuery = {
|
||||
page: 1,
|
||||
per_page: QUERY_DEFAULTS.pageSize,
|
||||
type: 'error,update',
|
||||
status: 'unactioned',
|
||||
};
|
||||
|
||||
const alerts = getNotes( alertsQuery );
|
||||
// Filter out notes that may have been marked actioned or not delayed after the initial request
|
||||
const filterNotes = note => 'unactioned' === note.status;
|
||||
const alerts = getNotes( alertsQuery ).filter( filterNotes );
|
||||
|
||||
return { alerts };
|
||||
const isLoading = isGetNotesRequesting( alertsQuery );
|
||||
|
||||
return {
|
||||
alerts,
|
||||
isLoading,
|
||||
};
|
||||
} ),
|
||||
withDispatch( dispatch => {
|
||||
const { updateNote } = dispatch( 'wc-api' );
|
||||
return {
|
||||
updateNote,
|
||||
};
|
||||
} )
|
||||
)( StoreAlerts );
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
*/
|
||||
import operations from './operations';
|
||||
import selectors from './selectors';
|
||||
import mutations from './mutations';
|
||||
|
||||
export default {
|
||||
operations,
|
||||
selectors,
|
||||
mutations,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/** @format */
|
||||
|
||||
const updateNote = operations => ( noteId, noteFields ) => {
|
||||
const resourceKey = 'note';
|
||||
operations.update( [ resourceKey ], { [ resourceKey ]: { noteId, ...noteFields } } );
|
||||
};
|
||||
|
||||
export default {
|
||||
updateNote,
|
||||
};
|
|
@ -19,6 +19,10 @@ function read( resourceNames, fetch = apiFetch ) {
|
|||
return [ ...readNotes( resourceNames, fetch ), ...readNoteQueries( resourceNames, fetch ) ];
|
||||
}
|
||||
|
||||
function update( resourceNames, data, fetch = apiFetch ) {
|
||||
return [ ...updateNote( resourceNames, data, fetch ) ];
|
||||
}
|
||||
|
||||
function readNoteQueries( resourceNames, fetch ) {
|
||||
const filteredNames = resourceNames.filter( name => isResourcePrefix( name, 'note-query' ) );
|
||||
|
||||
|
@ -71,6 +75,25 @@ function readNote( resourceName, fetch ) {
|
|||
} );
|
||||
}
|
||||
|
||||
function updateNote( resourceNames, data, fetch ) {
|
||||
const resourceName = 'note';
|
||||
if ( resourceNames.includes( resourceName ) ) {
|
||||
const { noteId, ...noteFields } = data[ resourceName ];
|
||||
const url = `${ NAMESPACE }/admin/notes/${ noteId }`;
|
||||
return [
|
||||
fetch( { path: url, method: 'PUT', data: noteFields } )
|
||||
.then( note => {
|
||||
return { [ resourceName + ':' + noteId ]: { data: note } };
|
||||
} )
|
||||
.catch( error => {
|
||||
return { [ resourceName + ':' + noteId ]: { error } };
|
||||
} ),
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export default {
|
||||
read,
|
||||
update,
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ function createWcApiSpec() {
|
|||
mutations: {
|
||||
...settings.mutations,
|
||||
...user.mutations,
|
||||
...notes.mutations,
|
||||
},
|
||||
selectors: {
|
||||
...items.selectors,
|
||||
|
@ -42,6 +43,7 @@ function createWcApiSpec() {
|
|||
return [
|
||||
...settings.operations.update( resourceNames, data ),
|
||||
...user.operations.update( resourceNames, data ),
|
||||
...notes.operations.update( resourceNames, data ),
|
||||
];
|
||||
},
|
||||
},
|
||||
|
|
|
@ -63,6 +63,11 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
'callback' => array( $this, 'get_item' ),
|
||||
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => array( $this, 'update_item' ),
|
||||
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
@ -124,6 +129,12 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
$args['type'] = $type;
|
||||
}
|
||||
|
||||
$status = isset( $request['status'] ) ? $request['status'] : '';
|
||||
$status = sanitize_text_field( $status );
|
||||
if ( ! empty( $status ) ) {
|
||||
$args['status'] = $status;
|
||||
}
|
||||
|
||||
$notes = WC_Admin_Notes::get_notes( 'edit', $args );
|
||||
|
||||
$data = array();
|
||||
|
@ -134,7 +145,7 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
}
|
||||
|
||||
$response = rest_ensure_response( $data );
|
||||
$response->header( 'X-WP-Total', WC_Admin_Notes::get_notes_count() );
|
||||
$response->header( 'X-WP-Total', WC_Admin_Notes::get_notes_count( $type, $status ) );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@ -167,6 +178,49 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single note.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Request|WP_Error
|
||||
*/
|
||||
public function update_item( $request ) {
|
||||
$note = WC_Admin_Notes::get_note( $request->get_param( 'id' ) );
|
||||
|
||||
if ( ! $note ) {
|
||||
return new WP_Error(
|
||||
'woocommerce_admin_notes_invalid_id',
|
||||
__( 'Sorry, there is no resouce with that ID.', 'wc-admin' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
// @todo Status is the only field that can be updated at the moment. We should also implement the "date reminder" setting.
|
||||
$note_changed = false;
|
||||
if ( ! is_null( $request->get_param( 'status' ) ) ) {
|
||||
$note->set_status( $request->get_param( 'status' ) );
|
||||
$note_changed = true;
|
||||
}
|
||||
|
||||
if ( $note_changed ) {
|
||||
$note->save();
|
||||
}
|
||||
return $this->get_item( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the current user has access to WRITE the settings APIs.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
* @return WP_Error|bool
|
||||
*/
|
||||
public function update_items_permissions_check( $request ) {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'wc-admin' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a path or query for serialization to the client.
|
||||
*
|
||||
|
@ -204,8 +258,9 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
$data['title'] = stripslashes( $data['title'] );
|
||||
$data['content'] = stripslashes( $data['content'] );
|
||||
foreach ( (array) $data['actions'] as $key => $value ) {
|
||||
$data['actions'][ $key ]->label = stripslashes( $data['actions'][ $key ]->label );
|
||||
$data['actions'][ $key ]->url = $this->prepare_query_for_response( $data['actions'][ $key ]->query );
|
||||
$data['actions'][ $key ]->label = stripslashes( $data['actions'][ $key ]->label );
|
||||
$data['actions'][ $key ]->url = $this->prepare_query_for_response( $data['actions'][ $key ]->query );
|
||||
$data['actions'][ $key ]->status = stripslashes( $data['actions'][ $key ]->status );
|
||||
}
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
|
||||
|
@ -233,6 +288,29 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
return apply_filters( 'woocommerce_rest_prepare_admin_note', $response, $data, $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query params for collections.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_collection_params() {
|
||||
$params = array();
|
||||
$params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
|
||||
$params['type'] = array(
|
||||
'description' => __( 'Type of note.', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'enum' => WC_Admin_Note::get_allowed_types(),
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
$params['status'] = array(
|
||||
'description' => __( 'Status of note.', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'enum' => WC_Admin_Note::get_allowed_statuses(),
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the note's schema, conforming to JSON Schema.
|
||||
*
|
||||
|
@ -296,7 +374,6 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
'description' => __( 'The status of the note (e.g. unactioned, actioned).', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'source' => array(
|
||||
'description' => __( 'Source of the note.', 'wc-admin' ),
|
||||
|
@ -320,7 +397,7 @@ class WC_Admin_REST_Admin_Notes_Controller extends WC_REST_CRUD_Controller {
|
|||
'description' => __( 'Date after which the user should be reminded of the note, if any.', 'wc-admin' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'readonly' => true, // @todo Allow date_reminder to be updated.
|
||||
),
|
||||
'date_reminder_gmt' => array(
|
||||
'description' => __( 'Date after which the user should be reminded of the note, if any (GMT).', 'wc-admin' ),
|
||||
|
|
|
@ -16,7 +16,7 @@ class WC_Admin_Install {
|
|||
*
|
||||
* @todo get this dynamically?
|
||||
*/
|
||||
const VERSION_NUMBER = '0.6.0';
|
||||
const VERSION_NUMBER = '0.8.0';
|
||||
|
||||
/**
|
||||
* Plugin version option name.
|
||||
|
@ -76,6 +76,8 @@ class WC_Admin_Install {
|
|||
self::create_tables();
|
||||
self::update_wc_admin_version();
|
||||
|
||||
WC_Admin_Notes_Historical_Data::add_note();
|
||||
|
||||
delete_transient( 'wc_admin_installing' );
|
||||
|
||||
do_action( 'wc_admin_installed' );
|
||||
|
@ -174,6 +176,7 @@ class WC_Admin_Install {
|
|||
name varchar(255) NOT NULL,
|
||||
label varchar(255) NOT NULL,
|
||||
query longtext NOT NULL,
|
||||
status varchar(255) NOT NULL,
|
||||
PRIMARY KEY (action_id),
|
||||
KEY note_id (note_id)
|
||||
) $collate;
|
||||
|
|
|
@ -365,6 +365,7 @@ class WC_Admin_Note extends WC_Data {
|
|||
/**
|
||||
* Set note data for potential re-localization.
|
||||
*
|
||||
* @todo Set a default empty array? https://github.com/woocommerce/wc-admin/pull/1763#pullrequestreview-212442921.
|
||||
* @param object $content_data Note data.
|
||||
*/
|
||||
public function set_content_data( $content_data ) {
|
||||
|
@ -450,11 +451,13 @@ class WC_Admin_Note extends WC_Data {
|
|||
* @param string $name Label name (not presented to user).
|
||||
* @param string $label Note label (e.g. presented as button label).
|
||||
* @param string $query Note query (for redirect).
|
||||
* @param string $status The status to set for the action should on click.
|
||||
*/
|
||||
public function add_action( $name, $label, $query ) {
|
||||
$name = wc_clean( $name );
|
||||
$label = wc_clean( $label );
|
||||
$query = wc_clean( $query );
|
||||
public function add_action( $name, $label, $query, $status = '' ) {
|
||||
$name = wc_clean( $name );
|
||||
$label = wc_clean( $label );
|
||||
$query = wc_clean( $query );
|
||||
$status = wc_clean( $status );
|
||||
|
||||
if ( empty( $name ) ) {
|
||||
$this->error( 'admin_note_invalid_data', __( 'The admin note action name prop cannot be empty.', 'wc-admin' ) );
|
||||
|
@ -469,9 +472,10 @@ class WC_Admin_Note extends WC_Data {
|
|||
}
|
||||
|
||||
$action = array(
|
||||
'name' => $name,
|
||||
'label' => $label,
|
||||
'query' => $query,
|
||||
'name' => $name,
|
||||
'label' => $label,
|
||||
'query' => $query,
|
||||
'status' => $status,
|
||||
);
|
||||
|
||||
$note_actions = $this->get_prop( 'actions', 'edit' );
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/**
|
||||
* WooCommerce Admin: Historical Analytics Data Note.
|
||||
*
|
||||
* Adds a notes to store alerts area concerning the historial analytics data tool.
|
||||
*
|
||||
* @package WooCommerce Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC_Admin_Notes_Historical_Data.
|
||||
*/
|
||||
class WC_Admin_Notes_Historical_Data {
|
||||
const NOTE_NAME = 'wc-admin-historical-data';
|
||||
|
||||
/**
|
||||
* Creates a note for regenerating historical data.
|
||||
*/
|
||||
public static function add_note() {
|
||||
$data_store = WC_Data_Store::load( 'admin-note' );
|
||||
|
||||
// First, see if we've already created this kind of note so we don't do it again.
|
||||
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
|
||||
if ( ! empty( $note_ids ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$note = new WC_Admin_Note();
|
||||
$note->set_title( __( 'WooCommerce Admin: Historical Analytics Data', 'wc-admin' ) );
|
||||
$note->set_content( __( 'To view your historical analytics data, you must process your existing orders and customers.', 'wc-admin' ) );
|
||||
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_UPDATE );
|
||||
$note->set_icon( 'info' );
|
||||
$note->set_name( self::NOTE_NAME );
|
||||
$note->set_content_data( (object) array() );
|
||||
$note->set_source( 'woocommerce-admin' );
|
||||
// @todo Add remind me later option. See https://github.com/woocommerce/wc-admin/issues/1756.
|
||||
$note->add_action(
|
||||
'get-started',
|
||||
__( 'Get Started', 'wc-admin' ),
|
||||
'?page=wc-admin#/analytics/settings',
|
||||
'actioned'
|
||||
);
|
||||
|
||||
$note->save();
|
||||
}
|
||||
}
|
||||
|
||||
new WC_Admin_Notes_Historical_Data();
|
|
@ -94,7 +94,7 @@ class WC_Admin_Notes_New_Sales_Record {
|
|||
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
|
||||
$note->set_icon( 'trophy' );
|
||||
$note->set_name( self::NOTE_NAME );
|
||||
$note->set_source( 'wc-admin' );
|
||||
$note->set_source( 'woocommerce-admin' );
|
||||
$note->add_action( 'view-report', __( 'View report', 'wc-admin' ), '?page=wc-admin#/analytics' );
|
||||
$note->save();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class WC_Admin_Notes_Settings_Notes {
|
|||
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
|
||||
$note->set_icon( 'info' );
|
||||
$note->set_name( $name );
|
||||
$note->set_source( 'wc-admin' );
|
||||
$note->set_source( 'woocommerce-admin' );
|
||||
$note->add_action(
|
||||
'open-customizer',
|
||||
__( 'Open Customizer', 'wc-admin' ),
|
||||
|
|
|
@ -185,7 +185,7 @@ class WC_Admin_Notes_Woo_Subscriptions_Notes {
|
|||
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_INFORMATIONAL );
|
||||
$note->set_icon( 'info' );
|
||||
$note->set_name( self::CONNECTION_NOTE_NAME );
|
||||
$note->set_source( 'wc-admin' );
|
||||
$note->set_source( 'woocommerce-admin' );
|
||||
$note->add_action(
|
||||
'connect',
|
||||
__( 'Connect', 'wc-admin' ),
|
||||
|
@ -334,7 +334,7 @@ class WC_Admin_Notes_Woo_Subscriptions_Notes {
|
|||
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_WARNING );
|
||||
$note->set_icon( 'notice' );
|
||||
$note->set_name( self::SUBSCRIPTION_NOTE_NAME );
|
||||
$note->set_source( 'wc-admin' );
|
||||
$note->set_source( 'woocommerce-admin' );
|
||||
$note->clear_actions();
|
||||
$note->add_action(
|
||||
'enable-autorenew',
|
||||
|
@ -398,7 +398,7 @@ class WC_Admin_Notes_Woo_Subscriptions_Notes {
|
|||
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_WARNING );
|
||||
$note->set_icon( 'notice' );
|
||||
$note->set_name( self::SUBSCRIPTION_NOTE_NAME );
|
||||
$note->set_source( 'wc-admin' );
|
||||
$note->set_source( 'woocommerce-admin' );
|
||||
$note->clear_actions();
|
||||
$note->add_action(
|
||||
'renew-subscription',
|
||||
|
|
|
@ -64,11 +64,12 @@ class WC_Admin_Notes {
|
|||
* Get the total number of notes
|
||||
*
|
||||
* @param string $type Comma separated list of note types.
|
||||
* @param string $status Comma separated list of statuses.
|
||||
* @return int
|
||||
*/
|
||||
public static function get_notes_count( $type = '' ) {
|
||||
public static function get_notes_count( $type = '', $status = '' ) {
|
||||
$data_store = WC_Data_Store::load( 'admin-note' );
|
||||
return $data_store->get_notes_count( $type );
|
||||
return $data_store->get_notes_count( $type, $status );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -148,7 +148,6 @@ class WC_Admin_Reports_Sync {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schedule an action to process a single Order.
|
||||
*
|
||||
|
|
|
@ -197,13 +197,13 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
|
||||
$actions = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT name, label, query FROM {$wpdb->prefix}wc_admin_note_actions WHERE note_id = %d",
|
||||
"SELECT name, label, query, status FROM {$wpdb->prefix}wc_admin_note_actions WHERE note_id = %d",
|
||||
$note->get_id()
|
||||
)
|
||||
);
|
||||
if ( $actions ) {
|
||||
foreach ( $actions as $action ) {
|
||||
$note->add_action( $action->name, $action->label, $action->query );
|
||||
$note->add_action( $action->name, $action->label, $action->query, $action->status );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,6 +232,7 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
'name' => $action->name,
|
||||
'label' => $action->label,
|
||||
'query' => $action->query,
|
||||
'status' => $action->status,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -258,6 +259,49 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
|
||||
$offset = $per_page * ( $page - 1 );
|
||||
|
||||
$where_clauses = $this->get_notes_where_clauses( $args );
|
||||
|
||||
$query = $wpdb->prepare(
|
||||
"SELECT note_id, title, content FROM {$wpdb->prefix}wc_admin_notes WHERE 1=1{$where_clauses} ORDER BY note_id DESC LIMIT %d, %d",
|
||||
$offset,
|
||||
$per_page
|
||||
); // WPCS: unprepared SQL ok.
|
||||
|
||||
return $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a count of notes.
|
||||
*
|
||||
* @param string $type Comma separated list of note types.
|
||||
* @param string $status Comma separated list of statuses.
|
||||
* @return array An array of objects containing a note id.
|
||||
*/
|
||||
public function get_notes_count( $type = '', $status = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
$where_clauses = $this->get_notes_where_clauses(
|
||||
array(
|
||||
'type' => $type,
|
||||
'status' => $status,
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! empty( $where_clauses ) ) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wc_admin_notes WHERE 1=1{$where_clauses}" );
|
||||
}
|
||||
|
||||
return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wc_admin_notes" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return where clauses for getting notes by status and type. For use in both the count and listing queries.
|
||||
*
|
||||
* @param array $args Array of args to pass.
|
||||
* @return string Where clauses for the query.
|
||||
*/
|
||||
public function get_notes_where_clauses( $args = array() ) {
|
||||
$allowed_types = WC_Admin_Note::get_allowed_types();
|
||||
$where_type_array = array();
|
||||
if ( isset( $args['type'] ) ) {
|
||||
|
@ -269,54 +313,32 @@ class WC_Admin_Notes_Data_Store extends WC_Data_Store_WP implements WC_Object_Da
|
|||
}
|
||||
}
|
||||
}
|
||||
$escaped_where_types = implode( ',', $where_type_array );
|
||||
|
||||
if ( empty( $escaped_where_types ) ) {
|
||||
$query = $wpdb->prepare(
|
||||
"SELECT note_id, title, content FROM {$wpdb->prefix}wc_admin_notes ORDER BY note_id DESC LIMIT %d, %d",
|
||||
$offset,
|
||||
$per_page
|
||||
);
|
||||
} else {
|
||||
$query = $wpdb->prepare(
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
"SELECT note_id, title, content FROM {$wpdb->prefix}wc_admin_notes WHERE type IN ($escaped_where_types) ORDER BY note_id DESC LIMIT %d, %d",
|
||||
$offset,
|
||||
$per_page
|
||||
);
|
||||
}
|
||||
|
||||
return $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a count of notes.
|
||||
*
|
||||
* @param string $type Comma separated list of note types.
|
||||
* @return array An array of objects containing a note id.
|
||||
*/
|
||||
public function get_notes_count( $type = '' ) {
|
||||
global $wpdb;
|
||||
|
||||
$allowed_types = WC_Admin_Note::get_allowed_types();
|
||||
$where_type_array = array();
|
||||
if ( ! empty( $type ) ) {
|
||||
$args_types = explode( ',', $type );
|
||||
foreach ( (array) $args_types as $args_type ) {
|
||||
$args_type = trim( $args_type );
|
||||
if ( in_array( $args_type, $allowed_types, true ) ) {
|
||||
$where_type_array[] = "'" . esc_sql( $args_type ) . "'";
|
||||
$allowed_statuses = WC_Admin_Note::get_allowed_statuses();
|
||||
$where_status_array = array();
|
||||
if ( isset( $args['status'] ) ) {
|
||||
$args_statuses = explode( ',', $args['status'] );
|
||||
foreach ( (array) $args_statuses as $args_status ) {
|
||||
$args_status = trim( $args_status );
|
||||
if ( in_array( $args_status, $allowed_statuses, true ) ) {
|
||||
$where_status_array[] = "'" . esc_sql( $args_status ) . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
$escaped_where_types = implode( ',', $where_type_array );
|
||||
|
||||
$escaped_where_types = implode( ',', $where_type_array );
|
||||
$escaped_status_types = implode( ',', $where_status_array );
|
||||
$where_clauses = '';
|
||||
|
||||
if ( ! empty( $escaped_where_types ) ) {
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wc_admin_notes WHERE type IN ($escaped_where_types)" );
|
||||
$where_clauses .= " AND type IN ($escaped_where_types)";
|
||||
}
|
||||
|
||||
return $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}wc_admin_notes" );
|
||||
if ( ! empty( $escaped_status_types ) ) {
|
||||
$where_clauses .= " AND status IN ($escaped_status_types)";
|
||||
}
|
||||
|
||||
return $where_clauses;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -191,7 +191,7 @@ function wc_admin_print_script_settings() {
|
|||
'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ),
|
||||
),
|
||||
'currentUserData' => $current_user_data,
|
||||
'alertCount' => WC_Admin_Notes::get_notes_count( 'error,update' ),
|
||||
'alertCount' => WC_Admin_Notes::get_notes_count( 'error,update', 'unactioned' ),
|
||||
);
|
||||
$settings = wc_admin_add_custom_settings( $settings );
|
||||
|
||||
|
|
|
@ -106,6 +106,45 @@ class WC_Tests_API_Admin_Notes extends WC_REST_Unit_Test_Case {
|
|||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a single note.
|
||||
*/
|
||||
public function test_update_note() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint . '/1' ) );
|
||||
$note = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
$this->assertEquals( 'unactioned', $note['status'] );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' );
|
||||
$request->set_body_params(
|
||||
array(
|
||||
'status' => 'actioned',
|
||||
)
|
||||
);
|
||||
|
||||
$response = $this->server->dispatch( $request );
|
||||
$note = $response->get_data();
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
$this->assertEquals( 'actioned', $note['status'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a single note without permission. It should fail.
|
||||
*/
|
||||
public function test_update_note_without_permission() {
|
||||
$request = new WP_REST_Request( 'PUT', $this->endpoint . '/1' );
|
||||
$request->set_body_params(
|
||||
array(
|
||||
'status' => 'actioned',
|
||||
)
|
||||
);
|
||||
$response = $this->server->dispatch( $request );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting lots of notes.
|
||||
*
|
||||
|
@ -139,6 +178,31 @@ class WC_Tests_API_Admin_Notes extends WC_REST_Unit_Test_Case {
|
|||
$this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test getting notes of a certain status.
|
||||
*/
|
||||
public function test_get_actioned_notes() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', $this->endpoint );
|
||||
$request->set_query_params( array( 'status' => 'actioned' ) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$notes = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
$this->assertEquals( 1, count( $notes ) );
|
||||
$this->assertEquals( $notes[0]['title'], 'PHPUNIT_TEST_NOTE_2_TITLE' );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', $this->endpoint );
|
||||
$request->set_query_params( array( 'status' => 'invalid' ) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$notes = $response->get_data();
|
||||
|
||||
// get_notes returns all results since 'status' is not one of actioned or unactioned.
|
||||
$this->assertEquals( 2, count( $notes ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting lots of notes without permission. It should fail.
|
||||
*
|
||||
|
|
|
@ -55,6 +55,7 @@ class WC_Helper_Admin_Notes {
|
|||
$note_2->set_icon( 'info' );
|
||||
$note_2->set_name( 'PHPUNIT_TEST_NOTE_NAME' );
|
||||
$note_2->set_source( 'PHPUNIT_TEST' );
|
||||
$note_2->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED );
|
||||
// This note has no actions.
|
||||
$note_2->save();
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ function wc_admin_plugins_loaded() {
|
|||
require_once WC_ADMIN_ABSPATH . '/includes/class-wc-admin-notes-new-sales-record.php';
|
||||
require_once WC_ADMIN_ABSPATH . '/includes/class-wc-admin-notes-settings-notes.php';
|
||||
require_once WC_ADMIN_ABSPATH . '/includes/class-wc-admin-notes-woo-subscriptions-notes.php';
|
||||
require_once WC_ADMIN_ABSPATH . '/includes/class-wc-admin-notes-historical-data.php';
|
||||
|
||||
// Verify we have a proper build.
|
||||
if ( ! wc_admin_build_file_exists() ) {
|
||||
|
|
Loading…
Reference in New Issue