Plugin Directory

Changeset 3185508


Ignore:
Timestamp:
11/11/2024 08:22:28 AM (16 months ago)
Author:
mergado
Message:

4.0.0

Location:
mergado-marketing-pack/trunk
Files:
9 added
52 edited

Legend:

Unmodified
Added
Removed
  • mergado-marketing-pack/trunk/README.txt

    r3134668 r3185508  
    11=== Mergado Pack ===
    2 Stable tag: 3.7.4
     2Stable tag: 4.0.0
    33Contributors: mergado
    44Donate link: https://pack.mergado.com/woocommerce
    55Tags: woocommerce, marketing, xml, export, feed
    66Requires at least: 4.5.1
    7 Tested up to: 6.6
     7Tested up to: 6.7
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    265265== Changelog ==
    266266
     267= 4.0.0 =
     268* BREAKING CHANGE: GAds, GUA, GTM, Facebook/Glami/Biano pixel - Updated VAT handling in product price settings for events. All events now follow the checkbox settings instead of shop defaults.
     269* NEW: Added custom actions `mergado_product_feed__before` and `mergado_product_feed__after` for use before and after product feed generation.
     270* NEW: Custom JS event `mmp_ga4_add_to_cart` added.
     271* NEW: Biano/Facebook/GA4/GAds/GUA/GTM - New option to enable/disable composite product ID.
     272* NEW: GA4 - Added toggle option for provided events.
     273* NEW: Product feed - Added shipping label field.
     274* NEW: Google Ads - Added option to select business type: retail/custom.
     275* IMPROVEMENT: GTM/GA4 - Product detail view event moved to occur after product click event.
     276* IMPROVEMENT: GA4 - Add to cart event now supports `product_id` parameter if `add-to-cart` doesn’t exist.
     277* IMPROVEMENT: Google Reviews - Lazy loading added for select box in settings to reduce load times and prevent timeout errors.
     278* IMPROVEMENT: Added function to fix or log badly encoded data in product feed generator.
     279* FIX: Corrected data fetching for parameterized URLs of variable products across multiple services.
     280* FIX: Partial resolution of event issues in cart/checkout when using WooCommerce Gutenberg blocks instead of shortcodes.
     281* OTHER: Updated support for the latest WordPress and WooCommerce versions.
     282
    267283= 3.7.4 =
    268284* NEW: Sklik - Customer info to conversion/retargeting hits
  • mergado-marketing-pack/trunk/admin/css/mergado-marketing-pack-admin.css

    r2766764 r3185508  
    950950body[class*="mergado"] .pb-10px {
    951951    padding-bottom: 10px;
     952}
     953
     954body[class*="mergado"] .px-5px {
     955    padding-left: 5px;
     956    padding-right: 5px;
    952957}
    953958
     
    22102215    font-size: 16px;
    22112216}
     2217
     2218.mmp_google-reviews__loading span {
     2219    color: #000000;
     2220    border: 1px solid #e6b819;
     2221    padding: 1px 10px;
     2222    background-color: #fff5af;
     2223    border-radius: 3px;
     2224    margin-top: 6px;
     2225    display: inline-block;
     2226    font-size: 12px;
     2227}
     2228
     2229.mmp_google-reviews__loading--failed span {
     2230    color: #c7254e;
     2231    border: 1px solid #c7254e;
     2232    padding: 1px 10px;
     2233    background-color: var(--mmp-alert--danger);
     2234    border-radius: 3px;
     2235    margin-top: 6px;
     2236    display: inline-block;
     2237    font-size: 12px;
     2238}
  • mergado-marketing-pack/trunk/admin/js/mergado-marketing-pack-admin.js

    r2909979 r3185508  
    33
    44    $(function() {
     5        googleReviewsPrepareInput();
    56        generateInlineCodeForGoogleReviews();
    67        deleteNoticeOnTab();
     
    303304    {
    304305        $('#gr_badge_position_inline_code').remove();
     306    }
     307
     308    function googleReviewsPrepareInput()
     309    {
     310        if($('body.mergado-pack_page_mergado-adsys').length > 0) {
     311
     312            // Get values
     313            var token = $('[data-token]').attr('data-token');
     314
     315            $.ajax({
     316                type: "POST",
     317                url: 'admin-ajax.php',
     318                data: {
     319                    action: 'ajax_get_google_reviews_gtin_values',
     320                    token: token,
     321                    dataType: 'json'
     322                },
     323                success: function(response) {
     324                    const selectedValue = $('.mmp_google-reviews__select').attr('data-default-value');
     325
     326                    response.data.forEach(function(data) {
     327                        const isSelected = (selectedValue == data) ? 'selected="selected"' : '';
     328
     329                        $('.mmp_google-reviews__select').append(`<option ${isSelected} value="${data}">${data}</option>`);
     330                    });
     331
     332                    $('.mmp_google-reviews__input').hide();
     333                    $('.mmp_google-reviews__select').show();
     334                    $('.mmp_google-reviews__loading').hide();
     335                },
     336                error: function(xhr, status, error) {
     337                    $('.mmp_google-reviews__input').show();
     338                    $('.mmp_google-reviews__loading').hide();
     339                    $('.mmp_google-reviews__loading--failed').show();
     340                }
     341            });
     342        }
    305343    }
    306344
  • mergado-marketing-pack/trunk/admin/templates/partials/tabs-adsys/adsys-biano.php

    r3134668 r3185508  
    7575                    <?php echo __('Choose whether the conversion value will be sent with or without VAT.', 'mergado-marketing-pack') ?>
    7676                </small>
     77            </td>
     78        </tr>
     79
     80        <tr>
     81            <th>
     82                <label for="<?php echo BianoService::COMPOSITE_ID_ENABLED ?>"><?php echo __('Composite ID of variation products', 'mergado-marketing-pack') ?></label>
     83            </th>
     84            <td colspan="2"><input type="checkbox"
     85                                   id="<?php echo BianoService::COMPOSITE_ID_ENABLED ?>"
     86                                   name="<?php echo BianoService::COMPOSITE_ID_ENABLED ?>"
     87                                   data-mmp-check-field="<?php echo BianoService::ACTIVE ?>"
     88                                   <?php if ($bianoService->isCompositeIdEnabled()){ ?>checked="checked"<?php } ?>>
     89                <br>
     90                <small class="badge badge_info"><?php echo __('Choose whether the IDs of the variation products will be sent as a composite e.g., "productId-variantId".', 'mergado-marketing-pack')?></small>
    7791            </td>
    7892        </tr>
  • mergado-marketing-pack/trunk/admin/templates/partials/tabs-adsys/adsys-facebook.php

    r3134668 r3185508  
    33use Mergado\Service\External\Facebook\FacebookService;
    44
    5 $facebookClass = FacebookService::getInstance();
     5$facebookService = FacebookService::getInstance();
    66?>
    77
     
    1515            </th>
    1616            <td><input type="checkbox" id="facebook-form-active" name="facebook-form-active"
    17                        data-mmp-check-main="facebook-active" data-mmp-activity-check-checkbox="true"
    18                        <?php if ($facebookClass->getActive() === 1){ ?>checked="checked"<?php } ?>>
     17                       data-mmp-check-main="<?php echo FacebookService::ACTIVE ?>" data-mmp-activity-check-checkbox="true"
     18                       <?php if ($facebookService->getActive() === 1){ ?>checked="checked"<?php } ?>>
    1919            </td>
    2020        </tr>
     
    2424            </th>
    2525            <td><input type="text" id="facebook-form-pixel" name="facebook-form-pixel"
    26                        data-mmp-check-field="facebook-active"
     26                       data-mmp-check-field="<?php echo FacebookService::ACTIVE ?>"
    2727                       placeholder="<?php echo __('Insert code here', 'mergado-marketing-pack') ?>"
    28                        value="<?php echo $facebookClass->getCode() ?>">
     28                       value="<?php echo $facebookService->getCode() ?>">
    2929                <br><small
    3030                        class="badge badge_question"><?php echo __('Pixel ID can be found in your Facebook Business Manager. Go to Events Manager > Add new data feed > Facebook pixel. Pixel ID is displayed below the title on the Overview page at the top left.', 'mergado-marketing-pack') ?></small>
     
    3636            </th>
    3737            <td><input type="checkbox" id="facebook-vat-included" name="facebook-vat-included"
    38                        data-mmp-check-field="facebook-active"
    39                        <?php if ($facebookClass->isConversionWithVat()){ ?>checked="checked"<?php } ?>>
     38                       data-mmp-check-field="<?php echo FacebookService::ACTIVE ?>"
     39                       <?php if ($facebookService->isConversionWithVat()){ ?>checked="checked"<?php } ?>>
    4040                <br><small
    4141                        class="badge badge_info"><?php echo __('Choose whether the conversion value will be sent with or without VAT.', 'mergado-marketing-pack') ?></small>
     42            </td>
     43        </tr>
     44
     45        <tr>
     46            <th>
     47                <label for="<?php echo FacebookService::COMPOSITE_ID_ENABLED ?>"><?php echo __('Composite ID of variation products', 'mergado-marketing-pack') ?></label>
     48            </th>
     49            <td colspan="2"><input type="checkbox"
     50                                   id="<?php echo FacebookService::COMPOSITE_ID_ENABLED ?>"
     51                                   name="<?php echo FacebookService::COMPOSITE_ID_ENABLED ?>"
     52                                   data-mmp-check-field="<?php echo FacebookService::ACTIVE ?>"
     53                                   <?php if ($facebookService->isCompositeIdEnabled()){ ?>checked="checked"<?php } ?>>
     54                <br>
     55                <small class="badge badge_info"><?php echo __('Choose whether the IDs of the variation products will be sent as a composite e.g., "productId-variantId".', 'mergado-marketing-pack')?></small>
    4256            </td>
    4357        </tr>
  • mergado-marketing-pack/trunk/admin/templates/partials/tabs-adsys/adsys-google.php

    r3134668 r3185508  
    1212$googleAds = GoogleAdsService::getInstance();
    1313$googleTagManager = GoogleTagManagerService::getInstance();
    14 
    15 
    16 global $wpdb;
    17 
    18 $query = 'SELECT DISTINCT postmeta.meta_key FROM ';
    19 $query .= $wpdb->prefix . 'posts AS posts';
    20 $query .= ' LEFT JOIN ' . $wpdb->prefix . 'postmeta AS postmeta ON posts.id = postmeta.post_id';
    21 $query .= ' WHERE (posts.post_type="product" OR posts.post_type="product_variation") AND postmeta.meta_key NOT LIKE "\_%"';
    22 
    23 $result = $wpdb->get_results($query, ARRAY_A);
    24 $fields = [0 => '_sku'];
    25 
    26 foreach ($result as $item) {
    27     $fields[] = $item['meta_key'];
    28 }
    29 
    30 $attributes = wc_get_attribute_taxonomies();
    31 $select = [0 => '_sku'];
    32 
    33 foreach ($attributes as $attr) {
    34     $select[] = $attr->attribute_name;
    35 }
    36 
    37 $fields = array_merge($fields, $select);
    3814?>
    3915
     
    6844            <td><input type="checkbox" id="adwords-form-remarketing-active"
    6945                       name="adwords-form-remarketing-active"
     46                       data-mmp-check-main="adwords-remarketing"
    7047                       <?php if ($googleAds->getRemarketingActive() === 1){ ?>checked="checked"<?php } ?>>
     48            </td>
     49        </tr>
     50        <tr>
     51            <th>
     52                <label for="<?php echo GoogleAdsService::BUSINESS_TYPE; ?>"><?php echo __('Select Business type', 'mergado-marketing-pack'); ?></label>
     53            </th>
     54            <td>
     55                <select name="<?php echo GoogleAdsService::BUSINESS_TYPE; ?>"
     56                        id="<?php echo GoogleAdsService::BUSINESS_TYPE ?>"
     57                        data-mmp-check-field="adwords-remarketing">
     58                <?php foreach (GoogleAdsService::ALL_BUSINESS_TYPES as $key => $name): ?>
     59                    <option
     60                        <?php if ($googleAds->getBusinessType() === $key){ ?>selected="selected"<?php } ?>
     61                        value="<?php echo $key ?>"
     62                    >
     63                        <?php echo $name ?>
     64                    </option>
     65                <?php endforeach ?>
     66                </select>
     67
     68                <br>
     69                <small class="badge badge_info"><?php echo __('Mergado Pack supports tag implementations for ecommerce solutions only. If your business type is not ecommerce, select Custom.', 'mergado-marketing-pack') ?></small>
    7170            </td>
    7271        </tr>
     
    118117                <br><small
    119118                        class="badge badge_info"><?php echo __('Choose whether the price of the products will be sent with or without VAT.', 'mergado-marketing-pack') ?></small>
     119            </td>
     120        </tr>
     121
     122        <tr>
     123            <th>
     124                <label for="<?php echo GoogleAdsService::COMPOSITE_ID_ENABLED ?>"><?php echo __('Composite ID of variation products', 'mergado-marketing-pack') ?></label>
     125            </th>
     126            <td colspan="2"><input type="checkbox"
     127                                   id="<?php echo GoogleAdsService::COMPOSITE_ID_ENABLED ?>"
     128                                   name="<?php echo GoogleAdsService::COMPOSITE_ID_ENABLED ?>"
     129                                   data-mmp-check-field="<?php echo GoogleAdsService::CONVERSION_ACTIVE ?>"
     130                                   <?php if ($googleAds->isCompositeIdEnabled()){ ?>checked="checked"<?php } ?>>
     131                <br>
     132                <small class="badge badge_info"><?php echo __('Choose whether the IDs of the variation products will be sent as a composite e.g., "productId-variantId".', 'mergado-marketing-pack')?></small>
    120133            </td>
    121134        </tr>
     
    197210                <br><small class="badge badge_info"><?php echo __('Choose whether the price of the products will be sent with or without VAT.
    198211This setting does not affect total revenue. The total revenue of the transaction is calculated including taxes and shipping costs according to the Google Analytics specification.', 'mergado-marketing-pack') ?></small>
     212            </td>
     213        </tr>
     214
     215        <tr>
     216            <th>
     217                <label for="<?php echo GaUniversalService::COMPOSITE_ID_ENABLED ?>"><?php echo __('Composite ID of variation products', 'mergado-marketing-pack') ?></label>
     218            </th>
     219            <td colspan="2"><input type="checkbox"
     220                                   id="<?php echo GaUniversalService::COMPOSITE_ID_ENABLED ?>"
     221                                   name="<?php echo GaUniversalService::COMPOSITE_ID_ENABLED ?>"
     222                                   data-mmp-check-field="<?php echo GaUniversalService::ECOMMERCE ?>"
     223                                   <?php if ($googleUniversalAnalyticsService->isCompositeIdEnabled()){ ?>checked="checked"<?php } ?>>
     224                <br>
     225                <small class="badge badge_info"><?php echo __('Choose whether the IDs of the variation products will be sent as a composite e.g., "productId-variantId".', 'mergado-marketing-pack')?></small>
    199226            </td>
    200227        </tr>
     
    311338            </td>
    312339        </tr>
     340
     341        <tr>
     342            <th>
     343                <label for="<?php echo Ga4Service::COMPOSITE_ID_ENABLED ?>"><?php echo __('Composite ID of variation products', 'mergado-marketing-pack') ?></label>
     344            </th>
     345            <td colspan="2"><input type="checkbox"
     346                                   id="<?php echo Ga4Service::COMPOSITE_ID_ENABLED ?>"
     347                                   name="<?php echo Ga4Service::COMPOSITE_ID_ENABLED ?>"
     348                                   data-mmp-check-field="<?php echo Ga4Service::ECOMMERCE ?>"
     349                                   <?php if ($ga4Service->isCompositeIdEnabled()){ ?>checked="checked"<?php } ?>>
     350                <br>
     351                <small class="badge badge_info"><?php echo __('Choose whether the IDs of the variation products will be sent as a composite e.g., "productId-variantId".', 'mergado-marketing-pack')?></small>
     352            </td>
     353        </tr>
     354
    313355        <tr>
    314356            <th>
     
    329371                        <tr>
    330372                            <th class="px-0 pt-0 pb-5px fw-500"><?php echo $data ?></th>
    331                             <td class="px-0 pt-0 pb-5px">
     373                            <td class="px-5px pt-0 pb-5px">
    332374                                <input type="checkbox" id="<?php echo Ga4Service::REFUND_STATUS . $key ?>"
    333375                                       name="<?php echo Ga4Service::REFUND_STATUS . $key ?>"
     
    341383            </td>
    342384        </tr>
     385        <tr></tr>
     386        <tr>
     387            <th>
     388                <label><?php echo __('Events', 'mergado-marketing-pack') ?></label>
     389            </th>
     390            <td>
     391                <small class="badge badge_info"><?php echo __('Select GA4 events that should be sent. This functionality is intended to disable default events in case you want to implement them on your own.', 'mergado-marketing-pack') ?></small>
     392            </td>
     393        </tr>
     394        <tr style="background-color: white;">
     395            <th>
     396
     397            </th>
     398            <td style="padding-top: 0;">
     399                <hr>
     400                <table>
     401                    <tbody>
     402                    <tr>
     403                        <th class="px-0 pt-0 pb-5px fw-500">
     404                            <label for="<?php echo Ga4Service::ADD_PAYMENT_INFO_EVENT_ENABLED ?>"><?php echo __('add_payment_info', 'mergado-marketing-pack') ?></label>
     405                        </th>
     406                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     407                                   id="<?php echo Ga4Service::ADD_PAYMENT_INFO_EVENT_ENABLED ?>"
     408                                   name="<?php echo Ga4Service::ADD_PAYMENT_INFO_EVENT_ENABLED ?>"
     409                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     410                                   <?php if ($ga4Service->isAddPaymentInfoEventEnabled()){ ?>checked="checked"<?php } ?>>
     411                        </td>
     412                    </tr>
     413
     414                    <tr>
     415                        <th class="px-0 pt-0 pb-5px fw-500">
     416                            <label for="<?php echo Ga4Service::ADD_SHIPPING_INFO_EVENT_ENABLED ?>"><?php echo __('add_shipping_info', 'mergado-marketing-pack') ?></label>
     417                        </th>
     418                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     419                                   id="<?php echo Ga4Service::ADD_SHIPPING_INFO_EVENT_ENABLED ?>"
     420                                   name="<?php echo Ga4Service::ADD_SHIPPING_INFO_EVENT_ENABLED ?>"
     421                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     422                                   <?php if ($ga4Service->isAddShippingInfoEventEnabled()){ ?>checked="checked"<?php } ?>>
     423                        </td>
     424                    </tr>
     425
     426                    <tr>
     427                        <th class="px-0 pt-0 pb-5px fw-500">
     428                            <label for="<?php echo Ga4Service::ADD_TO_CART_EVENT_ENABLED ?>"><?php echo __('add_to_cart', 'mergado-marketing-pack') ?></label>
     429                        </th>
     430                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     431                                   id="<?php echo Ga4Service::ADD_TO_CART_EVENT_ENABLED ?>"
     432                                   name="<?php echo Ga4Service::ADD_TO_CART_EVENT_ENABLED ?>"
     433                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     434                                   <?php if ($ga4Service->isAddToCartEventEnabled()){ ?>checked="checked"<?php } ?>>
     435                        </td>
     436                    </tr>
     437
     438                    <tr>
     439                        <th class="px-0 pt-0 pb-5px fw-500">
     440                            <label for="<?php echo Ga4Service::ADD_TO_CART_AJAX_EVENT_ENABLED ?>"><?php echo __('add_to_cart (ajax)', 'mergado-marketing-pack') ?></label>
     441                        </th>
     442                        <td class="px-5px pt-0 pb-5px">
     443                            <input type="checkbox"
     444                                  id="<?php echo Ga4Service::ADD_TO_CART_AJAX_EVENT_ENABLED ?>"
     445                                  name="<?php echo Ga4Service::ADD_TO_CART_AJAX_EVENT_ENABLED ?>"
     446                                  data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     447                                  <?php if ($ga4Service->isAddToCartAjaxEventEnabled()){ ?>checked="checked"<?php } ?>>
     448                        </td>
     449                    </tr>
     450
     451                    <tr>
     452                        <th class="px-0 pt-0 pb-5px fw-500">
     453                            <label for="<?php echo Ga4Service::BEGIN_CHECKOUT_EVENT_ENABLED ?>"><?php echo __('begin_checkout', 'mergado-marketing-pack') ?></label>
     454                        </th>
     455                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     456                                   id="<?php echo Ga4Service::BEGIN_CHECKOUT_EVENT_ENABLED ?>"
     457                                   name="<?php echo Ga4Service::BEGIN_CHECKOUT_EVENT_ENABLED ?>"
     458                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     459                                   <?php if ($ga4Service->isBeginCheckoutEventEnabled()){ ?>checked="checked"<?php } ?>>
     460                        </td>
     461                    </tr>
     462
     463                    <tr>
     464                        <th class="px-0 pt-0 pb-5px fw-500">
     465                            <label for="<?php echo Ga4Service::PURCHASE_EVENT_ENABLED ?>"><?php echo __('purchase', 'mergado-marketing-pack') ?></label>
     466                        </th>
     467                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     468                                   id="<?php echo Ga4Service::PURCHASE_EVENT_ENABLED ?>"
     469                                   name="<?php echo Ga4Service::PURCHASE_EVENT_ENABLED ?>"
     470                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     471                                   <?php if ($ga4Service->isPurchaseEventEnabled()){ ?>checked="checked"<?php } ?>>
     472                        </td>
     473                    </tr>
     474
     475                    <tr>
     476                        <th class="px-0 pt-0 pb-5px fw-500">
     477                            <label for="<?php echo Ga4Service::REMOVE_FROM_CART_EVENT_ENABLED ?>"><?php echo __('remove_from_cart', 'mergado-marketing-pack') ?></label>
     478                        </th>
     479                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     480                                   id="<?php echo Ga4Service::REMOVE_FROM_CART_EVENT_ENABLED ?>"
     481                                   name="<?php echo Ga4Service::REMOVE_FROM_CART_EVENT_ENABLED ?>"
     482                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     483                                   <?php if ($ga4Service->isRemoveFromCartEventEnabled()){ ?>checked="checked"<?php } ?>>
     484                        </td>
     485                    </tr>
     486
     487                    <tr>
     488                        <th class="px-0 pt-0 pb-5px fw-500">
     489                            <label for="<?php echo Ga4Service::SEARCH_EVENT_ENABLED ?>"><?php echo __('search', 'mergado-marketing-pack') ?></label>
     490                        </th>
     491                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     492                                   id="<?php echo Ga4Service::SEARCH_EVENT_ENABLED ?>"
     493                                   name="<?php echo Ga4Service::SEARCH_EVENT_ENABLED ?>"
     494                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     495                                   <?php if ($ga4Service->isSearchEventEnabled()){ ?>checked="checked"<?php } ?>>
     496                        </td>
     497                    </tr>
     498
     499                    <tr>
     500                        <th class="px-0 pt-0 pb-5px fw-500">
     501                            <label for="<?php echo Ga4Service::SELECT_CONTENT_EVENT_ENABLED ?>"><?php echo __('select_content', 'mergado-marketing-pack') ?></label>
     502                        </th>
     503                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     504                                   id="<?php echo Ga4Service::SELECT_CONTENT_EVENT_ENABLED ?>"
     505                                   name="<?php echo Ga4Service::SELECT_CONTENT_EVENT_ENABLED ?>"
     506                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     507                                   <?php if ($ga4Service->isSelectContentEventEnabled()){ ?>checked="checked"<?php } ?>>
     508                        </td>
     509                    </tr>
     510
     511                    <tr>
     512                        <th class="px-0 pt-0 pb-5px fw-500">
     513                            <label for="<?php echo Ga4Service::SELECT_ITEM_EVENT_ENABLED ?>"><?php echo __('select_item', 'mergado-marketing-pack') ?></label>
     514                        </th>
     515                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     516                                   id="<?php echo Ga4Service::SELECT_ITEM_EVENT_ENABLED ?>"
     517                                   name="<?php echo Ga4Service::SELECT_ITEM_EVENT_ENABLED ?>"
     518                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     519                                   <?php if ($ga4Service->isSelectItemEventEnabled()){ ?>checked="checked"<?php } ?>>
     520                        </td>
     521                    </tr>
     522
     523                    <tr>
     524                        <th class="px-0 pt-0 pb-5px fw-500">
     525                            <label for="<?php echo Ga4Service::VIEW_CART_EVENT_ENABLED ?>"><?php echo __('view_cart', 'mergado-marketing-pack') ?></label>
     526                        </th>
     527                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     528                                   id="<?php echo Ga4Service::VIEW_CART_EVENT_ENABLED ?>"
     529                                   name="<?php echo Ga4Service::VIEW_CART_EVENT_ENABLED ?>"
     530                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     531                                   <?php if ($ga4Service->isViewCartEventEnabled()){ ?>checked="checked"<?php } ?>>
     532                        </td>
     533                    </tr>
     534
     535                    <tr>
     536                        <th class="px-0 pt-0 pb-5px fw-500">
     537                            <label for="<?php echo Ga4Service::VIEW_ITEM_EVENT_ENABLED ?>"><?php echo __('view_item', 'mergado-marketing-pack') ?></label>
     538                        </th>
     539                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     540                                   id="<?php echo Ga4Service::VIEW_ITEM_EVENT_ENABLED ?>"
     541                                   name="<?php echo Ga4Service::VIEW_ITEM_EVENT_ENABLED ?>"
     542                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     543                                   <?php if ($ga4Service->isViewItemEventEnabled()){ ?>checked="checked"<?php } ?>>
     544                        </td>
     545                    </tr>
     546
     547                    <tr>
     548                        <th class="px-0 pt-0 pb-5px fw-500">
     549                            <label for="<?php echo Ga4Service::VIEW_ITEM_LIST_EVENT_ENABLED ?>"><?php echo __('view_item_list', 'mergado-marketing-pack') ?></label>
     550                        </th>
     551                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     552                                   id="<?php echo Ga4Service::VIEW_ITEM_LIST_EVENT_ENABLED ?>"
     553                                   name="<?php echo Ga4Service::VIEW_ITEM_LIST_EVENT_ENABLED ?>"
     554                                   data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     555                                   <?php if ($ga4Service->isViewItemListEventEnabled()){ ?>checked="checked"<?php } ?>>
     556                        </td>
     557                    </tr>
     558
     559                    <tr>
     560                        <th class="px-0 pt-0 pb-5px fw-500">
     561                            <label for="<?php echo Ga4Service::REFUND_EVENT_ENABLED ?>"><?php echo __('refund', 'mergado-marketing-pack') ?></label>
     562                        </th>
     563                        <td class="px-5px pt-0 pb-5px"><input type="checkbox"
     564                                                              id="<?php echo Ga4Service::REFUND_EVENT_ENABLED ?>"
     565                                                              name="<?php echo Ga4Service::REFUND_EVENT_ENABLED ?>"
     566                                                              data-mmp-check-field="<?php echo Ga4Service::ACTIVE ?>"
     567                                                              <?php if ($ga4Service->isRefundEventEnabled()){ ?>checked="checked"<?php } ?>>
     568                        </td>
     569                    </tr>
     570                    </tbody>
     571                </table>
     572            </td>
     573        </tr>
    343574        </tbody>
    344575    </table>
     
    363594            <td><input type="checkbox" id="<?php echo $googleTagManager::ACTIVE ?>"
    364595                       name="<?php echo $googleTagManager::ACTIVE ?>"
    365                        data-mmp-check-main="gtm-active"
     596                       data-mmp-check-main="<?php echo $googleTagManager::ACTIVE ?>"
    366597                       data-mmp-activity-check-checkbox="true"
    367598                       <?php if ($googleTagManager->getActive() === 1){ ?>checked="checked"<?php } ?>>
     
    373604            </th>
    374605            <td><input type="text" id="<?php echo $googleTagManager::CODE ?>"
    375                        name="<?php echo $googleTagManager::CODE ?>" data-mmp-check-field="gtm-active"
     606                       name="<?php echo $googleTagManager::CODE ?>" data-mmp-check-field="<?php echo $googleTagManager::ACTIVE ?>"
    376607                       placeholder="<?php echo __('Insert code here', 'mergado-marketing-pack') ?>"
    377608                       value="<?php echo $googleTagManager->getCode() ?>">
     
    386617            <td><input type="checkbox"
    387618                       id="<?php echo $googleTagManager::ECOMMERCE_ACTIVE ?>"
    388                        data-mmp-check-main="gtm-ecommerce"
    389                        data-mmp-check-field="gtm-active"
     619                       data-mmp-check-main="<?php echo $googleTagManager::ECOMMERCE_ACTIVE ?>"
     620                       data-mmp-check-field="<?php echo $googleTagManager::ACTIVE ?>"
    390621                       name="<?php echo $googleTagManager::ECOMMERCE_ACTIVE ?>"
    391622                       <?php if ($googleTagManager->getEcommerceActive() === 1){ ?>checked="checked"<?php } ?>>
     
    400631            <td><input type="checkbox"
    401632                       id="<?php echo $googleTagManager::ECOMMERCE_ENHANCED_ACTIVE ?>"
    402                        data-mmp-check-main="gtm-ecommerce-enhanced"
    403                        data-mmp-check-field="gtm-ecommerce"
    404                        data-mmp-check-subfiled="gtm-active"
     633                       data-mmp-check-main="<?php echo $googleTagManager::ECOMMERCE_ENHANCED_ACTIVE ?>"
     634                       data-mmp-check-field="<?php echo $googleTagManager::ECOMMERCE_ACTIVE ?>"
     635                       data-mmp-check-subfiled="<?php echo $googleTagManager::ACTIVE ?>"
    405636                       name="<?php echo $googleTagManager::ECOMMERCE_ENHANCED_ACTIVE ?>"
    406637                       <?php if ($googleTagManager->getEnhancedEcommerceActive() === 1){ ?>checked="checked"<?php } ?>>
     
    416647            <td><input type="number" id="<?php echo $googleTagManager::VIEW_LIST_ITEMS_COUNT ?>"
    417648                       name="<?php echo $googleTagManager::VIEW_LIST_ITEMS_COUNT ?>"
    418                        data-mmp-check-field="gtm-ecommerce-enhanced"
     649                       data-mmp-check-field="<?php echo $googleTagManager::ECOMMERCE_ENHANCED_ACTIVE ?>"
    419650                       placeholder="<?php echo __('Insert number here', 'mergado-marketing-pack') ?>"
    420651                       value="<?php echo $googleTagManager->getViewListItemsCount(); ?>"
     
    430661            </th>
    431662            <td colspan="2"><input type="checkbox" id="gtm-vat-included" name="gtm-vat-included"
    432                                    data-mmp-check-field="gtm-pixel-active"
     663                                   data-mmp-check-field="<?php echo $googleTagManager::ECOMMERCE_ACTIVE ?>"
    433664                                   <?php if ($googleTagManager->isConversionWithVat()){ ?>checked="checked"<?php } ?>>
    434665                <br><small class="badge badge_info"><?php echo __('Choose whether the price of the products will be sent with or without VAT.
    435666This setting does not affect total revenue. The total revenue of the transaction is calculated including taxes and shipping costs according to the Google Analytics specification.', 'mergado-marketing-pack') ?></small>
     667            </td>
     668        </tr>
     669        <tr>
     670            <th>
     671                <label for="<?php echo GoogleTagManagerService::COMPOSITE_ID_ENABLED ?>"><?php echo __('Composite ID of variation products', 'mergado-marketing-pack') ?></label>
     672            </th>
     673            <td colspan="2"><input type="checkbox"
     674                                   id="<?php echo GoogleTagManagerService::COMPOSITE_ID_ENABLED ?>"
     675                                   name="<?php echo GoogleTagManagerService::COMPOSITE_ID_ENABLED ?>"
     676                                   data-mmp-check-field="<?php echo $googleTagManager::ECOMMERCE_ACTIVE ?>"
     677                                   <?php if ($googleTagManager->isCompositeIdEnabled()){ ?>checked="checked"<?php } ?>>
     678                <br>
     679                <small class="badge badge_info"><?php echo __('Choose whether the IDs of the variation products will be sent as a composite e.g., "productId-variantId".', 'mergado-marketing-pack')?></small>
    436680            </td>
    437681        </tr>
     
    483727            </th>
    484728            <td>
    485                 <select name="<?php echo GoogleReviewsService::OPT_IN_GTIN ?>"
     729
     730                <input type="text"
     731                       class="mmp_google-reviews__input"
     732                       name="<?php echo GoogleReviewsService::OPT_IN_GTIN ?>"
     733                       id="<?php echo GoogleReviewsService::OPT_IN_GTIN ?>"
     734                       data-mmp-check-field="<?php echo GoogleReviewsService::OPT_IN_ACTIVE ?>"
     735                       value="<?php echo get_option(GoogleReviewsService::OPT_IN_GTIN, 0) !== 0 ? get_option(GoogleReviewsService::OPT_IN_GTIN, 0) : ''; ?>"
     736                />
     737
     738                <div class="mmp_google-reviews__loading">
     739                    <span><?php echo __('Preloading data from the database... This may take a while if your shop contains many products.', 'mergado-marketing-pack'); ?></span>
     740                </div>
     741
     742                <div class="mmp_google-reviews__loading--failed" style="display: none;">
     743                    <span><?php echo __('We were unable to preload your data. Please fill the meta_key from postmeta table manually.', 'mergado-marketing-pack'); ?></span>
     744                </div>
     745
     746                <select
     747                        style="display: none;"
     748                        class="mmp_google-reviews__select"
     749                        name="<?php echo GoogleReviewsService::OPT_IN_GTIN ?>"
    486750                        id="<?php echo GoogleReviewsService::OPT_IN_GTIN ?>"
    487                         data-mmp-check-field="<?php echo GoogleReviewsService::OPT_IN_ACTIVE ?>">
    488                     <?php foreach ($fields as $id => $data): ?>
    489                         <option
    490                             <?php if (get_option(GoogleReviewsService::OPT_IN_GTIN, 0) == $data){ ?>selected="selected"<?php } ?>
    491                             value="<?php echo $data ?>"><?php echo $data ?></option>
    492                     <?php endforeach ?>
     751                        data-mmp-check-field="<?php echo GoogleReviewsService::OPT_IN_ACTIVE ?>"
     752                        data-default-value="<?php echo get_option(GoogleReviewsService::OPT_IN_GTIN, 0); ?>"
     753                >
    493754                </select>
    494                 <br><small
     755
     756                <div>
     757                <small
    495758                        class="badge badge_question"><?php echo __('Select what field will be used as GTIN. "_sku" is default SKU value used by woocommerce', 'mergado-marketing-pack') ?></small>
     759                </div>
    496760            </td>
    497761        </tr>
  • mergado-marketing-pack/trunk/includes/class-mergado-marketing-pack.php

    r3041908 r3185508  
    1414 */
    1515
     16use Mergado\Helper\ControllerHelper;
    1617use Mergado\Service\AdminBarService;
    1718use Mergado\Service\AdminNoticeService;
     
    445446        add_action( 'wp_head', [ $this->glamiPixelServiceIntegration, 'init' ], 99 );
    446447        add_action( 'wp_head', [ $this->glamiPixelServiceIntegration, 'addToCartAjax' ], 99 );
    447         add_action('woocommerce_add_to_cart', function() {
    448             // Add items to head
    449             $this->headerExtra .= $this->glamiPixelServiceIntegration->addToCart();
    450         }, 99);
     448        add_action('woocommerce_add_to_cart', function() { $this->headerExtra .= $this->glamiPixelServiceIntegration->addToCart();}, 99);
    451449
    452450        // BIANO
     
    456454
    457455        // FB PIXEL
    458         add_action("woocommerce_before_checkout_billing_form", [$this->facebookServiceIntegration, "initiateCheckout"], 99);
     456        add_action("wp_footer", [$this->facebookServiceIntegration, "initiateCheckout"], 99);
    459457        add_action('woocommerce_add_to_cart', function() {
    460458            $this->headerExtra .= $this->facebookServiceIntegration->addToCart();
     
    468466        add_action( 'woocommerce_after_shipping_rate', [$this->ga4ServiceIntegration, "actionShippingRate"], 99);
    469467
    470         add_action("woocommerce_after_cart", [$this->ga4ServiceIntegration, "addCartData"], 99);
    471         add_action("woocommerce_before_checkout_billing_form", [$this->ga4ServiceIntegration, "addCartData"], 99);
    472 
    473         add_action("woocommerce_after_cart", [$this->googleUniversalAnalyticsServiceIntegration, 'removeFromCart'], 99);
    474         add_action("woocommerce_after_cart", [$this->ga4ServiceIntegration, 'removeFromCart'], 99);
    475         add_action("woocommerce_after_cart", [$this->ga4ServiceIntegration, 'viewCart'], 99);
    476         add_action("woocommerce_before_checkout_billing_form", [$this->googleUniversalAnalyticsServiceIntegration, "checkoutStep"], 99);
    477         add_action("woocommerce_before_checkout_billing_form", [$this->googleUniversalAnalyticsServiceIntegration, "checkoutManipulation"], 99);
    478         add_action("woocommerce_before_checkout_billing_form", [$this->ga4ServiceIntegration, "beginCheckout"], 99);
    479         add_action("woocommerce_before_checkout_billing_form", [$this->ga4ServiceIntegration, "addPaymentInfo"], 99);
    480         add_action("woocommerce_before_checkout_billing_form", [$this->ga4ServiceIntegration, "addShippingInfo"], 99);
    481         add_action("woocommerce_after_cart", [$this->googleUniversalAnalyticsServiceIntegration, "checkoutManipulation"], 99);
    482         add_action("woocommerce_after_cart", [$this->ga4ServiceIntegration, "addShippingInfo"], 99);
    483         add_action("woocommerce_after_cart", [$this->ga4ServiceIntegration, "addPaymentInfo"], 99);
    484 
     468        /**
     469         * Cart/checkout page
     470         */
     471        add_action('wp_footer', [$this->ga4ServiceIntegration, "addCartData"], 99);
     472        add_action("wp_footer", [$this->ga4ServiceIntegration, "addPaymentInfo"], 99);
     473        add_action("wp_footer", [$this->ga4ServiceIntegration, "addShippingInfo"], 99);
     474        add_action('wp_footer', [$this->googleUniversalAnalyticsServiceIntegration, "checkoutManipulation"], 99);
     475        add_action('wp_footer', [$this->googleTagManagerServiceIntegration, "checkoutManipulation"], 99);
     476
     477        /**
     478         * Cart page
     479         */
     480        add_action('wp_footer', [$this->googleUniversalAnalyticsServiceIntegration, 'removeFromCart'], 99);
     481        add_action('wp_footer', [$this->ga4ServiceIntegration, 'removeFromCart'], 99);
     482        add_action('wp_footer', [$this->ga4ServiceIntegration, 'viewCart'], 99);
     483
     484        /**
     485         * Checkout
     486         */
     487        add_action("wp_footer", [$this->googleUniversalAnalyticsServiceIntegration, "checkoutStep"], 99);
     488        add_action("wp_footer", [$this->ga4ServiceIntegration, "beginCheckout"], 99);
    485489
    486490
     
    510514        }, 99);
    511515
    512         add_action("woocommerce_before_checkout_billing_form", [$this->googleTagManagerServiceIntegration, "checkoutManipulation"], 99);
    513         add_action("woocommerce_after_cart", [$this->googleTagManagerServiceIntegration, "checkoutManipulation"], 99);
    514516        add_action("wp_footer", [$this->googleTagManagerServiceIntegration, "viewList"], 99);
    515 
    516517
    517518        // GA refund - backend - not part of GDPR
     
    675676        $productData['base_id'] = $product->get_id();
    676677
    677         if (!$product->is_type('variable')) {
     678        if ($product->is_type('variation')) {
     679            $productData['variation_id'] = $product->get_id();
     680            $productData['full_id'] = $product->get_parent_id() . '-' . $product->get_id();
     681            $productData['has_variation'] = true;
     682        } else if ($product->is_type('variable')) {
     683            $productData['full_id'] = $product->get_id();
     684            $productData['has_variation'] = true;
     685        } else {
    678686            $productData['full_id'] = $product->get_id();
    679687            $productData['has_variation'] = false;
    680         } else {
    681             $productData['variation_id'] = $product->get_id();
    682             $productData['full_id'] = $product->get_id() . '-' . $product->get_id(); // Product can't be shown in specific variation so its always like 11 - 11
    683             $productData['has_variation'] = true;
    684688        }
    685689
     
    736740            $this->pazaruvajServiceIntegration->orderConfirmation($orderId);
    737741            $this->facebookServiceIntegration->purchased($orderId);
    738             $this->googleAdsServiceIntegration->conversion($orderId);
     742            $this->googleAdsServiceIntegration->purchase($orderId);
    739743            $this->argepServiceIntegration->conversion($orderId);
    740744
     
    766770        $this->googleTagManagerServiceIntegration->productDetailView(); // must be before GTM
    767771
    768         if (is_order_received_page()) {
     772        if (ControllerHelper::isOrderReceivedPage()) {
    769773            $orderId = empty($_GET['order']) ? ($GLOBALS['wp']->query_vars['order-received'] ? $GLOBALS['wp']->query_vars['order-received'] : 0) : absint($_GET['order']);
    770774
     
    823827        $this->pazaruvajServiceIntegration->getWidgetTemplate();
    824828
    825         $this->googleUniversalAnalyticsServiceIntegration->removeFromCart();
    826 
    827829        $this->googleTagManagerServiceIntegration->removeFromCartAjax();
    828         $this->googleTagManagerServiceIntegration->addToCartAjax();;
     830        $this->googleTagManagerServiceIntegration->addToCartAjax();
    829831
    830832        $this->googleUniversalAnalyticsServiceIntegration->addToCartAjax(); // GDPR resolved inside
  • mergado-marketing-pack/trunk/mergado-marketing-pack.php

    r3134668 r3185508  
    1717 * Plugin URI:        https://www.mergado.cz
    1818 * Description:       Earn more on price comparator sites. <strong>REQUIRES: Woocommerce</strong>
    19  * Version:           3.7.4
     19 * Version:           4.0.0
    2020 * Author:            Mergado technologies, s. r. o.
    2121 * Author URI:        https://www.mergado.cz
     
    2626 *
    2727 * WC requires at least: 3.0
    28  * WC tested up to: 8.2.1
     28 * WC tested up to: 9.3.3
    2929 */
    3030
     
    4545}
    4646
    47 define('PLUGIN_VERSION', '3.7.4');
     47define('PLUGIN_VERSION', '4.0.0');
    4848define('WOOCOMMERCE_DEPENCENCY_MESSAGE', __('Mergado Pack plugin requires <a href="' . admin_url('plugin-install.php?tab=plugin-information&plugin=woocommerce') . '" target="_top">WooCommerce</a> plugin to be active!', 'mergado-marketing-pack'));
    4949define( '__MERGADO_DIR__', plugin_dir_path( __FILE__ ) );
  • mergado-marketing-pack/trunk/src/Feed/BaseFeed.php

    r3005696 r3185508  
    517517        foreach (glob($tmpShopDir . '*.xml') as $file) {
    518518            $xml = simplexml_load_file($file);
     519
     520            libxml_use_internal_errors(true);
     521
     522            if ($xml === false) {
     523                foreach (libxml_get_errors() as $error) {
     524                    $this->logger->error('--- Feed merge error ---', $this->logContext);
     525                    $this->logger->error('Partial XML file can\'t be loaded. There may be some invalid ( badly encoded ) characters in ' . $file, $this->logContext);
     526                    $this->logger->error('Error message: ' . $error->message, $this->logContext);
     527                }
     528                libxml_clear_errors();
     529            }
     530
    519531            $innerLoop = 0;
    520532
  • mergado-marketing-pack/trunk/src/Feed/Product/ProductFeed.php

    r3134668 r3185508  
    7373                throw new CronRunningException();
    7474            } else {
     75                do_action('mergado_product_feed__before');
     76
    7577                $this->setFeedLocked($now);
    7678
     
    101103                    CurrencySwitcherForWoocomerce::algSwitcherDisable();
    102104
     105                    do_action('mergado_product_feed__after');
     106
    103107                    return 'stepGenerated';
    104108                    // Common generating
     
    115119                    CurrencySwitcherForWoocomerce::algSwitcherDisable();
    116120
     121                    do_action('mergado_product_feed__after');
     122
    117123                    return 'fullGenerated';
    118124                    // Merge temporary files
     
    124130                    CurrencySwitcherForWoocomerce::algSwitcherDisable();
    125131
     132                    do_action('mergado_product_feed__after');
     133
    126134                    return 'merged';
    127135                }
    128136            }
    129137        } catch (CronRunningException $e) {
     138
    130139            throw $e;
    131140        } catch (Exception $e) {
    132141            $this->logger->error('Exception during feed generation: ' . $e, $this->logContext);
    133142
     143            do_action('mergado_product_feed__after');
    134144            throw $e;
    135145        }
     
    303313                    $productFeedItem->setStockQuantity(sprintf('%s', $v["stock"]));
    304314                }
     315
     316                $productFeedItem->setShippingLabel($productObject->get_shipping_class());
    305317
    306318                if (self::is_product_type($v['type'], 'simple')) {
  • mergado-marketing-pack/trunk/src/Feed/Product/ProductFeedItem.php

    r2998630 r3185508  
    3434    public $shippingSize;
    3535    public $shippingWeight;
     36    public $shippingLabel;
    3637    public $itemgroupId;
    3738    public $productno;
     
    393394    {
    394395        $this->shippingWeight = $shippingWeight;
     396    }
     397
     398    /**
     399     * @return mixed
     400     */
     401    public function getShippingLabel()
     402    {
     403        return $this->shippingLabel;
     404    }
     405
     406    /**
     407     * @param $shippingLabel
     408     */
     409    public function setShippingLabel($shippingLabel): void
     410    {
     411        $this->shippingLabel = $shippingLabel;
    395412    }
    396413
     
    533550            $this->createXmlItemProperty($item, 'SHIPPING_SIZE', $this->getShippingSize());
    534551            $this->createXmlItemProperty($item, 'SHIPPING_WEIGHT', $this->getShippingWeight());
     552            $this->createXmlItemProperty($item, 'SHIPPING_LABEL', $this->getShippingLabel(), true);
    535553            $this->createXmlItemProperty($item, 'ITEMGROUP_ID', $this->getItemgroupId());
    536554            $this->createXmlItemProperty($item, 'PRODUCTNO', $this->getProductno(), true);
  • mergado-marketing-pack/trunk/src/Feed/Shared/AbstractFeedItem.php

    r3001192 r3185508  
    44
    55use DOMDocument;
     6use Mergado\Exception\InvalidEncodingException;
     7use Mergado\Service\LogService;
    68
    79abstract class AbstractFeedItem implements FeedItemInterface
    810{
    911    protected $xml;
     12    /**
     13     * @var LogService|mixed
     14     */
     15    private $logger;
     16
    1017    public function __construct()
    1118    {
     19        $this->logger = LogService::getInstance();
    1220        $this->xml = new DOMDocument('1.0', 'UTF-8');
    1321    }
     
    5260            }
    5361
    54 
    5562            return $item->appendChild($element);
    5663        }
     
    7582        if ($sanitizeCData) {
    7683            $element = $this->xml->createElement($name);
    77             $element->appendChild($this->xml->createCDATASection($value));
     84
     85            $encodedValue = $this->checkAndFixEncodingWithLogger($value, $name);
     86
     87            $element->appendChild($this->xml->createCDATASection($encodedValue));
    7888            $item->appendChild($element);
    7989        } else {
     
    100110            if ($sanitizeCData) {
    101111                $element = $this->xml->createElement($name);
    102                 $element->appendChild($this->xml->createCDATASection($value));
     112
     113                $encodedValue = $this->checkAndFixEncodingWithLogger($value, $name);
     114
     115                $element->appendChild($this->xml->createCDATASection($encodedValue));
    103116                $item->appendChild($element);
    104117            } else {
     
    126139            $paramValue = $this->xml->createElement('VALUE');
    127140
     141            $encodedValue = $this->checkAndFixEncodingWithLogger($value['value'], 'Parameter_' . $value['name']);
     142
    128143            $paramName->appendChild($this->xml->createCDATASection($value['name']));
    129             $paramValue->appendChild($this->xml->createCDATASection($value['value']));
     144            $paramValue->appendChild($this->xml->createCDATASection($encodedValue));
    130145
    131146            $param->appendChild($paramName);
     
    137152        return $item;
    138153    }
     154
     155    protected function checkAndFixEncodingWithLogger($propertyContent, $propertyName): string
     156    {
     157        try {
     158            $fixedValue = $this->checkAndFixEncodingIfPossible($propertyContent);
     159        } catch (InvalidEncodingException $e) {
     160            $this->logger->error('Product #' . $this->getItemId() . ' : Invalid characters/encoding in property ' . $propertyName);
     161
     162            $fixedValue = '';
     163        }
     164
     165        return $fixedValue;
     166    }
     167
     168    /**
     169     * @throws InvalidEncodingException
     170     */
     171    protected function checkAndFixEncodingIfPossible($value): string
     172    {
     173        if (is_string($value)) {
     174            // Valid one...
     175            if (mb_check_encoding($value, 'UTF-8')) {
     176                return $value;
     177            }
     178
     179            // Try to fix encoding if possible ...
     180            $convertedText = mb_convert_encoding($value, 'UTF-8', 'auto');
     181
     182            if (mb_check_encoding($convertedText, 'UTF-8')) {
     183                return $convertedText;
     184            }
     185
     186            // Can't be fixed ... omit the value
     187            throw new InvalidEncodingException();
     188        }
     189
     190        return $value;
     191    }
    139192}
  • mergado-marketing-pack/trunk/src/Helper/AddToCartAjaxHelper.php

    r3041908 r3185508  
    55class AddToCartAjaxHelper
    66{
    7     public static function getDisabledActionNames() {
    8         return [
     7    public const DISABLED_ACTION_NAMES = [
    98            'xoo_wsc_add_to_cart',
    109            'woodmart_ajax_add_to_cart',
    1110            'reycore_ajax_add_to_cart'
    12         ];
     11    ];
     12
     13    public static function isAddToCartAjaxRequestDisabled(): bool
     14    {
     15        return isset($_REQUEST['action']) && in_array($_REQUEST['action'], self::DISABLED_ACTION_NAMES, true);
    1316    }
    1417}
  • mergado-marketing-pack/trunk/src/Helper/ProductHelper.php

    r2998630 r3185508  
    33namespace Mergado\Helper;
    44
     5use WC_Product;
     6
    57class ProductHelper
    68{
    7     public static function getMergedIdFromCartItem($item)
     9    public static function getProductVariationWcProduct(WC_Product $product)
    810    {
    9         if ($item['variation_id'] == 0) {
    10             return $item['product_id'];
     11        if ($product->is_type('variable')) {
     12            $variations = $product->get_available_variations();
     13
     14            if (!empty($variations)) {
     15                foreach ($variations as $variation) {
     16                    $isMatchingVariant = true;
     17
     18                    foreach ($variation['attributes'] as $attributeName => $attributeValue) {
     19                        // Check if the attribute is set in the GET request
     20                        if (isset($_GET[$attributeName])) {
     21                            // If the GET value doesn't match the variation attribute, it's not a match
     22                            if ($_GET[$attributeName] !== $attributeValue) {
     23                                $isMatchingVariant = false;
     24                                break;
     25                            }
     26                        } else {
     27                            // If attribute value is not empty and it's not in the GET request, it's not a match
     28                            if (!empty($attributeValue)) {
     29                                $isMatchingVariant = false;
     30                                break;
     31                            }
     32                        }
     33                    }
     34
     35                    if ($isMatchingVariant) {
     36                        $variationId = $variation['variation_id'];
     37                        $variationProduct = wc_get_product($variationId);
     38
     39                        // Return the product if the variation product is found
     40                        if ($variationProduct) {
     41                            return $variationProduct;
     42                        }
     43
     44                        return false;
     45                    }
     46                }
     47            }
    1148        }
    1249
    13         return $item['product_id'] . '-' . $item['variation_id'];
     50        return false;
    1451    }
     52
     53    public static function getProductCategories($productId, $returnAsArray = false)
     54    {
     55        $categories = get_the_terms($productId, 'product_cat');
     56
     57        $productCategories = [];
     58        if ($categories) {
     59            foreach ($categories as $category) {
     60                $productCategories[] = $category->name;
     61            }
     62        }
     63
     64        if ($returnAsArray) {
     65            return $productCategories;
     66        }
     67
     68        return implode(', ', $productCategories);
     69    }
     70
     71    public static function getProductPrices(WC_Product $product, bool $withVat): array
     72    {
     73        if ($withVat) {
     74            $regularPrice = (float)wc_get_price_including_tax($product, ['price' => $product->get_regular_price()]); // Normal product price without discount
     75            $price = (float)wc_get_price_including_tax($product); // Price after product discount
     76        } else {
     77            $regularPrice = (float)wc_get_price_excluding_tax($product, ['price' => $product->get_regular_price()]); // Normal product price without discount
     78            $price = (float)wc_get_price_excluding_tax($product); // Price after product discount
     79        }
     80
     81        return ['price' => $price, 'regularPrice' => $regularPrice, 'discount' => self::getDiscount($price, $regularPrice)];
     82    }
     83
     84    public static function getDiscount($price, $regularPrice): float
     85    {
     86        return round($price !== $regularPrice ? $regularPrice - $price : 0, 2);
     87    }
     88
    1589}
  • mergado-marketing-pack/trunk/src/Service/ApiService.php

    r2998630 r3185508  
    33namespace Mergado\Service;
    44
     5use Mergado\Endpoint\AdminAdSysEndpoint;
    56use Mergado\Endpoint\AdminAlertEndpoint;
    67use Mergado\Endpoint\AdminCookieEndpoint;
     
    5657    private $adminWizardEndpoint;
    5758
     59    /**
     60     * @var AdminAdSysEndpoint
     61     */
     62    private $adminAdSysEndpoint;
     63
    5864    public function __construct()
    5965    {
     
    6672        $this->adminScheduleEstimateEndpoint = new AdminScheduleEstimateEndpoint();
    6773        $this->adminWizardEndpoint = new AdminWizardEndpoint();
     74        $this->adminAdSysEndpoint = new AdminAdSysEndpoint();
    6875    }
    6976
     
    8491            $this->adminScheduleEstimateEndpoint->initEndpoints();
    8592            $this->adminWizardEndpoint->initEndpoints();
     93            $this->adminAdSysEndpoint->initEndpoints();
    8694        }
    8795    }
  • mergado-marketing-pack/trunk/src/Service/External/Biano/BianoService.php

    r2998630 r3185508  
    2828    public const LANGUAGES = ['CZ', 'SK', 'RO', 'NL', 'HU'];
    2929    public const CONVERSION_VAT_INCL = 'biano-vat-included';
     30    public const COMPOSITE_ID_ENABLED = 'mmp-biano-composite-id-enabled';
    3031
    3132    /******************************************************************************************************************
     
    4546    {
    4647        return $this->getConversionVatIncluded() === 1;
     48    }
     49
     50    public function isCompositeIdEnabled(): bool
     51    {
     52        return $this->getCompositeIdEnabled() === 1;
    4753    }
    4854
     
    7985    }
    8086
     87    public function getCompositeIdEnabled(): int
     88    {
     89        return (int)get_option(self::COMPOSITE_ID_ENABLED, 0);
     90    }
     91
    8192    /*******************************************************************************************************************
    8293     * GET NAMES
     
    109120        $checkboxes[] = self::ACTIVE;
    110121        $checkboxes[] = self::CONVERSION_VAT_INCL;
     122        $checkboxes[] = self::COMPOSITE_ID_ENABLED;
    111123
    112124        DatabaseManager::saveOptions($post,
  • mergado-marketing-pack/trunk/src/Service/External/Biano/BianoServiceIntegration.php

    r3041908 r3185508  
    33namespace Mergado\Service\External\Biano;
    44
    5 use Mergado\Helper\AddToCartAjaxHelper;
     5use Mergado\Helper\ControllerHelper;
    66use Mergado\Helper\LanguageHelper;
     7use Mergado\Helper\ProductDetailRequestHelper;
     8use Mergado\Helper\ProductPurchaseHelper;
    79use Mergado\Service\CookieService;
    810use Mergado\Traits\SingletonTrait;
     
    3638    }
    3739
    38     public function header()
    39     {
     40    public function header(): void
     41    {
     42        if(!$this->bianoService->isActive($this->lang)) {
     43            return;
     44        }
     45
    4046        $templatePathDefault = __DIR__ . '/templates/initDefault.php';
    4147        $templatePathFallback = __DIR__ . '/templates/iInitFallback.php';
    4248
    43         $active = $this->bianoService->isActive($this->lang);
    4449        $merchantId = $this->bianoService->getMerchantId($this->lang);
    4550
    46         if ($active) {
    47             // Default solution
    48             if (in_array($this->lang, BianoService::LANGUAGES)) {
    49 
    50                 $templateVariables = [
    51                     'merchantId' => $merchantId,
    52                     'consent' => $this->cookieService->advertisementEnabled() ? 'true' : 'false',
    53                     'lang' => strtolower($this->lang)
    54                 ];
    55 
    56                 echo TemplateLoader::getTemplate($templatePathDefault, $templateVariables);
    57 
    58                 // Fallback solution for other languages
     51        // Default solution
     52        if (in_array($this->lang, BianoService::LANGUAGES)) {
     53
     54            $templateVariables = [
     55                'merchantId' => $merchantId,
     56                'consent' => $this->cookieService->advertisementEnabled() ? 'true' : 'false',
     57                'lang' => strtolower($this->lang)
     58            ];
     59
     60            echo TemplateLoader::getTemplate($templatePathDefault, $templateVariables);
     61
     62            // Fallback solution for other languages
     63        } else {
     64            echo TemplateLoader::getTemplate($templatePathFallback, []);
     65        }
     66        ?>
     67
     68        <script>
     69          bianoTrack('init', '<?php echo $merchantId; ?>');
     70
     71          <?php if(ControllerHelper::isProduct()) { ?>
     72            <?php
     73                $withVat = $this->bianoService->isConversionWithVat();
     74                $compositeIdEnabled = $this->bianoService->isCompositeIdEnabled();
     75                $productData = ProductDetailRequestHelper::getProductDataForViewDetailRequest($withVat, $compositeIdEnabled) ?>
     76
     77            bianoTrack('track', 'product_view', {id: '<?php echo $productData['fullId']; ?>'});
     78          <?php } else { ?>
     79          bianoTrack('track', 'page_view');
     80          <?php } ?>
     81        </script>
     82
     83        <?php if (!$this->cookieService->advertisementEnabled()) { ?>
     84            <script>
     85              window.mmp.cookies.sections.advertisement.functions.bianoPixel = function () {
     86                bianoTrack('consent', true);
     87              };
     88            </script>
     89
     90            <?php
     91        }
     92    }
     93
     94    public function addToCart() : string
     95    {
     96        if (!$this->bianoService->isActive($this->lang)) {
     97            return '';
     98        }
     99
     100        $result = '';
     101
     102        $pricesWithVat = $this->bianoService->isConversionWithVat();
     103        $compositeIdEnabled = $this->bianoService->isCompositeIdEnabled();
     104        $products = ProductDetailRequestHelper::getAddToCartProductsFromRequest($pricesWithVat, 'groupedBianoPixel', $compositeIdEnabled);
     105
     106        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Biano/templates/addToCart.php';
     107
     108        foreach($products as $productData) {
     109            $result .= TemplateLoader::getTemplate($templatePath, [
     110                'id' => $productData['fullId'],
     111                'quantity' => $productData['quantity'],
     112                'unit_price' => $productData['prices']['price'],
     113                'currency' => get_woocommerce_currency(),
     114            ]);
     115        }
     116
     117        return $result;
     118    }
     119
     120    public function addToCartAjax(): bool
     121    {
     122        if (!$this->bianoService->isActive($this->lang)) {
     123            return false;
     124        }
     125
     126        $templatePath = __DIR__ . '/templates/addToCartAjax.php';
     127        $compositeIdEnabled = $this->bianoService->isCompositeIdEnabled();
     128        $conversionWithVat = $this->bianoService->isConversionWithVat();
     129
     130        echo TemplateLoader::getTemplate($templatePath, [
     131            'compositeIdEnabled' => $compositeIdEnabled,
     132            'conversionWithVat' => $conversionWithVat,
     133        ]);
     134
     135        return true;
     136    }
     137
     138    public function purchase($orderId): void
     139    {
     140        if (!$this->bianoService->isActive($this->lang)) {
     141            return;
     142        }
     143
     144        $vatIncluded = $this->bianoService->isConversionWithVat();
     145        $compositeIdEnabled = $this->bianoService->isCompositeIdEnabled();
     146
     147        $order = wc_get_order($orderId);
     148        $products_tmp = $order->get_items();
     149        $email = $order->get_billing_email();
     150
     151        //Set prices with or without vat
     152        // Specification looks that `quantity * unit_price` should be order_total
     153        if ($vatIncluded) {
     154            $orderPrice = number_format((float)$order->get_total() - $order->get_shipping_total() - $order->get_shipping_tax(), wc_get_price_decimals(), '.', '');
     155        } else {
     156            $orderPrice = number_format((float)$order->get_total() - $order->get_total_tax() - $order->get_shipping_total(), wc_get_price_decimals(), '.', '');
     157        }
     158
     159        $products = array();
     160        foreach ($products_tmp as $product) {
     161            $itemData = ProductPurchaseHelper::getProductDetails($product, $compositeIdEnabled);
     162
     163            $item = [
     164                'id' => (string)$itemData['fullId'],
     165                'quantity' => (int)$product->get_quantity(),
     166                'name' => $product->get_name(),
     167            ];
     168
     169            if ($itemData['product']->get_image_id()) {
     170                $item['image'] = htmlspecialchars(wp_get_original_image_url($itemData['product']->get_image_id()));
     171            }
     172
     173            if ($vatIncluded) {
     174                $item['unit_price'] = $product->get_total() + $product->get_total_tax();
    59175            } else {
    60                 echo TemplateLoader::getTemplate($templatePathFallback, []);
     176                $item['unit_price'] = $product->get_total();
    61177            }
    62             ?>
    63 
    64             <script>
    65               bianoTrack('init', '<?php echo $merchantId; ?>');
    66 
    67               <?php if(is_product()) { ?>
    68               bianoTrack('track', 'product_view', {id: '<?php echo wc_get_product()->get_id(); ?>'});
    69               <?php } else { ?>
    70               bianoTrack('track', 'page_view');
    71               <?php } ?>
    72             </script>
    73 
    74             <?php if (!$this->cookieService->advertisementEnabled()) { ?>
    75                 <script>
    76                   window.mmp.cookies.sections.advertisement.functions.bianoPixel = function () {
    77                     bianoTrack('consent', true);
    78                   };
    79                 </script>
    80 
    81                 <?php
    82             }
    83         }
    84     }
    85 
    86     public function addToCart() : string
    87     {
    88         $templatePath = __DIR__ . '/templates/addToCart.php';
    89 
    90         $result = '';
    91 
    92         // Disable if woodmart theme because of incompatibility
    93         if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], AddToCartAjaxHelper::getDisabledActionNames(), true)) {
    94             return $result;
    95         }
    96 
    97         $currency = get_woocommerce_currency();
    98 
    99         $active = $this->bianoService->isActive($this->lang);
    100 
    101         if ($active) {
    102             if (isset($_POST['add-to-cart'])) {
    103                 $product = wc_get_product($_POST['add-to-cart']);
    104 
    105                 if ($product->get_type() === 'grouped') { // Check if grouped product
    106                     if (!isset($_POST['groupedBianoPixel'])) { // Check if request is duplicate (grouped products send two posts with same data)
    107                         $_POST['groupedBianoPixel'] = true; // Set variable that disable next call of same addToCart
    108 
    109                         foreach ($_POST['quantity'] as $id => $quantity) {
    110                             $product = wc_get_product($id); // No need for ID changing because only simple products can be added on grouped page
    111 
    112                             $templateVariables = [
    113                                 'id' => $id,
    114                                 'quantity' => $quantity,
    115                                 'unit_price' => $product->get_price(),
    116                                 'currency' => $currency,
    117                             ];
    118 
    119                             $result .= TemplateLoader::getTemplate($templatePath, $templateVariables);
    120                         }
     178
     179            $products[] = $item;
     180        }
     181
     182        // Biano star
     183        $bianoStarServiceIntegration = BianoStarServiceIntegration::getInstance();
     184        $bianoStarShouldeBeSent = $bianoStarServiceIntegration->shouldBeSent($orderId);
     185
     186        $templatePath = __DIR__ . '/templates/purchase.php';
     187
     188        $templateVariables = [
     189            'orderId' => $orderId,
     190            'order_price' => (float)$orderPrice,
     191            'currency' => $order->get_currency(),
     192            'items' => json_encode($products, JSON_NUMERIC_CHECK),
     193            'bianoStarShouldBeSent' => $bianoStarShouldeBeSent
     194        ];
     195
     196
     197        if ($bianoStarShouldeBeSent) {
     198            $bianoStarService = $bianoStarServiceIntegration->getService();
     199
     200            $shippingDate = 0;
     201
     202            foreach ($products_tmp as $orderProduct) {
     203                if ($product->get_variation_id() == 0) {
     204                    $product = wc_get_product($orderProduct->get_data()['product_id']);
     205                } else {
     206                    $product = wc_get_product($orderProduct->get_data()['product_id']);
     207                }
     208
     209                $productStatus = $product->get_stock_status();
     210
     211                if ($productStatus === 'instock') {
     212                    if ($shippingDate < $bianoStarService->getShipmentInStock()) {
     213                        $shippingDate = $bianoStarService->getShipmentInStock();
    121214                    }
    122                 } else {
    123                     if (isset($_POST['variation_id']) && $_POST['variation_id'] && $_POST['variation_id'] !== '') {
    124                         $id = $product->get_data()['id'] . '-' . $_POST['variation_id'];
    125                     } else {
    126                         $id = $product->get_data()['id'];
     215                } else if ($productStatus === 'outofstock') {
     216                    if ($shippingDate < $bianoStarService->getShipmentOutOfStock()) {
     217                        $shippingDate = $bianoStarService->getShipmentOutOfStock();
    127218                    }
    128 
    129                     $templateVariables = [
    130                         'id' => $id,
    131                         'quantity' => $_POST['quantity'],
    132                         'unit_price' => $product->get_price(),
    133                         'currency' => $currency,
    134                     ];
    135 
    136                     $result .= TemplateLoader::getTemplate($templatePath, $templateVariables);
    137 
     219                } else if ($productStatus === 'onbackorder') {
     220                    if ($shippingDate < $bianoStarService->getShipmentBackorder()) {
     221                        $shippingDate = $bianoStarService->getShipmentBackorder();
     222                    }
    138223                }
    139224            }
    140         }
    141 
    142         return $result;
    143     }
    144 
    145     public function addToCartAjax()
    146     {
    147         $active = $this->bianoService->isActive($this->lang);
    148 
    149         if ($active) {
    150 
    151             $templatePath = __DIR__ . '/templates/addToCartAjax.php';
    152 
    153             echo TemplateLoader::getTemplate($templatePath, []);
    154 
    155             return true;
    156         }
    157 
    158         return false;
    159     }
    160 
    161     public function purchase($orderId)
    162     {
    163         $active = $this->bianoService->isActive($this->lang);
    164         $vatIncluded = $this->bianoService->isConversionWithVat();
    165 
    166         if ($active):
    167             $order = wc_get_order($orderId);
    168             $products_tmp = $order->get_items();
    169             $email = $order->get_billing_email();
    170 
    171             //Set prices with or without vat
    172             // Specification looks that `quantity * unit_price` should be order_total
    173             if ($vatIncluded) {
    174                 $orderPrice = number_format((float)$order->get_total() - $order->get_shipping_total() - $order->get_shipping_tax(), wc_get_price_decimals(), '.', '');
    175             } else {
    176                 $orderPrice = number_format((float)$order->get_total() - $order->get_total_tax() - $order->get_shipping_total(), wc_get_price_decimals(), '.', '');
    177             }
    178 
    179             $products = array();
    180             foreach ($products_tmp as $product) {
    181 
    182                 if ($product->get_variation_id() == 0) {
    183                     $id = $product->get_data()['product_id'];
    184                     $productObject = wc_get_product($product->get_data()['product_id']);
    185                 } else {
    186                     $id = $product->get_data()['product_id'] . '-' . $product->get_variation_id();
    187                     $productObject = wc_get_product($product->get_variation_id());
    188                 }
    189 
    190                 $item = [
    191                     'id' => (string)$id,
    192                     'quantity' => (int)$product->get_quantity(),
    193                     'name' => $product->get_name(),
    194                 ];
    195 
    196                 if ($productObject->get_image_id()) {
    197                     $item['image'] = htmlspecialchars(wp_get_original_image_url($productObject->get_image_id()));
    198                 }
    199 
    200                 if ($vatIncluded) {
    201                     $item['unit_price'] = $product->get_total() + $product->get_total_tax();
    202                 } else {
    203                     $item['unit_price'] = $product->get_total();
    204                 }
    205 
    206                 $products[] = $item;
    207             }
    208 
    209             // Biano star
    210             $bianoStarServiceIntegration = BianoStarServiceIntegration::getInstance();
    211             $bianoStarShouldeBeSent = $bianoStarServiceIntegration->shouldBeSent($orderId);
    212 
    213             $templatePath = __DIR__ . '/templates/purchase.php';
    214 
    215             $templateVariables = [
    216                 'orderId' => $orderId,
    217                 'order_price' => (float)$orderPrice,
    218                 'currency' => $order->get_currency(),
    219                 'items' => json_encode($products, JSON_NUMERIC_CHECK),
    220                 'bianoStarShouldBeSent' => $bianoStarShouldeBeSent
    221             ];
    222 
    223 
    224             if ($bianoStarShouldeBeSent) {
    225                 $bianoStarService = $bianoStarServiceIntegration->getService();
    226 
    227                 $shippingDate = 0;
    228 
    229                 foreach ($products_tmp as $orderProduct) {
    230                     if ($product->get_variation_id() == 0) {
    231                         $product = wc_get_product($orderProduct->get_data()['product_id']);
    232                     } else {
    233                         $product = wc_get_product($orderProduct->get_data()['product_id']);
    234                     }
    235 
    236                     $productStatus = $product->get_stock_status();
    237 
    238                     if ($productStatus === 'instock') {
    239                         if ($shippingDate < $bianoStarService->getShipmentInStock()) {
    240                             $shippingDate = $bianoStarService->getShipmentInStock();
    241                         }
    242                     } else if ($productStatus === 'outofstock') {
    243                         if ($shippingDate < $bianoStarService->getShipmentOutOfStock()) {
    244                             $shippingDate = $bianoStarService->getShipmentOutOfStock();
    245                         }
    246                     } else if ($productStatus === 'onbackorder') {
    247                         if ($shippingDate < $bianoStarService->getShipmentBackorder()) {
    248                             $shippingDate = $bianoStarService->getShipmentBackorder();
    249                         }
    250                     }
    251                 }
    252 
    253                 $templateVariables['email'] = $email;
    254                 $templateVariables['shippingDate'] = Date('Y-m-d', strtotime('+' . $shippingDate . ' days'));;
    255             }
    256 
    257             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    258 
    259         endif;
     225
     226            $templateVariables['email'] = $email;
     227            $templateVariables['shippingDate'] = Date('Y-m-d', strtotime('+' . $shippingDate . ' days'));;
     228        }
     229
     230        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    260231    }
    261232}
  • mergado-marketing-pack/trunk/src/Service/External/Biano/templates/addToCartAjax.php

    r2998630 r3185508  
    1212            var $_currency, $_id, $_price, $_priceClone;
    1313
    14             if (!$(this).hasClass('product_type_variable')) {
     14            if (!$(this).hasClass('product_type_variable') && !$(this).hasClass('product-type-variable')) {
    1515                if ($('[data-metadata-product-list]').length > 0) {
    1616                    // Classical loop
     
    2525
    2626                    $_currency = prodData['currency'];
    27                     $_id = prodData['full_id'];
    28                     $_price = prodData['price'];
     27                    <?php if($compositeIdEnabled): ?>
     28                        $_id = prodData['full_id'];
     29                    <?php else: ?>
     30                        $_id = prodData['base_id'];
     31                    <?php endif; ?>
     32                    $_price = <?php if($conversionWithVat): ?>prodData['price_with_vat']<?php else: ?>prodData['price_without_vat']<?php endif; ?>;
    2933                } else {
     34                    // Just partial fallback for special client pages
    3035                    $_currency = $('#mergadoSetup').attr('data-currency');
    3136                    $_id = $(this).closest('li.product').find('[data-product_id]').attr('data-product_id');
  • mergado-marketing-pack/trunk/src/Service/External/Facebook/FacebookService.php

    r2998630 r3185508  
    2727    public const CODE = 'facebook-form-pixel';
    2828    public const CONVERSION_VAT_INCL = 'facebook-vat-included';
     29    public const COMPOSITE_ID_ENABLED = 'mmp-facebook-composite-id-enabled';
    2930
    3031    /******************************************************************************************************************
     
    4344    {
    4445        return $this->getConversionVatIncluded() === 1;
     46    }
     47
     48    public function isCompositeIdEnabled(): bool
     49    {
     50        return $this->getCompositeIdEnabled() === 1;
    4551    }
    4652
     
    6470    }
    6571
     72    public function getCompositeIdEnabled(): int
     73    {
     74        return (int)get_option(self::COMPOSITE_ID_ENABLED, 0);
     75    }
     76
    6677    /*******************************************************************************************************************
    6778     * SAVE FIELDS
     
    7384            self::ACTIVE,
    7485            self::CONVERSION_VAT_INCL,
     86            self::COMPOSITE_ID_ENABLED
    7587        ], [
    7688            self::CODE,
  • mergado-marketing-pack/trunk/src/Service/External/Facebook/FacebookServiceIntegration.php

    r3041908 r3185508  
    1717namespace Mergado\Service\External\Facebook;
    1818
    19 use Mergado\Helper\AddToCartAjaxHelper;
     19use Mergado\Helper\ControllerHelper;
     20use Mergado\Helper\ProductCartHelper;
     21use Mergado\Helper\ProductDetailRequestHelper;
    2022use Mergado\Helper\ProductHelper;
     23use Mergado\Helper\ProductPurchaseHelper;
    2124use Mergado\Service\CookieService;
    2225use Mergado\Traits\SingletonTrait;
     
    4548    public function init(): void
    4649    {
    47         if ($this->facebookService->isActive()) {
    48 
    49             /**
    50              * Main code
    51              */
    52 
    53             if ($this->cookieService->advertisementEnabled()) {
    54                 $consent = 'grant';
    55             } else {
    56                 $consent = 'revoke';
     50        if (!$this->facebookService->isActive()) {
     51            return;
     52        }
     53
     54        /**
     55         * Main code
     56         */
     57
     58        if ($this->cookieService->advertisementEnabled()) {
     59            $consent = 'grant';
     60        } else {
     61            $consent = 'revoke';
     62        }
     63
     64        echo TemplateLoader::getTemplate(__DIR__ . '/templates/main.php', [
     65            'consent' => $consent,
     66            'code' => $this->facebookService->getCode()
     67        ]);
     68
     69        $withVat = $this->facebookService->isConversionWithVat();
     70        $compositeIdEnabled = $this->facebookService->isCompositeIdEnabled();
     71
     72        /**
     73         * Product page
     74         */
     75
     76        if (ControllerHelper::isProduct()) {
     77            $product = ProductDetailRequestHelper::getProductDataForViewDetailRequest($withVat, $compositeIdEnabled);
     78
     79            echo TemplateLoader::getTemplate(__DIR__ . '/templates/viewContent.php', [
     80                'productTitle' => $product['name'],
     81                'productId' => $product['fullId']
     82            ]);
     83        }
     84
     85
     86        /**
     87         * Product category
     88         */
     89
     90        if (ControllerHelper::isProductCategory()) {
     91            $category = get_queried_object();
     92            $products_tmp = wc_get_products(['category' => [$category->slug]]);
     93            $products = [];
     94
     95            foreach ($products_tmp as $product) {
     96                $itemData = ProductDetailRequestHelper::getProductDataForViewDetailRequest($withVat, $compositeIdEnabled, $product);
     97
     98                $products['ids'][] = "'" . $itemData['fullId'] . "'";
    5799            }
    58100
    59             echo TemplateLoader::getTemplate(__DIR__ . '/templates/main.php', [
    60                 'consent' => $consent,
    61                 'code' => $this->facebookService->getCode()
    62             ]);
    63 
    64 
    65             /**
    66              * Product page
    67              */
    68 
    69             if (is_product()) {
    70                 $product = get_queried_object();
    71 
    72                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/viewContent.php', [
    73                     'productTitle' => $product->post_title,
    74                     'productId' => $product->ID
    75                 ]);
    76             }
    77 
    78 
    79             /**
    80              * Product category
    81              */
    82 
    83             if (is_product_category()) {
    84                 $category = get_queried_object();
    85                 $products_tmp = wc_get_products(['category' => [$category->slug]]);
    86                 $products = [];
    87 
    88                 foreach ($products_tmp as $product) {
    89                     $id = $product->get_id();
    90 
    91                     $products['ids'][] = "'" . $id . "'";
    92                 }
    93 
    94                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/viewCategory.php', [
    95                     'categoryName' => $category->name,
    96                     'contentType' => 'product',
    97                     'productIds' => $products['ids'] ?? []
    98                 ]);
    99             }
    100 
    101 
    102             /**
    103              * Search
    104              */
    105 
    106             if (is_search()) {
    107                 $searchQuery = get_search_query();
    108                 $products = ['ids' => []];
    109 
    110                 global $wp_query;
    111 
    112                 $posts = $wp_query->get_posts();
    113 
    114                 foreach ($posts as $post) {
    115                     if (get_post_type($post) === 'product') {
    116                         $product = wc_get_product($post->ID);
    117 
    118                         $products['ids'][] = "'" . $product->get_id() . "'";
    119                     }
    120                 }
    121 
    122                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/search.php', [
    123                     'searchQuery' => $searchQuery,
    124                     'contentType' => 'product',
    125                     'productIds' => $products['ids'] ?? []
    126                 ]);
    127             }
    128         }
    129     }
    130 
    131     public function initiateCheckout(): void
    132     {
    133         if ($this->facebookService->isActive()) {
    134             global $woocommerce;
    135 
    136             $products = [];
    137             $quantity = 0;
    138 
    139             foreach ($woocommerce->cart->cart_contents as $item) {
    140                 $id = ProductHelper::getMergedIdFromCartItem($item);
    141 
    142                 $products['ids'][] = "'" . $id . "'";
    143                 $products['contents'][] = "{'id':'" . $id . "', 'quantity':'" . $item['quantity'] . "'}";
    144                 $quantity = $quantity + $item['quantity'];
    145             }
    146 
    147             if ($this->facebookService->isConversionWithVat()) {
    148                 $conversionValue = number_format((float)$woocommerce->cart->get_cart_contents_total(), wc_get_price_decimals(), '.', '');
    149             } else {
    150                 $conversionValue = number_format((float)$woocommerce->cart->get_cart_contents_total() - $woocommerce->cart->get_cart_contents_tax(), wc_get_price_decimals(), '.', '');
    151             }
    152 
    153             $templatePath = __DIR__ . '/templates/initiateCheckout.php';
    154 
    155             $templateVariables = [
    156                 'contentIds' => $products['ids'],
    157                 'contents' => $products['contents'],
     101            echo TemplateLoader::getTemplate(__DIR__ . '/templates/viewCategory.php', [
     102                'categoryName' => $category->name,
    158103                'contentType' => 'product',
    159                 'value' => $conversionValue,
    160                 'currency' => get_woocommerce_currency(),
    161                 'numItems' => $quantity,
    162             ];
    163 
    164             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    165         }
    166     }
    167 
    168     public function purchased($orderId): void
    169     {
    170         if ($this->facebookService->isActive()) {
    171             $order = wc_get_order($orderId);
    172             $products_tmp = $order->get_items();
    173 
    174             $products = [];
    175 
    176             foreach ($products_tmp as $product) {
    177                 if ($product->get_variation_id() == 0) {
    178                     $id = $product->get_data()['product_id'];
    179                 } else {
    180                     $id = $product->get_data()['product_id'] . '-' . $product->get_variation_id();
    181                 }
    182                 $products['ids'][] = "'" . $id . "'";
    183                 $products['contents'][] = "{'id':'" . $id . "', 'quantity':'" . $product['quantity'] . "'}";
    184             }
    185 
    186             if ($this->facebookService->isConversionWithVat()) {
    187                 $conversionValue = number_format((float)$order->get_total() - $order->get_shipping_total() - $order->get_shipping_tax(), wc_get_price_decimals(), '.', '');
    188             } else {
    189                 $conversionValue = number_format((float)$order->get_total() - $order->get_total_tax() - $order->get_shipping_total(), wc_get_price_decimals(), '.', '');
    190             }
    191 
    192             $templatePath = __DIR__ . '/templates/purchase.php';
    193 
    194             $templateVariables = [
    195                 'contentIds' => $products['ids'],
    196                 'contents' => $products['contents'],
    197                 'contentType' => 'product',
    198                 'value' => $conversionValue,
    199                 'currency' => get_woocommerce_currency()
    200             ];
    201 
    202             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    203         }
    204     }
    205 
    206     public function addToCart() : string
    207     {
    208         $result = '';
    209 
    210         // Disable if woodmart theme because of incompatibility
    211         if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], AddToCartAjaxHelper::getDisabledActionNames(), true)) {
    212             return $result;
    213         }
    214 
    215         $currency = get_woocommerce_currency();
    216 
    217         if ($this->facebookService->isActive()) {
    218             if (isset($_POST['add-to-cart'])) {
    219                 $product = wc_get_product($_POST['add-to-cart']);
    220 
    221                 if ($product->get_type() === 'grouped') { // Check if grouped product
    222                     if (!isset($_POST['groupedFbPixel'])) { // Check if request is duplicate (grouped products send two posts with same data)
    223                         $_POST['groupedFbPixel'] = true; // Set variable that disable next call of same addToCart
    224                         foreach ($_POST['quantity'] as $id => $quantity) {
    225                             $product = wc_get_product($id); // No need for ID changing because only simple products can be added on grouped page
    226 
    227                             $result .= TemplateLoader::getTemplate(__DIR__ . '/templates/addToCart.php', [
    228                                 'productName' => $product->get_name(),
    229                                 'contentIds' => $id,
    230                                 'id' => $id,
    231                                 'quantity' => $quantity,
    232                                 'contentType' => 'product',
    233                                 'value' => $product->get_price(),
    234                                 'currency' => $currency
    235                             ]);
    236                         }
    237                     }
    238                 } else {
    239                     // Merged Id
    240                     if (isset($_POST['variation_id']) && $_POST['variation_id'] && $_POST['variation_id'] !== '') {
    241                         $id = $product->get_data()['id'] . '-' . $_POST['variation_id'];
    242                     } else {
    243                         $id = $product->get_data()['id'];
    244                     }
    245 
    246                     // Default quantity 1
    247                     if (isset($_POST['quantity'])) {
    248                         $quantity = (int)$_POST['quantity'];
    249                     } else {
    250                         $quantity = 1;
    251                     }
    252 
    253                     $result .= TemplateLoader::getTemplate(__DIR__ . '/templates/addToCart.php', [
    254                         'productName' => $product->get_name(),
    255                         'contentIds' => $id,
    256                         'id' => $id,
    257                         'quantity' => $quantity,
    258                         'contentType' => 'product',
    259                         'value' => $product->get_price(),
    260                         'currency' => $currency
    261                     ]);
     104                'productIds' => $products['ids'] ?? []
     105            ]);
     106        }
     107
     108
     109        /**
     110         * Search
     111         */
     112
     113        if (ControllerHelper::isSearch()) {
     114            $searchQuery = get_search_query();
     115            $products = ['ids' => []];
     116
     117            global $wp_query;
     118
     119            $posts = $wp_query->get_posts();
     120
     121            foreach ($posts as $post) {
     122                if (get_post_type($post) === 'product') {
     123                    $product = wc_get_product($post->ID);
     124                    $itemData = ProductDetailRequestHelper::getProductDataForViewDetailRequest($withVat, $compositeIdEnabled, $product);
     125
     126                    $products['ids'][] = "'" . $itemData['fullId'] . "'";
    262127                }
    263128            }
     129
     130            echo TemplateLoader::getTemplate(__DIR__ . '/templates/search.php', [
     131                'searchQuery' => $searchQuery,
     132                'contentType' => 'product',
     133                'productIds' => $products['ids'] ?? []
     134            ]);
     135        }
     136
     137    }
     138
     139    public function initiateCheckout(): void
     140    {
     141        if (!ControllerHelper::isCheckout() || !$this->facebookService->isActive()) {
     142            return;
     143        }
     144
     145        global $woocommerce;
     146
     147        $products = [];
     148        $quantity = 0;
     149
     150        foreach ($woocommerce->cart->cart_contents as $item) {
     151            $compositeIdEnabled = $this->facebookService->isCompositeIdEnabled();
     152            $itemData = ProductCartHelper::getIdsFromCartItem($item, $compositeIdEnabled);
     153
     154            $products['ids'][] = "'" . $itemData['fullId'] . "'";
     155            $products['contents'][] = "{'id':'" . $itemData['fullId'] . "', 'quantity':'" . $item['quantity'] . "'}";
     156            $quantity = $quantity + $item['quantity'];
     157        }
     158
     159        if ($this->facebookService->isConversionWithVat()) {
     160            $conversionValue = number_format((float)$woocommerce->cart->get_cart_contents_total(), wc_get_price_decimals(), '.', '');
     161        } else {
     162            $conversionValue = number_format((float)$woocommerce->cart->get_cart_contents_total() - $woocommerce->cart->get_cart_contents_tax(), wc_get_price_decimals(), '.', '');
     163        }
     164
     165        $templatePath = __DIR__ . '/templates/initiateCheckout.php';
     166
     167        $templateVariables = [
     168            'contentIds' => $products['ids'],
     169            'contents' => $products['contents'],
     170            'contentType' => 'product',
     171            'value' => $conversionValue,
     172            'currency' => get_woocommerce_currency(),
     173            'numItems' => $quantity,
     174        ];
     175
     176        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     177    }
     178
     179    public function purchased($orderId): void
     180    {
     181        if (!$this->facebookService->isActive()) {
     182            return;
     183        }
     184
     185        $order = wc_get_order($orderId);
     186        $products_tmp = $order->get_items();
     187        $compositeIdEnabled = $this->facebookService->isCompositeIdEnabled();
     188
     189        $products = [];
     190
     191        foreach ($products_tmp as $product) {
     192            $itemData = ProductPurchaseHelper::getProductDetails($product, $compositeIdEnabled);
     193
     194            $products['ids'][] = "'" . $itemData['fullId'] . "'";
     195            $products['contents'][] = "{'id':'" . $itemData['fullId'] . "', 'quantity':'" . $product['quantity'] . "'}";
     196        }
     197
     198        if ($this->facebookService->isConversionWithVat()) {
     199            $conversionValue = number_format((float)$order->get_total() - $order->get_shipping_total() - $order->get_shipping_tax(), wc_get_price_decimals(), '.', '');
     200        } else {
     201            $conversionValue = number_format((float)$order->get_total() - $order->get_total_tax() - $order->get_shipping_total(), wc_get_price_decimals(), '.', '');
     202        }
     203
     204        $templatePath = __DIR__ . '/templates/purchase.php';
     205
     206        $templateVariables = [
     207            'contentIds' => $products['ids'],
     208            'contents' => $products['contents'],
     209            'contentType' => 'product',
     210            'value' => $conversionValue,
     211            'currency' => get_woocommerce_currency()
     212        ];
     213
     214        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     215    }
     216
     217    public function addToCart() : string
     218    {
     219        if (!$this->facebookService->isActive()) {
     220            return '';
     221        }
     222
     223        $result = '';
     224
     225        $pricesWithVat = $this->facebookService->isConversionWithVat();
     226        $compositeIdEnabled = $this->facebookService->isCompositeIdEnabled();
     227        $products = ProductDetailRequestHelper::getAddToCartProductsFromRequest($pricesWithVat, 'groupedFbPixel', $compositeIdEnabled);
     228
     229        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Facebook/templates/addToCart.php';
     230
     231        foreach($products as $productData) {
     232            $result .= TemplateLoader::getTemplate($templatePath, [
     233                'productName' => $productData['name'],
     234                'contentIds' => $productData['fullId'],
     235                'id' => $productData['fullId'],
     236                'quantity' => $productData['quantity'],
     237                'contentType' => 'product',
     238                'value' => $productData['prices']['price'],
     239                'currency' => get_woocommerce_currency()
     240            ]);
    264241        }
    265242
     
    269246    public function addToCartAjax(): void
    270247    {
    271         if ($this->facebookService->isActive()) {
    272             echo TemplateLoader::getTemplate(__DIR__ . '/templates/addToCartAjax.php', []);
    273         }
     248        if (!$this->facebookService->isActive()) {
     249            return;
     250        }
     251
     252        $compositeIdEnabled = $this->facebookService->isCompositeIdEnabled();
     253        $conversionWithVat = $this->facebookService->isConversionWithVat();
     254
     255        echo TemplateLoader::getTemplate(__DIR__ . '/templates/addToCartAjax.php', [
     256            'compositeIdEnabled' => $compositeIdEnabled,
     257            'conversionWithVat' => $conversionWithVat,
     258        ]);
    274259    }
    275260}
  • mergado-marketing-pack/trunk/src/Service/External/Facebook/templates/addToCartAjax.php

    r2998630 r3185508  
    1010
    1111    $(mmpSelector).on('click', function(e) {
    12       if(!$(this).hasClass('product_type_variable')) {
     12      if(!$(this).hasClass('product_type_variable') && !$(this).hasClass('product-type-variable')) {
    1313        if($('[data-metadata-product-list]').length > 0) {
    1414          // Classical loop
     
    2323
    2424          var $_currency = prodData['currency'];
    25           var $_id = prodData['full_id'];
     25            <?php if($compositeIdEnabled): ?>
     26              $_id = prodData['full_id'];
     27            <?php else: ?>
     28              $_id = prodData['base_id'];
     29            <?php endif; ?>
    2630          var $_name = prodData['name'];
    27           var $_price = prodData['price'];
     31          var $_price = <?php if($conversionWithVat): ?>prodData['price_with_vat']<?php else: ?>prodData['price_without_vat']<?php endif; ?>;
    2832          var $_qty = 1;
    2933        } else {
  • mergado-marketing-pack/trunk/src/Service/External/Facebook/templates/viewContent.php

    r2998630 r3185508  
    11<script>
    2   let id = '';
    3 
    4   if (document.getElementsByClassName('variation_id')[0] && document.getElementsByClassName('variation_id')[0].value != 0) {
    5     id = <?php echo $productId; ?> + '-' + document.getElementsByClassName('variation_id')[0].value;
    6   } else {
    7     id = <?php echo $productId; ?>;
    8   }
    9 
    102  fbq('trackCustom', 'ViewContent', {
    113    content_name: '<?php echo $productTitle; ?>',
    124    content_type: 'product',
    13     content_ids: [id]
     5    content_ids: [<?php echo $productId; ?>]
    146  });
    157</script>
  • mergado-marketing-pack/trunk/src/Service/External/Glami/GlamiPixelServiceIntegration.php

    r3041908 r3185508  
    1717namespace Mergado\Service\External\Glami;
    1818
    19 use Mergado\Helper\AddToCartAjaxHelper;
     19use Mergado\Helper\ControllerHelper;
    2020use Mergado\Helper\LanguageHelper;
     21use Mergado\Helper\ProductDetailRequestHelper;
     22use Mergado\Helper\ProductPurchaseHelper;
    2123use Mergado\Service\CookieService;
    2224use Mergado\Traits\SingletonTrait;
     
    4244    }
    4345
    44     public function init()
    45     {
    46         if ($this->glamiPixelService->isActive($this->lang)) {
    47             $templatePath = __DIR__ . '/templates/pixel/init.php';
     46    public function init(): void
     47    {
     48        if (!$this->glamiPixelService->isActive($this->lang)) {
     49            return;
     50        }
     51
     52        $templatePath = __DIR__ . '/templates/pixel/init.php';
     53
     54        $templateVariables = [
     55            'glamiCode' => $this->glamiPixelService->getCode($this->lang),
     56            'lang' => strtolower($this->lang),
     57            'consent' => (int)$this->cookieService->advertisementEnabled()
     58        ];
     59
     60        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     61    }
     62
     63    public function viewContent(): void
     64    {
     65        if (!$this->glamiPixelService->isActive($this->lang)) {
     66            return;
     67        }
     68
     69        /**
     70         * Product category
     71         */
     72        if (ControllerHelper::isProductCategory()) {
     73            $category = get_queried_object();
     74            $products_tmp = wc_get_products(array('category' => array($category->slug)));
     75            $products = [];
     76
     77            if (count($products_tmp) > 0) {
     78                foreach ($products_tmp as $product) {
     79                    $id = $product->get_id();
     80
     81                    $products['ids'][] = "'" . $id . "'";
     82                    $products['name'][] = "'" . $product->get_name() . "'";
     83                }
     84
     85                $products['ids'] = implode(',', $products['ids']);
     86                $products['name'] = implode(',', $products['name']);
     87            }
     88
     89            $templatePath = __DIR__ . '/templates/pixel/viewContentCategory.php';
    4890
    4991            $templateVariables = [
    50                 'glamiCode' => $this->glamiPixelService->getCode($this->lang),
    51                 'lang' => strtolower($this->lang),
     92                'contentType' => 'category',
     93                'itemIds' => $products['ids'] ?? '',
     94                'productNames' => $products['name'] ?? '',
     95                'categoryId' => $category->term_id,
     96                'categoryText' => $category->name,
    5297                'consent' => (int)$this->cookieService->advertisementEnabled()
    5398            ];
     
    55100            echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    56101        }
    57     }
    58 
    59     public function viewContent()
    60     {
    61         if ($this->glamiPixelService->isActive($this->lang)) {
    62 
    63             /**
    64              * Product category
    65              * - old comments says, that there is no way to get variation ID, so we send only the default one
    66              */
    67             if (is_product_category()) {
    68                 $category = get_queried_object();
    69                 $products_tmp = wc_get_products(array('category' => array($category->slug)));
    70                 $products = [];
    71 
    72                 if (count($products_tmp) > 0) {
    73                     foreach ($products_tmp as $product) {
    74                         $id = $product->get_id();
    75 
    76                         $products['ids'][] = "'" . $id . "'";
    77                         $products['name'][] = "'" . $product->get_name() . "'";
    78                     }
    79 
    80                     $products['ids'] = implode(',', $products['ids']);
    81                     $products['name'] = implode(',', $products['name']);
    82                 }
    83 
    84                 $templatePath = __DIR__ . '/templates/pixel/viewContentCategory.php';
    85 
    86                 $templateVariables = [
    87                     'contentType' => 'category',
    88                     'itemIds' => $products['ids'] ?? '',
    89                     'productNames' => $products['name'] ?? '',
    90                     'categoryId' => $category->term_id,
    91                     'categoryText' => $category->name,
    92                     'consent' => (int)$this->cookieService->advertisementEnabled()
    93                 ];
    94 
    95                 echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    96             }
    97 
    98 
    99             /**
    100              * Product detail
    101              * - old comments says, that there is no way to get variation ID, so we send only the default one
    102              * - OLD CODE: $id = $product->get_id() . '-' . $product->get_variation_id();
    103              */
    104             if (is_product()) {
    105                 $product = get_queried_object();
    106 
    107                 $id = $product->ID;
    108 
    109                 $templatePath = __DIR__ . '/templates/pixel/viewContentProduct.php';
    110 
    111                 $templateVariables = [
    112                     'contentType' => 'product',
    113                     'itemIds' => $id,
    114                     'productNames' => $product->post_title,
    115                     'consent' => (int)$this->cookieService->advertisementEnabled()
    116                 ];
    117 
    118                 echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    119             }
    120         }
    121     }
    122 
    123     public function purchased($orderId)
    124     {
    125         if ($this->glamiPixelService->isActive($this->lang)) {
    126             $order = wc_get_order($orderId);
    127             $products_tmp = $order->get_items();
    128             $products = array();
    129 
    130             foreach ($products_tmp as $product) {
    131                 if ($product->get_data()['variation_id'] == 0) {
    132                     $id = $product->get_data()['product_id'];
    133                 } else {
    134                     $id = $product->get_data()['variation_id'];
    135                 }
    136 
    137                 $products['ids'][] = "'" . $id . "'";
    138                 $products['name'][] = "'" . $product->get_name() . "'";
    139             }
    140 
    141             if ($this->glamiPixelService->isConversionWithVat()) {
    142                 $conversionValue = number_format((float)$order->get_total() - $order->get_shipping_total() - $order->get_shipping_tax(), wc_get_price_decimals(), '.', '');
    143             } else {
    144                 $conversionValue = number_format((float)$order->get_total() - $order->get_total_tax() - $order->get_shipping_total(), wc_get_price_decimals(), '.', '');
    145             }
    146 
    147             $templatePath = __DIR__ . '/templates/pixel/purchase.php';
     102
     103
     104        /**
     105         * Product detail
     106         */
     107        if (ControllerHelper::isProduct()) {
     108            $withVat = $this->glamiPixelService->isConversionWithVat();
     109
     110            $product = ProductDetailRequestHelper::getProductDataForViewDetailRequest($withVat, false);
     111
     112            $templatePath = __DIR__ . '/templates/pixel/viewContentProduct.php';
    148113
    149114            $templateVariables = [
    150                 'itemIds' => $products['ids'],
    151                 'productNames' => $products['name'],
    152                 'value' => $conversionValue,
    153                 'currency' => get_woocommerce_currency(),
    154                 'transactionId' => $orderId,
     115                'contentType' => 'product',
     116                'itemIds' => $product['fullId'],
     117                'productNames' => $product['name'],
    155118                'consent' => (int)$this->cookieService->advertisementEnabled()
    156119            ];
     
    160123    }
    161124
     125    public function purchased($orderId): void
     126    {
     127        if (!$this->glamiPixelService->isActive($this->lang)) {
     128            return;
     129        }
     130
     131        $order = wc_get_order($orderId);
     132        $products_tmp = $order->get_items();
     133        $products = array();
     134
     135        foreach ($products_tmp as $product) {
     136            $itemData = ProductPurchaseHelper::getProductDetails($product, false);
     137
     138            $products['ids'][] = "'" . $itemData['id'] . "'";
     139            $products['name'][] = "'" . $product->get_name() . "'";
     140        }
     141
     142        if ($this->glamiPixelService->isConversionWithVat()) {
     143            $conversionValue = number_format((float)$order->get_total() - $order->get_shipping_total() - $order->get_shipping_tax(), wc_get_price_decimals(), '.', '');
     144        } else {
     145            $conversionValue = number_format((float)$order->get_total() - $order->get_total_tax() - $order->get_shipping_total(), wc_get_price_decimals(), '.', '');
     146        }
     147
     148        $templatePath = __DIR__ . '/templates/pixel/purchase.php';
     149
     150        $templateVariables = [
     151            'itemIds' => $products['ids'],
     152            'productNames' => $products['name'],
     153            'value' => $conversionValue,
     154            'currency' => get_woocommerce_currency(),
     155            'transactionId' => $orderId,
     156            'consent' => (int)$this->cookieService->advertisementEnabled()
     157        ];
     158
     159        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     160    }
     161
    162162    public function addToCart() : string
    163163    {
     164        if (!$this->glamiPixelService->isActive($this->lang)) {
     165            return '';
     166        }
     167
    164168        $result = '';
    165169
    166         // Disable if woodmart theme is active (compatibility issue)
    167         if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], AddToCartAjaxHelper::getDisabledActionNames(), true)) {
    168             return $result;
    169         }
    170 
    171         if ($this->glamiPixelService->isActive($this->lang)) {
    172             if (isset($_POST['add-to-cart'])) {
    173 
    174                 $product = wc_get_product($_POST['add-to-cart']);
    175 
    176                 /**
    177                  * Grouped products
    178                  */
    179                 if ($product->get_type() === 'grouped') {
    180                     if (!isset($_POST['groupedGlami'])) { // Check if request is duplicate (grouped products send two posts with same data)
    181                         $_POST['groupedGlami'] = true; // Set variable that disable next call of same addToCart
    182 
    183                         foreach ($_POST['quantity'] as $id => $quantity) {
    184                             $product = wc_get_product($id); // No need for ID changing because only simple products can be added on grouped page
    185 
    186                             $templateVariables = [
    187                                 'itemIds' => $id,
    188                                 'productNames' => $product->get_name(),
    189                                 'value' => $product->get_price(),
    190                                 'currency' => get_woocommerce_currency(),
    191                                 'consent' => (int)$this->cookieService->advertisementEnabled()
    192                             ];
    193 
    194                             $result .= TemplateLoader::getTemplate(__DIR__ . '/templates/pixel/addToCart.php', $templateVariables);
    195                         }
    196                     }
    197 
    198                 /**
    199                  * Simple/variable products
    200                  */
    201                 } else {
    202                     if (isset($_POST['variation_id']) && $_POST['variation_id'] && $_POST['variation_id'] !== '') {
    203                         $id = $_POST['variation_id'];
    204                     } else {
    205                         $id = $product->get_data()['id'];
    206                     }
    207 
    208                     $templateVariables = [
    209                         'itemIds' => $id,
    210                         'productNames' => $product->get_name(),
    211                         'value' => $product->get_price(),
    212                         'currency' => get_woocommerce_currency(),
    213                         'consent' => (int)$this->cookieService->advertisementEnabled()
    214                     ];
    215 
    216                     $result .= TemplateLoader::getTemplate(__DIR__ . '/templates/pixel/addToCart.php', $templateVariables);
    217                 }
    218             }
     170        $pricesWithVat = $this->glamiPixelService->isConversionWithVat();
     171        $products = ProductDetailRequestHelper::getAddToCartProductsFromRequest($pricesWithVat, 'groupedGlami', false);
     172
     173        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Glami/templates/pixel/addToCart.php';
     174
     175        foreach($products as $productData) {
     176            $result .= TemplateLoader::getTemplate($templatePath, [
     177                'itemIds' => $productData['fullId'],
     178                'productNames' => $productData['name'],
     179                'value' => $productData['prices']['price'],
     180                'currency' => get_woocommerce_currency(),
     181                'consent' => (int)$this->cookieService->advertisementEnabled()
     182            ]);
    219183        }
    220184
     
    222186    }
    223187
    224     public function addToCartAjax()
    225     {
    226         if ($this->glamiPixelService->isActive($this->lang)) {
    227             $templatePath = __DIR__ . '/templates/pixel/addToCartAjax.php';
    228 
    229             $templateVariables = [
    230                 'consent' => (int)$this->cookieService->advertisementEnabled()
    231             ];
    232 
    233             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    234         }
     188    public function addToCartAjax(): void
     189    {
     190        if (!$this->glamiPixelService->isActive($this->lang)) {
     191            return;
     192        }
     193
     194        $templatePath = __DIR__ . '/templates/pixel/addToCartAjax.php';
     195
     196        $conversionWithVat = $this->glamiPixelService->isConversionWithVat();
     197
     198        $templateVariables = [
     199            'consent' => (int)$this->cookieService->advertisementEnabled(),
     200            'conversionWithVat' => $conversionWithVat
     201        ];
     202
     203        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    235204    }
    236205}
  • mergado-marketing-pack/trunk/src/Service/External/Glami/templates/pixel/addToCartAjax.php

    r2998630 r3185508  
    1111
    1212      $(mmpSelector).on('click', function () {
    13         if (!$(this).hasClass('product_type_variable')) {
     13        if(!$(this).hasClass('product_type_variable') && !$(this).hasClass('product-type-variable')) {
     14          if($('[data-metadata-product-list]').length > 0) {
     15            // Classical loop
     16            let prodElement = jQuery(this).closest('li.product');
    1417
    15           let product = $(this).closest('li.product');
     18            // Gutenberg block
     19            if (prodElement.length === 0) {
     20              prodElement = jQuery(this).closest('li.wc-block-grid__product');
     21            }
    1622
    17           // Product gutenberg block
    18           if (product.length === 0) {
    19             product = $(this).closest('li.wc-block-grid__product')
     23            var prodData = JSON.parse(prodElement.find('[data-metadata-product-list]').attr('data-metadata-product-list'));
     24
     25            var $_currency = prodData['currency'];
     26            var $_id = prodData['base_id'];
     27            var $_name = prodData['name'];
     28            var $_price = <?php if($conversionWithVat): ?>prodData['price_with_vat']<?php else: ?>prodData['price_without_vat']<?php endif; ?>;
     29          } else {
     30            var $_currency = $('#mergadoSetup').attr('data-currency');
     31            var $_id = $(product).find('[data-product_id]').attr('data-product_id');
     32            var $_name = $(product).find('.woocommerce-loop-product__title').text();
     33            var $_priceClone = $(product).clone();
     34            $_priceClone.find('del').remove();
     35            $_priceClone.find('.woocommerce-Price-currencySymbol').remove();
     36            var $_price = $_priceClone.find('.woocommerce-Price-amount.amount').text();
    2037          }
    21 
    22           var $_currency = $('#mergadoSetup').attr('data-currency');
    23           var $_id = $(product).find('[data-product_id]').attr('data-product_id');
    24           var $_name = $(product).find('.woocommerce-loop-product__title').text();
    25           var $_priceClone = $(product).clone();
    26           $_priceClone.find('del').remove();
    27           $_priceClone.find('.woocommerce-Price-currencySymbol').remove();
    28           var $_price = $_priceClone.find('.woocommerce-Price-amount.amount').text();
    29 
    3038
    3139          glami('track', 'AddToCart', {
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleAds/GoogleAdsService.php

    r2998630 r3185508  
    3030    public const CONVERSION_CODE = 'adwords-form-conversion-code';
    3131    public const CONVERSION_LABEL = 'adwords-form-conversion-label';
     32    public const BUSINESS_TYPE = 'mmp-google-gads-business-type';
    3233
    3334    public const CONVERSION_VAT_INCL = 'mmp-google-gads-vat-included';
    3435    public const SHIPPING_PRICE_INCL = 'mmp-google-gads-shipping-included';
     36    public const COMPOSITE_ID_ENABLED = 'mmp-google-gads-composite-id-enabled';
     37
     38    public const ALL_BUSINESS_TYPES = [
     39        self::BUSINESS_TYPE_RETAIL => 'Retail',
     40        self::BUSINESS_TYPE_CUSTOM => 'Custom'
     41    ];
     42
     43    public const BUSINESS_TYPE_RETAIL = 'retail';
     44    public const BUSINESS_TYPE_CUSTOM = 'custom';
    3545
    3646    /******************************************************************************************************************
     
    6373    {
    6474        return $this->getShippingPriceIncluded() === 1;
     75    }
     76
     77    public function isCompositeIdEnabled(): bool
     78    {
     79        return $this->getCompositeIdEnabled() === 1;
    6580    }
    6681
     
    103118    }
    104119
     120    public function getBusinessType(): string
     121    {
     122        return get_option(self::BUSINESS_TYPE, self::BUSINESS_TYPE_RETAIL);
     123    }
     124
    105125    public function getConversionVatIncluded(): int
    106126    {
     
    111131    {
    112132        return (int)get_option(self::SHIPPING_PRICE_INCL, 0);
     133    }
     134
     135    public function getCompositeIdEnabled(): int
     136    {
     137        return (int)get_option(self::COMPOSITE_ID_ENABLED, 0);
    113138    }
    114139
     
    124149            self::ENHANCED_CONVERSION_ACTIVE,
    125150            self::CONVERSION_VAT_INCL,
    126             self::SHIPPING_PRICE_INCL
     151            self::SHIPPING_PRICE_INCL,
     152            self::COMPOSITE_ID_ENABLED
    127153        ], [
    128154            self::CONVERSION_CODE,
    129155            self::CONVERSION_LABEL
    130         ]);
     156        ],
     157        [self::BUSINESS_TYPE]);
    131158    }
    132159}
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleAds/GoogleAdsServiceIntegration.php

    r3041908 r3185508  
    1818
    1919use Mergado;
     20use Mergado\Helper\ControllerHelper;
    2021use Mergado\Service\External\Google\Gtag\GtagIntegrationHelper;
    2122use Mergado\Traits\SingletonTrait;
     
    4243    }
    4344
    44     public function conversion($order_id): void
     45    public function purchase($orderId): void
    4546    {
    46         $order = wc_get_order($order_id);
     47        $order = wc_get_order($orderId);
    4748
    4849        $active = $this->googleAdsService->isConversionActive();
     
    6667        }
    6768
     69        $isCompositeIdEnabled = $this->googleAdsService->isCompositeIdEnabled();
     70        $isConversionWithVat = $this->googleAdsService->isConversionWithVat();
     71
     72        $products = GtagIntegrationHelper::getOrderProductsForAds(
     73            $orderId,
     74            $isCompositeIdEnabled,
     75            $isConversionWithVat,
     76            $this->googleAdsService->getBusinessType()
     77        );
     78
    6879        if ($active) {
    69             $templatePath = __DIR__ . '/templates/conversion.php';
     80            $templatePath = __DIR__ . '/templates/purchase.php';
    7081
    7182            $templateVariables = [
     
    7687                'value' => $orderTotal,
    7788                'currency' => get_woocommerce_currency(),
    78                 'transactionId' => $order_id,
     89                'items' => json_encode($products, JSON_NUMERIC_CHECK),
     90                'transactionId' => $orderId,
    7991            ];
    8092
     
    8597    public function productDetailView(): void
    8698    {
    87         if ($this->googleAdsService->isRemarketingActive()) {
    88             GtagIntegrationHelper::productDetailView($this->sendTo, $this->googleAdsService->isConversionWithVat());
     99        if (!$this->googleAdsService->isRemarketingActive()) {
     100            return;
    89101        }
     102
     103        GtagIntegrationHelper::productDetailView(
     104            $this->sendTo,
     105            $this->googleAdsService->isConversionWithVat(),
     106            $this->googleAdsService->isCompositeIdEnabled(),
     107            $this->googleAdsService->getBusinessType()
     108        );
    90109    }
    91110
    92111    public function viewItemList(): void
    93112    {
    94         if (is_shop() || is_product_category() || is_search()) {
     113        if (ControllerHelper::isShop() || ControllerHelper::isProductCategory() || ControllerHelper::isSearch()) {
    95114            if ($this->googleAdsService->isRemarketingActive()) {
    96                 GtagIntegrationHelper::viewItemList($this->sendTo, $this->googleAdsService->isConversionWithVat());
     115
     116                GtagIntegrationHelper::viewItemList(
     117                    $this->sendTo,
     118                    $this->googleAdsService->isConversionWithVat(),
     119                    $this->googleAdsService->isCompositeIdEnabled(),
     120                    $this->googleAdsService->getBusinessType()
     121                );
    97122            }
    98123        }
     
    101126    public function addToCart() : string
    102127    {
    103         if ($this->googleAdsService->isRemarketingActive()) {
    104             return GtagIntegrationHelper::addToCart($this->sendTo, $this->googleAdsService->isConversionWithVat());
     128        if (!$this->googleAdsService->isRemarketingActive()) {
     129            return '';
    105130        }
    106131
    107         return '';
     132        return GtagIntegrationHelper::addToCart(
     133            $this->sendTo,
     134            $this->googleAdsService->isConversionWithVat(),
     135            $this->googleAdsService->isCompositeIdEnabled(),
     136            $this->googleAdsService->getBusinessType()
     137        );
    108138    }
    109139
    110140    public function addToCartAjax(): void
    111141    {
    112         if ($this->googleAdsService->isRemarketingActive()) {
    113             GtagIntegrationHelper::addToCartAjax($this->sendTo, $this->googleAdsService->isConversionWithVat());
     142        if (!$this->googleAdsService->isRemarketingActive()) {
     143            return;
    114144        }
     145
     146        GtagIntegrationHelper::addToCartAjax(
     147            $this->sendTo,
     148            $this->googleAdsService->isConversionWithVat(),
     149            $this->googleAdsService->isCompositeIdEnabled(),
     150            $this->googleAdsService->getBusinessType()
     151        );
    115152    }
    116153
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleAnalytics/GA4/Ga4Service.php

    r2998630 r3185508  
    3131    public const SHIPPING_PRICE_INCL = 'mmp-google-ga4-shipping-included';
    3232    public const REFUND_STATUS = 'mmp-ga4-refund-status';
     33    public const COMPOSITE_ID_ENABLED = 'mmp-google-ga4-composite-id-enabled';
    3334
    3435    public const REFUND_OBJECT = 'mmp-ga4-refund-items-object'; // Saves refund data and shows theme on next page reload which happens immediately after refund
    3536    public const REFUND_PREFIX_ORDER_FULLY_REFUNDED = 'mmp-ga4-orderFullyRefunded-';
     37
     38    // Events
     39    public const ADD_PAYMENT_INFO_EVENT_ENABLED = 'mmp-ga4-add-payment-info-event-enabled';
     40    public const ADD_SHIPPING_INFO_EVENT_ENABLED = 'mmp-ga4-add-shipping-info-event-enabled';
     41    public const ADD_TO_CART_EVENT_ENABLED = 'mmp-ga4-add-to-cart-event-enabled';
     42    public const ADD_TO_CART_AJAX_EVENT_ENABLED = 'mmp-ga4-add-to-cart-ajax-event-enabled';
     43    public const BEGIN_CHECKOUT_EVENT_ENABLED = 'mmp-ga4-begin-checkout-event-enabled';
     44    public const PURCHASE_EVENT_ENABLED = 'mmp-ga4-purchase-event-enabled';
     45    public const REMOVE_FROM_CART_EVENT_ENABLED = 'mmp-ga4-remove-from-cart-event-enabled';
     46    public const SEARCH_EVENT_ENABLED = 'mmp-ga4-search-event-enabled';
     47    public const SELECT_CONTENT_EVENT_ENABLED = 'mmp-ga4-select-content-event-enabled';
     48    public const SELECT_ITEM_EVENT_ENABLED = 'mmp-ga4-select-item-event-enabled';
     49    public const VIEW_CART_EVENT_ENABLED = 'mmp-ga4-view-cart-event-enabled';
     50    public const VIEW_ITEM_EVENT_ENABLED = 'mmp-ga4-view-item-event-enabled';
     51    public const VIEW_ITEM_LIST_EVENT_ENABLED = 'mmp-ga4-view-item-list-event-enabled';
     52    public const REFUND_EVENT_ENABLED = 'mmp-ga4-refund-event-enabled';
    3653
    3754    /**
     
    6986        return $this->getConversionVatIncluded() === 1;
    7087    }
     88
     89    public function isCompositeIdEnabled(): bool
     90    {
     91        return $this->getCompositeIdEnabled() === 1;
     92    }
     93
     94    public function isAddPaymentInfoEventEnabled(): bool
     95    {
     96        return $this->getAddPaymentInfoEventEnabled() === 1;
     97    }
     98
     99    public function isAddShippingInfoEventEnabled(): bool
     100    {
     101        return $this->getAddShippingInfoEventEnabled() === 1;
     102    }
     103
     104    public function isAddToCartEventEnabled(): bool
     105    {
     106        return $this->getAddToCartEventEnabled() === 1;
     107    }
     108
     109    public function isBeginCheckoutEventEnabled(): bool
     110    {
     111        return $this->getBeginCheckoutEventEnabled() === 1;
     112    }
     113
     114    public function isPurchaseEventEnabled(): bool
     115    {
     116        return $this->getPurchaseEventEnabled() === 1;
     117    }
     118
     119    public function isRemoveFromCartEventEnabled(): bool
     120    {
     121        return $this->getRemoveFromCartEventEnabled() === 1;
     122    }
     123
     124    public function isSearchEventEnabled(): bool
     125    {
     126        return $this->getSearchEventEnabled() === 1;
     127    }
     128
     129    public function isSelectContentEventEnabled(): bool
     130    {
     131        return $this->getSelectContentEventEnabled() === 1;
     132    }
     133
     134    public function isSelectItemEventEnabled(): bool
     135    {
     136        return $this->getSelectItemEventEnabled() === 1;
     137    }
     138
     139    public function isViewCartEventEnabled(): bool
     140    {
     141        return $this->getViewCartEventEnabled() === 1;
     142    }
     143
     144    public function isViewItemEventEnabled(): bool
     145    {
     146        return $this->getViewItemEventEnabled() === 1;
     147    }
     148
     149    public function isViewItemListEventEnabled(): bool
     150    {
     151        return $this->getViewItemListEventEnabled() === 1;
     152    }
     153
     154    public function isRefundEventEnabled(): bool
     155    {
     156        return $this->getRefundEventEnabled() === 1;
     157    }
     158
     159    public function isAddToCartAjaxEventEnabled(): bool
     160    {
     161        return $this->getAddToCartAjaxEventEnabled() === 1;
     162    }
     163
    71164
    72165    /****************************************************
     
    116209    }
    117210
     211    public function getCompositeIdEnabled(): int
     212    {
     213        return (int)get_option(self::COMPOSITE_ID_ENABLED, 0);
     214    }
     215
     216    public function getBeginCheckoutEventEnabled(): int
     217    {
     218        return (int)get_option(self::BEGIN_CHECKOUT_EVENT_ENABLED, 1);
     219    }
     220
     221    public function getPurchaseEventEnabled(): int
     222    {
     223        return (int)get_option(self::PURCHASE_EVENT_ENABLED, 1);
     224    }
     225
     226    public function getRemoveFromCartEventEnabled(): int
     227    {
     228        return (int)get_option(self::REMOVE_FROM_CART_EVENT_ENABLED, 1);
     229    }
     230
     231    public function getSearchEventEnabled(): int
     232    {
     233        return (int)get_option(self::SEARCH_EVENT_ENABLED, 1);
     234    }
     235
     236    public function getSelectContentEventEnabled(): int
     237    {
     238        return (int)get_option(self::SELECT_CONTENT_EVENT_ENABLED, 1);
     239    }
     240
     241    public function getSelectItemEventEnabled(): int
     242    {
     243        return (int)get_option(self::SELECT_ITEM_EVENT_ENABLED, 1);
     244    }
     245
     246    public function getViewCartEventEnabled(): int
     247    {
     248        return (int)get_option(self::VIEW_CART_EVENT_ENABLED, 1);
     249    }
     250
     251
     252    public function getViewItemEventEnabled(): int
     253    {
     254        return (int)get_option(self::VIEW_ITEM_EVENT_ENABLED, 1);
     255    }
     256
     257    public function getViewItemListEventEnabled(): int
     258    {
     259        return (int)get_option(self::VIEW_ITEM_LIST_EVENT_ENABLED, 1);
     260    }
     261
     262    public function getAddPaymentInfoEventEnabled(): int
     263    {
     264        return (int)get_option(self::ADD_PAYMENT_INFO_EVENT_ENABLED, 1);
     265    }
     266
     267    public function getAddShippingInfoEventEnabled(): int
     268    {
     269        return (int)get_option(self::ADD_SHIPPING_INFO_EVENT_ENABLED, 1);
     270    }
     271
     272    public function getAddToCartEventEnabled(): int
     273    {
     274        return (int)get_option(self::ADD_TO_CART_EVENT_ENABLED, 1);
     275    }
     276
     277    public function getRefundEventEnabled(): int
     278    {
     279        return (int)get_option(self::REFUND_EVENT_ENABLED, 1);
     280    }
     281
     282    public function getAddToCartAjaxEventEnabled(): int
     283    {
     284        return (int)get_option(self::ADD_TO_CART_AJAX_EVENT_ENABLED, 1);
     285    }
     286
     287    /**
     288     * SET
     289     */
     290
    118291    public function setRefundObject($object): bool
    119292    {
    120293        return update_option(self::REFUND_OBJECT, $object, true);
    121294    }
     295
     296    /**
     297     * DELETE
     298     */
    122299
    123300    public function deleteRefundObject(): bool
     
    132309    public static function saveFields($post): void
    133310    {
    134         $checkboxes = array(self::ACTIVE, self::ECOMMERCE, self::CONVERSION_VAT_INCL, self::SHIPPING_PRICE_INCL);
     311        $checkboxes = [
     312            self::ACTIVE,
     313            self::ECOMMERCE,
     314            self::CONVERSION_VAT_INCL,
     315            self::SHIPPING_PRICE_INCL,
     316            self::ADD_PAYMENT_INFO_EVENT_ENABLED,
     317            self::ADD_SHIPPING_INFO_EVENT_ENABLED,
     318            self::ADD_TO_CART_EVENT_ENABLED,
     319            self::ADD_TO_CART_AJAX_EVENT_ENABLED,
     320            self::BEGIN_CHECKOUT_EVENT_ENABLED,
     321            self::PURCHASE_EVENT_ENABLED,
     322            self::REMOVE_FROM_CART_EVENT_ENABLED,
     323            self::SEARCH_EVENT_ENABLED,
     324            self::SELECT_CONTENT_EVENT_ENABLED,
     325            self::SELECT_ITEM_EVENT_ENABLED,
     326            self::VIEW_CART_EVENT_ENABLED,
     327            self::VIEW_ITEM_EVENT_ENABLED,
     328            self::VIEW_ITEM_LIST_EVENT_ENABLED,
     329            self::REFUND_EVENT_ENABLED,
     330        ];
    135331
    136332        foreach (wc_get_order_statuses() as $key => $data) {
     
    138334        }
    139335
     336        $checkboxes[] = self::COMPOSITE_ID_ENABLED;
     337
    140338        DatabaseManager::saveOptions($post, $checkboxes, [
    141339            self::CODE,
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleAnalytics/GA4/Ga4ServiceIntegration.php

    r3134668 r3185508  
    1919use Exception;
    2020use Mergado;
    21 use Mergado\Helper\AddToCartAjaxHelper;
     21use Mergado\Helper\ControllerHelper;
     22use Mergado\Helper\ProductDetailRequestHelper;
     23use Mergado\Helper\ProductHelper;
    2224use Mergado\Service\External\Google\GoogleAnalytics\GA4\objects\base\BaseGa4ItemEventObject;
    2325use Mergado\Service\External\Google\GoogleAnalytics\GA4\objects\base\BaseGa4ItemsEventObject;
     
    4042use WC_Product;
    4143use WC_Product_Simple;
    42 use WC_Product_Variable;
    4344use WooCommerce;
    4445
     
    7677    public function viewCart(): void
    7778    {
    78         if ($this->ga4Service->isActiveEcommerce()) {
    79             $cartDataObject = $this->getCartDataObject();
    80 
    81             echo TemplateLoader::getTemplate(
    82                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/viewCart.php',
    83                 ['eventObject' => $cartDataObject]
    84             );
    85         }
     79        if (ControllerHelper::isNotCart() || !$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isViewCartEventEnabled()) {
     80            return;
     81        }
     82
     83        $cartDataObject = $this->getCartDataObject();
     84
     85        echo TemplateLoader::getTemplate(
     86            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/viewCart.php',
     87            ['eventObject' => $cartDataObject]
     88        );
    8689    }
    8790
     
    110113    public function getCartEventItemsObject(bool $removeUrlAsKey = false): BaseGa4ItemsEventObject
    111114    {
    112         /**
    113          * @var $woocommerce WooCommerce
    114          */
    115115        global $woocommerce;
    116116
    117117        $eventItemsObject = new BaseGa4ItemsEventObject();
    118 
     118        $compositeIdEnabled = $this->ga4Service->isCompositeIdEnabled();
    119119
    120120        foreach ($woocommerce->cart->cart_contents as $key => $item) {
    121             $id = $this->getProductId($item);
    122 
    123             if ($item['variation_id']) {
    124                 $appliedCoupons = $this->getCartProductAppliedCoupons($item['product_id'], $item['variation_id']);
     121            $itemData = Mergado\Helper\ProductCartHelper::getIdsFromCartItem($item, $compositeIdEnabled);
     122
     123            if ($itemData['parentId'] === null) {
     124                $productCategories = ProductHelper::getProductCategories($itemData['id'], true);
     125                $appliedCoupons = $this->getCartProductAppliedCoupons($itemData['parentId'], $itemData['id']);
    125126            } else {
    126                 $appliedCoupons = $this->getCartProductAppliedCoupons($item['product_id']);
     127                $productCategories = ProductHelper::getProductCategories($itemData['id'], true);
     128                $appliedCoupons = $this->getCartProductAppliedCoupons($itemData['id']);
    127129            }
    128130
     
    136138            $eventItemObject = new BaseGa4ItemEventObject();
    137139            $eventItemObject
    138                 ->setItemId($id)
     140                ->setItemId($itemData['fullId'])
    139141                ->setItemName($product->get_name())
    140                 ->setItemCategories($this->getProductCategories($id))
     142                ->setItemCategories($productCategories)
    141143                ->setQuantity($item['quantity'])
    142144                ->setCoupon($appliedCoupons)
     
    156158
    157159        return $eventItemsObject;
    158     }
    159 
    160     public function getProductId($item)
    161     {
    162         if ($item['variation_id'] == 0) {
    163             $id = $item['product_id'];
    164         } else {
    165             $id = $item['product_id'] . '-' . $item['variation_id'];
    166         }
    167 
    168         return $id;
    169160    }
    170161
     
    189180    }
    190181
    191     public function getProductPrices(WC_Product $product): array
    192     {
    193         if ($this->ga4Service->isConversionWithVat()) {
    194             $regularPrice = (float)wc_get_price_including_tax($product, ['price' => $product->get_regular_price()]); // Normal product price without discount
    195             $price = (float)wc_get_price_including_tax($product); // Price after product discount
    196         } else {
    197             $regularPrice = (float)wc_get_price_excluding_tax($product, ['price' => $product->get_regular_price()]); // Normal product price without discount
    198             $price = (float)wc_get_price_excluding_tax($product); // Price after product discount
    199         }
    200 
    201         return ['price' => $price, 'regularPrice' => $regularPrice, 'discount' => $this->getDiscount($price, $regularPrice)];
    202     }
    203 
    204182    /**
    205183     * Prices and taxes inside $orderItem are not affected by woocomerce tax settings
     
    227205    }
    228206
    229     public function getProductCategories($id): array
    230     {
    231         $categories = get_the_terms($id, 'product_cat');
    232 
    233         $productCategories = [];
    234         if ($categories) {
    235             foreach ($categories as $category) {
    236                 $productCategories[] = $category->name;
    237             }
    238         }
    239 
    240         return $productCategories;
    241     }
    242 
    243207    public function getCartValue(): float
    244208    {
     
    262226    public function addPaymentInfo(): void
    263227    {
    264         if ($this->ga4Service->isActiveEcommerce()) {
     228        if (
     229            !$this->ga4Service->isActiveEcommerce() ||
     230            !$this->ga4Service->isAddPaymentInfoEventEnabled() ||
     231            ControllerHelper::isNotCartOrCheckout()
     232        ) {
     233            return;
     234        }
     235
     236        echo TemplateLoader::getTemplate(
     237            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addPaymentInfo.php', ['payment_methods' => $this->getPaymentMethods()]
     238        );
     239    }
     240
     241    public function addShippingInfo(): void
     242    {
     243        if (
     244            !$this->ga4Service->isActiveEcommerce() ||
     245            !$this->ga4Service->isAddShippingInfoEventEnabled() ||
     246            ControllerHelper::isNotCartOrCheckout()
     247        ) {
     248            return;
     249        }
     250
     251        $shippingMethods = $this->getShippingMethods();
     252
     253        if ($shippingMethods) {
    265254            echo TemplateLoader::getTemplate(
    266                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addPaymentInfo.php', ['payment_methods' => $this->getPaymentMethods()]
     255                __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addShippingInfo.php', ['shipping_methods' => $shippingMethods]
    267256            );
    268257        }
    269258    }
    270259
    271     public function addShippingInfo(): void
    272     {
    273         if ($this->ga4Service->isActiveEcommerce()) {
    274             $shippingMethods = $this->getShippingMethods();
    275 
    276             if ($shippingMethods) {
    277                 echo TemplateLoader::getTemplate(
    278                     __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addShippingInfo.php', ['shipping_methods' => $shippingMethods]
    279                 );
    280             }
    281         }
    282     }
    283 
    284260    public function addToCart() : string
    285261    {
     262        // Check if section is active
     263        if (!$this->ga4Service->isActiveEcommerce()) {
     264            return '';
     265        }
     266
    286267        $result = '';
    287 
    288         if ($this->ga4Service->isActiveEcommerce()) {
    289 
    290             // Disable if woodmart theme because of incompatibility
    291             if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], AddToCartAjaxHelper::getDisabledActionNames(), true)) {
    292                 return $result;
    293             }
    294 
    295             if (isset($_POST['add-to-cart'])) {
    296                 $product = wc_get_product($_POST['add-to-cart']);
    297 
    298                 $eventItemsObject = new BaseGa4ItemsEventObject();
    299 
    300                 if ($product->get_type() === 'grouped') { // Check if grouped product
    301                     if (!isset($_POST['groupedGTAG4'])) { // Check if request is duplicate (grouped products send two posts with same data)
    302                         $_POST['groupedGTAG4'] = true; // Set variable that disable next call of same addToCart
    303 
    304                         $totalMonetaryPrice = 0;
    305 
    306                         foreach ($_POST['quantity'] as $id => $quantity) {
    307                             $product = wc_get_product($id); // No need for ID changing because only simple products can be added on grouped page
    308 
    309                             $eventItemObject = new BaseGa4ItemEventObject();
    310 
    311                             $prices = $this->getProductPrices($product);
    312                             $totalMonetaryPrice = $totalMonetaryPrice + ($prices['price'] * $_POST['quantity']);
    313 
    314                             $eventItemObject
    315                                 ->setItemId($id)
    316                                 ->setItemName($product->get_name())
    317                                 ->setItemCategories($this->getProductCategories($id))
    318                                 ->setQuantity($_POST['quantity'])
    319                                 ->setPrice((float)$prices['price'])
    320                                 ->setDiscount((float)$prices['discount']);
    321 
    322                             // No variant ID
    323 
    324                             $eventItemsObject->addItem($eventItemObject);
    325                         }
    326 
    327                         $eventObject = new Ga4AddToCartEventObject();
    328                         $eventObject
    329                             ->setValue($totalMonetaryPrice)
    330                             ->setCurrency(get_woocommerce_currency())
    331                             ->setItems($eventItemsObject)
    332                             ->setSendTo($this->sendTo);
    333 
    334                         $result .= TemplateLoader::getTemplate(__MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addToCart.php',
    335                             ['eventObject' => $eventObject->getResult()]);
    336                     }
    337                 } else {
    338                     $product = wc_get_product($_POST['add-to-cart']);
    339 
    340                     if (isset($_POST['variation_id']) && $_POST['variation_id'] && $_POST['variation_id'] !== '') {
    341                         $id = $product->get_data()['id'] . '-' . $_POST['variation_id'];
    342                     } else {
    343                         $id = $product->get_data()['id'];
    344                     }
    345 
    346                     $eventItemObject = new BaseGa4ItemEventObject();
    347 
    348                     $prices = $this->getProductPrices($product);
    349 
    350                     $eventItemObject
    351                         ->setItemId($id)
    352                         ->setItemName($product->get_name())
    353                         ->setItemCategories($this->getProductCategories($id))
    354                         ->setQuantity($_POST['quantity'])
    355                         ->setPrice((float)$prices['price'])
    356                         ->setDiscount((float)$prices['discount']);
    357 
    358                     if (isset($_POST['variation_id']) && $_POST['variation_id']) {
    359                         $eventItemObject->setItemVariant($_POST['variation_id']);
    360                     }
    361 
    362                     $eventItemsObject->addItem($eventItemObject);
    363 
    364                     $eventObject = new Ga4AddToCartEventObject();
     268        $withVat = $this->ga4Service->isConversionWithVat();
     269        $totalMonetaryPrice = 0;
     270
     271        $eventItemsObject = new BaseGa4ItemsEventObject();
     272        $compositeIdEnabled = $this->ga4Service->isCompositeIdEnabled();
     273
     274        $products = ProductDetailRequestHelper::getAddToCartProductsFromRequest($withVat, 'groupedGTAG4', $compositeIdEnabled);
     275
     276        foreach($products as $productData) {
     277            $eventItemObject = new BaseGa4ItemEventObject();
     278
     279            $totalMonetaryPrice = $totalMonetaryPrice + ($productData['prices']['price'] * $_POST['quantity']);
     280
     281            $eventItemObject
     282                ->setItemId($productData['fullId'])
     283                ->setItemName($productData['name'])
     284                ->setItemCategories($productData['categories'])
     285                ->setQuantity($productData['quantity'])
     286                ->setPrice((float)$productData['prices']['price'])
     287                ->setDiscount((float)$productData['prices']['discount']);
     288
     289            // No variant ID
     290
     291            $eventItemsObject->addItem($eventItemObject);
     292        }
     293
     294        $eventObject = new Ga4AddToCartEventObject();
     295        $eventObject
     296            ->setValue((float)$totalMonetaryPrice)
     297            ->setCurrency(get_woocommerce_currency())
     298            ->setItems($eventItemsObject)
     299            ->setSendTo($this->sendTo);
     300
     301        $result .= TemplateLoader::getTemplate(
     302            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addToCart.php',
     303            ['eventObject' => $eventObject->getResult(), 'eventEnabled' => $this->ga4Service->isAddToCartEventEnabled()]
     304        );
     305
     306        return $result;
     307    }
     308
     309    public function addToCartAjax(): void
     310    {
     311        if (!$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isAddToCartAjaxEventEnabled()) {
     312            return;
     313        }
     314
     315        $eventObject = new Ga4AddToCartEventObject();
     316        $eventObject
     317            ->setCurrency(get_woocommerce_currency())
     318            ->setSendTo($this->sendTo);
     319
     320        echo TemplateLoader::getTemplate(
     321            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addToCartAjax.php',
     322            [
     323                'eventObject' => $eventObject->getResult(true),
     324                'withVat' => $this->ga4Service->isConversionWithVat(),
     325                'compositeIdEnabled' => $this->ga4Service->isCompositeIdEnabled()
     326            ]
     327        );
     328    }
     329
     330    public function search(): void
     331    {
     332        if (!$this->ga4Service->isActiveEcommerce() || !ControllerHelper::isSearch() || !$this->ga4Service->isSearchEventEnabled()) {
     333            return;
     334        }
     335
     336        $eventObject = new Ga4SearchEventObject(get_search_query());
     337
     338        echo TemplateLoader::getTemplate(
     339            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/search.php',
     340            ['eventObject' => $eventObject->getResult()]
     341        );
     342    }
     343
     344    public function beginCheckout(): void
     345    {
     346        if (!ControllerHelper::isCheckout() ||
     347            !$this->ga4Service->isActiveEcommerce() ||
     348            !$this->ga4Service->isBeginCheckoutEventEnabled()
     349        ) {
     350            return;
     351        }
     352
     353        echo TemplateLoader::getTemplate(
     354            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/beginCheckout.php'
     355        );
     356    }
     357
     358    public function productDetailView(): void
     359    {
     360        if (!$this->ga4Service->isActiveEcommerce() || !is_product()) {
     361            return;
     362        }
     363
     364        $pricesWithVat = $this->ga4Service->isConversionWithVat();
     365
     366        $compositeIdEnabled = $this->ga4Service->isCompositeIdEnabled();
     367        $itemData = ProductDetailRequestHelper::getProductDataForViewDetailRequest($pricesWithVat, $compositeIdEnabled);
     368
     369        $eventItemsObject = new BaseGa4ItemsEventObject();
     370        $eventItemObject = new BaseGa4ItemEventObject();
     371        $eventItemObject
     372            ->setItemId($itemData['fullId'])
     373            ->setItemName($itemData['name'])
     374            ->setItemCategories($itemData['categories'])
     375            ->setPrice($itemData['prices']['price'])
     376            ->setDiscount($itemData['prices']['discount']);
     377
     378        $eventItemsObject->addItem($eventItemObject);
     379
     380        // Select item
     381        // If user come from my url === clicked on product url
     382        if ($this->ga4Service->isSelectItemEventEnabled() && isset($_SERVER["HTTP_REFERER"])) {
     383            if (strpos($_SERVER["HTTP_REFERER"], get_site_url()) !== false) {
     384
     385                // If not same url... redirect after add to cart
     386                if ($_SERVER["HTTP_REFERER"] !== Mergado\Helper\UrlHelper::getCurrentUrl()) {
     387                    $eventObject = new Ga4SelectItemEventObject();
    365388                    $eventObject
    366                         ->setValue((float)$prices['price'] * $_POST['quantity'])
    367                         ->setCurrency(get_woocommerce_currency())
    368389                        ->setItems($eventItemsObject)
    369390                        ->setSendTo($this->sendTo);
    370391
    371                     $result .= TemplateLoader::getTemplate(
    372                         __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addToCart.php',
     392                    echo TemplateLoader::getTemplate(
     393                        __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/selectItem.php',
    373394                        ['eventObject' => $eventObject->getResult()]
    374395                    );
     
    377398        }
    378399
    379         return $result;
    380     }
    381 
    382     public function addToCartAjax(): void
    383     {
    384         if ($this->ga4Service->isActiveEcommerce()) {
    385             $eventObject = new Ga4AddToCartEventObject();
    386             $eventObject
    387                 ->setCurrency(get_woocommerce_currency())
    388                 ->setSendTo($this->sendTo);
    389 
    390             echo TemplateLoader::getTemplate(
    391                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addToCartAjax.php',
    392                 ['eventObject' => $eventObject->getResult(true), 'withVat' => $this->ga4Service->isConversionWithVat()]
    393             );
    394         }
    395     }
    396 
    397     public function search(): void
    398     {
    399         if ($this->ga4Service->isActiveEcommerce() && is_search()) {
    400             $eventObject = new Ga4SearchEventObject(get_search_query());
    401 
    402             echo TemplateLoader::getTemplate(
    403                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/search.php',
    404                 ['eventObject' => $eventObject->getResult()]
    405             );
    406         }
    407     }
    408 
    409     public function beginCheckout(): void
    410     {
    411         if ($this->ga4Service->isActiveEcommerce()) {
    412             echo TemplateLoader::getTemplate(
    413                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/beginCheckout.php'
    414             );
    415         }
    416     }
    417 
    418     public function productDetailView(): void
    419     {
    420         if ($this->ga4Service->isActiveEcommerce() && is_product()) {
    421             /**
    422              * @var $product WC_Product_Variable | WC_product
    423              */
    424             global $product;
    425 
    426             $id = get_queried_object_id();
    427 
    428             if ($product->is_type('variable')) {
    429                 $variations = $product->get_available_variations();
    430 
    431                 if (count($_GET) > 0 && $variations && is_array($variations) && count($variations) > 0) {
    432                     foreach ($variations as $variation) {
    433                         $isVariant = true;
    434 
    435                         foreach ($variation['attributes'] as $attrName => $attrValue) {
    436                             // If attribute not in get and attribute value is "" || attribute is set in get and value is same
    437                             if (isset($_GET[$attrName])) {
    438                                 if ($_GET[$attrName] !== $attrValue) {
    439                                     $isVariant = false;
    440                                     break;
    441                                 }
    442                             } else {
    443                                 if ($attrValue !== '') {
    444                                     $isVariant = false;
    445                                     break;
    446                                 }
    447                             }
    448                         }
    449 
    450                         if ($isVariant) {
    451                             $variableId = $variation['variation_id'];
    452                             $id = $id . '-' . $variableId;
    453                             break;
    454                         }
    455                     }
    456                 }
    457             }
    458 
    459             $itemPrices = $this->getProductPrices($product);
    460 
    461             $eventItemsObject = new BaseGa4ItemsEventObject();
    462             $eventItemObject = new BaseGa4ItemEventObject();
    463             $eventItemObject
    464                 ->setItemId($id)
    465                 ->setItemName($product->get_name())
    466                 ->setItemCategories($this->getProductCategories($id))
    467                 ->setPrice($itemPrices['price'])
    468                 ->setDiscount($itemPrices['discount']);
    469 
    470             if (isset($variableId) && $variableId) {
    471                 $eventItemObject->setItemVariant($variableId);
    472             }
    473 
    474             $eventItemsObject->addItem($eventItemObject);
    475 
     400        if ($this->ga4Service->isViewItemEventEnabled()) {
     401            // View item
    476402            $eventObject = new Ga4ViewItemEventObject();
    477403            $eventObject
    478                 ->setValue($itemPrices['price'])
     404                ->setValue($itemData['prices']['price'])
    479405                ->setCurrency(get_woocommerce_currency())
    480406                ->setItems($eventItemsObject)
     
    485411                ['eventObject' => $eventObject->getResult()]
    486412            );
    487 
    488             //If user come from my url === clicked on product url
    489             if (isset($_SERVER["HTTP_REFERER"])) {
    490                 if (strpos($_SERVER["HTTP_REFERER"], get_site_url()) !== false) {
    491 
    492                     // If not same url .. redirect after add to cart
    493                     if ($_SERVER["HTTP_REFERER"] !== Mergado\Helper\UrlHelper::getCurrentUrl()) {
    494                         $eventObject = new Ga4SelectItemEventObject();
    495                         $eventObject
    496                             ->setItems($eventItemsObject)
    497                             ->setSendTo($this->sendTo);
    498 
    499                         echo TemplateLoader::getTemplate(
    500                             __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/selectItem.php',
    501                             ['eventObject' => $eventObject->getResult()]
    502                         );
    503                     }
    504                 }
    505             }
    506 
     413        }
     414
     415        if ($this->ga4Service->isSelectContentEventEnabled()) {
     416            // Change of variation
    507417            $eventObject = new Ga4SelectContentEventObject('product');
    508418            $eventObject->setSendTo($this->sendTo);
    509419
    510             // Change of variation
    511420            echo TemplateLoader::getTemplate(
    512421                __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/selectContentVariation.php',
    513                 ['eventObject' => $eventObject->getResult()]
     422                ['eventObject' => $eventObject->getResult(), 'compositeIdEnabled' => $compositeIdEnabled]
    514423            );
    515424        }
     
    518427    public function removeFromCart(): void
    519428    {
    520         if ($this->ga4Service->isActiveEcommerce()) {
    521             $eventObjectItems = $this->getCartEventItemsObject(true);
    522 
    523             $eventObject = new Ga4RemoveFromCartEventObject();
    524             $eventObject
    525                 ->setValue($this->getCartValue())
    526                 ->setCurrency(get_woocommerce_currency())
    527                 ->setItems($eventObjectItems)
    528                 ->setSendTo($this->sendTo);
     429        if (ControllerHelper::isNotCart() || !$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isRemoveFromCartEventEnabled()) {
     430            return;
     431        }
     432
     433        $eventObjectItems = $this->getCartEventItemsObject(true);
     434
     435        $eventObject = new Ga4RemoveFromCartEventObject();
     436        $eventObject
     437            ->setValue($this->getCartValue())
     438            ->setCurrency(get_woocommerce_currency())
     439            ->setItems($eventObjectItems)
     440            ->setSendTo($this->sendTo);
     441
     442        echo TemplateLoader::getTemplate(
     443            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/removeFromCart.php',
     444            ['eventObject' => $eventObject->getResult()]
     445        );
     446    }
     447
     448    public function viewItemList(): void
     449    {
     450        if ( !$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isViewItemListEventEnabled()) {
     451            return;
     452        }
     453
     454        if (ControllerHelper::isShop() || ControllerHelper::isProductCategory() || ControllerHelper::isSearch()) {
     455            if (ControllerHelper::isShop()) {
     456                $listName = 'shop';
     457            } else if (ControllerHelper::isProductCategory()) {
     458                $listName = get_queried_object()->name;
     459            } else if (ControllerHelper::isSearch()) {
     460                $listName = 'search';
     461            } else {
     462                $listName = '';
     463            }
     464
     465            $eventObject = new Ga4ViewItemListEventObject();
     466            $eventObject->setItemListName($listName)->setSendTo($this->sendTo);
    529467
    530468            echo TemplateLoader::getTemplate(
    531                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/removeFromCart.php',
    532                 ['eventObject' => $eventObject->getResult()]
     469                __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/viewItemList.php',
     470                [
     471                    'eventObject' => $eventObject->getResult(true),
     472                    'currency' => get_woocommerce_currency(),
     473                    'withVat' => $this->ga4Service->isConversionWithVat(),
     474                    'compositeIdEnabled' => $this->ga4Service->isCompositeIdEnabled()
     475                ]
    533476            );
    534477        }
    535478    }
    536479
    537     public function viewItemList(): void
    538     {
    539         if (is_shop() || is_product_category() || is_search()) {
    540             if ($this->ga4Service->isActiveEcommerce()) {
    541                 if (is_shop()) {
    542                     $listName = 'shop';
    543                 } else if (is_product_category()) {
    544                     $listName = get_queried_object()->name;
    545                 } else if (is_search()) {
    546                     $listName = 'search';
    547                 } else {
    548                     $listName = '';
    549                 }
    550 
    551                 $eventObject = new Ga4ViewItemListEventObject();
    552                 $eventObject->setItemListName($listName)->setSendTo($this->sendTo);
    553 
    554                 echo TemplateLoader::getTemplate(
    555                     __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/viewItemList.php',
    556                     ['eventObject' => $eventObject->getResult(true), 'currency' => get_woocommerce_currency(), 'withVat' => $this->ga4Service->isConversionWithVat()]
    557                 );
    558             }
    559         }
    560     }
    561 
    562480    public function purchase($orderId): void
    563481    {
    564         if ($this->ga4Service->isActiveEcommerce()) {
    565             $order = wc_get_order($orderId);
    566             $products_tmp = $order->get_items();
    567 
    568             $orderCoupons = $this->getOrderCouponData($order);
    569 
    570             $eventItemsObject = new BaseGa4ItemsEventObject();
    571 
    572             foreach ($products_tmp as $product) {
    573                 if ($product instanceof WC_Order_Item_Product) {
    574                     $productId = $product->get_product_id();
    575                 } else {
    576                     $productId = $product->get_id();
    577                 }
    578 
    579                 if ($product->get_variation_id() == 0) {
    580                     $id = $productId;
    581                     $wcProduct = wc_get_product($id);
    582                     $productCoupons = $this->getOrderProductAppliedCoupons($orderCoupons, $id);
    583                 } else {
    584                     $id = $productId . '-' . $product->get_variation_id();
    585                     $wcProduct = wc_get_product($product->get_variation_id());
    586                     $productCoupons = $this->getOrderProductAppliedCoupons($orderCoupons, $productId, $product->get_variation_id());
    587                 }
    588 
    589                 $prices = $this->getPurchaseProductPrices($product, $wcProduct);
    590 
    591                 $eventItemObject = new BaseGa4ItemEventObject();
    592                 $eventItemObject
    593                     ->setItemId((string)$id)
    594                     ->setItemName($product->get_name())
    595                     ->setItemCategories($this->getProductCategories($id))
    596                     ->setQuantity($product->get_quantity())
    597                     ->setCoupon($productCoupons)
    598                     ->setPrice((float)$prices['price'])
    599                     ->setDiscount((float)$prices['discount']);
    600 
    601                 if ($product->get_variation_id() !== 0) {
    602                     $eventItemObject->setItemVariant($product->get_variation_id());
    603                 }
    604 
    605                 $eventItemsObject->addItem($eventItemObject);
    606             }
    607 
    608             $coupons = join(', ', $order->get_coupon_codes());
    609 
    610             $tax = $order->get_total_tax();
    611             $total = $order->get_total();
    612 
    613             if ($this->ga4Service->isConversionWithVat()) {
    614                 if (!$this->ga4Service->getShippingPriceIncluded()) {
    615                     $total = $total - ((float)$order->get_shipping_total() + (float)$order->get_shipping_tax());
    616                 }
    617 
    618                 $shipping = (float)$order->get_shipping_total() + (float)$order->get_shipping_tax();
     482        if (!$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isPurchaseEventEnabled()) {
     483            return;
     484        }
     485
     486        $order = wc_get_order($orderId);
     487        $products_tmp = $order->get_items();
     488
     489        $orderCoupons = $this->getOrderCouponData($order);
     490        $compositeIdEnabled = $this->ga4Service->isCompositeIdEnabled();
     491
     492        $eventItemsObject = new BaseGa4ItemsEventObject();
     493
     494        foreach ($products_tmp as $product) {
     495
     496            $itemData = Mergado\Helper\ProductPurchaseHelper::getProductDetails($product, $compositeIdEnabled);
     497
     498            if ($itemData['parentId'] === null) {
     499                $productCategories = ProductHelper::getProductCategories($itemData['id'], true);
     500                $productCoupons = $this->getOrderProductAppliedCoupons($orderCoupons, $itemData['id']);
    619501            } else {
    620                 $total = $order->get_total() - $order->get_total_tax();
    621                 $shipping = (float)$order->get_shipping_total();
    622 
    623                 if (!$this->ga4Service->getShippingPriceIncluded()) {
    624                     $total = $total - ((float)$order->get_shipping_total());
    625                 }
    626             }
    627 
    628             $eventObject = new Ga4PurchaseEventObject();
    629             $eventObject
    630                 ->setTransactionId((string)$order->get_id())
    631                 ->setCoupon($coupons)
    632                 ->setValue((float)$total)
    633                 ->setTax((float)$tax)
    634                 ->setShipping($shipping)
    635                 ->setCurrency(get_woocommerce_currency())
    636                 ->setItems($eventItemsObject)
    637                 ->setSendTo($this->sendTo);
    638 
    639             echo TemplateLoader::getTemplate(
    640                 __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/purchase.php',
    641                 ['eventObject' => $eventObject->getResult()]
    642             );
    643         }
     502                $productCategories = ProductHelper::getProductCategories($itemData['id'], true);
     503                $productCoupons = $this->getOrderProductAppliedCoupons($orderCoupons, $itemData['parentId'], $itemData['id']);
     504            }
     505
     506            $prices = $this->getPurchaseProductPrices($product, $itemData['product']);
     507
     508            $eventItemObject = new BaseGa4ItemEventObject();
     509            $eventItemObject
     510                ->setItemId((string)$itemData['fullId'])
     511                ->setItemName($product->get_name())
     512                ->setItemCategories($productCategories)
     513                ->setQuantity($product->get_quantity())
     514                ->setCoupon($productCoupons)
     515                ->setPrice((float)$prices['price'])
     516                ->setDiscount((float)$prices['discount']);
     517
     518            if ($product->get_variation_id() !== 0) {
     519                $eventItemObject->setItemVariant($product->get_variation_id());
     520            }
     521
     522            $eventItemsObject->addItem($eventItemObject);
     523        }
     524
     525        $coupons = implode(', ', $order->get_coupon_codes());
     526
     527        $tax = $order->get_total_tax();
     528        $total = $order->get_total();
     529
     530        if ($this->ga4Service->isConversionWithVat()) {
     531            if (!$this->ga4Service->getShippingPriceIncluded()) {
     532                $total = $total - ((float)$order->get_shipping_total() + (float)$order->get_shipping_tax());
     533            }
     534
     535            $shipping = (float)$order->get_shipping_total() + (float)$order->get_shipping_tax();
     536        } else {
     537            $total = $order->get_total() - $order->get_total_tax();
     538            $shipping = (float)$order->get_shipping_total();
     539
     540            if (!$this->ga4Service->getShippingPriceIncluded()) {
     541                $total = $total - ((float)$order->get_shipping_total());
     542            }
     543        }
     544
     545        $eventObject = new Ga4PurchaseEventObject();
     546        $eventObject
     547            ->setTransactionId((string)$order->get_id())
     548            ->setCoupon($coupons)
     549            ->setValue((float)$total)
     550            ->setTax((float)$tax)
     551            ->setShipping($shipping)
     552            ->setCurrency(get_woocommerce_currency())
     553            ->setItems($eventItemsObject)
     554            ->setSendTo($this->sendTo);
     555
     556        echo TemplateLoader::getTemplate(
     557            __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/purchase.php',
     558            ['eventObject' => $eventObject->getResult()]
     559        );
    644560    }
    645561
     
    665581    {
    666582        //Change status to refunded or if all prices filled when clicked refund button
    667         if ($this->ga4Service->isActiveEcommerce()) {
    668             $order = wc_get_order($orderId);
    669             $alreadyRefunded = $order->get_meta(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, true);
    670 
     583        if (!$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isRefundEventEnabled()) {
     584            return;
     585        }
     586
     587        $order = wc_get_order($orderId);
     588        $alreadyRefunded = $order->get_meta(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, true);
     589
     590        if (empty($alreadyRefunded)) {
     591            $order->update_meta_data(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, 1);
     592            $order->save();
     593
     594            $eventObject = new Ga4RefundEventObject();
     595            $eventObject
     596                ->setTransactionId($orderId)
     597                ->setSendTo($this->sendTo);
     598
     599            $this->ga4Service->setRefundObject($eventObject->getResult());
     600        }
     601    }
     602
     603    /**
     604     * @throws Exception
     605     */
     606    public function refundPartial($orderId, $refundId): void
     607    {
     608        if (!$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isRefundEventEnabled()) {
     609            return;
     610        }
     611
     612        $data = json_decode(stripslashes($_POST['line_item_qtys']));
     613
     614        $eventObjectItems = new BaseGa4ItemsEventObject();
     615
     616        foreach ($data as $id => $quantity) {
     617            $productId = wc_get_order_item_meta($id, '_product_id', true);
     618            $variationId = wc_get_order_item_meta($id, '_variation_id', true);
     619
     620            $compositeIdEnabled = $this->ga4Service->isCompositeIdEnabled();
     621
     622            if ($variationId != 0) {
     623                if ($compositeIdEnabled) {
     624                    $id = $productId . '-' . $variationId;
     625                } else {
     626                    $id = $variationId;
     627                }
     628            } else {
     629                $id = $productId;
     630            }
     631
     632            $eventItemObject = new BaseGa4ItemEventObject();
     633            $eventItemObject
     634                ->setItemId((string)$id)
     635                ->setQuantity($quantity);
     636
     637            if ($variationId != 0) {
     638                $eventItemObject->setItemVariant($variationId);
     639            }
     640
     641            $eventObjectItems->addItem($eventItemObject);
     642        }
     643
     644        // Check if products are empty ==> (products not refunded.. just discounted)
     645        if (isset($eventItemObject)) {
     646            $eventObject = new Ga4RefundEventObject();
     647            $eventObject
     648                ->setTransactionId($orderId)
     649                ->setItems($eventObjectItems)
     650                ->setSendTo($this->sendTo);
     651
     652            $this->ga4Service->setRefundObject($eventObject->getResult());
     653        }
     654    }
     655
     656    /**
     657     * @throws Exception
     658     */
     659    public function orderStatusChanged($orderId, $statusOld, $statusNew, $instance): void
     660    {
     661        if (!$this->ga4Service->isActiveEcommerce() || !$this->ga4Service->isRefundEventEnabled()) {
     662            return;
     663        }
     664
     665        $order = wc_get_order($orderId);
     666        $alreadyRefunded = $order->get_meta(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, true);
     667
     668
     669        if ($_POST['order_status'] && $this->ga4Service->isRefundStatusActive($_POST['order_status'])) {
     670
     671            // Check if backend data already sent
    671672            if (empty($alreadyRefunded)) {
    672673                $order->update_meta_data(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, 1);
     
    679680
    680681                $this->ga4Service->setRefundObject($eventObject->getResult());
    681             }
    682         }
    683     }
    684 
    685     /**
    686      * @throws Exception
    687      */
    688     public function refundPartial($orderId, $refundId): void
    689     {
    690         if ($this->ga4Service->isActiveEcommerce()) {
    691             $data = json_decode(stripslashes($_POST['line_item_qtys']));
    692 
    693             $eventObjectItems = new BaseGa4ItemsEventObject();
    694 
    695             foreach ($data as $id => $quantity) {
    696                 $productId = wc_get_order_item_meta($id, '_product_id', true);
    697                 $variationId = wc_get_order_item_meta($id, '_variation_id', true);
    698 
    699                 if ($variationId != 0) {
    700                     $id = $productId . '-' . $variationId;
    701                 } else {
    702                     $id = $productId;
    703                 }
    704 
    705                 $eventItemObject = new BaseGa4ItemEventObject();
    706                 $eventItemObject
    707                     ->setItemId((string)$id)
    708                     ->setQuantity($quantity);
    709 
    710                 if ($variationId != 0) {
    711                     $eventItemObject->setItemVariant($variationId);
    712                 }
    713 
    714                 $eventObjectItems->addItem($eventItemObject);
    715             }
    716 
    717             // Check if products are empty ==> (products not refunded.. just discounted)
    718             if (isset($eventItemObject)) {
    719                 $eventObject = new Ga4RefundEventObject();
    720                 $eventObject
    721                     ->setTransactionId($orderId)
    722                     ->setItems($eventObjectItems)
    723                     ->setSendTo($this->sendTo);
    724 
    725                 $this->ga4Service->setRefundObject($eventObject->getResult());
    726             }
    727         }
    728     }
    729 
    730     /**
    731      * @throws Exception
    732      */
    733     public function orderStatusChanged($orderId, $statusOld, $statusNew, $instance): void
    734     {
    735         $order = wc_get_order($orderId);
    736         $alreadyRefunded = $order->get_meta(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, true);
    737 
    738         if ($this->ga4Service->isActiveEcommerce()) {
    739 
    740             if ($_POST['order_status'] && $this->ga4Service->isRefundStatusActive($_POST['order_status'])) {
    741 
    742                 // Check if backend data already sent
    743                 if (empty($alreadyRefunded)) {
    744                     $order->update_meta_data(Ga4Service::REFUND_PREFIX_ORDER_FULLY_REFUNDED . $orderId, 1);
    745                     $order->save();
    746 
    747                     $eventObject = new Ga4RefundEventObject();
    748                     $eventObject
    749                         ->setTransactionId($orderId)
    750                         ->setSendTo($this->sendTo);
    751 
    752                     $this->ga4Service->setRefundObject($eventObject->getResult());
    753                 }
    754682            }
    755683        }
     
    882810    public function addCartData(): void
    883811    {
    884         if ($this->ga4Service->isActiveEcommerce()) {
    885             echo TemplateLoader::getTemplate(__MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addCartData.php', ['cartData' => $this->getCartDataObject(), 'coupon' => $this->getCartGlobalCoupon()]);
    886         }
     812        if (!$this->ga4Service->isActiveEcommerce() || ControllerHelper::isNotCartOrCheckout()
     813        ) {
     814            return;
     815        }
     816
     817        echo TemplateLoader::getTemplate(__MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/GA4/addCartData.php', ['cartData' => $this->getCartDataObject(), 'coupon' => $this->getCartGlobalCoupon()]);
    887818    }
    888819
    889820    public function actionShippingRate($method): void
    890821    {
    891         if ($this->ga4Service->isActiveEcommerce()) {
    892             echo sprintf('<div class="mergado-shipping-rate-label" style="display: none !important;">%s</div>', $method->get_label());
    893         }
     822        if (!$this->ga4Service->isActiveEcommerce()) {
     823            return;
     824        }
     825
     826        echo sprintf('<div class="mergado-shipping-rate-label" style="display: none !important;">%s</div>', $method->get_label());
    894827    }
    895828
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleAnalytics/Universal/GaUniversalService.php

    r2998630 r3185508  
    3030    public const ECOMMERCE_ENHANCED = 'mmp-ga-ua-enhanced-ecommerce';
    3131    public const CONVERSION_VAT_INCL = 'mmp-ga-ua-vat-included';
     32    public const COMPOSITE_ID_ENABLED = 'mmp-ga-ua-composite-id-enabled';
    3233
    3334    private $active;
     
    8283    {
    8384        return $this->getConversionVatIncluded() === 1;
     85    }
     86
     87    public function isCompositeIdEnabled(): bool
     88    {
     89        return $this->getCompositeIdEnabled() === 1;
    8490    }
    8591
     
    143149    }
    144150
     151    public function getCompositeIdEnabled(): int
     152    {
     153        return (int)get_option(self::COMPOSITE_ID_ENABLED, 0);
     154    }
     155
    145156    /*******************************************************************************************************************
    146157     * SAVE FIELDS
     
    154165            self::ECOMMERCE_ENHANCED,
    155166            self::CONVERSION_VAT_INCL,
     167            self::COMPOSITE_ID_ENABLED
    156168        ], [
    157169            self::CODE,
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleAnalytics/Universal/GaUniversalServiceIntegration.php

    r3041908 r3185508  
    33namespace Mergado\Service\External\Google\GoogleAnalytics\Universal;
    44
     5use Mergado\Helper\ControllerHelper;
     6use Mergado\Helper\ProductCartHelper;
     7use Mergado\Helper\ProductHelper;
    58use Mergado\Service\External\Google\Gtag\GtagIntegrationHelper;
    69use Mergado\Traits\SingletonTrait;
     
    4043    public function removeFromCart(): void
    4144    {
    42         if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    43             global $woocommerce;
    44             $products = [];
    45 
    46             foreach ($woocommerce->cart->cart_contents as $key => $item) {
    47                 if ($item['variation_id'] == 0) {
    48                     $id = $item['product_id'];
    49                 } else {
    50                     $id = $item['product_id'] . '-' . $item['variation_id'];
    51                 }
    52 
    53                 $category = get_the_terms($id, "product_cat");
    54                 $categories = [];
    55 
    56                 if ($category) {
    57                     foreach ($category as $term) {
    58                         $categories[] = $term->name;
    59                     }
    60                 }
    61 
    62                 $id = $item['product_id'];
    63                 $name = $item['data']->get_name();
    64                 $category = implode(', ', $categories);
    65                 $price = $item['data']->get_price();
    66 
    67                 $products[wc_get_cart_remove_url($key)] = [
    68                     'id' => $id,
    69                     'name' => $name,
    70                     'category' => $category,
    71                     'price' => (string)$price,
    72                 ];
     45        if (!$this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce() || !ControllerHelper::isCart()) {
     46            return;
     47        }
     48
     49        global $woocommerce;
     50        $products = [];
     51
     52        $compositeIdEnabled = $this->googleUniversalAnalyticsService->isCompositeIdEnabled();
     53        $withVat = $this->googleUniversalAnalyticsService->isConversionWithVat();
     54
     55        foreach ($woocommerce->cart->cart_contents as $key => $item) {
     56            $itemData = ProductCartHelper::getIdsFromCartItem($item, $compositeIdEnabled);
     57            $categories = ProductHelper::getProductCategories($item['product_id']);
     58
     59            $wcProduct = wc_get_product($item['product_id']);
     60
     61            $productPrices = ProductHelper::getProductPrices($wcProduct, $withVat);
     62
     63            $name = $item['data']->get_name();
     64
     65            $products[wc_get_cart_remove_url($key)] = [
     66                'id' => $itemData['fullId'],
     67                'name' => $name,
     68                'category' => $categories,
     69                'price' => (string)$productPrices['price'],
     70            ];
     71        }
     72
     73        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/removeFromCart.php';
     74
     75        $templateVariables = [
     76            'currency' => get_woocommerce_currency(),
     77            'products' => htmlspecialchars(json_encode($products, JSON_NUMERIC_CHECK), ENT_QUOTES),
     78            'sendTo' => $this->sendTo
     79        ];
     80
     81        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     82    }
     83
     84    public function purchased($orderId): void
     85    {
     86        if (!$this->googleUniversalAnalyticsService->isActiveEcommerce()) {
     87            return;
     88        }
     89
     90        $order = wc_get_order($orderId);
     91
     92        $compositeIdEnabled = $this->googleUniversalAnalyticsService->isCompositeIdEnabled();
     93        $conversionWithVat = $this->googleUniversalAnalyticsService->isConversionWithVat();
     94
     95        $products = GtagIntegrationHelper::getOrderProductsForAds($orderId, $compositeIdEnabled, $conversionWithVat);
     96
     97        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/purchased.php';
     98
     99        $templateVariables = [
     100            'transactionId' => $order->get_id(),
     101            'affiliation' => get_bloginfo('name'),
     102            'value' => $order->get_total(),
     103            'currency' => $order->get_currency(),
     104            'tax' => $order->get_total_tax(),
     105            'shipping' => $order->get_shipping_total(),
     106            'items' => json_encode($products, JSON_NUMERIC_CHECK),
     107            'sendTo' => $this->sendTo
     108        ];
     109
     110        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     111    }
     112
     113    public function checkoutStep(): void
     114    {
     115        global $wp;
     116
     117        if (!ControllerHelper::isCheckout() || !$this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
     118            return;
     119        }
     120
     121        global $woocommerce;
     122
     123        $products = [];
     124        $compositeIdEnabled = $this->googleUniversalAnalyticsService->isCompositeIdEnabled();
     125        $withVat = $this->googleUniversalAnalyticsService->isConversionWithVat();
     126
     127        foreach ($woocommerce->cart->cart_contents as $key => $item) {
     128            $itemData = ProductCartHelper::getIdsFromCartItem($item, $compositeIdEnabled);
     129
     130            if ($itemData['parentId'] === null) {
     131                $productCategories = ProductHelper::getProductCategories($itemData['id']);
     132            } else {
     133                $productCategories = ProductHelper::getProductCategories($itemData['parentId']);
    73134            }
    74135
    75             $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/removeFromCart.php';
    76 
    77             $templateVariables = [
    78                 'currency' => get_woocommerce_currency(),
    79                 'products' => htmlspecialchars(json_encode($products, JSON_NUMERIC_CHECK), ENT_QUOTES),
    80                 'sendTo' => $this->sendTo
     136            $wcProduct = wc_get_product($itemData['id']);
     137
     138            $productPrices = ProductHelper::getProductPrices($wcProduct, $withVat);
     139
     140            $name = $item['data']->get_name();
     141
     142            $products[] = [
     143                'id' => $itemData['fullId'],
     144                'name' => $name,
     145                'category' => $productCategories,
     146                'price' => (string)$productPrices['price'],
    81147            ];
    82 
    83             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    84         }
    85     }
    86 
    87     public function purchased($orderId): void
    88     {
    89         if ($this->googleUniversalAnalyticsService->isActiveEcommerce()) {
    90             $order = wc_get_order($orderId);
    91             $products_tmp = $order->get_items();
    92 
    93             $products = array();
    94 
    95             foreach ($products_tmp as $product) {
    96                 if ($product->get_variation_id() == 0) {
    97                     $id = $product->get_data()['product_id'];
    98                 } else {
    99                     $id = $product->get_data()['product_id'] . '-' . $product->get_variation_id();
    100                 }
    101 
    102                 $categories = get_the_terms($id, 'product_cat');
    103 
    104                 $output = [];
    105                 if ($categories) {
    106                     foreach ($categories as $category) {
    107                         $output[] = $category->name;
    108                     }
    109                 }
    110 
    111                 $productCategories = implode(", ", $output);
    112 
    113                 if ($this->googleUniversalAnalyticsService->isConversionWithVat()) {
    114                     $productPrice = ($product->get_total() + $product->get_total_tax()) / $product->get_quantity();
    115                 } else {
    116                     $productPrice = $product->get_total() / $product->get_quantity();
    117                 }
    118 
    119                 $products[] = [
    120                     'id' => $id,
    121                     'name' => $product->get_name(),
    122                     'category' => $productCategories,
    123                     'quantity' => (int)$product->get_quantity(),
    124                     'price' => (string)$productPrice,
    125                 ];
     148        }
     149
     150        $coupons = implode(', ', $woocommerce->cart->get_applied_coupons());
     151
     152        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/checkoutStep1.php';
     153
     154        $templateVariables = [
     155            'currency' => get_woocommerce_currency(),
     156            'checkoutStep' => 1,
     157            'items' => json_encode($products, JSON_NUMERIC_CHECK),
     158            'coupon' => $coupons,
     159            'sendTo' => $this->sendTo
     160        ];
     161
     162        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     163    }
     164
     165    public function checkoutManipulation(): void
     166    {
     167        if (!$this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce() || ControllerHelper::isNotCartOrCheckout()) {
     168            return;
     169        }
     170
     171        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/checkoutManipulation.php';
     172
     173        $templateVariables = [
     174            'sendTo' => $this->sendTo,
     175            'payment_methods' => $this->getPaymentMethods()
     176        ];
     177
     178        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     179    }
     180
     181    public function viewItemList(): void
     182    {
     183        if (ControllerHelper::isShop() || ControllerHelper::isProductCategory() || ControllerHelper::isSearch()) {
     184            if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
     185                GtagIntegrationHelper::viewItemList(
     186                    $this->sendTo,
     187                    $this->googleUniversalAnalyticsService->isConversionWithVat(),
     188                    $this->googleUniversalAnalyticsService->isCompositeIdEnabled(),
     189                    null
     190                );
    126191            }
    127 
    128             $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/purchased.php';
    129 
    130             $templateVariables = [
    131                 'transactionId' => $order->get_id(),
    132                 'affiliation' => get_bloginfo('name'),
    133                 'value' => $order->get_total(),
    134                 'currency' => $order->get_currency(),
    135                 'tax' => $order->get_total_tax(),
    136                 'shipping' => $order->get_shipping_total(),
    137                 'items' => json_encode($products, JSON_NUMERIC_CHECK),
    138                 'googleBusinessVertical' => 'retail',
    139                 'sendTo' => $this->sendTo
    140             ];
    141 
    142             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    143         }
    144     }
    145 
    146     public function checkoutStep(): void
    147     {
    148         if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    149             global $woocommerce;
    150 
    151             $products = [];
    152 
    153             foreach ($woocommerce->cart->cart_contents as $key => $item) {
    154                 if ($item['variation_id'] == 0) {
    155                     $id = $item['product_id'];
    156                 } else {
    157                     $id = $item['product_id'] . '-' . $item['variation_id'];
    158                 }
    159 
    160                 $category = get_the_terms($id, "product_cat");
    161                 $categories = [];
    162 
    163                 if ($category) {
    164                     foreach ($category as $term) {
    165                         $categories[] = $term->name;
    166                     }
    167                 }
    168 
    169                 $name = $item['data']->get_name();
    170                 $category = implode(', ', $categories);
    171                 $price = $item['data']->get_price();
    172 
    173                 $products[] = [
    174                     'id' => $id,
    175                     'name' => $name,
    176                     'category' => $category,
    177                     'price' => (string)$price,
    178                 ];
     192        }
     193    }
     194
     195    public function productDetailView(): void
     196    {
     197        if (!$this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
     198            return;
     199        }
     200
     201        GtagIntegrationHelper::productDetailView(
     202            $this->sendTo,
     203            $this->googleUniversalAnalyticsService->isConversionWithVat(),
     204            $this->googleUniversalAnalyticsService->isCompositeIdEnabled(),
     205            null
     206        );
     207    }
     208
     209    public function addToCart() : string
     210    {
     211        if (!$this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
     212            return '';
     213        }
     214
     215        return GtagIntegrationHelper::addToCart(
     216            $this->sendTo,
     217            $this->googleUniversalAnalyticsService->isConversionWithVat(),
     218            $this->googleUniversalAnalyticsService->isCompositeIdEnabled(),
     219            null
     220        );
     221    }
     222
     223    public function addToCartAjax(): void
     224    {
     225        if (!$this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
     226            return;
     227        }
     228
     229        GtagIntegrationHelper::addToCartAjax(
     230            $this->sendTo,
     231            $this->googleUniversalAnalyticsService->isConversionWithVat(),
     232            $this->googleUniversalAnalyticsService->isCompositeIdEnabled(),
     233            null
     234        );
     235    }
     236
     237    public function getPaymentMethods(): array
     238    {
     239        try {
     240            $methods = [];
     241
     242            foreach (WC()->payment_gateways()->payment_gateways() as $key => $gateway) {
     243                $methods[$key] = $gateway->get_title();
    179244            }
    180245
    181             $coupons = implode(', ', $woocommerce->cart->get_applied_coupons());
    182 
    183             $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/checkoutStep1.php';
    184 
    185             $templateVariables = [
    186                 'currency' => get_woocommerce_currency(),
    187                 'checkoutStep' => 1,
    188                 'items' => json_encode($products, JSON_NUMERIC_CHECK),
    189                 'coupon' => $coupons,
    190                 'sendTo' => $this->sendTo
    191             ];
    192 
    193             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    194         }
    195     }
    196 
    197     public function checkoutManipulation(): void
    198     {
    199         if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    200             $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/checkoutManipulation.php';
    201 
    202             $templateVariables = [
    203                 'sendTo' => $this->sendTo
    204             ];
    205 
    206             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    207         }
    208     }
    209 
    210     public function viewItemList(): void
    211     {
    212         if (is_shop() || is_product_category() || is_search()) {
    213             if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    214                 GtagIntegrationHelper::viewItemList($this->sendTo);
    215             }
    216         }
    217     }
    218 
    219     public function productDetailView(): void
    220     {
    221         if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    222             GtagIntegrationHelper::productDetailView($this->sendTo);
    223         }
    224     }
    225 
    226     public function addToCart() : string
    227     {
    228         if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    229             return GtagIntegrationHelper::addToCart($this->sendTo);
    230         }
    231 
    232         return '';
    233     }
    234 
    235     public function addToCartAjax(): void
    236     {
    237         if ($this->googleUniversalAnalyticsService->isActiveEnhancedEcommerce()) {
    238             GtagIntegrationHelper::addToCartAjax($this->sendTo);
     246            return $methods;
     247        } catch (\Exception $e) {
     248            return [];
    239249        }
    240250    }
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleReviews/GoogleReviewsService.php

    r2998630 r3185508  
    181181    }
    182182
     183    public function getGTINFieldValues(): array
     184    {
     185        global $wpdb;
     186
     187        $query = 'SELECT DISTINCT postmeta.meta_key FROM ';
     188        $query .= $wpdb->prefix . 'posts AS posts';
     189        $query .= ' LEFT JOIN ' . $wpdb->prefix . 'postmeta AS postmeta ON posts.id = postmeta.post_id';
     190        $query .= ' WHERE (posts.post_type="product" OR posts.post_type="product_variation") AND postmeta.meta_key NOT LIKE "\_%"';
     191
     192        $result = $wpdb->get_results($query, ARRAY_A);
     193        $fields = [0 => '_sku'];
     194
     195        foreach ($result as $item) {
     196            $fields[] = $item['meta_key'];
     197        }
     198
     199        $attributes = wc_get_attribute_taxonomies();
     200        $select = [0 => '_sku'];
     201
     202        foreach ($attributes as $attr) {
     203            $select[] = $attr->attribute_name;
     204        }
     205
     206        return array_merge($fields, $select);
     207    }
     208
    183209    /******************************************************************************************************************
    184210     * GET FIELDS
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleTagManager/GoogleTagManagerService.php

    r2998630 r3185508  
    3131    public const CONVERSION_VAT_INCL = 'gtm-vat-included';
    3232    public const VIEW_LIST_ITEMS_COUNT = 'mergado_google_tag_manager_view_list_items_count';
     33    public const COMPOSITE_ID_ENABLED = 'mmp-gtm-composite-id-enabled';
    3334
    3435    /******************************************************************************************************************
     
    6263        return $this->getConversionVatIncluded() === 1;
    6364    }
     65
     66    public function isCompositeIdEnabled(): bool
     67    {
     68        return $this->getCompositeIdEnabled() === 1;
     69    }
     70
    6471
    6572    /*******************************************************************************************************************
     
    103110    }
    104111
     112    public function getCompositeIdEnabled(): int
     113    {
     114        return (int)get_option(self::COMPOSITE_ID_ENABLED, 0);
     115    }
     116
    105117
    106118    /*******************************************************************************************************************
     
    115127            self::ECOMMERCE_ENHANCED_ACTIVE,
    116128            self::CONVERSION_VAT_INCL,
     129            self::COMPOSITE_ID_ENABLED
    117130        ], [
    118131            self::CODE,
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleTagManager/GoogleTagManagerServiceIntegration.php

    r3041908 r3185508  
    1818
    1919use Mergado;
    20 use Mergado\Helper\AddToCartAjaxHelper;
     20use Mergado\Helper\ControllerHelper;
     21use Mergado\Helper\ProductCartHelper;
     22use Mergado\Helper\ProductDetailRequestHelper;
    2123use Mergado\Helper\ProductHelper;
     24use Mergado\Helper\ProductPurchaseHelper;
    2225use Mergado\Traits\SingletonTrait;
    2326use Mergado\Utils\TemplateLoader;
     
    4144    public function mainCodeHead(): void
    4245    {
    43         $active = $this->googleTagManagerService->isActive();
    44 
    45         if ($active) {
    46             echo TemplateLoader::getTemplate(__DIR__ . '/templates/mainCodeHead.php', [
    47                 'code' => $this->googleTagManagerService->getCode()
     46        if(!$this->googleTagManagerService->isActive()) {
     47            return;
     48        }
     49
     50        echo TemplateLoader::getTemplate(__DIR__ . '/templates/mainCodeHead.php', [
     51            'code' => $this->googleTagManagerService->getCode()
     52        ]);
     53    }
     54
     55    public function mainCodeAfterBody(): void
     56    {
     57        if(!$this->googleTagManagerService->isActive()) {
     58            return;
     59        }
     60
     61        echo TemplateLoader::getTemplate(__DIR__ . '/templates/mainCodeAfterBody.php', [
     62            'code' => $this->googleTagManagerService->getCode()
     63        ]);
     64    }
     65
     66    public function removeFromCartAjax(): void
     67    {
     68        if (!$this->googleTagManagerService->isEnhancedEcommerceActive()) {
     69            return;
     70        }
     71
     72        global $woocommerce;
     73        $products = [];
     74
     75        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     76        $withVat = $this->googleTagManagerService->isConversionWithVat();
     77
     78        // Prepare data
     79        foreach ($woocommerce->cart->cart_contents as $key => $item) {
     80            $itemData = ProductCartHelper::getIdsFromCartItem($item, $compositeIdEnabled);
     81            $categories = ProductHelper::getProductCategories($item['product_id']);
     82
     83            $wcProduct = wc_get_product($item['product_id']);
     84
     85            $productPrices = Mergado\Helper\ProductHelper::getProductPrices($wcProduct, $withVat);
     86
     87            $name = $item['data']->get_name();
     88
     89            $products[wc_get_cart_remove_url($key)] = [
     90                'name' => $name,
     91                'id' => (string)$itemData['fullId'],
     92                'category' => $categories,
     93                'price' => (string)$productPrices['price'],
     94            ];
     95        }
     96
     97        echo TemplateLoader::getTemplate(__DIR__ . '/templates/removeFromCartAjax.php', [
     98            'products' => $products,
     99            'currency' => get_woocommerce_currency(),
     100        ]);
     101    }
     102
     103    public function addToCartAjax(): void
     104    {
     105        if(!$this->googleTagManagerService->isEnhancedEcommerceActive()) {
     106            return;
     107        }
     108
     109        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     110        $conversionWithVat = $this->googleTagManagerService->isConversionWithVat();
     111
     112        echo TemplateLoader::getTemplate(__DIR__ . '/templates/addToCartAjax.php',
     113            [
     114                'compositeIdEnabled' => $compositeIdEnabled,
     115                'conversionWithVat' => $conversionWithVat,
     116            ]
     117        );
     118    }
     119
     120    public function addToCart() : string
     121    {
     122        // Check if section is active
     123        if (!$this->googleTagManagerService->isEnhancedEcommerceActive()) {
     124            return '';
     125        }
     126
     127        $result = '';
     128        $withVat = $this->googleTagManagerService->isConversionWithVat();
     129        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     130
     131        $products = ProductDetailRequestHelper::getAddToCartProductsFromRequest($withVat, 'groupedGTM', $compositeIdEnabled);
     132
     133        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/GoogleTagManager/templates/addToCart.php';
     134
     135        foreach($products as $productData) {
     136            $result .= TemplateLoader::getTemplate($templatePath, [
     137                'currency' => get_woocommerce_currency(),
     138                'name' => $productData['name'],
     139                'id' => (string)$productData['fullId'],
     140                'price' => (string)$productData['prices']['price'],
     141                'quantity' => $productData['quantity'],
     142                'category' => $productData['categories']
    48143            ]);
    49144        }
    50     }
    51 
    52     public function mainCodeAfterBody(): void
    53     {
    54         $active = $this->googleTagManagerService->isActive();
    55 
    56         if ($active) {
    57             echo TemplateLoader::getTemplate(__DIR__ . '/templates/mainCodeAfterBody.php', [
    58                 'code' => $this->googleTagManagerService->getCode()
    59             ]);
    60         }
    61     }
    62 
    63     public function removeFromCartAjax(): void
    64     {
     145        return $result;
     146    }
     147
     148    public function purchase(): void
     149    {
     150        if (!$this->googleTagManagerService->isEnhancedEcommerceActive() || !ControllerHelper::isOrderReceivedPage()) {
     151            return;
     152        }
     153
     154        $orderId = empty($_GET['order']) ? ($GLOBALS['wp']->query_vars['order-received'] ? $GLOBALS['wp']->query_vars['order-received'] : 0) : absint($_GET['order']);
     155        $orderId_filter = apply_filters('woocommerce_thankyou_order_id', $orderId);
     156
     157        if ($orderId_filter != '') {
     158            $orderId = $orderId_filter;
     159        }
     160
     161        $order = wc_get_order($orderId);
     162        $products_tmp = $order->get_items();
     163
     164        $products = [];
     165
     166        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     167
     168        foreach ($products_tmp as $product) {
     169            $itemData = ProductPurchaseHelper::getProductDetails($product, $compositeIdEnabled);
     170
     171            if ($itemData['parentId'] === null) {
     172                $productCategories = ProductHelper::getProductCategories($itemData['id']);
     173            } else {
     174                $productCategories = ProductHelper::getProductCategories($itemData['parentId']);
     175            }
     176
     177            if ($this->googleTagManagerService->isConversionWithVat()) {
     178                $productPrice = ($product->get_total() + $product->get_total_tax()) / $product->get_quantity();
     179            } else {
     180                $productPrice = $product->get_total() / $product->get_quantity();
     181            }
     182
     183            $products[] = [
     184                'name' => $product->get_name(),
     185                'id' => (string)$itemData['fullId'],
     186                'category' => $productCategories,
     187                'quantity' => (int)$product->get_quantity(),
     188                'price' => (string)$productPrice,
     189            ];
     190
     191        }
     192
     193        global $woocommerce;
     194        $coupons = implode(', ', $woocommerce->cart->get_applied_coupons());
     195
     196        echo TemplateLoader::getTemplate(__DIR__ . '/templates/purchase.php', [
     197            'currencyCode' => $order->get_currency(),
     198            'id' => $order->get_id(),
     199            'affiliation' => get_bloginfo('name'),
     200            'revenue' => $order->get_total(),
     201            'tax' => $order->get_total_tax(),
     202            'shipping' => $order->get_shipping_total(),
     203            'coupon' => $coupons,
     204            'products' => $products
     205        ]);
     206    }
     207
     208    public function transaction(): void
     209    {
     210        $ecommerceActive = $this->googleTagManagerService->isEcommerceActive();
    65211        $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    66212
    67         if ($enhancedEcommerceActive) {
    68             global $woocommerce;
    69             $products = [];
    70 
    71             // Prepare data
    72             foreach ($woocommerce->cart->cart_contents as $key => $item) {
    73                 $id = ProductHelper::getMergedIdFromCartItem($item);
    74 
    75                 $category = get_the_terms($id, "product_cat");
    76                 $categories = [];
    77 
    78                 if ($category) {
    79                     foreach ($category as $term) {
    80                         $categories[] = $term->name;
    81                     }
    82                 }
    83 
    84                 $id = $item['product_id'];
    85                 $name = $item['data']->get_name();
    86                 $category = implode(', ', $categories);
    87                 $price = $item['data']->get_price();
    88 
    89                 $products[wc_get_cart_remove_url($key)] = [
    90                     'name' => $name,
    91                     'id' => $id,
    92                     'category' => $category,
    93                     'price' => (string)$price,
    94                 ];
    95             }
    96 
    97             echo TemplateLoader::getTemplate(__DIR__ . '/templates/removeFromCartAjax.php', [
    98                 'products' => $products,
    99                 'currency' => get_woocommerce_currency(),
    100             ]);
    101         }
    102     }
    103 
    104     public function addToCartAjax(): void
    105     {
    106         $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    107 
    108         if ($enhancedEcommerceActive) {
    109             echo TemplateLoader::getTemplate(__DIR__ . '/templates/addToCartAjax.php');
    110         }
    111     }
    112 
    113     public function addToCart() : string
    114     {
    115         $result = '';
    116 
    117         // Disable if woodmart theme because of incompatibility
    118         if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], AddToCartAjaxHelper::getDisabledActionNames(), true)) {
    119             return $result;
    120         }
    121 
    122         $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    123 
    124         if ($enhancedEcommerceActive) {
    125             if (isset($_POST['add-to-cart'])) {
    126                 $product = wc_get_product($_POST['add-to-cart']);
    127 
    128                 if ($product->get_type() === 'grouped') { // Check if grouped product
    129                     if (!isset($_POST['groupedGTM'])) { // Check if request is duplicate (grouped products send two posts with same data)
    130                         $_POST['groupedGTM'] = true; // Set variable that disable next call of same addToCart
    131 
    132                         foreach ($_POST['quantity'] as $id => $quantity) {
    133                             $product = wc_get_product($id); // No need for ID changing because only simple products can be added on grouped page
    134 
    135                             $categories = get_the_terms($id, 'product_cat');
    136                             $output = [];
    137                             if ($categories) {
    138                                 foreach ($categories as $category) {
    139                                     $output[] = $category->name;
    140                                 }
    141                             }
    142 
    143                             $productCategories = join(", ", $output);
    144 
    145                             $result .= TemplateLoader::getTemplate(__DIR__ . '/templates/addToCart.php', [
    146                                 'currency' => get_woocommerce_currency(),
    147                                 'name' => $product->get_name(),
    148                                 'id' => $id,
    149                                 'price' => $product->get_price(),
    150                                 'quantity' => $quantity,
    151                                 'category' => $productCategories
    152                             ]);
    153                         }
    154                     }
    155                 } else {// Simple and complicated products
    156                     if (isset($_POST['variation_id']) && $_POST['variation_id'] && $_POST['variation_id'] !== '') {
    157                         $id = $product->get_data()['id'] . '-' . $_POST['variation_id'];
    158                     } else {
    159                         $id = $product->get_data()['id'];
    160                     }
    161 
    162                     $categories = get_the_terms($id, 'product_cat');
    163 
    164                     $output = [];
    165                     if ($categories) {
    166                         foreach ($categories as $category) {
    167                             $output[] = $category->name;
    168                         }
    169                     }
    170 
    171                     $productCategories = join(", ", $output);
    172 
    173                     $result .= TemplateLoader::getTemplate(__DIR__ . '/templates/addToCart.php', [
    174                         'currency' => get_woocommerce_currency(),
    175                         'name' => $product->get_name(),
    176                         'id' => $id,
    177                         'price' => $product->get_price(),
    178                         'quantity' => $_POST['quantity'],
    179                         'category' => $productCategories
    180                     ]);
    181                 }
    182             }
    183         }
    184 
    185         return $result;
    186     }
    187 
    188     public function purchase(): void
    189     {
    190         if (is_order_received_page()) {
    191             $orderId = empty($_GET['order']) ? ($GLOBALS['wp']->query_vars['order-received'] ? $GLOBALS['wp']->query_vars['order-received'] : 0) : absint($_GET['order']);
    192             $orderId_filter = apply_filters('woocommerce_thankyou_order_id', $orderId);
    193 
    194             if ($orderId_filter != '') {
    195                 $orderId = $orderId_filter;
    196             }
    197 
    198             $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    199 
    200             if ($enhancedEcommerceActive) {
    201                 $order = wc_get_order($orderId);
    202                 $products_tmp = $order->get_items();
    203 
    204                 $products = array();
    205 
    206                 foreach ($products_tmp as $product) {
    207                     if ($product->get_variation_id() == 0) {
    208                         $id = $product->get_data()['product_id'];
    209                     } else {
    210                         $id = $product->get_data()['product_id'] . '-' . $product->get_variation_id();
    211                     }
    212 
    213                     $categories = get_the_terms($id, 'product_cat');
    214 
    215                     $output = [];
    216                     if ($categories) {
    217                         foreach ($categories as $category) {
    218                             $output[] = $category->name;
    219                         }
    220                     }
    221 
    222                     $productCategories = implode(", ", $output);
    223 
    224                     if ($this->googleTagManagerService->isConversionWithVat()) {
    225                         $productPrice = ($product->get_total() + $product->get_total_tax()) / $product->get_quantity();
    226                     } else {
    227                         $productPrice = $product->get_total() / $product->get_quantity();
    228                     }
    229 
    230                     $products[] = [
    231                         'name' => $product->get_name(),
    232                         'id' => $id,
    233                         'category' => $productCategories,
    234                         'quantity' => (int)$product->get_quantity(),
    235                         'price' => (string)$productPrice,
    236                     ];
    237 
    238                 }
    239 
    240                 global $woocommerce;
    241                 $coupons = implode(', ', $woocommerce->cart->get_applied_coupons());
    242 
    243                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/purchase.php', [
    244                     'currencyCode' => $order->get_currency(),
    245                     'id' => $order->get_id(),
    246                     'affiliation' => get_bloginfo('name'),
    247                     'revenue' => $order->get_total(),
    248                     'tax' => $order->get_total_tax(),
    249                     'shipping' => $order->get_shipping_total(),
    250                     'coupon' => $coupons,
    251                     'products' => $products
    252                 ]);
    253             }
    254         }
    255     }
    256 
    257     public function transaction(): void
    258     {
    259         if (is_order_received_page()) {
    260             $orderId = empty($_GET['order']) ? ($GLOBALS['wp']->query_vars['order-received'] ? $GLOBALS['wp']->query_vars['order-received'] : 0) : absint($_GET['order']);
    261             $orderId_filter = apply_filters('woocommerce_thankyou_order_id', $orderId);
    262 
    263             if ($orderId_filter != '') {
    264                 $orderId = $orderId_filter;
    265             }
    266 
    267             $ecommerceActive = $this->googleTagManagerService->isEcommerceActive();
    268             $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    269 
    270             if ($ecommerceActive && !$enhancedEcommerceActive) {
    271                 $order = wc_get_order($orderId);
    272                 $products_tmp = $order->get_items();
    273 
    274                 $products = array();
    275 
    276                 foreach ($products_tmp as $product) {
    277                     if ($product->get_variation_id() == 0) {
    278                         $id = $product->get_data()['product_id'];
    279                     } else {
    280                         $id = $product->get_data()['product_id'] . '-' . $product->get_variation_id();
    281                     }
    282 
    283                     $categories = get_the_terms($id, 'product_cat');
    284 
    285                     $output = [];
    286                     if ($categories) {
    287                         foreach ($categories as $category) {
    288                             $output[] = $category->name;
    289                         }
    290                     }
    291 
    292                     $productCategories = implode(", ", $output);
    293 
    294                     if ($this->googleTagManagerService->isConversionWithVat()) {
    295                         $productPrice = ($product->get_total() + $product->get_total_tax()) / $product->get_quantity();
    296                     } else {
    297                         $productPrice = $product->get_total() / $product->get_quantity();
    298                     }
    299 
    300                     $products[] = [
    301                         'name' => $product->get_name(),
    302                         'sku' => (string)$id,
    303                         'category' => $productCategories,
    304                         'quantity' => (int)$product->get_quantity(),
    305                         'price' => (string)$productPrice,
    306                     ];
    307 
    308                 }
    309 
    310                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/transaction.php', [
    311                     'transactionId' => $order->get_id(),
    312                     'transactionAffiliation' => get_bloginfo('name'),
    313                     'transactionTotal' => $order->get_total(),
    314                     'transactionTax' => $order->get_total_tax(),
    315                     'transactionShipping' => $order->get_shipping_total(),
    316                     'transactionProducts' => json_encode($products, JSON_NUMERIC_CHECK)
    317                 ]);
    318             }
    319         }
     213        if ((!$ecommerceActive || $enhancedEcommerceActive) || !ControllerHelper::isOrderReceivedPage()) {
     214            return;
     215        }
     216
     217        $orderId = empty($_GET['order']) ? ($GLOBALS['wp']->query_vars['order-received'] ? $GLOBALS['wp']->query_vars['order-received'] : 0) : absint($_GET['order']);
     218        $orderId_filter = apply_filters('woocommerce_thankyou_order_id', $orderId);
     219
     220        if ($orderId_filter != '') {
     221            $orderId = $orderId_filter;
     222        }
     223
     224        $order = wc_get_order($orderId);
     225        $products_tmp = $order->get_items();
     226
     227        $products = array();
     228
     229        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     230
     231        foreach ($products_tmp as $product) {
     232            $itemData = ProductPurchaseHelper::getProductDetails($product, $compositeIdEnabled);
     233
     234            if ($itemData['parentId'] === null) {
     235                $productCategories = ProductHelper::getProductCategories($itemData['id']);
     236            } else {
     237                $productCategories = ProductHelper::getProductCategories($itemData['parentId']);
     238            }
     239
     240            if ($this->googleTagManagerService->isConversionWithVat()) {
     241                $productPrice = ($product->get_total() + $product->get_total_tax()) / $product->get_quantity();
     242            } else {
     243                $productPrice = $product->get_total() / $product->get_quantity();
     244            }
     245
     246            $products[] = [
     247                'name' => $product->get_name(),
     248                'sku' => (string)$itemData['fullId'],
     249                'category' => $productCategories,
     250                'quantity' => (int)$product->get_quantity(),
     251                'price' => (string)$productPrice,
     252            ];
     253        }
     254
     255        echo TemplateLoader::getTemplate(__DIR__ . '/templates/transaction.php', [
     256            'transactionId' => $order->get_id(),
     257            'transactionAffiliation' => get_bloginfo('name'),
     258            'transactionTotal' => $order->get_total(),
     259            'transactionTax' => $order->get_total_tax(),
     260            'transactionShipping' => $order->get_shipping_total(),
     261            'transactionProducts' => json_encode($products, JSON_NUMERIC_CHECK)
     262        ]);
    320263    }
    321264
    322265    public function productDetailView(): void
    323266    {
    324         if (is_product()) {
    325             $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    326 
    327             if ($enhancedEcommerceActive) {
    328                 $id = get_queried_object_id();
    329                 $product = wc_get_product($id);
    330 
    331                 $categories = get_the_terms($id, 'product_cat');
    332 
    333                 $output = [];
    334                 if ($categories) {
    335                     foreach ($categories as $category) {
    336                         $output[] = $category->name;
    337                     }
    338                 }
    339 
    340                 $productCategories = implode(", ", $output);
    341 
    342                 $productData[] = [
    343                     'name' => $product->get_name(),
    344                     'id' => (string)$id,
    345                     'price' => $product->get_price(),
    346                     'category' => $productCategories,
    347                 ];
    348 
    349                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/productDetailView.php', [
     267        // Not enabled in settings or is product page
     268        if (!$this->googleTagManagerService->isEnhancedEcommerceActive() || !ControllerHelper::isProduct()) {
     269            return;
     270        }
     271
     272        $pricesWithVat = $this->googleTagManagerService->isConversionWithVat();
     273        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     274
     275        $itemData = ProductDetailRequestHelper::getProductDataForViewDetailRequest($pricesWithVat, $compositeIdEnabled);
     276
     277        $productCategories = $itemData['categories'];
     278
     279        $productData[] = [
     280            'name' => $itemData['name'],
     281            'id' => (string)$itemData['fullId'],
     282            'price' => (string)$itemData['prices']['price'],
     283            'category' => $productCategories,
     284        ];
     285
     286        // Product click
     287        // If user come from my url === clicked on product url
     288        $pageWasRefreshed = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
     289        if (!$pageWasRefreshed) {
     290            if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER["HTTP_REFERER"], get_site_url()) !== false) {
     291
     292                echo TemplateLoader::getTemplate(__DIR__ . '/templates/productClick.php', [
    350293                    'currency' => get_woocommerce_currency(),
    351294                    'products' => json_encode($productData, JSON_NUMERIC_CHECK)
    352295                ]);
    353 
    354                 //If user come from my url === clicked on product url
    355                 $pageWasRefreshed = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
    356                 if (!$pageWasRefreshed) {
    357                     if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER["HTTP_REFERER"], get_site_url()) !== false) {
    358 
    359                         echo TemplateLoader::getTemplate(__DIR__ . '/templates/productClick.php', [
    360                             'currency' => get_woocommerce_currency(),
    361                             'products' => json_encode($productData, JSON_NUMERIC_CHECK)
    362                         ]);
    363                     }
    364                 }
    365             }
    366         }
     296            }
     297        }
     298
     299        // Detail view
     300        echo TemplateLoader::getTemplate(__DIR__ . '/templates/productDetailView.php', [
     301            'currency' => get_woocommerce_currency(),
     302            'products' => json_encode($productData, JSON_NUMERIC_CHECK)
     303        ]);
    367304    }
    368305
    369306    public function checkoutManipulation(): void
    370307    {
    371         $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    372 
    373         if ($enhancedEcommerceActive) {
    374             echo TemplateLoader::getTemplate(__DIR__ . '/templates/checkoutManipulation.php');
    375         }
     308        if (!$this->googleTagManagerService->isEnhancedEcommerceActive() || ControllerHelper::isNotCartOrCheckout()) {
     309            return;
     310        }
     311
     312        echo TemplateLoader::getTemplate(__DIR__ . '/templates/checkoutManipulation.php');
    376313    }
    377314
    378315    public function checkoutStep(): void
    379316    {
    380         if (is_cart() || is_checkout()) {
    381             $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    382 
    383             if ($enhancedEcommerceActive) {
    384                 global $woocommerce;
    385 
    386                 $products = [];
    387 
    388                 foreach ($woocommerce->cart->cart_contents as $key => $item) {
    389                     $id = ProductHelper::getMergedIdFromCartItem($item);
    390 
    391                     $category = get_the_terms($id, "product_cat");
    392                     $categories = [];
    393 
    394                     if ($category) {
    395                         foreach ($category as $term) {
    396                             $categories[] = $term->name;
    397                         }
    398                     }
    399 
    400                     $name = $item['data']->get_name();
    401                     $category = implode(', ', $categories);
    402                     $price = $item['data']->get_price();
    403 
    404                     $products[] = [
    405                         'id' => $id,
    406                         'name' => $name,
    407                         'category' => $category,
    408                         'price' => (string)$price,
    409                     ];
    410                 };
    411 
    412                 if (is_cart()) {
    413                     $step = 1;
    414                 } else if (is_checkout()) {
    415                     $step = 2;
    416                 } else {
    417                     $step = 0;
    418                 }
    419 
    420                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/checkoutStep.php', [
    421                     'currency' => get_woocommerce_currency(),
    422                     'step' => $step,
    423                     'products' => json_encode($products, JSON_NUMERIC_CHECK)
    424                 ]);
    425             }
    426         }
     317        if (!$this->googleTagManagerService->isEnhancedEcommerceActive() || ControllerHelper::isNotCartOrCheckout()) {
     318            return;
     319        }
     320
     321        global $woocommerce;
     322
     323        $products = [];
     324
     325        $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     326        $withVat = $this->googleTagManagerService->isConversionWithVat();
     327
     328        foreach ($woocommerce->cart->cart_contents as $key => $item) {
     329            $itemData = ProductCartHelper::getIdsFromCartItem($item, $compositeIdEnabled);
     330
     331            if ($itemData['parentId'] === null) {
     332                $productCategories = ProductHelper::getProductCategories($itemData['id']);
     333            } else {
     334                $productCategories = ProductHelper::getProductCategories($itemData['parentId']);
     335            }
     336
     337            $wcProduct = wc_get_product($itemData['id']);
     338
     339            $productPrices = Mergado\Helper\ProductHelper::getProductPrices($wcProduct, $withVat);
     340
     341            $name = $item['data']->get_name();
     342
     343            $products[] = [
     344                'id' => (string)$itemData['fullId'],
     345                'name' => $name,
     346                'category' => $productCategories,
     347                'price' => (string)$productPrices['price'],
     348            ];
     349        };
     350
     351        if (ControllerHelper::isCart()) {
     352            $step = 1;
     353        } else if (ControllerHelper::isCheckout()) {
     354            $step = 2;
     355        } else {
     356            $step = 0;
     357        }
     358
     359        echo TemplateLoader::getTemplate(__DIR__ . '/templates/checkoutStep.php', [
     360            'currency' => get_woocommerce_currency(),
     361            'step' => $step,
     362            'products' => json_encode($products, JSON_NUMERIC_CHECK)
     363        ]);
    427364    }
    428365
    429366    public function viewList(): void
    430367    {
    431         if (is_shop() || is_product_category() || is_search()) {
    432             $enhancedEcommerceActive = $this->googleTagManagerService->isEnhancedEcommerceActive();
    433 
    434             if ($enhancedEcommerceActive) {
    435                 if (is_shop()) {
    436                     $list_name = 'shop';
    437                 } else if (is_product_category()) {
    438                     $list_name = get_queried_object()->name;
    439                 } else if (is_search()) {
    440                     $list_name = 'search';
    441                 } else {
    442                     $list_name = '';
    443                 }
    444 
    445                 $viewListItemsCount = $this->googleTagManagerService->getViewListItemsCount();
    446 
    447                 echo TemplateLoader::getTemplate(__DIR__ . '/templates/viewList.php', [
    448                     'currency' => get_woocommerce_currency(),
    449                     'listName' => $list_name,
    450                     'viewListItemsCount' => (int)$viewListItemsCount
    451                 ]);
    452             }
     368        if (!$this->googleTagManagerService->isEnhancedEcommerceActive()) {
     369            return;
     370        }
     371
     372        if (ControllerHelper::isShop() || ControllerHelper::isProductCategory() || ControllerHelper::isSearch()) {
     373            if (ControllerHelper::isShop()) {
     374                $list_name = 'shop';
     375            } else if (ControllerHelper::isProductCategory()) {
     376                $list_name = get_queried_object()->name;
     377            } else if (ControllerHelper::isSearch()) {
     378                $list_name = 'search';
     379            } else {
     380                $list_name = '';
     381            }
     382
     383            $viewListItemsCount = $this->googleTagManagerService->getViewListItemsCount();
     384            $compositeIdEnabled = $this->googleTagManagerService->isCompositeIdEnabled();
     385            $conversionWithVat = $this->googleTagManagerService->isConversionWithVat();
     386
     387            echo TemplateLoader::getTemplate(__DIR__ . '/templates/viewList.php', [
     388                'currency' => get_woocommerce_currency(),
     389                'listName' => $list_name,
     390                'viewListItemsCount' => (int)$viewListItemsCount,
     391                'compositeIdEnabled' => $compositeIdEnabled,
     392                'conversionWithVat' => $conversionWithVat,
     393            ]);
    453394        }
    454395    }
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleTagManager/templates/addToCart.php

    r2998630 r3185508  
    88          'products': [{
    99            'name': "<?php echo $name ?>",
    10             'id': "<?php echo $id ?>",
    11             'price': '<?php echo $price ?>',
     10            'id': <?php echo $id ?>,
     11            'price': <?php echo $price ?>,
    1212            'quantity': <?php echo $quantity ?>,
    1313            'category': "<?php echo $category ?>"
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleTagManager/templates/addToCartAjax.php

    r2998630 r3185508  
    2525            'products': [{
    2626              'name': prodData['name'],
    27               'id': prodData['full_id'],
    28               'price': prodData['price'],
     27              'id': <?php if($compositeIdEnabled): ?>prodData['full_id']<?php else: ?>prodData['base_id']<?php endif; ?>,
     28              'price': <?php if($conversionWithVat): ?>prodData['price_with_vat']<?php else: ?>prodData['price_without_vat']<?php endif; ?>,
    2929              'quantity': 1,
    3030              'category': prodData['category']
  • mergado-marketing-pack/trunk/src/Service/External/Google/GoogleTagManager/templates/viewList.php

    r2998630 r3185508  
    1414
    1515        items[key] = {};
    16         items[key]['id'] = values['full_id'];
     16        items[key]['id'] = <?php if($compositeIdEnabled):?>values['full_id']<?php else: ?>values['base_id']<?php endif;?>;
    1717        items[key]['name'] = values['name'];
    1818        items[key]['list'] = list_name;
    1919        items[key]['category'] = values['category'];
    2020        items[key]['position'] = key;
    21         items[key]['price'] = values['price'];
     21        items[key]['price'] = <?php if($conversionWithVat): ?>values['price_with_vat']<?php else: ?>values['price_without_vat']<?php endif; ?>;
    2222        // items[]['brand'] = values[''];
    2323        // items[]['variant'] = values[''];
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/GtagIntegrationHelper.php

    r3041908 r3185508  
    33namespace Mergado\Service\External\Google\Gtag;
    44
    5 use Mergado\Helper\AddToCartAjaxHelper;
     5use Mergado\External\WoodmartCompatibilityTools;
     6use Mergado\Helper\ControllerHelper;
     7use Mergado\Helper\ProductDetailRequestHelper;
     8use Mergado\Helper\ProductHelper;
     9use Mergado\Helper\ProductPurchaseHelper;
    610use Mergado\Service\CookieService;
    711use Mergado\Service\External\Argep\ArgepService;
     
    1418use Mergado\Utils\TemplateLoader;
    1519use WC_Product;
    16 use WpOrg\Requests\Cookie;
     20use WC_Product_Variable;
    1721
    1822class GtagIntegrationHelper
     
    6367    }
    6468
    65     public static function addToCart($sendTo, $withVat = null) : string
     69    public static function addToCart($sendTo, bool $withVat, bool $compositeIdEnabled, $googleAdsBusinessType = null) : string
    6670    {
    6771        $result = '';
    6872
    69         // Disable if woodmart theme because of incompatibility
    70         if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], AddToCartAjaxHelper::getDisabledActionNames(), true)) {
    71             return $result;
    72         }
    73 
    74         if (isset($_POST['add-to-cart'])) {
    75             $product = wc_get_product($_POST['add-to-cart']);
    76 
    77             if ($product->get_type() === 'grouped') { // Check if grouped product
    78                 if (!isset($_POST['groupedGTAG'])) { // Check if request is duplicate (grouped products send two posts with same data)
    79                     $_POST['groupedGTAG'] = true; // Set variable that disable next call of same addToCart
    80 
    81                     foreach ($_POST['quantity'] as $id => $quantity) {
    82                         $product = wc_get_product($id); // No need for ID changing because only simple products can be added on grouped page
    83                         $categories = get_the_terms($id, 'product_cat');
    84 
    85                         $output = [];
    86                         if ($categories) {
    87                             foreach ($categories as $category) {
    88                                 $output[] = $category->name;
    89                             }
    90                         }
    91 
    92                         $productCategories = join(", ", $output);
    93 
    94                         $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/addToCart.php';
    95 
    96                         $templateVariables = [
    97                             'currency' => get_woocommerce_currency(),
    98                             'itemsId' => $id,
    99                             'itemsName' => $product->get_name(),
    100                             'itemsCategory' => $productCategories,
    101                             'itemsQuantity' => $_POST['quantity'],
    102                             'itemsPrice' => self::getProductPrices($product, $withVat),
    103                             'itemsGoogleBusinessVertical' => 'retail',
    104                             'sendTo' => $sendTo,
    105                         ];
    106 
    107                         $result .= TemplateLoader::getTemplate($templatePath, $templateVariables);
    108                     }
    109                 }
    110             } else {
    111                 $product = wc_get_product($_POST['add-to-cart']);
    112 
    113                 if (isset($_POST['variation_id']) && $_POST['variation_id'] && $_POST['variation_id'] !== '') {
    114                     $id = $product->get_data()['id'] . '-' . $_POST['variation_id'];
    115                 } else {
    116                     $id = $product->get_data()['id'];
    117                 }
    118 
    119                 $categories = get_the_terms($id, 'product_cat');
    120 
    121                 $output = [];
    122                 if ($categories) {
    123                     foreach ($categories as $category) {
    124                         $output[] = $category->name;
    125                     }
    126                 }
    127 
    128                 $productCategories = implode(", ", $output);
    129 
    130                 $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/addToCart.php';
     73        $products = ProductDetailRequestHelper::getAddToCartProductsFromRequest($withVat, 'groupedGTAG', $compositeIdEnabled);
     74
     75        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/addToCart.php';
     76
     77        foreach($products as $productData) {
     78            $variables = [
     79                'currency' => get_woocommerce_currency(),
     80                'itemsId' => $productData['fullId'],
     81                'itemsName' => $productData['name'],
     82                'itemsCategory' => $productData['categories'],
     83                'itemsQuantity' => $_POST['quantity'],
     84                'itemsPrice' => $productData['prices']['price'],
     85                'sendTo' => $sendTo,
     86            ];
     87
     88            if ($googleAdsBusinessType) {
     89                $variables['itemsGoogleBusinessVertical'] = $googleAdsBusinessType;
     90            }
     91
     92            $result .= TemplateLoader::getTemplate($templatePath, $variables);
     93        }
     94
     95        return $result;
     96    }
     97
     98    public static function productDetailView($sendTo, bool $withVat, bool $compositeIdEnabled, $googleAdsBusinessType = null): void
     99    {
     100        // Not product detail page
     101        if (!ControllerHelper::isProduct()) {
     102            return;
     103        }
     104
     105        $itemData = ProductDetailRequestHelper::getProductDataForViewDetailRequest($withVat, $compositeIdEnabled);
     106
     107        $productData = [
     108            'id' => $itemData['fullId'],
     109            'name' => $itemData['name'],
     110            'category' => $itemData['categories'],
     111            'price' => $itemData['prices']['price']
     112        ];
     113
     114        if ($googleAdsBusinessType) {
     115            $productData['google_business_vertical'] = $googleAdsBusinessType;
     116        }
     117
     118        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/viewItem.php';
     119
     120        $templateVariables = [
     121            'currency' => get_woocommerce_currency(),
     122            'items' => json_encode($productData, JSON_NUMERIC_CHECK),
     123            'sendTo' => $sendTo,
     124        ];
     125
     126        echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     127
     128        //If user come from my url === clicked on product url
     129        if (isset($_SERVER["HTTP_REFERER"])) {
     130            if (strpos($_SERVER["HTTP_REFERER"], get_site_url()) !== false) {
     131
     132                $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/selectContent.php';
    131133
    132134                $templateVariables = [
    133135                    'currency' => get_woocommerce_currency(),
    134                     'itemsId' => $id,
    135                     'itemsName' => $product->get_name(),
    136                     'itemsCategory' => $productCategories,
    137                     'itemsQuantity' => $_POST['quantity'],
    138                     'itemsPrice' => self::getProductPrices($product, $withVat),
    139                     'itemsGoogleBusinessVertical' => 'retail',
    140                     'sendTo' => $sendTo,
     136                    'contentType' => 'product',
     137                    'items' => json_encode($productData, JSON_NUMERIC_CHECK),
     138                    'sendTo' => $sendTo
    141139                ];
    142140
    143                 $result .= TemplateLoader::getTemplate($templatePath, $templateVariables);
    144             }
    145         }
    146 
    147         return $result;
    148     }
    149 
    150     public static function productDetailView($sendTo, $withVat = null): void
    151     {
    152         if (is_product()) {
    153             $id = get_queried_object_id();
    154             $product = wc_get_product($id);
    155 
    156             $categories = get_the_terms($id, 'product_cat');
    157 
    158             $output = [];
    159             if ($categories) {
    160                 foreach ($categories as $category) {
    161                     $output[] = $category->name;
    162                 }
    163             }
    164 
    165             $productCategories = implode(", ", $output);
    166 
    167             $productData = [
    168                 'id' => $id,
    169                 'name' => $product->get_name(),
    170                 'category' => $productCategories,
    171                 'price' => self::getProductPrices($product, $withVat),
    172                 'google_business_vertical' => 'retail',
    173             ];
    174 
    175             $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/viewItem.php';
    176 
    177             $templateVariables = [
    178                 'currency' => get_woocommerce_currency(),
    179                 'items' => json_encode($productData, JSON_NUMERIC_CHECK),
    180                 'sendTo' => $sendTo
    181             ];
    182 
    183             echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    184 
    185             //If user come from my url === clicked on product url
    186             if (isset($_SERVER["HTTP_REFERER"])) {
    187                 if (strpos($_SERVER["HTTP_REFERER"], get_site_url()) !== false) {
    188 
    189                     $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/selectContent.php';
    190 
    191                     $templateVariables = [
    192                         'currency' => get_woocommerce_currency(),
    193                         'contentType' => 'product',
    194                         'items' => json_encode($productData, JSON_NUMERIC_CHECK),
    195                         'sendTo' => $sendTo
    196                     ];
    197 
    198                     echo TemplateLoader::getTemplate($templatePath, $templateVariables);
    199                 }
    200             }
    201         }
    202     }
    203 
    204     public static function addToCartAjax($sendTo, $withVat = null): void
     141                echo TemplateLoader::getTemplate($templatePath, $templateVariables);
     142            }
     143        }
     144    }
     145
     146    public static function addToCartAjax($sendTo, bool $withVat, bool $compositeIdEnabled, $googleAdsBusinessType = null): void
    205147    {
    206148        $templatePath = __MERGADO_SRC_DIR__ . 'Service/External/Google/Gtag/templates/Universal/addToCartAjax.php';
     
    209151            'currency' => get_woocommerce_currency(),
    210152            'sendTo' => $sendTo,
     153            'compositeIdEnabled' => $compositeIdEnabled,
     154            'googleAdsBusinessType' => $googleAdsBusinessType
    211155        ];
    212156
     
    214158    }
    215159
    216     public static function viewItemList($sendTo, $withVat = null): void
    217     {
    218         if (is_shop()) {
     160    public static function viewItemList($sendTo, bool $withVat, $compositeIdEnabled, $googleAdsBusinessType = null): void
     161    {
     162        if (ControllerHelper::isShop()) {
    219163            $listName = 'shop';
    220         } else if (is_product_category()) {
     164        } else if (ControllerHelper::isProductCategory()) {
    221165            $listName = get_queried_object()->name;
    222         } else if (is_search()) {
     166        } else if (ControllerHelper::isSearch()) {
    223167            $listName = 'search';
    224168        } else {
     
    233177            'listName' => $listName,
    234178            'sendTo' => $sendTo,
     179            'compositeIdEnabled' => $compositeIdEnabled,
     180            'googleAdsBusinessType' => $googleAdsBusinessType
    235181        ];
    236182
     
    339285    }
    340286
    341     /**
    342      * Helpers
    343      */
    344 
    345     public static function getProductPrices(WC_Product $product, $withVat = null): float
    346     {
    347         if ($withVat === null) {
    348             $price = $product->get_price(); //Default GA price
    349         } else if ($withVat) {
    350             $price = wc_get_price_including_tax($product); // Price after product discount
    351         } else {
    352             $price = wc_get_price_excluding_tax($product); // Price after product discount
    353         }
    354 
    355         return (float)$price;
     287    public static function getOrderProductsForAds($orderId, $isCompositeIdEnabled, $isConversionWithVat, $googleAdsBusinessType = null) : array
     288    {
     289        $order = wc_get_order($orderId);
     290        $products_tmp = $order->get_items();
     291
     292        $products = [];
     293
     294        foreach ($products_tmp as $product) {
     295            $itemData = ProductPurchaseHelper::getProductDetails($product, $isCompositeIdEnabled);
     296
     297            if ($itemData['parentId'] === null) {
     298                $productCategories = ProductHelper::getProductCategories($itemData['id']);
     299            } else {
     300                $productCategories = ProductHelper::getProductCategories($itemData['parentId']);
     301            }
     302
     303            if ($isConversionWithVat) {
     304                $productPrice = ($product->get_total() + $product->get_total_tax()) / $product->get_quantity();
     305            } else {
     306                $productPrice = $product->get_total() / $product->get_quantity();
     307            }
     308
     309            $product = [
     310                'id' => $itemData['fullId'],
     311                'name' => $product->get_name(),
     312                'category' => $productCategories,
     313                'quantity' => (int)$product->get_quantity(),
     314                'price' => (string)$productPrice,
     315            ];
     316
     317            if ($googleAdsBusinessType) {
     318                $product['google_business_vertical'] = $googleAdsBusinessType;
     319            }
     320
     321            $products[] = $product;
     322        }
     323
     324        return $products;
    356325    }
    357326}
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/addPaymentInfo.php

    r2998630 r3185508  
    44
    55    const ga4_payment_methods = <?php echo json_encode($payment_methods) ?>;
     6
     7    document.body.addEventListener('click', function(event) {
     8      if (event.target.matches('input[type="radio"][name*="radio-control-wc-payment-method-options"]')) {
     9
     10        let val = event.target.value
     11
     12        if (typeof ga4_payment_methods[val] !== "undefined") {
     13          val = ga4_payment_methods[val];
     14        }
     15
     16        sendAddPaymentInfo(val);
     17      }
     18    });
    619
    720    document.body.addEventListener('mergado_payment_method_selected', () => {
     
    1225      }
    1326
     27      sendAddPaymentInfo(val);
     28    });
     29
     30    function sendAddPaymentInfo(paymentType)
     31    {
    1432      let eventObject = {...window.mmp.ga4_cart_data.cart_data};
    1533      eventObject['coupon'] = window.mmp.ga4_cart_data.coupon;
    16       eventObject['payment_type'] = val;
     34      eventObject['payment_type'] = paymentType;
    1735
    1836      gtag('event', 'add_payment_info', eventObject);
    19     });
     37    }
    2038  });
    2139</script>
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/addShippingInfo.php

    r2998630 r3185508  
    66    var $ = jQuery;
    77
     8    // Shortcode
    89    $('body').on('click', 'input[type="radio"][name*="shipping_method"]', function () {
    910      mmp.ga4.sendShipping += 1;
    1011    });
    1112
    12     document.body.addEventListener('mergado_shipping_updated', sendShippingInfo);
    13     document.body.addEventListener('mergado_updated_checkout', sendShippingInfo);
     13    document.body.addEventListener('mergado_shipping_updated', sendShippingInfoShortcode);
     14    document.body.addEventListener('mergado_updated_checkout', sendShippingInfoShortcode);
    1415
    1516    const isCheckout = document.querySelector('body.woocommerce-checkout');
     
    1718    if (isCheckout !== null) {
    1819      mmp.ga4.sendShipping += 1;
    19       sendShippingInfo();
     20      sendShippingInfoShortcode();
    2021    }
     22
     23    // Gutenberg block
     24    document.body.addEventListener('click', function(event) {
     25      if (event.target.matches('label[class*="wc-block-components-radio-control__option"] input[type="radio"]')) {
     26        mmp.ga4.sendShipping += 1;
     27        submitShippingInfo(event.target.value);
     28      }
     29    });
    2130  });
    2231
    23   function sendShippingInfo() {
     32  function sendShippingInfoShortcode() {
    2433    if (mmp.ga4.sendShipping !== 0) {
    25       const ga4_shipping_methods = <?php echo json_encode($shipping_methods) ?>;
    2634      const input = document.querySelector('input[type="radio"][name*="shipping_method"]:checked');
    2735
    2836      if (input) {
    2937          let val = input.value;
     38          submitShippingInfo(val)
     39      }
     40    }
     41  }
    3042
    31           if (typeof ga4_shipping_methods[val] !== "undefined") {
    32             val = ga4_shipping_methods[val];
    33           }
     43  function submitShippingInfo(shippingType)
     44  {
     45    if (mmp.ga4.sendShipping !== 0) {
     46      const ga4_shipping_methods = <?php echo json_encode($shipping_methods) ?>;
     47
     48      if (typeof ga4_shipping_methods[shippingType] !== "undefined") {
     49          const val = ga4_shipping_methods[shippingType];
    3450
    3551          let eventObject = {...window.mmp.ga4_cart_data.cart_data};
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/addToCart.php

    r2998630 r3185508  
    11<script>
     2  <?php if($eventEnabled): ?>
     3  // Default event
    24  document.addEventListener("DOMContentLoaded", function () {
    35    gtag('event', 'add_to_cart', <?php echo json_encode($eventObject) ?>);
    46  });
     7  <?php endif; ?>
     8
     9  // Custom event for users
     10  document.addEventListener("mmp_ga4_add_to_cart", function () {
     11    gtag('event', 'add_to_cart', <?php echo json_encode($eventObject) ?>);
     12  }, {once: true});
    513</script>
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/addToCartAjax.php

    r2998630 r3185508  
    2727
    2828      var item = {
    29         "item_id": prodData['full_id'].toString(),
     29        "item_id": <?php if($compositeIdEnabled): ?>prodData['full_id'].toString()<?php else: ?>prodData['base_id'].toString()<?php endif; ?>,
    3030        "item_name": prodData['name'],
    3131        "item_category": prodData['category'],
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/removeFromCart.php

    r2998630 r3185508  
    99    var checkit = window.check_var_ga4;
    1010
     11    // Shortcode
    1112    if (checkit === undefined) {
    1213      window.check_var_ga4 = 1;
     
    1415
    1516      jQuery('body').on('click', '.product-remove a.remove', function () {
    16         var href = jQuery(this).attr('href');
    17         var eventObject = <?php echo json_encode($eventObject) ?>;
     17        const href = jQuery(this).attr('href');
     18        const item = mergadoProductsData[href];
    1819
    19         var item = mergadoProductsData[href];
     20        submitRemoveFromCart(item);
     21      });
     22    }
    2023
    21         eventObject['items'] = item;
    22         eventObject['value'] = (item['price'] * item['quantity']) - (item['discount'] * item['quantity']);
     24    function submitRemoveFromCart(item) {
     25      let eventObject = <?php echo json_encode($eventObject) ?>;
    2326
    24         gtag('event', 'remove_from_cart', eventObject);
    25       });
     27      eventObject['items'] = item;
     28      eventObject['value'] = (item['price'] * item['quantity']) - (item['discount'] * item['quantity']);
     29
     30      gtag('event', 'remove_from_cart', eventObject);
    2631    }
    2732  });
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/selectContentVariation.php

    r2998630 r3185508  
    11<script>
    2   document.addEventListener('DOMContentLoaded', function () {
     2  window.onload = function () {
    33    jQuery( ".single_variation_wrap" ).on( "show_variation", function ( event, variation ) {
    4         var defaultEvent = <?php echo json_encode($eventObject) ?>;
     4      var defaultEvent = <?php echo json_encode($eventObject) ?>;
    55
    6         var productId = document.querySelector('.variations_form.cart').getAttribute('data-product_id');
    7         var variationId = variation['variation_id'];
     6      var productId = document.querySelector('.variations_form.cart').getAttribute('data-product_id');
     7      var variationId = variation['variation_id'];
    88
    9         defaultEvent['item_id'] = (productId + '-' + variationId).toString();
     9      <?php if($compositeIdEnabled): ?>
     10      defaultEvent['item_id'] = (productId + '-' + variationId).toString();
     11      <?php else: ?>
     12      defaultEvent['item_id'] = variationId.toString();
     13      <?php endif; ?>
    1014
    11         gtag('event', 'select_content', defaultEvent);
    12       });
    13   });
     15      gtag('event', 'select_content', defaultEvent);
     16    });
     17  };
    1418</script>
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/GA4/viewItemList.php

    r2998630 r3185508  
    1313
    1414        eventObject['items'][key] = {
    15           'item_id': values['full_id'].toString(),
     15          'item_id': <?php if($compositeIdEnabled): ?>values['full_id'].toString()<?php else: ?>values['base_id'].toString()<?php endif; ?>,
    1616          'item_name': values['name'],
    1717          'index': key,
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/Universal/addToCart.php

    r2998630 r3185508  
    1010          "quantity": <?php echo $itemsQuantity ?>,
    1111          "price": "<?php echo $itemsPrice ?>",
    12           "google_business_vertical": "<?php echo $itemsGoogleBusinessVertical ?>"
     12          <?php if ($itemsGoogleBusinessVertical): ?>"google_business_vertical": "<?php echo $itemsGoogleBusinessVertical ?>"<?php endif ?>
    1313        }
    1414      ],
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/Universal/addToCartAjax.php

    r2998630 r3185508  
    1919      var prodData = JSON.parse(prodElement.find('[data-metadata-product-list]').attr('data-metadata-product-list'));
    2020
    21         <?php if($withVat === null):?>
    22           const price = prodData['price'];
    23           <?php elseif($withVat): ?>
    24           const price = prodData['price_with_vat'];
    25             <?php else: ?>
    26           const price = prodData['price_without_vat'];
    27         <?php endif; ?>
     21      <?php if($withVat): ?>
     22        const price = prodData['price_with_vat'];
     23      <?php else: ?>
     24        const price = prodData['price_without_vat'];
     25      <?php endif; ?>
    2826
    2927      gtag('event', 'add_to_cart', {
     
    3129        "items": [
    3230          {
    33             "id": prodData['full_id'],
     31            "id": <?php if($compositeIdEnabled): ?>prodData['full_id']<?php else: ?>prodData['base_id']<?php endif; ?>,
    3432            "name": prodData['name'],
    3533            "category": prodData['category'],
    3634            "quantity": 1,
    3735            "price": price,
    38             "google_business_vertical": "retail"
     36            <?php if ($googleAdsBusinessType): ?>"google_business_vertical": "<?php echo $googleAdsBusinessType ?>"<?php endif; ?>
    3937          }
    4038        ],
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/Universal/checkoutManipulation.php

    r2998630 r3185508  
    3939    //});
    4040
    41     //Payment
     41    //Payment - shortcode
    4242    $('body').on('payment_method_selected', function () {
    4343      // $('body').on('click', 'input[type="radio"][name="payment_method"]', function () {
     
    5959    });
    6060
     61    //Payment - gutenberg
     62    const gua_payment_methods = <?php echo json_encode($payment_methods) ?>;
    6163
    62     //Delivery
     64    document.body.addEventListener('click', function(event) {
     65      if (event.target.matches('input[type="radio"][name*="radio-control-wc-payment-method-options"]')) {
     66        let step;
     67        let val = event.target.value
     68
     69
     70        if (typeof gua_payment_methods[val] !== "undefined") {
     71          val = gua_payment_methods[val];
     72        }
     73
     74        if ($('body').hasClass('woocommerce-checkout')) {
     75          step = 1;
     76        } else {
     77          step = 0;
     78        }
     79
     80        gtag('event', 'set_checkout_option', {
     81          "checkout_step": step,
     82          "checkout_option": "payment method",
     83          "value": val,
     84          "send_to": "<?php echo $sendTo ?>",
     85        });
     86      }
     87    });
     88
     89
     90    //Delivery - shortcode
    6391    // $('body').on('updated_shipping_method', function () {
    6492    $('body').on('click', 'input[type="radio"][name*="shipping_method"]', function () {
     
    79107      });
    80108    });
     109
     110    //Delivery - gutenberg
     111    document.body.addEventListener('click', function(event) {
     112      if (event.target.matches('div[class*="wc-block-components-shipping-rates-control"] input[type="radio"]')) {
     113        var step;
     114        let val = event.target.value
     115
     116        if ($('body').hasClass('woocommerce-checkout')) {
     117          step = 1;
     118        } else {
     119          step = 0;
     120        }
     121
     122        gtag('event', 'set_checkout_option', {
     123          "checkout_step": step,
     124          "checkout_option": "shipping_method",
     125          "value": val,
     126          "send_to": "<?php echo $sendTo ?>",
     127        });
     128      }
     129    });
    81130  });
    82131</script>
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/Universal/purchased.php

    r2998630 r3185508  
    99      "shipping": <?php echo $shipping ?>,
    1010      "items": <?php echo $items ?>,
    11       "google_business_vertical": "<?php echo $googleBusinessVertical ?>",
    1211      "send_to": "<?php echo $sendTo ?>",
    1312    });
  • mergado-marketing-pack/trunk/src/Service/External/Google/Gtag/templates/Universal/viewItemList.php

    r2998630 r3185508  
    1010        var values = JSON.parse($(value).attr('data-metadata-product-list'));
    1111
    12         <?php if($withVat === null):?>
    13           const price = values['price'];
    14         <?php elseif($withVat): ?>
     12        <?php if($withVat): ?>
    1513          const price = values['price_with_vat'];
    1614        <?php else: ?>
     
    1917
    2018        items[key] = {};
    21         items[key]['id'] = values['full_id'];
     19        items[key]['id'] = <?php if($compositeIdEnabled): ?>values['full_id']<?php else: ?>values['base_id']<?php endif; ?>;
    2220        items[key]['name'] = values['name'];
    2321        items[key]['list_name'] = list_name;
     
    2523        items[key]['list_position'] = key;
    2624        items[key]['price'] = price;
    27         items[key]['google_business_vertical'] = 'retail';
     25        <?php if ($googleAdsBusinessType): ?> items[key]['google_business_vertical'] = '<?php echo $googleAdsBusinessType?>';<?php endif; ?>
    2826        // items[]['brand'] = values[''];
    2927        // items[]['variant'] = values[''];
  • mergado-marketing-pack/trunk/src/Service/External/Sklik/SklikServiceIntegration.php

    r3134668 r3185508  
    33namespace Mergado\Service\External\Sklik;
    44
     5use Mergado\Helper\ControllerHelper;
    56use Mergado\Service\CookieService;
    67use Mergado\Traits\SingletonTrait;
     
    7071        $phone = null;
    7172
    72         if (is_order_received_page()) {
     73        if (ControllerHelper::isOrderReceivedPage()) {
    7374            global $wp;
    7475
  • mergado-marketing-pack/trunk/src/Service/MigrationService.php

    r2998630 r3185508  
    2929            }
    3030        }
    31 
    3231    }
    3332
     
    3736    protected function migrationList(): void
    3837    {
     38        // Initial DB version ( "false" if it is the first run after installation )
    3939        $initialDbVersion = get_option(self::MERGADO_DB_VERSION, false);
    4040
    4141        MigrationUtils::migrateAlwaysWithoutVersionChange('2.0.0');
    4242
    43         MigrationUtils::migrateOnlyOnExactOrLowerVersion('2.1.5', $initialDbVersion);
    44         MigrationUtils::migrate('2.3.0');
    45         MigrationUtils::migrate('3.0.0');
    46         MigrationUtils::migrate('3.3.0');
    47         MigrationUtils::migrate('3.3.3');
    48         MigrationUtils::migrate('3.4.0');
    49         MigrationUtils::migrate('3.5.0');
     43        MigrationUtils::migrateOnExactOrLowerVersionAndSkipNewInstallations('2.1.5', $initialDbVersion);
     44        MigrationUtils::migrateAlways('2.3.0');
     45        MigrationUtils::migrateAlways('3.0.0');
     46        MigrationUtils::migrateAlways('3.3.0');
     47        MigrationUtils::migrateAlways('3.3.3');
     48        MigrationUtils::migrateAlways('3.4.0');
     49        MigrationUtils::migrateAlways('3.5.0');
     50
     51        MigrationUtils::migrateOnExactOrLowerVersionAndSkipNewInstallations('4.0.0', $initialDbVersion, null,true);
     52        MigrationUtils::migrateAlways('4.0.0', 'v4.0.0_a');
    5053    }
    5154}
  • mergado-marketing-pack/trunk/src/Utils/MigrationUtils.php

    r2998630 r3185508  
    1111     *
    1212     * @param string $version
     13     * @param string|null $migrationFileName
    1314     * @return void
    1415     */
    15     public static function migrate(string $version): void
     16    public static function migrateAlways(string $version, string $migrationFileName = null, bool $skipDbVersionUpdate = false): void
    1617    {
    17         if(!get_option(MigrationService::MERGADO_DB_VERSION) || get_option(MigrationService::MERGADO_DB_VERSION) < $version) {
    18             include __MERGADO_MIGRATIONS_DIR__ . sprintf('v%s.php', $version);
    19             self::updateDbVersion($version);
     18        $currentDbVersion = self::getCurrentDbVersion();
     19
     20        if(!$currentDbVersion || $currentDbVersion < $version) {
     21
     22            if ($migrationFileName) {
     23                include __MERGADO_MIGRATIONS_DIR__ . sprintf('%s.php', $migrationFileName);
     24            } else {
     25                include __MERGADO_MIGRATIONS_DIR__ . sprintf('v%s.php', $version);
     26            }
     27
     28            if (!$skipDbVersionUpdate) {
     29                self::updateDbVersion($version);
     30            }
    2031        }
    2132    }
     
    2334    /**
    2435     * Run specific migration for site (if multisite, apply to all)
    25      * Do not execute migration on new instalations
     36     * Do not execute migration on new installations
    2637     *
    2738     *
    2839     * @param string $version
    29      * @param $initalDbVersion
     40     * @param string $initalDbVersion
     41     * @param string|null $migrationFileName
    3042     * @return void
    3143     */
    32     public static function migrateOnlyOnExactOrLowerVersion(string $version, $initalDbVersion): void
     44    public static function migrateOnExactOrLowerVersionAndSkipNewInstallations(string $version, string $initalDbVersion, string $migrationFileName = null, bool $skipDbVersionUpdate = false): void
    3345    {
    34         if((PLUGIN_VERSION === $version && get_option(MigrationService::MERGADO_DB_VERSION) !== $version) || (get_option(MigrationService::MERGADO_DB_VERSION) !== false && get_option(MigrationService::MERGADO_DB_VERSION) < $initalDbVersion)) {
    35             include __MERGADO_MIGRATIONS_DIR__ . sprintf('v%s.php', $version);
    36             self::updateDbVersion($version);
     46        $currentDbVersion = self::getCurrentDbVersion();
     47
     48        if((PLUGIN_VERSION === $version && $currentDbVersion !== $version)
     49            || ($currentDbVersion !== false && $currentDbVersion < $initalDbVersion)) {
     50
     51            if ($migrationFileName) {
     52                include __MERGADO_MIGRATIONS_DIR__ . sprintf('%s.php', $migrationFileName);
     53            } else {
     54                include __MERGADO_MIGRATIONS_DIR__ . sprintf('v%s.php', $version);
     55            }
     56
     57            if (!$skipDbVersionUpdate) {
     58                self::updateDbVersion($version);
     59            }
    3760        }
    3861    }
     
    4265     *
    4366     * @param string $version
     67     * @param string|null $migrationFileName
    4468     * @return void
    4569     */
    46     public static function migrateAlwaysWithoutVersionChange(string $version): void
     70    public static function migrateAlwaysWithoutVersionChange(string $version, string $migrationFileName = null): void
    4771    {
    48         include __MERGADO_MIGRATIONS_DIR__ . sprintf('v%s.php', $version);
     72        if ($migrationFileName) {
     73            include __MERGADO_MIGRATIONS_DIR__ . sprintf('%s.php', $migrationFileName);
     74        } else {
     75            include __MERGADO_MIGRATIONS_DIR__ . sprintf('v%s.php', $version);
     76        }
    4977    }
    5078
Note: See TracChangeset for help on using the changeset viewer.