Skip to content

Commit

Permalink
starting to move actions from tracker into plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
tsteur committed Jun 17, 2014
1 parent dfc2c92 commit cb6ae9d
Show file tree
Hide file tree
Showing 25 changed files with 384 additions and 184 deletions.
7 changes: 1 addition & 6 deletions core/Db/Schema/Mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,13 @@ public function getTablesCreateSql()
idlink_va INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
idsite int(10) UNSIGNED NOT NULL,
idvisitor BINARY(8) NOT NULL,
server_time DATETIME NOT NULL,
idvisit INTEGER(10) UNSIGNED NOT NULL,
idaction_url_ref INTEGER(10) UNSIGNED NULL DEFAULT 0,
idaction_name_ref INTEGER(10) UNSIGNED NOT NULL,
idaction_event_category INTEGER(10) UNSIGNED DEFAULT NULL,
idaction_event_action INTEGER(10) UNSIGNED DEFAULT NULL,
time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL,
custom_float FLOAT NULL DEFAULT NULL,
PRIMARY KEY(idlink_va),
INDEX index_idvisit(idvisit),
INDEX index_idsite_servertime ( idsite, server_time )
INDEX index_idvisit(idvisit)
) ENGINE=$engine DEFAULT CHARSET=utf8
",

Expand Down
10 changes: 10 additions & 0 deletions core/Plugin/ActionDimension.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ public function shouldHandle()
return false;
}

/**
* @return string|int
* @throws \Exception in case not implemented
*/
public function getActionId()
{
throw new \Exception('You need to overwrite the getActionId method in case you implement the onLookupAction method in class: ' . get_class($this));
}

