update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
9abe039dc8
commit
47263617c5
93 changed files with 418860 additions and 226988 deletions
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -11,20 +11,25 @@ namespace Piwik\Plugins\SitesManager;
|
|||
use Exception;
|
||||
use Piwik\Access;
|
||||
use Piwik\Common;
|
||||
use Piwik\Container\StaticContainer;
|
||||
use Piwik\Date;
|
||||
use Piwik\Db;
|
||||
use Piwik\IP;
|
||||
use Piwik\MetricsFormatter;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Network\IPUtils;
|
||||
use Piwik\Option;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Measurable\MeasurableSettings;
|
||||
use Piwik\ProxyHttp;
|
||||
use Piwik\Scheduler\Scheduler;
|
||||
use Piwik\SettingsPiwik;
|
||||
use Piwik\SettingsServer;
|
||||
use Piwik\Site;
|
||||
use Piwik\TaskScheduler;
|
||||
use Piwik\Tracker;
|
||||
use Piwik\Tracker\Cache;
|
||||
use Piwik\Tracker\TrackerCodeGenerator;
|
||||
use Piwik\Measurable\Type;
|
||||
use Piwik\Url;
|
||||
use Piwik\UrlHelper;
|
||||
use Piwik\ProxyHttp;
|
||||
|
||||
/**
|
||||
* The SitesManager API gives you full control on Websites in Piwik (create, update and delete), and many methods to retrieve websites based on various attributes.
|
||||
|
|
@ -39,7 +44,7 @@ use Piwik\ProxyHttp;
|
|||
* Some methods will affect all websites globally: "setGlobalExcludedIps" will set the list of IPs to be excluded on all websites,
|
||||
* "setGlobalExcludedQueryParameters" will set the list of URL parameters to remove from URLs for all websites.
|
||||
* The existing values can be fetched via "getExcludedIpsGlobal" and "getExcludedQueryParametersGlobal".
|
||||
* See also the documentation about <a href='http://piwik.org/docs/manage-websites/' target='_blank'>Managing Websites</a> in Piwik.
|
||||
* See also the documentation about <a href='http://piwik.org/docs/manage-websites/' rel='noreferrer' target='_blank'>Managing Websites</a> in Piwik.
|
||||
* @method static \Piwik\Plugins\SitesManager\API getInstance()
|
||||
*/
|
||||
class API extends \Piwik\Plugin\API
|
||||
|
|
@ -69,27 +74,35 @@ class API extends \Piwik\Plugin\API
|
|||
* @param bool $customCampaignNameQueryParam
|
||||
* @param bool $customCampaignKeywordParam
|
||||
* @param bool $doNotTrack
|
||||
* @internal param $
|
||||
* @param bool $disableCookies
|
||||
* @return string The Javascript tag ready to be included on the HTML pages
|
||||
*/
|
||||
public function getJavascriptTag($idSite, $piwikUrl = '', $mergeSubdomains = false, $groupPageTitlesByDomain = false,
|
||||
$mergeAliasUrls = false, $visitorCustomVariables = false, $pageCustomVariables = false,
|
||||
$customCampaignNameQueryParam = false, $customCampaignKeywordParam = false,
|
||||
$doNotTrack = false)
|
||||
$doNotTrack = false, $disableCookies = false)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
|
||||
if (empty($piwikUrl)) {
|
||||
$piwikUrl = SettingsPiwik::getPiwikUrl();
|
||||
}
|
||||
$piwikUrl = Common::sanitizeInputValues($piwikUrl);
|
||||
|
||||
$htmlEncoded = Piwik::getJavascriptCode($idSite, $piwikUrl, $mergeSubdomains, $groupPageTitlesByDomain,
|
||||
$mergeAliasUrls, $visitorCustomVariables, $pageCustomVariables,
|
||||
$customCampaignNameQueryParam, $customCampaignKeywordParam,
|
||||
$doNotTrack);
|
||||
$htmlEncoded = str_replace(array('<br>', '<br />', '<br/>'), '', $htmlEncoded);
|
||||
return $htmlEncoded;
|
||||
// Revert the automatic encoding
|
||||
// TODO remove that when https://github.com/piwik/piwik/issues/4231 is fixed
|
||||
$piwikUrl = Common::unsanitizeInputValue($piwikUrl);
|
||||
$visitorCustomVariables = Common::unsanitizeInputValues($visitorCustomVariables);
|
||||
$pageCustomVariables = Common::unsanitizeInputValues($pageCustomVariables);
|
||||
$customCampaignNameQueryParam = Common::unsanitizeInputValue($customCampaignNameQueryParam);
|
||||
$customCampaignKeywordParam = Common::unsanitizeInputValue($customCampaignKeywordParam);
|
||||
|
||||
$generator = new TrackerCodeGenerator();
|
||||
$code = $generator->generate($idSite, $piwikUrl, $mergeSubdomains, $groupPageTitlesByDomain,
|
||||
$mergeAliasUrls, $visitorCustomVariables, $pageCustomVariables,
|
||||
$customCampaignNameQueryParam, $customCampaignKeywordParam,
|
||||
$doNotTrack, $disableCookies);
|
||||
$code = str_replace(array('<br>', '<br />', '<br/>'), '', $code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,14 +116,14 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getImageTrackingCode($idSite, $piwikUrl = '', $actionName = false, $idGoal = false, $revenue = false)
|
||||
{
|
||||
$urlParams = array('idSite' => $idSite, 'rec' => 1);
|
||||
$urlParams = array('idsite' => $idSite, 'rec' => 1);
|
||||
|
||||
if ($actionName !== false) {
|
||||
$urlParams['action_name'] = urlencode(Common::unsanitizeInputValue($actionName));
|
||||
}
|
||||
|
||||
if ($idGoal !== false) {
|
||||
$urlParams['idGoal'] = $idGoal;
|
||||
$urlParams['idgoal'] = $idGoal;
|
||||
if ($revenue !== false) {
|
||||
$urlParams['revenue'] = $revenue;
|
||||
}
|
||||
|
|
@ -139,14 +152,12 @@ class API extends \Piwik\Plugin\API
|
|||
* @param string $group Group name
|
||||
* @return array of sites
|
||||
*/
|
||||
public function getSitesFromGroup($group)
|
||||
public function getSitesFromGroup($group = '')
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$group = trim($group);
|
||||
|
||||
$sites = Db::get()->fetchAll("SELECT *
|
||||
FROM " . Common::prefixTable("site") . "
|
||||
WHERE `group` = ?", $group);
|
||||
$group = trim($group);
|
||||
$sites = $this->getModel()->getSitesFromGroup($group);
|
||||
|
||||
Site::setSitesFromArray($sites);
|
||||
return $sites;
|
||||
|
|
@ -161,12 +172,10 @@ class API extends \Piwik\Plugin\API
|
|||
public function getSitesGroups()
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$groups = Db::get()->fetchAll("SELECT DISTINCT `group` FROM " . Common::prefixTable("site"));
|
||||
$cleanedGroups = array();
|
||||
foreach ($groups as $group) {
|
||||
$cleanedGroups[] = $group['group'];
|
||||
}
|
||||
$cleanedGroups = array_map('trim', $cleanedGroups);
|
||||
|
||||
$groups = $this->getModel()->getSitesGroups();
|
||||
$cleanedGroups = array_map('trim', $groups);
|
||||
|
||||
return $cleanedGroups;
|
||||
}
|
||||
|
||||
|
|
@ -180,32 +189,17 @@ class API extends \Piwik\Plugin\API
|
|||
public function getSiteFromId($idSite)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$site = Db::get()->fetchRow("SELECT *
|
||||
FROM " . Common::prefixTable("site") . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
|
||||
Site::setSitesFromArray(array($site));
|
||||
$site = $this->getModel()->getSiteFromId($idSite);
|
||||
|
||||
Site::setSiteFromArray($idSite, $site);
|
||||
|
||||
return $site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of alias URLs registered for the given idSite.
|
||||
* The website ID must be valid when calling this method!
|
||||
*
|
||||
* @param int $idSite
|
||||
* @return array list of alias URLs
|
||||
*/
|
||||
private function getAliasSiteUrlsFromId($idSite)
|
||||
private function getModel()
|
||||
{
|
||||
$db = Db::get();
|
||||
$result = $db->fetchAll("SELECT url
|
||||
FROM " . Common::prefixTable("site_url") . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
$urls = array();
|
||||
foreach ($result as $url) {
|
||||
$urls[] = $url['url'];
|
||||
}
|
||||
return $urls;
|
||||
return new Model();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -218,25 +212,12 @@ class API extends \Piwik\Plugin\API
|
|||
public function getSiteUrlsFromId($idSite)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$site = new Site($idSite);
|
||||
$urls = $this->getAliasSiteUrlsFromId($idSite);
|
||||
return array_merge(array($site->getMainUrl()), $urls);
|
||||
return $this->getModel()->getSiteUrlsFromId($idSite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all the website IDs registered.
|
||||
* Caller must check access.
|
||||
*
|
||||
* @return array The list of website IDs
|
||||
*/
|
||||
private function getSitesId()
|
||||
{
|
||||
$result = Db::fetchAll("SELECT idsite FROM " . Common::prefixTable('site'));
|
||||
$idSites = array();
|
||||
foreach ($result as $idSite) {
|
||||
$idSites[] = $idSite['idsite'];
|
||||
}
|
||||
return $idSites;
|
||||
return $this->getModel()->getSitesId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -247,12 +228,15 @@ class API extends \Piwik\Plugin\API
|
|||
public function getAllSites()
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$sites = Db::get()->fetchAll("SELECT * FROM " . Common::prefixTable("site") . " ORDER BY idsite ASC");
|
||||
|
||||
$sites = $this->getModel()->getAllSites();
|
||||
$return = array();
|
||||
foreach ($sites as $site) {
|
||||
$return[$site['idsite']] = $site;
|
||||
}
|
||||
|
||||
Site::setSitesFromArray($return);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +250,7 @@ class API extends \Piwik\Plugin\API
|
|||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
try {
|
||||
return API::getInstance()->getSitesId();
|
||||
return $this->getSitesId();
|
||||
} catch (Exception $e) {
|
||||
// can be called before Piwik tables are created so return empty
|
||||
return array();
|
||||
|
|
@ -279,6 +263,7 @@ class API extends \Piwik\Plugin\API
|
|||
*
|
||||
* @param bool|int $timestamp
|
||||
* @return array The list of website IDs
|
||||
* @deprecated since 2.15 This method will be removed in Piwik 3.0, there is no replacement.
|
||||
*/
|
||||
public function getSitesIdWithVisits($timestamp = false)
|
||||
{
|
||||
|
|
@ -286,24 +271,16 @@ class API extends \Piwik\Plugin\API
|
|||
|
||||
if (empty($timestamp)) $timestamp = time();
|
||||
|
||||
$time = Date::factory((int)$timestamp)->getDatetime();
|
||||
$result = Db::fetchAll("
|
||||
SELECT
|
||||
idsite
|
||||
FROM
|
||||
" . Common::prefixTable('site') . " s
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM " . Common::prefixTable('log_visit') . " v
|
||||
WHERE v.idsite = s.idsite
|
||||
AND visit_last_action_time > ?
|
||||
AND visit_last_action_time <= ?
|
||||
LIMIT 1)
|
||||
", array($time, $now = Date::now()->addHour(1)->getDatetime()));
|
||||
$time = Date::factory((int)$timestamp)->getDatetime();
|
||||
$now = Date::now()->addHour(1)->getDatetime();
|
||||
|
||||
$result = $this->getModel()->getSitesWithVisits($time, $now);
|
||||
|
||||
$idSites = array();
|
||||
foreach ($result as $idSite) {
|
||||
$idSites[] = $idSite['idsite'];
|
||||
}
|
||||
|
||||
return $idSites;
|
||||
}
|
||||
|
||||
|
|
@ -311,12 +288,29 @@ class API extends \Piwik\Plugin\API
|
|||
* Returns the list of websites with the 'admin' access for the current user.
|
||||
* For the superUser it returns all the websites in the database.
|
||||
*
|
||||
* @param bool $fetchAliasUrls
|
||||
* @param false|string $pattern
|
||||
* @param false|int $limit
|
||||
* @return array for each site, an array of information (idsite, name, main_url, etc.)
|
||||
*/
|
||||
public function getSitesWithAdminAccess()
|
||||
public function getSitesWithAdminAccess($fetchAliasUrls = false, $pattern = false, $limit = false)
|
||||
{
|
||||
$sitesId = $this->getSitesIdWithAdminAccess();
|
||||
return $this->getSitesFromIds($sitesId);
|
||||
|
||||
if ($pattern === false) {
|
||||
$sites = $this->getSitesFromIds($sitesId, $limit);
|
||||
} else {
|
||||
$sites = $this->getModel()->getPatternMatchSites($sitesId, $pattern, $limit);
|
||||
Site::setSitesFromArray($sites);
|
||||
}
|
||||
|
||||
if ($fetchAliasUrls) {
|
||||
foreach ($sites as &$site) {
|
||||
$site['alias_urls'] = $this->getSiteUrlsFromId($site['idsite']);
|
||||
}
|
||||
}
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -377,7 +371,10 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getSitesIdWithAtLeastViewAccess($_restrictSitesToLogin = false)
|
||||
{
|
||||
if (Piwik::hasUserSuperUserAccess() && !TaskScheduler::isTaskBeingExecuted()) {
|
||||
/** @var Scheduler $scheduler */
|
||||
$scheduler = StaticContainer::getContainer()->get('Piwik\Scheduler\Scheduler');
|
||||
|
||||
if (Piwik::hasUserSuperUserAccess() && !$scheduler->isRunningTask()) {
|
||||
return Access::getInstance()->getSitesIdWithAtLeastViewAccess();
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +383,7 @@ class API extends \Piwik\Plugin\API
|
|||
// but during scheduled task execution, we sometimes want to restrict sites to
|
||||
// a different login than the superuser.
|
||||
&& (Piwik::hasUserSuperUserAccessOrIsTheUser($_restrictSitesToLogin)
|
||||
|| TaskScheduler::isTaskBeingExecuted())
|
||||
|| $scheduler->isRunningTask())
|
||||
) {
|
||||
|
||||
if (Piwik::hasTheUserSuperUserAccess($_restrictSitesToLogin)) {
|
||||
|
|
@ -394,10 +391,12 @@ class API extends \Piwik\Plugin\API
|
|||
}
|
||||
|
||||
$accessRaw = Access::getInstance()->getRawSitesWithSomeViewAccess($_restrictSitesToLogin);
|
||||
$sitesId = array();
|
||||
$sitesId = array();
|
||||
|
||||
foreach ($accessRaw as $access) {
|
||||
$sitesId[] = $access['idsite'];
|
||||
}
|
||||
|
||||
return $sitesId;
|
||||
} else {
|
||||
return Access::getInstance()->getSitesIdWithAtLeastViewAccess();
|
||||
|
|
@ -414,32 +413,28 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
private function getSitesFromIds($idSites, $limit = false)
|
||||
{
|
||||
if (count($idSites) === 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($limit) {
|
||||
$limit = "LIMIT " . (int)$limit;
|
||||
}
|
||||
|
||||
$db = Db::get();
|
||||
$sites = $db->fetchAll("SELECT *
|
||||
FROM " . Common::prefixTable("site") . "
|
||||
WHERE idsite IN (" . implode(", ", $idSites) . ")
|
||||
ORDER BY idsite ASC $limit");
|
||||
$sites = $this->getModel()->getSitesFromIds($idSites, $limit);
|
||||
|
||||
Site::setSitesFromArray($sites);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
protected function getNormalizedUrls($url)
|
||||
{
|
||||
if (strpos($url, 'www.') !== false) {
|
||||
$urlBis = str_replace('www.', '', $url);
|
||||
} else {
|
||||
$urlBis = str_replace('://', '://www.', $url);
|
||||
}
|
||||
return array($url, $urlBis);
|
||||
// if found, remove scheme and www. from URL
|
||||
$hostname = str_replace('www.', '', $url);
|
||||
$hostname = str_replace('http://', '', $hostname);
|
||||
$hostname = str_replace('https://', '', $hostname);
|
||||
|
||||
// return all variations of the URL
|
||||
return array(
|
||||
$url,
|
||||
"http://" . $hostname,
|
||||
"http://www." . $hostname,
|
||||
"https://" . $hostname,
|
||||
"https://www." . $hostname
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -451,29 +446,13 @@ class API extends \Piwik\Plugin\API
|
|||
public function getSitesIdFromSiteUrl($url)
|
||||
{
|
||||
$url = $this->removeTrailingSlash($url);
|
||||
list($url, $urlBis) = $this->getNormalizedUrls($url);
|
||||
$normalisedUrls = $this->getNormalizedUrls($url);
|
||||
|
||||
if (Piwik::hasUserSuperUserAccess()) {
|
||||
$ids = Db::get()->fetchAll(
|
||||
'SELECT idsite
|
||||
FROM ' . Common::prefixTable('site') . '
|
||||
WHERE (main_url = ? OR main_url = ?) ' .
|
||||
'UNION
|
||||
SELECT idsite
|
||||
FROM ' . Common::prefixTable('site_url') . '
|
||||
WHERE (url = ? OR url = ?) ', array($url, $urlBis, $url, $urlBis));
|
||||
$ids = $this->getModel()->getAllSitesIdFromSiteUrl($normalisedUrls);
|
||||
} else {
|
||||
$login = Piwik::getCurrentUserLogin();
|
||||
$ids = Db::get()->fetchAll(
|
||||
'SELECT idsite
|
||||
FROM ' . Common::prefixTable('site') . '
|
||||
WHERE (main_url = ? OR main_url = ?)' .
|
||||
'AND idsite IN (' . Access::getSqlAccessSite('idsite') . ') ' .
|
||||
'UNION
|
||||
SELECT idsite
|
||||
FROM ' . Common::prefixTable('site_url') . '
|
||||
WHERE (url = ? OR url = ?)' .
|
||||
'AND idsite IN (' . Access::getSqlAccessSite('idsite') . ')',
|
||||
array($url, $urlBis, $login, $url, $urlBis, $login));
|
||||
$ids = $this->getModel()->getSitesIdFromSiteUrlHavingAccess($login, $normalisedUrls);
|
||||
}
|
||||
|
||||
return $ids;
|
||||
|
|
@ -489,18 +468,17 @@ class API extends \Piwik\Plugin\API
|
|||
public function getSitesIdFromTimezones($timezones)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
|
||||
$timezones = Piwik::getArrayFromApiParameter($timezones);
|
||||
$timezones = array_unique($timezones);
|
||||
$ids = Db::get()->fetchAll(
|
||||
'SELECT idsite
|
||||
FROM ' . Common::prefixTable('site') . '
|
||||
WHERE timezone IN (' . Common::getSqlStringFieldsArray($timezones) . ')
|
||||
ORDER BY idsite ASC',
|
||||
$timezones);
|
||||
|
||||
$ids = $this->getModel()->getSitesFromTimezones($timezones);
|
||||
|
||||
$return = array();
|
||||
foreach ($ids as $id) {
|
||||
$return[] = $id['idsite'];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
|
@ -526,8 +504,10 @@ class API extends \Piwik\Plugin\API
|
|||
* @param null|string $excludedUserAgents
|
||||
* @param int $keepURLFragments If 1, URL fragments will be kept when tracking. If 2, they
|
||||
* will be removed. If 0, the default global behavior will be used.
|
||||
* @param array|null $settings JSON serialized settings eg {settingName: settingValue, ...}
|
||||
* @see getKeepURLFragmentsGlobal.
|
||||
* @param string $type The website type, defaults to "website" if not set.
|
||||
* @param bool|null $excludeUnknownUrls Track only URL matching one of website URLs
|
||||
*
|
||||
* @return int the website ID created
|
||||
*/
|
||||
|
|
@ -545,7 +525,9 @@ class API extends \Piwik\Plugin\API
|
|||
$startDate = null,
|
||||
$excludedUserAgents = null,
|
||||
$keepURLFragments = null,
|
||||
$type = null)
|
||||
$type = null,
|
||||
$settings = null,
|
||||
$excludeUnknownUrls = null)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
|
||||
|
|
@ -570,47 +552,53 @@ class API extends \Piwik\Plugin\API
|
|||
}
|
||||
$this->checkValidCurrency($currency);
|
||||
|
||||
$db = Db::get();
|
||||
|
||||
$url = $urls[0];
|
||||
$url = $urls[0];
|
||||
$urls = array_slice($urls, 1);
|
||||
|
||||
$bind = array('name' => $siteName,
|
||||
'main_url' => $url,
|
||||
|
||||
);
|
||||
'main_url' => $url);
|
||||
|
||||
$bind['exclude_unknown_urls'] = (int)$excludeUnknownUrls;
|
||||
$bind['excluded_ips'] = $this->checkAndReturnExcludedIps($excludedIps);
|
||||
$bind['excluded_parameters'] = $this->checkAndReturnCommaSeparatedStringList($excludedQueryParameters);
|
||||
$bind['excluded_parameters'] = $this->checkAndReturnCommaSeparatedStringList($excludedQueryParameters);
|
||||
$bind['excluded_user_agents'] = $this->checkAndReturnCommaSeparatedStringList($excludedUserAgents);
|
||||
$bind['keep_url_fragment'] = $keepURLFragments;
|
||||
$bind['timezone'] = $timezone;
|
||||
$bind['currency'] = $currency;
|
||||
$bind['ecommerce'] = (int)$ecommerce;
|
||||
$bind['keep_url_fragment'] = $keepURLFragments;
|
||||
$bind['timezone'] = $timezone;
|
||||
$bind['currency'] = $currency;
|
||||
$bind['ecommerce'] = (int)$ecommerce;
|
||||
$bind['sitesearch'] = $siteSearch;
|
||||
$bind['sitesearch_keyword_parameters'] = $searchKeywordParameters;
|
||||
$bind['sitesearch_keyword_parameters'] = $searchKeywordParameters;
|
||||
$bind['sitesearch_category_parameters'] = $searchCategoryParameters;
|
||||
$bind['ts_created'] = !is_null($startDate)
|
||||
? Date::factory($startDate)->getDatetime()
|
||||
: Date::now()->getDatetime();
|
||||
|
||||
if (is_null($startDate)) {
|
||||
$bind['ts_created'] = Date::now()->getDatetime();
|
||||
} else {
|
||||
$bind['ts_created'] = Date::factory($startDate)->getDatetime();
|
||||
}
|
||||
|
||||
$bind['type'] = $this->checkAndReturnType($type);
|
||||
|
||||
if (!empty($group)
|
||||
&& Piwik::hasUserSuperUserAccess()
|
||||
) {
|
||||
if (!empty($group) && Piwik::hasUserSuperUserAccess()) {
|
||||
$bind['group'] = trim($group);
|
||||
} else {
|
||||
$bind['group'] = "";
|
||||
}
|
||||
|
||||
$db->insert(Common::prefixTable("site"), $bind);
|
||||
if (!empty($settings)) {
|
||||
$this->validateMeasurableSettings(0, $bind['type'], $settings);
|
||||
}
|
||||
|
||||
$idSite = $db->lastInsertId();
|
||||
$idSite = $this->getModel()->createSite($bind);
|
||||
|
||||
$this->insertSiteUrls($idSite, $urls);
|
||||
|
||||
// we reload the access list which doesn't yet take in consideration this new website
|
||||
Access::getInstance()->reloadAccess();
|
||||
|
||||
if (!empty($settings)) {
|
||||
$this->updateMeasurableSettings($idSite, $settings);
|
||||
}
|
||||
|
||||
$this->postUpdateWebsite($idSite);
|
||||
|
||||
/**
|
||||
|
|
@ -620,13 +608,45 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
Piwik::postEvent('SitesManager.addSite.end', array($idSite));
|
||||
|
||||
return (int)$idSite;
|
||||
return (int) $idSite;
|
||||
}
|
||||
|
||||
private function validateMeasurableSettings($idSite, $idType, $settings)
|
||||
{
|
||||
$measurableSettings = new MeasurableSettings($idSite, $idType);
|
||||
|
||||
foreach ($measurableSettings->getSettingsForCurrentUser() as $measurableSetting) {
|
||||
$name = $measurableSetting->getName();
|
||||
if (!empty($settings[$name])) {
|
||||
$measurableSetting->setValue($settings[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function updateMeasurableSettings($idSite, $settings)
|
||||
{
|
||||
$idType = Site::getTypeFor($idSite);
|
||||
|
||||
$measurableSettings = new MeasurableSettings($idSite, $idType);
|
||||
|
||||
foreach ($measurableSettings->getSettingsForCurrentUser() as $measurableSetting) {
|
||||
$name = $measurableSetting->getName();
|
||||
if (!empty($settings[$name])) {
|
||||
$measurableSetting->setValue($settings[$name]);
|
||||
}
|
||||
// we do not clear existing settings if the value is missing.
|
||||
// There can be so many settings added by random plugins one would always clear some settings.
|
||||
}
|
||||
|
||||
$measurableSettings->save();
|
||||
}
|
||||
|
||||
private function postUpdateWebsite($idSite)
|
||||
{
|
||||
Site::clearCache();
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
Cache::clearCacheGeneral();
|
||||
SiteUrls::clearSitesCache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -641,7 +661,7 @@ class API extends \Piwik\Plugin\API
|
|||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
|
||||
$idSites = API::getInstance()->getSitesId();
|
||||
$idSites = $this->getSitesId();
|
||||
if (!in_array($idSite, $idSites)) {
|
||||
throw new Exception("website id = $idSite not found");
|
||||
}
|
||||
|
|
@ -650,27 +670,15 @@ class API extends \Piwik\Plugin\API
|
|||
throw new Exception(Piwik::translate("SitesManager_ExceptionDeleteSite"));
|
||||
}
|
||||
|
||||
$db = Db::get();
|
||||
|
||||
$db->query("DELETE FROM " . Common::prefixTable("site") . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
|
||||
$db->query("DELETE FROM " . Common::prefixTable("site_url") . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
|
||||
$db->query("DELETE FROM " . Common::prefixTable("access") . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
|
||||
// we do not delete logs here on purpose (you can run these queries on the log_ tables to delete all data)
|
||||
Cache::deleteCacheWebsiteAttributes($idSite);
|
||||
$this->getModel()->deleteSite($idSite);
|
||||
|
||||
/**
|
||||
* Triggered after a site has been deleted.
|
||||
*
|
||||
*
|
||||
* Plugins can use this event to remove site specific values or settings, such as removing all
|
||||
* goals that belong to a specific website. If you store any data related to a website you
|
||||
* should clean up that information here.
|
||||
*
|
||||
*
|
||||
* @param int $idSite The ID of the site being deleted.
|
||||
*/
|
||||
Piwik::postEvent('SitesManager.deleteSite.end', array($idSite));
|
||||
|
|
@ -713,12 +721,14 @@ class API extends \Piwik\Plugin\API
|
|||
|
||||
private function checkAndReturnType($type)
|
||||
{
|
||||
if(empty($type)) {
|
||||
if (empty($type)) {
|
||||
$type = Site::DEFAULT_SITE_TYPE;
|
||||
}
|
||||
if(!is_string($type)) {
|
||||
|
||||
if (!is_string($type)) {
|
||||
throw new Exception("Invalid website type $type");
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
|
@ -735,14 +745,17 @@ class API extends \Piwik\Plugin\API
|
|||
if (empty($excludedIps)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$ips = explode(',', $excludedIps);
|
||||
$ips = array_map('trim', $ips);
|
||||
$ips = array_filter($ips, 'strlen');
|
||||
|
||||
foreach ($ips as $ip) {
|
||||
if (!$this->isValidIp($ip)) {
|
||||
throw new Exception(Piwik::translate('SitesManager_ExceptionInvalidIPFormat', array($ip, "1.2.3.4, 1.2.3.*, or 1.2.3.4/5")));
|
||||
}
|
||||
}
|
||||
|
||||
$ips = implode(',', $ips);
|
||||
return $ips;
|
||||
}
|
||||
|
|
@ -787,7 +800,7 @@ class API extends \Piwik\Plugin\API
|
|||
$urls = $this->cleanParameterUrls($urls);
|
||||
$this->checkUrls($urls);
|
||||
|
||||
$this->deleteSiteAliasUrls($idSite);
|
||||
$this->getModel()->deleteSiteAliasUrls($idSite);
|
||||
$this->insertSiteUrls($idSite, $urls);
|
||||
$this->postUpdateWebsite($idSite);
|
||||
|
||||
|
|
@ -802,12 +815,12 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getIpsForRange($ipRange)
|
||||
{
|
||||
$range = IP::getIpsForRange($ipRange);
|
||||
if ($range === false) {
|
||||
$range = IPUtils::getIPRangeBounds($ipRange);
|
||||
if ($range === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array(IP::N2P($range[0]), IP::N2P($range[1]));
|
||||
return array(IPUtils::binaryToStringIP($range[0]), IPUtils::binaryToStringIP($range[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1078,6 +1091,8 @@ class API extends \Piwik\Plugin\API
|
|||
* @param int|null $keepURLFragments If 1, URL fragments will be kept when tracking. If 2, they
|
||||
* will be removed. If 0, the default global behavior will be used.
|
||||
* @param string $type The Website type, default value is "website"
|
||||
* @param array|null $settings JSON serialized settings eg {settingName: settingValue, ...}
|
||||
* @param bool|null $excludeUnknownUrls Track only URL matching one of website URLs
|
||||
* @throws Exception
|
||||
* @see getKeepURLFragmentsGlobal. If null, the existing value will
|
||||
* not be modified.
|
||||
|
|
@ -1099,11 +1114,14 @@ class API extends \Piwik\Plugin\API
|
|||
$startDate = null,
|
||||
$excludedUserAgents = null,
|
||||
$keepURLFragments = null,
|
||||
$type = null)
|
||||
$type = null,
|
||||
$settings = null,
|
||||
$excludeUnknownUrls = null)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
|
||||
$idSites = API::getInstance()->getSitesId();
|
||||
$idSites = $this->getSitesId();
|
||||
|
||||
if (!in_array($idSite, $idSites)) {
|
||||
throw new Exception("website id = $idSite not found");
|
||||
}
|
||||
|
|
@ -1145,6 +1163,7 @@ class API extends \Piwik\Plugin\API
|
|||
if (!is_null($startDate)) {
|
||||
$bind['ts_created'] = Date::factory($startDate)->getDatetime();
|
||||
}
|
||||
$bind['exclude_unknown_urls'] = (int)$excludeUnknownUrls;
|
||||
$bind['excluded_ips'] = $this->checkAndReturnExcludedIps($excludedIps);
|
||||
$bind['excluded_parameters'] = $this->checkAndReturnCommaSeparatedStringList($excludedQueryParameters);
|
||||
$bind['excluded_user_agents'] = $this->checkAndReturnCommaSeparatedStringList($excludedUserAgents);
|
||||
|
|
@ -1160,20 +1179,28 @@ class API extends \Piwik\Plugin\API
|
|||
list($searchKeywordParameters, $searchCategoryParameters) = $this->checkSiteSearchParameters($searchKeywordParameters, $searchCategoryParameters);
|
||||
$bind['sitesearch_keyword_parameters'] = $searchKeywordParameters;
|
||||
$bind['sitesearch_category_parameters'] = $searchCategoryParameters;
|
||||
$bind['type'] = $this->checkAndReturnType($type);
|
||||
|
||||
$db = Db::get();
|
||||
$db->update(Common::prefixTable("site"),
|
||||
$bind,
|
||||
"idsite = $idSite"
|
||||
);
|
||||
if (!is_null($type)) {
|
||||
$bind['type'] = $this->checkAndReturnType($type);
|
||||
}
|
||||
|
||||
if (!empty($settings)) {
|
||||
$this->validateMeasurableSettings($idSite, Site::getTypeFor($idSite), $settings);
|
||||
}
|
||||
|
||||
$this->getModel()->updateSite($bind, $idSite);
|
||||
|
||||
if (!empty($settings)) {
|
||||
$this->updateMeasurableSettings($idSite, $settings);
|
||||
}
|
||||
|
||||
// we now update the main + alias URLs
|
||||
$this->deleteSiteAliasUrls($idSite);
|
||||
$this->getModel()->deleteSiteAliasUrls($idSite);
|
||||
|
||||
if (count($urls) > 1) {
|
||||
$this->addSiteAliasUrls($idSite, array_slice($urls, 1));
|
||||
}
|
||||
|
||||
$this->postUpdateWebsite($idSite);
|
||||
}
|
||||
|
||||
|
|
@ -1185,19 +1212,14 @@ class API extends \Piwik\Plugin\API
|
|||
*
|
||||
* @ignore
|
||||
*/
|
||||
public function updateSiteCreatedTime($idSites, $minDate)
|
||||
public function updateSiteCreatedTime($idSites, Date $minDate)
|
||||
{
|
||||
$idSites = Site::getIdSitesFromIdSitesString($idSites);
|
||||
Piwik::checkUserHasAdminAccess($idSites);
|
||||
|
||||
// Update piwik_site.ts_created
|
||||
$query = "UPDATE " . Common::prefixTable("site") .
|
||||
" SET ts_created = ?" .
|
||||
" WHERE idsite IN ( " . implode(",", $idSites) . " )
|
||||
AND ts_created > ?";
|
||||
$minDateSql = $minDate->subDay(1)->getDatetime();
|
||||
$bind = array($minDateSql, $minDateSql);
|
||||
Db::query($query, $bind);
|
||||
|
||||
$this->getModel()->updateSiteCreatedTime($idSites, $minDateSql);
|
||||
}
|
||||
|
||||
private function checkAndReturnCommaSeparatedStringList($parameters)
|
||||
|
|
@ -1221,7 +1243,7 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getCurrencyList()
|
||||
{
|
||||
$currencies = MetricsFormatter::getCurrencyList();
|
||||
$currencies = Site::getCurrencyList();
|
||||
return array_map(function ($a) {
|
||||
return $a[1] . " (" . $a[0] . ")";
|
||||
}, $currencies);
|
||||
|
|
@ -1234,12 +1256,23 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getCurrencySymbols()
|
||||
{
|
||||
$currencies = MetricsFormatter::getCurrencyList();
|
||||
$currencies = Site::getCurrencyList();
|
||||
return array_map(function ($a) {
|
||||
return $a[0];
|
||||
}, $currencies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Timezone support is enabled on server
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTimezoneSupportEnabled()
|
||||
{
|
||||
Piwik::checkUserHasSomeViewAccess();
|
||||
return SettingsServer::isTimezoneSupportEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of timezones supported.
|
||||
* Used for addSite and updateSite
|
||||
|
|
@ -1297,6 +1330,8 @@ class API extends \Piwik\Plugin\API
|
|||
|
||||
$return = array();
|
||||
foreach ($GmtOffsets as $offset) {
|
||||
$offset = Common::forceDotAsSeparatorForDecimalPoint($offset);
|
||||
|
||||
if ($offset > 0) {
|
||||
$offset = '+' . $offset;
|
||||
} elseif ($offset == 0) {
|
||||
|
|
@ -1317,12 +1352,8 @@ class API extends \Piwik\Plugin\API
|
|||
public function getUniqueSiteTimezones()
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$results = Db::fetchAll("SELECT distinct timezone FROM " . Common::prefixTable('site'));
|
||||
$timezones = array();
|
||||
foreach ($results as $result) {
|
||||
$timezones[] = $result['timezone'];
|
||||
}
|
||||
return $timezones;
|
||||
|
||||
return $this->getModel()->getUniqueSiteTimezones();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1332,14 +1363,9 @@ class API extends \Piwik\Plugin\API
|
|||
private function insertSiteUrls($idSite, $urls)
|
||||
{
|
||||
if (count($urls) != 0) {
|
||||
$db = Db::get();
|
||||
foreach ($urls as $url) {
|
||||
try {
|
||||
$db->insert(Common::prefixTable("site_url"), array(
|
||||
'idsite' => $idSite,
|
||||
'url' => $url
|
||||
)
|
||||
);
|
||||
$this->getModel()->insertSiteUrl($idSite, $url);
|
||||
} catch(Exception $e) {
|
||||
// See bug #4149
|
||||
}
|
||||
|
|
@ -1347,16 +1373,6 @@ class API extends \Piwik\Plugin\API
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the alias URLs for the given idSite.
|
||||
*/
|
||||
private function deleteSiteAliasUrls($idsite)
|
||||
{
|
||||
$db = Db::get();
|
||||
$db->query("DELETE FROM " . Common::prefixTable("site_url") . "
|
||||
WHERE idsite = ?", $idsite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the final slash in the URLs if found
|
||||
*
|
||||
|
|
@ -1371,6 +1387,7 @@ class API extends \Piwik\Plugin\API
|
|||
) {
|
||||
$url = substr($url, 0, strlen($url) - 1);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
|
@ -1394,7 +1411,7 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
private function isValidIp($ip)
|
||||
{
|
||||
return IP::getIpsForRange($ip) !== false;
|
||||
return IPUtils::getIPRangeBounds($ip) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1425,6 +1442,7 @@ class API extends \Piwik\Plugin\API
|
|||
if (empty($searchKeywordParameters)) {
|
||||
$searchKeywordParameters = '';
|
||||
}
|
||||
|
||||
if (empty($searchCategoryParameters)) {
|
||||
$searchCategoryParameters = '';
|
||||
}
|
||||
|
|
@ -1460,17 +1478,22 @@ class API extends \Piwik\Plugin\API
|
|||
if (!is_array($urls)) {
|
||||
$urls = array($urls);
|
||||
}
|
||||
$urls = array_filter($urls);
|
||||
|
||||
$urls = array_filter($urls);
|
||||
$urls = array_map('urldecode', $urls);
|
||||
|
||||
foreach ($urls as &$url) {
|
||||
$url = $this->removeTrailingSlash($url);
|
||||
if (strpos($url, 'http') !== 0) {
|
||||
$scheme = parse_url($url, PHP_URL_SCHEME);
|
||||
if (empty($scheme)
|
||||
&& strpos($url, '://') === false
|
||||
) {
|
||||
$url = 'http://' . $url;
|
||||
}
|
||||
$url = trim($url);
|
||||
$url = Common::sanitizeInputValue($url);
|
||||
}
|
||||
|
||||
$urls = array_unique($urls);
|
||||
return $urls;
|
||||
}
|
||||
|
|
@ -1503,40 +1526,45 @@ class API extends \Piwik\Plugin\API
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getPatternMatchSites($pattern)
|
||||
/**
|
||||
* Find websites matching the given pattern.
|
||||
*
|
||||
* Any website will be returned that matches the pattern in the name, URL or group.
|
||||
* To limit the number of returned sites you can either specify `filter_limit` as usual or `limit` which is
|
||||
* faster.
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param int|false $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getPatternMatchSites($pattern, $limit = false)
|
||||
{
|
||||
$ids = $this->getSitesIdWithAtLeastViewAccess();
|
||||
if (empty($ids)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$ids_str = '';
|
||||
foreach ($ids as $id_val) {
|
||||
$ids_str .= $id_val . ' , ';
|
||||
}
|
||||
$ids_str .= $id_val;
|
||||
$sites = $this->getModel()->getPatternMatchSites($ids, $pattern, $limit);
|
||||
|
||||
$db = Db::get();
|
||||
$bind = array('%' . $pattern . '%', 'http%' . $pattern . '%', '%' . $pattern . '%');
|
||||
|
||||
// Also match the idsite
|
||||
$where = '';
|
||||
if (is_numeric($pattern)) {
|
||||
$bind[] = $pattern;
|
||||
$where = 'OR s.idsite = ?';
|
||||
}
|
||||
$sites = $db->fetchAll("SELECT idsite, name, main_url, `group`
|
||||
FROM " . Common::prefixTable('site') . " s
|
||||
WHERE ( s.name like ?
|
||||
OR s.main_url like ?
|
||||
OR s.`group` like ?
|
||||
$where )
|
||||
AND idsite in ($ids_str)
|
||||
LIMIT " . SettingsPiwik::getWebsitesCountToDisplay(),
|
||||
$bind);
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of websites to display per page.
|
||||
*
|
||||
* For example this is used in the All Websites Dashboard, in the Website Selector etc. If multiple websites are
|
||||
* shown somewhere, one should request this method to detect how many websites should be shown per page when
|
||||
* using paging. To use paging is always recommended since some installations have thousands of websites.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumWebsitesToDisplayPerPage()
|
||||
{
|
||||
Piwik::checkUserHasSomeViewAccess();
|
||||
|
||||
return SettingsPiwik::getWebsitesCountToDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function that throws if a value is not valid for the 'keep_url_fragment'
|
||||
* column of the piwik_site table.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -11,15 +11,13 @@ namespace Piwik\Plugins\SitesManager;
|
|||
use Exception;
|
||||
use Piwik\API\ResponseBuilder;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable\Renderer\Json;
|
||||
use Piwik\Date;
|
||||
use Piwik\IP;
|
||||
use Piwik\Exception\UnexpectedWebsiteFoundException;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Measurable\MeasurableSettings;
|
||||
use Piwik\SettingsPiwik;
|
||||
use Piwik\SettingsServer;
|
||||
use Piwik\Site;
|
||||
use Piwik\Tracker\TrackerCodeGenerator;
|
||||
use Piwik\Url;
|
||||
use Piwik\UrlHelper;
|
||||
use Piwik\View;
|
||||
|
||||
/**
|
||||
|
|
@ -32,62 +30,53 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$view = new View('@SitesManager/index');
|
||||
Piwik::checkUserHasSomeAdminAccess();
|
||||
|
||||
Site::clearCache();
|
||||
if (Piwik::hasUserSuperUserAccess()) {
|
||||
$sitesRaw = API::getInstance()->getAllSites();
|
||||
return $this->renderTemplate('index');
|
||||
}
|
||||
|
||||
public function getMeasurableTypeSettings()
|
||||
{
|
||||
$idSite = Common::getRequestVar('idSite', 0, 'int');
|
||||
$idType = Common::getRequestVar('idType', '', 'string');
|
||||
|
||||
if ($idSite >= 1) {
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
} else if ($idSite === 0) {
|
||||
Piwik::checkUserHasSomeAdminAccess();
|
||||
} else {
|
||||
$sitesRaw = API::getInstance()->getSitesWithAdminAccess();
|
||||
}
|
||||
// Gets sites after Site.setSite hook was called
|
||||
$sites = array_values( Site::getSites() );
|
||||
if(count($sites) != count($sitesRaw)) {
|
||||
throw new Exception("One or more website are missing or invalid.");
|
||||
throw new Exception('Invalid idSite parameter. IdSite has to be zero or higher');
|
||||
}
|
||||
|
||||
foreach ($sites as &$site) {
|
||||
$site['alias_urls'] = API::getInstance()->getSiteUrlsFromId($site['idsite']);
|
||||
$site['excluded_ips'] = explode(',', $site['excluded_ips']);
|
||||
$site['excluded_parameters'] = explode(',', $site['excluded_parameters']);
|
||||
$site['excluded_user_agents'] = explode(',', $site['excluded_user_agents']);
|
||||
}
|
||||
$view->adminSites = $sites;
|
||||
$view->adminSitesCount = count($sites);
|
||||
$view = new View('@SitesManager/measurable_type_settings');
|
||||
|
||||
$timezones = API::getInstance()->getTimezonesList();
|
||||
$view->timezoneSupported = SettingsServer::isTimezoneSupportEnabled();
|
||||
$view->timezones = Common::json_encode($timezones);
|
||||
$view->defaultTimezone = API::getInstance()->getDefaultTimezone();
|
||||
$propSettings = new MeasurableSettings($idSite, $idType);
|
||||
$view->settings = $propSettings->getSettingsForCurrentUser();
|
||||
|
||||
$view->currencies = Common::json_encode(API::getInstance()->getCurrencyList());
|
||||
$view->defaultCurrency = API::getInstance()->getDefaultCurrency();
|
||||
|
||||
$view->utcTime = Date::now()->getDatetime();
|
||||
$excludedIpsGlobal = API::getInstance()->getExcludedIpsGlobal();
|
||||
$view->globalExcludedIps = str_replace(',', "\n", $excludedIpsGlobal);
|
||||
$excludedQueryParametersGlobal = API::getInstance()->getExcludedQueryParametersGlobal();
|
||||
$view->globalExcludedQueryParameters = str_replace(',', "\n", $excludedQueryParametersGlobal);
|
||||
|
||||
$globalExcludedUserAgents = API::getInstance()->getExcludedUserAgentsGlobal();
|
||||
$view->globalExcludedUserAgents = str_replace(',', "\n", $globalExcludedUserAgents);
|
||||
|
||||
$view->globalSearchKeywordParameters = API::getInstance()->getSearchKeywordParametersGlobal();
|
||||
$view->globalSearchCategoryParameters = API::getInstance()->getSearchCategoryParametersGlobal();
|
||||
$view->isSearchCategoryTrackingEnabled = \Piwik\Plugin\Manager::getInstance()->isPluginActivated('CustomVariables');
|
||||
$view->allowSiteSpecificUserAgentExclude =
|
||||
API::getInstance()->isSiteSpecificUserAgentExcludeEnabled();
|
||||
|
||||
$view->globalKeepURLFragments = API::getInstance()->getKeepURLFragmentsGlobal();
|
||||
|
||||
$view->currentIpAddress = IP::getIpFromHeader();
|
||||
|
||||
$view->showAddSite = (boolean)Common::getRequestVar('showaddsite', false);
|
||||
|
||||
$this->setBasicVariablesView($view);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function getGlobalSettings()
|
||||
{
|
||||
Piwik::checkUserHasSomeViewAccess();
|
||||
|
||||
$response = new ResponseBuilder(Common::getRequestVar('format'));
|
||||
|
||||
$globalSettings = array();
|
||||
|
||||
$globalSettings['keepURLFragmentsGlobal'] = API::getInstance()->getKeepURLFragmentsGlobal();
|
||||
$globalSettings['siteSpecificUserAgentExcludeEnabled'] = API::getInstance()->isSiteSpecificUserAgentExcludeEnabled();
|
||||
$globalSettings['defaultCurrency'] = API::getInstance()->getDefaultCurrency();
|
||||
$globalSettings['searchKeywordParametersGlobal'] = API::getInstance()->getSearchKeywordParametersGlobal();
|
||||
$globalSettings['searchCategoryParametersGlobal'] = API::getInstance()->getSearchCategoryParametersGlobal();
|
||||
$globalSettings['defaultTimezone'] = API::getInstance()->getDefaultTimezone();
|
||||
$globalSettings['excludedIpsGlobal'] = API::getInstance()->getExcludedIpsGlobal();
|
||||
$globalSettings['excludedQueryParametersGlobal'] = API::getInstance()->getExcludedQueryParametersGlobal();
|
||||
$globalSettings['excludedUserAgentsGlobal'] = API::getInstance()->getExcludedUserAgentsGlobal();
|
||||
|
||||
return $response->getResponse($globalSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records Global settings when user submit changes
|
||||
*/
|
||||
|
|
@ -133,15 +122,15 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
|
|||
{
|
||||
$idSite = Common::getRequestVar('idSite');
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$jsTag = Piwik::getJavascriptCode($idSite, SettingsPiwik::getPiwikUrl());
|
||||
$view = new View('@SitesManager/displayJavascriptCode');
|
||||
$this->setBasicVariablesView($view);
|
||||
$view->idSite = $idSite;
|
||||
$site = new Site($idSite);
|
||||
$view->displaySiteName = $site->getName();
|
||||
$view->jsTag = $jsTag;
|
||||
$javascriptGenerator = new TrackerCodeGenerator();
|
||||
$jsTag = $javascriptGenerator->generate($idSite, SettingsPiwik::getPiwikUrl());
|
||||
$site = new Site($idSite);
|
||||
|
||||
return $view->render();
|
||||
return $this->renderTemplate('displayJavascriptCode', array(
|
||||
'idSite' => $idSite,
|
||||
'displaySiteName' => $site->getName(),
|
||||
'jsTag' => $jsTag
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -155,4 +144,24 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
|
|||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
return file_get_contents($path . $filename);
|
||||
}
|
||||
|
||||
public function siteWithoutData()
|
||||
{
|
||||
$javascriptGenerator = new TrackerCodeGenerator();
|
||||
$piwikUrl = Url::getCurrentUrlWithoutFileName();
|
||||
|
||||
if (!$this->site) {
|
||||
throw new UnexpectedWebsiteFoundException('Invalid site ' . $this->idSite);
|
||||
}
|
||||
|
||||
return $this->renderTemplate('siteWithoutData', array(
|
||||
'siteName' => $this->site->getName(),
|
||||
'trackingHelp' => $this->renderTemplate('_displayJavascriptCode', array(
|
||||
'displaySiteName' => Common::unsanitizeInputValue($this->site->getName()),
|
||||
'jsTag' => $javascriptGenerator->generate($this->idSite, $piwikUrl),
|
||||
'idSite' => $this->idSite,
|
||||
'piwikUrl' => $piwikUrl,
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
58
www/analytics/plugins/SitesManager/Menu.php
Normal file
58
www/analytics/plugins/SitesManager/Menu.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\SitesManager;
|
||||
|
||||
use Piwik\Menu\MenuAdmin;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Measurable\Type\TypeManager;
|
||||
|
||||
class Menu extends \Piwik\Plugin\Menu
|
||||
{
|
||||
private $typeManager;
|
||||
|
||||
public function __construct(TypeManager $typeManager)
|
||||
{
|
||||
$this->typeManager = $typeManager;
|
||||
}
|
||||
|
||||
public function configureAdminMenu(MenuAdmin $menu)
|
||||
{
|
||||
if (Piwik::isUserHasSomeAdminAccess()) {
|
||||
$type = $this->getFirstTypeIfOnlyOneIsInUse();
|
||||
|
||||
$menuName = 'General_Measurables';
|
||||
if ($type) {
|
||||
$menuName = $type->getNamePlural();
|
||||
}
|
||||
|
||||
$menu->addManageItem($menuName,
|
||||
$this->urlForAction('index'),
|
||||
$order = 1);
|
||||
}
|
||||
}
|
||||
|
||||
private function getFirstTypeIfOnlyOneIsInUse()
|
||||
{
|
||||
$types = $this->typeManager->getAllTypes();
|
||||
|
||||
if (count($types) === 1) {
|
||||
// only one type is in use, use this one for the wording
|
||||
return reset($types);
|
||||
} else {
|
||||
// multiple types are activated, check whether only one is actually in use
|
||||
$model = new Model();
|
||||
$typeIds = $model->getUsedTypeIds();
|
||||
|
||||
if (count($typeIds) === 1) {
|
||||
$typeManager = new TypeManager();
|
||||
return $typeManager->getType(reset($typeIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
428
www/analytics/plugins/SitesManager/Model.php
Normal file
428
www/analytics/plugins/SitesManager/Model.php
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\SitesManager;
|
||||
|
||||
use Piwik\Access;
|
||||
use Piwik\Date;
|
||||
use Piwik\Db;
|
||||
use Piwik\Common;
|
||||
use Exception;
|
||||
|
||||
class Model
|
||||
{
|
||||
private static $rawPrefix = 'site';
|
||||
private $table;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->table = Common::prefixTable(self::$rawPrefix);
|
||||
}
|
||||
|
||||
public function createSite($site)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$db->insert($this->table, $site);
|
||||
|
||||
$idSite = $db->lastInsertId();
|
||||
|
||||
return $idSite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all websites belonging to the specified group
|
||||
* @param string $group Group name
|
||||
* @return array of sites
|
||||
*/
|
||||
public function getSitesFromGroup($group)
|
||||
{
|
||||
$sites = $this->getDb()->fetchAll("SELECT * FROM " . $this->table . "
|
||||
WHERE `group` = ?", $group);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of website groups, including the empty group
|
||||
* if no group were specified for some websites
|
||||
*
|
||||
* @return array of group names strings
|
||||
*/
|
||||
public function getSitesGroups()
|
||||
{
|
||||
$groups = $this->getDb()->fetchAll("SELECT DISTINCT `group` FROM " . $this->table);
|
||||
|
||||
$cleanedGroups = array();
|
||||
foreach ($groups as $group) {
|
||||
$cleanedGroups[] = $group['group'];
|
||||
}
|
||||
|
||||
return $cleanedGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all websites
|
||||
*
|
||||
* @return array The list of websites, indexed by idsite
|
||||
*/
|
||||
public function getAllSites()
|
||||
{
|
||||
$sites = $this->getDb()->fetchAll("SELECT * FROM " . $this->table . " ORDER BY idsite ASC");
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of the website IDs that received some visits since the specified timestamp.
|
||||
*
|
||||
* @param string $time
|
||||
* @param string $now
|
||||
* @return array The list of website IDs
|
||||
*/
|
||||
public function getSitesWithVisits($time, $now)
|
||||
{
|
||||
$sites = Db::fetchAll("
|
||||
SELECT idsite FROM " . $this->table . " s
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM " . Common::prefixTable('log_visit') . " v
|
||||
WHERE v.idsite = s.idsite
|
||||
AND visit_last_action_time > ?
|
||||
AND visit_last_action_time <= ?
|
||||
LIMIT 1)
|
||||
", array($time, $now));
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of websites ID associated with a URL.
|
||||
*
|
||||
* @param array $urls
|
||||
* @return array list of websites ID
|
||||
*/
|
||||
public function getAllSitesIdFromSiteUrl(array $urls)
|
||||
{
|
||||
$siteUrlTable = Common::prefixTable('site_url');
|
||||
|
||||
$ids = $this->getDb()->fetchAll(
|
||||
'SELECT idsite FROM ' . $this->table . '
|
||||
WHERE main_url IN ( ' . Common::getSqlStringFieldsArray($urls) . ') ' .
|
||||
'UNION
|
||||
SELECT idsite FROM ' . $siteUrlTable . '
|
||||
WHERE url IN ( ' . Common::getSqlStringFieldsArray($urls) . ') ',
|
||||
|
||||
// Bind
|
||||
array_merge( $urls, $urls)
|
||||
);
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of websites ID associated with a URL.
|
||||
*
|
||||
* @param string $login
|
||||
* @param array $urls
|
||||
* @return array list of websites ID
|
||||
*/
|
||||
public function getSitesIdFromSiteUrlHavingAccess($login, $urls)
|
||||
{
|
||||
$siteUrlTable = Common::prefixTable('site_url');
|
||||
$sqlAccessSite = Access::getSqlAccessSite('idsite');
|
||||
|
||||
$ids = $this->getDb()->fetchAll(
|
||||
'SELECT idsite
|
||||
FROM ' . $this->table . '
|
||||
WHERE main_url IN ( ' . Common::getSqlStringFieldsArray($urls) . ')' .
|
||||
'AND idsite IN (' . $sqlAccessSite . ') ' .
|
||||
'UNION
|
||||
SELECT idsite
|
||||
FROM ' . $siteUrlTable . '
|
||||
WHERE url IN ( ' . Common::getSqlStringFieldsArray($urls) . ')' .
|
||||
'AND idsite IN (' . $sqlAccessSite . ')',
|
||||
|
||||
// Bind
|
||||
array_merge( $urls,
|
||||
array( $login ),
|
||||
$urls,
|
||||
array( $login )
|
||||
)
|
||||
);
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all websites with a timezone matching one the specified timezones
|
||||
*
|
||||
* @param array $timezones
|
||||
* @return array
|
||||
* @ignore
|
||||
*/
|
||||
public function getSitesFromTimezones($timezones)
|
||||
{
|
||||
$query = 'SELECT idsite FROM ' . $this->table . '
|
||||
WHERE timezone IN (' . Common::getSqlStringFieldsArray($timezones) . ')
|
||||
ORDER BY idsite ASC';
|
||||
$sites = $this->getDb()->fetchAll($query, $timezones);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
public function deleteSite($idSite)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$db->query("DELETE FROM " . $this->table . " WHERE idsite = ?", $idSite);
|
||||
$db->query("DELETE FROM " . Common::prefixTable("site_url") . " WHERE idsite = ?", $idSite);
|
||||
$db->query("DELETE FROM " . Common::prefixTable("access") . " WHERE idsite = ?", $idSite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of websites from the ID array in parameters.
|
||||
*
|
||||
* @param array $idSites list of website ID
|
||||
* @param bool $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getSitesFromIds($idSites, $limit = false)
|
||||
{
|
||||
if (count($idSites) === 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($limit) {
|
||||
$limit = "LIMIT " . (int)$limit;
|
||||
} else {
|
||||
$limit = '';
|
||||
}
|
||||
|
||||
$idSites = array_map('intval', $idSites);
|
||||
|
||||
$db = $this->getDb();
|
||||
$sites = $db->fetchAll("SELECT * FROM " . $this->table . "
|
||||
WHERE idsite IN (" . implode(", ", $idSites) . ")
|
||||
ORDER BY idsite ASC $limit");
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the website information : name, main_url
|
||||
*
|
||||
* @throws Exception if the site ID doesn't exist or the user doesn't have access to it
|
||||
* @param int $idSite
|
||||
* @return array
|
||||
*/
|
||||
public function getSiteFromId($idSite)
|
||||
{
|
||||
$site = $this->getDb()->fetchRow("SELECT * FROM " . $this->table . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
|
||||
return $site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all the website IDs registered.
|
||||
* Caller must check access.
|
||||
*
|
||||
* @return array The list of website IDs
|
||||
*/
|
||||
public function getSitesId()
|
||||
{
|
||||
$result = Db::fetchAll("SELECT idsite FROM " . Common::prefixTable('site'));
|
||||
|
||||
$idSites = array();
|
||||
foreach ($result as $idSite) {
|
||||
$idSites[] = $idSite['idsite'];
|
||||
}
|
||||
|
||||
return $idSites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all URLs registered for the given idSite (main_url + alias URLs).
|
||||
*
|
||||
* @throws Exception if the website ID doesn't exist or the user doesn't have access to it
|
||||
* @param int $idSite
|
||||
* @return array list of URLs
|
||||
*/
|
||||
public function getSiteUrlsFromId($idSite)
|
||||
{
|
||||
$urls = $this->getAliasSiteUrlsFromId($idSite);
|
||||
$site = $this->getSiteFromId($idSite);
|
||||
|
||||
if (empty($site)) {
|
||||
return $urls;
|
||||
}
|
||||
|
||||
return array_merge(array($site['main_url']), $urls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of alias URLs registered for the given idSite.
|
||||
* The website ID must be valid when calling this method!
|
||||
*
|
||||
* @param int $idSite
|
||||
* @return array list of alias URLs
|
||||
*/
|
||||
public function getAliasSiteUrlsFromId($idSite)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$result = $db->fetchAll("SELECT url FROM " . Common::prefixTable("site_url") . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
$urls = array();
|
||||
foreach ($result as $url) {
|
||||
$urls[] = $url['url'];
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of alias URLs registered for the given idSite.
|
||||
* The website ID must be valid when calling this method!
|
||||
*
|
||||
* @param int $idSite
|
||||
* @return array list of alias URLs
|
||||
*/
|
||||
public function getAllKnownUrlsForAllSites()
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$mainUrls = $db->fetchAll("SELECT idsite, main_url as url FROM " . Common::prefixTable("site"));
|
||||
$aliasUrls = $db->fetchAll("SELECT idsite, url FROM " . Common::prefixTable("site_url"));
|
||||
|
||||
return array_merge($mainUrls, $aliasUrls);
|
||||
}
|
||||
|
||||
public function updateSite($site, $idSite)
|
||||
{
|
||||
$idSite = (int) $idSite;
|
||||
|
||||
$db = $this->getDb();
|
||||
$db->update($this->table, $site, "idsite = $idSite");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of unique timezones from all configured sites.
|
||||
*
|
||||
* @return array ( string )
|
||||
*/
|
||||
public function getUniqueSiteTimezones()
|
||||
{
|
||||
$results = Db::fetchAll("SELECT distinct timezone FROM " . $this->table);
|
||||
|
||||
$timezones = array();
|
||||
foreach ($results as $result) {
|
||||
$timezones[] = $result['timezone'];
|
||||
}
|
||||
|
||||
return $timezones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the field ts_created for the specified websites.
|
||||
*
|
||||
* @param $idSites int[] Id Site to update ts_created
|
||||
* @param string Date to set as creation date.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
public function updateSiteCreatedTime($idSites, $minDateSql)
|
||||
{
|
||||
$idSites = array_map('intval', $idSites);
|
||||
|
||||
$query = "UPDATE " . $this->table . " SET ts_created = ?" .
|
||||
" WHERE idsite IN ( " . implode(",", $idSites) . " ) AND ts_created > ?";
|
||||
|
||||
$bind = array($minDateSql, $minDateSql);
|
||||
|
||||
Db::query($query, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all used type ids (unique)
|
||||
* @return array of used type ids
|
||||
*/
|
||||
public function getUsedTypeIds()
|
||||
{
|
||||
$types = array();
|
||||
$rows = $this->getDb()->fetchAll("SELECT DISTINCT `type` as typeid FROM " . $this->table);
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$types[] = $row['typeid'];
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the list of alias URLs for the website.
|
||||
* The URLs must not exist already for this website!
|
||||
*/
|
||||
public function insertSiteUrl($idSite, $url)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$db->insert(Common::prefixTable("site_url"), array(
|
||||
'idsite' => (int) $idSite,
|
||||
'url' => $url
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getPatternMatchSites($ids, $pattern, $limit)
|
||||
{
|
||||
$ids_str = '';
|
||||
foreach ($ids as $id_val) {
|
||||
$ids_str .= (int) $id_val . ' , ';
|
||||
}
|
||||
$ids_str .= (int) $id_val;
|
||||
|
||||
$bind = array('%' . $pattern . '%', 'http%' . $pattern . '%', '%' . $pattern . '%');
|
||||
|
||||
// Also match the idsite
|
||||
$where = '';
|
||||
if (is_numeric($pattern)) {
|
||||
$bind[] = $pattern;
|
||||
$where = 'OR s.idsite = ?';
|
||||
}
|
||||
|
||||
$query = "SELECT *
|
||||
FROM " . $this->table . " s
|
||||
WHERE ( s.name like ?
|
||||
OR s.main_url like ?
|
||||
OR s.`group` like ?
|
||||
$where )
|
||||
AND idsite in ($ids_str)";
|
||||
|
||||
if ($limit !== false) {
|
||||
$query .= " LIMIT " . (int) $limit;
|
||||
}
|
||||
|
||||
$db = $this->getDb();
|
||||
$sites = $db->fetchAll($query, $bind);
|
||||
|
||||
return $sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the alias URLs for the given idSite.
|
||||
*/
|
||||
public function deleteSiteAliasUrls($idsite)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$db->query("DELETE FROM " . Common::prefixTable("site_url") . " WHERE idsite = ?", $idsite);
|
||||
}
|
||||
|
||||
private function getDb()
|
||||
{
|
||||
return Db::get();
|
||||
}
|
||||
}
|
||||
212
www/analytics/plugins/SitesManager/SiteUrls.php
Normal file
212
www/analytics/plugins/SitesManager/SiteUrls.php
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\SitesManager;
|
||||
|
||||
use Piwik\Cache;
|
||||
use Piwik\Common;
|
||||
|
||||
class SiteUrls
|
||||
{
|
||||
private static $cacheId = 'allSiteUrlsPerSite';
|
||||
|
||||
public static function clearSitesCache()
|
||||
{
|
||||
self::getCache()->delete(self::$cacheId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups all URLs by host, path and idsite.
|
||||
*
|
||||
* @param array $urls An array containing URLs by idsite,
|
||||
* eg array(array($idSite = 1 => array('apache.piwik', 'apache2.piwik'), 2 => array(), ...))
|
||||
* as returned by {@link getAllCachedSiteUrls()} and {@link getAllSiteUrls}
|
||||
* @return array All urls grouped by host => path => idSites. Path having the most '/' will be listed first
|
||||
* array(
|
||||
'apache.piwik' => array(
|
||||
'/test/two' => $idsite = array(3),
|
||||
'/test' => $idsite = array(1),
|
||||
'/' => $idsite = array(2),
|
||||
),
|
||||
'test.apache.piwik' => array(
|
||||
'/test/two' => $idsite = array(3),
|
||||
'/test' => $idsite = array(1),
|
||||
'/' => $idsite = array(2, 3),
|
||||
),
|
||||
);
|
||||
*/
|
||||
public function groupUrlsByHost($siteUrls)
|
||||
{
|
||||
if (empty($siteUrls)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$allUrls = array();
|
||||
|
||||
foreach ($siteUrls as $idSite => $urls) {
|
||||
$idSite = (int) $idSite;
|
||||
foreach ($urls as $url) {
|
||||
$urlParsed = @parse_url($url);
|
||||
|
||||
if ($urlParsed === false || !isset($urlParsed['host'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$host = $this->toCanonicalHost($urlParsed['host']);
|
||||
$path = $this->getCanonicalPathFromParsedUrl($urlParsed);
|
||||
|
||||
if (!isset($allUrls[$host])) {
|
||||
$allUrls[$host] = array();
|
||||
}
|
||||
|
||||
if (!isset($allUrls[$host][$path])) {
|
||||
$allUrls[$host][$path] = array();
|
||||
}
|
||||
|
||||
if (!in_array($idSite, $allUrls[$host][$path])) {
|
||||
$allUrls[$host][$path][] = $idSite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($allUrls as $host => $paths) {
|
||||
uksort($paths, array($this, 'sortByPathDepth'));
|
||||
$allUrls[$host] = $paths;
|
||||
}
|
||||
|
||||
return $allUrls;
|
||||
}
|
||||
|
||||
public function getIdSitesMatchingUrl($parsedUrl, $urlsGroupedByHost)
|
||||
{
|
||||
if (empty($parsedUrl['host'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$urlHost = $this->toCanonicalHost($parsedUrl['host']);
|
||||
$urlPath = $this->getCanonicalPathFromParsedUrl($parsedUrl);
|
||||
|
||||
$matchingSites = null;
|
||||
if (isset($urlsGroupedByHost[$urlHost])) {
|
||||
$paths = $urlsGroupedByHost[$urlHost];
|
||||
|
||||
foreach ($paths as $path => $idSites) {
|
||||
if (0 === strpos($urlPath, $path)) {
|
||||
$matchingSites = $idSites;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($matchingSites) && isset($paths['/'])) {
|
||||
$matchingSites = $paths['/'];
|
||||
}
|
||||
}
|
||||
|
||||
return $matchingSites;
|
||||
}
|
||||
|
||||
public function getPathMatchingUrl($parsedUrl, $urlsGroupedByHost)
|
||||
{
|
||||
if (empty($parsedUrl['host'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$urlHost = $this->toCanonicalHost($parsedUrl['host']);
|
||||
$urlPath = $this->getCanonicalPathFromParsedUrl($parsedUrl);
|
||||
|
||||
$matchingSites = null;
|
||||
if (isset($urlsGroupedByHost[$urlHost])) {
|
||||
$paths = $urlsGroupedByHost[$urlHost];
|
||||
|
||||
foreach ($paths as $path => $idSites) {
|
||||
if (0 === strpos($urlPath, $path)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getAllCachedSiteUrls()
|
||||
{
|
||||
$cache = $this->getCache();
|
||||
$siteUrls = $cache->fetch(self::$cacheId);
|
||||
|
||||
if (empty($siteUrls)) {
|
||||
$siteUrls = $this->getAllSiteUrls();
|
||||
$cache->save(self::$cacheId, $siteUrls, 1800);
|
||||
}
|
||||
|
||||
return $siteUrls;
|
||||
}
|
||||
|
||||
public function getAllSiteUrls()
|
||||
{
|
||||
$model = new Model();
|
||||
$siteUrls = $model->getAllKnownUrlsForAllSites();
|
||||
|
||||
if (empty($siteUrls)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$urls = array();
|
||||
foreach ($siteUrls as $siteUrl) {
|
||||
$siteId = (int) $siteUrl['idsite'];
|
||||
|
||||
if (!isset($urls[$siteId])) {
|
||||
$urls[$siteId] = array();
|
||||
}
|
||||
|
||||
$urls[$siteId][] = $siteUrl['url'];
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
||||
private static function getCache()
|
||||
{
|
||||
return Cache::getLazyCache();
|
||||
}
|
||||
|
||||
private function sortByPathDepth($pathA, $pathB)
|
||||
{
|
||||
// list first the paths with most '/' , and list path = '/' last
|
||||
$numSlashA = substr_count($pathA, '/');
|
||||
$numSlashB = substr_count($pathB, '/');
|
||||
|
||||
if ($numSlashA === $numSlashB) {
|
||||
return -1 * strcmp($pathA, $pathB);
|
||||
}
|
||||
|
||||
return $numSlashA > $numSlashB ? -1 : 1;
|
||||
}
|
||||
|
||||
private function toCanonicalHost($host)
|
||||
{
|
||||
$host = Common::mb_strtolower($host);
|
||||
if (strpos($host, 'www.') === 0) {
|
||||
$host = substr($host, 4);
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
private function getCanonicalPathFromParsedUrl($urlParsed)
|
||||
{
|
||||
$path = '/';
|
||||
|
||||
if (isset($urlParsed['path'])) {
|
||||
$path = Common::mb_strtolower($urlParsed['path']);
|
||||
if (!Common::stringEndsWith($path, '/')) {
|
||||
$path .= '/';
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -8,8 +8,14 @@
|
|||
*/
|
||||
namespace Piwik\Plugins\SitesManager;
|
||||
|
||||
use Piwik\Menu\MenuAdmin;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Common;
|
||||
use Piwik\Archive\ArchiveInvalidator;
|
||||
use Piwik\Container\StaticContainer;
|
||||
use Piwik\Db;
|
||||
use Piwik\Plugins\PrivacyManager\PrivacyManager;
|
||||
use Piwik\Measurable\Settings\Storage;
|
||||
use Piwik\Tracker\Cache;
|
||||
use Piwik\Tracker\Model as TrackerModel;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -21,25 +27,54 @@ class SitesManager extends \Piwik\Plugin
|
|||
const KEEP_URL_FRAGMENT_NO = 2;
|
||||
|
||||
/**
|
||||
* @see Piwik\Plugin::getListHooksRegistered
|
||||
* @see Piwik\Plugin::registerEvents
|
||||
*/
|
||||
public function getListHooksRegistered()
|
||||
public function registerEvents()
|
||||
{
|
||||
return array(
|
||||
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
|
||||
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
|
||||
'Menu.Admin.addItems' => 'addMenu',
|
||||
'Tracker.Cache.getSiteAttributes' => 'recordWebsiteDataInCache',
|
||||
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
|
||||
'SitesManager.deleteSite.end' => 'onSiteDeleted',
|
||||
'Request.dispatch' => 'redirectDashboardToWelcomePage',
|
||||
);
|
||||
}
|
||||
|
||||
function addMenu()
|
||||
public function redirectDashboardToWelcomePage(&$module, &$action)
|
||||
{
|
||||
MenuAdmin::getInstance()->add('CoreAdminHome_MenuManage', 'SitesManager_Sites',
|
||||
array('module' => 'SitesManager', 'action' => 'index'),
|
||||
Piwik::isUserHasSomeAdminAccess(),
|
||||
$order = 1);
|
||||
if ($module !== 'CoreHome' || $action !== 'index') {
|
||||
return;
|
||||
}
|
||||
|
||||
$siteId = Common::getRequestVar('idSite', false, 'int');
|
||||
if (!$siteId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the screen if purging logs is enabled
|
||||
$settings = PrivacyManager::getPurgeDataSettings();
|
||||
if ($settings['delete_logs_enable'] == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$trackerModel = new TrackerModel();
|
||||
if ($trackerModel->isSiteEmpty($siteId)) {
|
||||
$module = 'SitesManager';
|
||||
$action = 'siteWithoutData';
|
||||
}
|
||||
}
|
||||
|
||||
public function onSiteDeleted($idSite)
|
||||
{
|
||||
// we do not delete logs here on purpose (you can run these queries on the log_ tables to delete all data)
|
||||
Cache::deleteCacheWebsiteAttributes($idSite);
|
||||
|
||||
$archiveInvalidator = StaticContainer::get('Piwik\Archive\ArchiveInvalidator');
|
||||
$archiveInvalidator->forgetRememberedArchivedReportsToInvalidateForSite($idSite);
|
||||
|
||||
$measurableStorage = new Storage(Db::get(), $idSite);
|
||||
$measurableStorage->deleteAllValues();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -48,7 +83,7 @@ class SitesManager extends \Piwik\Plugin
|
|||
public function getStylesheetFiles(&$stylesheets)
|
||||
{
|
||||
$stylesheets[] = "plugins/SitesManager/stylesheets/SitesManager.less";
|
||||
$stylesheets[] = "plugins/Zeitgeist/stylesheets/base.less";
|
||||
$stylesheets[] = "plugins/Morpheus/stylesheets/base.less";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -56,7 +91,15 @@ class SitesManager extends \Piwik\Plugin
|
|||
*/
|
||||
public function getJsFiles(&$jsFiles)
|
||||
{
|
||||
$jsFiles[] = "plugins/SitesManager/javascripts/SitesManager.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/api-helper.service.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/api-site.service.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/api-core.service.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/sites-manager-type-model.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/sites-manager-admin-sites-model.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/multiline-field.directive.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/edit-trigger.directive.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/sites-manager.controller.js";
|
||||
$jsFiles[] = "plugins/SitesManager/angularjs/sites-manager/sites-manager-site.controller.js";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,12 +112,16 @@ class SitesManager extends \Piwik\Plugin
|
|||
*/
|
||||
public function recordWebsiteDataInCache(&$array, $idSite)
|
||||
{
|
||||
$idSite = (int)$idSite;
|
||||
$idSite = (int) $idSite;
|
||||
|
||||
$urls = API::getInstance()->getSiteUrlsFromId($idSite);
|
||||
|
||||
// add the 'hosts' entry in the website array
|
||||
$array['hosts'] = $this->getTrackerHosts($idSite);
|
||||
$array['urls'] = $urls;
|
||||
$array['hosts'] = $this->getTrackerHosts($urls);
|
||||
|
||||
$website = API::getInstance()->getSiteFromId($idSite);
|
||||
$array['exclude_unknown_urls'] = $website['exclude_unknown_urls'];
|
||||
$array['excluded_ips'] = $this->getTrackerExcludedIps($website);
|
||||
$array['excluded_parameters'] = self::getTrackerExcludedQueryParameters($website);
|
||||
$array['excluded_user_agents'] = self::getExcludedUserAgents($website);
|
||||
|
|
@ -82,6 +129,21 @@ class SitesManager extends \Piwik\Plugin
|
|||
$array['sitesearch'] = $website['sitesearch'];
|
||||
$array['sitesearch_keyword_parameters'] = $this->getTrackerSearchKeywordParameters($website);
|
||||
$array['sitesearch_category_parameters'] = $this->getTrackerSearchCategoryParameters($website);
|
||||
$array['timezone'] = $this->getTimezoneFromWebsite($website);
|
||||
$array['ts_created'] = $website['ts_created'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we should keep URL fragments for a specific site.
|
||||
*
|
||||
* @param array $site DB data for the site.
|
||||
* @return bool
|
||||
*/
|
||||
private static function getTimezoneFromWebsite($site)
|
||||
{
|
||||
if (!empty($site['timezone'])) {
|
||||
return $site['timezone'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -180,7 +242,7 @@ class SitesManager extends \Piwik\Plugin
|
|||
* @param string $parameters The unfiltered list.
|
||||
* @return array The filtered list of strings as an array.
|
||||
*/
|
||||
static private function filterBlankFromCommaSepList($parameters)
|
||||
private static function filterBlankFromCommaSepList($parameters)
|
||||
{
|
||||
$parameters = explode(',', $parameters);
|
||||
$parameters = array_filter($parameters, 'strlen');
|
||||
|
|
@ -193,9 +255,8 @@ class SitesManager extends \Piwik\Plugin
|
|||
* @param int $idSite
|
||||
* @return array
|
||||
*/
|
||||
private function getTrackerHosts($idSite)
|
||||
private function getTrackerHosts($urls)
|
||||
{
|
||||
$urls = API::getInstance()->getSiteUrlsFromId($idSite);
|
||||
$hosts = array();
|
||||
foreach ($urls as $url) {
|
||||
$url = parse_url($url);
|
||||
|
|
@ -210,7 +271,84 @@ class SitesManager extends \Piwik\Plugin
|
|||
{
|
||||
$translationKeys[] = "General_Save";
|
||||
$translationKeys[] = "General_OrCancel";
|
||||
$translationKeys[] = "General_Actions";
|
||||
$translationKeys[] = "General_Search";
|
||||
$translationKeys[] = "General_Previous";
|
||||
$translationKeys[] = "General_Next";
|
||||
$translationKeys[] = "General_Pagination";
|
||||
$translationKeys[] = "General_Cancel";
|
||||
$translationKeys[] = "General_ClickToSearch";
|
||||
$translationKeys[] = "General_PaginationWithoutTotal";
|
||||
$translationKeys[] = "General_Loading";
|
||||
$translationKeys[] = "Actions_SubmenuSitesearch";
|
||||
$translationKeys[] = "SitesManager_OnlyOneSiteAtTime";
|
||||
$translationKeys[] = "SitesManager_DeleteConfirm";
|
||||
$translationKeys[] = "SitesManager_Urls";
|
||||
$translationKeys[] = "SitesManager_ExcludedIps";
|
||||
$translationKeys[] = "SitesManager_ExcludedParameters";
|
||||
$translationKeys[] = "SitesManager_ExcludedUserAgents";
|
||||
$translationKeys[] = "SitesManager_Timezone";
|
||||
$translationKeys[] = "SitesManager_Currency";
|
||||
$translationKeys[] = "SitesManager_ShowTrackingTag";
|
||||
$translationKeys[] = "SitesManager_AliasUrlHelp";
|
||||
$translationKeys[] = "SitesManager_OnlyMatchedUrlsAllowed";
|
||||
$translationKeys[] = "SitesManager_OnlyMatchedUrlsAllowedHelp";
|
||||
$translationKeys[] = "SitesManager_OnlyMatchedUrlsAllowedHelpExamples";
|
||||
$translationKeys[] = "SitesManager_KeepURLFragmentsLong";
|
||||
$translationKeys[] = "SitesManager_HelpExcludedIps";
|
||||
$translationKeys[] = "SitesManager_ListOfQueryParametersToExclude";
|
||||
$translationKeys[] = "SitesManager_PiwikWillAutomaticallyExcludeCommonSessionParameters";
|
||||
$translationKeys[] = "SitesManager_GlobalExcludedUserAgentHelp1";
|
||||
$translationKeys[] = "SitesManager_GlobalListExcludedUserAgents_Desc";
|
||||
$translationKeys[] = "SitesManager_GlobalExcludedUserAgentHelp2";
|
||||
$translationKeys[] = "SitesManager_WebsitesManagement";
|
||||
$translationKeys[] = "SitesManager_MainDescription";
|
||||
$translationKeys[] = "SitesManager_YouCurrentlyHaveAccessToNWebsites";
|
||||
$translationKeys[] = "SitesManager_SuperUserAccessCan";
|
||||
$translationKeys[] = "SitesManager_EnableSiteSearch";
|
||||
$translationKeys[] = "SitesManager_DisableSiteSearch";
|
||||
$translationKeys[] = "SitesManager_SearchUseDefault";
|
||||
$translationKeys[] = "SitesManager_Sites";
|
||||
$translationKeys[] = "SitesManager_SiteSearchUse";
|
||||
$translationKeys[] = "SitesManager_SearchKeywordLabel";
|
||||
$translationKeys[] = "SitesManager_SearchCategoryLabel";
|
||||
$translationKeys[] = "SitesManager_YourCurrentIpAddressIs";
|
||||
$translationKeys[] = "SitesManager_SearchKeywordParametersDesc";
|
||||
$translationKeys[] = "SitesManager_SearchCategoryParametersDesc";
|
||||
$translationKeys[] = "SitesManager_CurrencySymbolWillBeUsedForGoals";
|
||||
$translationKeys[] = "SitesManager_ChangingYourTimezoneWillOnlyAffectDataForward";
|
||||
$translationKeys[] = "SitesManager_AdvancedTimezoneSupportNotFound";
|
||||
$translationKeys[] = "SitesManager_ChooseCityInSameTimezoneAsYou";
|
||||
$translationKeys[] = "SitesManager_UTCTimeIs";
|
||||
$translationKeys[] = "SitesManager_EnableEcommerce";
|
||||
$translationKeys[] = "SitesManager_NotAnEcommerceSite";
|
||||
$translationKeys[] = "SitesManager_EcommerceHelp";
|
||||
$translationKeys[] = "SitesManager_PiwikOffersEcommerceAnalytics";
|
||||
$translationKeys[] = "SitesManager_GlobalWebsitesSettings";
|
||||
$translationKeys[] = "SitesManager_GlobalListExcludedIps";
|
||||
$translationKeys[] = "SitesManager_ListOfIpsToBeExcludedOnAllWebsites";
|
||||
$translationKeys[] = "SitesManager_GlobalListExcludedQueryParameters";
|
||||
$translationKeys[] = "SitesManager_ListOfQueryParametersToBeExcludedOnAllWebsites";
|
||||
$translationKeys[] = "SitesManager_GlobalListExcludedUserAgents";
|
||||
$translationKeys[] = "SitesManager_EnableSiteSpecificUserAgentExclude_Help";
|
||||
$translationKeys[] = "SitesManager_EnableSiteSpecificUserAgentExclude";
|
||||
$translationKeys[] = "SitesManager_KeepURLFragments";
|
||||
$translationKeys[] = "SitesManager_KeepURLFragmentsHelp";
|
||||
$translationKeys[] = "SitesManager_KeepURLFragmentsHelp2";
|
||||
$translationKeys[] = "SitesManager_TrackingSiteSearch";
|
||||
$translationKeys[] = "SitesManager_SearchParametersNote";
|
||||
$translationKeys[] = "SitesManager_SearchParametersNote2";
|
||||
$translationKeys[] = "SitesManager_SearchCategoryDesc";
|
||||
$translationKeys[] = "SitesManager_DefaultTimezoneForNewWebsites";
|
||||
$translationKeys[] = "SitesManager_SelectDefaultTimezone";
|
||||
$translationKeys[] = "SitesManager_DefaultCurrencyForNewWebsites";
|
||||
$translationKeys[] = "SitesManager_SelectDefaultCurrency";
|
||||
$translationKeys[] = "SitesManager_AddMeasurable";
|
||||
$translationKeys[] = "SitesManager_AddSite";
|
||||
$translationKeys[] = "SitesManager_XManagement";
|
||||
$translationKeys[] = "SitesManager_ChooseMeasurableTypeHeadline";
|
||||
$translationKeys[] = "General_Measurables";
|
||||
$translationKeys[] = "Goals_Ecommerce";
|
||||
$translationKeys[] = "SitesManager_NotFound";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\SitesManager\Tracker;
|
||||
|
||||
use Piwik\Date;
|
||||
use Piwik\Tracker\Cache;
|
||||
use Piwik\Tracker\Request;
|
||||
use Piwik\Tracker\RequestProcessor;
|
||||
use Piwik\Tracker\Visit\VisitProperties;
|
||||
use Piwik\Plugins\SitesManager\Model as SitesManagerModel;
|
||||
|
||||
/**
|
||||
* Handles site specific logic during tracking.
|
||||
*/
|
||||
class SitesManagerRequestProcessor extends RequestProcessor
|
||||
{
|
||||
/**
|
||||
* @var SitesManagerModel
|
||||
*/
|
||||
private $sitesManagerModel;
|
||||
|
||||
public function __construct(SitesManagerModel $sitesManagerModel)
|
||||
{
|
||||
$this->sitesManagerModel = $sitesManagerModel;
|
||||
}
|
||||
|
||||
public function recordLogs(VisitProperties $visitProperties, Request $request)
|
||||
{
|
||||
// if we successfully record some data and the date is older than the site's created time,
|
||||
// update the created time so the data will be viewable in the UI
|
||||
$idSite = $request->getIdSite();
|
||||
|
||||
$createdTimeTimestamp = $this->getSiteCreatedTime($idSite);
|
||||
if (empty($createdTimeTimestamp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$requestTimestamp = Date::factory((int) $request->getCurrentTimestamp());
|
||||
|
||||
// replicating old Piwik logic, see:
|
||||
// https://github.com/piwik/piwik/blob/baa6da86266c7c44bc2d65821c7ffe042c2f4716/core/Archive/ArchiveInvalidator.php#L150
|
||||
// before when this was done during archive invalidation, the date would not have an attached time and
|
||||
// one extra day was subtracted from the minimum.
|
||||
// I am not sure why this is required or if it is still required, but some tests that check the contents
|
||||
// of archive tables will fail w/o this.
|
||||
$requestTimestamp = $requestTimestamp->subDay(1)->setTime('00:00:00');
|
||||
|
||||
if ($requestTimestamp->isEarlier($createdTimeTimestamp)) {
|
||||
$this->updateSiteCreatedTime($idSite, $requestTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
private function getSiteCreatedTime($idSite)
|
||||
{
|
||||
$attributes = Cache::getCacheWebsiteAttributes($idSite);
|
||||
if (!isset($attributes['ts_created'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Date::factory($attributes['ts_created']);
|
||||
}
|
||||
|
||||
private function updateSiteCreatedTime($idSite, Date $timestamp)
|
||||
{
|
||||
$this->sitesManagerModel->updateSiteCreatedTime(array($idSite), $timestamp->getDatetime());
|
||||
Cache::deleteCacheWebsiteAttributes($idSite);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
// can probably be shared
|
||||
angular.module('piwikApp').factory('coreAPI', CoreAPIFactory);
|
||||
|
||||
CoreAPIFactory.$inject = ['sitesManagerApiHelper'];
|
||||
|
||||
function CoreAPIFactory(api) {
|
||||
|
||||
return {
|
||||
getIpFromHeader: getIpFromHeader(),
|
||||
isPluginActivated: isPluginActivated()
|
||||
};
|
||||
|
||||
function getIpFromHeader() {
|
||||
return api.fetchApi('API.getIpFromHeader', api.valueAdaptor);
|
||||
}
|
||||
|
||||
function isPluginActivated() {
|
||||
return api.fetchApi('API.isPluginActivated', api.valueAdaptor);
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
// can probably be renamed and shared
|
||||
angular.module('piwikApp').factory('sitesManagerApiHelper', SitesManagerAPIHelperFactory);
|
||||
|
||||
SitesManagerAPIHelperFactory.$inject = ['piwikApi'];
|
||||
|
||||
function SitesManagerAPIHelperFactory(piwikApi) {
|
||||
|
||||
return {
|
||||
fetch: fetch,
|
||||
commaDelimitedFieldToArray: commaDelimitedFieldToArray,
|
||||
fetchApi: fetchApi,
|
||||
fetchAction: fetchAction,
|
||||
singleObjectAdaptor: singleObjectAdaptor,
|
||||
valueAdaptor: valueAdaptor,
|
||||
noop: noop
|
||||
};
|
||||
|
||||
function fetch (endpoint, jsonResponseAdaptor, params) {
|
||||
|
||||
return function (clientHandover, additionalParams) {
|
||||
|
||||
params = angular.extend(params || {}, additionalParams || {});
|
||||
|
||||
var requestDefinition = angular.extend(endpoint, params);
|
||||
|
||||
var responseHandler = function (response) {
|
||||
|
||||
response = jsonResponseAdaptor(response);
|
||||
|
||||
clientHandover(response);
|
||||
};
|
||||
|
||||
piwikApi.fetch(requestDefinition).then(responseHandler);
|
||||
};
|
||||
}
|
||||
|
||||
function commaDelimitedFieldToArray (value) {
|
||||
|
||||
if(!value)
|
||||
return [];
|
||||
|
||||
return value.split(',');
|
||||
}
|
||||
|
||||
function fetchApi(apiMethod, jsonResponseAdaptor, params) {
|
||||
|
||||
return fetch({method: apiMethod}, jsonResponseAdaptor, params);
|
||||
}
|
||||
|
||||
function fetchAction(module, action, jsonResponseAdaptor, params) {
|
||||
|
||||
return fetch({module: module, action: action}, jsonResponseAdaptor, params);
|
||||
}
|
||||
|
||||
function singleObjectAdaptor(response) {
|
||||
return response[0];
|
||||
}
|
||||
|
||||
function valueAdaptor(response) {
|
||||
return response.value;
|
||||
}
|
||||
|
||||
function noop(response) {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').factory('sitesManagerAPI', SitesManagerAPIFactory);
|
||||
|
||||
SitesManagerAPIFactory.$inject = ['sitesManagerApiHelper'];
|
||||
|
||||
function SitesManagerAPIFactory(api) {
|
||||
|
||||
return {
|
||||
getCurrencyList: getCurrencyList(),
|
||||
getTimezonesList: getTimezonesList(),
|
||||
isTimezoneSupportEnabled: isTimezoneSupportEnabled(),
|
||||
getGlobalSettings: getGlobalSettings(),
|
||||
getSitesIdWithAdminAccess: getSitesIdWithAdminAccess()
|
||||
};
|
||||
|
||||
function getSitesIdWithAdminAccess () {
|
||||
return api.fetchApi('SitesManager.getSitesIdWithAdminAccess', api.noop, {
|
||||
filter_limit: '-1',
|
||||
});
|
||||
}
|
||||
function getCurrencyList () {
|
||||
return api.fetchApi('SitesManager.getCurrencyList', api.noop);
|
||||
}
|
||||
|
||||
function getTimezonesList () {
|
||||
return api.fetchApi('SitesManager.getTimezonesList', api.noop);
|
||||
}
|
||||
|
||||
function isTimezoneSupportEnabled () {
|
||||
return api.fetchApi('SitesManager.isTimezoneSupportEnabled', api.valueAdaptor);
|
||||
}
|
||||
|
||||
function getGlobalSettings () {
|
||||
return api.fetchAction('SitesManager', 'getGlobalSettings', api.noop);
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('sitesManagerEditTrigger', sitesManagerEditTrigger);
|
||||
|
||||
function sitesManagerEditTrigger() {
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element) {
|
||||
|
||||
element.bind('click', function(){
|
||||
|
||||
if(!scope.site.editMode)
|
||||
scope.$apply(scope.editSite());
|
||||
});
|
||||
|
||||
scope.$watch('site.editMode', function() {
|
||||
|
||||
element.toggleClass('editable-site-field', !scope.site.editMode);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<textarea
|
||||
cols="{{ cols }}"
|
||||
rows="{{ rows }}"
|
||||
ng-model="field.value"
|
||||
ng-change="onChange()">
|
||||
|
||||
</textarea>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').directive('sitesManagerMultilineField', sitesManagerMultilineField);
|
||||
|
||||
function sitesManagerMultilineField() {
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
replace: true,
|
||||
scope: {
|
||||
managedValue: '=field',
|
||||
rows: '@?',
|
||||
cols: '@?'
|
||||
},
|
||||
templateUrl: 'plugins/SitesManager/angularjs/sites-manager/multiline-field.directive.html?cb=' + piwik.cacheBuster,
|
||||
link: function (scope) {
|
||||
|
||||
var separator = '\n';
|
||||
|
||||
var init = function () {
|
||||
|
||||
scope.field = {};
|
||||
scope.onChange = updateManagedScopeValue;
|
||||
|
||||
scope.$watch('managedValue', updateInputValue);
|
||||
};
|
||||
|
||||
var updateManagedScopeValue = function () {
|
||||
scope.managedValue = scope.field.value.trim().split(separator);
|
||||
};
|
||||
|
||||
var updateInputValue = function () {
|
||||
|
||||
if(angular.isUndefined(scope.managedValue))
|
||||
return;
|
||||
|
||||
scope.field.value = scope.managedValue.join(separator);
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
115
www/analytics/plugins/SitesManager/angularjs/sites-manager/sites-manager-admin-sites-model.js
vendored
Normal file
115
www/analytics/plugins/SitesManager/angularjs/sites-manager/sites-manager-admin-sites-model.js
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* Model for Sites Manager. Fetches only sites one has at least Admin permission.
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').factory('sitesManagerAdminSitesModel', sitesManagerAdminSitesModel);
|
||||
|
||||
sitesManagerAdminSitesModel.$inject = ['piwikApi'];
|
||||
|
||||
function sitesManagerAdminSitesModel(piwikApi)
|
||||
{
|
||||
var model = {
|
||||
sites : [],
|
||||
searchTerm : '',
|
||||
isLoading : false,
|
||||
pageSize : 10,
|
||||
currentPage : 0,
|
||||
offsetStart : 0,
|
||||
offsetEnd : 10,
|
||||
hasPrev : false,
|
||||
hasNext : false,
|
||||
previousPage: previousPage,
|
||||
nextPage: nextPage,
|
||||
searchSite: searchSite,
|
||||
fetchLimitedSitesWithAdminAccess: fetchLimitedSitesWithAdminAccess
|
||||
};
|
||||
|
||||
return model;
|
||||
|
||||
function onError ()
|
||||
{
|
||||
setSites([]);
|
||||
}
|
||||
|
||||
function setSites(sites)
|
||||
{
|
||||
model.sites = sites;
|
||||
|
||||
var numSites = sites.length;
|
||||
model.offsetStart = model.currentPage * model.pageSize;
|
||||
model.offsetEnd = model.offsetStart + numSites;
|
||||
model.hasPrev = model.currentPage >= 1;
|
||||
model.hasNext = numSites === model.pageSize;
|
||||
}
|
||||
|
||||
function setCurrentPage(page)
|
||||
{
|
||||
if (page < 0) {
|
||||
page = 0;
|
||||
}
|
||||
|
||||
model.currentPage = page;
|
||||
}
|
||||
|
||||
function previousPage()
|
||||
{
|
||||
setCurrentPage(model.currentPage - 1);
|
||||
fetchLimitedSitesWithAdminAccess();
|
||||
}
|
||||
|
||||
function nextPage()
|
||||
{
|
||||
setCurrentPage(model.currentPage + 1);
|
||||
fetchLimitedSitesWithAdminAccess();
|
||||
}
|
||||
|
||||
function searchSite (term)
|
||||
{
|
||||
model.searchTerm = term;
|
||||
setCurrentPage(0);
|
||||
fetchLimitedSitesWithAdminAccess();
|
||||
}
|
||||
|
||||
function fetchLimitedSitesWithAdminAccess(callback)
|
||||
{
|
||||
if (model.isLoading) {
|
||||
piwikApi.abort();
|
||||
}
|
||||
|
||||
model.isLoading = true;
|
||||
|
||||
var limit = model.pageSize;
|
||||
var offset = model.currentPage * model.pageSize;
|
||||
|
||||
var params = {
|
||||
method: 'SitesManager.getSitesWithAdminAccess',
|
||||
fetchAliasUrls: true,
|
||||
limit: limit + offset, // this is applied in SitesManager.getSitesWithAdminAccess API
|
||||
filter_offset: offset, // filter_offset and filter_limit is applied in response builder
|
||||
filter_limit: limit
|
||||
};
|
||||
|
||||
if (model.searchTerm) {
|
||||
params.pattern = model.searchTerm;
|
||||
}
|
||||
|
||||
return piwikApi.fetch(params).then(function (sites) {
|
||||
|
||||
if (!sites) {
|
||||
onError();
|
||||
return;
|
||||
}
|
||||
|
||||
setSites(sites);
|
||||
|
||||
}, onError)['finally'](function () {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
|
||||
model.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').controller('SitesManagerSiteController', SitesManagerSiteController);
|
||||
|
||||
SitesManagerSiteController.$inject = ['$scope', '$filter', 'sitesManagerApiHelper', 'sitesManagerTypeModel'];
|
||||
|
||||
function SitesManagerSiteController($scope, $filter, sitesManagerApiHelper, sitesManagerTypeModel) {
|
||||
|
||||
var translate = $filter('translate');
|
||||
|
||||
var init = function () {
|
||||
|
||||
initModel();
|
||||
initActions();
|
||||
|
||||
sitesManagerTypeModel.fetchTypeById($scope.site.type).then(function (type) {
|
||||
if (type) {
|
||||
$scope.currentType = type;
|
||||
$scope.howToSetupUrl = type.howToSetupUrl;
|
||||
$scope.isInternalSetupUrl = '?' === ('' + type.howToSetupUrl).substr(0, 1);
|
||||
} else {
|
||||
$scope.currentType = {name: $scope.site.type};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var initActions = function () {
|
||||
|
||||
$scope.editSite = editSite;
|
||||
$scope.saveSite = saveSite;
|
||||
$scope.openDeleteDialog = openDeleteDialog;
|
||||
$scope.site['delete'] = deleteSite;
|
||||
};
|
||||
|
||||
var initModel = function() {
|
||||
|
||||
if(siteIsNew())
|
||||
initNewSite();
|
||||
else
|
||||
initExistingSite();
|
||||
|
||||
$scope.site.editDialog = {};
|
||||
$scope.site.removeDialog = {};
|
||||
};
|
||||
|
||||
var editSite = function () {
|
||||
|
||||
if ($scope.siteIsBeingEdited) {
|
||||
|
||||
$scope.site.editDialog.show = true;
|
||||
$scope.site.editDialog.title = translate('SitesManager_OnlyOneSiteAtTime', '"' + $scope.lookupCurrentEditSite().name + '"');
|
||||
|
||||
} else {
|
||||
|
||||
$scope.site.editMode = true;
|
||||
$scope.informSiteIsBeingEdited();
|
||||
}
|
||||
};
|
||||
|
||||
var saveSite = function() {
|
||||
|
||||
var sendSiteSearchKeywordParams = $scope.site.sitesearch == '1' && !$scope.site.useDefaultSiteSearchParams;
|
||||
var sendSearchCategoryParameters = sendSiteSearchKeywordParams && $scope.customVariablesActivated;
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json'
|
||||
}, 'GET');
|
||||
|
||||
if(siteIsNew()) {
|
||||
|
||||
ajaxHandler.addParams({
|
||||
method: 'SitesManager.addSite'
|
||||
}, 'GET');
|
||||
|
||||
} else {
|
||||
|
||||
ajaxHandler.addParams({
|
||||
idSite: $scope.site.idsite,
|
||||
method: 'SitesManager.updateSite'
|
||||
}, 'GET');
|
||||
}
|
||||
|
||||
var settings = $('.typeSettings fieldset').serializeArray();
|
||||
|
||||
var flatSettings = '';
|
||||
if (settings.length) {
|
||||
flatSettings = {};
|
||||
angular.forEach(settings, function (setting) {
|
||||
flatSettings[setting.name] = setting.value;
|
||||
});
|
||||
}
|
||||
|
||||
ajaxHandler.addParams({
|
||||
siteName: $scope.site.name,
|
||||
timezone: $scope.site.timezone,
|
||||
currency: $scope.site.currency,
|
||||
ecommerce: $scope.site.ecommerce,
|
||||
excludedIps: $scope.site.excluded_ips.join(','),
|
||||
excludedQueryParameters: $scope.site.excluded_parameters.join(','),
|
||||
excludedUserAgents: $scope.site.excluded_user_agents.join(','),
|
||||
keepURLFragments: $scope.site.keep_url_fragment,
|
||||
siteSearch: $scope.site.sitesearch,
|
||||
type: $scope.site.type,
|
||||
searchKeywordParameters: sendSiteSearchKeywordParams ? $scope.site.sitesearch_keyword_parameters.join(',') : null,
|
||||
searchCategoryParameters: sendSearchCategoryParameters ? $scope.site.sitesearch_category_parameters.join(',') : null,
|
||||
urls: $scope.site.alias_urls,
|
||||
excludeUnknownUrls: $scope.site.exclude_unknown_urls,
|
||||
settings: flatSettings
|
||||
}, 'POST');
|
||||
|
||||
ajaxHandler.redirectOnSuccess($scope.redirectParams);
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
};
|
||||
|
||||
var siteIsNew = function() {
|
||||
return angular.isUndefined($scope.site.idsite);
|
||||
};
|
||||
|
||||
var initNewSite = function() {
|
||||
|
||||
$scope.informSiteIsBeingEdited();
|
||||
|
||||
$scope.site.editMode = true;
|
||||
$scope.site.name = "Name";
|
||||
$scope.site.alias_urls = [
|
||||
"http://siteUrl.com/",
|
||||
"http://siteUrl2.com/"
|
||||
];
|
||||
$scope.site.exclude_unknown_urls = 0;
|
||||
$scope.site.keep_url_fragment = "0";
|
||||
$scope.site.excluded_ips = [];
|
||||
$scope.site.excluded_parameters = [];
|
||||
$scope.site.excluded_user_agents = [];
|
||||
$scope.site.sitesearch_keyword_parameters = [];
|
||||
$scope.site.sitesearch_category_parameters = [];
|
||||
$scope.site.sitesearch = $scope.globalSettings.searchKeywordParametersGlobal.length ? "1" : "0";
|
||||
$scope.site.timezone = $scope.globalSettings.defaultTimezone;
|
||||
$scope.site.currency = $scope.globalSettings.defaultCurrency;
|
||||
$scope.site.ecommerce = "0";
|
||||
|
||||
updateSiteWithSiteSearchConfig();
|
||||
};
|
||||
|
||||
var initExistingSite = function() {
|
||||
|
||||
$scope.site.excluded_ips = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.excluded_ips);
|
||||
$scope.site.excluded_parameters = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.excluded_parameters);
|
||||
$scope.site.excluded_user_agents = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.excluded_user_agents);
|
||||
$scope.site.sitesearch_keyword_parameters = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.sitesearch_keyword_parameters);
|
||||
$scope.site.sitesearch_category_parameters = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.site.sitesearch_category_parameters);
|
||||
|
||||
updateSiteWithSiteSearchConfig();
|
||||
};
|
||||
|
||||
var updateSiteWithSiteSearchConfig = function() {
|
||||
|
||||
$scope.site.useDefaultSiteSearchParams =
|
||||
$scope.globalSettings.searchKeywordParametersGlobal.length && !$scope.site.sitesearch_keyword_parameters.length;
|
||||
};
|
||||
|
||||
var openDeleteDialog = function() {
|
||||
|
||||
$scope.site.removeDialog.title = translate('SitesManager_DeleteConfirm', '"' + $scope.site.name + '" (idSite = ' + $scope.site.idsite + ')');
|
||||
$scope.site.removeDialog.show = true;
|
||||
};
|
||||
|
||||
var deleteSite = function() {
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
|
||||
ajaxHandler.addParams({
|
||||
idSite: $scope.site.idsite,
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'SitesManager.deleteSite'
|
||||
}, 'GET');
|
||||
|
||||
ajaxHandler.redirectOnSuccess($scope.redirectParams);
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
})();
|
||||
52
www/analytics/plugins/SitesManager/angularjs/sites-manager/sites-manager-type-model.js
vendored
Normal file
52
www/analytics/plugins/SitesManager/angularjs/sites-manager/sites-manager-type-model.js
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* Model for Sites Manager. Fetches only sites one has at least Admin permission.
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').factory('sitesManagerTypeModel', sitesManagerTypeModel);
|
||||
|
||||
sitesManagerTypeModel.$inject = ['piwikApi'];
|
||||
|
||||
function sitesManagerTypeModel(piwikApi)
|
||||
{
|
||||
var typesPromise = null;
|
||||
|
||||
var model = {
|
||||
typesById: {},
|
||||
fetchTypeById: fetchTypeById,
|
||||
fetchAvailableTypes: fetchAvailableTypes,
|
||||
hasMultipleTypes: hasMultipleTypes
|
||||
};
|
||||
|
||||
return model;
|
||||
|
||||
function hasMultipleTypes(typeId)
|
||||
{
|
||||
return fetchAvailableTypes().then(function (types) {
|
||||
return types && types.length > 1;
|
||||
});
|
||||
}
|
||||
|
||||
function fetchTypeById(typeId)
|
||||
{
|
||||
return fetchAvailableTypes().then(function () {
|
||||
return model.typesById[typeId];
|
||||
});
|
||||
}
|
||||
|
||||
function fetchAvailableTypes()
|
||||
{
|
||||
if (!typesPromise) {
|
||||
typesPromise = piwikApi.fetch({method: 'API.getAvailableMeasurableTypes'}).then(function (types) {
|
||||
|
||||
angular.forEach(types, function (type) {
|
||||
model.typesById[type.id] = type;
|
||||
});
|
||||
|
||||
return types;
|
||||
});
|
||||
}
|
||||
|
||||
return typesPromise;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
/*!
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
(function () {
|
||||
angular.module('piwikApp').controller('SitesManagerController', SitesManagerController);
|
||||
|
||||
SitesManagerController.$inject = ['$scope', '$filter', 'coreAPI', 'sitesManagerAPI', 'piwikApi', 'sitesManagerAdminSitesModel', 'piwik', 'sitesManagerApiHelper', 'sitesManagerTypeModel'];
|
||||
|
||||
function SitesManagerController($scope, $filter, coreAPI, sitesManagerAPI, piwikApi, adminSites, piwik, sitesManagerApiHelper, sitesManagerTypeModel) {
|
||||
|
||||
var translate = $filter('translate');
|
||||
|
||||
var init = function () {
|
||||
|
||||
$scope.period = piwik.broadcast.getValueFromUrl('period');
|
||||
$scope.date = piwik.broadcast.getValueFromUrl('date');
|
||||
$scope.adminSites = adminSites;
|
||||
$scope.hasSuperUserAccess = piwik.hasSuperUserAccess;
|
||||
$scope.redirectParams = {showaddsite: false};
|
||||
$scope.siteIsBeingEdited = false;
|
||||
$scope.cacheBuster = piwik.cacheBuster;
|
||||
$scope.totalNumberOfSites = '?';
|
||||
|
||||
initSelectLists();
|
||||
initUtcTime();
|
||||
initUserIP();
|
||||
initCustomVariablesActivated();
|
||||
initIsTimezoneSupportEnabled();
|
||||
initGlobalParams();
|
||||
|
||||
initActions();
|
||||
};
|
||||
|
||||
var initActions = function () {
|
||||
|
||||
$scope.cancelEditSite = cancelEditSite;
|
||||
$scope.addSite = addSite;
|
||||
$scope.addNewEntity = addNewEntity;
|
||||
$scope.saveGlobalSettings = saveGlobalSettings;
|
||||
|
||||
$scope.informSiteIsBeingEdited = informSiteIsBeingEdited;
|
||||
$scope.lookupCurrentEditSite = lookupCurrentEditSite;
|
||||
|
||||
$scope.closeAddMeasurableDialog = function () {
|
||||
// I couldn't figure out another way to close that jquery dialog
|
||||
var element = angular.element('[piwik-dialog="$parent.showAddSiteDialog"]');
|
||||
if (element.parents('ui-dialog') && element.dialog('isOpen')) {
|
||||
element.dialog('close');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var initAvailableTypes = function () {
|
||||
return sitesManagerTypeModel.fetchAvailableTypes().then(function (types) {
|
||||
$scope.availableTypes = types;
|
||||
$scope.typeForNewEntity = 'website';
|
||||
|
||||
return types;
|
||||
});
|
||||
};
|
||||
|
||||
var informSiteIsBeingEdited = function() {
|
||||
|
||||
$scope.siteIsBeingEdited = true;
|
||||
};
|
||||
|
||||
var initSelectLists = function() {
|
||||
|
||||
initSiteSearchSelectOptions();
|
||||
initEcommerceSelectOptions();
|
||||
initCurrencyList();
|
||||
initTimezones();
|
||||
};
|
||||
|
||||
var initGlobalParams = function() {
|
||||
|
||||
showLoading();
|
||||
|
||||
var availableTypesPromise = initAvailableTypes();
|
||||
|
||||
sitesManagerAPI.getGlobalSettings(function(globalSettings) {
|
||||
|
||||
$scope.globalSettings = globalSettings;
|
||||
|
||||
$scope.globalSettings.searchKeywordParametersGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.searchKeywordParametersGlobal);
|
||||
$scope.globalSettings.searchCategoryParametersGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.searchCategoryParametersGlobal);
|
||||
$scope.globalSettings.excludedIpsGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.excludedIpsGlobal);
|
||||
$scope.globalSettings.excludedQueryParametersGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.excludedQueryParametersGlobal);
|
||||
$scope.globalSettings.excludedUserAgentsGlobal = sitesManagerApiHelper.commaDelimitedFieldToArray($scope.globalSettings.excludedUserAgentsGlobal);
|
||||
|
||||
hideLoading();
|
||||
|
||||
initKeepURLFragmentsList();
|
||||
|
||||
adminSites.fetchLimitedSitesWithAdminAccess(function () {
|
||||
availableTypesPromise.then(function () {
|
||||
triggerAddSiteIfRequested();
|
||||
});
|
||||
});
|
||||
sitesManagerAPI.getSitesIdWithAdminAccess(function (siteIds) {
|
||||
if (siteIds && siteIds.length) {
|
||||
$scope.totalNumberOfSites = siteIds.length;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var triggerAddSiteIfRequested = function() {
|
||||
var search = String(window.location.search);
|
||||
|
||||
if(piwik.helper.getArrayFromQueryString(search).showaddsite == 1)
|
||||
addNewEntity();
|
||||
};
|
||||
|
||||
var initEcommerceSelectOptions = function() {
|
||||
|
||||
$scope.eCommerceptions = [
|
||||
{key: '0', value: translate('SitesManager_NotAnEcommerceSite')},
|
||||
{key: '1', value: translate('SitesManager_EnableEcommerce')}
|
||||
];
|
||||
};
|
||||
|
||||
var initUtcTime = function() {
|
||||
|
||||
var currentDate = new Date();
|
||||
|
||||
$scope.utcTime = new Date(
|
||||
currentDate.getUTCFullYear(),
|
||||
currentDate.getUTCMonth(),
|
||||
currentDate.getUTCDate(),
|
||||
currentDate.getUTCHours(),
|
||||
currentDate.getUTCMinutes(),
|
||||
currentDate.getUTCSeconds()
|
||||
);
|
||||
};
|
||||
|
||||
var initIsTimezoneSupportEnabled = function() {
|
||||
|
||||
sitesManagerAPI.isTimezoneSupportEnabled(function (timezoneSupportEnabled) {
|
||||
$scope.timezoneSupportEnabled = timezoneSupportEnabled;
|
||||
});
|
||||
};
|
||||
|
||||
var initTimezones = function() {
|
||||
|
||||
sitesManagerAPI.getTimezonesList(
|
||||
|
||||
function (timezones) {
|
||||
|
||||
$scope.timezones = [];
|
||||
|
||||
angular.forEach(timezones, function(groupTimezones, timezoneGroup) {
|
||||
|
||||
angular.forEach(groupTimezones, function(label, code) {
|
||||
|
||||
$scope.timezones.push({
|
||||
group: timezoneGroup,
|
||||
code: code,
|
||||
label: label
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var initCustomVariablesActivated = function() {
|
||||
|
||||
coreAPI.isPluginActivated(
|
||||
|
||||
function (customVariablesActivated) {
|
||||
$scope.customVariablesActivated = customVariablesActivated;
|
||||
},
|
||||
|
||||
{pluginName: 'CustomVariables'}
|
||||
);
|
||||
};
|
||||
|
||||
var initUserIP = function() {
|
||||
|
||||
coreAPI.getIpFromHeader(function(ip) {
|
||||
$scope.currentIpAddress = ip;
|
||||
});
|
||||
};
|
||||
|
||||
var initSiteSearchSelectOptions = function() {
|
||||
|
||||
$scope.siteSearchOptions = [
|
||||
{key: '1', value: translate('SitesManager_EnableSiteSearch')},
|
||||
{key: '0', value: translate('SitesManager_DisableSiteSearch')}
|
||||
];
|
||||
};
|
||||
|
||||
var initKeepURLFragmentsList = function() {
|
||||
|
||||
$scope.keepURLFragmentsOptions = {
|
||||
0: ($scope.globalSettings.keepURLFragmentsGlobal ? translate('General_Yes') : translate('General_No')) + ' (' + translate('General_Default') + ')',
|
||||
1: translate('General_Yes'),
|
||||
2: translate('General_No')
|
||||
};
|
||||
};
|
||||
|
||||
var addNewEntity = function () {
|
||||
sitesManagerTypeModel.hasMultipleTypes().then(function (hasMultipleTypes) {
|
||||
if (hasMultipleTypes) {
|
||||
$scope.showAddSiteDialog = true;
|
||||
} else if ($scope.availableTypes.length === 1) {
|
||||
var type = $scope.availableTypes[0].id;
|
||||
addSite(type);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var addSite = function(type) {
|
||||
if (!type) {
|
||||
type = 'website'; // todo shall we really hard code this or trigger an exception or so?
|
||||
}
|
||||
|
||||
$scope.adminSites.sites.unshift({type: type});
|
||||
};
|
||||
|
||||
var saveGlobalSettings = function() {
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
|
||||
ajaxHandler.addParams({
|
||||
module: 'SitesManager',
|
||||
format: 'json',
|
||||
action: 'setGlobalSettings'
|
||||
}, 'GET');
|
||||
|
||||
ajaxHandler.addParams({
|
||||
timezone: $scope.globalSettings.defaultTimezone,
|
||||
currency: $scope.globalSettings.defaultCurrency,
|
||||
excludedIps: $scope.globalSettings.excludedIpsGlobal.join(','),
|
||||
excludedQueryParameters: $scope.globalSettings.excludedQueryParametersGlobal.join(','),
|
||||
excludedUserAgents: $scope.globalSettings.excludedUserAgentsGlobal.join(','),
|
||||
keepURLFragments: $scope.globalSettings.keepURLFragmentsGlobal ? 1 : 0,
|
||||
enableSiteUserAgentExclude: $scope.globalSettings.siteSpecificUserAgentExcludeEnabled ? 1 : 0,
|
||||
searchKeywordParameters: $scope.globalSettings.searchKeywordParametersGlobal.join(','),
|
||||
searchCategoryParameters: $scope.globalSettings.searchCategoryParametersGlobal.join(',')
|
||||
}, 'POST');
|
||||
|
||||
ajaxHandler.redirectOnSuccess($scope.redirectParams);
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
};
|
||||
|
||||
var cancelEditSite = function ($event) {
|
||||
$event.stopPropagation();
|
||||
piwik.helper.redirect($scope.redirectParams);
|
||||
};
|
||||
|
||||
var lookupCurrentEditSite = function () {
|
||||
|
||||
var sitesInEditMode = $scope.adminSites.sites.filter(function(site) {
|
||||
return site.editMode;
|
||||
});
|
||||
|
||||
return sitesInEditMode[0];
|
||||
};
|
||||
|
||||
var initCurrencyList = function () {
|
||||
|
||||
sitesManagerAPI.getCurrencyList(function (currencies) {
|
||||
$scope.currencies = currencies;
|
||||
});
|
||||
};
|
||||
|
||||
var showLoading = function() {
|
||||
$scope.loading = true;
|
||||
};
|
||||
|
||||
var hideLoading = function() {
|
||||
$scope.loading = false;
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
})();
|
||||
|
|
@ -1,473 +0,0 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
// NOTE: if you cannot find the definition of a variable here, look in index.twig
|
||||
function SitesManager(_timezones, _currencies, _defaultTimezone, _defaultCurrency) {
|
||||
|
||||
var timezones = _timezones;
|
||||
var currencies = _currencies;
|
||||
var defaultTimezone = _defaultTimezone;
|
||||
var defaultCurrency = _defaultCurrency;
|
||||
var siteBeingEdited = false;
|
||||
var siteBeingEditedName = '';
|
||||
|
||||
function sendDeleteSiteAJAX(idSite) {
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
idSite: idSite,
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'SitesManager.deleteSite'
|
||||
}, 'GET');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function sendAddSiteAJAX(row) {
|
||||
var siteName = $(row).find('input#name').val();
|
||||
var urls = $(row).find('textarea#urls').val();
|
||||
urls = urls.trim().split("\n");
|
||||
var excludedIps = $(row).find('textarea#excludedIps').val();
|
||||
excludedIps = piwikHelper.getApiFormatTextarea(excludedIps);
|
||||
var timezone = $(row).find('#timezones option:selected').val();
|
||||
var currency = $(row).find('#currencies option:selected').val();
|
||||
var excludedQueryParameters = $(row).find('textarea#excludedQueryParameters').val();
|
||||
excludedQueryParameters = piwikHelper.getApiFormatTextarea(excludedQueryParameters);
|
||||
var excludedUserAgents = $(row).find('textarea#excludedUserAgents').val();
|
||||
excludedUserAgents = piwikHelper.getApiFormatTextarea(excludedUserAgents);
|
||||
var keepURLFragments = $('#keepURLFragmentSelect', row).val();
|
||||
var ecommerce = $(row).find('#ecommerce option:selected').val();
|
||||
var sitesearch = $(row).find('#sitesearch option:selected').val();
|
||||
var searchKeywordParameters = $('input#searchKeywordParameters').val();
|
||||
var searchCategoryParameters = $('input#searchCategoryParameters').val();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'SitesManager.addSite'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams({
|
||||
siteName: siteName,
|
||||
timezone: timezone,
|
||||
currency: currency,
|
||||
ecommerce: ecommerce,
|
||||
excludedIps: excludedIps,
|
||||
excludedQueryParameters: excludedQueryParameters,
|
||||
excludedUserAgents: excludedUserAgents,
|
||||
keepURLFragments: keepURLFragments,
|
||||
siteSearch: sitesearch,
|
||||
searchKeywordParameters: searchKeywordParameters,
|
||||
searchCategoryParameters: searchCategoryParameters,
|
||||
urls: urls
|
||||
}, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function sendUpdateSiteAJAX(row) {
|
||||
var siteName = $(row).find('input#siteName').val();
|
||||
var idSite = $(row).children('#idSite').html();
|
||||
var urls = $(row).find('textarea#urls').val();
|
||||
urls = urls.trim().split("\n");
|
||||
var excludedIps = $(row).find('textarea#excludedIps').val();
|
||||
excludedIps = piwikHelper.getApiFormatTextarea(excludedIps);
|
||||
|
||||
var excludedQueryParameters = $(row).find('textarea#excludedQueryParameters').val();
|
||||
excludedQueryParameters = piwikHelper.getApiFormatTextarea(excludedQueryParameters);
|
||||
var excludedUserAgents = $(row).find('textarea#excludedUserAgents').val();
|
||||
excludedUserAgents = piwikHelper.getApiFormatTextarea(excludedUserAgents);
|
||||
var keepURLFragments = $('#keepURLFragmentSelect', row).val();
|
||||
var timezone = $(row).find('#timezones option:selected').val();
|
||||
var currency = $(row).find('#currencies option:selected').val();
|
||||
var ecommerce = $(row).find('#ecommerce option:selected').val();
|
||||
var sitesearch = $(row).find('#sitesearch option:selected').val();
|
||||
var searchKeywordParameters = $('input#searchKeywordParameters').val();
|
||||
var searchCategoryParameters = $('input#searchCategoryParameters').val();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'SitesManager.updateSite',
|
||||
idSite: idSite
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams({
|
||||
siteName: siteName,
|
||||
timezone: timezone,
|
||||
currency: currency,
|
||||
ecommerce: ecommerce,
|
||||
excludedIps: excludedIps,
|
||||
excludedQueryParameters: excludedQueryParameters,
|
||||
excludedUserAgents: excludedUserAgents,
|
||||
keepURLFragments: keepURLFragments,
|
||||
siteSearch: sitesearch,
|
||||
searchKeywordParameters: searchKeywordParameters,
|
||||
searchCategoryParameters: searchCategoryParameters,
|
||||
urls: urls
|
||||
}, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function sendGlobalSettingsAJAX() {
|
||||
var timezone = $('#defaultTimezone').find('option:selected').val();
|
||||
var currency = $('#defaultCurrency').find('option:selected').val();
|
||||
var excludedIps = $('textarea#globalExcludedIps').val();
|
||||
excludedIps = piwikHelper.getApiFormatTextarea(excludedIps);
|
||||
var excludedQueryParameters = $('textarea#globalExcludedQueryParameters').val();
|
||||
excludedQueryParameters = piwikHelper.getApiFormatTextarea(excludedQueryParameters);
|
||||
var globalExcludedUserAgents = $('textarea#globalExcludedUserAgents').val();
|
||||
globalExcludedUserAgents = piwikHelper.getApiFormatTextarea(globalExcludedUserAgents);
|
||||
var globalKeepURLFragments = $('#globalKeepURLFragments').is(':checked') ? 1 : 0;
|
||||
var searchKeywordParameters = $('input#globalSearchKeywordParameters').val();
|
||||
var searchCategoryParameters = $('input#globalSearchCategoryParameters').val();
|
||||
var enableSiteUserAgentExclude = $('input#enableSiteUserAgentExclude').is(':checked') ? 1 : 0;
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'SitesManager',
|
||||
format: 'json',
|
||||
action: 'setGlobalSettings'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams({
|
||||
timezone: timezone,
|
||||
currency: currency,
|
||||
excludedIps: excludedIps,
|
||||
excludedQueryParameters: excludedQueryParameters,
|
||||
excludedUserAgents: globalExcludedUserAgents,
|
||||
keepURLFragments: globalKeepURLFragments,
|
||||
enableSiteUserAgentExclude: enableSiteUserAgentExclude,
|
||||
searchKeywordParameters: searchKeywordParameters,
|
||||
searchCategoryParameters: searchCategoryParameters
|
||||
}, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement('#ajaxLoadingGlobalSettings');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorGlobalSettings');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
this.init = function () {
|
||||
$('.addRowSite').click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
$('.addRowSite').toggle();
|
||||
|
||||
var excludedUserAgentCell = '';
|
||||
if ($('#exclude-user-agent-header').is(':visible')) {
|
||||
excludedUserAgentCell = '<td><textarea cols="20" rows="4" id="excludedUserAgents"></textarea><br />' + excludedUserAgentsHelp + '</td>';
|
||||
}
|
||||
|
||||
var numberOfRows = $('table#editSites')[0].rows.length;
|
||||
var newRowId = 'rowNew' + numberOfRows;
|
||||
var submitButtonHtml = '<input type="submit" class="addsite submit" value="' + _pk_translate('General_Save') + '" />';
|
||||
$($.parseHTML(' <tr id="' + newRowId + '">\
|
||||
<td> </td>\
|
||||
<td><input id="name" value="Name" size="15" /><br/><br/><br/>' + submitButtonHtml + '</td>\
|
||||
<td><textarea cols="25" rows="3" id="urls">http://siteUrl.com/\nhttp://siteUrl2.com/</textarea><br />' + aliasUrlsHelp + keepURLFragmentSelectHTML + '</td>\
|
||||
<td><textarea cols="20" rows="4" id="excludedIps"></textarea><br />' + excludedIpHelp + '</td>\
|
||||
<td><textarea cols="20" rows="4" id="excludedQueryParameters"></textarea><br />' + excludedQueryParametersHelp + '</td>' +
|
||||
excludedUserAgentCell +
|
||||
'<td>' + getSitesearchSelector(false) + '</td>\
|
||||
<td>' + getTimezoneSelector(defaultTimezone) + '<br />' + timezoneHelp + '</td>\
|
||||
<td>' + getCurrencySelector(defaultCurrency) + '<br />' + currencyHelp + '</td>\
|
||||
<td>' + getEcommerceSelector(0) + '<br />' + ecommerceHelp + '</td>\
|
||||
<td>' + submitButtonHtml + '</td>\
|
||||
<td><span class="cancel link_but">' + sprintf(_pk_translate('General_OrCancel'), "", "") + '</span></td>\
|
||||
</tr>'))
|
||||
.appendTo('#editSites')
|
||||
;
|
||||
|
||||
piwikHelper.lazyScrollTo('#' + newRowId);
|
||||
|
||||
$('.addsite').click(function () {
|
||||
sendAddSiteAJAX($('tr#' + newRowId));
|
||||
});
|
||||
|
||||
$('.cancel').click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
$(this).parents('tr').remove();
|
||||
$('.addRowSite').toggle();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// when click on deleteuser, the we ask for confirmation and then delete the user
|
||||
$('.deleteSite').click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
var idRow = $(this).attr('id');
|
||||
var nameToDelete = $(this).parent().parent().find('input#siteName').val() || $(this).parent().parent().find('td#siteName').html();
|
||||
var idsiteToDelete = $(this).parent().parent().find('#idSite').html();
|
||||
|
||||
$('#confirm').find('h2').text(sprintf(_pk_translate('SitesManager_DeleteConfirm'), '"' + nameToDelete + '" (idSite = ' + idsiteToDelete + ')'));
|
||||
piwikHelper.modalConfirm('#confirm', { yes: function () {
|
||||
|
||||
sendDeleteSiteAJAX(idsiteToDelete);
|
||||
}});
|
||||
}
|
||||
);
|
||||
|
||||
var alreadyEdited = [];
|
||||
$('.editSite')
|
||||
.click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
var idRow = $(this).attr('id');
|
||||
if (alreadyEdited[idRow] == 1) return;
|
||||
if (siteBeingEdited) {
|
||||
$('#alert').find('h2').text(sprintf(_pk_translate('SitesManager_OnlyOneSiteAtTime'), '"' + $("<div/>").html(siteBeingEditedName).text() + '"'));
|
||||
piwikHelper.modalConfirm('#alert', {});
|
||||
return;
|
||||
}
|
||||
siteBeingEdited = true;
|
||||
|
||||
alreadyEdited[idRow] = 1;
|
||||
$('tr#' + idRow + ' .editableSite').each(
|
||||
// make the fields editable
|
||||
// change the EDIT button to VALID button
|
||||
function (i, n) {
|
||||
var contentBefore = $(n).html();
|
||||
|
||||
var idName = $(n).attr('id');
|
||||
if (idName == 'siteName') {
|
||||
siteBeingEditedName = contentBefore;
|
||||
var contentAfter = '<input id="' + idName + '" value="' + piwikHelper.htmlEntities( piwikHelper.htmlDecode(contentBefore))+ '" size="15" />';
|
||||
|
||||
var inputSave = $('<br/><input style="margin-top:50px" type="submit" class="submit" value="' + _pk_translate('General_Save') + '" />')
|
||||
.click(function () { submitUpdateSite($(this).parent()); });
|
||||
var spanCancel = $('<div><br/>' + sprintf(_pk_translate('General_OrCancel'), "", "") + '</div>')
|
||||
.click(function () { piwikHelper.refreshAfter(0); });
|
||||
$(n)
|
||||
.html(contentAfter)
|
||||
.keypress(submitSiteOnEnter)
|
||||
.append(inputSave)
|
||||
.append(spanCancel);
|
||||
}
|
||||
else if (idName == 'urls') {
|
||||
var keepURLFragmentsForSite = $(this).closest('tr').attr('data-keep-url-fragments');
|
||||
var contentAfter = '<textarea cols="25" rows="3" id="urls">' + contentBefore.replace(/<br *\/? *> */gi, "\n") + '</textarea>';
|
||||
contentAfter += '<br />' + aliasUrlsHelp + keepURLFragmentSelectHTML;
|
||||
$(n).html(contentAfter).find('select').val(keepURLFragmentsForSite);
|
||||
}
|
||||
else if (idName == 'excludedIps') {
|
||||
var contentAfter = '<textarea cols="20" rows="4" id="excludedIps">' + contentBefore.replace(/<br *\/? *>/gi, "\n") + '</textarea>';
|
||||
contentAfter += '<br />' + excludedIpHelp;
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
else if (idName == 'excludedQueryParameters') {
|
||||
var contentAfter = '<textarea cols="20" rows="4" id="excludedQueryParameters">' + contentBefore.replace(/<br *\/? *>/gi, "\n") + '</textarea>';
|
||||
contentAfter += '<br />' + excludedQueryParametersHelp;
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
else if (idName == 'excludedUserAgents') {
|
||||
var contentAfter = '<textarea cols="20" rows="4" id="excludedUserAgents">' +
|
||||
contentBefore.replace(/<br *\/? *>/gi, "\n") + '</textarea><br />' + excludedUserAgentsHelp;
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
else if (idName == 'timezone') {
|
||||
var contentAfter = getTimezoneSelector(contentBefore);
|
||||
contentAfter += '<br />' + timezoneHelp;
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
else if (idName == 'currency') {
|
||||
var contentAfter = getCurrencySelector(contentBefore);
|
||||
contentAfter += '<br />' + currencyHelp;
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
else if (idName == 'ecommerce') {
|
||||
var ecommerceActive = contentBefore.indexOf("ecommerceActive") > 0 ? 1 : 0;
|
||||
contentAfter = getEcommerceSelector(ecommerceActive) + '<br />' + ecommerceHelp;
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
else if (idName == 'sitesearch') {
|
||||
contentAfter = getSitesearchSelector(contentBefore);
|
||||
$(n).html(contentAfter);
|
||||
onClickSiteSearchUseDefault();
|
||||
}
|
||||
}
|
||||
);
|
||||
$(this)
|
||||
.toggle()
|
||||
.parent()
|
||||
.prepend($('<input type="submit" class="updateSite submit" value="' + _pk_translate('General_Save') + '" />')
|
||||
.click(function () { sendUpdateSiteAJAX($('tr#' + idRow)); })
|
||||
);
|
||||
});
|
||||
|
||||
$('#globalSettingsSubmit').click(function () {
|
||||
sendGlobalSettingsAJAX();
|
||||
});
|
||||
|
||||
$('#defaultTimezone').html(getTimezoneSelector(defaultTimezone));
|
||||
$('#defaultCurrency').html(getCurrencySelector(defaultCurrency));
|
||||
|
||||
$('td.editableSite').click(function (event) {
|
||||
$(this).parent().find('.editSite').click();
|
||||
});
|
||||
};
|
||||
|
||||
function getSitesearchSelector(contentBefore) {
|
||||
var globalKeywordParameters = $('input#globalSearchKeywordParameters').val().trim();
|
||||
var globalCategoryParameters = $('input#globalSearchCategoryParameters').val().trim();
|
||||
if (contentBefore) {
|
||||
var enabled = contentBefore.indexOf("sitesearchActive") > 0 ? 1 : 0;
|
||||
var spanSearch = $(contentBefore).filter('.sskp');
|
||||
var searchKeywordParameters = spanSearch.attr('sitesearch_keyword_parameters').trim();
|
||||
var searchCategoryParameters = spanSearch.attr('sitesearch_category_parameters').trim();
|
||||
var checked = globalKeywordParameters.length && !searchKeywordParameters.trim().length;
|
||||
} else {
|
||||
var searchKeywordParameters = globalKeywordParameters;
|
||||
var searchCategoryParameters = globalCategoryParameters;
|
||||
var enabled = searchKeywordParameters.length || searchCategoryParameters.length; // default is enabled
|
||||
var checked = enabled;
|
||||
}
|
||||
|
||||
var searchGlobalHasValues = globalKeywordParameters.trim().length;
|
||||
var html = '<select id="sitesearch" onchange="return onClickSiteSearchUseDefault();">';
|
||||
var selected = ' selected="selected" ';
|
||||
html += '<option ' + (enabled ? selected : '') + ' value="1">' + sitesearchEnabled + '</option>';
|
||||
html += '<option ' + (enabled ? '' : selected) + ' value="0">' + sitesearchDisabled + '</option>';
|
||||
html += '</select>';
|
||||
html += '<span style="font-size: 11px;"><br/>';
|
||||
|
||||
if (searchGlobalHasValues) {
|
||||
var checkedStr = checked ? ' checked ' : '';
|
||||
html += '<span id="sitesearchUseDefault"' + (!enabled ? ' style="display:none" ' : '') + '><input type="checkbox" '
|
||||
+ checkedStr + ' id="sitesearchUseDefaultCheck" onclick="return onClickSiteSearchUseDefault();"> '
|
||||
+ sitesearchUseDefault + ' </span>';
|
||||
+ '</label>';
|
||||
|
||||
html += '<div ' + ((checked && enabled) ? '' : 'style="display-none"') + ' class="searchDisplayParams form-description">'
|
||||
+ searchKeywordLabel + ' (' + strDefault + ') ' + ': '
|
||||
+ piwikHelper.htmlEntities( globalKeywordParameters )
|
||||
+ (globalCategoryParameters.length ? ', ' + searchCategoryLabel + ': ' + piwikHelper.htmlEntities(globalCategoryParameters) : '')
|
||||
+ '</div>';
|
||||
}
|
||||
html += '<div id="sitesearchIntro">' + sitesearchIntro + '</div>';
|
||||
|
||||
html += '<div id="searchSiteParameters">';
|
||||
html += '<br/><label><div style="margin-bottom:3px">'
|
||||
+ piwikHelper.htmlEntities(searchKeywordLabel)
|
||||
+ '</div><input type="text" size="22" id="searchKeywordParameters" value="'
|
||||
+ piwikHelper.htmlEntities(searchKeywordParameters)
|
||||
+ '" style="font-size:9pt;font-family:monospace"></input>'
|
||||
+ searchKeywordHelp + '</label>';
|
||||
|
||||
// if custom var plugin is disabled, category tracking not supported
|
||||
if (globalCategoryParameters != 'globalSearchCategoryParametersIsDisabled') {
|
||||
html += '<br/><label><div style="margin-bottom:3px">' + searchCategoryLabel + '</div><input type="text" size="22" id="searchCategoryParameters" value="' + searchCategoryParameters + '" style="font-size:9pt;font-family:monospace"></input>' + searchCategoryHelp + '</label>';
|
||||
}
|
||||
html += '</div></span>';
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function getEcommerceSelector(enabled) {
|
||||
var html = '<select id="ecommerce">';
|
||||
var selected = ' selected="selected" ';
|
||||
html += '<option ' + (enabled ? '' : selected) + ' value="0">' + ecommerceDisabled + '</option>';
|
||||
html += '<option ' + (enabled ? selected : '') + ' value="1">' + ecommerceEnabled + '</option>';
|
||||
html += '</select>';
|
||||
return html;
|
||||
}
|
||||
|
||||
function getTimezoneSelector(selectedTimezone) {
|
||||
var html = '<select id="timezones">';
|
||||
for (var continent in timezones) {
|
||||
html += '<optgroup label="' + continent + '">';
|
||||
for (var timezoneId in timezones[continent]) {
|
||||
var selected = '';
|
||||
if (timezoneId == selectedTimezone) {
|
||||
selected = ' selected="selected" ';
|
||||
}
|
||||
html += '<option ' + selected + ' value="' + timezoneId + '">' + timezones[continent][timezoneId] + '</option>';
|
||||
}
|
||||
html += "</optgroup>\n";
|
||||
}
|
||||
html += '</select>';
|
||||
return html;
|
||||
}
|
||||
|
||||
|
||||
function getCurrencySelector(selectedCurrency) {
|
||||
var html = '<select id="currencies">';
|
||||
for (var currency in currencies) {
|
||||
var selected = '';
|
||||
if (currency == selectedCurrency) {
|
||||
selected = ' selected="selected" ';
|
||||
}
|
||||
html += '<option ' + selected + ' value="' + currency + '">' + currencies[currency] + '</option>';
|
||||
}
|
||||
html += '</select>';
|
||||
return html;
|
||||
}
|
||||
|
||||
function submitSiteOnEnter(e) {
|
||||
var key = e.keyCode || e.which;
|
||||
if (key == 13) {
|
||||
submitUpdateSite(this);
|
||||
$(this).find('.addsite').click();
|
||||
}
|
||||
}
|
||||
|
||||
function submitUpdateSite(self) {
|
||||
$(self).parent().find('.updateSite').click();
|
||||
}
|
||||
}
|
||||
|
||||
function onClickSiteSearchUseDefault() {
|
||||
// Site Search enabled
|
||||
if ($('select#sitesearch').val() == "1") {
|
||||
$('#sitesearchUseDefault').show();
|
||||
|
||||
// Use default is checked
|
||||
if ($('#sitesearchUseDefaultCheck').is(':checked')) {
|
||||
$('#searchSiteParameters').hide();
|
||||
$('#sitesearchIntro').show();
|
||||
$('#searchKeywordParameters,#searchCategoryParameters').val('');
|
||||
$('.searchDisplayParams').show();
|
||||
// Use default is unchecked
|
||||
|
||||
} else {
|
||||
$('#sitesearchIntro').hide();
|
||||
$('.searchDisplayParams').hide();
|
||||
$('#searchSiteParameters').show();
|
||||
}
|
||||
} else {
|
||||
$('.searchDisplayParams').hide();
|
||||
$('#sitesearchUseDefault').hide();
|
||||
$('#searchSiteParameters').hide();
|
||||
$('#sitesearchIntro').show();
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
|
||||
// when code element is clicked, select the text
|
||||
$('.trackingHelp code').click(function() {
|
||||
// credit where credit is due:
|
||||
// http://stackoverflow.com/questions/1173194/select-all-div-text-with-single-mouse-click
|
||||
var range;
|
||||
if (document.body.createTextRange) // MSIE
|
||||
{
|
||||
range = document.body.createTextRange();
|
||||
range.moveToElementText(this);
|
||||
range.select();
|
||||
}
|
||||
else if (window.getSelection) // others
|
||||
{
|
||||
range = document.createRange();
|
||||
range.selectNodeContents(this);
|
||||
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
})
|
||||
.click();
|
||||
});
|
||||
18
www/analytics/plugins/SitesManager/lang/am.json
Normal file
18
www/analytics/plugins/SitesManager/lang/am.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"SitesManager": {
|
||||
"AddSite": "አዲስ ድር ጣቢያ ጨምር",
|
||||
"Currency": "ገንዘብ",
|
||||
"DeleteConfirm": "እርግጠኛ ነህ ድር ጣቢያውን ለመሰረዝ %s?",
|
||||
"ExceptionDeleteSite": "የተመዘገበ ብቸኛው ድር ጣቢያ ስለሆነ ለመዘረዝ አይቻልም። በመጀመሪያ አዲስ ድር ጣቢያ ጨምርና ቀጠሎ ይህንን ሰርዝ።",
|
||||
"ExceptionEmptyName": "የድር ጣቢያው ስም ባዶ መሆን አይችልም።",
|
||||
"ExceptionNoUrl": "ለዚህ ድር ጣቢያ ቢያንስ አንድ ዩ አር ኤል ማምር አለብህ።",
|
||||
"JsTrackingTagHelp": "በሁሉም ገፆች ለማካተት እንዲያስችልህ የጃቫ ስክሪፕት ዱካ መከተያ መለያ እዚህ አለ",
|
||||
"MainDescription": "የድር ማመዛዘኛ ሪፖርት ድር ጣቢያ ያስፈልጋቸዋል! ጨምር፣ አልቅ፣ ድር ጣቢያ ሰርዝ እና በገፅህ ላይ ለማስገባት የፈለግከውን የጃቫ ስክሪፕት አሳይ",
|
||||
"NoWebsites": "ለታስተዳድረው የምትችለው ምንም አይነት ድር ጣቢያ የለም",
|
||||
"ShowTrackingTag": "የዱካ መከተያ መለያ አሳይ",
|
||||
"Sites": "ድር ጣቢያዎች",
|
||||
"Timezone": "የሰዓት ሰቅ",
|
||||
"Urls": "ዩ አር ኤሎች",
|
||||
"WebsitesManagement": "የድር ጣቢያ ምነጃ"
|
||||
}
|
||||
}
|
||||
53
www/analytics/plugins/SitesManager/lang/ar.json
Normal file
53
www/analytics/plugins/SitesManager/lang/ar.json
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"SitesManager": {
|
||||
"AddSite": "أضف موقعاً جديداً",
|
||||
"AdvancedTimezoneSupportNotFound": "الدعم المتقدم لإعدادات المناطق الزمنية غير موجود في نظام PHP لديك (مدعم في الإصدار 5.2). لا يزال في إمكانك اختيار الفارق الزمني UTC يدوياً.",
|
||||
"AliasUrlHelp": "من المفضل - ولكن ليس إجبارياً - تحديد روابط ويب المتعددة - واحد لكل سطر - والتي سيستخدمها زوارك للوصول لموقعك. العناوين المرادفة لموقع ما لن تظهر في تقارير الإحالة. لاحظ أنه ليس من الضروري أن تضيف الروابط مع بادئة www وبدونها حيث يقوم Piwik بوضع الاثنين في اعتباره.",
|
||||
"ChangingYourTimezoneWillOnlyAffectDataForward": "تغيير المنطقة الزمنية سيؤثر فقط على البيانات التي ستحدث في المستقبل، ولن يكون لها أثر رجعي.",
|
||||
"ChooseCityInSameTimezoneAsYou": "اختر مدينة في نفس منطقتك الزمنية",
|
||||
"Currency": "العملة",
|
||||
"CurrencySymbolWillBeUsedForGoals": "رمز العملة الذي سيتم عرضه بجوار عائد الأهداف.",
|
||||
"DefaultCurrencyForNewWebsites": "العملة الافتراضية للمواقع الجديدة",
|
||||
"DefaultTimezoneForNewWebsites": "المنطقة الزمنية الافتراضية للمواقع الجديدة",
|
||||
"DeleteConfirm": "هل ترغب حقاً في حذف هذا الموقع %s؟",
|
||||
"ExceptionDeleteSite": "لا يمكنك حذف هذا الموقع، فهو الوحيد المسجل لديك. أضف موقعاً جديداً ثم قم بحذف هذا الموقع.",
|
||||
"ExceptionEmptyName": "لا يمكن ترك حقل اسم الموقع فارغاً.",
|
||||
"ExceptionInvalidCurrency": "العملة \"%s\" غير صالحة. الرجاء إدخال رمز عملة صالح (مثل %s).",
|
||||
"ExceptionInvalidIPFormat": "عنوان IP المستثنى \"%s\" لا يوافق صيغة عنوان IP صحيحة (مثل %s).",
|
||||
"ExceptionInvalidTimezone": "المنقطة الزمنية \"%s\" غير صالحة. الرجاء إدخال منطقة زمنية صالحة.",
|
||||
"ExceptionInvalidUrl": "الرابط \"%s\" غير صالح.",
|
||||
"ExceptionNoUrl": "يجب عليك أن تحدد رابط ويب وحيد على الأقل للموقع.",
|
||||
"ExcludedIps": "عناوين IP المستثناة",
|
||||
"ExcludedParameters": "الباراميترات المستثناة",
|
||||
"GlobalListExcludedIps": "القائمة العامة لعناوين IP المستثناة",
|
||||
"GlobalListExcludedQueryParameters": "القائمة العامة لباراميترات روابط الاستعلام المستثناة",
|
||||
"GlobalWebsitesSettings": "إعدادات المواقع العامة",
|
||||
"HelpExcludedIps": "أدخل قائمة عناوين IP، واحداً لكل سطر، والتي ترغب في استثنائها من عملية التتبع بواسطة Piwik. يمكنك استخدام العلامات العشوائية مثل %1$s أو %2$s",
|
||||
"JsTrackingTagHelp": "إليك وسم التتبع بلغة جافا لتضمنه في كافة صفحات موقعك.",
|
||||
"ListOfIpsToBeExcludedOnAllWebsites": "عناوين IP الموضحة بالأسفل سيتم استثناؤها من عمليات التتبع على كافة المواقع.",
|
||||
"ListOfQueryParametersToBeExcludedOnAllWebsites": "سيتم استثناء باراميترات روابط الاستعلام التالية من كافة روابط جميع المواقع.",
|
||||
"ListOfQueryParametersToExclude": "أدخل قائمة باراميترات روابط الاستعلام، واحداً لكل سطر، ليتم استثنءه من تقارير روابط الصفحات.",
|
||||
"MainDescription": "تحليلات ويب الخاصة بك تحتاج لمواقع! أضف، حدِّث أو احذف مواقع واعرض أكواد جافا لتدخلها في صفحاتك.",
|
||||
"NotFound": "لم يتم العثور على مواقع تخص",
|
||||
"NoWebsites": "أنت لا تملك أي مواقع لتديرها.",
|
||||
"OnlyOneSiteAtTime": "لا يمكنك تحرير أكثر من موقع في الوقت ذاته. يرجى حفظ أو إلغاء التغييرات الحالية على الموقع %s.",
|
||||
"PiwikWillAutomaticallyExcludeCommonSessionParameters": "سيقوم Piwik آلياً باستثناء كافة باراميترات الجلسات الشائعة (%s).",
|
||||
"SelectACity": "اختر مدينة",
|
||||
"SelectDefaultCurrency": "يمكنك اختيار العملة الافتراضية للمواقع الجديدة.",
|
||||
"SelectDefaultTimezone": "يمكنك تحديد منطقة زمنية افتراضية للمواقع الجديدة",
|
||||
"ShowTrackingTag": "عرض وسم التتبع",
|
||||
"Sites": "المواقع",
|
||||
"SiteWithoutDataTitle": "لم يتم تسجيل بيانات حتى الآن",
|
||||
"SiteWithoutDataDescription": "لم يتم تتبُّع بيانات إحصاء لموقع الوب هذا حتى الآن.",
|
||||
"Timezone": "المنطقة الزمنية",
|
||||
"TrackingSiteSearch": "تتبُّع البحث الداخلي للموقع",
|
||||
"TrackingTags": "وسم التتبع لموقع %s",
|
||||
"Urls": "الروابط",
|
||||
"UTCTimeIs": "توقيت UTC هو %s.",
|
||||
"WebsitesManagement": "إدارة المواقع",
|
||||
"XManagement": "إدارة %s",
|
||||
"ChooseMeasurableTypeHeadline": "ما الذي ترغب قياسه ؟",
|
||||
"YouCurrentlyHaveAccessToNWebsites": "يمكنك حالياً الوصول إلى مواقع %s.",
|
||||
"YourCurrentIpAddressIs": "عنوان IP الحالي لديك هو %s"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue