getPiwikUrl() 공개 정적인 메소드

Returns the URL to this Piwik instance, eg. **http://demo.piwik.org/** or **http://example.org/piwik/**.
public static getPiwikUrl ( ) : string
리턴 string
예제 #1
0
 protected function sendNotifications()
 {
     $latestVersion = $this->getLatestVersion();
     $host = SettingsPiwik::getPiwikUrl();
     $subject = Piwik::translate('CoreUpdater_NotificationSubjectAvailableCoreUpdate', $latestVersion);
     $message = Piwik::translate('ScheduledReports_EmailHello');
     $message .= "\n\n";
     $message .= Piwik::translate('CoreUpdater_ThereIsNewVersionAvailableForUpdate');
     $message .= "\n\n";
     $message .= Piwik::translate('CoreUpdater_YouCanUpgradeAutomaticallyOrDownloadPackage', $latestVersion);
     $message .= "\n";
     $message .= $host . 'index.php?module=CoreUpdater&action=newVersionAvailable';
     $message .= "\n\n";
     $version = new Version();
     if ($version->isStableVersion($latestVersion)) {
         $message .= Piwik::translate('CoreUpdater_ViewVersionChangelog');
         $message .= "\n";
         $message .= $this->getLinkToChangeLog($latestVersion);
         $message .= "\n\n";
     }
     $message .= Piwik::translate('CoreUpdater_FeedbackRequest');
     $message .= "\n";
     $message .= 'http://piwik.org/contact/';
     $this->sendEmailNotification($subject, $message);
 }
