add piwik installation
This commit is contained in:
parent
90aa4ef157
commit
8c5d4f0c31
109 changed files with 563902 additions and 0 deletions
242
www/analytics/plugins/CoreHome/Controller.php
Normal file
242
www/analytics/plugins/CoreHome/Controller.php
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
<?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\CoreHome;
|
||||
|
||||
use Exception;
|
||||
use Piwik\API\Request;
|
||||
use Piwik\Common;
|
||||
use Piwik\Date;
|
||||
use Piwik\FrontController;
|
||||
use Piwik\Menu\MenuMain;
|
||||
use Piwik\Notification\Manager as NotificationManager;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\CoreHome\DataTableRowAction\MultiRowEvolution;
|
||||
use Piwik\Plugins\CoreHome\DataTableRowAction\RowEvolution;
|
||||
use Piwik\Plugins\CorePluginsAdmin\MarketplaceApiClient;
|
||||
use Piwik\Plugins\Dashboard\DashboardManagerControl;
|
||||
use Piwik\Plugins\UsersManager\API;
|
||||
use Piwik\Site;
|
||||
use Piwik\UpdateCheck;
|
||||
use Piwik\Url;
|
||||
use Piwik\View;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Controller extends \Piwik\Plugin\Controller
|
||||
{
|
||||
function getDefaultAction()
|
||||
{
|
||||
return 'redirectToCoreHomeIndex';
|
||||
}
|
||||
|
||||
function redirectToCoreHomeIndex()
|
||||
{
|
||||
$defaultReport = API::getInstance()->getUserPreference(Piwik::getCurrentUserLogin(), API::PREFERENCE_DEFAULT_REPORT);
|
||||
$module = 'CoreHome';
|
||||
$action = 'index';
|
||||
|
||||
// User preference: default report to load is the All Websites dashboard
|
||||
if ($defaultReport == 'MultiSites'
|
||||
&& \Piwik\Plugin\Manager::getInstance()->isPluginActivated('MultiSites')
|
||||
) {
|
||||
$module = 'MultiSites';
|
||||
}
|
||||
if ($defaultReport == Piwik::getLoginPluginName()) {
|
||||
$module = Piwik::getLoginPluginName();
|
||||
}
|
||||
$idSite = Common::getRequestVar('idSite', false, 'int');
|
||||
parent::redirectToIndex($module, $action, $idSite);
|
||||
}
|
||||
|
||||
public function showInContext()
|
||||
{
|
||||
$controllerName = Common::getRequestVar('moduleToLoad');
|
||||
$actionName = Common::getRequestVar('actionToLoad', 'index');
|
||||
if ($actionName == 'showInContext') {
|
||||
throw new Exception("Preventing infinite recursion...");
|
||||
}
|
||||
$view = $this->getDefaultIndexView();
|
||||
$view->content = FrontController::getInstance()->fetchDispatch($controllerName, $actionName);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function markNotificationAsRead()
|
||||
{
|
||||
$notificationId = Common::getRequestVar('notificationId');
|
||||
NotificationManager::cancel($notificationId);
|
||||
}
|
||||
|
||||
protected function getDefaultIndexView()
|
||||
{
|
||||
$view = new View('@CoreHome/getDefaultIndexView');
|
||||
$this->setGeneralVariablesView($view);
|
||||
$view->menu = MenuMain::getInstance()->getMenu();
|
||||
$view->dashboardSettingsControl = new DashboardManagerControl();
|
||||
$view->content = '';
|
||||
return $view;
|
||||
}
|
||||
|
||||
protected function setDateTodayIfWebsiteCreatedToday()
|
||||
{
|
||||
$date = Common::getRequestVar('date', false);
|
||||
if ($date == 'today'
|
||||
|| Common::getRequestVar('period', false) == 'range'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
$websiteId = Common::getRequestVar('idSite', false, 'int');
|
||||
if ($websiteId) {
|
||||
$website = new Site($websiteId);
|
||||
$datetimeCreationDate = $website->getCreationDate()->getDatetime();
|
||||
$creationDateLocalTimezone = Date::factory($datetimeCreationDate, $website->getTimezone())->toString('Y-m-d');
|
||||
$todayLocalTimezone = Date::factory('now', $website->getTimezone())->toString('Y-m-d');
|
||||
if ($creationDateLocalTimezone == $todayLocalTimezone) {
|
||||
Piwik::redirectToModule('CoreHome', 'index',
|
||||
array('date' => 'today',
|
||||
'idSite' => $websiteId,
|
||||
'period' => Common::getRequestVar('period'))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->setDateTodayIfWebsiteCreatedToday();
|
||||
$view = $this->getDefaultIndexView();
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// ROW EVOLUTION
|
||||
// The following methods render the popover that shows the
|
||||
// evolution of a singe or multiple rows in a data table
|
||||
// --------------------------------------------------------
|
||||
|
||||
/** Render the entire row evolution popover for a single row */
|
||||
public function getRowEvolutionPopover()
|
||||
{
|
||||
$rowEvolution = $this->makeRowEvolution($isMulti = false);
|
||||
$view = new View('@CoreHome/getRowEvolutionPopover');
|
||||
return $rowEvolution->renderPopover($this, $view);
|
||||
}
|
||||
|
||||
/** Render the entire row evolution popover for multiple rows */
|
||||
public function getMultiRowEvolutionPopover()
|
||||
{
|
||||
$rowEvolution = $this->makeRowEvolution($isMulti = true);
|
||||
$view = new View('@CoreHome/getMultiRowEvolutionPopover');
|
||||
return $rowEvolution->renderPopover($this, $view);
|
||||
}
|
||||
|
||||
/** Generic method to get an evolution graph or a sparkline for the row evolution popover */
|
||||
public function getRowEvolutionGraph($fetch = false, $rowEvolution = null)
|
||||
{
|
||||
if (empty($rowEvolution)) {
|
||||
$label = Common::getRequestVar('label', '', 'string');
|
||||
$isMultiRowEvolution = strpos($label, ',') !== false;
|
||||
|
||||
$rowEvolution = $this->makeRowEvolution($isMultiRowEvolution, $graphType = 'graphEvolution');
|
||||
$rowEvolution->useAvailableMetrics();
|
||||
}
|
||||
|
||||
$view = $rowEvolution->getRowEvolutionGraph();
|
||||
return $this->renderView($view);
|
||||
}
|
||||
|
||||
/** Utility function. Creates a RowEvolution instance. */
|
||||
private function makeRowEvolution($isMultiRowEvolution, $graphType = null)
|
||||
{
|
||||
if ($isMultiRowEvolution) {
|
||||
return new MultiRowEvolution($this->idSite, $this->date, $graphType);
|
||||
} else {
|
||||
return new RowEvolution($this->idSite, $this->date, $graphType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a check for updates and re-renders the header message.
|
||||
*
|
||||
* This will check piwik.org at most once per 10s.
|
||||
*/
|
||||
public function checkForUpdates()
|
||||
{
|
||||
Piwik::checkUserHasSomeAdminAccess();
|
||||
$this->checkTokenInUrl();
|
||||
|
||||
// perform check (but only once every 10s)
|
||||
UpdateCheck::check($force = false, UpdateCheck::UI_CLICK_CHECK_INTERVAL);
|
||||
|
||||
MarketplaceApiClient::clearAllCacheEntries();
|
||||
|
||||
$view = new View('@CoreHome/checkForUpdates');
|
||||
$this->setGeneralVariablesView($view);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders and echo's the in-app donate form w/ slider.
|
||||
*/
|
||||
public function getDonateForm()
|
||||
{
|
||||
$view = new View('@CoreHome/getDonateForm');
|
||||
if (Common::getRequestVar('widget', false)
|
||||
&& Piwik::hasUserSuperUserAccess()
|
||||
) {
|
||||
$view->footerMessage = Piwik::translate('CoreHome_OnlyForSuperUserAccess');
|
||||
}
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders and echo's HTML that displays the Piwik promo video.
|
||||
*/
|
||||
public function getPromoVideo()
|
||||
{
|
||||
$view = new View('@CoreHome/getPromoVideo');
|
||||
$view->shareText = Piwik::translate('CoreHome_SharePiwikShort');
|
||||
$view->shareTextLong = Piwik::translate('CoreHome_SharePiwikLong');
|
||||
$view->promoVideoUrl = 'http://www.youtube.com/watch?v=OslfF_EH81g';
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects the user to a paypal so they can donate to Piwik.
|
||||
*/
|
||||
public function redirectToPaypal()
|
||||
{
|
||||
$parameters = Request::getRequestArrayFromString($request = null);
|
||||
foreach ($parameters as $name => $param) {
|
||||
if ($name == 'idSite'
|
||||
|| $name == 'module'
|
||||
|| $name == 'action'
|
||||
) {
|
||||
unset($parameters[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$url = "https://www.paypal.com/cgi-bin/webscr?" . Url::getQueryStringFromParameters($parameters);
|
||||
|
||||
header("Location: $url");
|
||||
exit;
|
||||
}
|
||||
|
||||
public function getSiteSelector()
|
||||
{
|
||||
return "<div piwik-siteselector class=\"sites_autocomplete\" switch-site-on-select=\"false\"></div>";
|
||||
}
|
||||
|
||||
public function getPeriodSelector()
|
||||
{
|
||||
$view = new View("@CoreHome/_periodSelect");
|
||||
$this->setGeneralVariablesView($view);
|
||||
return $view->render();
|
||||
}
|
||||
}
|
||||
201
www/analytics/plugins/CoreHome/CoreHome.php
Normal file
201
www/analytics/plugins/CoreHome/CoreHome.php
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
<?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\CoreHome;
|
||||
|
||||
use Piwik\WidgetsList;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class CoreHome extends \Piwik\Plugin
|
||||
{
|
||||
/**
|
||||
* @see Piwik\Plugin::getListHooksRegistered
|
||||
*/
|
||||
public function getListHooksRegistered()
|
||||
{
|
||||
return array(
|
||||
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
|
||||
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
|
||||
'WidgetsList.addWidgets' => 'addWidgets',
|
||||
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the donate form widget.
|
||||
*/
|
||||
public function addWidgets()
|
||||
{
|
||||
WidgetsList::add('Example Widgets', 'CoreHome_SupportPiwik', 'CoreHome', 'getDonateForm');
|
||||
WidgetsList::add('Example Widgets', 'Installation_Welcome', 'CoreHome', 'getPromoVideo');
|
||||
}
|
||||
|
||||
public function getStylesheetFiles(&$stylesheets)
|
||||
{
|
||||
$stylesheets[] = "libs/jquery/themes/base/jquery-ui.css";
|
||||
$stylesheets[] = "libs/jquery/stylesheets/jquery.jscrollpane.css";
|
||||
$stylesheets[] = "libs/jquery/stylesheets/scroll.less";
|
||||
$stylesheets[] = "plugins/Zeitgeist/stylesheets/base.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/coreHome.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/menu.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/dataTable.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/cloud.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/jquery.ui.autocomplete.css";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/jqplotColors.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/sparklineColors.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/promo.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/color_manager.css";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/sparklineColors.less";
|
||||
$stylesheets[] = "plugins/CoreHome/stylesheets/notification.less";
|
||||
$stylesheets[] = "plugins/CoreHome/angularjs/enrichedheadline/enrichedheadline.less";
|
||||
}
|
||||
|
||||
public function getJsFiles(&$jsFiles)
|
||||
{
|
||||
$jsFiles[] = "libs/jquery/jquery.js";
|
||||
$jsFiles[] = "libs/jquery/jquery-ui.js";
|
||||
$jsFiles[] = "libs/jquery/jquery.browser.js";
|
||||
$jsFiles[] = "libs/jquery/jquery.truncate.js";
|
||||
$jsFiles[] = "libs/jquery/jquery.scrollTo.js";
|
||||
$jsFiles[] = "libs/jquery/jquery.history.js";
|
||||
$jsFiles[] = "libs/jquery/jquery.jscrollpane.js";
|
||||
$jsFiles[] = "libs/jquery/jquery.mousewheel.js";
|
||||
$jsFiles[] = "libs/jquery/mwheelIntent.js";
|
||||
$jsFiles[] = "libs/javascript/sprintf.js";
|
||||
$jsFiles[] = "libs/angularjs/angular.min.js";
|
||||
$jsFiles[] = "libs/angularjs/angular-sanitize.min.js";
|
||||
$jsFiles[] = "libs/angularjs/angular-animate.min.js";
|
||||
$jsFiles[] = "plugins/Zeitgeist/javascripts/piwikHelper.js";
|
||||
$jsFiles[] = "plugins/Zeitgeist/javascripts/ajaxHelper.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/require.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/uiControl.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/dataTable.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/dataTable_rowactions.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/popover.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/broadcast.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/menu.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/menu_init.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/calendar.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/sparkline.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/corehome.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/top_controls.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/donate.js";
|
||||
$jsFiles[] = "libs/jqplot/jqplot-custom.min.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/promo.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/color_manager.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/notification.js";
|
||||
$jsFiles[] = "plugins/CoreHome/javascripts/notification_parser.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/piwikAppConfig.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/services/service.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/services/piwik.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/services/piwik-api.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/filters/filter.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/filters/translate.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/filters/startfrom.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/filters/evolution.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/directive.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/autocomplete-matched.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/focus-anywhere-but-here.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/ignore-click.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/onenter.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/focusif.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/common/directives/dialog.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/piwikApp.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/anchorLinkFix.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/siteselector/siteselector-model.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/siteselector/siteselector-controller.js";
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/siteselector/siteselector-directive.js";
|
||||
|
||||
$jsFiles[] = "plugins/CoreHome/angularjs/enrichedheadline/enrichedheadline-directive.js";
|
||||
}
|
||||
|
||||
public function getClientSideTranslationKeys(&$translationKeys)
|
||||
{
|
||||
$translationKeys[] = 'General_InvalidDateRange';
|
||||
$translationKeys[] = 'General_Loading';
|
||||
$translationKeys[] = 'General_Show';
|
||||
$translationKeys[] = 'General_Hide';
|
||||
$translationKeys[] = 'General_YearShort';
|
||||
$translationKeys[] = 'General_MultiSitesSummary';
|
||||
$translationKeys[] = 'CoreHome_YouAreUsingTheLatestVersion';
|
||||
$translationKeys[] = 'CoreHome_IncludeRowsWithLowPopulation';
|
||||
$translationKeys[] = 'CoreHome_ExcludeRowsWithLowPopulation';
|
||||
$translationKeys[] = 'CoreHome_DataTableIncludeAggregateRows';
|
||||
$translationKeys[] = 'CoreHome_DataTableExcludeAggregateRows';
|
||||
$translationKeys[] = 'CoreHome_Default';
|
||||
$translationKeys[] = 'CoreHome_PageOf';
|
||||
$translationKeys[] = 'CoreHome_FlattenDataTable';
|
||||
$translationKeys[] = 'CoreHome_UnFlattenDataTable';
|
||||
$translationKeys[] = 'CoreHome_ExternalHelp';
|
||||
$translationKeys[] = 'SitesManager_NotFound';
|
||||
$translationKeys[] = 'Annotations_ViewAndAddAnnotations';
|
||||
$translationKeys[] = 'General_RowEvolutionRowActionTooltipTitle';
|
||||
$translationKeys[] = 'General_RowEvolutionRowActionTooltip';
|
||||
$translationKeys[] = 'Annotations_IconDesc';
|
||||
$translationKeys[] = 'Annotations_IconDescHideNotes';
|
||||
$translationKeys[] = 'Annotations_HideAnnotationsFor';
|
||||
$translationKeys[] = 'General_LoadingPopover';
|
||||
$translationKeys[] = 'General_LoadingPopoverFor';
|
||||
$translationKeys[] = 'General_ShortMonth_1';
|
||||
$translationKeys[] = 'General_ShortMonth_2';
|
||||
$translationKeys[] = 'General_ShortMonth_3';
|
||||
$translationKeys[] = 'General_ShortMonth_4';
|
||||
$translationKeys[] = 'General_ShortMonth_5';
|
||||
$translationKeys[] = 'General_ShortMonth_6';
|
||||
$translationKeys[] = 'General_ShortMonth_7';
|
||||
$translationKeys[] = 'General_ShortMonth_8';
|
||||
$translationKeys[] = 'General_ShortMonth_9';
|
||||
$translationKeys[] = 'General_ShortMonth_10';
|
||||
$translationKeys[] = 'General_ShortMonth_11';
|
||||
$translationKeys[] = 'General_ShortMonth_12';
|
||||
$translationKeys[] = 'General_LongMonth_1';
|
||||
$translationKeys[] = 'General_LongMonth_2';
|
||||
$translationKeys[] = 'General_LongMonth_3';
|
||||
$translationKeys[] = 'General_LongMonth_4';
|
||||
$translationKeys[] = 'General_LongMonth_5';
|
||||
$translationKeys[] = 'General_LongMonth_6';
|
||||
$translationKeys[] = 'General_LongMonth_7';
|
||||
$translationKeys[] = 'General_LongMonth_8';
|
||||
$translationKeys[] = 'General_LongMonth_9';
|
||||
$translationKeys[] = 'General_LongMonth_10';
|
||||
$translationKeys[] = 'General_LongMonth_11';
|
||||
$translationKeys[] = 'General_LongMonth_12';
|
||||
$translationKeys[] = 'General_ShortDay_1';
|
||||
$translationKeys[] = 'General_ShortDay_2';
|
||||
$translationKeys[] = 'General_ShortDay_3';
|
||||
$translationKeys[] = 'General_ShortDay_4';
|
||||
$translationKeys[] = 'General_ShortDay_5';
|
||||
$translationKeys[] = 'General_ShortDay_6';
|
||||
$translationKeys[] = 'General_ShortDay_7';
|
||||
$translationKeys[] = 'General_LongDay_1';
|
||||
$translationKeys[] = 'General_LongDay_2';
|
||||
$translationKeys[] = 'General_LongDay_3';
|
||||
$translationKeys[] = 'General_LongDay_4';
|
||||
$translationKeys[] = 'General_LongDay_5';
|
||||
$translationKeys[] = 'General_LongDay_6';
|
||||
$translationKeys[] = 'General_LongDay_7';
|
||||
$translationKeys[] = 'General_DayMo';
|
||||
$translationKeys[] = 'General_DayTu';
|
||||
$translationKeys[] = 'General_DayWe';
|
||||
$translationKeys[] = 'General_DayTh';
|
||||
$translationKeys[] = 'General_DayFr';
|
||||
$translationKeys[] = 'General_DaySa';
|
||||
$translationKeys[] = 'General_DaySu';
|
||||
$translationKeys[] = 'General_Search';
|
||||
$translationKeys[] = 'General_MoreDetails';
|
||||
$translationKeys[] = 'General_Help';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?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\CoreHome\DataTableRowAction;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\Piwik;
|
||||
|
||||
/**
|
||||
* MULTI ROW EVOLUTION
|
||||
* The class handles the popover that shows the evolution of a multiple rows in a data table
|
||||
*/
|
||||
class MultiRowEvolution extends RowEvolution
|
||||
{
|
||||
/** The requested metric */
|
||||
protected $metric;
|
||||
|
||||
/** Show all metrics in the evolution graph when the popover opens */
|
||||
protected $initiallyShowAllMetrics = true;
|
||||
|
||||
/** The metrics available in the metrics select */
|
||||
protected $metricsForSelect;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
* @param int $idSite
|
||||
* @param \Piwik\Date $date ($this->date from controller)
|
||||
*/
|
||||
public function __construct($idSite, $date)
|
||||
{
|
||||
$this->metric = Common::getRequestVar('column', '', 'string');
|
||||
parent::__construct($idSite, $date);
|
||||
}
|
||||
|
||||
protected function loadEvolutionReport($column = false)
|
||||
{
|
||||
// set the "column" parameter for the API.getRowEvolution call
|
||||
parent::loadEvolutionReport($this->metric);
|
||||
}
|
||||
|
||||
protected function extractEvolutionReport($report)
|
||||
{
|
||||
$this->metric = $report['column'];
|
||||
$this->dataTable = $report['reportData'];
|
||||
$this->availableMetrics = $report['metadata']['metrics'];
|
||||
$this->metricsForSelect = $report['metadata']['columns'];
|
||||
$this->dimension = $report['metadata']['dimension'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the popover
|
||||
* @param \Piwik\Plugins\CoreHome\Controller $controller
|
||||
* @param View (the popover_rowevolution template)
|
||||
*/
|
||||
public function renderPopover($controller, $view)
|
||||
{
|
||||
// add data for metric select box
|
||||
$view->availableMetrics = $this->metricsForSelect;
|
||||
$view->selectedMetric = $this->metric;
|
||||
|
||||
$view->availableRecordsText = $this->dimension . ': '
|
||||
. Piwik::translate('RowEvolution_ComparingRecords', array(count($this->availableMetrics)));
|
||||
|
||||
return parent::renderPopover($controller, $view);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
<?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\CoreHome\DataTableRowAction;
|
||||
|
||||
use Exception;
|
||||
use Piwik\API\Request;
|
||||
use Piwik\API\ResponseBuilder;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Date;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution as EvolutionViz;
|
||||
use Piwik\Url;
|
||||
use Piwik\ViewDataTable\Factory;
|
||||
|
||||
/**
|
||||
* ROW EVOLUTION
|
||||
* The class handles the popover that shows the evolution of a singe row in a data table
|
||||
*/
|
||||
class RowEvolution
|
||||
{
|
||||
|
||||
/** The current site id */
|
||||
protected $idSite;
|
||||
|
||||
/** The api method to get the data. Format: Plugin.apiAction */
|
||||
protected $apiMethod;
|
||||
|
||||
/** The label of the requested row */
|
||||
protected $label;
|
||||
|
||||
/** The requested period */
|
||||
protected $period;
|
||||
|
||||
/** The requested date */
|
||||
protected $date;
|
||||
|
||||
/** The request segment */
|
||||
protected $segment;
|
||||
|
||||
/** The metrics that are available for the requested report and period */
|
||||
protected $availableMetrics;
|
||||
|
||||
/** The name of the dimension of the current report */
|
||||
protected $dimension;
|
||||
|
||||
/**
|
||||
* The data
|
||||
* @var \Piwik\DataTable
|
||||
*/
|
||||
protected $dataTable;
|
||||
|
||||
/** The label of the current record */
|
||||
protected $rowLabel;
|
||||
|
||||
/** The icon of the current record */
|
||||
protected $rowIcon;
|
||||
|
||||
/** The type of graph that has been requested last */
|
||||
protected $graphType;
|
||||
|
||||
/** The metrics for the graph that has been requested last */
|
||||
protected $graphMetrics;
|
||||
|
||||
/** Whether or not to show all metrics in the evolution graph when to popover opens */
|
||||
protected $initiallyShowAllMetrics = false;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
* Initialize some local variables from the request
|
||||
* @param int $idSite
|
||||
* @param Date $date ($this->date from controller)
|
||||
* @param null|string $graphType
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($idSite, $date, $graphType = null)
|
||||
{
|
||||
$this->apiMethod = Common::getRequestVar('apiMethod', '', 'string');
|
||||
if (empty($this->apiMethod)) throw new Exception("Parameter apiMethod not set.");
|
||||
|
||||
$this->label = ResponseBuilder::getLabelFromRequest($_GET);
|
||||
$this->label = $this->label[0];
|
||||
|
||||
if ($this->label === '') throw new Exception("Parameter label not set.");
|
||||
|
||||
$this->period = Common::getRequestVar('period', '', 'string');
|
||||
if (empty($this->period)) throw new Exception("Parameter period not set.");
|
||||
|
||||
$this->idSite = $idSite;
|
||||
$this->graphType = $graphType;
|
||||
|
||||
if ($this->period != 'range') {
|
||||
// handle day, week, month and year: display last X periods
|
||||
$end = $date->toString();
|
||||
list($this->date, $lastN) = EvolutionViz::getDateRangeAndLastN($this->period, $end);
|
||||
}
|
||||
$this->segment = \Piwik\API\Request::getRawSegmentFromRequest();
|
||||
|
||||
$this->loadEvolutionReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the popover
|
||||
* @param \Piwik\Plugins\CoreHome\Controller $controller
|
||||
* @param View (the popover_rowevolution template)
|
||||
*/
|
||||
public function renderPopover($controller, $view)
|
||||
{
|
||||
// render main evolution graph
|
||||
$this->graphType = 'graphEvolution';
|
||||
$this->graphMetrics = $this->availableMetrics;
|
||||
$view->graph = $controller->getRowEvolutionGraph($fetch = true, $rowEvolution = $this);
|
||||
|
||||
// render metrics overview
|
||||
$view->metrics = $this->getMetricsToggles();
|
||||
|
||||
// available metrics text
|
||||
$metricsText = Piwik::translate('RowEvolution_AvailableMetrics');
|
||||
$popoverTitle = '';
|
||||
if ($this->rowLabel) {
|
||||
$icon = $this->rowIcon ? '<img src="' . $this->rowIcon . '" alt="">' : '';
|
||||
$metricsText = sprintf(Piwik::translate('RowEvolution_MetricsFor'), $this->dimension . ': ' . $icon . ' ' . $this->rowLabel);
|
||||
$popoverTitle = $icon . ' ' . $this->rowLabel;
|
||||
}
|
||||
|
||||
$view->availableMetricsText = $metricsText;
|
||||
$view->popoverTitle = $popoverTitle;
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
protected function loadEvolutionReport($column = false)
|
||||
{
|
||||
list($apiModule, $apiAction) = explode('.', $this->apiMethod);
|
||||
|
||||
$parameters = array(
|
||||
'method' => 'API.getRowEvolution',
|
||||
'label' => $this->label,
|
||||
'apiModule' => $apiModule,
|
||||
'apiAction' => $apiAction,
|
||||
'idSite' => $this->idSite,
|
||||
'period' => $this->period,
|
||||
'date' => $this->date,
|
||||
'format' => 'original',
|
||||
'serialize' => '0'
|
||||
);
|
||||
if (!empty($this->segment)) {
|
||||
$parameters['segment'] = $this->segment;
|
||||
}
|
||||
|
||||
if ($column !== false) {
|
||||
$parameters['column'] = $column;
|
||||
}
|
||||
|
||||
$url = Url::getQueryStringFromParameters($parameters);
|
||||
|
||||
$request = new Request($url);
|
||||
$report = $request->process();
|
||||
|
||||
$this->extractEvolutionReport($report);
|
||||
}
|
||||
|
||||
protected function extractEvolutionReport($report)
|
||||
{
|
||||
$this->dataTable = $report['reportData'];
|
||||
$this->rowLabel = $this->extractPrettyLabel($report);
|
||||
$this->rowIcon = !empty($report['logo']) ? $report['logo'] : false;
|
||||
$this->availableMetrics = $report['metadata']['metrics'];
|
||||
$this->dimension = $report['metadata']['dimension'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to get an evolution graph or a sparkline for the row evolution popover.
|
||||
* Do as much as possible from outside the controller.
|
||||
* @param string|bool $graphType
|
||||
* @param array|bool $metrics
|
||||
* @return Factory
|
||||
*/
|
||||
public function getRowEvolutionGraph($graphType = false, $metrics = false)
|
||||
{
|
||||
// set up the view data table
|
||||
$view = Factory::build($graphType ? : $this->graphType, $this->apiMethod,
|
||||
$controllerAction = 'CoreHome.getRowEvolutionGraph', $forceDefault = true);
|
||||
$view->setDataTable($this->dataTable);
|
||||
|
||||
if (!empty($this->graphMetrics)) { // In row Evolution popover, this is empty
|
||||
$view->config->columns_to_display = array_keys($metrics ? : $this->graphMetrics);
|
||||
}
|
||||
|
||||
$view->config->show_goals = false;
|
||||
$view->config->show_all_views_icons = false;
|
||||
$view->config->show_active_view_icon = false;
|
||||
$view->config->show_related_reports = false;
|
||||
$view->config->show_series_picker = false;
|
||||
$view->config->show_footer_message = false;
|
||||
|
||||
foreach ($this->availableMetrics as $metric => $metadata) {
|
||||
$view->config->translations[$metric] = $metadata['name'];
|
||||
}
|
||||
|
||||
$view->config->external_series_toggle = 'RowEvolutionSeriesToggle';
|
||||
$view->config->external_series_toggle_show_all = $this->initiallyShowAllMetrics;
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare metrics toggles with spark lines
|
||||
* @return array
|
||||
*/
|
||||
protected function getMetricsToggles()
|
||||
{
|
||||
$i = 0;
|
||||
$metrics = array();
|
||||
foreach ($this->availableMetrics as $metric => $metricData) {
|
||||
$unit = Metrics::getUnit($metric, $this->idSite);
|
||||
$change = isset($metricData['change']) ? $metricData['change'] : false;
|
||||
|
||||
list($first, $last) = $this->getFirstAndLastDataPointsForMetric($metric);
|
||||
$details = Piwik::translate('RowEvolution_MetricBetweenText', array($first, $last));
|
||||
|
||||
if ($change !== false) {
|
||||
$lowerIsBetter = Metrics::isLowerValueBetter($metric);
|
||||
if (substr($change, 0, 1) == '+') {
|
||||
$changeClass = $lowerIsBetter ? 'bad' : 'good';
|
||||
$changeImage = $lowerIsBetter ? 'arrow_up_red' : 'arrow_up';
|
||||
} else if (substr($change, 0, 1) == '-') {
|
||||
$changeClass = $lowerIsBetter ? 'good' : 'bad';
|
||||
$changeImage = $lowerIsBetter ? 'arrow_down_green' : 'arrow_down';
|
||||
} else {
|
||||
$changeClass = 'neutral';
|
||||
$changeImage = false;
|
||||
}
|
||||
|
||||
$change = '<span class="' . $changeClass . '">'
|
||||
. ($changeImage ? '<img src="plugins/MultiSites/images/' . $changeImage . '.png" /> ' : '')
|
||||
. $change . '</span>';
|
||||
|
||||
$details .= ', ' . Piwik::translate('RowEvolution_MetricChangeText', $change);
|
||||
}
|
||||
|
||||
// set metric min/max text (used as tooltip for details)
|
||||
$max = isset($metricData['max']) ? $metricData['max'] : 0;
|
||||
$min = isset($metricData['min']) ? $metricData['min'] : 0;
|
||||
$min .= $unit;
|
||||
$max .= $unit;
|
||||
$minmax = Piwik::translate('RowEvolution_MetricMinMax', array($metricData['name'], $min, $max));
|
||||
|
||||
$newMetric = array(
|
||||
'label' => $metricData['name'],
|
||||
'details' => $details,
|
||||
'minmax' => $minmax,
|
||||
'sparkline' => $this->getSparkline($metric),
|
||||
);
|
||||
// Multi Rows, each metric can be for a particular row and display an icon
|
||||
if (!empty($metricData['logo'])) {
|
||||
$newMetric['logo'] = $metricData['logo'];
|
||||
}
|
||||
$metrics[] = $newMetric;
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $metrics;
|
||||
}
|
||||
|
||||
/** Get the img tag for a sparkline showing a single metric */
|
||||
protected function getSparkline($metric)
|
||||
{
|
||||
// sparkline is always echoed, so we need to buffer the output
|
||||
$view = $this->getRowEvolutionGraph($graphType = 'sparkline', $metrics = array($metric => $metric));
|
||||
|
||||
ob_start();
|
||||
$view->render();
|
||||
$spark = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// undo header change by sparkline renderer
|
||||
header('Content-type: text/html');
|
||||
|
||||
// base64 encode the image and put it in an img tag
|
||||
$spark = base64_encode($spark);
|
||||
return '<img src="data:image/png;base64,' . $spark . '" />';
|
||||
}
|
||||
|
||||
/** Use the available metrics for the metrics of the last requested graph. */
|
||||
public function useAvailableMetrics()
|
||||
{
|
||||
$this->graphMetrics = $this->availableMetrics;
|
||||
}
|
||||
|
||||
private function getFirstAndLastDataPointsForMetric($metric)
|
||||
{
|
||||
$first = 0;
|
||||
$firstTable = $this->dataTable->getFirstRow();
|
||||
if (!empty($firstTable)) {
|
||||
$row = $firstTable->getFirstRow();
|
||||
if (!empty($row)) {
|
||||
$first = floatval($row->getColumn($metric));
|
||||
}
|
||||
}
|
||||
|
||||
$last = 0;
|
||||
$lastTable = $this->dataTable->getLastRow();
|
||||
if (!empty($lastTable)) {
|
||||
$row = $lastTable->getFirstRow();
|
||||
if (!empty($row)) {
|
||||
$last = floatval($row->getColumn($metric));
|
||||
}
|
||||
}
|
||||
|
||||
return array($first, $last);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $report
|
||||
* @return string
|
||||
*/
|
||||
protected function extractPrettyLabel($report)
|
||||
{
|
||||
// By default, use the specified label
|
||||
$rowLabel = Common::sanitizeInputValue($report['label']);
|
||||
$rowLabel = str_replace('/', '<wbr>/', str_replace('&', '<wbr>&', $rowLabel ));
|
||||
|
||||
// If the dataTable specifies a label_html, use this instead
|
||||
/** @var $dataTableMap \Piwik\DataTable\Map */
|
||||
$dataTableMap = $report['reportData'];
|
||||
$labelPretty = $dataTableMap->getColumn('label_html');
|
||||
$labelPretty = array_filter($labelPretty, 'strlen');
|
||||
$labelPretty = current($labelPretty);
|
||||
if(!empty($labelPretty)) {
|
||||
return $labelPretty;
|
||||
}
|
||||
return $rowLabel;
|
||||
}
|
||||
}
|
||||
108
www/analytics/plugins/CoreHome/angularjs/anchorLinkFix.js
vendored
Normal file
108
www/analytics/plugins/CoreHome/angularjs/anchorLinkFix.js
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* See http://dev.piwik.org/trac/ticket/4795 "linking to #hash tag does not work after merging AngularJS"
|
||||
*/
|
||||
(function () {
|
||||
|
||||
function scrollToAnchorNode($node)
|
||||
{
|
||||
$.scrollTo($node, 20);
|
||||
}
|
||||
|
||||
function preventDefaultIfEventExists(event)
|
||||
{
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToAnchorIfPossible(hash, event)
|
||||
{
|
||||
if (!hash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (-1 !== hash.indexOf('&')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $node = $('#' + hash);
|
||||
|
||||
if ($node && $node.length) {
|
||||
scrollToAnchorNode($node);
|
||||
preventDefaultIfEventExists(event);
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $('a[name='+ hash + ']');
|
||||
|
||||
if ($node && $node.length) {
|
||||
scrollToAnchorNode($node);
|
||||
preventDefaultIfEventExists(event);
|
||||
}
|
||||
}
|
||||
|
||||
function isLinkWithinSamePage(location, newUrl)
|
||||
{
|
||||
if (location && location.origin && -1 === newUrl.indexOf(location.origin)) {
|
||||
// link to different domain
|
||||
return false;
|
||||
}
|
||||
|
||||
if (location && location.pathname && -1 === newUrl.indexOf(location.pathname)) {
|
||||
// link to different path
|
||||
return false;
|
||||
}
|
||||
|
||||
if (location && location.search && -1 === newUrl.indexOf(location.search)) {
|
||||
// link with different search
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleScrollToAnchorIfPresentOnPageLoad()
|
||||
{
|
||||
if (location.hash.substr(0, 2) == '#/') {
|
||||
var hash = location.hash.substr(2);
|
||||
scrollToAnchorIfPossible(hash, null);
|
||||
}
|
||||
}
|
||||
|
||||
function handleScrollToAnchorAfterPageLoad()
|
||||
{
|
||||
angular.module('piwikApp').run(['$rootScope', function ($rootScope) {
|
||||
|
||||
$rootScope.$on('$locationChangeStart', function (event, newUrl, oldUrl, $location) {
|
||||
|
||||
if (!newUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hashPos = newUrl.indexOf('#/');
|
||||
if (-1 === hashPos) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLinkWithinSamePage(this.location, newUrl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hash = newUrl.substr(hashPos + 2);
|
||||
|
||||
scrollToAnchorIfPossible(hash, event);
|
||||
});
|
||||
}]);
|
||||
}
|
||||
|
||||
handleScrollToAnchorAfterPageLoad();
|
||||
$(handleScrollToAnchorIfPresentOnPageLoad);
|
||||
|
||||
})();
|
||||
42
www/analytics/plugins/CoreHome/angularjs/common/directives/autocomplete-matched.js
vendored
Normal file
42
www/analytics/plugins/CoreHome/angularjs/common/directives/autocomplete-matched.js
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* If the given text or resolved expression matches any text within the element, the matching text will be wrapped
|
||||
* with a class.
|
||||
*
|
||||
* Example:
|
||||
* <div piwik-autocomplete-matched="'text'">My text</div> ==> <div>My <span class="autocompleteMatched">text</span></div>
|
||||
*
|
||||
* <div piwik-autocomplete-matched="searchTerm">{{ name }}</div>
|
||||
* <input type="text" ng-model="searchTerm">
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikAutocompleteMatched', function() {
|
||||
return function(scope, element, attrs) {
|
||||
var searchTerm;
|
||||
|
||||
scope.$watch(attrs.piwikAutocompleteMatched, function(value) {
|
||||
searchTerm = value;
|
||||
updateText();
|
||||
});
|
||||
|
||||
function updateText () {
|
||||
if (!searchTerm || !element) {
|
||||
return;
|
||||
}
|
||||
|
||||
var content = element.html();
|
||||
var startTerm = content.toLowerCase().indexOf(searchTerm.toLowerCase());
|
||||
|
||||
if (-1 !== startTerm) {
|
||||
var word = content.substr(startTerm, searchTerm.length);
|
||||
content = content.replace(word, '<span class="autocompleteMatched">' + word + '</span>');
|
||||
element.html(content);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
43
www/analytics/plugins/CoreHome/angularjs/common/directives/autocomplete-matched_spec.js
vendored
Normal file
43
www/analytics/plugins/CoreHome/angularjs/common/directives/autocomplete-matched_spec.js
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
describe('piwikAutocompleteMatchedDirective', function() {
|
||||
var $compile;
|
||||
var $rootScope;
|
||||
|
||||
beforeEach(module('piwikApp.directive'));
|
||||
beforeEach(inject(function(_$compile_, _$rootScope_){
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
}));
|
||||
|
||||
function assertRenderedContentIs(query, expectedResult) {
|
||||
var template = '<div piwik-autocomplete-matched="\'' + query + '\'">My Content</div>';
|
||||
var element = $compile(template)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.html()).to.eql(expectedResult);
|
||||
}
|
||||
|
||||
describe('#piwikAutocompleteMatched()', function() {
|
||||
|
||||
it('should not change anything if query does not match the text', function() {
|
||||
assertRenderedContentIs('Whatever', 'My Content');
|
||||
});
|
||||
|
||||
it('should wrap the matching part and find case insensitive', function() {
|
||||
assertRenderedContentIs('y cont', 'M<span class="autocompleteMatched">y Cont</span>ent');
|
||||
});
|
||||
|
||||
it('should be able to wrap the whole content', function() {
|
||||
assertRenderedContentIs('my content', '<span class="autocompleteMatched">My Content</span>');
|
||||
});
|
||||
|
||||
it('should find matching content case sensitive', function() {
|
||||
assertRenderedContentIs('My Co', '<span class="autocompleteMatched">My Co</span>ntent');
|
||||
});
|
||||
});
|
||||
});
|
||||
41
www/analytics/plugins/CoreHome/angularjs/common/directives/dialog.js
vendored
Normal file
41
www/analytics/plugins/CoreHome/angularjs/common/directives/dialog.js
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* <div piwik-dialog="showDialog">...</div>
|
||||
* Will show dialog once showDialog evaluates to true.
|
||||
*
|
||||
* <div piwik-dialog="showDialog" yes="executeMyFunction();">
|
||||
* ... <input type="button" role="yes" value="button">
|
||||
* </div>
|
||||
* Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikDialog', function(piwik) {
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
element.css('display', 'none');
|
||||
|
||||
element.on( "dialogclose", function() {
|
||||
scope.$eval(attrs.piwikDialog+'=false');
|
||||
});
|
||||
|
||||
scope.$watch(attrs.piwikDialog, function(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
piwik.helper.modalConfirm(element, {yes: function() {
|
||||
if (attrs.yes) {
|
||||
scope.$eval(attrs.yes);
|
||||
}
|
||||
}});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
8
www/analytics/plugins/CoreHome/angularjs/common/directives/directive.js
vendored
Normal file
8
www/analytics/plugins/CoreHome/angularjs/common/directives/directive.js
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
angular.module('piwikApp.directive', []);
|
||||
40
www/analytics/plugins/CoreHome/angularjs/common/directives/focus-anywhere-but-here.js
vendored
Normal file
40
www/analytics/plugins/CoreHome/angularjs/common/directives/focus-anywhere-but-here.js
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* The given expression will be executed when the user presses either escape or presses something outside
|
||||
* of this element
|
||||
*
|
||||
* Example:
|
||||
* <div piwik-focus-anywhere-but-here="closeDialog()">my dialog</div>
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikFocusAnywhereButHere', function($document){
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attr, ctrl) {
|
||||
|
||||
function onClickOutsideElement (event) {
|
||||
if (element.has(event.target).length === 0) {
|
||||
scope.$apply(attr.piwikFocusAnywhereButHere);
|
||||
}
|
||||
}
|
||||
|
||||
function onEscapeHandler (event) {
|
||||
if (event.which === 27) {
|
||||
scope.$apply(attr.piwikFocusAnywhereButHere);
|
||||
}
|
||||
}
|
||||
|
||||
$document.on('keyup', onEscapeHandler);
|
||||
$document.on('mouseup', onClickOutsideElement);
|
||||
scope.$on('$destroy', function() {
|
||||
$document.off('mouseup', onClickOutsideElement);
|
||||
$document.off('keyup', onEscapeHandler);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
27
www/analytics/plugins/CoreHome/angularjs/common/directives/focusif.js
vendored
Normal file
27
www/analytics/plugins/CoreHome/angularjs/common/directives/focusif.js
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* If the given expression evaluates to true the element will be focussed
|
||||
*
|
||||
* Example:
|
||||
* <input type="text" piwik-focus-if="view.editName">
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikFocusIf', function($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
scope.$watch(attrs.piwikFocusIf, function(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
$timeout(function () {
|
||||
element[0].focus();
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
21
www/analytics/plugins/CoreHome/angularjs/common/directives/ignore-click.js
vendored
Normal file
21
www/analytics/plugins/CoreHome/angularjs/common/directives/ignore-click.js
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prevents the default behavior of the click. For instance useful if a link should only work in case the user
|
||||
* does a "right click open in new window".
|
||||
*
|
||||
* Example
|
||||
* <a piwik-ignore-click ng-click="doSomething()" href="/">my link</a>
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikIgnoreClick', function() {
|
||||
return function(scope, element, attrs) {
|
||||
$(element).click(function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
};
|
||||
});
|
||||
27
www/analytics/plugins/CoreHome/angularjs/common/directives/onenter.js
vendored
Normal file
27
www/analytics/plugins/CoreHome/angularjs/common/directives/onenter.js
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows you to define any expression to be executed in case the user presses enter
|
||||
*
|
||||
* Example
|
||||
* <div piwik-onenter="save()">
|
||||
* <div piwik-onenter="showList=false">
|
||||
*/
|
||||
angular.module('piwikApp.directive').directive('piwikOnenter', function() {
|
||||
return function(scope, element, attrs) {
|
||||
element.bind("keydown keypress", function(event) {
|
||||
if(event.which === 13) {
|
||||
scope.$apply(function(){
|
||||
scope.$eval(attrs.piwikOnenter, {'event': event});
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
44
www/analytics/plugins/CoreHome/angularjs/common/filters/evolution.js
vendored
Normal file
44
www/analytics/plugins/CoreHome/angularjs/common/filters/evolution.js
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
angular.module('piwikApp.filter').filter('evolution', function() {
|
||||
|
||||
function calculateEvolution(currentValue, pastValue)
|
||||
{
|
||||
pastValue = parseInt(pastValue, 10);
|
||||
currentValue = parseInt(currentValue, 10) - pastValue;
|
||||
|
||||
if (currentValue === 0 || isNaN(currentValue)) {
|
||||
evolution = 0;
|
||||
} else if (pastValue === 0 || isNaN(pastValue)) {
|
||||
evolution = 100;
|
||||
} else {
|
||||
evolution = (currentValue / pastValue) * 100;
|
||||
}
|
||||
|
||||
return evolution;
|
||||
}
|
||||
|
||||
function formatEvolution(evolution)
|
||||
{
|
||||
evolution = Math.round(evolution);
|
||||
|
||||
if (evolution > 0) {
|
||||
evolution = '+' + evolution;
|
||||
}
|
||||
|
||||
evolution += '%';
|
||||
|
||||
return evolution;
|
||||
}
|
||||
|
||||
return function(currentValue, pastValue) {
|
||||
var evolution = calculateEvolution(currentValue, pastValue);
|
||||
|
||||
return formatEvolution(evolution);
|
||||
};
|
||||
});
|
||||
7
www/analytics/plugins/CoreHome/angularjs/common/filters/filter.js
vendored
Normal file
7
www/analytics/plugins/CoreHome/angularjs/common/filters/filter.js
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
angular.module('piwikApp.filter', []);
|
||||
13
www/analytics/plugins/CoreHome/angularjs/common/filters/startfrom.js
vendored
Normal file
13
www/analytics/plugins/CoreHome/angularjs/common/filters/startfrom.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
angular.module('piwikApp.filter').filter('startFrom', function() {
|
||||
return function(input, start) {
|
||||
start = +start; //parse to int
|
||||
return input.slice(start);
|
||||
};
|
||||
});
|
||||
40
www/analytics/plugins/CoreHome/angularjs/common/filters/startfrom_spec.js
vendored
Normal file
40
www/analytics/plugins/CoreHome/angularjs/common/filters/startfrom_spec.js
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
describe('startFromFilter', function() {
|
||||
var startFrom;
|
||||
|
||||
beforeEach(module('piwikApp.filter'));
|
||||
beforeEach(inject(function($injector) {
|
||||
var $filter = $injector.get('$filter');
|
||||
startFrom = $filter('startFrom');
|
||||
}));
|
||||
|
||||
describe('#startFrom()', function() {
|
||||
|
||||
it('should return all entries if index is zero', function() {
|
||||
|
||||
var result = startFrom([1,2,3], 0);
|
||||
|
||||
expect(result).to.eql([1,2,3]);
|
||||
});
|
||||
|
||||
it('should return only partial entries if filter is higher than zero', function() {
|
||||
|
||||
var result = startFrom([1,2,3], 2);
|
||||
|
||||
expect(result).to.eql([3]);
|
||||
});
|
||||
|
||||
it('should return no entries if start is higher than input length', function() {
|
||||
|
||||
var result = startFrom([1,2,3], 11);
|
||||
|
||||
expect(result).to.eql([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
19
www/analytics/plugins/CoreHome/angularjs/common/filters/translate.js
vendored
Normal file
19
www/analytics/plugins/CoreHome/angularjs/common/filters/translate.js
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
angular.module('piwikApp.filter').filter('translate', function() {
|
||||
|
||||
return function(key, value1, value2, value3) {
|
||||
var values = [];
|
||||
if (arguments && arguments.length > 1) {
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
values.push(arguments[index]);
|
||||
}
|
||||
}
|
||||
return _pk_translate(key, values);
|
||||
};
|
||||
});
|
||||
186
www/analytics/plugins/CoreHome/angularjs/common/services/piwik-api.js
vendored
Normal file
186
www/analytics/plugins/CoreHome/angularjs/common/services/piwik-api.js
vendored
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $rootScope, piwik, $window) {
|
||||
|
||||
var url = 'index.php';
|
||||
var format = 'json';
|
||||
var getParams = {};
|
||||
var postParams = {};
|
||||
var requestHandle = null;
|
||||
|
||||
var piwikApi = {};
|
||||
|
||||
/**
|
||||
* Adds params to the request.
|
||||
* If params are given more then once, the latest given value is used for the request
|
||||
*
|
||||
* @param {object} params
|
||||
* @return {void}
|
||||
*/
|
||||
function addParams (params) {
|
||||
if (typeof params == 'string') {
|
||||
params = piwik.broadcast.getValuesFromUrl(params);
|
||||
}
|
||||
|
||||
for (var key in params) {
|
||||
getParams[key] = params[key];
|
||||
}
|
||||
}
|
||||
|
||||
function reset () {
|
||||
getParams = {};
|
||||
postParams = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the request
|
||||
* @return $promise
|
||||
*/
|
||||
function send () {
|
||||
|
||||
var deferred = $q.defer();
|
||||
var requestHandle = deferred;
|
||||
|
||||
var onError = function (message) {
|
||||
deferred.reject(message);
|
||||
requestHandle = null;
|
||||
};
|
||||
|
||||
var onSuccess = function (response) {
|
||||
if (response && response.result == 'error') {
|
||||
|
||||
if (response.message) {
|
||||
onError(response.message);
|
||||
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(response.message, {
|
||||
context: 'error',
|
||||
type: 'toast',
|
||||
id: 'ajaxHelper'
|
||||
});
|
||||
notification.scrollToNotification();
|
||||
} else {
|
||||
onError(null);
|
||||
}
|
||||
|
||||
} else {
|
||||
deferred.resolve(response);
|
||||
}
|
||||
requestHandle = null;
|
||||
};
|
||||
|
||||
var headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
// ie 8,9,10 caches ajax requests, prevent this
|
||||
'cache-control': 'no-cache'
|
||||
};
|
||||
|
||||
var ajaxCall = {
|
||||
method: 'POST',
|
||||
url: url,
|
||||
responseType: format,
|
||||
params: _mixinDefaultGetParams(getParams),
|
||||
data: $.param(getPostParams(postParams)),
|
||||
timeout: deferred.promise,
|
||||
headers: headers
|
||||
};
|
||||
|
||||
$http(ajaxCall).success(onSuccess).error(onError);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parameters to send as POST
|
||||
*
|
||||
* @param {object} params parameter object
|
||||
* @return {object}
|
||||
* @private
|
||||
*/
|
||||
function getPostParams () {
|
||||
return {
|
||||
token_auth: piwik.token_auth
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin the default parameters to send as GET
|
||||
*
|
||||
* @param {object} getParamsToMixin parameter object
|
||||
* @return {object}
|
||||
* @private
|
||||
*/
|
||||
function _mixinDefaultGetParams (getParamsToMixin) {
|
||||
|
||||
var defaultParams = {
|
||||
idSite: piwik.idSite || piwik.broadcast.getValueFromUrl('idSite'),
|
||||
period: piwik.period || piwik.broadcast.getValueFromUrl('period'),
|
||||
segment: piwik.broadcast.getValueFromHash('segment', $window.location.href.split('#')[1])
|
||||
};
|
||||
|
||||
// never append token_auth to url
|
||||
if (getParamsToMixin.token_auth) {
|
||||
getParamsToMixin.token_auth = null;
|
||||
delete getParamsToMixin.token_auth;
|
||||
}
|
||||
|
||||
for (var key in defaultParams) {
|
||||
if (!getParamsToMixin[key] && !postParams[key] && defaultParams[key]) {
|
||||
getParamsToMixin[key] = defaultParams[key];
|
||||
}
|
||||
}
|
||||
|
||||
// handle default date & period if not already set
|
||||
if (!getParamsToMixin.date && !postParams.date) {
|
||||
getParamsToMixin.date = piwik.currentDateString || piwik.broadcast.getValueFromUrl('date');
|
||||
if (getParamsToMixin.period == 'range' && piwik.currentDateString) {
|
||||
getParamsToMixin.date = piwik.startDateString + ',' + getParamsToMixin.date;
|
||||
}
|
||||
}
|
||||
|
||||
return getParamsToMixin;
|
||||
}
|
||||
|
||||
piwikApi.abort = function () {
|
||||
reset();
|
||||
|
||||
if (requestHandle) {
|
||||
requestHandle.resolve();
|
||||
requestHandle = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform a reading API request.
|
||||
* @param getParams
|
||||
*/
|
||||
piwikApi.fetch = function (getParams) {
|
||||
|
||||
getParams.module = 'API';
|
||||
getParams.format = 'JSON';
|
||||
|
||||
addParams(getParams, 'GET');
|
||||
|
||||
var promise = send();
|
||||
|
||||
reset();
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
piwikApi.post = function (getParams, _postParams_) {
|
||||
if (_postParams_) {
|
||||
postParams = _postParams_;
|
||||
}
|
||||
|
||||
return this.fetch(getParams);
|
||||
};
|
||||
|
||||
return piwikApi;
|
||||
});
|
||||
13
www/analytics/plugins/CoreHome/angularjs/common/services/piwik.js
vendored
Normal file
13
www/analytics/plugins/CoreHome/angularjs/common/services/piwik.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
angular.module('piwikApp.service').service('piwik', function () {
|
||||
|
||||
piwik.helper = piwikHelper;
|
||||
piwik.broadcast = broadcast;
|
||||
return piwik;
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue