This commit is contained in:
coderkun 2015-04-27 16:42:05 +02:00
commit 046a724272
4209 changed files with 1186656 additions and 0 deletions

View file

@ -0,0 +1,209 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CoreAdminHome;
use Exception;
use Piwik\Config;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\Date;
use Piwik\Db;
use Piwik\Option;
use Piwik\Period;
use Piwik\Period\Week;
use Piwik\Piwik;
use Piwik\Plugins\PrivacyManager\PrivacyManager;
use Piwik\Plugins\SitesManager\SitesManager;
use Piwik\SettingsPiwik;
use Piwik\Site;
use Piwik\TaskScheduler;
/**
* @method static \Piwik\Plugins\CoreAdminHome\API getInstance()
*/
class API extends \Piwik\Plugin\API
{
/**
* Will run all scheduled tasks due to run at this time.
*
* @return array
*/
public function runScheduledTasks()
{
Piwik::checkUserHasSuperUserAccess();
return TaskScheduler::runTasks();
}
/*
* stores the list of websites IDs to re-reprocess in archive.php
*/
const OPTION_INVALIDATED_IDSITES = 'InvalidatedOldReports_WebsiteIds';
/**
* When tracking data in the past (using Tracking API), this function
* can be used to invalidate reports for the idSites and dates where new data
* was added.
* DEV: If you call this API, the UI should display the data correctly, but will process
* in real time, which could be very slow after large data imports.
* After calling this function via REST, you can manually force all data
* to be reprocessed by visiting the script as the Super User:
* http://example.net/piwik/misc/cron/archive.php?token_auth=$SUPER_USER_TOKEN_AUTH_HERE
* REQUIREMENTS: On large piwik setups, you will need in PHP configuration: max_execution_time = 0
* We recommend to use an hourly schedule of the script at misc/cron/archive.php
* More information: http://piwik.org/setup-auto-archiving/
*
* @param string $idSites Comma separated list of idSite that have had data imported for the specified dates
* @param string $dates Comma separated list of dates to invalidate for all these websites
* @throws Exception
* @return array
*/
public function invalidateArchivedReports($idSites, $dates)
{
$idSites = Site::getIdSitesFromIdSitesString($idSites);
if (empty($idSites)) {
throw new Exception("Specify a value for &idSites= as a comma separated list of website IDs, for which your token_auth has 'admin' permission");
}
Piwik::checkUserHasAdminAccess($idSites);
// Ensure the specified dates are valid
$toInvalidate = $invalidDates = array();
$dates = explode(',', $dates);
$dates = array_unique($dates);
foreach ($dates as $theDate) {
try {
$date = Date::factory($theDate);
} catch (Exception $e) {
$invalidDates[] = $theDate;
continue;
}
if ($date->toString() == $theDate) {
$toInvalidate[] = $date;
} else {
$invalidDates[] = $theDate;
}
}
// If using the feature "Delete logs older than N days"...
$purgeDataSettings = PrivacyManager::getPurgeDataSettings();
$logsAreDeletedBeforeThisDate = $purgeDataSettings['delete_logs_schedule_lowest_interval'];
$logsDeleteEnabled = $purgeDataSettings['delete_logs_enable'];
$minimumDateWithLogs = false;
if ($logsDeleteEnabled
&& $logsAreDeletedBeforeThisDate
) {
$minimumDateWithLogs = Date::factory('today')->subDay($logsAreDeletedBeforeThisDate);
}
// Given the list of dates, process which tables they should be deleted from
$minDate = false;
$warningDates = $processedDates = array();
/* @var $date Date */
foreach ($toInvalidate as $date) {
// we should only delete reports for dates that are more recent than N days
if ($minimumDateWithLogs
&& $date->isEarlier($minimumDateWithLogs)
) {
$warningDates[] = $date->toString();
} else {
$processedDates[] = $date->toString();
}
$month = $date->toString('Y_m');
// For a given date, we must invalidate in the monthly archive table
$datesByMonth[$month][] = $date->toString();
// But also the year stored in January
$year = $date->toString('Y_01');
$datesByMonth[$year][] = $date->toString();
// but also weeks overlapping several months stored in the month where the week is starting
/* @var $week Week */
$week = Period::factory('week', $date);
$weekAsString = $week->getDateStart()->toString('Y_m');
$datesByMonth[$weekAsString][] = $date->toString();
// Keep track of the minimum date for each website
if ($minDate === false
|| $date->isEarlier($minDate)
) {
$minDate = $date;
}
}
// In each table, invalidate day/week/month/year containing this date
$archiveTables = ArchiveTableCreator::getTablesArchivesInstalled();
foreach ($archiveTables as $table) {
// Extract Y_m from table name
$suffix = ArchiveTableCreator::getDateFromTableName($table);
if (!isset($datesByMonth[$suffix])) {
continue;
}
// Dates which are to be deleted from this table
$datesToDeleteInTable = $datesByMonth[$suffix];
// Build one statement to delete all dates from the given table
$sql = $bind = array();
$datesToDeleteInTable = array_unique($datesToDeleteInTable);
foreach ($datesToDeleteInTable as $dateToDelete) {
$sql[] = '(date1 <= ? AND ? <= date2)';
$bind[] = $dateToDelete;
$bind[] = $dateToDelete;
}
$sql = implode(" OR ", $sql);
$query = "DELETE FROM $table " .
" WHERE ( $sql ) " .
" AND idsite IN (" . implode(",", $idSites) . ")";
Db::query($query, $bind);
}
\Piwik\Plugins\SitesManager\API::getInstance()->updateSiteCreatedTime($idSites, $minDate);
// Force to re-process data for these websites in the next archive.php cron run
$invalidatedIdSites = self::getWebsiteIdsToInvalidate();
$invalidatedIdSites = array_merge($invalidatedIdSites, $idSites);
$invalidatedIdSites = array_unique($invalidatedIdSites);
$invalidatedIdSites = array_values($invalidatedIdSites);
Option::set(self::OPTION_INVALIDATED_IDSITES, serialize($invalidatedIdSites));
Site::clearCache();
$output = array();
// output logs
if ($warningDates) {
$output[] = 'Warning: the following Dates have not been invalidated, because they are earlier than your Log Deletion limit: ' .
implode(", ", $warningDates) .
"\n The last day with logs is " . $minimumDateWithLogs . ". " .
"\n Please disable 'Delete old Logs' or set it to a higher deletion threshold (eg. 180 days or 365 years).'.";
}
$output[] = "Success. The following dates were invalidated successfully: " .
implode(", ", $processedDates);
return $output;
}
/**
* Returns array of idSites to force re-process next time archive.php runs
*
* @ignore
* @return mixed
*/
static public function getWebsiteIdsToInvalidate()
{
Piwik::checkUserHasSomeAdminAccess();
Option::clearCachedOption(self::OPTION_INVALIDATED_IDSITES);
$invalidatedIdSites = Option::get(self::OPTION_INVALIDATED_IDSITES);
if ($invalidatedIdSites
&& ($invalidatedIdSites = unserialize($invalidatedIdSites))
&& count($invalidatedIdSites)
) {
return $invalidatedIdSites;
}
return array();
}
}

View file

@ -0,0 +1,351 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CoreAdminHome;
use Exception;
use Piwik\API\ResponseBuilder;
use Piwik\ArchiveProcessor\Rules;
use Piwik\Common;
use Piwik\Config;
use Piwik\DataTable\Renderer\Json;
use Piwik\Menu\MenuTop;
use Piwik\Nonce;
use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugins\CorePluginsAdmin\UpdateCommunication;
use Piwik\Plugins\CustomVariables\CustomVariables;
use Piwik\Plugins\LanguagesManager\API as APILanguagesManager;
use Piwik\Plugins\LanguagesManager\LanguagesManager;
use Piwik\Plugins\SitesManager\API as APISitesManager;
use Piwik\Settings\Manager as SettingsManager;
use Piwik\Site;
use Piwik\Tracker\IgnoreCookie;
use Piwik\Url;
use Piwik\View;
/**
*
*/
class Controller extends \Piwik\Plugin\ControllerAdmin
{
const SET_PLUGIN_SETTINGS_NONCE = 'CoreAdminHome.setPluginSettings';
public function index()
{
$this->redirectToIndex('UsersManager', 'userSettings');
return;
}
public function generalSettings()
{
Piwik::checkUserHasSomeAdminAccess();
$view = new View('@CoreAdminHome/generalSettings');
if (Piwik::hasUserSuperUserAccess()) {
$this->handleGeneralSettingsAdmin($view);
$view->trustedHosts = Url::getTrustedHostsFromConfig();
$logo = new CustomLogo();
$view->branding = array('use_custom_logo' => $logo->isEnabled());
$view->logosWriteable = $logo->isCustomLogoWritable();
$view->pathUserLogo = CustomLogo::getPathUserLogo();
$view->pathUserLogoSmall = CustomLogo::getPathUserLogoSmall();
$view->pathUserLogoSVG = CustomLogo::getPathUserSvgLogo();
$view->pathUserLogoDirectory = realpath(dirname($view->pathUserLogo) . '/');
}
$view->language = LanguagesManager::getLanguageCodeForCurrentUser();
$this->setBasicVariablesView($view);
return $view->render();
}
public function pluginSettings()
{
Piwik::checkUserIsNotAnonymous();
$settings = $this->getPluginSettings();
$view = new View('@CoreAdminHome/pluginSettings');
$view->nonce = Nonce::getNonce(static::SET_PLUGIN_SETTINGS_NONCE);
$view->pluginSettings = $settings;
$view->firstSuperUserSettingNames = $this->getFirstSuperUserSettingNames($settings);
$this->setBasicVariablesView($view);
return $view->render();
}
private function getPluginSettings()
{
$pluginsSettings = SettingsManager::getPluginSettingsForCurrentUser();
ksort($pluginsSettings);
return $pluginsSettings;
}
/**
* @param \Piwik\Plugin\Settings[] $pluginsSettings
* @return array array([pluginName] => [])
*/
private function getFirstSuperUserSettingNames($pluginsSettings)
{
$names = array();
foreach ($pluginsSettings as $pluginName => $pluginSettings) {
foreach ($pluginSettings->getSettingsForCurrentUser() as $setting) {
if ($setting instanceof \Piwik\Settings\SystemSetting) {
$names[$pluginName] = $setting->getName();
break;
}
}
}
return $names;
}
public function setPluginSettings()
{
Piwik::checkUserIsNotAnonymous();
Json::sendHeaderJSON();
$nonce = Common::getRequestVar('nonce', null, 'string');
if (!Nonce::verifyNonce(static::SET_PLUGIN_SETTINGS_NONCE, $nonce)) {
return json_encode(array(
'result' => 'error',
'message' => Piwik::translate('General_ExceptionNonceMismatch')
));
}
$pluginsSettings = SettingsManager::getPluginSettingsForCurrentUser();
try {
foreach ($pluginsSettings as $pluginName => $pluginSetting) {
foreach ($pluginSetting->getSettingsForCurrentUser() as $setting) {
$value = $this->findSettingValueFromRequest($pluginName, $setting->getKey());
if (!is_null($value)) {
$setting->setValue($value);
}
}
}
foreach ($pluginsSettings as $pluginSetting) {
$pluginSetting->save();
}
} catch (Exception $e) {
$message = html_entity_decode($e->getMessage(), ENT_QUOTES, 'UTF-8');
return json_encode(array('result' => 'error', 'message' => $message));
}
Nonce::discardNonce(static::SET_PLUGIN_SETTINGS_NONCE);
return json_encode(array('result' => 'success'));
}
private function findSettingValueFromRequest($pluginName, $settingKey)
{
$changedPluginSettings = Common::getRequestVar('settings', null, 'array');
if (!array_key_exists($pluginName, $changedPluginSettings)) {
return;
}
$settings = $changedPluginSettings[$pluginName];
foreach ($settings as $setting) {
if ($setting['name'] == $settingKey) {
return $setting['value'];
}
}
}
public function setGeneralSettings()
{
Piwik::checkUserHasSuperUserAccess();
$response = new ResponseBuilder(Common::getRequestVar('format'));
try {
$this->checkTokenInUrl();
$this->saveGeneralSettings();
$customLogo = new CustomLogo();
if (Common::getRequestVar('useCustomLogo', '0')) {
$customLogo->enable();
} else {
$customLogo->disable();
}
$toReturn = $response->getResponse();
} catch (Exception $e) {
$toReturn = $response->getResponseException($e);
}
return $toReturn;
}
/**
* Renders and echo's an admin page that lets users generate custom JavaScript
* tracking code and custom image tracker links.
*/
public function trackingCodeGenerator()
{
$view = new View('@CoreAdminHome/trackingCodeGenerator');
$this->setBasicVariablesView($view);
$view->topMenu = MenuTop::getInstance()->getMenu();
$viewableIdSites = APISitesManager::getInstance()->getSitesIdWithAtLeastViewAccess();
$defaultIdSite = reset($viewableIdSites);
$view->idSite = Common::getRequestVar('idSite', $defaultIdSite, 'int');
$view->defaultReportSiteName = Site::getNameFor($view->idSite);
$view->defaultSiteRevenue = \Piwik\MetricsFormatter::getCurrencySymbol($view->idSite);
$view->maxCustomVariables = CustomVariables::getMaxCustomVariables();
$allUrls = APISitesManager::getInstance()->getSiteUrlsFromId($view->idSite);
if (isset($allUrls[1])) {
$aliasUrl = $allUrls[1];
} else {
$aliasUrl = 'x.domain.com';
}
$view->defaultReportSiteAlias = $aliasUrl;
$mainUrl = Site::getMainUrlFor($view->idSite);
$view->defaultReportSiteDomain = @parse_url($mainUrl, PHP_URL_HOST);
// get currencies for each viewable site
$view->currencySymbols = APISitesManager::getInstance()->getCurrencySymbols();
$view->serverSideDoNotTrackEnabled = \Piwik\Plugins\PrivacyManager\DoNotTrackHeaderChecker::isActive();
return $view->render();
}
/**
* Shows the "Track Visits" checkbox.
*/
public function optOut()
{
$trackVisits = !IgnoreCookie::isIgnoreCookieFound();
$nonce = Common::getRequestVar('nonce', false);
$language = Common::getRequestVar('language', '');
if ($nonce !== false && Nonce::verifyNonce('Piwik_OptOut', $nonce)) {
Nonce::discardNonce('Piwik_OptOut');
IgnoreCookie::setIgnoreCookie();
$trackVisits = !$trackVisits;
}
$view = new View('@CoreAdminHome/optOut');
$view->trackVisits = $trackVisits;
$view->nonce = Nonce::getNonce('Piwik_OptOut', 3600);
$view->language = APILanguagesManager::getInstance()->isLanguageAvailable($language)
? $language
: LanguagesManager::getLanguageCodeForCurrentUser();
return $view->render();
}
public function uploadCustomLogo()
{
Piwik::checkUserHasSuperUserAccess();
$logo = new CustomLogo();
$success = $logo->copyUploadedLogoToFilesystem();
if($success) {
return '1';
}
return '0';
}
static public function isGeneralSettingsAdminEnabled()
{
return (bool) Config::getInstance()->General['enable_general_settings_admin'];
}
private function saveGeneralSettings()
{
if(!self::isGeneralSettingsAdminEnabled()) {
// General settings + Beta channel + SMTP settings is disabled
return;
}
// General Setting
$enableBrowserTriggerArchiving = Common::getRequestVar('enableBrowserTriggerArchiving');
$todayArchiveTimeToLive = Common::getRequestVar('todayArchiveTimeToLive');
Rules::setBrowserTriggerArchiving((bool)$enableBrowserTriggerArchiving);
Rules::setTodayArchiveTimeToLive($todayArchiveTimeToLive);
// update beta channel setting
$debug = Config::getInstance()->Debug;
$debug['allow_upgrades_to_beta'] = Common::getRequestVar('enableBetaReleaseCheck', '0', 'int');
Config::getInstance()->Debug = $debug;
// Update email settings
$mail = array();
$mail['transport'] = (Common::getRequestVar('mailUseSmtp') == '1') ? 'smtp' : '';
$mail['port'] = Common::getRequestVar('mailPort', '');
$mail['host'] = Common::unsanitizeInputValue(Common::getRequestVar('mailHost', ''));
$mail['type'] = Common::getRequestVar('mailType', '');
$mail['username'] = Common::unsanitizeInputValue(Common::getRequestVar('mailUsername', ''));
$mail['password'] = Common::unsanitizeInputValue(Common::getRequestVar('mailPassword', ''));
$mail['encryption'] = Common::getRequestVar('mailEncryption', '');
Config::getInstance()->mail = $mail;
// update trusted host settings
$trustedHosts = Common::getRequestVar('trustedHosts', false, 'json');
if ($trustedHosts !== false) {
Url::saveTrustedHostnameInConfig($trustedHosts);
}
Config::getInstance()->forceSave();
$pluginUpdateCommunication = new UpdateCommunication();
if (Common::getRequestVar('enablePluginUpdateCommunication', '0', 'int')) {
$pluginUpdateCommunication->enable();
} else {
$pluginUpdateCommunication->disable();
}
}
private function handleGeneralSettingsAdmin($view)
{
// Whether to display or not the general settings (cron, beta, smtp)
$view->isGeneralSettingsAdminEnabled = self::isGeneralSettingsAdminEnabled();
if($view->isGeneralSettingsAdminEnabled) {
$this->displayWarningIfConfigFileNotWritable();
}
$enableBrowserTriggerArchiving = Rules::isBrowserTriggerEnabled();
$todayArchiveTimeToLive = Rules::getTodayArchiveTimeToLive();
$showWarningCron = false;
if (!$enableBrowserTriggerArchiving
&& $todayArchiveTimeToLive < 3600
) {
$showWarningCron = true;
}
$view->showWarningCron = $showWarningCron;
$view->todayArchiveTimeToLive = $todayArchiveTimeToLive;
$view->enableBrowserTriggerArchiving = $enableBrowserTriggerArchiving;
$view->enableBetaReleaseCheck = Config::getInstance()->Debug['allow_upgrades_to_beta'];
$view->mail = Config::getInstance()->mail;
$pluginUpdateCommunication = new UpdateCommunication();
$view->canUpdateCommunication = $pluginUpdateCommunication->canBeEnabled();
$view->enableSendPluginUpdateCommunication = $pluginUpdateCommunication->isEnabled();
}
}

View file

@ -0,0 +1,129 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CoreAdminHome;
use Piwik\DataAccess\ArchiveSelector;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\Date;
use Piwik\Db;
use Piwik\Menu\MenuAdmin;
use Piwik\Piwik;
use Piwik\ScheduledTask;
use Piwik\ScheduledTime;
use Piwik\Settings\Manager as SettingsManager;
use Piwik\Settings\UserSetting;
/**
*
*/
class CoreAdminHome extends \Piwik\Plugin
{
/**
* @see Piwik\Plugin::getListHooksRegistered
*/
public function getListHooksRegistered()
{
return array(
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'Menu.Admin.addItems' => 'addMenu',
'TaskScheduler.getScheduledTasks' => 'getScheduledTasks',
'UsersManager.deleteUser' => 'cleanupUser'
);
}
public function cleanupUser($userLogin)
{
UserSetting::removeAllUserSettingsForUser($userLogin);
}
public function getScheduledTasks(&$tasks)
{
// general data purge on older archive tables, executed daily
$purgeArchiveTablesTask = new ScheduledTask ($this,
'purgeOutdatedArchives',
null,
ScheduledTime::factory('daily'),
ScheduledTask::HIGH_PRIORITY);
$tasks[] = $purgeArchiveTablesTask;
// lowest priority since tables should be optimized after they are modified
$optimizeArchiveTableTask = new ScheduledTask ($this,
'optimizeArchiveTable',
null,
ScheduledTime::factory('daily'),
ScheduledTask::LOWEST_PRIORITY);
$tasks[] = $optimizeArchiveTableTask;
}
public function getStylesheetFiles(&$stylesheets)
{
$stylesheets[] = "libs/jquery/themes/base/jquery-ui.css";
$stylesheets[] = "plugins/CoreAdminHome/stylesheets/menu.less";
$stylesheets[] = "plugins/Zeitgeist/stylesheets/base.less";
$stylesheets[] = "plugins/CoreAdminHome/stylesheets/generalSettings.less";
$stylesheets[] = "plugins/CoreAdminHome/stylesheets/pluginSettings.less";
}
public function getJsFiles(&$jsFiles)
{
$jsFiles[] = "libs/jquery/jquery.js";
$jsFiles[] = "libs/jquery/jquery-ui.js";
$jsFiles[] = "libs/jquery/jquery.browser.js";
$jsFiles[] = "libs/javascript/sprintf.js";
$jsFiles[] = "plugins/Zeitgeist/javascripts/piwikHelper.js";
$jsFiles[] = "plugins/Zeitgeist/javascripts/ajaxHelper.js";
$jsFiles[] = "libs/jquery/jquery.history.js";
$jsFiles[] = "plugins/CoreHome/javascripts/broadcast.js";
$jsFiles[] = "plugins/CoreAdminHome/javascripts/generalSettings.js";
$jsFiles[] = "plugins/CoreHome/javascripts/donate.js";
$jsFiles[] = "plugins/CoreAdminHome/javascripts/pluginSettings.js";
}
function addMenu()
{
MenuAdmin::getInstance()->add('CoreAdminHome_MenuManage', null, "", Piwik::isUserHasSomeAdminAccess(), $order = 1);
MenuAdmin::getInstance()->add('CoreAdminHome_MenuDiagnostic', null, "", Piwik::isUserHasSomeAdminAccess(), $order = 10);
MenuAdmin::getInstance()->add('General_Settings', null, "", Piwik::isUserHasSomeAdminAccess(), $order = 5);
MenuAdmin::getInstance()->add('General_Settings', 'CoreAdminHome_MenuGeneralSettings',
array('module' => 'CoreAdminHome', 'action' => 'generalSettings'),
Piwik::isUserHasSomeAdminAccess(),
$order = 6);
MenuAdmin::getInstance()->add('CoreAdminHome_MenuManage', 'CoreAdminHome_TrackingCode',
array('module' => 'CoreAdminHome', 'action' => 'trackingCodeGenerator'),
Piwik::isUserHasSomeAdminAccess(),
$order = 4);
MenuAdmin::getInstance()->add('General_Settings', 'CoreAdminHome_PluginSettings',
array('module' => 'CoreAdminHome', 'action' => 'pluginSettings'),
SettingsManager::hasPluginsSettingsForCurrentUser(),
$order = 7);
}
function purgeOutdatedArchives()
{
$archiveTables = ArchiveTableCreator::getTablesArchivesInstalled();
foreach ($archiveTables as $table) {
$date = ArchiveTableCreator::getDateFromTableName($table);
list($year, $month) = explode('_', $date);
// Somehow we may have archive tables created with older dates, prevent exception from being thrown
if($year > 1990) {
ArchiveSelector::purgeOutdatedArchives(Date::factory("$year-$month-15"));
}
}
}
function optimizeArchiveTable()
{
$archiveTables = ArchiveTableCreator::getTablesArchivesInstalled();
Db::optimizeTables($archiveTables);
}
}