예제 #2
0
파일: Rss.php 프로젝트: diosmosis/piwik
 /**
  * Computes the output for the given data table
  *
  * @param DataTable $table
  * @return string
  * @throws Exception
  */
 protected function renderTable($table)
 {
     if (!$table instanceof DataTable\Map || $table->getKeyName() != 'date') {
         throw new Exception("RSS feeds can be generated for one specific website &idSite=X." . "\nPlease specify only one idSite or consider using &format=XML instead.");
     }
     $idSite = Common::getRequestVar('idSite', 1, 'int');
     $period = Common::getRequestVar('period');
     $piwikUrl = SettingsPiwik::getPiwikUrl() . "?module=CoreHome&action=index&idSite=" . $idSite . "&period=" . $period;
     $out = "";
     $moreRecentFirst = array_reverse($table->getDataTables(), true);
     foreach ($moreRecentFirst as $date => $subtable) {
         /** @var DataTable $subtable */
         $timestamp = $subtable->getMetadata(Archive\DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getDateStart()->getTimestamp();
         $site = $subtable->getMetadata(Archive\DataTableFactory::TABLE_METADATA_SITE_INDEX);
         $pudDate = date('r', $timestamp);
         $dateInSiteTimezone = Date::factory($timestamp);
         if ($site) {
             $dateInSiteTimezone = $dateInSiteTimezone->setTimezone($site->getTimezone());
         }
         $dateInSiteTimezone = $dateInSiteTimezone->toString('Y-m-d');
         $thisPiwikUrl = Common::sanitizeInputValue($piwikUrl . "&date={$dateInSiteTimezone}");
         $siteName = $site ? $site->getName() : '';
         $title = $siteName . " on " . $date;
         $out .= "\t<item>\n\t\t<pubDate>{$pudDate}</pubDate>\n\t\t<guid>{$thisPiwikUrl}</guid>\n\t\t<link>{$thisPiwikUrl}</link>\n\t\t<title>{$title}</title>\n\t\t<author>http://piwik.org</author>\n\t\t<description>";
         $out .= Common::sanitizeInputValue($this->renderDataTable($subtable));
         $out .= "</description>\n\t</item>\n";
     }
     $header = $this->getRssHeader();
     $footer = $this->getRssFooter();
     return $header . $out . $footer;
 }
예제 #3
0
파일: API.php 프로젝트: a4tunado/piwik
 /**
  * Returns the javascript tag for the given idSite.
  * This tag must be included on every page to be tracked by Piwik
  *
  * @param int $idSite
  * @param string $piwikUrl
  * @param bool $mergeSubdomains
  * @param bool $groupPageTitlesByDomain
  * @param bool $mergeAliasUrls
  * @param bool $visitorCustomVariables
  * @param bool $pageCustomVariables
  * @param bool $customCampaignNameQueryParam
  * @param bool $customCampaignKeywordParam
  * @param bool $doNotTrack
  * @param bool $disableCookies
  * @return string The Javascript tag ready to be included on the HTML pages
  */
 public function getJavascriptTag($idSite, $piwikUrl = '', $mergeSubdomains = false, $groupPageTitlesByDomain = false, $mergeAliasUrls = false, $visitorCustomVariables = false, $pageCustomVariables = false, $customCampaignNameQueryParam = false, $customCampaignKeywordParam = false, $doNotTrack = false, $disableCookies = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     if (empty($piwikUrl)) {
         $piwikUrl = SettingsPiwik::getPiwikUrl();
     }
     $piwikUrl = Common::sanitizeInputValues($piwikUrl);
     $htmlEncoded = Piwik::getJavascriptCode($idSite, $piwikUrl, $mergeSubdomains, $groupPageTitlesByDomain, $mergeAliasUrls, $visitorCustomVariables, $pageCustomVariables, $customCampaignNameQueryParam, $customCampaignKeywordParam, $doNotTrack, $disableCookies);
     $htmlEncoded = str_replace(array('<br>', '<br />', '<br/>'), '', $htmlEncoded);
     return $htmlEncoded;
 }
예제 #4
0
 /**
  * Sets the sender.
  *
  * @param string $email Email address of the sender.
  * @param null|string $name Name of the sender.
  * @return Zend_Mail
  */
 public function setFrom($email, $name = null)
 {
     $hostname = Config::getInstance()->mail['defaultHostnameIfEmpty'];
     $piwikHost = Url::getCurrentHost($hostname);
     // If known Piwik URL, use it instead of "localhost"
     $piwikUrl = SettingsPiwik::getPiwikUrl();
     $url = parse_url($piwikUrl);
     if (isset($url['host']) && $url['host'] != 'localhost' && $url['host'] != '127.0.0.1') {
         $piwikHost = $url['host'];
     }
     $email = str_replace('{DOMAIN}', $piwikHost, $email);
     return parent::setFrom($email, $name);
 }
예제 #5
0
 protected function getPathToLogo($pathOnly, $defaultLogo, $themeLogo, $customLogo)
 {
     $pathToPiwikRoot = Filesystem::getPathToPiwikRoot();
     $logo = $defaultLogo;
     $themeName = \Piwik\Plugin\Manager::getInstance()->getThemeEnabled()->getPluginName();
     $themeLogo = sprintf($themeLogo, $themeName);
     if (file_exists($pathToPiwikRoot . '/' . $themeLogo)) {
         $logo = $themeLogo;
     }
     if (Config::getInstance()->branding['use_custom_logo'] == 1 && file_exists($pathToPiwikRoot . '/' . $customLogo)) {
         $logo = $customLogo;
     }
     if (!$pathOnly) {
         return SettingsPiwik::getPiwikUrl() . $logo;
     }
     return $pathToPiwikRoot . '/' . $logo;
 }
예제 #6
0
 /**
  * @internal For Debugging only
  * Call metadata reports and draw the default graph for each report.
  */
 public function index()
 {
     Piwik::checkUserHasSomeAdminAccess();
     $idSite = Common::getRequestVar('idSite', 1, 'int');
     $period = Common::getRequestVar('period', 'day', 'string');
     $date = Common::getRequestVar('date', 'today', 'string');
     $_GET['token_auth'] = Piwik::getCurrentUserTokenAuth();
     $reports = APIPlugins::getInstance()->getReportMetadata($idSite, $period, $date);
     $plot = array();
     foreach ($reports as $report) {
         if (!empty($report['imageGraphUrl'])) {
             $plot[] = array($report['category'] . ' › ' . $report['name'], SettingsPiwik::getPiwikUrl() . $report['imageGraphUrl']);
         }
     }
     $view = new View('@ImageGraph/index');
     $view->titleAndUrls = $plot;
     return $view->render();
 }
예제 #7
0
 /**
  * Returns the javascript tag for the given idSite.
  * This tag must be included on every page to be tracked by Piwik
  *
  * @param int $idSite
  * @param string $piwikUrl
  * @param bool $mergeSubdomains
  * @param bool $groupPageTitlesByDomain
  * @param bool $mergeAliasUrls
  * @param bool $visitorCustomVariables
  * @param bool $pageCustomVariables
  * @param bool $customCampaignNameQueryParam
  * @param bool $customCampaignKeywordParam
  * @param bool $doNotTrack
  * @param bool $disableCookies
  * @return string The Javascript tag ready to be included on the HTML pages
  */
 public function getJavascriptTag($idSite, $piwikUrl = '', $mergeSubdomains = false, $groupPageTitlesByDomain = false, $mergeAliasUrls = false, $visitorCustomVariables = false, $pageCustomVariables = false, $customCampaignNameQueryParam = false, $customCampaignKeywordParam = false, $doNotTrack = false, $disableCookies = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     if (empty($piwikUrl)) {
         $piwikUrl = SettingsPiwik::getPiwikUrl();
     }
     // Revert the automatic encoding
     // TODO remove that when https://github.com/piwik/piwik/issues/4231 is fixed
     $piwikUrl = Common::unsanitizeInputValue($piwikUrl);
     $visitorCustomVariables = Common::unsanitizeInputValues($visitorCustomVariables);
     $pageCustomVariables = Common::unsanitizeInputValues($pageCustomVariables);
     $customCampaignNameQueryParam = Common::unsanitizeInputValue($customCampaignNameQueryParam);
     $customCampaignKeywordParam = Common::unsanitizeInputValue($customCampaignKeywordParam);
     $generator = new TrackerCodeGenerator();
     $code = $generator->generate($idSite, $piwikUrl, $mergeSubdomains, $groupPageTitlesByDomain, $mergeAliasUrls, $visitorCustomVariables, $pageCustomVariables, $customCampaignNameQueryParam, $customCampaignKeywordParam, $doNotTrack, $disableCookies);
     $code = str_replace(array('<br>', '<br />', '<br/>'), '', $code);
     return $code;
 }
예제 #8
0
function prepareServerVariables(Config $config)
{
    $testConfig = $config->tests;
    if ('@REQUEST_URI@' === $testConfig['request_uri']) {
        // config not done yet, if Piwik is installed we can automatically configure request_uri and http_host
        $url = \Piwik\SettingsPiwik::getPiwikUrl();
        if (!empty($url)) {
            $parsedUrl = parse_url($url);
            $testConfig['request_uri'] = $parsedUrl['path'];
            $testConfig['http_host'] = $parsedUrl['host'];
            $config->tests = $testConfig;
            $config->forceSave();
        }
    }
    $_SERVER['HTTP_HOST'] = $testConfig['http_host'];
    $_SERVER['REQUEST_URI'] = $testConfig['request_uri'];
    $_SERVER['REMOTE_ADDR'] = $testConfig['remote_addr'];
}
 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;
 }
