From 23fcf598e04ec33d3c1b4f541a573b013a741b9d Mon Sep 17 00:00:00 2001 From: Thomas Steur Date: Tue, 17 Jun 2014 23:05:17 +0200 Subject: [PATCH] moved more code from core to plugins, eg Visit, Actions and some Conversion columns --- core/Db/Schema/Mysql.php | 23 -- core/Plugin/VisitDimension.php | 49 ++- core/Tracker/Action.php | 4 +- core/Tracker/GoalManager.php | 105 +----- core/Tracker/Referrer.php | 301 ------------------ core/Tracker/Settings.php | 30 +- core/Tracker/Visit.php | 51 ++- core/Tracker/Visitor.php | 11 +- piwik.php | 1 - plugins/CoreHome/Columns/IdSite.php | 11 + .../CoreHome/Columns/VisitLastActionTime.php | 1 - .../Columns/VisitorDaysSinceFirst.php | 11 + .../Columns/VisitorDaysSinceOrder.php | 11 + plugins/CoreHome/Columns/VisitorReturning.php | 12 + plugins/CoreHome/Columns/VisitsCount.php | 11 + plugins/Referrers/Columns/Base.php | 91 ++++++ plugins/Referrers/Columns/Keyword.php | 11 + plugins/Referrers/Columns/ReferrerName.php | 11 + plugins/Referrers/Columns/ReferrerType.php | 11 + .../Columns/ReferrerVisitServerDate.php | 35 ++ plugins/UserCountry/Columns/City.php | 11 + plugins/UserCountry/Columns/Country.php | 24 ++ plugins/UserCountry/Columns/Latitude.php | 11 + plugins/UserCountry/Columns/Longitude.php | 11 + plugins/UserCountry/Columns/Region.php | 11 + plugins/UserSettings/Columns/PluginCookie.php | 37 +++ .../UserSettings/Columns/PluginDirector.php | 37 +++ plugins/UserSettings/Columns/PluginFlash.php | 37 +++ plugins/UserSettings/Columns/PluginGears.php | 37 +++ plugins/UserSettings/Columns/PluginJava.php | 37 +++ plugins/UserSettings/Columns/PluginPdf.php | 37 +++ .../UserSettings/Columns/PluginQuickTime.php | 37 +++ .../UserSettings/Columns/PluginRealPlayer.php | 37 +++ .../Columns/PluginSilverlight.php | 37 +++ .../Columns/PluginWindowsMedia.php | 37 +++ 35 files changed, 747 insertions(+), 482 deletions(-) delete mode 100644 core/Tracker/Referrer.php create mode 100644 plugins/Referrers/Columns/ReferrerVisitServerDate.php create mode 100644 plugins/UserSettings/Columns/PluginCookie.php create mode 100644 plugins/UserSettings/Columns/PluginDirector.php create mode 100644 plugins/UserSettings/Columns/PluginFlash.php create mode 100644 plugins/UserSettings/Columns/PluginGears.php create mode 100644 plugins/UserSettings/Columns/PluginJava.php create mode 100644 plugins/UserSettings/Columns/PluginPdf.php create mode 100644 plugins/UserSettings/Columns/PluginQuickTime.php create mode 100644 plugins/UserSettings/Columns/PluginRealPlayer.php create mode 100644 plugins/UserSettings/Columns/PluginSilverlight.php create mode 100644 plugins/UserSettings/Columns/PluginWindowsMedia.php diff --git a/core/Db/Schema/Mysql.php b/core/Db/Schema/Mysql.php index f23321be43e..2a0a8144f20 100644 --- a/core/Db/Schema/Mysql.php +++ b/core/Db/Schema/Mysql.php @@ -150,16 +150,6 @@ public function getTablesCreateSql() idvisitor BINARY(8) NOT NULL, visit_last_action_time DATETIME NOT NULL, config_id BINARY(8) NOT NULL, - config_pdf TINYINT(1) NOT NULL, - config_flash TINYINT(1) NOT NULL, - config_java TINYINT(1) NOT NULL, - config_director TINYINT(1) NOT NULL, - config_quicktime TINYINT(1) NOT NULL, - config_realplayer TINYINT(1) NOT NULL, - config_windowsmedia TINYINT(1) NOT NULL, - config_gears TINYINT(1) NOT NULL, - config_silverlight TINYINT(1) NOT NULL, - config_cookie TINYINT(1) NOT NULL, location_ip VARBINARY(16) NOT NULL, PRIMARY KEY(idvisit), INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time), @@ -198,19 +188,6 @@ public function getTablesCreateSql() server_time datetime NOT NULL, idaction_url int(11) default NULL, idlink_va int(11) default NULL, - referer_visit_server_date date default NULL, - referer_type int(10) unsigned default NULL, - referer_name varchar(70) default NULL, - referer_keyword varchar(255) default NULL, - visitor_returning tinyint(1) NOT NULL, - visitor_count_visits SMALLINT(5) UNSIGNED NOT NULL, - visitor_days_since_first SMALLINT(5) UNSIGNED NOT NULL, - visitor_days_since_order SMALLINT(5) UNSIGNED NOT NULL, - location_country char(3) NOT NULL, - location_region char(2) DEFAULT NULL, - location_city varchar(255) DEFAULT NULL, - location_latitude float(10, 6) DEFAULT NULL, - location_longitude float(10, 6) DEFAULT NULL, url text NOT NULL, idgoal int(10) NOT NULL, buster int unsigned NOT NULL, diff --git a/core/Plugin/VisitDimension.php b/core/Plugin/VisitDimension.php index d8434f9ee97..451ba7b181b 100644 --- a/core/Plugin/VisitDimension.php +++ b/core/Plugin/VisitDimension.php @@ -10,7 +10,6 @@ use Piwik\Common; use Piwik\Db; -use Piwik\Tracker\Request; use Piwik\Plugin\Manager as PluginManager; /** @@ -36,6 +35,14 @@ protected function init() } + public function hasImplementedEvent($method) + { + $reflectionObject = new \ReflectionObject($this); + $declaringClass = $reflectionObject->getMethod($method)->getDeclaringClass(); + + return get_class() !== $declaringClass->name; + } + public function install() { if (empty($this->fieldName) || empty($this->fieldType)) { @@ -43,8 +50,24 @@ public function install() } try { - $sql = "ALTER TABLE `" . Common::prefixTable("log_visit") . "` ADD `$this->fieldName` $this->fieldType"; - Db::exec($sql); + if ($this->hasImplementedEvent('onNewVisit') + || $this->hasImplementedEvent('onExistingVisit') + || $this->hasImplementedEvent('onConvertedVisit') ) { + $sql = "ALTER TABLE `" . Common::prefixTable("log_visit") . "` ADD `$this->fieldName` $this->fieldType;"; + Db::exec($sql); + } + + } catch (\Exception $e) { + if (!Db::get()->isErrNo($e, '1060')) { + throw $e; + } + } + + try { + if ($this->hasImplementedEvent('onRecordGoal')) { + $sql = "ALTER TABLE `" . Common::prefixTable("log_conversion") . "` ADD `$this->fieldName` $this->fieldType;"; + Db::exec($sql); + } } catch (\Exception $e) { if (!Db::get()->isErrNo($e, '1060')) { @@ -82,6 +105,26 @@ public function getFieldName() return $this->fieldName; } + public function onNewVisit() + { + return false; + } + + public function onExistingVisit() + { + return false; + } + + public function onConvertedVisit() + { + return false; + } + + public function onRecordGoal() + { + return false; + } + abstract public function getName(); /** @return \Piwik\Plugin\VisitDimension[] */ diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php index 75ea3fd58f2..02067c21016 100644 --- a/core/Tracker/Action.php +++ b/core/Tracker/Action.php @@ -78,9 +78,11 @@ private static function getPriority(Action $actionType) { $key = array_search($actionType->getActionType(), self::$factoryPriority); - if (!$key) { + if (false === $key) { return -1; } + + return $key; } public function shouldHandle() diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php index daa88bd7b9a..9d7ece7c050 100644 --- a/core/Tracker/GoalManager.php +++ b/core/Tracker/GoalManager.php @@ -12,6 +12,7 @@ use Piwik\Common; use Piwik\Config; use Piwik\Piwik; +use Piwik\Plugin\VisitDimension; use Piwik\Plugins\CustomVariables\CustomVariables; use Piwik\Tracker; @@ -186,43 +187,23 @@ function detectGoalId($idSite) /** * Records one or several goals matched in this request. * - * @param int $idSite + * @param Visitor $visitor * @param array $visitorInformation * @param array $visitCustomVariables * @param Action $action */ - public function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action) + public function recordGoals(Visitor $visitor, $visitorInformation, $visitCustomVariables, $action) { - $referrerTimestamp = $this->request->getParam('_refts'); - $referrerUrl = $this->request->getParam('_ref'); - $referrerCampaignName = trim(urldecode($this->request->getParam('_rcn'))); - $referrerCampaignKeyword = trim(urldecode($this->request->getParam('_rck'))); - $browserLanguage = $this->request->getBrowserLanguage(); - - $location_country = isset($visitorInformation['location_country']) - ? $visitorInformation['location_country'] - : Common::getCountry( - $browserLanguage, - $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess'], - $visitorInformation['location_ip'] - ); - $goal = array( - 'idvisit' => $visitorInformation['idvisit'], - 'idsite' => $idSite, - 'idvisitor' => $visitorInformation['idvisitor'], - 'server_time' => Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']), - 'location_country' => $location_country, - 'visitor_returning' => $visitorInformation['visitor_returning'], - 'visitor_days_since_first' => $visitorInformation['visitor_days_since_first'], - 'visitor_days_since_order' => $visitorInformation['visitor_days_since_order'], - 'visitor_count_visits' => $visitorInformation['visitor_count_visits'], + 'idvisit' => $visitorInformation['idvisit'], + 'idvisitor' => $visitorInformation['idvisitor'], + 'server_time' => Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']) ); - $extraLocationCols = array('location_region', 'location_city', 'location_latitude', 'location_longitude'); - foreach ($extraLocationCols as $col) { - if (isset($visitorInformation[$col])) { - $goal[$col] = $visitorInformation[$col]; + foreach (VisitDimension::getAllDimensions() as $dimension) { + $value = $dimension->onRecordGoal($this->request, $visitor, $action); + if (false !== $value) { + $goal[$dimension->getFieldName()] = $value; } } @@ -244,55 +225,6 @@ public function recordGoals($idSite, $visitorInformation, $visitCustomVariables, } } - // Attributing the correct Referrer to this conversion. - // Priority order is as follows: - // 0) In some cases, the campaign is not passed from the JS so we look it up from the current visit - // 1) Campaign name/kwd parsed in the JS - // 2) Referrer URL stored in the _ref cookie - // 3) If no info from the cookie, attribute to the current visit referrer - - // 3) Default values: current referrer - $type = $visitorInformation['referer_type']; - $name = $visitorInformation['referer_name']; - $keyword = $visitorInformation['referer_keyword']; - $time = $visitorInformation['visit_first_action_time']; - - // 0) In some (unknown!?) cases the campaign is not found in the attribution cookie, but the URL ref was found. - // In this case we look up if the current visit is credited to a campaign and will credit this campaign rather than the URL ref (since campaigns have higher priority) - if (empty($referrerCampaignName) - && $type == Common::REFERRER_TYPE_CAMPAIGN - && !empty($name) - ) { - // Use default values per above - } // 1) Campaigns from 1st party cookie - elseif (!empty($referrerCampaignName)) { - $type = Common::REFERRER_TYPE_CAMPAIGN; - $name = $referrerCampaignName; - $keyword = $referrerCampaignKeyword; - $time = $referrerTimestamp; - } // 2) Referrer URL parsing - elseif (!empty($referrerUrl)) { - $referrer = new Referrer(); - $referrer = $referrer->getReferrerInformation($referrerUrl, $currentUrl = '', $idSite); - - // if the parsed referrer is interesting enough, ie. website or search engine - if (in_array($referrer['referer_type'], array(Common::REFERRER_TYPE_SEARCH_ENGINE, Common::REFERRER_TYPE_WEBSITE))) { - $type = $referrer['referer_type']; - $name = $referrer['referer_name']; - $keyword = $referrer['referer_keyword']; - $time = $referrerTimestamp; - } - } - $this->setCampaignValuesToLowercase($type, $name, $keyword); - - $goal += array( - 'referer_type' => $type, - 'referer_name' => $name, - 'referer_keyword' => $keyword, - // this field is currently unused - 'referer_visit_server_date' => date("Y-m-d", $time), - ); - // some goals are converted, so must be ecommerce Order or Cart Update if ($this->requestIsEcommerce) { $this->recordEcommerceGoal($goal, $visitorInformation); @@ -840,23 +772,6 @@ protected function updateExistingConversion($newGoal, $updateWhere) return true; } - /** - * @param $type - * @param $name - * @param $keyword - */ - protected function setCampaignValuesToLowercase($type, &$name, &$keyword) - { - if ($type === Common::REFERRER_TYPE_CAMPAIGN) { - if (!empty($name)) { - $name = Common::mb_strtolower($name); - } - if (!empty($keyword)) { - $keyword = Common::mb_strtolower($keyword); - } - } - } - /** * @param $goal * @param $pattern_type diff --git a/core/Tracker/Referrer.php b/core/Tracker/Referrer.php deleted file mode 100644 index 12d8ff747dc..00000000000 --- a/core/Tracker/Referrer.php +++ /dev/null @@ -1,301 +0,0 @@ -idsite = $idSite; - - // default values for the referer_* fields - $referrerUrl = Common::unsanitizeInputValue($referrerUrl); - if (!empty($referrerUrl) - && !UrlHelper::isLookLikeUrl($referrerUrl) - ) { - $referrerUrl = ''; - } - - $currentUrl = PageUrl::cleanupUrl($currentUrl); - - $this->referrerUrl = $referrerUrl; - $this->referrerUrlParse = @parse_url($this->referrerUrl); - $this->currentUrlParse = @parse_url($currentUrl); - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY; - $this->nameReferrerAnalyzed = ''; - $this->keywordReferrerAnalyzed = ''; - $this->referrerHost = ''; - - if (isset($this->referrerUrlParse['host'])) { - $this->referrerHost = $this->referrerUrlParse['host']; - } - - $referrerDetected = $this->detectReferrerCampaign(); - - if (!$referrerDetected) { - if ($this->detectReferrerDirectEntry() - || $this->detectReferrerSearchEngine() - ) { - $referrerDetected = true; - } - } - - if (!empty($this->referrerHost) - && !$referrerDetected - ) { - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_WEBSITE; - $this->nameReferrerAnalyzed = Common::mb_strtolower($this->referrerHost); - } - - $referrerInformation = array( - 'referer_type' => $this->typeReferrerAnalyzed, - 'referer_name' => $this->nameReferrerAnalyzed, - 'referer_keyword' => $this->keywordReferrerAnalyzed, - 'referer_url' => $this->referrerUrl, - ); - - return $referrerInformation; - } - - /** - * Search engine detection - * @return bool - */ - protected function detectReferrerSearchEngine() - { - $searchEngineInformation = UrlHelper::extractSearchEngineInformationFromUrl($this->referrerUrl); - - /** - * Triggered when detecting the search engine of a referrer URL. - * - * Plugins can use this event to provide custom search engine detection - * logic. - * - * @param array &$searchEngineInformation An array with the following information: - * - * - **name**: The search engine name. - * - **keywords**: The search keywords used. - * - * This parameter is initialized to the results - * of Piwik's default search engine detection - * logic. - * @param string referrerUrl The referrer URL from the tracking request. - */ - Piwik::postEvent('Tracker.detectReferrerSearchEngine', array(&$searchEngineInformation, $this->referrerUrl)); - if ($searchEngineInformation === false) { - return false; - } - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_SEARCH_ENGINE; - $this->nameReferrerAnalyzed = $searchEngineInformation['name']; - $this->keywordReferrerAnalyzed = $searchEngineInformation['keywords']; - return true; - } - - /** - * @param string $string - * @return bool - */ - protected function detectCampaignFromString($string) - { - foreach ($this->campaignNames as $campaignNameParameter) { - $campaignName = trim(urldecode(UrlHelper::getParameterFromQueryString($string, $campaignNameParameter))); - if (!empty($campaignName)) { - break; - } - } - - if (empty($campaignName)) { - return false; - } - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_CAMPAIGN; - $this->nameReferrerAnalyzed = $campaignName; - - foreach ($this->campaignKeywords as $campaignKeywordParameter) { - $campaignKeyword = UrlHelper::getParameterFromQueryString($string, $campaignKeywordParameter); - if (!empty($campaignKeyword)) { - $this->keywordReferrerAnalyzed = trim(urldecode($campaignKeyword)); - break; - } - } - return !empty($this->keywordReferrerAnalyzed); - } - - protected function detectReferrerCampaignFromLandingUrl() - { - if (!isset($this->currentUrlParse['query']) - && !isset($this->currentUrlParse['fragment']) - ) { - return false; - } - $campaignParameters = Common::getCampaignParameters(); - $this->campaignNames = $campaignParameters[0]; - $this->campaignKeywords = $campaignParameters[1]; - - $found = false; - - // 1) Detect campaign from query string - if (isset($this->currentUrlParse['query'])) { - $found = $this->detectCampaignFromString($this->currentUrlParse['query']); - } - - // 2) Detect from fragment #hash - if (!$found - && isset($this->currentUrlParse['fragment']) - ) { - $this->detectCampaignFromString($this->currentUrlParse['fragment']); - } - } - - /** - * We have previously tried to detect the campaign variables in the URL - * so at this stage, if the referrer host is the current host, - * or if the referrer host is any of the registered URL for this website, - * it is considered a direct entry - * @return bool - */ - protected function detectReferrerDirectEntry() - { - if (!empty($this->referrerHost)) { - // is the referrer host the current host? - if (isset($this->currentUrlParse['host'])) { - $currentHost = mb_strtolower($this->currentUrlParse['host'], 'UTF-8'); - if ($currentHost == mb_strtolower($this->referrerHost, 'UTF-8')) { - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY; - return true; - } - } - if (Visit::isHostKnownAliasHost($this->referrerHost, $this->idsite)) { - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY; - return true; - } - } - return false; - } - - protected function detectCampaignKeywordFromReferrerUrl() - { - if(!empty($this->nameReferrerAnalyzed) - && !empty($this->keywordReferrerAnalyzed)) { - // keyword is already set, we skip - return true; - } - - // Set the Campaign keyword to the keyword found in the Referrer URL if any - if(!empty($this->nameReferrerAnalyzed)) { - $referrerUrlInfo = UrlHelper::extractSearchEngineInformationFromUrl($this->referrerUrl); - if (!empty($referrerUrlInfo['keywords'])) { - $this->keywordReferrerAnalyzed = $referrerUrlInfo['keywords']; - } - } - - // Set the keyword, to the hostname found, in a Adsense Referrer URL '&url=' parameter - if (empty($this->keywordReferrerAnalyzed) - && !empty($this->referrerUrlParse['query']) - && !empty($this->referrerHost) - && (strpos($this->referrerHost, 'googleads') !== false || strpos($this->referrerHost, 'doubleclick') !== false) - ) { - // This parameter sometimes is found & contains the page with the adsense ad bringing visitor to our site - $value = $this->getParameterValueFromReferrerUrl('url'); - if (!empty($value)) { - $parsedAdsenseReferrerUrl = parse_url($value); - if (!empty($parsedAdsenseReferrerUrl['host'])) { - - if(empty($this->nameReferrerAnalyzed)) { - $type = $this->getParameterValueFromReferrerUrl('ad_type'); - $type = $type ? " ($type)" : ''; - $this->nameReferrerAnalyzed = self::LABEL_ADWORDS_NAME . $type; - $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_CAMPAIGN; - } - $this->keywordReferrerAnalyzed = self::LABEL_PREFIX_ADWORDS_KEYWORD . $parsedAdsenseReferrerUrl['host']; - } - } - } - - } - - /** - * @return string - */ - protected function getParameterValueFromReferrerUrl($adsenseReferrerParameter) - { - $value = trim(urldecode(UrlHelper::getParameterFromQueryString($this->referrerUrlParse['query'], $adsenseReferrerParameter))); - return $value; - } - - /** - * @return bool - */ - protected function detectReferrerCampaign() - { - $this->detectReferrerCampaignFromLandingUrl(); - $this->detectCampaignKeywordFromReferrerUrl(); - - if ($this->typeReferrerAnalyzed != Common::REFERRER_TYPE_CAMPAIGN) { - return false; - } - // if we detected a campaign but there is still no keyword set, we set the keyword to the Referrer host - if(empty($this->keywordReferrerAnalyzed)) { - $this->keywordReferrerAnalyzed = $this->referrerHost; - } - - $this->keywordReferrerAnalyzed = Common::mb_strtolower($this->keywordReferrerAnalyzed); - $this->nameReferrerAnalyzed = Common::mb_strtolower($this->nameReferrerAnalyzed); - return true; - } - -} diff --git a/core/Tracker/Settings.php b/core/Tracker/Settings.php index 341eb6d69b9..142c071446b 100644 --- a/core/Tracker/Settings.php +++ b/core/Tracker/Settings.php @@ -15,17 +15,18 @@ class Settings { function __construct(Request $request, $ip) { - $this->request = $request; + $this->request = $request; $this->ipAddress = $ip; - $this->params = array(); + $this->configId = null; } - function getInfo() + function getConfigId() { - if(empty($this->params)) { + if (empty($this->configId)) { $this->loadInfo(); } - return $this->params; + + return $this->configId; } protected function loadInfo() @@ -40,14 +41,15 @@ protected function loadInfo() $deviceDetector->parse(); $aBrowserInfo = $deviceDetector->getBrowser(); - $browserName = !empty($aBrowserInfo['short_name']) ? $aBrowserInfo['short_name'] : 'UNK'; + $browserName = !empty($aBrowserInfo['short_name']) ? $aBrowserInfo['short_name'] : 'UNK'; $browserVersion = !empty($aBrowserInfo['version']) ? $aBrowserInfo['version'] : ''; $os = $deviceDetector->getOS(); $os = empty($os['short_name']) ? 'UNK' : $os['short_name']; $browserLang = substr($this->request->getBrowserLanguage(), 0, 20); // limit the length of this string to match db - $configurationHash = $this->getConfigHash( + + $this->configId = $this->getConfigHash( $os, $browserName, $browserVersion, @@ -63,20 +65,6 @@ protected function loadInfo() $plugin_Cookie, $this->ipAddress, $browserLang); - - $this->params = array( - 'config_id' => $configurationHash, - 'config_pdf' => $plugin_PDF, - 'config_flash' => $plugin_Flash, - 'config_java' => $plugin_Java, - 'config_director' => $plugin_Director, - 'config_quicktime' => $plugin_Quicktime, - 'config_realplayer' => $plugin_RealPlayer, - 'config_windowsmedia' => $plugin_WindowsMedia, - 'config_gears' => $plugin_Gears, - 'config_silverlight' => $plugin_Silverlight, - 'config_cookie' => $plugin_Cookie - ); } diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php index 3a0ed0b5759..7dceab977a2 100644 --- a/core/Tracker/Visit.php +++ b/core/Tracker/Visit.php @@ -142,12 +142,13 @@ public function handle() /*** * Visitor recognition */ - $visitor = new Visitor($this->request, $this->getSettingsObject(), $this->visitorInfo, $this->visitorCustomVariables); + $visitorId = $this->getSettingsObject()->getConfigId(); + $visitor = new Visitor($this->request, $visitorId, $this->visitorInfo, $this->visitorCustomVariables); $visitor->recognize(); $this->visitorInfo = $visitor->getVisitorInfo(); - $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit(); + $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit($visitor); if (!$isLastActionInTheSameVisit) { Common::printDebug("Visitor detected, but last action was more than 30 minutes ago..."); @@ -162,7 +163,7 @@ public function handle() if ($visitor->isVisitorKnown() && $isLastActionInTheSameVisit ) { - $idReferrerActionUrl = $this->visitorInfo['visit_exit_idaction_url']; + $idReferrerActionUrl = $this->visitorInfo['visit_exit_idaction_url']; $idReferrerActionName = $this->visitorInfo['visit_exit_idaction_name']; try { $this->handleExistingVisit($visitor, $action, $visitIsConverted); @@ -208,7 +209,7 @@ public function handle() // record the goals if applicable if ($someGoalsConverted) { $this->goalManager->recordGoals( - $this->request->getIdSite(), + $visitor, $this->visitorInfo, $this->visitorCustomVariables, $action @@ -259,6 +260,9 @@ protected function handleExistingVisit($visitor, $action, $visitIsConverted) Piwik::postEvent('Tracker.existingVisitInformation', array(&$valuesToUpdate, $this->visitorInfo)); $this->updateExistingVisit($valuesToUpdate); + + $this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp(); + $visitor->setVisitorColumn('visit_last_action_time', $this->visitorInfo['visit_last_action_time']); } /** @@ -320,10 +324,13 @@ 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(); + + $visitor->setVisitorColumn('idvisit', $this->visitorInfo['idvisit']); + $visitor->setVisitorColumn('visit_first_action_time', $this->visitorInfo['visit_first_action_time']); + $visitor->setVisitorColumn('visit_last_action_time', $this->visitorInfo['visit_last_action_time']); } /** @@ -383,11 +390,13 @@ protected function getSettingsObject() * Returns true if the last action was done during the last 30 minutes * @return bool */ - protected function isLastActionInTheSameVisit() + protected function isLastActionInTheSameVisit(Visitor $visitor) { - return isset($this->visitorInfo['visit_last_action_time']) - && ($this->visitorInfo['visit_last_action_time'] - > ($this->request->getCurrentTimestamp() - Config::getInstance()->Tracker['visit_standard_length'])); + $lastActionTime = $visitor->getVisitorColumn('visit_last_action_time'); + + return isset($lastActionTime) + && false !== $lastActionTime + && ($lastActionTime > ($this->request->getCurrentTimestamp() - Config::getInstance()->Tracker['visit_standard_length'])); } // is the referrer host any of the registered URLs for this website? @@ -451,8 +460,6 @@ protected function updateExistingVisit($valuesToUpdate) $result = Tracker::getDatabase()->query($sqlQuery, $sqlBind); - $this->visitorInfo['visit_last_action_time'] = $this->request->getCurrentTimestamp(); - // Debug output if (isset($valuesToUpdate['idvisitor'])) { $valuesToUpdate['idvisitor'] = bin2hex($valuesToUpdate['idvisitor']); @@ -479,22 +486,10 @@ protected function printVisitorInformation() protected function getNewVisitorInformation($idVisitor) { - $userInfo = $this->getSettingsObject()->getInfo(); - return array( - 'idvisitor' => $idVisitor, - 'config_id' => $userInfo['config_id'], - 'config_pdf' => $userInfo['config_pdf'], - 'config_flash' => $userInfo['config_flash'], - 'config_java' => $userInfo['config_java'], - 'config_director' => $userInfo['config_director'], - 'config_quicktime' => $userInfo['config_quicktime'], - 'config_realplayer' => $userInfo['config_realplayer'], - 'config_windowsmedia' => $userInfo['config_windowsmedia'], - 'config_gears' => $userInfo['config_gears'], - 'config_silverlight' => $userInfo['config_silverlight'], - 'config_cookie' => $userInfo['config_cookie'], - 'location_ip' => $this->getVisitorIp(), + 'idvisitor' => $idVisitor, + 'config_id' => $this->getSettingsObject()->getConfigId(), + 'location_ip' => $this->getVisitorIp(), ); } @@ -539,10 +534,6 @@ protected function getExistingVisitFieldsToUpdate($visitor, $action, $visitIsCon private function triggerHookOnDimensions($dimensions, $hook, $visitor, $action, $valuesToUpdate = null) { foreach ($dimensions as $dimension) { - if (!method_exists($dimension, $hook)) { - continue; - } - $value = $dimension->$hook($this->request, $visitor, $action); if ($value !== false) { diff --git a/core/Tracker/Visitor.php b/core/Tracker/Visitor.php index 8839c30a5bd..dbdcac29886 100644 --- a/core/Tracker/Visitor.php +++ b/core/Tracker/Visitor.php @@ -20,14 +20,14 @@ class Visitor private $visitorKnown = false; private $request; private $visitorInfo; - private $userInfo; + private $configId; - public function __construct(Request $request, Tracker\Settings $settings, $visitorInfo = array(), $customVariables = null) + public function __construct(Request $request, $configId, $visitorInfo = array(), $customVariables = null) { $this->request = $request; $this->visitorInfo = $visitorInfo; $this->customVariables = $customVariables; - $this->userInfo = $settings->getInfo(); + $this->configId = $configId; } /** @@ -41,7 +41,7 @@ public function recognize() { $this->setIsVisitorKonwn(false); - $configId = $this->userInfo['config_id']; + $configId = $this->configId; $idVisitor = $this->request->getVisitorId(); $isVisitorIdToLookup = !empty($idVisitor); @@ -270,11 +270,10 @@ public static function getVisitFieldsPersist() $dimensions = VisitDimension::getAllDimensions(); foreach ($dimensions as $dimension) { - if (method_exists($dimension, 'onExistingVisit')) { + if ($dimension->hasImplementedEvent('onExistingVisit')) { $fields[] = $dimension->getFieldName(); } - /** * This event collects a list of [visit entity]() properties that should be loaded when reading * the existing visit. Properties that appear in this list will be available in other tracking diff --git a/piwik.php b/piwik.php index 40096c11cef..325e35692a1 100644 --- a/piwik.php +++ b/piwik.php @@ -71,7 +71,6 @@ require_once PIWIK_INCLUDE_PATH . '/core/Tracker/Action.php'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/ActionPageview.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'; require_once PIWIK_INCLUDE_PATH . '/core/Tracker/VisitorNotFoundInDb.php'; require_once PIWIK_INCLUDE_PATH . '/core/CacheFile.php'; diff --git a/plugins/CoreHome/Columns/IdSite.php b/plugins/CoreHome/Columns/IdSite.php index 2c29df898b0..369bfc31cef 100644 --- a/plugins/CoreHome/Columns/IdSite.php +++ b/plugins/CoreHome/Columns/IdSite.php @@ -38,4 +38,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) { return $request->getIdSite(); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $request->getIdSite(); + } } \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitLastActionTime.php b/plugins/CoreHome/Columns/VisitLastActionTime.php index 9bf59906870..21a21033704 100644 --- a/plugins/CoreHome/Columns/VisitLastActionTime.php +++ b/plugins/CoreHome/Columns/VisitLastActionTime.php @@ -49,5 +49,4 @@ public function onExistingVisit(Request $request, Visitor $visitor, $action) { return $this->onNewVisit($request, $visitor, $action); } - } \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php b/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php index 04791dcf81e..7e2230432d4 100644 --- a/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php +++ b/plugins/CoreHome/Columns/VisitorDaysSinceFirst.php @@ -43,4 +43,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) { return $request->getDaysSinceFirstVisit(); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php b/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php index d4007bc58a2..8ccde5c0e0b 100644 --- a/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php +++ b/plugins/CoreHome/Columns/VisitorDaysSinceOrder.php @@ -50,4 +50,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) return $daysSinceLastOrder; } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitorReturning.php b/plugins/CoreHome/Columns/VisitorReturning.php index bfd3c476335..cf78ee44bf0 100644 --- a/plugins/CoreHome/Columns/VisitorReturning.php +++ b/plugins/CoreHome/Columns/VisitorReturning.php @@ -23,6 +23,7 @@ class VisitorReturning extends VisitDimension protected $fieldName = 'visitor_returning'; protected $fieldType = 'TINYINT(1) NOT NULL'; + protected $conversionField = true; protected function init() { @@ -69,4 +70,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) return self::IS_NEW; } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/CoreHome/Columns/VisitsCount.php b/plugins/CoreHome/Columns/VisitsCount.php index 6fb53c6ff0c..b1df599495e 100644 --- a/plugins/CoreHome/Columns/VisitsCount.php +++ b/plugins/CoreHome/Columns/VisitsCount.php @@ -43,4 +43,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) { return $request->getVisitCount(); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/Referrers/Columns/Base.php b/plugins/Referrers/Columns/Base.php index 268cd8b2c1b..470753715ec 100644 --- a/plugins/Referrers/Columns/Base.php +++ b/plugins/Referrers/Columns/Base.php @@ -12,7 +12,10 @@ use Piwik\Piwik; use Piwik\Plugin\VisitDimension; use Piwik\Tracker\PageUrl; +use Piwik\Tracker\Request; use Piwik\Tracker\Visit; +use Piwik\Tracker\Visitor; +use Piwik\Tracker\Action; use Piwik\UrlHelper; @@ -301,4 +304,92 @@ protected function detectReferrerCampaign() return true; } + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function getValueForRecordGoal(Request $request, Visitor $visitor) + { + $referrerTimestamp = $request->getParam('_refts'); + $referrerUrl = $request->getParam('_ref'); + $referrerCampaignName = trim(urldecode($request->getParam('_rcn'))); + $referrerCampaignKeyword = trim(urldecode($request->getParam('_rck'))); + + // Attributing the correct Referrer to this conversion. + // Priority order is as follows: + // 0) In some cases, the campaign is not passed from the JS so we look it up from the current visit + // 1) Campaign name/kwd parsed in the JS + // 2) Referrer URL stored in the _ref cookie + // 3) If no info from the cookie, attribute to the current visit referrer + + // 3) Default values: current referrer + $type = $visitor->getVisitorColumn('referer_type'); + $name = $visitor->getVisitorColumn('referer_name'); + $keyword = $visitor->getVisitorColumn('referer_keyword'); + $time = $visitor->getVisitorColumn('visit_first_action_time'); + + // 0) In some (unknown!?) cases the campaign is not found in the attribution cookie, but the URL ref was found. + // In this case we look up if the current visit is credited to a campaign and will credit this campaign rather than the URL ref (since campaigns have higher priority) + if (empty($referrerCampaignName) + && $type == Common::REFERRER_TYPE_CAMPAIGN + && !empty($name) + ) { + // Use default values per above + } // 1) Campaigns from 1st party cookie + elseif (!empty($referrerCampaignName)) { + $type = Common::REFERRER_TYPE_CAMPAIGN; + $name = $referrerCampaignName; + $keyword = $referrerCampaignKeyword; + $time = $referrerTimestamp; + } // 2) Referrer URL parsing + elseif (!empty($referrerUrl)) { + + $idSite = $request->getIdSite(); + $referrer = $this->getReferrerInformation($referrerUrl, $currentUrl = '', $idSite); + + // if the parsed referrer is interesting enough, ie. website or search engine + if (in_array($referrer['referer_type'], array(Common::REFERRER_TYPE_SEARCH_ENGINE, Common::REFERRER_TYPE_WEBSITE))) { + $type = $referrer['referer_type']; + $name = $referrer['referer_name']; + $keyword = $referrer['referer_keyword']; + $time = $referrerTimestamp; + } + } + + $this->setCampaignValuesToLowercase($type, $name, $keyword); + + $fields = array( + 'referer_type' => $type, + 'referer_name' => $name, + 'referer_keyword' => $keyword, + // this field is currently unused + 'referer_visit_server_date' => date("Y-m-d", $time), + ); + + if (array_key_exists($this->fieldName, $fields)) { + return $fields[$this->fieldName]; + } + + return false; + } + + /** + * @param $type + * @param $name + * @param $keyword + */ + protected function setCampaignValuesToLowercase($type, &$name, &$keyword) + { + if ($type === Common::REFERRER_TYPE_CAMPAIGN) { + if (!empty($name)) { + $name = Common::mb_strtolower($name); + } + if (!empty($keyword)) { + $keyword = Common::mb_strtolower($keyword); + } + } + } + } diff --git a/plugins/Referrers/Columns/Keyword.php b/plugins/Referrers/Columns/Keyword.php index 31e495e96e2..573aa8b44d1 100644 --- a/plugins/Referrers/Columns/Keyword.php +++ b/plugins/Referrers/Columns/Keyword.php @@ -52,4 +52,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) return $information['referer_keyword']; } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $this->getValueForRecordGoal($request, $visitor); + } } diff --git a/plugins/Referrers/Columns/ReferrerName.php b/plugins/Referrers/Columns/ReferrerName.php index 38e1ec9bb18..854fb9a6821 100644 --- a/plugins/Referrers/Columns/ReferrerName.php +++ b/plugins/Referrers/Columns/ReferrerName.php @@ -52,4 +52,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) return $information['referer_name']; } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $this->getValueForRecordGoal($request, $visitor); + } } diff --git a/plugins/Referrers/Columns/ReferrerType.php b/plugins/Referrers/Columns/ReferrerType.php index 93df8e406d4..03976c101e5 100644 --- a/plugins/Referrers/Columns/ReferrerType.php +++ b/plugins/Referrers/Columns/ReferrerType.php @@ -49,4 +49,15 @@ public function onNewVisit(Request $request, Visitor $visitor, $action) return $information['referer_type']; } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $this->getValueForRecordGoal($request, $visitor); + } } diff --git a/plugins/Referrers/Columns/ReferrerVisitServerDate.php b/plugins/Referrers/Columns/ReferrerVisitServerDate.php new file mode 100644 index 00000000000..5eb4e758e9b --- /dev/null +++ b/plugins/Referrers/Columns/ReferrerVisitServerDate.php @@ -0,0 +1,35 @@ +getValueForRecordGoal($request, $visitor); + } +} diff --git a/plugins/UserCountry/Columns/City.php b/plugins/UserCountry/Columns/City.php index 929dae92f21..aa353e6ca3b 100644 --- a/plugins/UserCountry/Columns/City.php +++ b/plugins/UserCountry/Columns/City.php @@ -63,4 +63,15 @@ public function onExistingVisit(Request $request, Visitor $visitor, $action) { return $this->getUrlOverrideValueIfAllowed('city', $request); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/UserCountry/Columns/Country.php b/plugins/UserCountry/Columns/Country.php index a9feced9f69..9e7e41b47a1 100644 --- a/plugins/UserCountry/Columns/Country.php +++ b/plugins/UserCountry/Columns/Country.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\UserCountry\Columns; use Piwik\Common; +use Piwik\Config; use Piwik\IP; use Piwik\Piwik; use Piwik\Plugins\Provider\Provider; @@ -114,4 +115,27 @@ public function onExistingVisit(Request $request, Visitor $visitor, $action) { return $this->getUrlOverrideValueIfAllowed('country', $request); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + $country = $visitor->getVisitorColumn($this->fieldName); + + if (isset($country) && false !== $country) { + return $country; + } + + $browserLanguage = $request->getBrowserLanguage(); + $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess']; + $locationIp = $visitor->getVisitorColumn('location_ip'); + + $country = Common::getCountry($browserLanguage, $enableLanguageToCountryGuess, $locationIp); + + return $country; + } } \ No newline at end of file diff --git a/plugins/UserCountry/Columns/Latitude.php b/plugins/UserCountry/Columns/Latitude.php index afadffee9db..ec1b543c5cb 100644 --- a/plugins/UserCountry/Columns/Latitude.php +++ b/plugins/UserCountry/Columns/Latitude.php @@ -63,4 +63,15 @@ public function onExistingVisit(Request $request, Visitor $visitor, $action) { return $this->getUrlOverrideValueIfAllowed('lat', $request); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/UserCountry/Columns/Longitude.php b/plugins/UserCountry/Columns/Longitude.php index d5971321c3f..5fd4261329d 100644 --- a/plugins/UserCountry/Columns/Longitude.php +++ b/plugins/UserCountry/Columns/Longitude.php @@ -63,4 +63,15 @@ public function onExistingVisit(Request $request, Visitor $visitor, $action) { return $this->getUrlOverrideValueIfAllowed('long', $request); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/UserCountry/Columns/Region.php b/plugins/UserCountry/Columns/Region.php index 6010a7de5f6..b85ac2ab3b5 100644 --- a/plugins/UserCountry/Columns/Region.php +++ b/plugins/UserCountry/Columns/Region.php @@ -63,4 +63,15 @@ public function onExistingVisit(Request $request, Visitor $visitor, $action) { return $this->getUrlOverrideValueIfAllowed('region', $request); } + + /** + * @param Request $request + * @param Visitor $visitor + * @param Action|null $action + * @return mixed + */ + public function onRecordGoal(Request $request, Visitor $visitor, $action) + { + return $visitor->getVisitorColumn($this->fieldName); + } } \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginCookie.php b/plugins/UserSettings/Columns/PluginCookie.php new file mode 100644 index 00000000000..653bd757da5 --- /dev/null +++ b/plugins/UserSettings/Columns/PluginCookie.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginDirector.php b/plugins/UserSettings/Columns/PluginDirector.php new file mode 100644 index 00000000000..8e8ec9041b2 --- /dev/null +++ b/plugins/UserSettings/Columns/PluginDirector.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginFlash.php b/plugins/UserSettings/Columns/PluginFlash.php new file mode 100644 index 00000000000..b2b546704fb --- /dev/null +++ b/plugins/UserSettings/Columns/PluginFlash.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginGears.php b/plugins/UserSettings/Columns/PluginGears.php new file mode 100644 index 00000000000..46aee3d6b5b --- /dev/null +++ b/plugins/UserSettings/Columns/PluginGears.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginJava.php b/plugins/UserSettings/Columns/PluginJava.php new file mode 100644 index 00000000000..1caf4845d3b --- /dev/null +++ b/plugins/UserSettings/Columns/PluginJava.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginPdf.php b/plugins/UserSettings/Columns/PluginPdf.php new file mode 100644 index 00000000000..8270387b493 --- /dev/null +++ b/plugins/UserSettings/Columns/PluginPdf.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginQuickTime.php b/plugins/UserSettings/Columns/PluginQuickTime.php new file mode 100644 index 00000000000..dbb1ccb569f --- /dev/null +++ b/plugins/UserSettings/Columns/PluginQuickTime.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginRealPlayer.php b/plugins/UserSettings/Columns/PluginRealPlayer.php new file mode 100644 index 00000000000..66f2453e152 --- /dev/null +++ b/plugins/UserSettings/Columns/PluginRealPlayer.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginSilverlight.php b/plugins/UserSettings/Columns/PluginSilverlight.php new file mode 100644 index 00000000000..7462b619330 --- /dev/null +++ b/plugins/UserSettings/Columns/PluginSilverlight.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file diff --git a/plugins/UserSettings/Columns/PluginWindowsMedia.php b/plugins/UserSettings/Columns/PluginWindowsMedia.php new file mode 100644 index 00000000000..2879a7cbce4 --- /dev/null +++ b/plugins/UserSettings/Columns/PluginWindowsMedia.php @@ -0,0 +1,37 @@ +getParams()); + } +} \ No newline at end of file