View file

@ -0,0 +1,203 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CoreAdminHome;
use Piwik\Config;
use Piwik\Filesystem;
use Piwik\Option;
use Piwik\SettingsPiwik;
class CustomLogo
{
const LOGO_HEIGHT = 300;
const LOGO_SMALL_HEIGHT = 100;
public function getLogoUrl($pathOnly = false)
{
$defaultLogo = 'plugins/Zeitgeist/images/logo.png';
$themeLogo = 'plugins/%s/images/logo.png';
$userLogo = CustomLogo::getPathUserLogo();
return $this->getPathToLogo($pathOnly, $defaultLogo, $themeLogo, $userLogo);
}
public function getHeaderLogoUrl($pathOnly = false)
{
$defaultLogo = 'plugins/Zeitgeist/images/logo-header.png';
$themeLogo = 'plugins/%s/images/logo-header.png';
$customLogo = CustomLogo::getPathUserLogoSmall();
return $this->getPathToLogo($pathOnly, $defaultLogo, $themeLogo, $customLogo);
}
public function getSVGLogoUrl($pathOnly = false)
{
$defaultLogo = 'plugins/Zeitgeist/images/logo.svg';
$themeLogo = 'plugins/%s/images/logo.svg';
$customLogo = CustomLogo::getPathUserSvgLogo();
$svg = $this->getPathToLogo($pathOnly, $defaultLogo, $themeLogo, $customLogo);
return $svg;
}
public function isEnabled()
{
return (bool) Option::get('branding_use_custom_logo');
}
public function enable()
{
Option::set('branding_use_custom_logo', '1', true);
}
public function disable()
{
Option::set('branding_use_custom_logo', '0', true);
}
public function hasSVGLogo()
{
if (!$this->isEnabled()) {
/* We always have our application logo */
return true;
}
if ($this->isEnabled()
&& file_exists(Filesystem::getPathToPiwikRoot() . '/' . CustomLogo::getPathUserSvgLogo())
) {
return true;
}
return false;
}
/**
* @return bool
*/
public function isCustomLogoWritable()
{
if(Config::getInstance()->General['enable_custom_logo_check'] == 0) {
return true;
}
$pathUserLogo = $this->getPathUserLogo();
$directoryWritingTo = PIWIK_DOCUMENT_ROOT . '/' . dirname($pathUserLogo);
// Create directory if not already created
Filesystem::mkdir($directoryWritingTo, $denyAccess = false);
$directoryWritable = is_writable($directoryWritingTo);
$logoFilesWriteable = is_writeable(PIWIK_DOCUMENT_ROOT . '/' . $pathUserLogo)
&& is_writeable(PIWIK_DOCUMENT_ROOT . '/' . $this->getPathUserSvgLogo())
&& is_writeable(PIWIK_DOCUMENT_ROOT . '/' . $this->getPathUserLogoSmall());;
$serverUploadEnabled = ini_get('file_uploads') == 1;
$isCustomLogoWritable = ($logoFilesWriteable || $directoryWritable) && $serverUploadEnabled;
return $isCustomLogoWritable;
}
protected function getPathToLogo($pathOnly, $defaultLogo, $themeLogo, $customLogo)
{
$pathToPiwikRoot = Filesystem::getPathToPiwikRoot();
$logo = $defaultLogo;
$themeName = \Piwik\Plugin\Manager::getInstance()->getThemeEnabled()->getPluginName();
$themeLogo = sprintf($themeLogo, $themeName);
if (file_exists($pathToPiwikRoot . '/' . $themeLogo)) {
$logo = $themeLogo;
}
if ($this->isEnabled()
&& file_exists($pathToPiwikRoot . '/' . $customLogo)
) {
$logo = $customLogo;
}
if (!$pathOnly) {
return SettingsPiwik::getPiwikUrl() . $logo;
}
return $pathToPiwikRoot . '/' . $logo;
}
public static function getPathUserLogo()
{
return self::rewritePath('misc/user/logo.png');
}
public static function getPathUserSvgLogo()
{
return self::rewritePath('misc/user/logo.svg');
}
public static function getPathUserLogoSmall()
{
return self::rewritePath('misc/user/logo-header.png');
}
protected static function rewritePath($path)
{
return SettingsPiwik::rewriteMiscUserPathWithHostname($path);
}
public function copyUploadedLogoToFilesystem()
{
if (empty($_FILES['customLogo'])
|| !empty($_FILES['customLogo']['error'])
) {
return false;
}
$file = $_FILES['customLogo']['tmp_name'];
if (!file_exists($file)) {
return false;
}
list($width, $height) = getimagesize($file);
switch ($_FILES['customLogo']['type']) {
case 'image/jpeg':
$image = imagecreatefromjpeg($file);
break;
case 'image/png':
$image = imagecreatefrompng($file);
break;
case 'image/gif':
$image = imagecreatefromgif($file);
break;
default:
return false;
}
$widthExpected = round($width * self::LOGO_HEIGHT / $height);
$smallWidthExpected = round($width * self::LOGO_SMALL_HEIGHT / $height);
$logo = imagecreatetruecolor($widthExpected, self::LOGO_HEIGHT);
$logoSmall = imagecreatetruecolor($smallWidthExpected, self::LOGO_SMALL_HEIGHT);
// Handle transparency
$background = imagecolorallocate($logo, 0, 0, 0);
$backgroundSmall = imagecolorallocate($logoSmall, 0, 0, 0);
imagecolortransparent($logo, $background);
imagecolortransparent($logoSmall, $backgroundSmall);
if ($_FILES['customLogo']['type'] == 'image/png') {
imagealphablending($logo, false);
imagealphablending($logoSmall, false);
imagesavealpha($logo, true);
imagesavealpha($logoSmall, true);
}
imagecopyresized($logo, $image, 0, 0, 0, 0, $widthExpected, self::LOGO_HEIGHT, $width, $height);
imagecopyresized($logoSmall, $image, 0, 0, 0, 0, $smallWidthExpected, self::LOGO_SMALL_HEIGHT, $width, $height);
imagepng($logo, PIWIK_DOCUMENT_ROOT . '/' . $this->getPathUserLogo(), 3);
imagepng($logoSmall, PIWIK_DOCUMENT_ROOT . '/' . $this->getPathUserLogoSmall(), 3);
return true;
}
}

View file