예제 #10
0
 /**
  * Tracker requests will automatically trigger the Scheduled tasks.
  * This is useful for users who don't setup the cron,
  * but still want daily/weekly/monthly PDF reports emailed automatically.
  *
  * This is similar to calling the API CoreAdminHome.runScheduledTasks
  */
 public function runScheduledTasks()
 {
     $now = time();
     // Currently, there are no hourly tasks. When there are some,
     // this could be too aggressive minimum interval (some hours would be skipped in case of low traffic)
     $minimumInterval = TrackerConfig::getConfigValue('scheduled_tasks_min_interval');
     // If the user disabled browser archiving, he has already setup a cron
     // To avoid parallel requests triggering the Scheduled Tasks,
     // Get last time tasks started executing
     $cache = Cache::getCacheGeneral();
     if ($minimumInterval <= 0 || empty($cache['isBrowserTriggerEnabled'])) {
         Common::printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled.");
         return;
     }
     $nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval;
     if (defined('DEBUG_FORCE_SCHEDULED_TASKS') && DEBUG_FORCE_SCHEDULED_TASKS || $cache['lastTrackerCronRun'] === false || $nextRunTime < $now) {
         $cache['lastTrackerCronRun'] = $now;
         Cache::setCacheGeneral($cache);
         Tracker::initCorePiwikInTrackerMode();
         Option::set('lastTrackerCronRun', $cache['lastTrackerCronRun']);
         Common::printDebug('-> Scheduled Tasks: Starting...');
         // save current user privilege and temporarily assume Super User privilege
         $isSuperUser = Piwik::hasUserSuperUserAccess();
         // Scheduled tasks assume Super User is running
         Piwik::setUserHasSuperUserAccess();
         $tokens = CronArchive::getSuperUserTokenAuths();
         $tokenAuth = reset($tokens);
         $invokeScheduledTasksUrl = SettingsPiwik::getPiwikUrl() . "?module=API&format=csv&convertToUnicode=0&method=CoreAdminHome.runScheduledTasks&trigger=archivephp&token_auth={$tokenAuth}";
         $cliMulti = new CliMulti();
         $responses = $cliMulti->request(array($invokeScheduledTasksUrl));
         $resultTasks = reset($responses);
         // restore original user privilege
         Piwik::setUserHasSuperUserAccess($isSuperUser);
         Common::printDebug($resultTasks);
         Common::printDebug('Finished Scheduled Tasks.');
     } else {
         Common::printDebug("-> Scheduled tasks not triggered.");
     }
     Common::printDebug("Next run will be from: " . date('Y-m-d H:i:s', $nextRunTime) . ' UTC');
 }
 /**
  * Must be called before dispatch()
  * - checks that directories are writable,
  * - loads the configuration file,
  * - loads the plugin,
  * - inits the DB connection,
  * - etc.
  *
  * @throws Exception
  * @return void
  */
 public function init()
 {
     static $initialized = false;
     if ($initialized) {
         return;
     }
     $initialized = true;
     $tmpPath = StaticContainer::get('path.tmp');
     $directoriesToCheck = array($tmpPath, $tmpPath . '/assets/', $tmpPath . '/cache/', $tmpPath . '/logs/', $tmpPath . '/tcpdf/', $tmpPath . '/templates_c/');
     Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);
     $this->handleMaintenanceMode();
     $this->handleProfiler();
     $this->handleSSLRedirection();
     Plugin\Manager::getInstance()->loadPluginTranslations();
     Plugin\Manager::getInstance()->loadActivatedPlugins();
     // try to connect to the database
     try {
         Db::createDatabaseObject();
         Db::fetchAll("SELECT DATABASE()");
     } catch (Exception $exception) {
         if (self::shouldRethrowException()) {
             throw $exception;
         }
         Log::debug($exception);
         /**
          * Triggered when Piwik cannot connect to the database.
          *
          * This event can be used to start the installation process or to display a custom error
          * message.
          *
          * @param Exception $exception The exception thrown from creating and testing the database
          *                             connection.
          */
         Piwik::postEvent('Db.cannotConnectToDb', array($exception), $pending = true);
         throw $exception;
     }
     // try to get an option (to check if data can be queried)
     try {
         Option::get('TestingIfDatabaseConnectionWorked');
     } catch (Exception $exception) {
         if (self::shouldRethrowException()) {
             throw $exception;
         }
         Log::debug($exception);
         /**
          * Triggered when Piwik cannot access database data.
          *
          * This event can be used to start the installation process or to display a custom error
          * message.
          *
          * @param Exception $exception The exception thrown from trying to get an option value.
          */
         Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true);
         throw $exception;
     }
     // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs
     Access::getInstance();
     /**
      * Triggered just after the platform is initialized and plugins are loaded.
      *
      * This event can be used to do early initialization.
      *
      * _Note: At this point the user is not authenticated yet._
      */
     Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen');
     $this->throwIfPiwikVersionIsOlderThanDBSchema();
     \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
     // ensure the current Piwik URL is known for later use
     if (method_exists('Piwik\\SettingsPiwik', 'getPiwikUrl')) {
         SettingsPiwik::getPiwikUrl();
     }
     /**
      * Triggered before the user is authenticated, when the global authentication object
      * should be created.
      *
      * Plugins that provide their own authentication implementation should use this event
      * to set the global authentication object (which must derive from {@link Piwik\Auth}).
      *
      * **Example**
      *
      *     Piwik::addAction('Request.initAuthenticationObject', function() {
      *         StaticContainer::getContainer()->set('Piwik\Auth', new MyAuthImplementation());
      *     });
      */
     Piwik::postEvent('Request.initAuthenticationObject');
     try {
         $authAdapter = StaticContainer::get('Piwik\\Auth');
     } catch (Exception $e) {
         $message = "Authentication object cannot be found in the container. Maybe the Login plugin is not activated?\n                        <br />You can activate the plugin by adding:<br />\n                        <code>Plugins[] = Login</code><br />\n                        under the <code>[Plugins]</code> section in your config/config.ini.php";
         $ex = new AuthenticationFailedException($message);
         $ex->setIsHtmlMessage();
         throw $ex;
     }
     Access::getInstance()->reloadAccess($authAdapter);
     // Force the auth to use the token_auth if specified, so that embed dashboard
     // and all other non widgetized controller methods works fine
     if (Common::getRequestVar('token_auth', false, 'string') !== false) {
         Request::reloadAuthUsingTokenAuth();
     }
     SettingsServer::raiseMemoryLimitIfNecessary();
     \Piwik\Plugin\Manager::getInstance()->postLoadPlugins();
     /**
      * Triggered after the platform is initialized and after the user has been authenticated, but
      * before the platform has handled the request.
      *
      * Piwik uses this event to check for updates to Piwik.
      */
     Piwik::postEvent('Platform.initialized');
 }
