Merge pull request #19 from woocommerce/add/cron_job_trigger
Add cron trigger
This commit is contained in:
commit
85dbb03504
|
@ -29,6 +29,7 @@ function register_woocommerce_admin_test_helper_rest_route( $route, $callback, $
|
|||
require( 'admin-notes/delete-all-notes.php' );
|
||||
require( 'admin-notes/add-note.php' );
|
||||
require( 'tools/trigger-wca-install.php' );
|
||||
require( 'tools/trigger-cron-job.php' );
|
||||
require( 'tools/run-wc-admin-daily.php' );
|
||||
require( 'options/rest-api.php' );
|
||||
require( 'tools/delete-all-products.php');
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
register_woocommerce_admin_test_helper_rest_route(
|
||||
'/tools/get-cron-list/v1',
|
||||
'tools_get_cron_list',
|
||||
array(
|
||||
'methods' => 'GET',
|
||||
)
|
||||
);
|
||||
register_woocommerce_admin_test_helper_rest_route(
|
||||
'/tools/trigger-selected-cron/v1',
|
||||
'trigger_selected_cron',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'args' => array(
|
||||
'hook' => array(
|
||||
'description' => 'Name of the cron that will be triggered.',
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
'signature' => array(
|
||||
'description' => 'Signature of the cron to trigger.',
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
function tools_get_cron_list() {
|
||||
$crons = _get_cron_array();
|
||||
$events = array();
|
||||
|
||||
if ( empty( $crons ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ( $crons as $cron ) {
|
||||
foreach ( $cron as $hook => $data ) {
|
||||
foreach ( $data as $signature => $element ) {
|
||||
$events[ $hook ] = (object) array(
|
||||
'hook' => $hook,
|
||||
'signature' => $signature,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new WP_REST_Response( $events, 200 );
|
||||
}
|
||||
|
||||
function trigger_selected_cron( $request ) {
|
||||
$hook = $request->get_param( 'hook' );
|
||||
$signature = $request->get_param( 'signature' );
|
||||
|
||||
if ( ! isset( $hook ) || ! isset( $signature ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$crons = _get_cron_array();
|
||||
foreach ( $crons as $cron ) {
|
||||
if ( isset( $cron[ $hook ][ $signature ] ) ) {
|
||||
$args = $cron[ $hook ][ $signature ]['args'];
|
||||
delete_transient( 'doing_cron' );
|
||||
$scheduled = schedule_event( $hook, $args );
|
||||
|
||||
if ( false === $scheduled ) {
|
||||
return $scheduled;
|
||||
}
|
||||
|
||||
add_filter( 'cron_request', function( array $cron_request ) {
|
||||
$cron_request['url'] = add_query_arg( 'run-cron', 1, $cron_request['url'] );
|
||||
return $cron_request;
|
||||
} );
|
||||
|
||||
spawn_cron();
|
||||
sleep( 1 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function schedule_event( $hook, $args = array() ) {
|
||||
$event = (object) array(
|
||||
'hook' => $hook,
|
||||
'timestamp' => 1,
|
||||
'schedule' => false,
|
||||
'args' => $args,
|
||||
);
|
||||
$crons = (array) _get_cron_array();
|
||||
$key = md5( serialize( $event->args ) );
|
||||
|
||||
$crons[ $event->timestamp ][ $event->hook ][ $key ] = array(
|
||||
'schedule' => $event->schedule,
|
||||
'args' => $event->args,
|
||||
);
|
||||
uksort( $crons, 'strnatcasecmp' );
|
||||
return _set_cron_array( $crons );
|
||||
}
|
|
@ -2,9 +2,8 @@
|
|||
* External dependencies.
|
||||
*/
|
||||
import { useState } from '@wordpress/element';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { Button, SelectControl } from '@wordpress/components';
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
import { SelectControl } from '@wordpress/components';
|
||||
|
||||
|
||||
export const AddNote = () => {
|
||||
|
|
|
@ -60,6 +60,13 @@
|
|||
&.command {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.trigger-cron-job {
|
||||
width: 40%;
|
||||
padding-top: 4px;
|
||||
.components-base-control__field {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.components-notice {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { TriggerCronJob, TRIGGER_CRON_ACTION_NAME } from './trigger-cron';
|
||||
|
||||
export default [
|
||||
{
|
||||
command: 'Trigger WCA Install',
|
||||
|
@ -39,4 +41,9 @@ export default [
|
|||
description: 'Delete all products',
|
||||
action: 'deleteAllProducts',
|
||||
},
|
||||
{
|
||||
command: 'Run a cron job',
|
||||
description: <TriggerCronJob />,
|
||||
action: TRIGGER_CRON_ACTION_NAME,
|
||||
},
|
||||
];
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* External dependencies.
|
||||
*/
|
||||
import { SelectControl } from '@wordpress/components';
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { STORE_KEY } from '../data/constants';
|
||||
|
||||
export const TRIGGER_CRON_ACTION_NAME = 'runSelectedCronJob';
|
||||
|
||||
export const TriggerCronJob = () => {
|
||||
const { cronList } = useSelect((select) => {
|
||||
const { getCronJobs } = select(STORE_KEY);
|
||||
return {
|
||||
cronList: getCronJobs(),
|
||||
};
|
||||
});
|
||||
const { updateCommandParams } = useDispatch(STORE_KEY);
|
||||
|
||||
function onCronChange(selectedValue) {
|
||||
const { hook, signature } = cronList[selectedValue];
|
||||
updateCommandParams(TRIGGER_CRON_ACTION_NAME, { hook, signature });
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
return Object.keys(cronList).map((name) => {
|
||||
return { label: name, value: name };
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="trigger-cron-job">
|
||||
{!cronList ? (
|
||||
<p>Loading ...</p>
|
||||
) : (
|
||||
<SelectControl
|
||||
label="Select cron job to run"
|
||||
onChange={onCronChange}
|
||||
labelPosition="side"
|
||||
options={getOptions()}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -4,6 +4,8 @@ const TYPES = {
|
|||
ADD_MESSAGE: 'ADD_MESSAGE',
|
||||
UPDATE_MESSAGE: 'UPDATE_MESSAGE',
|
||||
REMOVE_MESSAGE: 'REMOVE_MESSAGE',
|
||||
ADD_COMMAND_PARAMS: 'ADD_COMMAND_PARAMS',
|
||||
SET_CRON_JOBS: 'SET_CRON_JOBS',
|
||||
};
|
||||
|
||||
export default TYPES;
|
||||
|
|
|
@ -9,21 +9,21 @@ import { apiFetch } from '@wordpress/data-controls';
|
|||
import TYPES from './action-types';
|
||||
import { API_NAMESPACE } from './constants';
|
||||
|
||||
export function addCurrentlyRunning( command ) {
|
||||
export function addCurrentlyRunning(command) {
|
||||
return {
|
||||
type: TYPES.ADD_CURRENTLY_RUNNING,
|
||||
command,
|
||||
};
|
||||
}
|
||||
|
||||
export function removeCurrentlyRunning( command ) {
|
||||
export function removeCurrentlyRunning(command) {
|
||||
return {
|
||||
type: TYPES.REMOVE_CURRENTLY_RUNNING,
|
||||
command,
|
||||
};
|
||||
}
|
||||
|
||||
export function addMessage( source, message ) {
|
||||
export function addMessage(source, message) {
|
||||
return {
|
||||
type: TYPES.ADD_MESSAGE,
|
||||
source,
|
||||
|
@ -31,7 +31,7 @@ export function addMessage( source, message ) {
|
|||
};
|
||||
}
|
||||
|
||||
export function updateMessage( source, message, status ) {
|
||||
export function updateMessage(source, message, status) {
|
||||
return {
|
||||
type: TYPES.ADD_MESSAGE,
|
||||
source,
|
||||
|
@ -40,69 +40,84 @@ export function updateMessage( source, message, status ) {
|
|||
};
|
||||
}
|
||||
|
||||
export function removeMessage( source ) {
|
||||
export function removeMessage(source) {
|
||||
return {
|
||||
type: TYPES.REMOVE_MESSAGE,
|
||||
source,
|
||||
};
|
||||
}
|
||||
|
||||
function* runCommand( commandName, func ) {
|
||||
export function updateCommandParams(source, params) {
|
||||
return {
|
||||
type: TYPES.ADD_COMMAND_PARAMS,
|
||||
source,
|
||||
params,
|
||||
};
|
||||
}
|
||||
|
||||
export function setCronJobs(cronJobs) {
|
||||
return {
|
||||
type: TYPES.SET_CRON_JOBS,
|
||||
cronJobs,
|
||||
};
|
||||
}
|
||||
|
||||
function* runCommand(commandName, func) {
|
||||
try {
|
||||
yield addCurrentlyRunning( commandName );
|
||||
yield addMessage( commandName, 'Executing...' );
|
||||
yield addCurrentlyRunning(commandName);
|
||||
yield addMessage(commandName, 'Executing...');
|
||||
yield func();
|
||||
yield removeCurrentlyRunning( commandName );
|
||||
yield updateMessage( commandName, 'Successful!' );
|
||||
} catch ( e ) {
|
||||
yield updateMessage( commandName, e.message, 'error' );
|
||||
yield removeCurrentlyRunning( commandName );
|
||||
yield removeCurrentlyRunning(commandName);
|
||||
yield updateMessage(commandName, 'Successful!');
|
||||
} catch (e) {
|
||||
yield updateMessage(commandName, e.message, 'error');
|
||||
yield removeCurrentlyRunning(commandName);
|
||||
}
|
||||
}
|
||||
|
||||
export function* triggerWcaInstall() {
|
||||
yield runCommand( 'Trigger WCA Install', function* () {
|
||||
yield apiFetch( {
|
||||
yield runCommand('Trigger WCA Install', function* () {
|
||||
yield apiFetch({
|
||||
path: API_NAMESPACE + '/tools/trigger-wca-install/v1',
|
||||
method: 'POST',
|
||||
} );
|
||||
} );
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function* resetOnboardingWizard() {
|
||||
yield runCommand( 'Reset Onboarding Wizard', function* () {
|
||||
yield runCommand('Reset Onboarding Wizard', function* () {
|
||||
const optionsToDelete = [
|
||||
'woocommerce_task_list_tracked_completed_tasks',
|
||||
'woocommerce_onboarding_profile',
|
||||
'_transient_wc_onboarding_themes',
|
||||
];
|
||||
yield apiFetch( {
|
||||
yield apiFetch({
|
||||
method: 'DELETE',
|
||||
path: `${ API_NAMESPACE }/options/${ optionsToDelete.join( ',' ) }`,
|
||||
} );
|
||||
} );
|
||||
path: `${API_NAMESPACE}/options/${optionsToDelete.join(',')}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function* resetJetpackConnection() {
|
||||
yield runCommand( 'Reset Jetpack Connection', function* () {
|
||||
yield apiFetch( {
|
||||
yield runCommand('Reset Jetpack Connection', function* () {
|
||||
yield apiFetch({
|
||||
method: 'DELETE',
|
||||
path: `${ API_NAMESPACE }/options/jetpack_options`,
|
||||
} );
|
||||
} );
|
||||
path: `${API_NAMESPACE}/options/jetpack_options`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function* enableTrackingDebug() {
|
||||
yield runCommand( 'Enable WC Admin Tracking Debug Mode', function* () {
|
||||
window.localStorage.setItem( 'debug', 'wc-admin:*' );
|
||||
} );
|
||||
yield runCommand('Enable WC Admin Tracking Debug Mode', function* () {
|
||||
window.localStorage.setItem('debug', 'wc-admin:*');
|
||||
});
|
||||
}
|
||||
|
||||
export function* updateStoreAge() {
|
||||
yield runCommand( 'Update Installation timestamp', function* () {
|
||||
yield runCommand('Update Installation timestamp', function* () {
|
||||
const today = new Date();
|
||||
const dd = String( today.getDate() ).padStart( 2, '0' );
|
||||
const mm = String( today.getMonth() + 1 ).padStart( 2, '0' ); //January is 0!
|
||||
const dd = String(today.getDate()).padStart(2, '0');
|
||||
const mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
|
||||
const yyyy = today.getFullYear();
|
||||
|
||||
// eslint-disable-next-line no-alert
|
||||
|
@ -111,43 +126,52 @@ export function* updateStoreAge() {
|
|||
yyyy + '/' + mm + '/' + dd
|
||||
);
|
||||
|
||||
if ( numberOfDays !== null ) {
|
||||
const dates = numberOfDays.split( '/' );
|
||||
if (numberOfDays !== null) {
|
||||
const dates = numberOfDays.split('/');
|
||||
const newTimestamp = Math.round(
|
||||
new Date( dates[ 0 ], dates[ 1 ] - 1, dates[ 2 ] ).getTime() /
|
||||
1000
|
||||
new Date(dates[0], dates[1] - 1, dates[2]).getTime() / 1000
|
||||
);
|
||||
const payload = {
|
||||
woocommerce_admin_install_timestamp: JSON.parse( newTimestamp ),
|
||||
woocommerce_admin_install_timestamp: JSON.parse(newTimestamp),
|
||||
};
|
||||
yield apiFetch( {
|
||||
yield apiFetch({
|
||||
method: 'POST',
|
||||
path: '/wc-admin/options',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify( payload ),
|
||||
} );
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
} );
|
||||
});
|
||||
}
|
||||
|
||||
export function* runWcAdminDailyJob() {
|
||||
yield runCommand( 'Run wc_admin_daily job', function* () {
|
||||
yield apiFetch( {
|
||||
yield runCommand('Run wc_admin_daily job', function* () {
|
||||
yield apiFetch({
|
||||
path: API_NAMESPACE + '/tools/run-wc-admin-daily/v1',
|
||||
method: 'POST',
|
||||
} );
|
||||
} );
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function* deleteAllProducts() {
|
||||
if ( ! confirm( 'Are you sure you want to delete all of the products?' ) ) {
|
||||
if (!confirm('Are you sure you want to delete all of the products?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
yield runCommand( 'Delete all products', function* () {
|
||||
yield apiFetch( {
|
||||
path: `${ API_NAMESPACE }/tools/delete-all-products/v1`,
|
||||
yield runCommand('Delete all products', function* () {
|
||||
yield apiFetch({
|
||||
path: `${API_NAMESPACE}/tools/delete-all-products/v1`,
|
||||
method: 'POST',
|
||||
} );
|
||||
} );
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function* runSelectedCronJob(params) {
|
||||
yield runCommand('Run selected cron job', function* () {
|
||||
yield apiFetch({
|
||||
path: API_NAMESPACE + '/tools/run-wc-admin-daily/v1',
|
||||
method: 'POST',
|
||||
data: params,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { controls } from '@wordpress/data-controls';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import * as actions from './actions';
|
||||
import * as resolvers from './resolvers';
|
||||
import * as selectors from './selectors';
|
||||
import reducer from './reducer';
|
||||
import { STORE_KEY } from './constants';
|
||||
|
@ -15,6 +16,7 @@ import { STORE_KEY } from './constants';
|
|||
export default registerStore( STORE_KEY, {
|
||||
actions,
|
||||
selectors,
|
||||
resolvers,
|
||||
controls,
|
||||
reducer,
|
||||
} );
|
||||
|
|
|
@ -6,7 +6,9 @@ import TYPES from './action-types';
|
|||
const DEFAULT_STATE = {
|
||||
currentlyRunning: {},
|
||||
errorMessages: [],
|
||||
cronJobs: false,
|
||||
messages: {},
|
||||
params: [],
|
||||
status: '',
|
||||
};
|
||||
|
||||
|
@ -54,6 +56,18 @@ const reducer = ( state = DEFAULT_STATE, action ) => {
|
|||
[ action.command ]: false,
|
||||
},
|
||||
};
|
||||
case TYPES.SET_CRON_JOBS:
|
||||
return {
|
||||
...state,
|
||||
cronJobs: action.cronJobs,
|
||||
};
|
||||
case TYPES.ADD_COMMAND_PARAMS:
|
||||
return {
|
||||
...state,
|
||||
params: {
|
||||
[ action.source ]: action.params,
|
||||
},
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { apiFetch } from '@wordpress/data-controls';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { API_NAMESPACE } from './constants';
|
||||
import { setCronJobs } from './actions';
|
||||
|
||||
export function* getCronJobs() {
|
||||
const path = `${ API_NAMESPACE }/tools/get-cron-list/v1`;
|
||||
|
||||
try {
|
||||
const response = yield apiFetch( {
|
||||
path,
|
||||
method: 'GET',
|
||||
} );
|
||||
yield setCronJobs( response );
|
||||
} catch ( error ) {
|
||||
throw new Error( error );
|
||||
}
|
||||
}
|
|
@ -9,3 +9,11 @@ export function getMessages( state ) {
|
|||
export function getStatus( state ) {
|
||||
return state.status;
|
||||
}
|
||||
|
||||
export function getCommandParams( state ) {
|
||||
return state.params;
|
||||
}
|
||||
|
||||
export function getCronJobs( state ) {
|
||||
return state.cronJobs;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { default as commands } from './commands';
|
|||
import { STORE_KEY } from './data/constants';
|
||||
import './data';
|
||||
|
||||
function Tools( { actions, currentlyRunningCommands, messages } ) {
|
||||
function Tools( { actions, currentlyRunningCommands, messages, comandParams } ) {
|
||||
actions = actions();
|
||||
return (
|
||||
<div id="wc-admin-test-helper-tools">
|
||||
|
@ -38,17 +38,18 @@ function Tools( { actions, currentlyRunningCommands, messages } ) {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ commands.map( ( command, index ) => {
|
||||
{ commands.map( ( { action, command, description }, index ) => {
|
||||
const params = comandParams[ action ] ?? false;
|
||||
return (
|
||||
<tr key={ index }>
|
||||
<td className="command">{ command.command }</td>
|
||||
<td>{ command.description }</td>
|
||||
<td className="command">{ command }</td>
|
||||
<td>{ description }</td>
|
||||
<td>
|
||||
<Button
|
||||
onClick={ actions[ command.action ] }
|
||||
onClick={ () => actions[ action ]( params ) }
|
||||
disabled={
|
||||
currentlyRunningCommands[
|
||||
command.command
|
||||
command
|
||||
]
|
||||
}
|
||||
isPrimary
|
||||
|
@ -67,10 +68,11 @@ function Tools( { actions, currentlyRunningCommands, messages } ) {
|
|||
|
||||
export default compose(
|
||||
withSelect( ( select ) => {
|
||||
const { getCurrentlyRunning, getMessages } = select( STORE_KEY );
|
||||
const { getCurrentlyRunning, getMessages, getCommandParams } = select( STORE_KEY );
|
||||
return {
|
||||
currentlyRunningCommands: getCurrentlyRunning(),
|
||||
messages: getMessages(),
|
||||
comandParams: getCommandParams(),
|
||||
};
|
||||
} ),
|
||||
withDispatch( ( dispatch ) => {
|
||||
|
|
Loading…
Reference in New Issue