Cherrycake
ExamplesGithub
version 2.x alpha
version 2.x alpha
  • Introduction
  • Status
  • Changelog
  • Migration
  • Architecture
    • Basics
    • Modules
    • Classes
    • Lifecycle
      • Deep lifecycle
    • Performance
    • Security
    • Patterns
      • Files structure
    • Items
    • Server requirements
  • Guide
    • Getting started
      • Skeleton start
      • Docker start
    • Modules guide
    • Classes guide
    • Actions guide
      • Complex actions
      • Variable path components
      • Accept GET or POST parameters
      • Getting the URL of an action
      • Cached actions
      • Brute force attacks
    • Patterns guide
      • Passing variables to a pattern
      • Nested patterns
      • Cached patterns
    • Cache guide
      • Time To Live
      • Using cache
      • Lists
      • Queues
      • Pools
    • Database guide
      • Basic queries
      • Prepared queries
      • Cached queries
      • Cache key naming
      • Removing queries from cache
    • Items guide
      • Item cache
      • Item lists
      • Items custom filters
      • Items custom ordering
      • Mixing filters and ordering
      • Items with relationships
      • Items cache
    • HtmlDocument guide
    • Css and Javascript guide
      • Modules injecting CSS and JavaScript
    • Session guide
    • Login guide
      • Creating a complete login workflow
    • Locale guide
      • Multilingual texts
      • Domain based site localization
    • Log guide
      • Loading Log events from the database
    • Stats guide
      • Stats events with additional dimensions
      • Loading Stats events from the database
    • Janitor guide
      • Janitor tasks configuration files
    • Command line interface
    • Debugging
  • Reference
    • Core modules
      • Actions
        • Actions methods
      • Browser
      • Cache
        • Cache methods
      • Css
        • Css methods
      • Database
      • Email
      • Errors
      • HtmlDocument
        • HtmlDocument methods
      • ItemAdmin
      • Janitor
        • Janitor methods
      • Javascript
        • Javascript methods
      • Locale
        • Locale methods
      • Log
        • Log methods
      • Login
        • Login methods
      • Output
        • Output methods
      • Patterns
        • Patterns methods
      • Security
        • Security methods
      • Session
        • Session methods
      • Stats
        • Stats methods
      • SystemLog
      • TableAdmin
      • Translation
      • Validate
    • Core classes
      • Action
        • Action methods
        • Action properties
      • AjaxResponseJson
      • BasicObject
        • BasicObject methods
      • CacheProvider
        • CacheProvider methods
      • Color
      • DatabaseProvider
        • DatabaseProvider methods
      • DatabaseResult
        • DatabaseResult methods
        • DatabaseResult properties
      • DatabaseRow
      • Engine
        • Engine methods
        • Engine properties
      • Gradient
      • Item
        • Item methods
        • Item properties
      • Items
        • Items methods
        • Items properties
      • Image
      • JanitorTask
        • JanitorTask methods
        • JanitorTask properties
      • LogEvent
        • LogEvent methods
        • LogEvent Properties
      • LogEvents
        • LogEvents methods
      • Module
        • Module methods
        • Module properties
      • Response
      • Request
        • Request methods
      • RequestParameter
        • RequestParameter methods
      • RequestPathComponent
        • RequestPathComponent methods
      • Result
      • StatsEvent
        • StatsEvent properties
      • StatsEvents
        • StatsEvents methods
      • SystemLogEvent
        • SystemLogEvent methods
        • SystemLogEvent properties
      • SystemLogEvents
        • SystemLogEvents methods
  • Code conventions
  • License
  • Extras
Powered by GitBook
On this page

Was this helpful?

  1. Guide
  2. Stats guide

Stats events with additional dimensions

PreviousStats guideNextLoading Stats events from the database

Last updated 3 years ago

Was this helpful?

Adding additional dimensions to a class allows you to keep track of the event in relation to a certain identifier. The best way to understand this is via an example:

Imagine you want to trigger a StatsEvent every time a user in your web app logs in. A simple way of doing this would be to create a StatsEventUserLogin class just like we saw in the main section:

<?php

namespace CherrycakeApp;

class StatsEventUserLogin extends \Cherrycake\Stats\StatsEvent {
	protected $timeResolution = \Cherrycake\Stats\STATS_EVENT_TIME_RESOLUTION_DAY;
	protected $typeDescription = "User login";
}

To trigger this StatsEvent in the example we saw in the section, we would do it in the doLogin method, like this:

function doLogin($request) {
    global $e;
    $result = $e->Login->doLogin($request->email, $request->password);
    if (
        $result == \Cherrycake\Login\LOGIN_RESULT_FAILED_UNKNOWN_USER
        ||
        $result == \Cherrycake\Login\LOGIN_RESULT_FAILED_WRONG_PASSWORD
    ) {    
        $e->Output->setResponse(new \Cherrycake\Actions\ResponseTextHtml([
            "code" => \Cherrycake\Output\RESPONSE_OK,
            "payload" => $e->HtmlDocument->header()."Login error".$e->HtmlDocument->footer()
        ]));
    }
    else {
        $e->Stats->trigger(new StatsEventUserLogin);
        
        $e->Output->setResponse(new \Cherrycake\Actions\Response([
            "code" => \Cherrycake\Outut\RESPONSE_REDIRECT_FOUND,
            "url" => $e->Actions->getAction("loginGuideHome")->request->buildUrl()
        ]));
    }
}

But what if we wanted to keep track of the times each individual user logs in? That's exactly what an additional dimension would do. In this case, the additional dimension would be the user's id.

To add the user id as an additional dimension to the StatsEventUserLogin class, we would modify it like this:

<?php

namespace CherrycakeApp;

class StatsEventUserLogin extends \Cherrycake\Stats\StatsEvent {
    protected $timeResolution = \Cherrycake\Stats\STATS_EVENT_TIME_RESOLUTION_DAY;
    protected $typeDescription = "User login";
    protected $isSecondaryId = true;
    protected $secondaryIdDescription = "User id";

    function loadInline($data = false) {
        if ($data["userId"] ?? false)
            $this->secondary_id = $data["userId"];		
        return parent::loadInline($data);
    }
}

Notice we've added the $isSecondaryId and $secondaryIdDescription properties, and we overloaded the StatsEvent::loadInline method to retrieve the passed userId key and assign it to the secondary_id property. Don't forget to call the parent constructor at the end there.

So now, when triggering the StatsEventUserLogin event, we can pass the user's id like this:

$e->Stats->trigger(new StatsEventUserLogin(["userId" => $e->Login->user->id]));

You can create another additional dimension by setting the $isTertiaryId and $tertiaryIdDescription properties, and updating the loadInline method accordingly.

Using additional dimensions like this will add multiple rows to the database per each time frame and different dimension value, take into account that this will of course cause the stats table to grow a lot bigger.

See this example working in the site.

StatsEvent
Stats guide
Creating a complete login workflow
Cherrycake documentation examples