예제 #12
0
파일: View.php 프로젝트: diosmosis/piwik
 /**
  * Constructor.
  *
  * @param string $templateFile The template file to load. Must be in the following format:
  *                             `"@MyPlugin/templateFileName"`. Note the absence of .twig
  *                             from the end of the name.
  */
 public function __construct($templateFile)
 {
     $templateExt = '.twig';
     if (substr($templateFile, -strlen($templateExt)) !== $templateExt) {
         $templateFile .= $templateExt;
     }
     $this->template = $templateFile;
     $this->initializeTwig();
     $this->piwik_version = Version::VERSION;
     $this->userLogin = Piwik::getCurrentUserLogin();
     $this->isSuperUser = Access::getInstance()->hasSuperUserAccess();
     try {
         $this->piwikUrl = SettingsPiwik::getPiwikUrl();
     } catch (Exception $ex) {
         // pass (occurs when DB cannot be connected to, perhaps piwik URL cache should be stored in config file...)
     }
 }
예제 #13
0
 /**
  * Displays the admin UI page showing all tracking tags
  * @return string
  */
 function displayJavascriptCode()
 {
     $idSite = Common::getRequestVar('idSite');
     Piwik::checkUserHasViewAccess($idSite);
     $javascriptGenerator = new TrackerCodeGenerator();
     $jsTag = $javascriptGenerator->generate($idSite, SettingsPiwik::getPiwikUrl());
     $site = new Site($idSite);
     return $this->renderTemplate('displayJavascriptCode', array('idSite' => $idSite, 'displaySiteName' => $site->getName(), 'jsTag' => $jsTag));
 }
예제 #14
0
 protected function sendNotifications($pluginsToBeNotified)
 {
     $hasThemeUpdate = false;
     $hasPluginUpdate = false;
     foreach ($pluginsToBeNotified as $plugin) {
         $hasThemeUpdate = $hasThemeUpdate || $plugin['isTheme'];
         $hasPluginUpdate = $hasPluginUpdate || !$plugin['isTheme'];
     }
     $subject = Piwik::translate('CoreUpdater_NotificationSubjectAvailablePluginUpdate');
     $message = Piwik::translate('ScheduledReports_EmailHello');
     $message .= "\n\n";
     $message .= Piwik::translate('CoreUpdater_ThereIsNewPluginVersionAvailableForUpdate');
     $message .= "\n\n";
     foreach ($pluginsToBeNotified as $plugin) {
         $message .= sprintf(' * %s %s', $plugin['name'], $plugin['latestVersion']);
         $message .= "\n";
     }
     $message .= "\n";
     $host = SettingsPiwik::getPiwikUrl();
     if ($hasThemeUpdate) {
         $message .= Piwik::translate('CoreUpdater_NotificationClickToUpdateThemes') . "\n";
         $message .= $host . 'index.php?module=CorePluginsAdmin&action=themes';
     }
     if ($hasPluginUpdate) {
         if ($hasThemeUpdate) {
             $message .= "\n\n";
         }
         $message .= Piwik::translate('CoreUpdater_NotificationClickToUpdatePlugins') . "\n";
         $message .= $host . 'index.php?module=CorePluginsAdmin&action=plugins';
     }
     $message .= "\n\n";
     $message .= Piwik::translate('Installation_HappyAnalysing');
     $this->sendEmailNotification($subject, $message);
 }