@ -0,0 +1,142 @@
/*!
* Piwik - Web Analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
function sendGeneralSettingsAJAX() {
var enableBrowserTriggerArchiving = $('input[name=enableBrowserTriggerArchiving]:checked').val();
var enablePluginUpdateCommunication = $('input[name=enablePluginUpdateCommunication]:checked').val();
var enableBetaReleaseCheck = $('input[name=enableBetaReleaseCheck]:checked').val();
var todayArchiveTimeToLive = $('#todayArchiveTimeToLive').val();
var trustedHosts = [];
$('input[name=trusted_host]').each(function () {
trustedHosts.push($(this).val());
});
var ajaxHandler = new ajaxHelper();
ajaxHandler.setLoadingElement();
ajaxHandler.addParams({
format: 'json',
enableBrowserTriggerArchiving: enableBrowserTriggerArchiving,
enablePluginUpdateCommunication: enablePluginUpdateCommunication,
enableBetaReleaseCheck: enableBetaReleaseCheck,
todayArchiveTimeToLive: todayArchiveTimeToLive,
mailUseSmtp: isSmtpEnabled(),
mailPort: $('#mailPort').val(),
mailHost: $('#mailHost').val(),
mailType: $('#mailType').val(),
mailUsername: $('#mailUsername').val(),
mailPassword: $('#mailPassword').val(),
mailEncryption: $('#mailEncryption').val(),
useCustomLogo: isCustomLogoEnabled(),
trustedHosts: JSON.stringify(trustedHosts)
}, 'POST');
ajaxHandler.addParams({
module: 'CoreAdminHome',
action: 'setGeneralSettings'
}, 'GET');
ajaxHandler.redirectOnSuccess();
ajaxHandler.send(true);
}
function showSmtpSettings(value) {
$('#smtpSettings').toggle(value == 1);
}
function isSmtpEnabled() {
return $('input[name="mailUseSmtp"]:checked').val();
}
function showCustomLogoSettings(value) {
$('#logoSettings').toggle(value == 1);
}
function isCustomLogoEnabled() {
return $('input[name="useCustomLogo"]:checked').val();
}
function refreshCustomLogo() {
var imageDiv = $("#currentLogo");
if (imageDiv && imageDiv.attr("src")) {
var logoUrl = imageDiv.attr("src").split("?")[0];
imageDiv.attr("src", logoUrl + "?" + (new Date()).getTime());
}
}
$(document).ready(function () {
var originalTrustedHostCount = $('input[name=trusted_host]').length;
showSmtpSettings(isSmtpEnabled());
showCustomLogoSettings(isCustomLogoEnabled());
$('#generalSettingsSubmit').click(function () {
var doSubmit = function () {
sendGeneralSettingsAJAX();
};
var hasTrustedHostsChanged = false,
hosts = $('input[name=trusted_host]');
if (hosts.length != originalTrustedHostCount) {
hasTrustedHostsChanged = true;
}
else {
hosts.each(function () {
hasTrustedHostsChanged |= this.defaultValue != this.value;
});
}
// if trusted hosts have changed, make sure to ask for confirmation
if (hasTrustedHostsChanged) {
piwikHelper.modalConfirm('#confirmTrustedHostChange', {yes: doSubmit});
}
else {
doSubmit();
}
});
$('input[name=mailUseSmtp]').click(function () {
showSmtpSettings($(this).val());
});
$('input[name=useCustomLogo]').click(function () {
refreshCustomLogo();
showCustomLogoSettings($(this).val());
});
$('input').keypress(function (e) {
var key = e.keyCode || e.which;
if (key == 13) {
$('#generalSettingsSubmit').click();
}
}
);
$("#logoUploadForm").submit(function (data) {
var submittingForm = $(this);
var frameName = "upload" + (new Date()).getTime();
var uploadFrame = $("<iframe name=\"" + frameName + "\" />");
uploadFrame.css("display", "none");
uploadFrame.load(function (data) {
setTimeout(function () {
refreshCustomLogo();
uploadFrame.remove();
}, 1000);
});
$("body:first").append(uploadFrame);
submittingForm.attr("target", frameName);
});
$('#customLogo').change(function () {$("#logoUploadForm").submit()});
// trusted hosts event handling
var trustedHostSettings = $('#trustedHostSettings');
trustedHostSettings.on('click', '.remove-trusted-host', function (e) {
e.preventDefault();
$(this).parent('li').remove();
return false;
});
trustedHostSettings.find('.add-trusted-host').click(function (e) {
e.preventDefault();
// append new row to the table
trustedHostSettings.find('ul').append(trustedHostSettings.find('li:last').clone());
trustedHostSettings.find('li:last input').val('');
return false;
});
});

View file

@ -0,0 +1,310 @@
/*!
* Piwik - Web Analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function ($, require) {
var piwikHost = window.location.host,
piwikPath = location.pathname.substring(0, location.pathname.lastIndexOf('/')),
exports = require('piwik/Tracking');
/**
* This class is deprecated. Use server-side events instead.
*
* @deprecated
*/
var TrackingCodeGenerator = function () {
// empty
};
var TrackingCodeGeneratorSingleton = exports.TrackingCodeGenerator = new TrackingCodeGenerator();
$(document).ready(function () {
// get preloaded server-side data necessary for code generation
var dataElement = $('#js-tracking-generator-data'),
currencySymbols = JSON.parse(dataElement.attr('data-currencies')),
maxCustomVariables = parseInt(dataElement.attr('max-custom-variables'), 10),
siteUrls = {},
siteCurrencies = {},
allGoals = {},
noneText = $('#image-tracker-goal').find('>option').text();
//
// utility methods
//
// returns JavaScript code for tracking custom variables based on an array of
// custom variable name-value pairs (so an array of 2-element arrays) and
// a scope (either 'visit' or 'page')
var getCustomVariableJS = function (customVariables, scope) {
var result = '';
for (var i = 0; i != 5; ++i) {
if (customVariables[i]) {
var key = customVariables[i][0],
value = customVariables[i][1];
result += ' _paq.push(["setCustomVariable", ' + (i + 1) + ', ' + JSON.stringify(key) + ', '
+ JSON.stringify(value) + ', ' + JSON.stringify(scope) + ']);\n';
}
}
return result;
};
// gets the list of custom variables entered by the user in a custom variable
// section
var getCustomVariables = function (sectionId) {
var customVariableNames = $('.custom-variable-name', '#' + sectionId),
customVariableValues = $('.custom-variable-value', '#' + sectionId);
var result = [];
if ($('.section-toggler-link', '#' + sectionId).is(':checked')) {
for (var i = 0; i != customVariableNames.length; ++i) {
var name = $(customVariableNames[i]).val();
result[i] = null;
if (name) {
result[i] = [name, $(customVariableValues[i]).val()];
}
}
}
return result;
};
// quickly gets the host + port from a url
var getHostNameFromUrl = function (url) {
var element = $('<a></a>')[0];
element.href = url;
return element.hostname;
};
// queries Piwik for needed site info for one site
var getSiteData = function (idSite, sectionSelect, callback) {
// if data is already loaded, don't do an AJAX request
if (siteUrls[idSite]
&& siteCurrencies[idSite]
&& typeof allGoals[idSite] !== 'undefined'
) {
callback();
return;
}
// disable section
$(sectionSelect).find('input,select,textarea').attr('disabled', 'disabled');
var ajaxRequest = new ajaxHelper();
ajaxRequest.setBulkRequests(
// get site info (for currency)
{
module: 'API',
method: 'SitesManager.getSiteFromId',
idSite: idSite
},
// get site urls
{
module: 'API',
method: 'SitesManager.getSiteUrlsFromId',
idSite: idSite
},
// get site goals
{
module: 'API',
method: 'Goals.getGoals',
idSite: idSite
}
);
ajaxRequest.setCallback(function (data) {
var currency = data[0][0].currency || '';
siteCurrencies[idSite] = currencySymbols[currency.toUpperCase()];
siteUrls[idSite] = data[1] || [];
allGoals[idSite] = data[2] || [];
// re-enable controls
$(sectionSelect).find('input,select,textarea').removeAttr('disabled');
callback();
});
ajaxRequest.setFormat('json');
ajaxRequest.send(false);
};
// resets the select options of a goal select using a site ID
var resetGoalSelectItems = function (idsite, id) {
var selectElement = $('#' + id).html('');
selectElement.append($('<option value=""></option>').text(noneText));
var goals = allGoals[idsite] || [];
for (var key in goals) {
var goal = goals[key];
selectElement.append($('<option/>').val(goal.idgoal).text(goal.name));
}
// set currency string
$('#' + id).parent().find('.currency').text(siteCurrencies[idsite]);
};
// function that generates JS code
var generateJsCodeAjax = null,
generateJsCode = function () {
// get params used to generate JS code
var params = {
piwikUrl: piwikHost + piwikPath,
groupPageTitlesByDomain: $('#javascript-tracking-group-by-domain').is(':checked') ? 1 : 0,
mergeSubdomains: $('#javascript-tracking-all-subdomains').is(':checked') ? 1 : 0,
mergeAliasUrls: $('#javascript-tracking-all-aliases').is(':checked') ? 1 : 0,
visitorCustomVariables: getCustomVariables('javascript-tracking-visitor-cv'),
pageCustomVariables: getCustomVariables('javascript-tracking-page-cv'),
customCampaignNameQueryParam: null,
customCampaignKeywordParam: null,
doNotTrack: $('#javascript-tracking-do-not-track').is(':checked') ? 1 : 0,
};
if ($('#custom-campaign-query-params-check').is(':checked')) {
params.customCampaignNameQueryParam = $('#custom-campaign-name-query-param').val();
params.customCampaignKeywordParam = $('#custom-campaign-keyword-query-param').val();
}
if (generateJsCodeAjax) {
generateJsCodeAjax.abort();
}
generateJsCodeAjax = new ajaxHelper();
generateJsCodeAjax.addParams({
module: 'API',
format: 'json',
method: 'SitesManager.getJavascriptTag',
idSite: $('#js-tracker-website').attr('siteid')
}, 'GET');
generateJsCodeAjax.addParams(params, 'POST');
generateJsCodeAjax.setCallback(function (response) {
generateJsCodeAjax = null;
$('#javascript-text').find('textarea').val(response.value);
});
generateJsCodeAjax.send();
};
// function that generates image tracker link
var generateImageTrackingAjax = null,
generateImageTrackerLink = function () {
// get data used to generate the link
var generateDataParams = {
piwikUrl: piwikHost + piwikPath,
actionName: $('#image-tracker-action-name').val(),
};
if ($('#image-tracking-goal-check').is(':checked')) {
generateDataParams.idGoal = $('#image-tracker-goal').val();
if (generateDataParams.idGoal) {
generateDataParams.revenue = $('#image-tracker-advanced-options').find('.revenue').val();
}
}
if (generateImageTrackingAjax) {
generateImageTrackingAjax.abort();
}
generateImageTrackingAjax = new ajaxHelper();
generateImageTrackingAjax.addParams({
module: 'API',
format: 'json',
method: 'SitesManager.getImageTrackingCode',
idSite: $('#image-tracker-website').attr('siteid')
}, 'GET');
generateImageTrackingAjax.addParams(generateDataParams, 'POST');
generateImageTrackingAjax.setCallback(function (response) {
generateImageTrackingAjax = null;
$('#image-tracking-text').find('textarea').val(response.value);
});
generateImageTrackingAjax.send();
};
// on image link tracker site change, change available goals
$('#image-tracker-website').bind('change', function (e, site) {
getSiteData(site.id, '#image-tracking-code-options', function () {
resetGoalSelectItems(site.id, 'image-tracker-goal');
generateImageTrackerLink();
});
});
// on js link tracker site change, change available goals
$('#js-tracker-website').bind('change', function (e, site) {
$('.current-site-name', '#optional-js-tracking-options').each(function () {
$(this).html(site.name);
});
getSiteData(site.id, '#js-code-options', function () {
var siteHost = getHostNameFromUrl(siteUrls[site.id][0]);
$('.current-site-host', '#optional-js-tracking-options').each(function () {
$(this).text(siteHost);
});
var defaultAliasUrl = 'x.' + siteHost;
$('.current-site-alias').text(siteUrls[site.id][1] || defaultAliasUrl);
resetGoalSelectItems(site.id, 'js-tracker-goal');
generateJsCode();
});
});
// on click 'add' link in custom variable section, add a new row, but only
// allow 5 custom variable entry rows
$('.add-custom-variable').click(function (e) {
e.preventDefault();
var newRow = '<tr>\
<td>&nbsp;</td>\
<td><input type="textbox" class="custom-variable-name"/></td>\
<td>&nbsp;</td>\
<td><input type="textbox" class="custom-variable-value"/></td>\
</tr>',
row = $(this).closest('tr');
row.before(newRow);
// hide add button if max # of custom variables has been reached
// (X custom variables + 1 row for add new row)
if ($('tr', row.parent()).length == (maxCustomVariables + 1)) {
$(this).hide();
}
return false;
});
// when any input in the JS tracking options section changes, regenerate JS code
$('#optional-js-tracking-options').on('change', 'input', function () {
generateJsCode();
});
// when any input/select in the image tracking options section changes, regenerate
// image tracker link
$('#image-tracking-section').on('change', 'input,select', function () {
generateImageTrackerLink();
});
// on click generated code textareas, select the text so it can be easily copied
$('#javascript-text>textarea,#image-tracking-text>textarea').click(function () {
$(this).select();
});
// initial generation
getSiteData(
$('#js-tracker-website').attr('siteid'),
'#js-code-options,#image-tracking-code-options',
function () {
var imageTrackerSiteId = $('#image-tracker-website').attr('siteid');
resetGoalSelectItems(imageTrackerSiteId, 'image-tracker-goal');
generateJsCode();
generateImageTrackerLink();
}
);
});
}(jQuery, require));

