Giter Site home page Giter Site logo

aawnu / php-ga4 Goto Github PK

View Code? Open in Web Editor NEW
43.0 4.0 7.0 336 KB

PHP Wrapper for Google Analytics 4 with Server Side Tracking

License: MIT License

PHP 100.00%
ga4 google-analytics-4 php-library server-side-tracking sst google-analytics php php8 gdpr composer-library

php-ga4's Introduction

php-ga4's People

Contributors

8ctopus avatar aawnu avatar dependabot[bot] avatar jordykouters avatar tobz-nz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

php-ga4's Issues

Server only tracking, user tracking?

I implemented tracking on a new property that tracks servers ONLY.

I see the pageviews correctly, but I don't see the users.
It's as if the events were not launched by users and therefore I can't understand their behavior, they all seem to be unconnected events.

I call the library and set setClientId to a unique value for each user.

Am I doing something wrong or is it not possible to have the concept of user by tracking only servers?

Move support up to PHP 8+

Official support for PHP 7 will soon end. Updating the supported versions of this library will provide better options for type checking and stricter data control.

  • v1.0 will be moved into own branch for legacy support of executable errors | composer 1.0.*
  • Future versions with updated support will be released as v1.1.x | composer ^1.1

https://www.php.net/supported-versions.php

Add import method of array values

I would like to add arraycreation of events and items, where it is currently done through chained events only.

Currently:

use AlexWestergaard\PhpGa4\Event;

$event = Event\ViewCart::new()
    ->setCurrency('EUR')
    ->setValue(10.00);

I would like to also allow:

use AlexWestergaard\PhpGa4\Event;

$event = Event\ViewCart::fromArray([
    'currency' => 'DKK', // eq ViewCart::$currency
    'value' => 10.00', // eq ViewCart::$value
]);

It should also have proper validation for sub-model imports, so that ViewCart::addItem(Item $item) would be triggered on <items=>Object|Array> either by executing addItem if object or import through item::fromArray()->toArray() if Array.

the purpose of this should be the ability to build larger datasets and then import as array post-process rather than in-process.

Add document title

Hello!

I need your help, i send data with your extension but my Views box in analytics is empty, how to add document title param to your code?

kรฉp

Status of page_view event

The page_view event is not officially supported by measurement protocol, maybe that should be reflected in the README.

Enable debug_mode support?

This is a really nice library, thank you for building it. One thing I noticed is I couldn't find a way to enable debug_mode in events (not to be confused with the debug url).

This is supposed to allow measurement protocol events to show up in the "Debug View" in the Admin Console, making it easier to see in real-time if the right stuff is getting into Analytics.

If this is somehow supported and I just missed it please let me know. Otherwise it would be a cool setting to see added.

php-ga4: ^1.1 - Events are not appearing in GA4 realtime .

Hi there,
I'm trying to use your package to record GA4 backend events and I'm not having much luck. I'm using Laravel 8 with php 8.1.
The code seems to execute (exception code does not fire), however the events are not appearing, specifically add_to_cart. Here is my code...

`
$measurementId = env('GA4_MEASUREMENT_ID');
$ga4ApiSecret = env('GA4_API_KEY');

    $clientID = null;

    if(isset($_COOKIE['_ga'])) {
        $gaCookie = $_COOKIE['_ga'];
        $clientID = explode('.', $gaCookie)[2];
    }

    try {
        $events = Converter::parseEvents($event);
        Analytics::new($measurementId, $ga4ApiSecret)
            ->setClientId($clientID)
            ->addEvent(...$events)
            ->post();
    } catch (Exception\Ga4Exception $exception) {
        // Handle exception
        Log::alert('GA4 Event failed');
        Log::alert($exception);
        Log::alert($event);

    }

`

My event looks like this...

array ( 'add_to_cart' => array ( 'currency' => 'AUD', 'value' => 38, 'items' => array ( 0 => array ( 'item_id' => 29, 'item_name' => '500g Musk Scrolls', 'price' => 38, 'quantity' => 1, ), ), ), )

The GA4 credentials and event data appear to be fine as I have recorded the event with another package but I like the way this package calls are made and it better fits my application.

Can you suggest how I can debug the problem? Many thanks

User location

In your experience, what happens if:

  • user comes to your website and gets a new session from gtag.js
  • then user buys and your website backend sends a purchase event using this library.

In which country will the purchase take place? The country of the user's IP address or the country of your server's IP address?

Convert GTAG Parameters into Server-Side Parameters too

Studying the PageView request made by GTAG in JavaScript it seems that parameter names are the same as V1 but with limited parameter scope.

https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters

GET Parameters