예제 #15
0
 public function sendReport($reportType, $report, $contents, $filename, $prettyDate, $reportSubject, $reportTitle, $additionalFiles, Period $period = null, $force)
 {
     if (!self::manageEvent($reportType)) {
         return;
     }
     // Safeguard against sending the same report twice to the same email (unless $force is true)
     if (!$force && $this->reportAlreadySent($report, $period)) {
         Log::warning('Preventing the same scheduled report from being sent again (report #%s for period "%s")', $report['idreport'], $prettyDate);
         return;
     }
     $periods = self::getPeriodToFrequencyAsAdjective();
     $message = Piwik::translate('ScheduledReports_EmailHello');
     $subject = Piwik::translate('General_Report') . ' ' . $reportTitle . " - " . $prettyDate;
     $mail = new Mail();
     $mail->setDefaultFromPiwik();
     $mail->setSubject($subject);
     $attachmentName = $subject;
     $this->setReplyToAsSender($mail, $report);
     $displaySegmentInfo = false;
     $segmentInfo = null;
     $segment = API::getSegment($report['idsegment']);
     if ($segment != null) {
         $displaySegmentInfo = true;
         $segmentInfo = Piwik::translate('ScheduledReports_SegmentAppliedToReports', $segment['name']);
     }
     $messageFindAttached = Piwik::translate('ScheduledReports_PleaseFindAttachedFile', array($periods[$report['period']], $reportTitle));
     $messageFindBelow = Piwik::translate('ScheduledReports_PleaseFindBelow', array($periods[$report['period']], $reportTitle));
     $messageSentFrom = '';
     $piwikUrl = SettingsPiwik::getPiwikUrl();
     if (!empty($piwikUrl)) {
         $messageSentFrom = Piwik::translate('ScheduledReports_SentFromX', $piwikUrl);
     }
     switch ($report['format']) {
         case 'html':
             // Needed when using images as attachment with cid
             $mail->setType(Zend_Mime::MULTIPART_RELATED);
             $message .= "<br/>{$messageFindBelow}<br/>{$messageSentFrom}";
             if ($displaySegmentInfo) {
                 $message .= " " . $segmentInfo;
             }
             $mail->setBodyHtml($message . "<br/><br/>" . $contents);
             break;
         case 'csv':
             $message .= "\n{$messageFindAttached}\n{$messageSentFrom}";
             if ($displaySegmentInfo) {
                 $message .= " " . $segmentInfo;
             }
             $mail->setBodyText($message);
             $mail->createAttachment($contents, 'application/csv', Zend_Mime::DISPOSITION_INLINE, Zend_Mime::ENCODING_BASE64, $attachmentName . '.csv');
             break;
         default:
         case 'pdf':
             $message .= "\n{$messageFindAttached}\n{$messageSentFrom}";
             if ($displaySegmentInfo) {
                 $message .= " " . $segmentInfo;
             }
             $mail->setBodyText($message);
             $mail->createAttachment($contents, 'application/pdf', Zend_Mime::DISPOSITION_INLINE, Zend_Mime::ENCODING_BASE64, $attachmentName . '.pdf');
             break;
     }
     foreach ($additionalFiles as $additionalFile) {
         $fileContent = $additionalFile['content'];
         $at = $mail->createAttachment($fileContent, $additionalFile['mimeType'], Zend_Mime::DISPOSITION_INLINE, $additionalFile['encoding'], $additionalFile['filename']);
         $at->id = $additionalFile['cid'];
         unset($fileContent);
     }
     // Get user emails and languages
     $reportParameters = $report['parameters'];
     $emails = array();
     if (isset($reportParameters[self::ADDITIONAL_EMAILS_PARAMETER])) {
         $emails = $reportParameters[self::ADDITIONAL_EMAILS_PARAMETER];
     }
     if ($reportParameters[self::EMAIL_ME_PARAMETER] == 1) {
         if (Piwik::getCurrentUserLogin() == $report['login']) {
             $emails[] = Piwik::getCurrentUserEmail();
         } else {
             try {
                 $user = APIUsersManager::getInstance()->getUser($report['login']);
             } catch (Exception $e) {
                 return;
             }
             $emails[] = $user['email'];
         }
     }
     if (!$force) {
         $this->markReportAsSent($report, $period);
     }
     foreach ($emails as $email) {
         if (empty($email)) {
             continue;
         }
         $mail->addTo($email);
         try {
             $mail->send();
         } catch (Exception $e) {
             // If running from piwik.php with debug, we ignore the 'email not sent' error
             $tracker = new Tracker();
             if (!$tracker->isDebugModeEnabled()) {
                 throw new Exception("An error occured while sending '{$filename}' " . " to " . implode(', ', $mail->getRecipients()) . ". Error was '" . $e->getMessage() . "'");
             }
         }
         $mail->clearRecipients();
     }
 }
    public function test_formatAlerts_asHtml()
    {
        $alerts = $this->getTriggeredAlerts();
        $host = SettingsPiwik::getPiwikUrl();
        $rendered = $this->controller->formatAlerts($alerts, 'html');
        $expected = <<<FORMATTED
<table style="border-collapse: collapse;width:100%" class="tableForm dataTable entityTable">
    <thead style="background-color:rgb(228,226,215);color:rgb(37,87,146);">
    <tr>
        <th style="padding:6px 6px;text-align: left;">Alert Name</th>
                <th style="padding:6px 6px;text-align: left;">Report</th>
        <th style="padding:6px 6px;text-align: left;">Alert Condition</th>
        <th style="padding:6px 6px;text-align: left;">Alert</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;"><a href="{$host}index.php?module=CustomAlerts&action=editAlert&idAlert=1&idSite=1&period=week&date=yesterday">MyName1</a></td>
                <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;">Single Website dashboard</td>
        <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;">Website is 'Piwik'</td>
        <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;">Visits decreased more than 5000 from 228.128 to 4493</td>
    </tr>

    <tr>
        <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;"><a href="{$host}index.php?module=CustomAlerts&action=editAlert&idAlert=2&idSite=1&period=week&date=yesterday">MyName2</a></td>
                <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;">Single Website dashboard</td>
        <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;">Website is 'Piwik'</td>
        <td style="max-width:300px;border-bottom:1px solid rgb(231,231,231);padding:5px 0 5px 6px;">Visits decreased more than 5000 from 228.128 to 4493</td>
    </tr>

    </tbody>
</table>
FORMATTED;
        $this->assertEquals($expected, $rendered);
    }
예제 #17
0
 /**
  * Displays the admin UI page showing all tracking tags
  * @return string
  */
 function displayJavascriptCode()
 {
     $idSite = Common::getRequestVar('idSite');
     Piwik::checkUserHasViewAccess($idSite);
     $jsTag = Piwik::getJavascriptCode($idSite, SettingsPiwik::getPiwikUrl());
     $view = new View('@SitesManager/displayJavascriptCode');
     $this->setBasicVariablesView($view);
     $view->idSite = $idSite;
     $site = new Site($idSite);
     $view->displaySiteName = $site->getName();
     $view->jsTag = $jsTag;
     return $view->render();
 }
예제 #18
0
 private function assignCommonParameters(View $view)
 {
     $view->assign("reportFontFamily", ReportRenderer::DEFAULT_REPORT_FONT_FAMILY);
     $view->assign("reportTitleTextColor", ReportRenderer::REPORT_TITLE_TEXT_COLOR);
     $view->assign("reportTitleTextSize", self::REPORT_TITLE_TEXT_SIZE);
     $view->assign("reportTextColor", ReportRenderer::REPORT_TEXT_COLOR);
     $view->assign("tableHeaderBgColor", ReportRenderer::TABLE_HEADER_BG_COLOR);
     $view->assign("tableHeaderTextColor", ReportRenderer::TABLE_HEADER_TEXT_COLOR);
     $view->assign("tableCellBorderColor", ReportRenderer::TABLE_CELL_BORDER_COLOR);
     $view->assign("tableBgColor", ReportRenderer::TABLE_BG_COLOR);
     $view->assign("reportTableHeaderTextWeight", self::TABLE_HEADER_TEXT_WEIGHT);
     $view->assign("reportTableHeaderTextSize", self::REPORT_TABLE_HEADER_TEXT_SIZE);
     $view->assign("reportTableHeaderTextTransform", ReportRenderer::TABLE_HEADER_TEXT_TRANSFORM);
     $view->assign("reportTableRowTextSize", self::REPORT_TABLE_ROW_TEXT_SIZE);
     $view->assign("reportBackToTopTextSize", self::REPORT_BACK_TO_TOP_TEXT_SIZE);
     $view->assign("currentPath", SettingsPiwik::getPiwikUrl());
     $view->assign("logoHeader", API::getInstance()->getHeaderLogoUrl());
 }
