automatewoo/admin/Analytics/Rest_API/Conversions/Controller.php
fei-source 47d3c9a8b6 Update to v6.2.2
Source: GrootMade/Festinger Vault
2026-03-15 08:31:15 +08:00

293 lines
8.9 KiB
PHP

<?php
namespace AutomateWoo\Admin\Analytics\Rest_API\Conversions;
defined( 'ABSPATH' ) || exit;
use AutomateWoo\Admin\Analytics\Rest_API\Upstream\Generic_Controller;
use AutomateWoo\Admin\Analytics\Rest_API\Upstream\Generic_Query;
use Automattic\WooCommerce\Admin\API\Reports\ExportableInterface;
use Automattic\WooCommerce\Admin\API\Reports\ParameterException;
/**
* REST API Conversions Report list controller class.
*
* @since 5.7.0
*/
class Controller extends Generic_Controller implements ExportableInterface {
/**
* Route base.
*
* @var string
*/
protected $rest_base = 'reports/conversions';
/**
* Forwards a Conversions Query constructor.
*
* @param array $query_args Set of args to be forwarded to the constructor.
* @return Generic_Query
*/
protected function construct_query( $query_args ) {
return new Generic_Query( $query_args, 'report-conversions-list' );
}
/**
* Get the order number for an order. If no filter is present for `woocommerce_order_number`, we can just return the ID.
* Returns the parent order number if the order is actually a refund.
*
* @param int $order_id Order ID.
* @return string|null
*/
protected function get_order_number( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof \WC_Order && ! $order instanceof \WC_Order_Refund ) {
return null;
}
if ( 'shop_order_refund' === $order->get_type() ) {
$order = wc_get_order( $order->get_parent_id() );
}
if ( ! has_filter( 'woocommerce_order_number' ) ) {
return (string) $order->get_id();
}
return $order->get_order_number();
}
/**
* Get the order total with the related currency formatting.
* Returns the parent order total if the order is actually a refund.
*
* @param int $order_id Order ID.
* @return string|null
*/
protected function get_total_formatted( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order instanceof \WC_Order && ! $order instanceof \WC_Order_Refund ) {
return null;
}
if ( 'shop_order_refund' === $order->get_type() ) {
$order = wc_get_order( $order->get_parent_id() );
}
return wp_strip_all_tags( html_entity_decode( $order->get_formatted_order_total() ), true );
}
/**
* Get all reports.
*
* @param \WP_REST_Request $request Request data.
* @return \WP_REST_Response|\WP_Error
*/
public function get_items( $request ) {
$query_args = $this->prepare_reports_query( $request );
$query = $this->construct_query( $query_args );
try {
$report_data = $query->get_data();
} catch ( ParameterException $e ) {
return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
$data = array();
foreach ( $report_data->data as $orders_data ) {
$orders_data['order_number'] = $this->get_order_number( $orders_data['order_id'] );
$orders_data['total_formatted'] = $this->get_total_formatted( $orders_data['order_id'] );
$item = $this->prepare_item_for_response( (object) $orders_data, $request );
$data[] = $this->prepare_response_for_collection( $item );
}
return $this->add_pagination_headers(
$request,
$data,
(int) $report_data->total,
(int) $report_data->page_no,
(int) $report_data->pages
);
}
/**
* Get the column names for export.
*
* @since 6.1.9
*
* @return array Key value pair of Column ID => Label.
*/
public function get_export_columns() {
$export_columns = array(
'order_number' => __( 'Order #', 'automatewoo' ),
'customer' => __( 'Customer', 'automatewoo' ),
'workflow' => __( 'Workflow', 'automatewoo' ),
'conversion' => __( 'Log', 'automatewoo' ),
'first_interacted' => __( 'First Interacted', 'automatewoo' ),
'order_placed' => __( 'Order Placed', 'automatewoo' ),
'order_total' => __( 'Order Total', 'automatewoo' ),
);
/**
* Filter to add or remove column names from the conversions report for export.
*/
return apply_filters(
'automatewoo_report_conversions_export_columns',
$export_columns
);
}
/**
* Get the column values for export.
*
* @since 6.1.9
*
* @param array $item Single report item/row.
* @return array Key value pair of Column ID => Row Value.
*/
public function prepare_item_for_export( $item ) {
$user_id = $item['extended_info']['customer']['user_id'] ?? 'guest';
$export_item = array(
'order_number' => $item['order_number'],
'customer' => "{$item['extended_info']['customer']['first_name']} {$item['extended_info']['customer']['last_name']} ({$user_id})",
'workflow' => $item['workflow_id'],
'conversion' => $item['conversion_id'],
'first_interacted' => $item['extended_info']['conversion']['date_opened'] ?? '',
'order_placed' => $item['date_created'],
'order_total' => $item['total_sales'],
);
/**
* Filter to prepare extra columns in the export item for the conversions export.
*/
return apply_filters(
'automatewoo_report_conversions_prepare_export_item',
$export_item,
$item
);
}
/**
* Get the Report's schema, conforming to JSON Schema.
*
* @return array
*/
public function get_item_schema() {
$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'report_conversions_list',
'type' => 'object',
'properties' => array(
'order_id' => array(
'description' => __( 'Order ID.', 'automatewoo' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'order_number' => array(
'description' => __( 'Order Number.', 'automatewoo' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'date_created' => array(
'description' => __( "Date the order was created, in the site's timezone.", 'automatewoo' ),
'type' => 'string',
'format' => 'date-time',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'date_created_gmt' => array(
'description' => __( 'Date the order was created, as GMT.', 'automatewoo' ),
'type' => 'string',
'format' => 'date-time',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'customer_id' => array(
'description' => __( 'Customer ID.', 'automatewoo' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'total_sales' => array(
'description' => __( 'Order total.', 'automatewoo' ),
'type' => 'number',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'total_formatted' => array(
'description' => __( 'Order total (formatted).', 'automatewoo' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'workflow_id' => array(
'description' => __( 'Workflow ID which triggered the conversion.', 'automatewoo' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'conversion_id' => array(
'description' => __( 'Conversion log ID.', 'automatewoo' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'extended_info' => array(
'customer' => array(
'type' => 'object',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'Order customer information.', 'automatewoo' ),
),
'workflow' => array(
'type' => 'object',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'Workflow information.', 'automatewoo' ),
),
'conversion' => array(
'type' => 'object',
'readonly' => true,
'context' => array( 'view', 'edit' ),
'description' => __( 'Conversion information.', 'automatewoo' ),
),
),
),
);
return $this->add_additional_fields_schema( $schema );
}
/**
* Get the query params for collections.
*
* @return array
*/
public function get_collection_params() {
$params = parent::get_collection_params();
$params['extended_info'] = array(
'description' => __( 'Add additional info about each conversion to the report.', 'automatewoo' ),
'type' => 'boolean',
'default' => false,
'sanitize_callback' => 'wc_string_to_bool',
'validate_callback' => 'rest_validate_request_arg',
);
$params['workflows'] = array(
'description' => __( 'Limit result set to specific workflow IDs.', 'automatewoo' ),
'type' => 'array',
'sanitize_callback' => 'wp_parse_id_list',
'validate_callback' => 'rest_validate_request_arg',
'items' => array(
'type' => 'integer',
),
);
return $params;
}
}