| 1 |
<?php |
| 2 |
|
| 3 |
declare(strict_types=1); |
| 4 |
|
| 5 |
namespace RenzoJohnson\Blocks\Settings\Tabs; |
| 6 |
|
| 7 |
use RenzoJohnson\Blocks\Settings\FieldDefinition; |
| 8 |
use RenzoJohnson\Blocks\Settings\FieldType; |
| 9 |
use RenzoJohnson\Blocks\Settings\Requirement; |
| 10 |
use RenzoJohnson\Blocks\Settings\SanitizerType; |
| 11 |
use RenzoJohnson\Blocks\Settings\SectionDefinition; |
| 12 |
use RenzoJohnson\Blocks\Settings\SettingDefinition; |
| 13 |
use RenzoJohnson\Blocks\Settings\TabDefinition; |
| 14 |
use RenzoJohnson\Blocks\Settings\TabProvider; |
| 15 |
|
| 16 |
\defined( 'ABSPATH' ) || exit; |
| 17 |
|
| 18 |
final class AnalyticsTab implements TabProvider { |
| 19 |
public function definition(): TabDefinition { |
| 20 |
return new TabDefinition( |
| 21 |
'analytics', |
| 22 |
\__( 'Analytics', 'blocks' ), |
| 23 |
array( |
| 24 |
new SectionDefinition( |
| 25 |
'blocks_analytics_identity', |
| 26 |
\__( 'GA4 Configuration', 'blocks' ), |
| 27 |
array( \__( 'Configure one Google Analytics 4 owner for this site.', 'blocks' ) ), |
| 28 |
array( |
| 29 |
$this->field( 'blocks_ga4_measurement_id', \__( 'GA4 Measurement ID', 'blocks' ), \__( 'Google Analytics 4 web-stream ID, for example G-ABC123XYZ.', 'blocks' ), FieldType::Text, 'string', '', SanitizerType::Ga4MeasurementId, public_token: 'ga4_measurement_id' ), |
| 30 |
$this->checkbox( 'blocks_ga4_ecommerce_enabled', \__( 'GA4 Analytics', 'blocks' ), \__( 'Load the async Google tag and enabled analytics events. When disabled, Blocks loads no analytics assets and does not suppress another analytics owner.', 'blocks' ) ), |
| 31 |
$this->checkbox( 'blocks_ga4_zaraz_enabled', \__( 'Cloudflare Zaraz Transport', 'blocks' ), \__( 'Send frontend analytics through the dedicated zaraz subdomain instead of loading gtag.js directly. Enable only after the proxied hostname and Zaraz GA4 tool are configured.', 'blocks' ) ), |
| 32 |
$this->field( |
| 33 |
'blocks_ga4_product_identifier', |
| 34 |
\__( 'Product Identification', 'blocks' ), |
| 35 |
\__( 'Choose the stable identifier sent for WooCommerce products. Changing it can split historical reports.', 'blocks' ), |
| 36 |
FieldType::Select, |
| 37 |
'string', |
| 38 |
'product_id', |
| 39 |
SanitizerType::Ga4ProductIdentifier, |
| 40 |
array( |
| 41 |
'options' => array( |
| 42 |
'product_id' => \__( 'Product ID', 'blocks' ), |
| 43 |
'product_sku' => \__( 'Product SKU with prefixed ID fallback', 'blocks' ), |
| 44 |
), |
| 45 |
) |
| 46 |
), |
| 47 |
$this->checkbox( 'blocks_ga4_display_advertising_enabled', \__( 'Display Advertising Support', 'blocks' ), \__( 'Allow Google signals for advertising features. Leave off unless your consent and privacy policy cover this use.', 'blocks' ) ), |
| 48 |
$this->checkbox( 'blocks_ga4_linker_allow_incoming_enabled', \__( 'Accept Incoming Linker Parameters', 'blocks' ), \__( 'Allow valid incoming Google linker parameters from configured cross-domain journeys.', 'blocks' ) ), |
| 49 |
$this->field( 'blocks_ga4_cross_domains', \__( 'Cross-Domain Tracking', 'blocks' ), \__( 'Comma-separated hostnames that belong to the same measured journey, for example example.com, checkout.example.com.', 'blocks' ), FieldType::Text, 'string', '', SanitizerType::Ga4DomainList ), |
| 50 |
), |
| 51 |
), |
| 52 |
new SectionDefinition( |
| 53 |
'blocks_analytics_events', |
| 54 |
\__( 'Events', 'blocks' ), |
| 55 |
array( \__( 'Enable only the events required by this site.', 'blocks' ) ), |
| 56 |
array( |
| 57 |
$this->field( 'blocks_ga4_mp_api_secret', \__( 'GA4 Measurement Protocol API Secret', 'blocks' ), \__( 'Encrypted server credential used only for queued add-to-cart delivery. Create it in GA4 Admin → Data Streams → Measurement Protocol API secrets.', 'blocks' ), FieldType::Secret, 'string', '', SanitizerType::Secret, sensitive: true, exportable: false ), |
| 58 |
$this->checkbox( 'blocks_ga4_404_enabled', \__( 'Track 404 Errors', 'blocks' ), \__( 'Send the existing 404 Not Found analytics event on not-found pages.', 'blocks' ) ), |
| 59 |
$this->checkbox( 'blocks_ga4_purchase_enabled', \__( 'Purchase Transactions', 'blocks' ), \__( 'Send one purchase event from a valid WooCommerce order-received page.', 'blocks' ) ), |
| 60 |
$this->checkbox( 'blocks_ga4_add_to_cart_enabled', \__( 'Add to Cart Events', 'blocks' ), \__( 'Queue one server-side add_to_cart event after WooCommerce accepts an item. Requires the encrypted API secret.', 'blocks' ) ), |
| 61 |
$this->checkbox( 'blocks_ga4_remove_from_cart_enabled', \__( 'Remove from Cart Events', 'blocks' ), \__( 'Send remove_from_cart when a shopper removes a known cart item.', 'blocks' ) ), |
| 62 |
$this->checkbox( 'blocks_ga4_view_item_list_enabled', \__( 'Product Impressions', 'blocks' ), \__( 'Send view_item_list for WooCommerce lists and Blocks pricing cards in the visitor browser.', 'blocks' ) ), |
| 63 |
$this->checkbox( 'blocks_ga4_select_content_enabled', \__( 'Product List Clicks', 'blocks' ), \__( 'Preserve the existing select_content event for product-list selections.', 'blocks' ) ), |
| 64 |
$this->checkbox( 'blocks_ga4_view_item_enabled', \__( 'Product Detail Views', 'blocks' ), \__( 'Send view_item on a valid single-product page.', 'blocks' ) ), |
| 65 |
$this->checkbox( 'blocks_ga4_begin_checkout_enabled', \__( 'Checkout Process', 'blocks' ), \__( 'Send begin_checkout plus shipping and payment information events during checkout.', 'blocks' ) ), |
| 66 |
), |
| 67 |
), |
| 68 |
), |
| 69 |
); |
| 70 |
} |
| 71 |
|
| 72 |
/** |
| 73 |
* @param array<string, mixed> $render_args Renderer arguments. |
| 74 |
*/ |
| 75 |
private function field( |
| 76 |
string $option_name, |
| 77 |
string $label, |
| 78 |
string $description, |
| 79 |
FieldType $type, |
| 80 |
string $wp_type, |
| 81 |
bool|int|string $default_value, |
| 82 |
SanitizerType $sanitizer, |
| 83 |
array $render_args = array(), |
| 84 |
bool $sensitive = false, |
| 85 |
bool $exportable = true, |
| 86 |
?string $public_token = null, |
| 87 |
): FieldDefinition { |
| 88 |
return new FieldDefinition( |
| 89 |
$option_name, |
| 90 |
$label, |
| 91 |
$description, |
| 92 |
$type, |
| 93 |
array( new SettingDefinition( $option_name, $wp_type, $default_value, $sanitizer, $sensitive, $exportable, $public_token ) ), |
| 94 |
$render_args, |
| 95 |
Requirement::Always, |
| 96 |
); |
| 97 |
} |
| 98 |
|
| 99 |
private function checkbox( string $option_name, string $label, string $description ): FieldDefinition { |
| 100 |
return $this->field( $option_name, $label, $description, FieldType::Checkbox, 'boolean', false, SanitizerType::Boolean ); |
| 101 |
} |
| 102 |
} |
| 103 |
|