View file

@ -0,0 +1,82 @@
/*!
* Piwik - Web Analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
$(document).ready(function () {
$submit = $('.pluginsSettingsSubmit');
if (!$submit) {
return;
}
$submit.click(updatePluginSettings);
function updatePluginSettings()
{
var $nonce = $('[name="setpluginsettingsnonce"]');
var nonceValue = '';
if ($nonce) {
nonceValue = $nonce.val();
}
var ajaxHandler = new ajaxHelper();
ajaxHandler.addParams({
module: 'CoreAdminHome',
action: 'setPluginSettings',
nonce: nonceValue
}, 'GET');
ajaxHandler.addParams({settings: getSettings()}, 'POST');
ajaxHandler.redirectOnSuccess();
ajaxHandler.setLoadingElement(getLoadingElement());
ajaxHandler.setErrorElement(getErrorElement());
ajaxHandler.send(true);
}
function getSettings()
{
var $pluginSections = $( "#pluginSettings[data-pluginname]" );
var values = {};
$pluginSections.each(function (index, pluginSection) {
$pluginSection = $(pluginSection);
var pluginName = $pluginSection.attr('data-pluginname');
var serialized = $('input, textarea, select:not([multiple])', $pluginSection).serializeArray();
// by default, it does not generate an array
var $multiSelects = $('select[multiple]', $pluginSection);
$multiSelects.each(function (index, multiSelect) {
var name = $(multiSelect).attr('name');
serialized.push({name: name, value: $(multiSelect).val()});
});
// by default, values of unchecked checkboxes are not send
var $uncheckedNodes = $('input[type=checkbox]:not(:checked)', $pluginSection);
$uncheckedNodes.each(function (index, uncheckedNode) {
var name = $(uncheckedNode).attr('name');
serialized.push({name: name, value: 0});
});
values[pluginName] = serialized;
});
return values;
}
function getErrorElement()
{
return $('#ajaxErrorPluginSettings');
}
function getLoadingElement()
{
return $('#ajaxLoadingPluginSettings');
}
});

View file

@ -0,0 +1,176 @@
.admin img {
vertical-align: middle;;
}
.admin a {
color: black;
}
#content.admin {
margin: 0 0 0 260px;
padding: 0 0 40px;
display: table;
font: 13px Arial, Helvetica, sans-serif;
}
.admin #header_message {
margin-top: 10px;
}
table.admin {
font-size: 0.9em;
font-family: Arial, Helvetica, verdana sans-serif;
background-color: #fff;
border-collapse: collapse;
}
table.admin thead th {
border-right: 1px solid #fff;
color: #fff;
text-align: center;
padding: 5px;
text-transform: uppercase;
height: 25px;
background-color: #a3c159;
font-weight: bold;
}
table.admin tbody tr {
background-color: #fff;
border-bottom: 1px solid #f0f0f0;
}
table.admin tbody td {
color: #414141;
text-align: left;
vertical-align: top;
}
table.admin tbody th {
text-align: left;
padding: 2px;
}
table.admin tbody td, table.admin tbody th {
color: #536C2A;
text-decoration: none;
font-weight: normal;
padding: 10px;
}
table.admin tbody td:hover, table.admin tbody th:hover {
color: #009193;
text-decoration: none;
}
.warning {
border: 1px dotted gray;
padding: 15px;
font-size: .8em;
}
.warning ul {
margin-left: 50px;
}
.access_error {
font-size: .7em;
padding: 15px;
}
.admin h2 {
border-bottom: 1px solid #DADADA;
margin: 15px -15px 20px 0;
padding: 0 0 5px 0;
font-size: 24px;
width:100%;
}
.admin p, .admin section {
margin-top: 10px;
line-height: 140%;
padding-bottom: 20px;
}
.adminTable {
width: 100%;
clear: both;
margin: 0;
}
.adminTable a {
text-decoration: none;
color: #2B5C97;
}
.adminTable abbr {
white-space: nowrap;
}
.adminTable td {
font-size: 13px;
vertical-align: top;
padding: 7px 15px 9px 10px;
vertical-align: top;
}
.adminTable td.action-links {
text-align: right;
}
.adminTable .check-column {
text-align: right;
width: 1.5em;
padding: 0;
}
.adminTable .num {
text-align: center;
}
.adminTable .name {
font-weight: bold;
}
.adminTable .ui-inline-help {
margin-top: 0;
width: 100%;
}
/* other styles */
.form-description {
color: #666666;
font-style: italic;
margin-left: 10px;
}
#logoSettings, #smtpSettings {
margin-left: 50px;
}
/* to override .admin a */
.admin .sites_autocomplete a {
color: #255792;
}
/* trusted host styles */
#trustedHostSettings .adminTable {
width: 300px;
}
#trustedHostSettings .adminTable td {
vertical-align: middle;
padding-bottom: 0;
}
#trustedHostSettings .adminTable tr td:last-child {
padding: 0 0 0 0;
}
#trustedHostSettings input {
width: 238px;
}
#trustedHostSettings .add-trusted-host-container {
padding: 12px 24px;
}

View file

@ -0,0 +1,79 @@
#javascript-output-section textarea, #image-link-output-section textarea {
width: 100%;
display: block;
color: #111;
font-family: "Courier New", Courier, monospace;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#javascript-output-section textarea {
height: 256px;
}
#image-link-output-section textarea {
height: 128px;
}
label {
margin-right: .35em;
display: inline-block;
}
#optional-js-tracking-options>tbody>tr>td, #image-tracking-section>tbody>tr>td {
width: 488px;
max-width: 488px;
}
.custom-variable-name, .custom-variable-value {
width: 100px;
}
h3 {
margin-top: 0;
}
.small-form-description {
color: #666;
font-size: 1em;
font-style: italic;
margin-left: 4em;
}
.tracking-option-section {
margin-bottom: 1.5em;
}
#javascript-output-section, #image-link-output-section {
padding-top: 1em;
}
#optional-js-tracking-options th, #image-tracking-section th {
text-align: left;
}
#js-visitor-cv-extra, #js-page-cv-extra, #js-campaign-query-param-extra {
margin-left: 1em;
}
#js-visitor-cv-extra td, #js-page-cv-extra td, #js-campaign-query-param-extra td {
vertical-align: middle;
}
.revenue {
width: 32px;
}
.goal-picker {
height: 1.2em;
}
.goal-picker select {
width: 128px;
}
#js-campaign-query-param-extra input {
width: 72px;
}

View file