예제 #19
0
 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;
 }
예제 #20
0
 /**
  * Must be called before dispatch()
  * - checks that directories are writable,
  * - loads the configuration file,
  * - loads the plugin,
  * - inits the DB connection,
  * - etc.
  *
  * @throws Exception
  * @return void
  */
 public function init()
 {
     static $initialized = false;
     if ($initialized) {
         return;
     }
     $initialized = true;
     try {
         Registry::set('timer', new Timer());
         $directoriesToCheck = array('/tmp/', '/tmp/assets/', '/tmp/cache/', '/tmp/logs/', '/tmp/tcpdf/', '/tmp/templates_c/');
         Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);
         self::assignCliParametersToRequest();
         Translate::loadEnglishTranslation();
         $exceptionToThrow = self::createConfigObject();
         if (Session::isFileBasedSessions()) {
             Session::start();
         }
         $this->handleMaintenanceMode();
         $this->handleSSLRedirection();
         $this->handleProfiler();
         $pluginsManager = \Piwik\Plugin\Manager::getInstance();
         $pluginsToLoad = Config::getInstance()->Plugins['Plugins'];
         $pluginsManager->loadPlugins($pluginsToLoad);
         if ($exceptionToThrow) {
             throw $exceptionToThrow;
         }
         try {
             Db::createDatabaseObject();
             Option::get('TestingIfDatabaseConnectionWorked');
         } catch (Exception $exception) {
             if (self::shouldRethrowException()) {
                 throw $exception;
             }
             /**
              * Triggered if the INI config file has the incorrect format or if certain required configuration
              * options are absent.
              * 
              * This event can be used to start the installation process or to display a custom error message.
              * 
              * @param Exception $exception The exception thrown from creating and testing the database
              *                             connection.
              */
             Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true);
             throw $exception;
         }
         // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs
         Access::getInstance();
         /**
          * Triggered just after the platform is initialized and plugins are loaded.
          * 
          * This event can be used to do early initialization.
          * 
          * _Note: At this point the user is not authenticated yet._
          */
         Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen');
         \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
         // ensure the current Piwik URL is known for later use
         if (method_exists('Piwik\\SettingsPiwik', 'getPiwikUrl')) {
             $host = SettingsPiwik::getPiwikUrl();
         }
         /**
          * Triggered before the user is authenticated, when the global authentication object
          * should be created.
          * 
          * Plugins that provide their own authentication implementation should use this event
          * to set the global authentication object (which must derive from {@link Piwik\Auth}).
          * 
          * **Example**
          * 
          *     Piwik::addAction('Request.initAuthenticationObject', function() {
          *         Piwik\Registry::set('auth', new MyAuthImplementation());
          *     });
          */
         Piwik::postEvent('Request.initAuthenticationObject');
         try {
             $authAdapter = Registry::get('auth');
         } catch (Exception $e) {
             throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated?\n                                <br />You can activate the plugin by adding:<br />\n                                <code>Plugins[] = Login</code><br />\n                                under the <code>[Plugins]</code> section in your config/config.ini.php");
         }
         Access::getInstance()->reloadAccess($authAdapter);
         // Force the auth to use the token_auth if specified, so that embed dashboard
         // and all other non widgetized controller methods works fine
         if (($token_auth = Common::getRequestVar('token_auth', false, 'string')) !== false) {
             Request::reloadAuthUsingTokenAuth();
         }
         SettingsServer::raiseMemoryLimitIfNecessary();
         Translate::reloadLanguage();
         $pluginsManager->postLoadPlugins();
         /**
          * Triggered after the platform is initialized and after the user has been authenticated, but
          * before the platform has handled the request.
          * 
          * Piwik uses this event to check for updates to Piwik.
          */
         Piwik::postEvent('Updater.checkForUpdates');
     } catch (Exception $e) {
         if (self::shouldRethrowException()) {
             throw $e;
         }
         $debugTrace = $e->getTraceAsString();
         Piwik_ExitWithMessage($e->getMessage(), $debugTrace, true);
     }
 }
예제 #21
0
파일: Mail.php 프로젝트: diosmosis/piwik
 /**
  * @param string $email
  * @return string
  */
 protected function parseDomainPlaceholderAsPiwikHostName($email)
 {
     $hostname = Config::getInstance()->mail['defaultHostnameIfEmpty'];
     $piwikHost = Url::getCurrentHost($hostname);
     // If known Piwik URL, use it instead of "localhost"
     $piwikUrl = SettingsPiwik::getPiwikUrl();
     $url = parse_url($piwikUrl);
     if ($this->isHostDefinedAndNotLocal($url)) {
         $piwikHost = $url['host'];
     }
     return str_replace('{DOMAIN}', $piwikHost, $email);
 }