v: 2
tid: G-XXXXX
gtm: 2oe7d0
_p: 1486226803
_z: ccd.v9B
cid: 00000.000000
ul: en-us
sr: 1920x1080
sid: 1657899578
sct: 3
seg: 1
dl: http%3A%2F%2F127.0.0.1%2F
dr: http%3A%2F%2F127.0.0.1%2F
dt: Chttr.link
_s: 1

Body Parameters

en=page_view&_ee=1
en=scroll&epn.percent_scrolled=90&_et=8

Refactor structure and use of facades/abstraction

In order to give developers more freedom of how they want functionality to work inside each model, the type checks should depend on method access with stronger data validation rather than expect base functionality to not be overwritten.

  • Update folder structure for simpler code organization
  • Replace use of (abstract) models to interfaces for simpler point of entry
  • Update event facades to use grouping of reusable variable facades (more code, simpler bulk editing)

rationale for Analytics::new()

Hi again Alex,

What is the rationale for Analytics::new('G-XXXXXX', 'eMVPMEcTbaI1iuWtrPw', true) instead of new Analytics('G-XXXXXX', 'eMVPMEcTbaI1iuWtrPw', true)?

If you follow the code then you will see there is 3 layers.

If you follow the code then you will see there is 3 layers.

Analytics[ Events[ Items ] ] ]

Add src/Item.php to your src/Event/BeginCheckout.php event, then add the event to src/Analytics.php.

You should not be able to addItem on Analytics, if this is doable then I will fix it later.

Originally posted by @aawnu in #55 (comment)

sorry i really dont understand what you mean. how do i add items to my events?

in your begincheckout class you do have this

  public function addItem(Facade\Type\ItemType $item)
    {
        $this->items[] = $item->toArray();
        return $this;
    }

and i did add it.

$analytics->addItem([
                'item_id' => 'bla bla',
                'currency'=> 'USD',
                'price'   =>'60.00',
                'quantity'=> 1
            ]);

Problem with Event Refund

In GA4 documentation there are two types of Refund - partial and full.
When I use event for Full refund, I need to set Items, but only transaction_id should be required. Items (selected) are required for partial refund.

Client id must have been created by gtag.js?

I have found this in the google doc:

In order for an event to be valid, it must have a client_id that has already been used to send an event from gtag.js. You will need to capture this ID client-side and include it in your call to the Measurement Protocol. In send an event to your property, we use "client_id" as the client_id. You will need to replace this with a real client_id that comes from gtag.js.

Does your practical experience corroborate the quote or not?

If affirmative, I think it should be added to the doc.

I'm adding the stackoverflow question that made me think about this if you're interested https://stackoverflow.com/questions/69105735/google-analytics-4-measurement-protocol-api-used-without-gtag-js-or-firebase

Add core events of GA.js/GTAG.js as SST-Events

begin checkout

Hi, is this how to do a begin checkout in the backend?

use AlexWestergaard\PhpGa4\Exception;
use AlexWestergaard\PhpGa4\Analytics;
use AlexWestergaard\PhpGa4\Event\BeginCheckout;
use AlexWestergaard\PhpGa4\Item;

try {
            // If gtag.js, this can be the _ga or _gid cookie
            // This can be any kind of session identifier
            $session = $_COOKIE['_ga'] ?? $_COOKIE['_gid'] ?? $_COOKIE['PHPSESSID'];

            $analytics = Analytics::new( 'G-XXXXXXXX','xYzzX_xYzzXzxyZxX')
            ->setClientId($session);

            $analytics->addEvent(new BeginCheckout);
            $analytics->setCurrency('usd');
            $analytics->setValue('60.00');
            $analytics->addItem([
                'item_id' => 'bla bla',
                'currency'=> 'USD',
                'price'   =>'60.00',
                'quantity'=> 1
            ]);
            $analytics->post();
        } catch (Exception\Ga4Exception $exception) {
            // Handle exception
            if (YII_DEBUG) dd($exception);
            Yii::error($exception);
        }

i'm getting this error

