public function __toString() { $sql = $this->sql; if (!Common::stringEndsWith($sql, ';')) { $sql .= ';'; } return $sql; }
private function buildUserSettingName($name, $userLogin = null) { if (empty($userLogin)) { $userLogin = Piwik::getCurrentUserLogin(); } // the asterisk tag is indeed important here and better than an underscore. Imagine a plugin has the settings // "api_password" and "api". A user having the login "_password" could otherwise under circumstances change the // setting for "api" although he is not allowed to. It is not so important at the moment because only alNum is // currently allowed as a name this might change in the future. $appendix = '#' . $userLogin . '#'; if (Common::stringEndsWith($name, $appendix)) { return $name; } return $name . $appendix; }
public function addViewDataTable(&$viewDataTable) { // Both are the same HtmlTable, just the Pivot one has some extra logic in case Pivot is used. // We don't want to use the same HtmlTable twice in the UI. Therefore we always need to remove one. if (Common::getRequestVar('pivotBy', '')) { $tableToRemove = 'Visualizations\\HtmlTable'; } else { $tableToRemove = 'HtmlTable\\PivotBy'; } foreach ($viewDataTable as $index => $table) { if (Common::stringEndsWith($table, $tableToRemove)) { unset($viewDataTable[$index]); } } }
protected function execute(InputInterface $input, OutputInterface $output) { $buildNumber = $input->getArgument('buildnumber'); $targetDir = PIWIK_INCLUDE_PATH . '/' . dirname($this->targetDir); $tmpDir = StaticContainer::get('path.tmp'); $this->validate($buildNumber, $targetDir, $tmpDir); if (Common::stringEndsWith($buildNumber, '.1')) { // eg make '14820.1' to '14820' to be backwards compatible $buildNumber = substr($buildNumber, 0, -2); } $filename = sprintf('system.%s.tar.bz2', $buildNumber); $urlBase = sprintf('http://builds-artifacts.piwik.org/piwik/piwik/%s', $filename); $tests = Http::sendHttpRequest($urlBase, $timeout = 120); $tarFile = $tmpDir . $filename; file_put_contents($tarFile, $tests); $tar = new Tar($tarFile, 'bz2'); $tar->extract($targetDir); $this->writeSuccessMessage($output, array('All processed system test results were copied to <comment>' . $this->targetDir . '</comment>', 'Compare them with the expected test results and commit them if needed.')); unlink($tarFile); }
/** * @param InputInterface $input * @param OutputInterface $output * @return string * @throws \RunTimeException */ private function getTestName(InputInterface $input, OutputInterface $output) { $testname = $input->getOption('testname'); $validate = function ($testname) { if (empty($testname)) { throw new \InvalidArgumentException('You have to enter a valid test name '); } return $testname; }; if (empty($testname)) { $dialog = $this->getHelperSet()->get('dialog'); $testname = $dialog->askAndValidate($output, 'Enter the name of the test: ', $validate); } else { $validate($testname); } if (!Common::stringEndsWith(strtolower($testname), 'test')) { $testname = $testname . 'Test'; } $testname = ucfirst($testname); return $testname; }
protected function concatenateAssets() { $mergedContent = ''; foreach ($this->getAssetCatalog()->getAssets() as $uiAsset) { $uiAsset->validateFile(); try { $path = $uiAsset->getAbsoluteLocation(); } catch (Exception $e) { $path = null; } if (!empty($path) && Common::stringEndsWith($path, '.css')) { // to fix #10173 $mergedContent .= "\n" . $this->getCssStatementForReplacement($path) . "\n"; $this->cssAssetsToReplace[] = $uiAsset; } else { $content = $this->processFileContent($uiAsset); $mergedContent .= $this->getFileSeparator() . $content; } } $this->mergedContent = $mergedContent; }
public function getTargets() { $targets = array(); if ($this->settings->trackToPiwik->getValue()) { $targets[] = array('url' => 'http://demo-anonymous.piwik.org/piwik.php', 'idSite' => 1, 'useAnonymization' => true); } $ownSiteId = $this->settings->ownPiwikSiteId->getValue(); if ($ownSiteId) { $piwikUrl = SettingsPiwik::getPiwikUrl(); if (!Common::stringEndsWith($piwikUrl, '/')) { $piwikUrl .= '/'; } $targets[] = array('url' => $piwikUrl . 'piwik.php', 'idSite' => (int) $ownSiteId, 'useAnonymization' => $this->settings->anonymizeSelfPiwik->getValue()); } $customUrl = $this->settings->customPiwikSiteUrl->getValue(); $customSiteId = $this->settings->customPiwikSiteId->getValue(); if ($customUrl && $customSiteId) { $targets[] = array('url' => $customUrl, 'idSite' => (int) $customSiteId, 'useAnonymization' => $this->settings->anonymizeCustomPiwik->getValue()); } return $targets; }
private static function getBestPathForLoadData() { try { $path = Db::fetchOne('SELECT @@secure_file_priv'); // was introduced in 5.0.38 } catch (Exception $e) { // we do not rethrow exception as an error is expected if MySQL is < 5.0.38 // in this case tableInsertBatch might still work } if (empty($path) || !@is_dir($path) || !@is_writable($path)) { $path = StaticContainer::get('path.tmp') . '/assets/'; } elseif (!Common::stringEndsWith($path, '/')) { $path .= '/'; } return $path; }
private function getCanonicalPathFromParsedUrl($urlParsed) { $path = '/'; if (isset($urlParsed['path'])) { $path = Common::mb_strtolower($urlParsed['path']); if (!Common::stringEndsWith($path, '/')) { $path .= '/'; } } return $path; }
/** * Checks whether any of the given URLs has the given host. If not, we will also check whether any URL uses a * subdomain of the given host. For instance if host is "example.com" and a URL is "http://www.example.com" we * consider this as valid and return true. The always trusted hosts such as "127.0.0.1" are considered valid as well. * * @param $host * @param $urls * @return bool */ public static function isHostInUrls($host, $urls) { if (empty($host)) { return false; } $host = Common::mb_strtolower($host); if (!empty($urls)) { foreach ($urls as $url) { if (Common::mb_strtolower($url) === $host) { return true; } $siteHost = self::getHostFromUrl($url); if ($siteHost === $host) { return true; } if (Common::stringEndsWith($siteHost, '.' . $host)) { // allow subdomains return true; } } } return in_array($host, self::$alwaysTrustedHosts); }
/** * @param string $format * @param array $request * @return ApiRenderer * @throws Exception */ public static function factory($format, $request) { $formatToCheck = '\\' . ucfirst(strtolower($format)); $rendererClassnames = Plugin\Manager::getInstance()->findMultipleComponents('Renderer', 'Piwik\\API\\ApiRenderer'); foreach ($rendererClassnames as $klassName) { if (Common::stringEndsWith($klassName, $formatToCheck)) { return new $klassName($request); } } $availableRenderers = array(); foreach ($rendererClassnames as $rendererClassname) { $availableRenderers[] = self::getFormatFromClass($rendererClassname); } $availableRenderers = implode(', ', $availableRenderers); @header('Content-Type: text/plain; charset=utf-8'); throw new Exception(Piwik::translate('General_ExceptionInvalidRendererFormat', array($format, $availableRenderers))); }
private function initPiwikHost($piwikUrl = false) { // If core:archive command run as a web cron, we use the current hostname+path if (empty($piwikUrl)) { if (!empty(self::$url)) { $piwikUrl = self::$url; } else { // example.org/piwik/ $piwikUrl = SettingsPiwik::getPiwikUrl(); } } if (!$piwikUrl) { $this->logFatalErrorUrlExpected(); } if (!\Piwik\UrlHelper::isLookLikeUrl($piwikUrl)) { // try adding http:// in case it's missing $piwikUrl = "http://" . $piwikUrl; } if (!\Piwik\UrlHelper::isLookLikeUrl($piwikUrl)) { $this->logFatalErrorUrlExpected(); } // ensure there is a trailing slash if ($piwikUrl[strlen($piwikUrl) - 1] != '/' && !Common::stringEndsWith($piwikUrl, 'index.php')) { $piwikUrl .= '/'; } $this->initConfigObject($piwikUrl); if (Config::getInstance()->General['force_ssl'] == 1) { $piwikUrl = str_replace('http://', 'https://', $piwikUrl); } if (!Common::stringEndsWith($piwikUrl, 'index.php')) { $piwikUrl .= 'index.php'; } $this->piwikUrl = $piwikUrl; }
protected function checkAndUpdateRequiredPiwikVersion($pluginName, OutputInterface $output) { $pluginJsonPath = $this->getPluginPath($pluginName) . '/plugin.json'; $relativePluginJson = $this->getRelativePluginPath($pluginName) . '/plugin.json'; if (!file_exists($pluginJsonPath) || !is_writable($pluginJsonPath)) { return; } $pluginJson = file_get_contents($pluginJsonPath); $pluginJson = json_decode($pluginJson, true); if (empty($pluginJson)) { return; } if (empty($pluginJson['require'])) { $pluginJson['require'] = array(); } $piwikVersion = Version::VERSION; $nextMajorVersion = (int) substr($piwikVersion, 0, strpos($piwikVersion, '.')) + 1; $secondPartPiwikVersionRequire = ',<' . $nextMajorVersion . '.0.0-b1'; if (false === strpos($piwikVersion, '-')) { // see https://github.com/composer/composer/issues/4080 we need to specify -stable otherwise it would match // $piwikVersion-dev meaning it would also match all pre-released. However, we only want to match a stable // release $piwikVersion .= '-stable'; } $newRequiredVersion = sprintf('>=%s,<%d.0.0', $piwikVersion, $nextMajorVersion); if (!empty($pluginJson['require']['piwik'])) { $requiredVersion = trim($pluginJson['require']['piwik']); if ($requiredVersion === $newRequiredVersion) { // there is nothing to updated return; } // our generated versions look like ">=2.25.4,<3.0.0-b1". // We only updated the Piwik version in the first part if the piwik version looks like that or if it has only // one piwik version defined. In all other cases, eg user uses || etc we do not update it as user has customized // the piwik version. foreach (['<>', '!=', '<=', '==', '^'] as $comparison) { if (strpos($requiredVersion, $comparison) === 0) { // user is using custom piwik version require, we do not overwrite anything. return; } } if (strpos($requiredVersion, '||') !== false || strpos($requiredVersion, ' ') !== false) { // user is using custom piwik version require, we do not overwrite anything. return; } $requiredPiwikVersions = explode(',', (string) $requiredVersion); $numRequiredPiwikVersions = count($requiredPiwikVersions); if ($numRequiredPiwikVersions > 2) { // user is using custom piwik version require, we do not overwrite anything. return; } if ($numRequiredPiwikVersions === 2 && !Common::stringEndsWith($requiredVersion, $secondPartPiwikVersionRequire)) { // user is using custom piwik version require, we do not overwrite anything return; } // if only one piwik version is defined we update it to make sure it does now specify an upper version limit $dependency = new Dependency(); $missingVersion = $dependency->getMissingVersions($piwikVersion, $requiredVersion); if (!empty($missingVersion)) { $msg = sprintf('We cannot generate this component as the plugin "%s" requires the Piwik version "%s" in the file "%s". Generating this component requires "%s". If you know your plugin is compatible with your Piwik version remove the required Piwik version in "%s" and try to execute this command again.', $pluginName, $requiredVersion, $relativePluginJson, $newRequiredVersion, $relativePluginJson); throw new \Exception($msg); } $output->writeln(''); $output->writeln(sprintf('<comment>We have updated the required Piwik version from "%s" to "%s" in "%s".</comment>', $requiredVersion, $newRequiredVersion, $relativePluginJson)); } else { $output->writeln(''); $output->writeln(sprintf('<comment>We have updated your "%s" to require the Piwik version "%s".</comment>', $relativePluginJson, $newRequiredVersion)); } $pluginJson['require']['piwik'] = $newRequiredVersion; file_put_contents($pluginJsonPath, $this->toJson($pluginJson)); }
private function createTrackToCustomSiteUrlSetting() { $this->customPiwikSiteUrl = new SystemSetting('customSiteUrl', 'Piwik Url'); $this->customPiwikSiteUrl->readableByCurrentUser = true; $this->customPiwikSiteUrl->uiControlType = static::CONTROL_TEXT; $this->customPiwikSiteUrl->uiControlAttributes = array('placeHolder' => 'eg. http://example.com/piwik'); $this->customPiwikSiteUrl->introduction = 'Send anonymize usage data to a custom Piwik'; $this->customPiwikSiteUrl->description = ''; $this->customPiwikSiteUrl->defaultValue = ''; $this->customPiwikSiteUrl->validate = function ($value, $setting) { if (empty($value)) { return; } if (!UrlHelper::isLookLikeUrl($value)) { throw new Exception("URL '{$value}' seems to be not a valid URL"); } // TODO should we check if URL exists and is valid?!? might not work if instance is not connected to internet }; $this->customPiwikSiteUrl->transform = function ($value) { if (empty($value)) { return ''; } if (!Common::stringEndsWith($value, '/piwik.php')) { if (!Common::stringEndsWith($value, '/')) { $value .= '/'; } $value .= 'piwik.php'; } return $value; }; $this->addSetting($this->customPiwikSiteUrl); }
private function createTrackToCustomSiteUrlSetting() { return $this->makeSetting('customSiteUrl', $default = '', FieldConfig::TYPE_STRING, function (FieldConfig $field) { $field->title = 'Piwik Url'; $field->uiControl = FieldConfig::UI_CONTROL_TEXT; $field->uiControlAttributes = array('placeHolder' => 'eg. http://example.com/piwik'); $field->introduction = 'Send anonymize usage data to a custom Piwik'; $field->description = ''; $field->validate = function ($value, $setting) { if (empty($value)) { return; } if (!UrlHelper::isLookLikeUrl($value)) { throw new Exception("URL '{$value}' seems to be not a valid URL"); } // TODO should we check if URL exists and is valid?!? might not work if instance is not connected to internet }; $field->transform = function ($value) { if (empty($value)) { return ''; } if (!Common::stringEndsWith($value, '/piwik.php')) { if (!Common::stringEndsWith($value, '/')) { $value .= '/'; } $value .= 'piwik.php'; } return $value; }; }); }