예제 #22
0
 /**
  * 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;
 }
예제 #23
0
파일: Tracker.php 프로젝트: Abine/piwik
 /**
  * Tracker requests will automatically trigger the Scheduled tasks.
  * This is useful for users who don't setup the cron,
  * but still want daily/weekly/monthly PDF reports emailed automatically.
  *
  * This is similar to calling the API CoreAdminHome.runScheduledTasks
  */
 protected static function runScheduledTasks()
 {
     $now = time();
     // Currently, there are no hourly tasks. When there are some,
     // this could be too aggressive minimum interval (some hours would be skipped in case of low traffic)
     $minimumInterval = Config::getInstance()->Tracker['scheduled_tasks_min_interval'];
     // If the user disabled browser archiving, he has already setup a cron
     // To avoid parallel requests triggering the Scheduled Tasks,
     // Get last time tasks started executing
     $cache = Cache::getCacheGeneral();
     if ($minimumInterval <= 0 || empty($cache['isBrowserTriggerEnabled'])) {
         Common::printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled.");
         return;
     }
     $nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval;
     if (isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS'] || $cache['lastTrackerCronRun'] === false || $nextRunTime < $now) {
         $cache['lastTrackerCronRun'] = $now;
         Cache::setCacheGeneral($cache);
         self::initCorePiwikInTrackerMode();
         Option::set('lastTrackerCronRun', $cache['lastTrackerCronRun']);
         Common::printDebug('-> Scheduled Tasks: Starting...');
         // save current user privilege and temporarily assume Super User privilege
         $isSuperUser = Piwik::hasUserSuperUserAccess();
         // Scheduled tasks assume Super User is running
         Piwik::setUserHasSuperUserAccess();
         // While each plugins should ensure that necessary languages are loaded,
         // we ensure English translations at least are loaded
         Translate::loadEnglishTranslation();
         ob_start();
         CronArchive::$url = SettingsPiwik::getPiwikUrl();
         $cronArchive = new CronArchive();
         $cronArchive->runScheduledTasksInTrackerMode();
         $resultTasks = ob_get_contents();
         ob_clean();
         // restore original user privilege
         Piwik::setUserHasSuperUserAccess($isSuperUser);
         foreach (explode('</pre>', $resultTasks) as $resultTask) {
             Common::printDebug(str_replace('<pre>', '', $resultTask));
         }
         Common::printDebug('Finished Scheduled Tasks.');
     } else {
         Common::printDebug("-> Scheduled tasks not triggered.");
     }
     Common::printDebug("Next run will be from: " . date('Y-m-d H:i:s', $nextRunTime) . ' UTC');
 }
예제 #24
0
 private function executeNotAsyncHttp($url, Output $output)
 {
     $piwikUrl = $this->urlToPiwik ?: SettingsPiwik::getPiwikUrl();
     if (empty($piwikUrl)) {
         $piwikUrl = 'http://' . Url::getHost() . '/';
     }
     $url = $piwikUrl . $url;
     if (Config::getInstance()->General['force_ssl'] == 1) {
         $url = str_replace("http://", "https://", $url);
     }
     if ($this->runAsSuperUser) {
         $tokenAuths = self::getSuperUserTokenAuths();
         $tokenAuth = reset($tokenAuths);
         if (strpos($url, '?') === false) {
             $url .= '?';
         } else {
             $url .= '&';
         }
         $url .= 'token_auth=' . $tokenAuth;
     }
     try {
         Log::debug("Execute HTTP API request: " . $url);
         $response = Http::sendHttpRequestBy('curl', $url, $timeout = 0, $userAgent = null, $destinationPath = null, $file = null, $followDepth = 0, $acceptLanguage = false, $this->acceptInvalidSSLCertificate);
         $output->write($response);
     } catch (\Exception $e) {
         $message = "Got invalid response from API request: {$url}. ";
         if (isset($response) && empty($response)) {
             $message .= "The response was empty. This usually means a server error. This solution to this error is generally to increase the value of 'memory_limit' in your php.ini file. Please check your Web server Error Log file for more details.";
         } else {
             $message .= "Response was '" . $e->getMessage() . "'";
         }
         $output->write($message);
         Log::debug($e);
     }
 }
 protected function buildNotificationMessage($pluginsToBeNotified, $hasThemeUpdate, $hasPluginUpdate)
 {
     $message = Piwik::translate('ScheduledReports_EmailHello');
     $message .= "\n\n";
     $message .= Piwik::translate('CoreUpdater_ThereIsNewPluginVersionAvailableForUpdate');
     $message .= "\n\n";
     foreach ($pluginsToBeNotified as $plugin) {
         $message .= sprintf(' * %s %s', $plugin['name'], $plugin['latestVersion']);
         $message .= "\n";
     }
     $message .= "\n";
     $host = SettingsPiwik::getPiwikUrl();
     if ($hasThemeUpdate) {
         $message .= Piwik::translate('CoreUpdater_NotificationClickToUpdateThemes') . "\n";
         $message .= $host . 'index.php?module=CorePluginsAdmin&action=themes';
     }
     if ($hasPluginUpdate) {
         if ($hasThemeUpdate) {
             $message .= "\n\n";
         }
         $message .= Piwik::translate('CoreUpdater_NotificationClickToUpdatePlugins') . "\n";
         $message .= $host . 'index.php?module=CorePluginsAdmin&action=plugins';
     }
     $message .= "\n\n";
     $message .= Piwik::translate('Installation_HappyAnalysing');
     return $message;
 }
예제 #26
0
파일: CustomLogo.php 프로젝트: P3PO/piwik
 protected function getPathToLogo($pathOnly, $defaultLogo, $themeLogo, $customLogo)
 {
     $pathToPiwikRoot = Filesystem::getPathToPiwikRoot();
     $logo = $defaultLogo;
     $theme = \Piwik\Plugin\Manager::getInstance()->getThemeEnabled();
     if (!$theme) {
         $themeName = Manager::DEFAULT_THEME;
     } else {
         $themeName = $theme->getPluginName();
     }
     $themeLogo = sprintf($themeLogo, $themeName);
     if (file_exists($pathToPiwikRoot . '/' . $themeLogo)) {
         $logo = $themeLogo;
     }
     if ($this->isEnabled() && file_exists($pathToPiwikRoot . '/' . $customLogo)) {
         $logo = $customLogo;
     }
     if (!$pathOnly) {
         return SettingsPiwik::getPiwikUrl() . $logo;
     }
     return $pathToPiwikRoot . '/' . $logo;
 }
예제 #27
0
    function getKeywordsForPage()
    {
        Piwik::checkUserHasViewAccess($this->idSite);
        $requestUrl = '&date=previous1' . '&period=week' . '&idSite=' . $this->idSite;
        $topPageUrlRequest = $requestUrl . '&method=Actions.getPageUrls' . '&filter_limit=50' . '&format=original';
        $request = new Request($topPageUrlRequest);
        $request = $request->process();
        /** @var $request Map */
        $tables = $request->getDataTables();
        $topPageUrl = false;
        $first = key($tables);
        if (!empty($first)) {
            $topPageUrls = $tables[$first];
            $topPageUrls = $topPageUrls->getRowsMetadata('url');
            $tmpTopPageUrls = array_values($topPageUrls);
            $topPageUrl = current($tmpTopPageUrls);
        }
        if (empty($topPageUrl)) {
            $topPageUrl = $this->site->getMainUrl();
        }
        $url = $topPageUrl;
        // HTML
        $api = SettingsPiwik::getPiwikUrl() . '?module=API&method=Referrers.getKeywordsForPageUrl' . '&format=php' . '&filter_limit=10' . '&token_auth=' . Piwik::getCurrentUserTokenAuth();
        $api .= $requestUrl;
        $code = '
// This function will call the API to get best keyword for current URL.
// Then it writes the list of best keywords in a HTML list
function DisplayTopKeywords($url = "")
{
	// Do not spend more than 1 second fetching the data
	@ini_set("default_socket_timeout", $timeout = 1);
	// Get the Keywords data
	$url = empty($url) ? "http://". $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] : $url;
	$api = "' . $api . '&url=" . urlencode($url);
	$keywords = @unserialize(file_get_contents($api));
	if($keywords === false || isset($keywords["result"])) {
		// DEBUG ONLY: uncomment for troubleshooting an empty output (the URL output reveals the token_auth)
		// echo "Error while fetching the <a href=\'$api\'>Top Keywords from Piwik</a>";
		return;
	}

	// Display the list in HTML
	$url = htmlspecialchars($url, ENT_QUOTES);
	$output = "<h2>Top Keywords for <a href=\'$url\'>$url</a></h2><ul>";
	foreach($keywords as $keyword) {
		$output .= "<li>". $keyword . "</li>";
	}
	if(empty($keywords)) { $output .= "Nothing yet..."; }
	$output .= "</ul>";
	echo $output;
}
';
        $jsonRequest = str_replace('format=php', 'format=json', $api);
        echo "<p>This widget is designed to work in your website directly.\n\t\tThis widget makes it easy to use Piwik to <i>automatically display the list of Top Keywords</i>, for each of your website Page URLs.</p>\n\t\t<p>\n\t\t<b>Example API URL</b> - For example if you would like to get the top 10 keywords, used last week, to land on the page <a target='_blank' href='{$topPageUrl}'>{$topPageUrl}</a>,\n\t\tin format JSON: you would dynamically fetch the data using <a target='_blank' href='{$jsonRequest}&url=" . urlencode($topPageUrl) . "'>this API request URL</a>. Make sure you encode the 'url' parameter in the URL.</p>\n\n\t\t<p><b>PHP Function ready to use!</b> - If you use PHP on your website, we have prepared a small code snippet that you can copy paste in your Website PHP files. You can then simply call the function <code>DisplayTopKeywords();</code> anywhere in your template, at the bottom of the content or in your blog sidebar.\n\t\tIf you run this code in your page {$topPageUrl}, it would output the following:";
        echo "<div style='width:400px;margin-left:20px;padding:10px;border:1px solid black;'>";
        function DisplayTopKeywords($url = "", $api)
        {
            // Do not spend more than 1 second fetching the data
            @ini_set("default_socket_timeout", $timeout = 1);
            // Get the Keywords data
            $url = empty($url) ? "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] : $url;
            $api = $api . "&url=" . urlencode($url);
            $keywords = @unserialize(file_get_contents($api));
            if ($keywords === false || isset($keywords["result"])) {
                // DEBUG ONLY: uncomment for troubleshooting an empty output (the URL output reveals the token_auth)
                //echo "Error while fetching the <a href=\'".$api."\'>Top Keywords from Piwik</a>";
                return;
            }
            // Display the list in HTML
            $url = htmlspecialchars($url, ENT_QUOTES);
            $output = "<h2>Top Keywords for <a href=\\'{$url}\\'>{$url}</a></h2><ul>";
            foreach ($keywords as $keyword) {
                $output .= "<li>" . $keyword . "</li>";
            }
            if (empty($keywords)) {
                $output .= "Nothing yet...";
            }
            $output .= "</ul>";
            echo $output;
        }
        DisplayTopKeywords($topPageUrl, $api);
        echo "</div><br/>\n\t\t<p>Here is the PHP function that you can paste in your pages:</P>\n\t\t<textarea cols=60 rows=8>&lt;?php\n" . htmlspecialchars($code) . "\n DisplayTopKeywords();</textarea>\n\t\t";
        echo "\n\t\t<p><strong>Notes</strong>: You can for example edit the code to to make the Top search keywords link to your Website search result pages.\n\t\t<br/>On medium to large traffic websites, we recommend to cache this data, as to minimize the performance impact of calling the Piwik API on each page view.\n\t\t</p>\n\t\t";
    }
 /**
  * Returns true if the supplied instance ID refers to this Piwik instance, false if otherwise.
  * Assumes the instance ID is the base URL to the Piwik instance.
  *
  * @param string $instanceIdUrl
  * @return bool
  */
 protected function isUrlThisInstanceUrl($instanceIdUrl)
 {
     $thisPiwikUrl = SettingsPiwik::getPiwikUrl();
     $thisPiwikUrl = $this->getNormalizedUrl($thisPiwikUrl, $isThisPiwikUrl = true);
     $instanceIdUrl = $this->getNormalizedUrl($instanceIdUrl);
     return $thisPiwikUrl == $instanceIdUrl;
 }