AlexWestergaard\PhpGa4\Exception\Ga4IOException#1
(
    [*:message] => 'Missing required parameter: items'
   .....
   .....

how do i fix this? Thank you.

Update GA4Exception with improved error reporting

Transform GA4Exception to handle stacking on its own until being thrown; avoid having to pass it between classes when throwing is stalled until right before returning/exiting.

This should also make it simpler to use GA4Exception when extending the base Model class for custom event types.

User Properties - Question

Hello, first of all, thank you for the great library.

I've a few questions about the user properties, is anyone able to help me?

  1. GA4 docs isn't very clear about the user-properties, do you know if I can set any key-value there or they've specific user-properties that I can use?
  2. I know that I need to set up those user properties in the GA4 configurations, do you know what happens if I send a request with a user property that wasn't previously set up there? Will that still work fine? And the opposite, if I don't send an expected key?
  3. Do you've any links that might help me to understand better how to use the user-properties? The ones that I found in the GA4 docs weren't useful to understand certain detail.

question: How to get data to show up in debug?

I've been trying without success to get the debug mode working, in order to view events as soon as they are generated in debugView (I have some events that google says are not correct and I would like to figure out why)

https://analytics.google.com/analytics/web/#/a62992619p355170503/admin/debugview/overview

Do you know how to do it? I will be happy to submit a PR for the readme as I believe it will be useful for others.

Here's my sample code:

$clientId = $_COOKIE['_ga'] ?? $_COOKIE['_gid'] ?? null;

if (!$clientId) {
    throw new Exception('GA cookie not set');
}

$debug = true;

$analytics = Analytics::new($trackingId, $apiSecret, $debug)
    ->setClientId($clientId)
    ->setTimestampMicros(time());

$price = 1;
$transactionId = strtoupper(bin2hex(random_bytes(10)));

$purchase = Event\Purchase::new()
    ->setCurrency('USD')
    ->setValue($price)
    ->setTransactionId($transactionId);

$products = [
    [
        'name' => 'ball',
        'amount' => 5.00,
    ], [
        'name' => 'pen',
        'amount' => 5.00,
    ],
];

foreach ($products as $product) {
    $item = Item::new()
        ->setItemName($product['name'])
        ->setQuantity(1)
        ->setPrice($product['amount']);

    $purchase->addItem($item);
}

$analytics->addEvent($purchase);
$analytics->post();

PHP 8.3 support

Please add support for the recently released PHP 8.3.

Thanks.

Item -> item_category - Validation error [VALUE_INVALID]

I think there might be an issue with item_category

Item.php

    public function addItemCategory(string $category)
    {
        $this->item_category[] = $category;
        return $this;
    }

I'm adding a category name like this

$item->addItemCategory( $category->name );

But then I get a validation error

jsonBody: {"non_personalized_ads":false,"client_id":"GA1.1123123123","events":[{"name":"view_item","params":{"currency":"GBP","value":2.6000000000000001,"items":[{"item_id":"443","item_name":"Complete Food Meal","currency":"GBP","item_category":["Food"],"price":2.6000000000000001,"quantity":1}]}}]}

Formatted jsonBody

{
    "non_personalized_ads": false,
    "client_id": "GA1.1123123123",
    "events": [
        {
            "name": "view_item",
            "params": {
                "currency": "GBP",
                "value": 2.6,
                "items": [
                    {
                        "item_id": "443",
                        "item_name": "Complete Food Meal",
                        "currency": "GBP",
                        "item_category": [
                            "Food"
                        ],
                        "price": 2.6,
                        "quantity": 1
                    }
                ]
            }
        }
    ]
}

Response code: 200
URL: https://www.google-analytics.com/debug/mp/collect?measurement_id=G-123&api_secret=XYZ

PHP Fatal error

Uncaught AlexWestergaard\PhpGa4\Exception\Ga4Exception: Validation Message > VALUE_INVALID [events.params.items]: Item param [item_category] has unsupported value. Value [list_value     { values { string_value: "Food" } }] is unsupported list value. in /vendor/alexwestergaard/php-ga4/src/Exception/Ga4Exception.php:77

According to https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtag#view_item_details
item_category should be a string and it allows to add up to 5 indexed item_categoryINDEX params

      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",

I'm happy to update the code to work properly.

Thanks
Michal

README _gid cookie question

I never get the _gid cookie, does it still exist? If not, we should remove it from the readme

$session = $_COOKIE['_ga'] ?? $_COOKIE['_gid'] ?? $_COOKIE['PHPSESSID'];

ask for help

Dear aaw,
i've been working on PHP GA4 but still failed to set logEvent on php
on react this worked

import { getAnalytics, logEvent } from "firebase/analytics";
const analytics = getAnalytics();
logEvent(analytics, 'whatever', { name: 1});

So how to set it by using your library?
Thank you. Regards

Dashboard not reflecting the posted report

I tried posting a pageview, and the code worked without a glitch, but the usage is not reported or shown in the analytics dashboard. Am I doing something wrong?

include_once(__DIR__ . '/vendor/autoload.php');

use AlexWestergaard\PhpGa4\Analytics;
use AlexWestergaard\PhpGa4\Event\PageView;

$clientId = $_COOKIE['_ga'] ?? $_COOKIE['_gid'] ?? $_COOKIE['PHPSESSID'] ?? null;

if(isset($_COOKIE['_ga'])) {
    $gaCookie = $_COOKIE['_ga'];
    $clientID = explode('.', $gaCookie)[2];
}


$event = PageView::new()
->setLanguage('en')
->setScreenResolution('1024x768')
->setPageLocation('/home')
->setPageTitle('Home');

// GA4 Initialize
$analytics = Analytics::new ('G-xxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxx')
->setClientId($clientId)
->setTimestampMicros(time())
->addEvent($event)
->post();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.