protected function addSegment(Segment $segment)
{
$sqlSegment = $segment->getSqlSegment();
Expand Down Expand Up @@ -90,6 +99,7 @@ public static function getAllDimensions()
{
$plugins = PluginManager::getInstance()->getLoadedPlugins();
$instances = array();

foreach ($plugins as $plugin) {
foreach (self::getDimensions($plugin) as $instance) {
$instances[] = $instance;
Expand Down
146 changes: 103 additions & 43 deletions core/Tracker/Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use Exception;
use Piwik\Common;
use Piwik\Piwik;
use Piwik\Plugin\ActionDimension;
use Piwik\Plugin\Manager;
use Piwik\Tracker;

/**
Expand All @@ -36,37 +38,71 @@ abstract class Action

const DB_COLUMN_CUSTOM_FLOAT = 'custom_float';

private static $factoryPriority = array(
self::TYPE_PAGE_URL, self::TYPE_SITE_SEARCH, self::TYPE_EVENT, self::TYPE_OUTLINK, self::TYPE_DOWNLOAD
);

/**
* Makes the correct Action object based on the request.
*
* @param Request $request
* @return ActionClickUrl|ActionPageview|ActionSiteSearch
* @return Action
*/
static public function factory(Request $request)
{
$downloadUrl = $request->getParam('download');
if (!empty($downloadUrl)) {
return new ActionClickUrl(self::TYPE_DOWNLOAD, $downloadUrl, $request);
/** @var Action[] $actions */
$actions = self::getAllActions($request);

foreach ($actions as $actionType) {
if (empty($action)) {
$action = $actionType;
continue;
}

$posPrevious = self::getPriority($action);
$posCurrent = self::getPriority($actionType);

if ($posCurrent > $posPrevious) {
$action = $actionType;
}
}

$outlinkUrl = $request->getParam('link');
if (!empty($outlinkUrl)) {
return new ActionClickUrl(self::TYPE_OUTLINK, $outlinkUrl, $request);
if (!empty($action)) {
return $action;
}

$url = $request->getParam('url');
return new ActionPageview($request);
}

private static function getPriority(Action $actionType)
{
$key = array_search($actionType->getActionType(), self::$factoryPriority);

$eventCategory = $request->getParam('e_c');
$eventAction = $request->getParam('e_a');
if(strlen($eventCategory) > 0 && strlen($eventAction) > 0 ) {
return new ActionEvent($eventCategory, $eventAction, $url, $request);
if (!$key) {
return -1;
}
}

$action = new ActionSiteSearch($url, $request);
if ($action->isSearchDetected()) {
return $action;
public function shouldHandle()
{
return false;
}

static private function getAllActions(Request $request)
{
$actions = Manager::getInstance()->findMultipleComponents('Actions', '\\Piwik\\Tracker\\Action');
$instances = array();

foreach ($actions as $action) {
/** @var \Piwik\Tracker\Action $instance */
$instance = new $action($request);

if ($instance->shouldHandle($request)) {
$instances[] = $instance;
}
}
return new ActionPageview($url, $request);

return $instances;
}

/**
Expand All @@ -83,7 +119,7 @@ static public function factory(Request $request)
public function __construct($type, Request $request)
{
$this->actionType = $type;
$this->request = $request;
$this->request = $request;
}

/**
Expand Down Expand Up @@ -118,7 +154,6 @@ public function getCustomFloatValue()
return false;
}


protected function setActionName($name)
{
$name = PageUrl::cleanupString((string)$name);
Expand Down Expand Up @@ -147,7 +182,7 @@ protected function getUrlAndType()
if (!empty($url)) {
// normalize urls by stripping protocol and www
$url = PageUrl::normalizeUrl($url);
return array($url['url'], Tracker\Action::TYPE_PAGE_URL, $url['prefixId']);
return array($url['url'], self::TYPE_PAGE_URL, $url['prefixId']);
}
return false;
}
Expand All @@ -159,7 +194,6 @@ public function getIdActionUrl()
return (int)$idUrl;
}


public function getIdActionUrlForEntryAndExitIds()
{
return $this->getIdActionUrl();
Expand Down Expand Up @@ -223,10 +257,29 @@ public function loadIdsFromLogActionTable()
if(!empty($this->actionIdsCached)) {
return;
}
$actions = $this->getActionsToLookup();

$actions = $this->getActionsToLookup();
$dimensions = ActionDimension::getAllDimensions();

foreach ($dimensions as $dimension) {
if (method_exists($dimension, 'onLookupAction')) {
$field = $dimension->getFieldName();
$value = $dimension->onLookupAction($this->request, $this);

if (empty($field)) {
throw new Exception('Dimension ' . get_class($dimension) . ' does not define a field name');
}

if ($value !== false) {
$actions[$field] = array($value, $dimension->getActionId());
Common::printDebug("$field = $value");
}
}
}

$actions = array_filter($actions, 'count');

if(empty($actions)) {
if (empty($actions)) {
return;
}

Expand All @@ -239,34 +292,41 @@ public function loadIdsFromLogActionTable()
/**
* Records in the DB the association between the visit and this action.
*
* @param int $idVisit is the ID of the current visit in the DB table log_visit
* @param $visitorIdCookie
* @param int $idReferrerActionUrl is the ID of the last action done by the current visit.
* @param $idReferrerActionName
* @param int $timeSpentReferrerAction is the number of seconds since the last action was done.
* It is directly related to idReferrerActionUrl.
* @param Visitor $visitor
*/
public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idReferrerActionName, $timeSpentReferrerAction)
public function record(Visitor $visitor, $idReferrerActionUrl, $idReferrerActionName)
{
$this->loadIdsFromLogActionTable();

$visitAction = array(
'idvisit' => $idVisit,
'idsite' => $this->request->getIdSite(),
'idvisitor' => $visitorIdCookie,
'server_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()),
'idaction_url' => $this->getIdActionUrl(),
'idaction_url_ref' => $idReferrerActionUrl,
'idaction_name_ref' => $idReferrerActionName,
'time_spent_ref_action' => $timeSpentReferrerAction
'idvisit' => $visitor->getVisitorColumn('idvisit'),
'idsite' => $this->request->getIdSite(),
'idvisitor' => $visitor->getVisitorColumn('idvisitor'),
'idaction_url' => $this->getIdActionUrl(),
'idaction_url_ref' => $idReferrerActionUrl,
'idaction_name_ref' => $idReferrerActionName
);

$dimensions = ActionDimension::getAllDimensions();

foreach ($dimensions as $dimension) {
if (method_exists($dimension, 'onNewAction')) {
$value = $dimension->onNewAction($this->request, $this, $visitor);

if ($value !== false) {
$visitAction[$dimension->getFieldName()] = $value;
}
}
}

// idaction_name is NULLable. we only set it when applicable
if($this->isActionHasActionName()) {
if ($this->isActionHasActionName()) {
$visitAction['idaction_name'] = (int)$this->getIdActionName();
}

foreach($this->actionIdsCached as $field => $idAction) {
foreach ($this->actionIdsCached as $field => $idAction) {
$visitAction[$field] = ($idAction === false) ? 0 : $idAction;
}

Expand All @@ -282,9 +342,9 @@ public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idRefe
}

$visitAction = array_merge($visitAction, $customVariables);
$fields = implode(", ", array_keys($visitAction));
$bind = array_values($visitAction);
$values = Common::getSqlStringFieldsArray($visitAction);
$fields = implode(", ", array_keys($visitAction));
$bind = array_values($visitAction);
$values = Common::getSqlStringFieldsArray($visitAction);

$sql = "INSERT INTO " . Common::prefixTable('log_link_visit_action') . " ($fields) VALUES ($values)";
Tracker::getDatabase()->query($sql, $bind);
Expand All @@ -310,8 +370,8 @@ public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idRefe
*/
protected function isActionHasActionName()
{
return in_array($this->getActionType(), array(Tracker\Action::TYPE_PAGE_TITLE,
Tracker\Action::TYPE_PAGE_URL,
Tracker\Action::TYPE_SITE_SEARCH));
return in_array($this->getActionType(), array(self::TYPE_PAGE_TITLE,
self::TYPE_PAGE_URL,
self::TYPE_SITE_SEARCH));
}
}
12 changes: 9 additions & 3 deletions core/Tracker/ActionPageview.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ class ActionPageview extends Action
{
protected $timeGeneration = false;

function __construct($url, Request $request)
function __construct(Request $request)
{
parent::__construct(Action::TYPE_PAGE_URL, $request);

$url = $request->getParam('url');
$this->setActionUrl($url);

$actionName = $request->getParam('action_name');
Expand All @@ -41,12 +42,17 @@ protected function getActionsToLookup()
);
}

function getCustomFloatValue()
public function getCustomFloatValue()
{
return $this->request->getPageGenerationTime();
}

protected function cleanupActionName($actionName)
public function shouldHandle()
{
return true;
}

private function cleanupActionName($actionName)
{
// get the delimiter, by default '/'; BC, we read the old action_category_delimiter first (see #1067)
$actionCategoryDelimiter = isset(Config::getInstance()->General['action_category_delimiter'])
Expand Down
13 changes: 6 additions & 7 deletions core/Tracker/Visit.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,7 @@ public function handle()
try {
$this->handleExistingVisit($visitor, $action, $visitIsConverted);
if (!is_null($action)) {
$action->record($this->visitorInfo['idvisit'],
$this->visitorInfo['idvisitor'],
$idReferrerActionUrl,
$idReferrerActionName,
$this->visitorInfo['time_spent_ref_action']
);
$action->record($visitor, $idReferrerActionUrl, $idReferrerActionName);
}
} catch (VisitorNotFoundInDb $e) {

Expand Down Expand Up @@ -203,7 +198,7 @@ public function handle()
) {
$this->handleNewVisit($visitor, $action, $visitIsConverted);
if (!is_null($action)) {
$action->record($this->visitorInfo['idvisit'], $this->visitorInfo['idvisitor'], 0, 0, 0);
$action->record($visitor, 0, 0);
}
}

Expand Down Expand Up @@ -240,7 +235,10 @@ protected function handleExistingVisit($visitor, $action, $visitIsConverted)

$valuesToUpdate = $this->getExistingVisitFieldsToUpdate($visitor, $action, $visitIsConverted);

// TODO we should not have to sync this->visitorInfo and $visitor columns.
// TODO it should be its own dimension
$this->visitorInfo['time_spent_ref_action'] = $this->getTimeSpentReferrerAction();
$visitor->setVisitorColumn('time_spent_ref_action', $this->visitorInfo['time_spent_ref_action']);

// update visitorInfo
foreach ($valuesToUpdate AS $name => $value) {
Expand Down Expand Up @@ -322,6 +320,7 @@ protected function handleNewVisit($visitor, $action, $visitIsConverted)

$idVisit = $this->insertNewVisit( $this->visitorInfo );

$visitor->setVisitorColumn('idvisit', $idVisit);
$this->visitorInfo['idvisit'] = $idVisit;
$this->visitorInfo['visit_first_action_time'] = $this->request->getCurrentTimestamp();
$this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp();
Expand Down
3 changes: 0 additions & 3 deletions piwik.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/PageUrl.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/TableLogAction.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Action.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionClickUrl.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionEvent.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionPageview.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionSiteSearch.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Request.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Referrer.php';
require_once PIWIK_INCLUDE_PATH . '/core/Tracker/VisitExcluded.php';
Expand Down
6 changes: 0 additions & 6 deletions plugins/API/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,15 @@
use Piwik\DataTable\Filter\ColumnDelete;
use Piwik\DataTable\Row;
use Piwik\Date;
use Piwik\Filesystem;
use Piwik\Menu\MenuReporting;
use Piwik\Menu\MenuTop;
use Piwik\Metrics;
use Piwik\Period;
use Piwik\Period\Range;
use Piwik\Piwik;
use Piwik\Plugin\ActionDimension;
use Piwik\Plugin\VisitDimension;
use Piwik\Plugins\CoreAdminHome\CustomLogo;
use Piwik\Tracker\Action;
use Piwik\Tracker\GoalManager;
use Piwik\Translate;
use Piwik\Version;
use Piwik\WidgetsList;

require_once PIWIK_INCLUDE_PATH . '/core/Config.php';

Expand Down
Loading

0 comments on commit cb6ae9d

Please sign in to comment.