قرینه از
https://github.com/matomo-org/matomo.git
synced 2025-08-22 15:07:44 +00:00

* Add feature flags plugin w/ config implementation and example feature * Make sure FeatureFlags plugin always loaded * Don't use DI for test feature, create new migration / version for the plugin * Add license info to files * Update screenshot tests * Update screenshot tests * Show HTML tag in markup * Update plugins/FeatureFlags/config/config.php Co-authored-by: Michal Kleiner <michal@innocraft.com> * Change Feature class names to NameFeatureFlag * Increase version * Increase version * Fix migration file name * Don't use DI for test feature, create new migration / version for the plugin * remove not needed migration * Make interface easier to use so you don't have to pass objects but just class names. * Move flags to DI and write more tests * Add command + system tests * Fix cs problems * Fix problem with example flag in home controller * Fix CS issues * Tidy up command * Update plugins/FeatureFlags/config/config.php Co-authored-by: Michal Kleiner <michal@innocraft.com> * Remove dependency on DI for feature flag manager * Split command into 3 commands, and rely on plugin manager rather than DI * Use constants for storage implementation * Use correct implementation of manager * Update deletion to not depend on concrete class * Remove plugin from pluginToAlwaysActivate and add plugin.json file * Fix spacing * Remove orphaned test * Remove extra closing bracket * Fix desc of command * Remove plugins.json and plugin base class * Fix config DI * Add plugin to list of always activated plugins * ensure to automatically activate newly added plugins, that are enabled by default * Ensure to always load di config of always activated plugins * Update expected screenshots --------- Co-authored-by: Michal Kleiner <michal@innocraft.com> Co-authored-by: sgiehl <stefan@matomo.org> Co-authored-by: Marc Neudert <marc@innocraft.com>
356 خطوط
12 KiB
PHP
356 خطوط
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Matomo - free/libre analytics platform
|
|
*
|
|
* @link https://matomo.org
|
|
* @license https://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\Config;
|
|
use Piwik\Container\StaticContainer;
|
|
use Piwik\DataTable\Renderer\Json;
|
|
use Piwik\Date;
|
|
use Piwik\FrontController;
|
|
use Piwik\Log\LoggerInterface;
|
|
use Piwik\Notification\Manager as NotificationManager;
|
|
use Piwik\Piwik;
|
|
use Piwik\Plugin\Report;
|
|
use Piwik\Plugins\FeatureFlags\FeatureFlagManager;
|
|
use Piwik\Plugins\FeatureFlags\FeatureFlags\Example;
|
|
use Piwik\Plugins\FeatureFlags\Storage\ConfigFeatureFlagStorage;
|
|
use Piwik\Plugins\Marketplace\Marketplace;
|
|
use Piwik\SettingsPiwik;
|
|
use Piwik\Widget\Widget;
|
|
use Piwik\Plugins\CoreHome\DataTableRowAction\MultiRowEvolution;
|
|
use Piwik\Plugins\CoreHome\DataTableRowAction\RowEvolution;
|
|
use Piwik\Plugins\UsersManager\API;
|
|
use Piwik\Translation\Translator;
|
|
use Piwik\UpdateCheck;
|
|
use Piwik\Url;
|
|
use Piwik\View;
|
|
use Piwik\ViewDataTable\Manager as ViewDataTableManager;
|
|
use Piwik\Widget\WidgetConfig;
|
|
|
|
class Controller extends \Piwik\Plugin\Controller
|
|
{
|
|
/**
|
|
* @var Translator
|
|
*/
|
|
private $translator;
|
|
|
|
/**
|
|
* @var FeatureFlagManager
|
|
*/
|
|
private $featureFlagManager;
|
|
|
|
public function __construct(Translator $translator)
|
|
{
|
|
$this->translator = $translator;
|
|
|
|
parent::__construct();
|
|
|
|
$this->featureFlagManager = new FeatureFlagManager(
|
|
[new ConfigFeatureFlagStorage(Config::getInstance())],
|
|
StaticContainer::get(LoggerInterface::class)
|
|
);
|
|
}
|
|
|
|
public function getDefaultAction()
|
|
{
|
|
return 'redirectToCoreHomeIndex';
|
|
}
|
|
|
|
public function renderReportWidget(Report $report)
|
|
{
|
|
Piwik::checkUserHasSomeViewAccess();
|
|
$this->checkSitePermission();
|
|
|
|
$report->checkIsEnabled();
|
|
|
|
return $report->render();
|
|
}
|
|
|
|
/**
|
|
* This is only used for exported widgets
|
|
* @return string
|
|
* @throws Exception
|
|
* @throws \Piwik\NoAccessException
|
|
*/
|
|
public function renderWidgetContainer()
|
|
{
|
|
Piwik::checkUserHasSomeViewAccess();
|
|
$this->checkSitePermission();
|
|
|
|
$view = new View('@CoreHome/widgetContainer');
|
|
$view->isWidgetized = (bool) Common::getRequestVar('widget', 0, 'int');
|
|
$view->containerId = Common::getRequestVar('containerId', null, 'string');
|
|
|
|
return $view->render();
|
|
}
|
|
|
|
/**
|
|
* @param Widget $widget
|
|
* @return mixed
|
|
* @throws Exception
|
|
*/
|
|
public function renderWidget($widget)
|
|
{
|
|
Piwik::checkUserHasSomeViewAccess();
|
|
|
|
$config = new WidgetConfig();
|
|
$widget::configure($config);
|
|
|
|
$content = $widget->render();
|
|
|
|
if ($config->getName() && Common::getRequestVar('showtitle', '', 'string') === '1') {
|
|
if (
|
|
strpos($content, '<h2') !== false
|
|
|| strpos($content, ' content-title=') !== false
|
|
|| strpos($content, 'CoreHome.EnrichedHeadline') !== false
|
|
|| strpos($content, '<h1') !== false
|
|
) {
|
|
// already includes title
|
|
return $content;
|
|
}
|
|
|
|
if (
|
|
strpos($content, '<!-- has-content-block -->') === false
|
|
&& strpos($content, 'class="card"') === false
|
|
&& strpos($content, "class='card'") === false
|
|
&& strpos($content, 'class="card-content"') === false
|
|
&& strpos($content, "class='card-content'") === false
|
|
) {
|
|
$view = new View('@CoreHome/_singleWidget');
|
|
$view->title = $config->getName();
|
|
$view->content = $content;
|
|
return $view->render();
|
|
}
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
public function redirectToCoreHomeIndex()
|
|
{
|
|
$defaultReport = API::getInstance()->getUserPreference(
|
|
API::PREFERENCE_DEFAULT_REPORT,
|
|
Piwik::getCurrentUserLogin()
|
|
);
|
|
$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();
|
|
}
|
|
|
|
parent::redirectToIndex($module, $action, $this->idSite);
|
|
}
|
|
|
|
public function showInContext()
|
|
{
|
|
$controllerName = Common::getRequestVar('moduleToLoad');
|
|
$actionName = Common::getRequestVar('actionToLoad', 'index');
|
|
|
|
if ($controllerName == 'API') {
|
|
throw new Exception("Showing API requests in context is not supported for security reasons. Please change query parameter 'moduleToLoad'.");
|
|
}
|
|
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()
|
|
{
|
|
Piwik::checkUserHasSomeViewAccess();
|
|
$this->checkTokenInUrl();
|
|
|
|
$notificationId = Common::getRequestVar('notificationId');
|
|
NotificationManager::cancel($notificationId);
|
|
|
|
Json::sendHeaderJSON();
|
|
return json_encode(true);
|
|
}
|
|
|
|
protected function getDefaultIndexView()
|
|
{
|
|
if (SettingsPiwik::isInternetEnabled() && Marketplace::isMarketplaceEnabled()) {
|
|
$this->securityPolicy->addPolicy('img-src', '*.matomo.org');
|
|
$this->securityPolicy->addPolicy('default-src', '*.matomo.org');
|
|
}
|
|
|
|
$view = new View('@CoreHome/getDefaultIndexView');
|
|
$this->setGeneralVariablesView($view);
|
|
$view->showMenu = true;
|
|
$view->content = '';
|
|
$view->exampleFeatureEnabled = $this->featureFlagManager->isFeatureActive(Example::class);
|
|
return $view;
|
|
}
|
|
|
|
protected function setDateTodayIfWebsiteCreatedToday()
|
|
{
|
|
$date = Common::getRequestVar('date', false);
|
|
if (
|
|
$date == 'today'
|
|
|| Common::getRequestVar('period', false) == 'range'
|
|
) {
|
|
return;
|
|
}
|
|
|
|
if ($this->site) {
|
|
$datetimeCreationDate = $this->site->getCreationDate()->getDatetime();
|
|
$creationDateLocalTimezone = Date::factory($datetimeCreationDate, $this->site->getTimezone())->toString('Y-m-d');
|
|
$todayLocalTimezone = Date::factory('now', $this->site->getTimezone())->toString('Y-m-d');
|
|
|
|
if ($creationDateLocalTimezone == $todayLocalTimezone) {
|
|
Piwik::redirectToModule(
|
|
'CoreHome',
|
|
'index',
|
|
array('date' => 'today',
|
|
'idSite' => $this->idSite,
|
|
'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 single 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);
|
|
|
|
$view = new View('@CoreHome/checkForUpdates');
|
|
$view->isManualUpdateCheck = true;
|
|
$view->lastUpdateCheckFailed = UpdateCheck::hasLastCheckFailed();
|
|
$this->setGeneralVariablesView($view);
|
|
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]);
|
|
}
|
|
}
|
|
$paypalParameters = [
|
|
"cmd" => "_s-xclick"
|
|
];
|
|
if (empty($parameters["onetime"]) || $parameters["onetime"] != "true") {
|
|
$paypalParameters["hosted_button_id"] = "DVKLY73RS7JTE";
|
|
$paypalParameters["currency_code"] = "USD";
|
|
$paypalParameters["on0"] = "Piwik Supporter";
|
|
if (!empty($parameters["os0"])) {
|
|
$paypalParameters["os0"] = $parameters["os0"];
|
|
}
|
|
} else {
|
|
$paypalParameters["hosted_button_id"] = "RPL23NJURMTFA";
|
|
}
|
|
|
|
$url = "https://www.paypal.com/cgi-bin/webscr?" . Url::getQueryStringFromParameters($paypalParameters);
|
|
|
|
Url::redirectToUrl($url);
|
|
exit;
|
|
}
|
|
|
|
public function saveViewDataTableParameters()
|
|
{
|
|
Piwik::checkUserIsNotAnonymous();
|
|
$this->checkTokenInUrl();
|
|
|
|
$reportId = Common::getRequestVar('report_id', null, 'string');
|
|
$parameters = (array) Common::getRequestVar('parameters', null, 'json');
|
|
$login = Piwik::getCurrentUserLogin();
|
|
$containerId = Common::getRequestVar('containerId', '', 'string');
|
|
|
|
ViewDataTableManager::saveViewDataTableParameters($login, $reportId, $parameters, $containerId);
|
|
}
|
|
}
|