WooCommerceOrderMetaBox.php
130 lines
| 1 | <?php |
| 2 | |
| 3 | namespace IAWP\WooCommerceOrderMetaBox; |
| 4 | |
| 5 | use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController; |
| 6 | use IAWPSCOPED\Carbon\CarbonImmutable; |
| 7 | use IAWP\Illuminate_Builder; |
| 8 | use IAWP\Tables; |
| 9 | use IAWP\Utils\Format; |
| 10 | use IAWP\Utils\Timezone; |
| 11 | use IAWPSCOPED\Illuminate\Database\Query\JoinClause; |
| 12 | /** @internal */ |
| 13 | class WooCommerceOrderMetaBox |
| 14 | { |
| 15 | private int $order_id; |
| 16 | private ?object $record; |
| 17 | public function __construct(int $order_id) |
| 18 | { |
| 19 | $this->order_id = $order_id; |
| 20 | $this->record = $this->record(); |
| 21 | } |
| 22 | public function add_meta_box() : void |
| 23 | { |
| 24 | if ($this->record === null) { |
| 25 | return; |
| 26 | } |
| 27 | \add_meta_box('iawp-wc-referrer-source', \esc_html__('Customer Journey', 'independent-analytics'), function () { |
| 28 | $this->render(); |
| 29 | }, self::woocommerce_screen_id(), 'side'); |
| 30 | } |
| 31 | private function render() : void |
| 32 | { |
| 33 | if ($this->record === null) { |
| 34 | return; |
| 35 | } |
| 36 | echo \IAWPSCOPED\iawp_render('woocommerce-order-meta-box', ['record' => $this->record, 'journey_url' => $this->journey_url()]); |
| 37 | } |
| 38 | private function journey_url() : string |
| 39 | { |
| 40 | $session_id = $this->record->session_id; |
| 41 | $visitor_id = $this->record->visitor_id; |
| 42 | return \add_query_arg(['visitor' => $visitor_id, 'session' => $session_id], \admin_url('admin.php?page=independent-analytics-visitor')); |
| 43 | } |
| 44 | private function record() : ?object |
| 45 | { |
| 46 | $query = Illuminate_Builder::new()->select('initial_resources.cached_title AS initial_page_title', 'initial_resources.cached_url AS initial_page_url', 'sessions.total_views', 'sessions.created_at AS arrived_at', 'sessions.session_id', 'sessions.visitor_id', 'orders.created_at AS ordered_at', 'landing_pages.title AS landing_page_title', 'utm_sources.utm_source', 'utm_mediums.utm_medium', 'utm_campaigns.utm_campaign', 'utm_term', 'utm_content', 'referrers.referrer', 'referrers.domain AS referrer_domain', 'referrer_types.referrer_type', 'countries.country', 'countries.country_code', 'cities.city', 'device_types.device_type', 'device_oss.device_os', 'device_browsers.device_browser')->from(Tables::orders(), 'orders')->join(Tables::views() . ' AS views', function (JoinClause $join) { |
| 47 | $join->on('views.id', '=', 'orders.view_id'); |
| 48 | })->join(Tables::sessions() . ' AS sessions', function (JoinClause $join) { |
| 49 | $join->on('sessions.session_id', '=', 'views.session_id'); |
| 50 | })->leftJoin(Tables::campaigns() . ' AS campaigns', function (JoinClause $join) { |
| 51 | $join->on('sessions.campaign_id', '=', 'campaigns.campaign_id'); |
| 52 | })->leftJoin(Tables::landing_pages() . ' AS landing_pages', function (JoinClause $join) { |
| 53 | $join->on('campaigns.landing_page_id', '=', 'landing_pages.id'); |
| 54 | })->leftJoin(Tables::utm_sources() . ' AS utm_sources', function (JoinClause $join) { |
| 55 | $join->on('campaigns.utm_source_id', '=', 'utm_sources.id'); |
| 56 | })->leftJoin(Tables::utm_mediums() . ' AS utm_mediums', function (JoinClause $join) { |
| 57 | $join->on('campaigns.utm_medium_id', '=', 'utm_mediums.id'); |
| 58 | })->leftJoin(Tables::utm_campaigns() . ' AS utm_campaigns', function (JoinClause $join) { |
| 59 | $join->on('campaigns.utm_campaign_id', '=', 'utm_campaigns.id'); |
| 60 | })->leftJoin(Tables::referrers() . ' AS referrers', function (JoinClause $join) { |
| 61 | $join->on('sessions.referrer_id', '=', 'referrers.id'); |
| 62 | })->leftJoin(Tables::referrer_types() . ' AS referrer_types', function (JoinClause $join) { |
| 63 | $join->on('referrers.referrer_type_id', '=', 'referrer_types.id'); |
| 64 | })->leftJoin(Tables::views() . ' AS initial_views', function (JoinClause $join) { |
| 65 | $join->on('sessions.initial_view_id', '=', 'initial_views.id'); |
| 66 | })->leftJoin(Tables::resources() . ' AS initial_resources', function (JoinClause $join) { |
| 67 | $join->on('initial_views.resource_id', '=', 'initial_resources.id'); |
| 68 | })->leftJoin(Tables::countries() . ' AS countries', function (JoinClause $join) { |
| 69 | $join->on('sessions.country_id', '=', 'countries.country_id'); |
| 70 | })->leftJoin(Tables::cities() . ' AS cities', function (JoinClause $join) { |
| 71 | $join->on('sessions.city_id', '=', 'cities.city_id'); |
| 72 | })->leftJoin(Tables::device_types() . ' AS device_types', function (JoinClause $join) { |
| 73 | $join->on('sessions.device_type_id', '=', 'device_types.device_type_id'); |
| 74 | })->leftJoin(Tables::device_oss() . ' AS device_oss', function (JoinClause $join) { |
| 75 | $join->on('sessions.device_os_id', '=', 'device_oss.device_os_id'); |
| 76 | })->leftJoin(Tables::device_browsers() . ' AS device_browsers', function (JoinClause $join) { |
| 77 | $join->on('sessions.device_browser_id', '=', 'device_browsers.device_browser_id'); |
| 78 | })->where('orders.woocommerce_order_id', '=', $this->order_id); |
| 79 | $record = $query->get()->first(); |
| 80 | if (!$record) { |
| 81 | return null; |
| 82 | } |
| 83 | if ($record->referrer_domain === "") { |
| 84 | $record->referrer_domain = null; |
| 85 | } |
| 86 | $record->arrived_at = $this->format_date($record->arrived_at); |
| 87 | $record->ordered_at = $this->format_date($record->ordered_at); |
| 88 | return $record; |
| 89 | } |
| 90 | private function format_date(string $value) : string |
| 91 | { |
| 92 | try { |
| 93 | $date = CarbonImmutable::parse($value, 'utc')->setTimezone(Timezone::site_timezone()); |
| 94 | return $date->format(Format::time()); |
| 95 | } catch (\Throwable $e) { |
| 96 | return $value; |
| 97 | } |
| 98 | } |
| 99 | public static function register() |
| 100 | { |
| 101 | \add_action('add_meta_boxes', function ($post_type, $post) { |
| 102 | if (!\IAWPSCOPED\iawp()->is_woocommerce_support_enabled()) { |
| 103 | return; |
| 104 | } |
| 105 | $current_screen_id = \get_current_screen()->id ?? null; |
| 106 | if ($current_screen_id !== self::woocommerce_screen_id()) { |
| 107 | return; |
| 108 | } |
| 109 | $order_id = self::get_order_id($post); |
| 110 | $box = new self($order_id); |
| 111 | $box->add_meta_box(); |
| 112 | }, 10, 2); |
| 113 | } |
| 114 | private static function get_order_id($post) : int |
| 115 | { |
| 116 | $order = $post; |
| 117 | if ($post instanceof \WP_Post) { |
| 118 | $order = wc_get_order($post->ID); |
| 119 | } |
| 120 | return $order->get_id(); |
| 121 | } |
| 122 | private static function woocommerce_screen_id() : string |
| 123 | { |
| 124 | if (\class_exists('\\Automattic\\WooCommerce\\Internal\\DataStores\\Orders\\CustomOrdersTableController') && wc_get_container()->get(CustomOrdersTableController::class)->custom_orders_table_usage_is_enabled()) { |
| 125 | return wc_get_page_screen_id('shop-order'); |
| 126 | } |
| 127 | return 'shop_order'; |
| 128 | } |
| 129 | } |
| 130 |