/** * @link http://php-di.org/doc/container-configuration.html * @throws \Exception * @return Container */ public function create() { $builder = new ContainerBuilder(); $builder->useAnnotations(false); $builder->setDefinitionCache(new ArrayCache()); // INI config $builder->addDefinitions(new IniConfigDefinitionSource(Config::getInstance())); // Global config $builder->addDefinitions(PIWIK_USER_PATH . '/config/global.php'); // Plugin configs $this->addPluginConfigs($builder); // Development config if (Development::isEnabled()) { $builder->addDefinitions(PIWIK_USER_PATH . '/config/environment/dev.php'); } // User config if (file_exists(PIWIK_USER_PATH . '/config/config.php')) { $builder->addDefinitions(PIWIK_USER_PATH . '/config/config.php'); } // Environment config $this->addEnvironmentConfig($builder); if (!empty($this->definitions)) { $builder->addDefinitions($this->definitions); } return $builder->build(); }
public function demo() { if (!Development::isEnabled() || !Piwik::isUserHasSomeAdminAccess()) { return; } return $this->renderTemplate('demo'); }
private function shouldSkipCategory($category) { $category = strtolower($category); if ($category === 'database') { return true; } $developmentOnlySections = array('database_tests', 'tests', 'debugtests'); return !Development::isEnabled() && in_array($category, $developmentOnlySections); }
public function configureUserMenu(MenuUser $menu) { $menu->registerMenuIcon('UsersManager_MenuPersonal', 'icon-user-personal'); $menu->registerMenuIcon('CoreAdminHome_MenuManage', 'icon-user-manage'); $menu->registerMenuIcon('CorePluginsAdmin_MenuPlatform', 'icon-user-platform'); if (Development::isEnabled() && Piwik::isUserHasSomeAdminAccess()) { $menu->addPlatformItem('UI Demo', $this->urlForAction('demo'), $order = 15); } }
/** * Here you can define any action that should be performed during the update. For instance executing SQL statements, * renaming config entries, updating files, etc. */ public static function update() { if (!Development::isEnabled()) { return; } $config = Config::getInstance(); $dbTests = $config->database_tests; if ($dbTests['username'] === '@USERNAME@') { $dbTests['username'] = '******'; } $config->database_tests = $dbTests; $config->forceSave(); }
private static function populateCache() { if (Development::isEnabled()) { return; } if (SettingsServer::isTrackerApiRequest()) { $eventToPersist = 'Tracker.end'; $mode = 'tracker'; } else { $eventToPersist = 'Request.dispatch.end'; $mode = 'ui'; } $cache = self::getStorage()->get('StaticCache-' . $mode); if (is_array($cache)) { self::$content = $cache; } Piwik::addAction($eventToPersist, array(__CLASS__, 'persistCache')); }
public function configureAdminMenu(MenuAdmin $menu) { $menu->registerMenuIcon('CoreAdminHome_MenuDevelopment', 'icon-admin-development'); $menu->registerMenuIcon('CoreAdminHome_MenuDiagnostic', 'icon-admin-diagnostic'); $menu->registerMenuIcon('CorePluginsAdmin_MenuPlatform', 'icon-admin-platform'); $menu->registerMenuIcon('General_Settings', 'icon-admin-settings'); $menu->registerMenuIcon('CoreAdminHome_Administration', 'icon-settings'); $menu->registerMenuIcon('UsersManager_MenuPersonal', 'icon-user-personal'); $menu->registerMenuIcon('CoreAdminHome_MenuSystem', 'icon-server'); $menu->registerMenuIcon('CorePluginsAdmin_MenuPlatform', 'icon-user-platform'); $manageMeasurablesIcon = 'icon-open-source'; $menu->registerMenuIcon('CoreAdminHome_MenuMeasurables', $manageMeasurablesIcon); $menu->registerMenuIcon('SitesManager_Sites', $manageMeasurablesIcon); $menu->registerMenuIcon('MobileAppMeasurable_MobileApps', $manageMeasurablesIcon); if (Development::isEnabled() && Piwik::isUserHasSomeAdminAccess()) { $menu->addDevelopmentItem('UI Demo', $this->urlForAction('demo')); } }
public function execute() { $label = $this->translator->translate('Installation_SystemCheckFileIntegrity'); if (Development::isEnabled()) { return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK)); } $messages = Filechecks::getFileIntegrityInformation(); $ok = array_shift($messages); if (empty($messages)) { return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK)); } if ($ok) { $status = DiagnosticResult::STATUS_WARNING; return array(DiagnosticResult::singleResult($label, $status, $messages[0])); } $comment = $this->translator->translate('General_FileIntegrityWarningExplanation'); // Keep only the 20 first lines else it becomes unmanageable if (count($messages) > 20) { $messages = array_slice($messages, 0, 20); $messages[] = '...'; } $comment .= '<br/><br/><pre style="overflow-x: scroll;max-width: 600px;">' . implode("\n", $messages) . '</pre>'; return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)); }
private static function notifyWhenDebugOnDemandIsEnabled($trackerSetting) { if (!Development::isEnabled() && Piwik::hasUserSuperUserAccess() && TrackerConfig::getConfigValue($trackerSetting)) { $message = Piwik::translate('General_WarningDebugOnDemandEnabled'); $message = sprintf($message, '"' . $trackerSetting . '"', '"[Tracker] ' . $trackerSetting . '"', '"0"', '"config/config.ini.php"'); $notification = new Notification($message); $notification->title = Piwik::translate('General_Warning'); $notification->priority = Notification::PRIORITY_LOW; $notification->context = Notification::CONTEXT_WARNING; $notification->type = Notification::TYPE_TRANSIENT; $notification->flags = Notification::FLAG_NO_CLEAR; NotificationManager::notify('Tracker' . $trackerSetting, $notification); } }
/** * Renders the current view. Also sends the stored 'Content-Type' HTML header. * See {@link setContentType()}. * * @return string Generated template. */ public function render() { try { $this->currentModule = Piwik::getModule(); $this->currentAction = Piwik::getAction(); $this->url = Common::sanitizeInputValue(Url::getCurrentUrl()); $this->token_auth = Piwik::getCurrentUserTokenAuth(); $this->userHasSomeAdminAccess = Piwik::isUserHasSomeAdminAccess(); $this->userIsAnonymous = Piwik::isUserIsAnonymous(); $this->userIsSuperUser = Piwik::hasUserSuperUserAccess(); $this->latest_version_available = UpdateCheck::isNewestVersionAvailable(); $this->disableLink = Common::getRequestVar('disableLink', 0, 'int'); $this->isWidget = Common::getRequestVar('widget', 0, 'int'); $piwikAds = StaticContainer::get('Piwik\\ProfessionalServices\\Advertising'); $this->areAdsForProfessionalServicesEnabled = $piwikAds->areAdsForProfessionalServicesEnabled(); if (Development::isEnabled()) { $cacheBuster = rand(0, 10000); } else { $cacheBuster = UIAssetCacheBuster::getInstance()->piwikVersionBasedCacheBuster(); } $this->cacheBuster = $cacheBuster; $this->loginModule = Piwik::getLoginPluginName(); $user = APIUsersManager::getInstance()->getUser($this->userLogin); $this->userAlias = $user['alias']; } catch (Exception $e) { Log::debug($e); // can fail, for example at installation (no plugin loaded yet) } ProxyHttp::overrideCacheControlHeaders('no-store'); Common::sendHeader('Content-Type: ' . $this->contentType); // always sending this header, sometimes empty, to ensure that Dashboard embed loads // - when calling sendHeader() multiple times, the last one prevails Common::sendHeader('X-Frame-Options: ' . (string) $this->xFrameOptions); return $this->renderTwigTemplate(); }
public function configureUserMenu(MenuUser $menu) { if (Development::isEnabled() && Piwik::isUserHasSomeAdminAccess()) { $menu->addPlatformItem('UI Demo', $this->urlForAction('demo'), $order = 15); } }
/** * Copies the given method and all needed use statements into an existing class. The target class name will be * built based on the given $replace argument. * @param string $sourceClassName * @param string $methodName * @param array $replace */ protected function copyTemplateMethodToExisitingClass($sourceClassName, $methodName, $replace) { $targetClassName = $this->replaceContent($replace, $sourceClassName); if (Development::methodExists($targetClassName, $methodName)) { // we do not want to add the same method twice return; } Development::checkMethodExists($sourceClassName, $methodName, 'Cannot copy template method: '); $targetClass = new \ReflectionClass($targetClassName); $file = new \SplFileObject($targetClass->getFileName()); $methodCode = Development::getMethodSourceCode($sourceClassName, $methodName); $methodCode = $this->replaceContent($replace, $methodCode); $methodLine = $targetClass->getEndLine() - 1; $sourceUses = Development::getUseStatements($sourceClassName); $targetUses = Development::getUseStatements($targetClassName); $usesToAdd = array_diff($sourceUses, $targetUses); if (empty($usesToAdd)) { $useCode = ''; } else { $useCode = "\nuse " . implode("\nuse ", $usesToAdd) . "\n"; } // search for namespace line before the class starts $useLine = 0; foreach (new \LimitIterator($file, 0, $targetClass->getStartLine()) as $index => $line) { if (0 === strpos(trim($line), 'namespace ')) { $useLine = $index + 1; break; } } $newClassCode = ''; foreach (new \LimitIterator($file) as $index => $line) { if ($index == $methodLine) { $newClassCode .= $methodCode; } if (0 !== $useLine && $index == $useLine) { $newClassCode .= $useCode; } $newClassCode .= $line; } file_put_contents($targetClass->getFileName(), $newClassCode); }
public function configureAdminMenu(MenuAdmin $menu) { if (Development::isEnabled() && Piwik::isUserHasSomeAdminAccess()) { $menu->addDevelopmentItem('LanguagesManager_TranslationSearch', array('module' => 'LanguagesManager', 'action' => 'searchTranslation')); } }
private function enableDevelopmentLanguageInDevEnvironment(&$languages) { if (!Development::isEnabled()) { $key = array_search(DevelopmentLoader::LANGUAGE_ID, $languages); if ($key) { unset($languages[$key]); } } }
/** * Initializes Profiling via XHProf. * See: https://github.com/piwik/piwik/blob/master/tests/README.xhprof.md */ public static function setupProfilerXHProf($mainRun = false, $setupDuringTracking = false) { if (!$setupDuringTracking && SettingsServer::isTrackerApiRequest()) { // do not profile Tracker return; } if (self::$isXhprofSetup) { return; } $xhProfPath = PIWIK_INCLUDE_PATH . '/vendor/facebook/xhprof/extension/modules/xhprof.so'; if (!file_exists($xhProfPath)) { throw new Exception("Cannot find xhprof, run 'composer install --dev' and build the extension."); } if (!function_exists('xhprof_enable')) { throw new Exception("Cannot find xhprof_enable, make sure to add 'extension={$xhProfPath}' to your php.ini."); } $outputDir = ini_get("xhprof.output_dir"); if (empty($outputDir)) { throw new Exception("The profiler output dir is not set. Add 'xhprof.output_dir=...' to your php.ini."); } if (!is_writable($outputDir)) { throw new Exception("The profiler output dir '" . ini_get("xhprof.output_dir") . "' should exist and be writable."); } if (!function_exists('xhprof_error')) { function xhprof_error($out) { echo substr($out, 0, 300) . '...'; } } $currentGitBranch = SettingsPiwik::getCurrentGitBranch(); $profilerNamespace = "piwik"; if ($currentGitBranch != 'master') { $profilerNamespace .= "-" . $currentGitBranch; } if ($mainRun) { self::setProfilingRunIds(array()); } xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); register_shutdown_function(function () use($profilerNamespace, $mainRun) { $xhprofData = xhprof_disable(); $xhprofRuns = new XHProfRuns_Default(); $runId = $xhprofRuns->save_run($xhprofData, $profilerNamespace); if (empty($runId)) { die('could not write profiler run'); } $runs = Profiler::getProfilingRunIds(); array_unshift($runs, $runId); if ($mainRun) { Profiler::aggregateXhprofRuns($runs, $profilerNamespace, $saveTo = $runId); $baseUrlStored = SettingsPiwik::getPiwikUrl(); $out = "\n\n"; $baseUrl = "http://" . @$_SERVER['HTTP_HOST'] . "/" . @$_SERVER['REQUEST_URI']; if (strlen($baseUrlStored) > strlen($baseUrl)) { $baseUrl = $baseUrlStored; } $baseUrl = $baseUrlStored . "vendor/facebook/xhprof/xhprof_html/?source={$profilerNamespace}&run={$runId}"; $out .= "Profiler report is available at:\n"; $out .= "<a href='{$baseUrl}'>{$baseUrl}</a>"; $out .= "\n\n"; if (Development::isEnabled()) { $out .= "WARNING: Development mode is enabled. Many runtime optimizations are not applied in development mode. "; $out .= "Unless you intend to profile Piwik in development mode, your profile may not be accurate."; $out .= "\n\n"; } echo $out; } else { Profiler::setProfilingRunIds($runs); } }); self::$isXhprofSetup = true; }
private function checkIsValidWidget(WidgetConfig $widget) { if (!$widget->getModule()) { Development::error('No module is defined for added widget having name "' . $widget->getName()); } if (!$widget->getAction()) { Development::error('No action is defined for added widget having name "' . $widget->getName()); } }
private function checkisValidCallable($module, $action) { if (!Development::isEnabled()) { return; } $prefix = 'Menu item added in ' . get_class($this) . ' will fail when being selected. '; if (!is_string($action)) { Development::error($prefix . 'No valid action is specified. Make sure the defined action that should be executed is a string.'); } $reportAction = lcfirst(substr($action, 4)); if (ReportsProvider::factory($module, $reportAction)) { return; } $controllerClass = '\\Piwik\\Plugins\\' . $module . '\\Controller'; if (!Development::methodExists($controllerClass, $action)) { Development::error($prefix . 'The defined action "' . $action . '" does not exist in ' . $controllerClass . '". Make sure to define such a method.'); } if (!Development::isCallableMethod($controllerClass, $action)) { Development::error($prefix . 'The defined action "' . $action . '" is not callable on "' . $controllerClass . '". Make sure the method is public.'); } }
public function configureAdminMenu(MenuAdmin $menu) { if (Development::isEnabled() && Piwik::isUserHasSomeAdminAccess()) { $menu->addDevelopmentItem('LanguagesManager_TranslationSearch', $this->urlForAction('searchTranslation')); } }
/** * Load translations for loaded plugins * * @param bool|string $language Optional language code */ public function loadPluginTranslations($language = false) { if (empty($language)) { $language = Translate::getLanguageToLoad(); } $cache = new CacheFile('tracker', 43200); // ttl=12hours $cacheKey = 'PluginTranslations'; if (!empty($language)) { $cacheKey .= '-' . trim($language); } if (!empty($this->loadedPlugins)) { // makes sure to create a translation in case loaded plugins change (ie Tests vs Tracker vs UI etc) $cacheKey .= '-' . md5(implode('', $this->getLoadedPluginsName())); } $translations = $cache->get($cacheKey); if (!empty($translations) && is_array($translations) && !Development::isEnabled()) { Translate::mergeTranslationArray($translations); return; } $translations = array(); $pluginNames = self::getAllPluginsNames(); foreach ($pluginNames as $pluginName) { if ($this->isPluginLoaded($pluginName) || $this->isPluginBundledWithCore($pluginName)) { $this->loadTranslation($pluginName, $language); if (isset($GLOBALS['Piwik_translations'][$pluginName])) { $translations[$pluginName] = $GLOBALS['Piwik_translations'][$pluginName]; } } } $cache->set($cacheKey, $translations); }
public function sendReport($idReport, $period = false, $date = false, $force = false) { Piwik::checkUserIsNotAnonymous(); $reports = $this->getReports($idSite = false, false, $idReport); $report = reset($reports); if ($report['period'] == 'never') { $report['period'] = 'day'; } if (!empty($period)) { $report['period'] = $period; } if (empty($date)) { $date = Date::now()->subPeriod(1, $report['period'])->toString(); } $language = \Piwik\Plugins\LanguagesManager\API::getInstance()->getLanguageForUser($report['login']); // generate report list($outputFilename, $prettyDate, $reportSubject, $reportTitle, $additionalFiles) = $this->generateReport($idReport, $date, $language, self::OUTPUT_SAVE_ON_DISK, $report['period']); if (!file_exists($outputFilename)) { throw new Exception("The report file wasn't found in {$outputFilename}"); } $contents = file_get_contents($outputFilename); if (empty($contents)) { Log::warning("Scheduled report file '%s' exists but is empty!", $outputFilename); } /** * Triggered when sending scheduled reports. * * Plugins that provide new scheduled report transport mediums should use this event to * send the scheduled report. * * @param string $reportType A string ID describing how the report is sent, eg, * `'sms'` or `'email'`. * @param array $report An array describing the scheduled report that is being * generated. * @param string $contents The contents of the scheduled report that was generated * and now should be sent. * @param string $filename The path to the file where the scheduled report has * been saved. * @param string $prettyDate A prettified date string for the data within the * scheduled report. * @param string $reportSubject A string describing what's in the scheduled * report. * @param string $reportTitle The scheduled report's given title (given by a Piwik user). * @param array $additionalFiles The list of additional files that should be * sent with this report. * @param \Piwik\Period $period The period for which the report has been generated. * @param boolean $force A report can only be sent once per period. Setting this to true * will force to send the report even if it has already been sent. */ Piwik::postEvent(self::SEND_REPORT_EVENT, array($report['type'], $report, $contents, $filename = basename($outputFilename), $prettyDate, $reportSubject, $reportTitle, $additionalFiles, \Piwik\Period\Factory::build($report['period'], $date), $force)); // Update flag in DB $now = Date::now()->getDatetime(); $this->getModel()->updateReport($report['idreport'], array('ts_last_sent' => $now)); if (!Development::isEnabled()) { @chmod($outputFilename, 0600); Filesystem::deleteFileIfExists($outputFilename); } }
public function isAvailable() { return PiwikDevelopment::isEnabled(); }
/** * See {@link AddSegmentByLabel}. * * @param DataTable $table */ public function filter($table) { if (empty($this->segments)) { $msg = 'AddSegmentByLabel is called without having any segments defined'; Development::error($msg); return; } if (count($this->segments) === 1) { $segment = reset($this->segments); foreach ($table->getRowsWithoutSummaryRow() as $key => $row) { $label = $row->getColumn('label'); if (!empty($label)) { $row->setMetadata('segment', $segment . '==' . urlencode($label)); } } } elseif (!empty($this->delimiter)) { $numSegments = count($this->segments); $conditionAnd = ';'; foreach ($table->getRowsWithoutSummaryRow() as $key => $row) { $label = $row->getColumn('label'); if (!empty($label)) { $parts = explode($this->delimiter, $label); if (count($parts) === $numSegments) { $filter = array(); foreach ($this->segments as $index => $segment) { if (!empty($segment)) { $filter[] = $segment . '==' . urlencode($parts[$index]); } } $row->setMetadata('segment', implode($conditionAnd, $filter)); } } } } else { $names = implode(', ', $this->segments); $msg = 'Multiple segments are given but no delimiter defined. Segments: ' . $names; Development::error($msg); } }
private function checkIsValidWidget($name, $method) { if (!Development::isEnabled()) { return; } if (empty($name)) { Development::error('No name is defined for added widget having method "' . $method . '" in ' . get_class($this)); } if (Development::isCallableMethod($this, $method)) { return; } $controllerClass = 'Piwik\\Plugins\\' . $this->getModule() . '\\Controller'; if (!Development::methodExists($this, $method) && !Development::methodExists($controllerClass, $method)) { Development::error('The added method "' . $method . '" neither exists in "' . get_class($this) . '" nor "' . $controllerClass . '". Make sure to define such a method.'); } $definedInClass = get_class($this); if (Development::methodExists($controllerClass, $method)) { if (Development::isCallableMethod($controllerClass, $method)) { return; } $definedInClass = $controllerClass; } Development::error('The method "' . $method . '" is not callable on "' . $definedInClass . '". Make sure the method is public.'); }
private function checkIsValidTask($objectOrClassName, $methodName) { Development::checkMethodIsCallable($objectOrClassName, $methodName, 'The registered task is not valid as the method'); }
public function configureAdminMenu(MenuAdmin $menu) { if (Development::isEnabled() && Piwik::isUserHasSomeAdminAccess()) { $menu->addDevelopmentItem('UI demo', $this->urlForAction('demo')); } }
/** * This method ensures that Piwik Platform cannot be running when using a NEWER database. */ private function throwIfPiwikVersionIsOlderThanDBSchema() { // When developing this situation happens often when switching branches if (Development::isEnabled()) { return; } $updater = new Updater(); $dbSchemaVersion = $updater->getCurrentComponentVersion('core'); $current = Version::VERSION; if (-1 === version_compare($current, $dbSchemaVersion)) { $messages = array(Piwik::translate('General_ExceptionDatabaseVersionNewerThanCodebase', array($current, $dbSchemaVersion)), Piwik::translate('General_ExceptionDatabaseVersionNewerThanCodebaseWait'), Piwik::translate('General_ExceptionContactSupportGeneric', array('', ''))); throw new DatabaseSchemaIsNewerThanCodebaseException(implode(" ", $messages)); } }
public function isEnabled() { return Development::isEnabled() && SettingsPiwik::isGitDeployment(); }
public function isEnabled() { return Development::isEnabled(); }
/** * See {@link add()}. Adds a new menu item to the development section of the admin menu. * @param string $menuName * @param array $url * @param int $order * @param bool|string $tooltip * @api * @since 2.5.0 */ public function addDevelopmentItem($menuName, $url, $order = 50, $tooltip = false) { if (Development::isEnabled()) { $this->addItem('CoreAdminHome_MenuDevelopment', $menuName, $url, $order, $tooltip); } }