@ -0,0 +1,78 @@
#container {
clear: left;
}
.Menu--admin {
padding: 0;
float: left;
width: 240px;
}
.Menu--admin > .Menu-tabList {
background-image: linear-gradient(top, #FECB00 0%, #FE9800 25%, #FE6702 50%, #CA0000 75%, #670002 100%);
background-image: -o-linear-gradient(top, #FECB00 0%, #FE9800 25%, #FE6702 50%, #CA0000 75%, #670002 100%);
background-image: -moz-linear-gradient(top, #FECB00 0%, #FE9800 25%, #FE6702 50%, #CA0000 75%, #670002 100%);
background-image: -webkit-linear-gradient(top, #FECB00 0%, #FE9800 25%, #FE6702 50%, #CA0000 75%, #670002 100%);
background-image: -ms-linear-gradient(top, #FECB00 0%, #FE9800 25%, #FE6702 50%, #CA0000 75%, #670002 100%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FECB00), color-stop(0.25, #FE9800), color-stop(0.5, #FE6702), color-stop(0.75, #CA0000), color-stop(1, #670002));
-moz-background-size: 5px 100%;
background-size: 5px 100%;
background-position: 0 0, 100% 0;
background-repeat: no-repeat;
}
.Menu--admin > .Menu-tabList {
padding-left: 5px;
margin-bottom: 0;
margin-top: 0.1em;
border: 1px solid #ddd;
border-radius: 5px;
}
.Menu--admin > .Menu-tabList li {
list-style: none;
margin: 0;
}
.Menu--admin > .Menu-tabList > li {
padding-bottom: 5px;
}
.Menu--admin > .Menu-tabList > li > a,
.Menu--admin > .Menu-tabList > li > span {
text-decoration: none;
border-bottom: 1px dotted #778;
display: block;
padding: 5px 10px;
font-size: 18px;
color: #7E7363;
}
.Menu--admin > .Menu-tabList li li a {
text-decoration: none;
padding: 0.6em 0.9em;
font: 14px Arial, Helvetica, sans-serif;
display: block;
}
.Menu--admin > .Menu-tabList li li a:link,
.Menu--admin > .Menu-tabList li li a:visited {
color: #000;
}
.Menu--admin > .Menu-tabList li li a:hover,
.Menu--admin > .Menu-tabList li li a.active {
color: #e87500;
background: #f1f1f1;
border-color: #000;
}
.Menu--admin > .Menu-tabList li li a:hover {
text-decoration: underline;
}
.Menu--admin > .Menu-tabList li li a.current {
background: #defdbb;
}

View file

@ -0,0 +1,40 @@
#pluginSettings {
width: 820px;
border-spacing: 0px 15px;
.columnTitle {
width:400px
}
.columnField {
width:220px
}
.columnHelp {
width:200px
}
.title {
font-weight: bold
}
.settingIntroduction {
padding-bottom: 0px;
}
.form-description {
font-style: normal;
margin-top: 3px;
display: block;
}
.superUserSettings {
margin-top: 1em;
}
}
#pluginsSettings {
.submitSeparator {
background-color: #DADADA;
height: 1px;
border: 0px;
}
}

View file

@ -0,0 +1,23 @@
{% if adminMenu|length > 1 %}
<div class="Menu Menu--admin">
<ul class="Menu-tabList">
{% for name,submenu in adminMenu %}
{% if submenu._hasSubmenu %}
<li>
<span>{{ name|translate }}</span>
<ul>
{% for sname,url in submenu %}
{% if sname|slice(0,1) != '_' %}
<li>
<a href='index.php{{ url._url|urlRewriteWithParameters }}'
{% if currentAdminMenuName is defined and sname==currentAdminMenuName %}class='active'{% endif %}>{{ sname|translate }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}

View file

@ -0,0 +1,324 @@
{% extends 'admin.twig' %}
{% block content %}
{# load macros #}
{% import 'macros.twig' as piwik %}
{% import 'ajaxMacros.twig' as ajax %}
{% if isSuperUser %}
{{ ajax.errorDiv() }}
{{ ajax.loadingDiv() }}
<h2>{{ 'CoreAdminHome_ArchivingSettings'|translate }}</h2>
<table class="adminTable" style='width:900px;'>
{% if isGeneralSettingsAdminEnabled %}
<tr>
<td style="width:400px;">{{ 'General_AllowPiwikArchivingToTriggerBrowser'|translate }}</td>
<td style="width:220px;">
<fieldset>
<input id="enableBrowserTriggerArchiving-yes" type="radio" value="1" name="enableBrowserTriggerArchiving"{% if enableBrowserTriggerArchiving==1 %} checked="checked"{% endif %} />
<label for="enableBrowserTriggerArchiving-yes">{{ 'General_Yes'|translate }}</label><br/>
<span class="form-description">{{ 'General_Default'|translate }}</span>
<br/><br/>
<input id="enableBrowserTriggerArchiving-no" type="radio" value="0" name="enableBrowserTriggerArchiving"{% if enableBrowserTriggerArchiving==0 %} checked="checked"{% endif %} />
<label for="enableBrowserTriggerArchiving-no">{{ 'General_No'|translate }}</label><br/>
<span class="form-description">{{ 'General_ArchivingTriggerDescription'|translate("<a href='?module=Proxy&action=redirect&url=http://piwik.org/docs/setup-auto-archiving/' target='_blank'>","</a>")|raw }}</span>
</fieldset>
<td>
{% set browserArchivingHelp %}
{{ 'General_ArchivingInlineHelp'|translate }}
<br/>
{{ 'General_SeeTheOfficialDocumentationForMoreInformation'|translate("<a href='?module=Proxy&action=redirect&url=http://piwik.org/docs/setup-auto-archiving/' target='_blank'>","</a>")|raw }}
{% endset %}
{{ piwik.inlineHelp(browserArchivingHelp) }}
</td>
</tr>
{% else %}
<tr>
<td style="width:400px;">{{ 'General_AllowPiwikArchivingToTriggerBrowser'|translate }}</td>
<td style="width:220px;">
<input id="enableBrowserTriggerArchiving-disabled" type="radio" checked="checked" disabled="disabled" />
<label for="enableBrowserTriggerArchiving-disabled">{% if enableBrowserTriggerArchiving==1 %}{{ 'General_Yes'|translate }}{% else %}{{ 'General_No'|translate }}{% endif %}</label><br/>
</td>
</tr>
{% endif %}
<tr>
<td width="400px">
<label for="todayArchiveTimeToLive">
{{ 'General_ReportsContainingTodayWillBeProcessedAtMostEvery'|translate }}
</label>
</td>
<td>
{% set timeOutInput %}
<input size='3' value='{{ todayArchiveTimeToLive }}' id='todayArchiveTimeToLive' {% if not isGeneralSettingsAdminEnabled %}disabled="disabled"{% endif %}/>
{% endset %}
{{ 'General_NSeconds'|translate(timeOutInput)|raw }}
</td>
{% if isGeneralSettingsAdminEnabled %}
<td width='450px'>
{% set archiveTodayTTLHelp %}
{% if showWarningCron %}
<strong>
{{ 'General_NewReportsWillBeProcessedByCron'|translate }}<br/>
{{ 'General_ReportsWillBeProcessedAtMostEveryHour'|translate }}
{{ 'General_IfArchivingIsFastYouCanSetupCronRunMoreOften'|translate }}<br/>
</strong>
{% endif %}
{{ 'General_SmallTrafficYouCanLeaveDefault'|translate(10) }}
<br/>
{{ 'General_MediumToHighTrafficItIsRecommendedTo'|translate(1800,3600) }}
{% endset %}
{{ piwik.inlineHelp(archiveTodayTTLHelp) }}
</td>
{% endif %}
</tr>
{% if isGeneralSettingsAdminEnabled %}
<tr>
<td colspan="3">
<h2>{{ 'CoreAdminHome_UpdateSettings'|translate }}</h2>
</td>
</tr>
<tr>
<td style="width:400px;">{{ 'CoreAdminHome_CheckReleaseGetVersion'|translate }}</td>
<td style="width:220px;">
<fieldset>
<input id="enableBetaReleaseCheck-0" type="radio" value="0" name="enableBetaReleaseCheck"{% if enableBetaReleaseCheck==0 %} checked="checked"{% endif %} />
<label for="enableBetaReleaseCheck-0">{{ 'CoreAdminHome_LatestStableRelease'|translate }}</label><br/>
<span class="form-description">{{ 'General_Recommended'|translate }}</span>
<br/><br/>
<input id="enableBetaReleaseCheck-1" type="radio" value="1" name="enableBetaReleaseCheck"{% if enableBetaReleaseCheck==1 %} checked="checked"{% endif %} />
<label for="enableBetaReleaseCheck-1">{{ 'CoreAdminHome_LatestBetaRelease'|translate }}</label><br/>
<span class="form-description">{{ 'CoreAdminHome_ForBetaTestersOnly'|translate }}</span>
</fieldset>
<td>
{% set checkReleaseHelp %}
{{ 'CoreAdminHome_DevelopmentProcess'|translate("<a href='?module=Proxy&action=redirect&url=http://piwik.org/participate/development-process/' target='_blank'>","</a>")|raw }}
<br/>
{{ 'CoreAdminHome_StableReleases'|translate("<a href='?module=Proxy&action=redirect&url=http://piwik.org/participate/user-feedback/' target='_blank'>","</a>")|raw }}
{% endset %}
{{ piwik.inlineHelp(checkReleaseHelp) }}
</td>
</tr>
{% if canUpdateCommunication %}
<tr>
<td style="width:400px;">{{ 'CoreAdminHome_SendPluginUpdateCommunication'|translate }}</td>
<td style="width:220px;">
<fieldset>
<input id="enablePluginUpdateCommunication-1" type="radio"
name="enablePluginUpdateCommunication" value="1"
{% if enableSendPluginUpdateCommunication==1 %} checked="checked"{% endif %}/>
<label for="enablePluginUpdateCommunication-1">{{ 'General_Yes'|translate }}</label>
<br />
<br />
<input class="indented-radio-button" id="enablePluginUpdateCommunication-0" type="radio"
name="enablePluginUpdateCommunication" value="0"
{% if enableSendPluginUpdateCommunication==0 %} checked="checked"{% endif %}/>
<label for="enablePluginUpdateCommunication-0">{{ 'General_No'|translate }}</label>
<br />
<span class="form-description">{{ 'General_Default'|translate }}</span>
</fieldset>
<td>
{{ piwik.inlineHelp('CoreAdminHome_SendPluginUpdateCommunicationHelp'|translate) }}
</td>
</tr>
{% endif %}
{% endif %}
</table>
{% if isGeneralSettingsAdminEnabled %}
<h2>{{ 'CoreAdminHome_EmailServerSettings'|translate }}</h2>
<div id='emailSettings'>
<table class="adminTable" style='width:600px;'>
<tr>
<td>{{ 'General_UseSMTPServerForEmail'|translate }}<br/>
<span class="form-description">{{ 'General_SelectYesIfYouWantToSendEmailsViaServer'|translate }}</span>
</td>
<td style="width:200px;">
<input id="mailUseSmtp-1" type="radio" name="mailUseSmtp" value="1" {% if mail.transport == 'smtp' %} checked {% endif %}/>
<label for="mailUseSmtp-1">{{ 'General_Yes'|translate }}</label>
<input class="indented-radio-button" id="mailUseSmtp-0" type="radio" name="mailUseSmtp" value="0"
{% if mail.transport == '' %} checked {% endif %}/>
<label for="mailUseSmtp-0">{{ 'General_No'|translate }}</label>
</td>
</tr>
</table>
</div>
<div id='smtpSettings'>
<table class="adminTable" style='width:550px;'>
<tr>
<td><label for="mailHost">{{ 'General_SmtpServerAddress'|translate }}</label></td>
<td style="width:200px;"><input type="text" id="mailHost" value="{{ mail.host }}"></td>
</tr>
<tr>
<td><label for="mailPort">{{ 'General_SmtpPort'|translate }}</label><br/>
<span class="form-description">{{ 'General_OptionalSmtpPort'|translate }}</span></td>
<td><input type="text" id="mailPort" value="{{ mail.port }}"></td>
</tr>
<tr>
<td><label for="mailType">{{ 'General_AuthenticationMethodSmtp'|translate }}</label><br/>
<span class="form-description">{{ 'General_OnlyUsedIfUserPwdIsSet'|translate }}</span>
</td>
<td>
<select id="mailType">
<option value="" {% if mail.type == '' %} selected="selected" {% endif %}></option>
<option id="plain" {% if mail.type == 'Plain' %} selected="selected" {% endif %} value="Plain">Plain</option>
<option id="login" {% if mail.type == 'Login' %} selected="selected" {% endif %} value="Login"> Login</option>
<option id="cram-md5" {% if mail.type == 'Crammd5' %} selected="selected" {% endif %} value="Crammd5"> Crammd5</option>
</select>
</td>
</tr>
<tr>
<td><label for="mailUsername">{{ 'General_SmtpUsername'|translate }}</label><br/>
<span class="form-description">{{ 'General_OnlyEnterIfRequired'|translate }}</span></td>
<td>
<input type="text" id="mailUsername" value="{{ mail.username }}"/>
</td>
</tr>
<tr>
<td><label for="mailPassword">{{ 'General_SmtpPassword'|translate }}</label><br/>
<span class="form-description">{{ 'General_OnlyEnterIfRequiredPassword'|translate }}<br/>
{{ 'General_WarningPasswordStored'|translate("<strong>","</strong>")|raw }}</span>
</td>
<td>
<input type="password" id="mailPassword" value="{{ mail.password }}"/>
</td>
</tr>
<tr>
<td><label for="mailEncryption">{{ 'General_SmtpEncryption'|translate }}</label><br/>
<span class="form-description">{{ 'General_EncryptedSmtpTransport'|translate }}</span></td>
<td>
<select id="mailEncryption">
<option value="" {% if mail.encryption == '' %} selected="selected" {% endif %}></option>
<option id="ssl" {% if mail.encryption == 'ssl' %} selected="selected" {% endif %} value="ssl">SSL</option>
<option id="tls" {% if mail.encryption == 'tls' %} selected="selected" {% endif %} value="tls">TLS</option>
</select>
</td>
</tr>
</table>
</div>
{% endif %}
<h2>{{ 'CoreAdminHome_BrandingSettings'|translate }}</h2>
<div id='brandSettings'>
{{ 'CoreAdminHome_CustomLogoHelpText'|translate }}
<table class="adminTable" style="width:900px;">
<tr>
<td style="width:200px;">{{ 'CoreAdminHome_UseCustomLogo'|translate }}</td>
<td style="width:200px;">
<input id="useCustomLogo-1" type="radio" name="useCustomLogo" value="1" {% if branding.use_custom_logo == 1 %} checked {% endif %}/>
<label for="useCustomLogo-1">{{ 'General_Yes'|translate }}</label>
<input class="indented-radio-button" id="useCustomLogo-0" type="radio" name="useCustomLogo" value="0" {% if branding.use_custom_logo == 0 %} checked {% endif %} />
<label for="useCustomLogo-0" class>{{ 'General_No'|translate }}</label>
</td>
<td id="inlineHelpCustomLogo">
{% set giveUsFeedbackText %}"{{ 'General_GiveUsYourFeedback'|translate }}"{% endset %}
{% set customLogoHelp %}
{{ 'CoreAdminHome_CustomLogoFeedbackInfo'|translate(giveUsFeedbackText,"<a href='?module=CorePluginsAdmin&action=plugins' target='_blank'>","</a>")|raw }}
{% endset %}
{{ piwik.inlineHelp(customLogoHelp) }}
</td>
</tr>
</table>
</div>
<div id='logoSettings'>
<form id="logoUploadForm" method="post" enctype="multipart/form-data" action="index.php?module=CoreAdminHome&format=json&action=uploadCustomLogo">
<table class="adminTable" style='width:550px;'>
<tr>
{% if logosWriteable %}
<td>
<label for="customLogo">{{ 'CoreAdminHome_LogoUpload'|translate }}:<br/>
<span class="form-description">{{ 'CoreAdminHome_LogoUploadHelp'|translate("JPG / PNG / GIF",110) }}</span>
</label>
</td>
<td style="width:200px;">
<input name="customLogo" type="file" id="customLogo"/>
<img src="{{ pathUserLogo }}?r={{ random() }}" id="currentLogo" height="150"/>
</td>
{% else %}
<td>
<div style="display:inline-block;margin-top:10px;" id="CoreAdminHome_LogoNotWriteable">
{{ 'CoreAdminHome_LogoNotWriteableInstruction'
|translate("<strong>"~pathUserLogoDirectory~"</strong><br/>", pathUserLogo ~", "~ pathUserLogoSmall ~", "~ pathUserLogoSVG ~"")
|notification({'placeAt': '#CoreAdminHome_LogoNotWriteable', 'noclear': true, 'context': 'warning', 'raw': true}) }}
</div>
</td>
{% endif %}
</tr>
</table>
</form>
</div>
<div class="ui-confirm" id="confirmTrustedHostChange">
<h2>{{ 'CoreAdminHome_TrustedHostConfirm'|translate }}</h2>
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
</div>
<h2 id="trustedHostsSection">{{ 'CoreAdminHome_TrustedHostSettings'|translate }}</h2>
<div id='trustedHostSettings'>
{% include "@CoreHome/_warningInvalidHost.twig" %}
{% if not isGeneralSettingsAdminEnabled %}
{{ 'CoreAdminHome_PiwikIsInstalledAt'|translate }}: {{ trustedHosts|join(", ") }}
{% else %}
<p>{{ 'CoreAdminHome_PiwikIsInstalledAt'|translate }}:</p>
<strong>{{ 'CoreAdminHome_ValidPiwikHostname'|translate }}</strong>
<ul>
{% for hostIdx, host in trustedHosts %}
<li>
<input name="trusted_host" type="text" value="{{ host }}"/>
<a href="#" class="remove-trusted-host" title="{{ 'General_Delete'|translate }}">
<img alt="{{ 'General_Delete'|translate }}" src="plugins/Morpheus/images/ico_delete.png" />
</a>
</li>
{% endfor %}
</ul>
<div class="add-trusted-host-container">
<a href="#" class="add-trusted-host"><em>{{ 'General_Add'|translate }}</em></a>
</div>
{% endif %}
</div>
<input type="submit" value="{{ 'General_Save'|translate }}" id="generalSettingsSubmit" class="submit"/>
<br/>
<br/>
{% if isDataPurgeSettingsEnabled %}
{% set clickDeleteLogSettings %}{{ 'PrivacyManager_DeleteDataSettings'|translate }}{% endset %}
<h2>{{ 'PrivacyManager_DeleteDataSettings'|translate }}</h2>
<p>
{{ 'PrivacyManager_DeleteDataDescription'|translate }} {{ 'PrivacyManager_DeleteDataDescription2'|translate }}
<br/>
<a href='{{ linkTo({'module':"PrivacyManager", 'action':"privacySettings"}) }}#deleteLogsAnchor'>
{{ 'PrivacyManager_ClickHereSettings'|translate("'" ~ clickDeleteLogSettings ~ "'") }}
</a>
</p>
{% endif %}
{% endif %}
<h2>{{ 'CoreAdminHome_OptOutForYourVisitors'|translate }}</h2>
<p>{{ 'CoreAdminHome_OptOutExplanation'|translate }}
{% set optOutUrl %}{{ piwikUrl }}index.php?module=CoreAdminHome&action=optOut&language={{ language }}{% endset %}
{% set iframeOptOut %}
<iframe style="border: 0; height: 200px; width: 600px;" src="{{ optOutUrl }}"></iframe>
{% endset %}
<code>{{ iframeOptOut|escape }}</code>
<br/>
{{ 'CoreAdminHome_OptOutExplanationBis'|translate("<a href='" ~ optOutUrl ~ "' target='_blank'>","</a>")|raw }}
</p>
{% endblock %}

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
{% if not trackVisits %}
{{ 'CoreAdminHome_OptOutComplete'|translate }}
<br/>
{{ 'CoreAdminHome_OptOutCompleteBis'|translate }}
{% else %}
{{ 'CoreAdminHome_YouMayOptOut'|translate }}
<br/>
{{ 'CoreAdminHome_YouMayOptOutBis'|translate }}
{% endif %}
<br/><br/>
<form method="post" action="?module=CoreAdminHome&amp;action=optOut{% if language %}&amp;language={{ language }}{% endif %}">
<input type="hidden" name="nonce" value="{{ nonce }}" />
<input type="hidden" name="fuzz" value="{{ "now"|date }}" />
<input onclick="this.form.submit()" type="checkbox" id="trackVisits" name="trackVisits" {% if trackVisits %}checked="checked"{% endif %} />
<label for="trackVisits"><strong>
{% if trackVisits %}
{{ 'CoreAdminHome_YouAreOptedIn'|translate }} {{ 'CoreAdminHome_ClickHereToOptOut'|translate }}
{% else %}
{{ 'CoreAdminHome_YouAreOptedOut'|translate }} {{ 'CoreAdminHome_ClickHereToOptIn'|translate }}
{% endif %}
</strong></label>
</form>
</body>
</html>

View file

@ -0,0 +1,173 @@
{% extends 'admin.twig' %}
{% block content %}
<div id="pluginsSettings">
{% import 'macros.twig' as piwik %}
{% import 'ajaxMacros.twig' as ajax %}
<p>
{{ 'CoreAdminHome_PluginSettingsIntro'|translate }}
{% for pluginName, settings in pluginSettings %}
<a href="#{{ pluginName|e('html_attr') }}">{{ pluginName }}</a>{% if not loop.last %}, {% endif %}
{% endfor %}
</p>
<input type="hidden" name="setpluginsettingsnonce" value="{{ nonce }}">
{% for pluginName, settings in pluginSettings %}
<h2 id="{{ pluginName|e('html_attr') }}">{{ pluginName }}</h2>
{% if settings.getIntroduction %}
<p class="pluginIntroduction">
{{ settings.getIntroduction }}
</p>
{% endif %}
<table class="adminTable" id="pluginSettings" data-pluginname="{{ pluginName|e('html_attr') }}">
{% for name, setting in settings.getSettingsForCurrentUser %}
{% set settingValue = setting.getValue %}
{% if pluginName in firstSuperUserSettingNames|keys and name == firstSuperUserSettingNames[pluginName] %}
<tr>
<td colspan="3">
<h3 class="superUserSettings">{{ 'MobileMessaging_Settings_SuperAdmin'|translate }}</h3>
</td>
</tr>
{% endif %}
{% if setting.introduction %}
<tr>
<td colspan="3">
<p class="settingIntroduction">
{{ setting.introduction }}
</p>
</td>
</tr>
{% endif %}
<tr>
<td class="columnTitle">
<span class="title">{{ setting.title }}</span>
<br />
<span class='form-description'>
{{ setting.description }}
</span>
</td>
<td class="columnField">
<fieldset>
<label>
{% if setting.uiControlType == 'select' or setting.uiControlType == 'multiselect' %}
<select
{% for attr, val in setting.uiControlAttributes %}
{{ attr|e('html_attr') }}="{{ val|e('html_attr') }}"
{% endfor %}
name="{{ setting.getKey|e('html_attr') }}"
{% if setting.uiControlType == 'multiselect' %}multiple{% endif %}>
{% for key, value in setting.availableValues %}
<option value='{{ key }}'
{% if settingValue is iterable and key in settingValue %}
selected='selected'
{% elseif settingValue==key %}
selected='selected'
{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
{% elseif setting.uiControlType == 'textarea' %}
<textarea style="width: 176px;"
{% for attr, val in setting.uiControlAttributes %}
{{ attr|e('html_attr') }}="{{ val|e('html_attr') }}"
{% endfor %}
name="{{ setting.getKey|e('html_attr') }}"
>
{{- settingValue -}}
</textarea>
{% elseif setting.uiControlType == 'radio' %}
{% for key, value in setting.availableValues %}
<input
id="name-value-{{ loop.index }}"
{% for attr, val in setting.uiControlAttributes %}
{{ attr|e('html_attr') }}="{{ val|e('html_attr') }}"
{% endfor %}
{% if settingValue==key %}
checked="checked"
{% endif %}
type="radio"
value="{{ key|e('html_attr') }}"
name="{{ setting.getKey|e('html_attr') }}" />
<label for="name-value-{{ loop.index }}">{{ value }}</label>
<br />
{% endfor %}
{% else %}
<input
{% for attr, val in setting.uiControlAttributes %}
{{ attr|e('html_attr') }}="{{ val|e('html_attr') }}"
{% endfor %}
{% if setting.uiControlType == 'checkbox' %}
value="1"
{% endif %}
{% if setting.uiControlType == 'checkbox' and settingValue %}
checked="checked"
{% endif %}
type="{{ setting.uiControlType|e('html_attr') }}"
name="{{ setting.getKey|e('html_attr') }}"
value="{{ settingValue|e('html_attr') }}"
>
{% endif %}
{% if setting.defaultValue and setting.uiControlType != 'checkbox' %}
<br/>
<span class='form-description'>
{{ 'General_Default'|translate }}
{% if setting.defaultValue is iterable %}
{{ setting.defaultValue|join(', ')|truncate(50) }}
{% else %}
{{ setting.defaultValue|truncate(50) }}
{% endif %}
</span>
{% endif %}
</label>
</fieldset>
</td>
<td class="columnHelp">
{% if setting.inlineHelp %}
<div class="ui-widget">
<div class="ui-inline-help">
{{ setting.inlineHelp }}
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endfor %}
<hr class="submitSeparator"/>
{{ ajax.errorDiv('ajaxErrorPluginSettings') }}
{{ ajax.loadingDiv('ajaxLoadingPluginSettings') }}
<input type="submit" value="{{ 'General_Save'|translate }}" class="pluginsSettingsSubmit submit"/>
</div>
{% endblock %}

View file

@ -0,0 +1,272 @@
{% extends 'admin.twig' %}
{% block head %}
{{ parent() }}
<link rel="stylesheet" href="plugins/CoreAdminHome/stylesheets/jsTrackingGenerator.css" />
<script type="text/javascript" src="plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js"></script>
{% endblock %}
{% block content %}
<div id="js-tracking-generator-data" max-custom-variables="{{ maxCustomVariables|e('html_attr') }}" data-currencies="{{ currencySymbols|json_encode }}"></div>
<h2 piwik-enriched-headline
feature-name="{{ 'CoreAdminHome_TrackingCode'|translate }}"
help-url="http://piwik.org/docs/tracking-api/">{{ 'CoreAdminHome_JavaScriptTracking'|translate }}</h2>
<div id="js-code-options" class="adminTable">
<p>
{{ 'CoreAdminHome_JSTrackingIntro1'|translate }}
<br/><br/>
{{ 'CoreAdminHome_JSTrackingIntro2'|translate }} {{ 'CoreAdminHome_JSTrackingIntro3'|translate('<a href="http://piwik.org/integrate/" target="_blank">','</a>')|raw }}
<br/><br/>
{{ 'CoreAdminHome_JSTrackingIntro4'|translate('<a href="#image-tracking-link">','</a>')|raw }}
<br/><br/>
{{ 'CoreAdminHome_JSTrackingIntro5'|translate('<a target="_blank" href="http://piwik.org/docs/javascript-tracking/">','</a>')|raw }}
</p>
<div>
{# website #}
<label class="website-label"><strong>{{ 'General_Website'|translate }}</strong></label>
<div piwik-siteselector
class="sites_autocomplete"
siteid="{{ idSite }}"
sitename="{{ defaultReportSiteName }}"
show-all-sites-item="false"
switch-site-on-select="false"
id="js-tracker-website"
show-selected-site="true"></div>
<br/><br/><br/>
</div>
<table id="optional-js-tracking-options" class="adminTable">
<tr>
<th>{{ 'General_Options'|translate }}</th>
<th>{{ 'Mobile_Advanced'|translate }}
<a href="#" class="section-toggler-link" data-section-id="javascript-advanced-options">({{ 'General_Show'|translate }})</a>
</th>
</tr>
<tr>
<td>
{# track across all subdomains #}
<div class="tracking-option-section">
<input type="checkbox" id="javascript-tracking-all-subdomains"/>
<label for="javascript-tracking-all-subdomains">{{ 'CoreAdminHome_JSTracking_MergeSubdomains'|translate }}
<span class='current-site-name'>{{ defaultReportSiteName|raw }}</span>
</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_MergeSubdomainsDesc'|translate("x.<span class='current-site-host'>"~defaultReportSiteDomain~"</span>","y.<span class='current-site-host'>"~defaultReportSiteDomain~"</span>")|raw }}
</div>
</div>
{# group page titles by site domain #}
<div class="tracking-option-section">
<input type="checkbox" id="javascript-tracking-group-by-domain"/>
<label for="javascript-tracking-group-by-domain">{{ 'CoreAdminHome_JSTracking_GroupPageTitlesByDomain'|translate }}</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_GroupPageTitlesByDomainDesc1'|translate("<span class='current-site-host'>" ~ defaultReportSiteDomain ~ "</span>")|raw }}
</div>
</div>
{# track across all site aliases #}
<div class="tracking-option-section">
<input type="checkbox" id="javascript-tracking-all-aliases"/>
<label for="javascript-tracking-all-aliases">{{ 'CoreAdminHome_JSTracking_MergeAliases'|translate }}
<span class='current-site-name'>{{ defaultReportSiteName|raw }}</span>
</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_MergeAliasesDesc'|translate("<span class='current-site-alias'>"~defaultReportSiteAlias~"</span>")|raw }}
</div>
</div>
</td>
<td>
<div id="javascript-advanced-options" style="display:none;">
{# visitor custom variable #}
<div class="custom-variable tracking-option-section" id="javascript-tracking-visitor-cv">
<input class="section-toggler-link" type="checkbox" id="javascript-tracking-visitor-cv-check" data-section-id="js-visitor-cv-extra"/>
<label for="javascript-tracking-visitor-cv-check">{{ 'CoreAdminHome_JSTracking_VisitorCustomVars'|translate }}</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_VisitorCustomVarsDesc'|translate }}
</div>
<table style="display:none;" id="js-visitor-cv-extra">
<tr>
<td><strong>{{ 'General_Name'|translate }}</strong></td>
<td><input type="textbox" class="custom-variable-name" placeholder="e.g. Type"/></td>
<td><strong>{{ 'General_Value'|translate }}</strong></td>
<td><input type="textbox" class="custom-variable-value" placeholder="e.g. Customer"/></td>
</tr>
<tr>
<td colspan="4" style="text-align:right;">
<a href="#" class="add-custom-variable">{{ 'General_Add'|translate }}</a>
</td>
</tr>
</table>
</div>
{# page view custom variable #}
<div class="custom-variable tracking-option-section" id="javascript-tracking-page-cv">
<input class="section-toggler-link" type="checkbox" id="javascript-tracking-page-cv-check" data-section-id="js-page-cv-extra"/>
<label for="javascript-tracking-page-cv-check">{{ 'CoreAdminHome_JSTracking_PageCustomVars'|translate }}</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_PageCustomVarsDesc'|translate }}
</div>
<table style="display:none;" id="js-page-cv-extra">
<tr>
<td><strong>{{ 'General_Name'|translate }}</strong></td>
<td><input type="textbox" class="custom-variable-name" placeholder="e.g. Category"/></td>
<td><strong>{{ 'General_Value'|translate }}</strong></td>
<td><input type="textbox" class="custom-variable-value" placeholder="e.g. White Papers"/></td>
</tr>
<tr>
<td colspan="4" style="text-align:right;">
<a href="#" class="add-custom-variable">{{ 'General_Add'|translate }}</a>
</td>
</tr>
</table>
</div>
{# do not track support #}
<div class="tracking-option-section">
<input type="checkbox" id="javascript-tracking-do-not-track"/>
<label for="javascript-tracking-do-not-track">{{ 'CoreAdminHome_JSTracking_EnableDoNotTrack'|translate }}</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_EnableDoNotTrackDesc'|translate }}
{% if serverSideDoNotTrackEnabled %}
<br/>
<br/>
{{ 'CoreAdminHome_JSTracking_EnableDoNotTrack_AlreadyEnabled'|translate }}
{% endif %}
</div>
</div>
{# custom campaign name/keyword query params #}
<div class="tracking-option-section">
<input class="section-toggler-link" type="checkbox" id="custom-campaign-query-params-check"
data-section-id="js-campaign-query-param-extra"/>
<label for="custom-campaign-query-params-check">{{ 'CoreAdminHome_JSTracking_CustomCampaignQueryParam'|translate }}</label>
<div class="small-form-description">
{{ 'CoreAdminHome_JSTracking_CustomCampaignQueryParamDesc'|translate('<a href="http://piwik.org/faq/general/#faq_119" target="_blank">','</a>')|raw }}
</div>
<table style="display:none;" id="js-campaign-query-param-extra">
<tr>
<td><strong>{{ 'CoreAdminHome_JSTracking_CampaignNameParam'|translate }}</strong></td>
<td><input type="text" id="custom-campaign-name-query-param"/></td>
</tr>
<tr>
<td><strong>{{ 'CoreAdminHome_JSTracking_CampaignKwdParam'|translate }}</strong></td>
<td><input type="text" id="custom-campaign-keyword-query-param"/></td>
</tr>
</table>
</div>
</div>
</td>
</tr>
</table>
</div>
<div id="javascript-output-section">
<h3>{{ 'General_JsTrackingTag'|translate }}</h3>
<p class="form-description">{{ 'CoreAdminHome_JSTracking_CodeNote'|translate("&lt;/body&gt;")|raw }}</p>
<div id="javascript-text">
<textarea> </textarea>
</div>
<br/>
</div>
<h2 id="image-tracking-link">{{ 'CoreAdminHome_ImageTracking'|translate }}</h2>
<div id="image-tracking-code-options" class="adminTable">
<p>
{{ 'CoreAdminHome_ImageTrackingIntro1'|translate }} {{ 'CoreAdminHome_ImageTrackingIntro2'|translate("<em>&lt;noscript&gt;&lt;/noscript&gt;</em>")|raw }}
<br/><br/>
{{ 'CoreAdminHome_ImageTrackingIntro3'|translate('<a href="http://piwik.org/docs/tracking-api/reference/" target="_blank">','</a>')|raw }}
</p>
<div>
{# website #}
<label class="website-label"><strong>{{ 'General_Website'|translate }}</strong></label>
<div piwik-siteselector
class="sites_autocomplete"
siteid="{{ idSite }}"
sitename="{{ defaultReportSiteName }}"
id="image-tracker-website"
show-all-sites-item="false"
switch-site-on-select="false"
show-selected-site="true"></div>
<br/><br/><br/>
</div>
<table id="image-tracking-section" class="adminTable">
<tr>
<th>{{ 'General_Options'|translate }}</th>
<th>{{ 'Mobile_Advanced'|translate }}
<a href="#" class="section-toggler-link" data-section-id="image-tracker-advanced-options">
({{ 'General_Show'|translate }})
</a>
</th>
</tr>
<tr>
<td>
{# action_name #}
<div class="tracking-option-section">
<label for="image-tracker-action-name">{{ 'Actions_ColumnPageName'|translate }}</label>
<input type="text" id="image-tracker-action-name"/>
</div>
</td>
<td>
<div id="image-tracker-advanced-options" style="display:none;">
{# goal #}
<div class="goal-picker tracking-option-section">
<input class="section-toggler-link" type="checkbox" id="image-tracking-goal-check" data-section-id="image-goal-picker-extra"/>
<label for="image-tracking-goal-check">{{ 'CoreAdminHome_TrackAGoal'|translate }}</label>
<div style="display:none;" id="image-goal-picker-extra">
<select id="image-tracker-goal">
<option value="">{{ 'UserCountryMap_None'|translate }}</option>
</select>
<span>{{ 'CoreAdminHome_WithOptionalRevenue'|translate }}</span>
<span class="currency">{{ defaultSiteRevenue }}</span>
<input type="text" class="revenue" value=""/>
</div>
</div>
</div>
</td>
</tr>
</table>
<div id="image-link-output-section" width="560px">
<h3>{{ 'CoreAdminHome_ImageTrackingLink'|translate }}</h3><br/><br/>
<div id="image-tracking-text">
<textarea> </textarea>
</div>
<br/>
</div>
</div>
<h2>{{ 'CoreAdminHome_ImportingServerLogs'|translate }}</h2>
<p>
{{ 'CoreAdminHome_ImportingServerLogsDesc'|translate('<a href="http://piwik.org/log-analytics/" target="_blank">','</a>')|raw }}
</p>
{% endblock %}