automatewoo/includes/Workflows/Factory.php
fei-source 47d3c9a8b6 Update to v6.2.2
Source: GrootMade/Festinger Vault
2026-03-15 08:31:15 +08:00

268 lines
6.7 KiB
PHP

<?php
namespace AutomateWoo\Workflows;
use AutomateWoo\Clean;
use AutomateWoo\Cache;
use AutomateWoo\Entity\Workflow as WorkflowEntity;
use AutomateWoo\Exceptions\InvalidWorkflow;
use AutomateWoo\Workflow;
use WP_Error;
/**
* @since 3.9
*/
class Factory {
/**
* Get a Workflow object by its ID.
*
* @param int $id The workflow ID.
*
* @return Workflow|false The workflow object, or false when the ID is invalid or the object can't be retrieved.
*/
public static function get( $id ) {
$id = (int) $id;
if ( $id <= 0 ) {
return false;
}
$id = Clean::id( $id );
if ( ! $id ) {
return false;
}
$workflow = new Workflow( $id );
if ( ! $workflow->exists ) {
return false;
}
return $workflow;
}
/**
* Create a workflow given an Entity.
*
* @since 5.1.0
*
* @param WorkflowEntity $entity The entity to use for Workflow creation.
*
* @return Workflow
*
* @throws InvalidWorkflow When the workflow already exists or there is an issue creating the workflow.
*/
public static function create( WorkflowEntity $entity ) {
$workflow = self::get( $entity->get_id() );
if ( $workflow ) {
throw InvalidWorkflow::workflow_exists( esc_html( $workflow->get_id() ) );
}
return self::create_from_array( $entity->to_array() );
}
/**
* Update a workflow given an Entity.
*
* @since 6.0.10
*
* @param WorkflowEntity $entity The entity to use for Workflow update.
*
* @return Workflow
*
* @throws InvalidWorkflow When the workflow already exists or there is an issue updating the workflow.
*/
public static function update( WorkflowEntity $entity ) {
return self::update_from_array( $entity->to_array() );
}
/**
* Create a workflow from an array of data.
*
* @since 5.1.0
*
* @param array $data The array of workflow data.
*
* @return Workflow
* @throws InvalidWorkflow When there is an issue creating the workflow.
*/
public static function create_from_array( $data = [] ) {
$data = array_replace_recursive(
[
'title' => '',
'status' => new Status( Status::DISABLED ),
'type' => 'automatic',
'is_transactional' => false,
'order' => 0,
'origin' => WorkflowEntity::ORIGIN_MANUALLY_CREATED,
'options' => [
'when_to_run' => 'immediately',
],
'trigger' => [
'name' => '',
'options' => [],
],
'rules' => [],
'actions' => [],
],
$data
);
$post_id = self::create_post( $data );
$workflow = self::create_workflow_object_from_data( $post_id, $data );
// Clear cached workflow data.
Cache::flush_group( 'workflows' );
do_action( 'automatewoo/workflow/created', $workflow->get_id() );
return $workflow;
}
/**
* Update a workflow from an array of data.
*
* @since 6.0.10
*
* @param array $data The array of workflow data.
*
* @return Workflow
* @throws InvalidWorkflow When there is an issue updating the workflow.
*/
public static function update_from_array( $data = [] ) {
$post_id = self::update_post( $data );
$workflow = self::create_workflow_object_from_data( $post_id, $data );
// Clear cached workflow data.
Cache::flush_group( 'workflows' );
do_action( 'automatewoo/workflow/updated', $workflow->get_id() );
return $workflow;
}
/**
* Create a post object from an array of workflow data.
*
* @param array $data The array of workflow data.
*
* @return int The created post ID.
* @throws InvalidWorkflow When there is a problem creating the post.
*/
private static function create_post( array $data ): int {
$post_data = self::prepare_post_data( $data );
$post_id = wp_insert_post( $post_data, true );
if ( $post_id instanceof WP_Error ) {
throw InvalidWorkflow::error_creating_workflow( esc_html( $post_id->get_error_message() ) );
}
return $post_id;
}
/**
* Update a post object from an array of workflow data.
*
* @param array $data The array of workflow data.
*
* @return int The updated post ID.
* @throws InvalidWorkflow When there is a problem updating the post.
*/
private static function update_post( array $data ): int {
$post_data = self::prepare_post_data( $data );
$post_id = wp_update_post( $post_data, true );
if ( $post_id instanceof WP_Error ) {
throw InvalidWorkflow::error_updating_workflow( esc_html( $post_id->get_error_message() ) );
}
return $post_id;
}
/**
* Create an array of post data from an array of workflow data.
*
* The 'status' property within the $data array should NOT be the post type equivalent. This
* method will handle converting to the post type version of the status.
*
* @param array $data The array of workflow data.
*
* @return array
*/
private static function prepare_post_data( $data ): array {
if ( isset( $data['status'] ) ) {
$data['status'] = $data['status'] instanceof Status
? $data['status']->get_post_status()
: ( new Status( $data['status'] ) )->get_post_status();
}
$post_keys = [
'id' => 'ID',
'title' => 'post_title',
'status' => 'post_status',
'order' => 'menu_order',
];
$post_data = [ 'post_type' => Workflow::POST_TYPE ];
foreach ( array_intersect_key( $data, $post_keys ) as $key => $value ) {
$post_data[ $post_keys[ $key ] ] = $value;
}
return $post_data;
}
/**
* Create a workflow object from an array of data.
*
* @param int $id Workflow ID.
* @param array $data Workflow data.
*
* @return Workflow
*/
private static function create_workflow_object_from_data( int $id, array $data ): Workflow {
$workflow = new Workflow( $id );
$workflow->set_trigger_data( $data['trigger']['name'], $data['trigger']['options'] );
$workflow->set_type( $data['type'] );
if ( ! empty( $data['rules'] ) ) {
$workflow->set_rule_data( $data['rules'] );
}
if ( ! empty( $data['actions'] ) ) {
$workflow->set_actions_data( self::maybe_convert_to_legacy_action_data( $data['actions'] ) );
}
$workflow->update_meta( 'workflow_options', $data['options'] );
$workflow->update_meta( 'is_transactional', $data['is_transactional'] );
$workflow->update_meta( 'origin', $data['origin'] );
return $workflow;
}
/**
* Convert action data structure to legacy data structure.
*
* @since 5.1.0
*
* @param array $actions
*
* @return array
*/
private static function maybe_convert_to_legacy_action_data( array $actions ): array {
$converted = [];
foreach ( $actions as $action ) {
if ( isset( $action['action_name'] ) ) {
$converted[] = $action;
continue;
}
if ( isset( $action['name'], $action['options'] ) ) {
$converted[] = array_merge(
[ 'action_name' => $action['name'] ],
$action['options']
);
}
}
return $converted;
}
}