Skip to content

Commit

Permalink
Merge pull request #7 from zumba/readme-docs
Browse files Browse the repository at this point in the history
Initial fleshing out readme
  • Loading branch information
jrbasso committed Apr 29, 2016
2 parents 0d46d99 + b885993 commit 3db7ef7
Showing 1 changed file with 262 additions and 4 deletions.
266 changes: 262 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,267 @@

This is a moderately thin PHP API for [Amplitude](https://amplitude.com/), powerful enough to do what you need without getting in the way. Designed to work well in 2 main scenarios:

* **Same user & Amplitude App** - When you are tracking possibly multiple events, all for the same user, all for the same Amplitude app. This library provides a singleton method that allows persisting the user and API key.
* **Multiple Users / Same or Different Amplitude Apps** - For times you may need to log multiple events for a lot of different users, possibly using different amplitude apps.
* **Multiple Events using Same User & Amplitude App** - When you are tracking possibly multiple events, all for the same user, all for the same Amplitude app. This library provides a Singleton instance that allows initializing the API key and user info once for the page load, that gets used for any events logged during that page load.
* **Multiple Events across Multiple Users and possibly multiple Amplitude Apps** - For times you may need to log multiple events for a lot of different users, possibly using different amplitude apps.

# Work in Progress
# Example

```php
// After User is Initialized in your application, set the user info in Amplitude that you want to track (minimally
// the user identifier or device identifier, and of course your Amplitude App API key)
$amplitude = \Zumba\Amplitude\Amplitude::getInstance();
$amplitude->init('APIKEY', 'johnny@example.com')
->addUserProperties([
'dob' => '1980-11-04',
'name' => 'Johnny 5'
])
// Only call this once API Key and user ID or device ID is set
->logQueuedEvents();

// -- Meanwhile, in another part of the code... --

// Anywhere else in your application that needs to log an event
// This will even work if called before the above code initializes Amplitude! If that is case, it will queue it
// and send the event when logQueuedEvents() is called. If Amplitude is already initialized, this will send the event
// to Amplitude right away (only uses a queue for early-logged events)
\Zumba\Amplitude\Amplitude::getInstance()
->queueEvent('EVENT TYPE');

// Can pass in an array for the second parameter to set event properties
\Zumba\Amplitude\Amplitude::getInstance()
->queueEvent('SECOND EVENT', ['quantity' => 1, 'price' => 15.32, 'Custom Property' => 'Widgets']);

// This is a simple example to get you started, see the rest of the readme for more examples
```

# Logging Anonymous Users

Since this is a PHP SDK, there are a lot of options for tracking Anonymous users. Since this could be run in CLI mode or as a cron job, this SDK does not handle sessions for you.

Your application will need to figure out a way to track users across multiple page loads, chances are your app is already doing this with PHP sessions or something like it.

Once you have that unique identifier that allows an anonymous user to be tracked between page loads, set that as the `deviceId`. Do this for both logged in users and anonymous users, that way once a user is logged in their past events will be linked to the user.

```php
// After your application has set up the session (for instance in your bootloader or similar), initialize Amplitude:
$amplitude = \Zumba\Amplitude\Amplitude::getInstance();
// Notice we are not setting second parameter here for user ID, we will do that below if it is available
$amplitude->init('APIKEY');

// Can use the PHP session ID, or alternatively, any unique string your application uses to track sessions
$sessionId = session_id();

// Keep track of whether we have a session or user ID
$canLogEvents = false;
if (!empty($sessionId)) {
$amplitude->setDeviceId($sessionId);
$canLogEvents = true;
}
// Presumes $applicationUserId set prior to this by your application
if (!empty($applicationUserId)) {
$amplitude->setUserId($applicationUserId);
$canLogEvents = true;
}
if (!empty($userData)) {
// If you have other user properties, set them as well... They will be set on the first event sent to Amplitude
$amplitude->setUserProperties($userData);
}

if ($canLogEvents) {
// Make sure to send any events that may have gotten queued early
$amplitude->logQueuedEvents();
} else {
// Do not have a user ID or device ID for this page load, so set `optOut`, to prevent amplitude from trying
// to send events (since it won't work without user or device ID)
$amplitude->setOptOut(true);
}

// -- Meanwhile, in another part of the code... --

// Just queue events as normal
\Zumba\Amplitude\Amplitude::getInstance()->queueEvent('EVENT');

```
# Events

We have made the library very flexible, in terms of giving you options for how to set up the event to be sent to Amplitude. Use the method that best suites your own preferences and project needs.

## Just Send It!

The first option is the easiest, the one used in the main example. Just call either `queueEvent` or `logEvent` with the event type and event properties if there are any.
```php
// Send just event with no event properties:
\Zumba\Amplitude\Amplitude::getInstance()
->queueEvent('EVENT-NAME');

// Send event and add a property:
\Zumba\Amplitude\Amplitude::getInstance()
->queueEvent('EVENT-NAME', ['property1' => 'value1']);
```

## Using Event Object

You have the option to use an event object to set up the event, if this is more convenient for your use case. The example of how to do this is below:

```php
// Get the next event that will be queued or sent:
$event = \Zumba\Amplitude\Amplitude::getInstance()->event();

// Set up the even there, by setting properties...
$event->eventType = 'EVENT-NAME';

// Queue or send the event - since we got the event using the event method, it will be the one used on the next
// queue or send, no need to pass it back in.
\Zumba\Amplitude\Amplitude::getInstance()->queueEvent();
```

### Setting event properties
As far as setting the event properties on the event object, you have a few options once you have that `$event` object:

```php
// First, probably the most common, you can use the magic set methods to just set the property like this:
$event->propertyName = 'property value';

// Set using set(), handy for property names that are invalid as PHP variables:
$event->set('Property name with Space', 'property value');

// Set can be chained:
$event->set('prop1', 'val1')
->set('prop2', 'val2')
->set('prop3', 'val3');

// Pass in array of properties for the first parameter:
$event->set(
[
'prop1' => 'val1',
'prop2' => 'val2',
]
);

```
### Unsetting event properties
If a property has already been set on an event, you can unset it.

```php
// For non-standard property names, use the unsetProperty method:
$event->unsetProperty('My Location');

// Magic unset also works
unset($event->productId);
```

### Sending or Queuing the Event

Once you have set all the event properties, you can then send or queue the event, just by calling `$amplitude->queueEvent()` or `$amplitude->sendEvent()`.

Note: If you just created a new `Event` object, before calling `queueEvent()` or `logEvent()`, you must pass that event into amplitude like this:
```php
$event = new \Zumba\Amplitude\Event();

// Set event properties here

// Pass the event into amplitude and queue it
\Zumba\Amplitude\Amplitude::getInstance()
->event($event)
->queueEvent();
```

If however, you used the event method to get the event, no need to pass it back into Amplitude.
```php
$event = \Zumba\Amplitude\Amplitude::getInstance()->event();

// Set event properties here

// Send that event
\Zumba\Amplitude\Amplitude::getInstance()->queueEvent();
```
In other words, when dealing with the `Event` object directly, it must have passed through Amplitude's `event()` method one way or the other before attempting to call `queueEvent()` or `logEvent()`.

### Tip: No Need to Pass Around Event Object
If you need to set up an event across different parts of the code, you ***could*** pass that event around, but you don't ***have to***, as `Amplitude` keeps track of the next event object to be sent or queued. So you could do something like this:

```php
$event = \Zumba\Amplitude\Amplitude::getInstance()->event();
$event->eventType = 'Complicated Event';

// -- Meanwhile, in another part of the code... --
// As long as the event has not yet been sent or queued up, you can get it and change it as needed:
$event = \Zumba\Amplitude\Amplitude::getInstance()->event();
$event->deviceId = 'DEVICE ID';

// Just remember, once finished setting up the event, call queueEvent() or logEvent() once.
\Zumba\Amplitude\Amplitude::getInstance()->queueEvent();
```

### Don't forget the eventType

When using the event object, remember that the `eventType` must be set one way or another before the event is queued or logged.

```php
// Either set it this way:
$event->eventType = 'EVENT';

// OR set it when logging/queuing the event:
\Zumba\Amplitude\Amplitude::getInstance()
->queueEvent('EVENT');
```

Note that setting it when calling `queueEvent()` or `logEvent()` will overwrite the `eventType` if it is already set in the event object, but any other properties set on the event will remain intact.

### Custom Event Factory

Say you wanted to make some sort of factory that is cranking out events to send, maybe even each with it's own user ID already set... You could do something like this:
```php
$amplitude = \Zumba\Amplitude\Amplitude::getInstance()
->init('APIKEY');
foreach ($eventFactory->getEvents() as $event) {
$amplitude->event($event)
->queueEvent();
}
```

## Using `event($array)` - Quickly set event properties
For times that you just want to quickly set some properties on the next event that will be queued or sent, but aren't ready to actually send or queue the event yet, you can pass in an array of properties into the `$amplitude->event()` method.

```php
// Convinience way to quickly add properties to an event, just pass in array of properties to the event method:
\Zumba\Zumba\Amplitude::getInstance()->event(
[
'eventProp' => 'Event Value',
'productId' => 'acme-widget-45',
'price' => 15.32,
]
);

// The above is equivalent of:
$event = \Zumba\Zumba\Amplitude::getInstance()->event();
$event->set(
[
'eventProp' => 'Event Value',
'productId' => 'acme-widget-45',
'price' => 15.32,
]
);
```

# queueEvent() vs. logEvent()

The difference?

* Both:
* Require the eventType to be set and non-empty.
* `logEvent()`:
* Requires API Key to be set, will throw exception if not set yet.
* Requires either userId or deviceId to be set, will throw exception if not set either on the amplitude instance, or on the event itself.
* Always sends the event at the time it is called, assuming requirements met.
* `queueEvent()`:
* Does NOT require API key to be set first.
* Does NOT require userId or deviceId to be set first.
* If either of those are not set, OR if there are still un-sent events in the queue, it will add the event to an internal queue. This queue does not persist across page loads, if any remain in the queue they are lost if not send during that page load.
* If those requirements ARE set, and there is nothing in the queue, it sends immediately. So if you have already initialized Amplitude, set the API key and the userId or deviceId, when you call `queueEvent()` it will behave exactly the same as calling `logEvent()` would.
* If you do use this, immediately after initializing Amplitude (setting the API key and either the `userId` or `deviceId` in amplitude), be sure to call `$amplitude->logQueuedEvents()` to send any events that are on the queue. If nothing is on the queue, no worries, nothing happens.

Why would you ever use `logEvent()` instead of `queueEvent()`? The use case for that is when sending events for multiple users, in such a way that you are initializing the data then sending right away. Using `logEvent()` in that case you would catch right away if something is not initialized right away (it will throw a logic exception), instead of "quietly" starting up a queue that you may never deal with if not expecting there to be one.

**TL;DR:** If you know that you will always be initializing amplitude before calling an event, you can use `logEvent()` directly. Otherwise use `queueEvent()` and just be sure to call `$amplitude->logQueuedEvents()` once you do have Amplitude initialized and user data set.

We're still working documenting all the things and working out any kinks, but should have version 1.0.0 ready soon, stay tooned!

0 comments on commit 3db7ef7

Please sign in to comment.