/** * Create a component instance that exists within a specific plugin. Uses the component's * unqualified class name and expected base type. * * This method will only create a class if it is located within the component type's * associated subdirectory. * * @param string $pluginName The name of the plugin the component is expected to belong to, * eg, `'UserSettings'`. * @param string $componentClassSimpleName The component's class name w/o namespace, eg, * `"GetKeywords"`. * @param string $componentTypeClass The fully qualified class name of the component type, eg, * `"Piwik\Plugin\Report"`. * @return mixed|null A new instance of the desired component or null if not found. If the * plugin is not loaded or activated or the component is not located in * in the sub-namespace specified by `$componentTypeClass::COMPONENT_SUBNAMESPACE`, * this method will return null. */ public static function factory($pluginName, $componentClassSimpleName, $componentTypeClass) { if (empty($pluginName) || empty($componentClassSimpleName)) { return null; } $pluginManager = PluginManager::getInstance(); try { if (!$pluginManager->isPluginActivated($pluginName)) { return null; } $plugin = $pluginManager->getLoadedPlugin($pluginName); } catch (Exception $e) { Log::debug($e); return null; } $subnamespace = $componentTypeClass::COMPONENT_SUBNAMESPACE; $desiredComponentClass = 'Piwik\\Plugins\\' . $pluginName . '\\' . $subnamespace . '\\' . $componentClassSimpleName; $components = $plugin->findMultipleComponents($subnamespace, $componentTypeClass); foreach ($components as $class) { if ($class == $desiredComponentClass) { return new $class(); } } return null; }
protected function execute(InputInterface $input, OutputInterface $output) { // Set memory limit to off @ini_set('memory_limit', -1); Piwik::doAsSuperUser(function () use($input, $output) { $settings = new MigratorSettings(); $settings->idSite = $input->getArgument('idSite'); $settings->site = $this->getSite($settings->idSite); $settings->dateFrom = $input->getOption('date-from') ? new \DateTime($input->getOption('date-from')) : null; $settings->dateTo = $input->getOption('date-to') ? new \DateTime($input->getOption('date-to')) : null; $settings->skipArchiveData = $input->getOption('skip-archive-data'); $settings->skipLogData = $input->getOption('skip-log-data'); $config = Db::getDatabaseConfig(); $startTime = microtime(true); $this->createTargetDatabaseConfig($input, $output, $config); $tmpConfig = $config; $sourceDb = Db::get(); try { $targetDb = @Db\Adapter::factory($config['adapter'], $tmpConfig); } catch (\Exception $e) { throw new \RuntimeException('Unable to connect to the target database: ' . $e->getMessage(), 0, $e); } $sourceDbHelper = new DBHelper($sourceDb, Db::getDatabaseConfig()); $migratorFacade = new Migrator($sourceDbHelper, new DBHelper($targetDb, $config), GCHelper::getInstance(), $settings, new ArchiveLister($sourceDbHelper)); $migratorFacade->migrate(); $endTime = microtime(true); Log::debug(sprintf('Time taken: %01.2f sec', $endTime - $startTime)); Log::debug(sprintf('Peak memory usage: %01.2f MB', memory_get_peak_usage(true) / 1048576)); }); }
private static function getErrorResponse(Exception $ex) { $debugTrace = $ex->getTraceAsString(); $message = $ex->getMessage(); if (!method_exists($ex, 'isHtmlMessage') || !$ex->isHtmlMessage()) { $message = Common::sanitizeInputValue($message); } $logo = new CustomLogo(); $logoHeaderUrl = false; $logoFaviconUrl = false; try { $logoHeaderUrl = $logo->getHeaderLogoUrl(); $logoFaviconUrl = $logo->getPathUserFavicon(); } catch (Exception $ex) { Log::debug($ex); } $result = Piwik_GetErrorMessagePage($message, $debugTrace, true, true, $logoHeaderUrl, $logoFaviconUrl); /** * Triggered before a Piwik error page is displayed to the user. * * This event can be used to modify the content of the error page that is displayed when * an exception is caught. * * @param string &$result The HTML of the error page. * @param Exception $ex The Exception displayed in the error page. */ Piwik::postEvent('FrontController.modifyErrorPage', array(&$result, $ex)); return $result; }
/** * Purges old data from the following tables: * - log_visit * - log_link_visit_action * - log_conversion * - log_conversion_item * - log_action */ public function purgeData() { $maxIdVisit = $this->getDeleteIdVisitOffset(); // break if no ID was found (nothing to delete for given period) if (empty($maxIdVisit)) { return; } $logTables = self::getDeleteTableLogTables(); // delete data from log tables $where = "WHERE idvisit <= ?"; foreach ($logTables as $logTable) { // deleting from log_action must be handled differently, so we do it later if ($logTable != Common::prefixTable('log_action')) { Db::deleteAllRows($logTable, $where, "idvisit ASC", $this->maxRowsToDeletePerQuery, array($maxIdVisit)); } } // delete unused actions from the log_action table (but only if we can lock tables) if (Db::isLockPrivilegeGranted()) { $this->purgeUnusedLogActions(); } else { $logMessage = get_class($this) . ": LOCK TABLES privilege not granted; skipping unused actions purge"; Log::warning($logMessage); } // optimize table overhead after deletion Db::optimizeTables($logTables); }
protected static function deleteArchivesWithPeriodRange(Date $date) { $numericTable = ArchiveTableCreator::getNumericTable($date); $blobTable = ArchiveTableCreator::getBlobTable($date); $yesterday = Date::factory('yesterday')->getDateTime(); Log::debug("Purging Custom Range archives: done [ purged archives older than %s from %s / blob ]", $yesterday, $numericTable); self::getModel()->deleteArchivesWithPeriodRange($numericTable, $blobTable, Piwik::$idPeriods['range'], $yesterday); }
public function updateTracker() { try { $trackerUpdater = new TrackerUpdater(); $trackerUpdater->update(); } catch (\Exception $e) { Log::error('There was an error while updating the javascript tracker: ' . $e->getMessage()); } }
public function testConnection() { try { $this->connectIfNeeded(); return 'TEST' === $this->redis->echo('TEST'); } catch (\Exception $e) { Log::debug($e->getMessage()); } return false; }
public static function tearDownAfterClass() { Log::debug("Tearing down " . get_called_class()); if (!isset(static::$fixture)) { $fixture = new Fixture(); } else { $fixture = static::$fixture; } $fixture->performTearDown(); }
public function logVariables() { try { if (isset($_SERVER['QUERY_STRING'])) { \Piwik\Log::verbose("Test Environment Variables for (%s):\n%s", $_SERVER['QUERY_STRING'], print_r($this->behaviorOverrideProperties, true)); } } catch (Exception $ex) { // ignore } }
/** * @test */ public function it_should_add_severity_for_errors() { $processor = new ExceptionToTextProcessor(); Log::$debugBacktraceForTests = '[stack trace]'; $exception = new \ErrorException('Hello world', 0, 1, 'file.php', 123); $record = array('context' => array('exception' => $exception)); $result = $processor($record); $expected = array('message' => "file.php(123): Error - Hello world\n[stack trace]", 'context' => array('exception' => $exception)); $this->assertEquals($expected, $result); }
private function addCommandIfExists($command) { if (!class_exists($command)) { Log::warning(sprintf('Cannot add command %s, class does not exist', $command)); } elseif (!is_subclass_of($command, 'Piwik\\Plugin\\ConsoleCommand')) { Log::warning(sprintf('Cannot add command %s, class does not extend Piwik\\Plugin\\ConsoleCommand', $command)); } else { $this->add(new $command()); } }
public function migrate($siteId, \DateTime $from = null, \DateTime $to = null) { $archives = $this->archiveLister->getArchiveList($from, $to); foreach ($archives as $archiveDate) { Log::debug('Migrating archive ' . $archiveDate); $this->migrateArchive($archiveDate, 'archive_numeric_' . $archiveDate, $siteId); try { $this->migrateArchive($archiveDate, 'archive_blob_' . $archiveDate, $siteId); } catch (\Exception $e) { // blob tables can be missing } } }
protected static function deleteArchivesWithPeriodRange(Date $date) { $query = "DELETE FROM %s WHERE period = ? AND ts_archived < ?"; $yesterday = Date::factory('yesterday')->getDateTime(); $bind = array(Piwik::$idPeriods['range'], $yesterday); $numericTable = ArchiveTableCreator::getNumericTable($date); Db::query(sprintf($query, $numericTable), $bind); Log::debug("Purging Custom Range archives: done [ purged archives older than %s from %s / blob ]", $yesterday, $numericTable); try { Db::query(sprintf($query, ArchiveTableCreator::getBlobTable($date)), $bind); } catch (Exception $e) { // Individual blob tables could be missing } }
public function run() { $console = new Application(); $commands = $this->getAvailableCommands(); foreach ($commands as $command) { if (!class_exists($command)) { Log::warning(sprintf('Cannot add command %s, class does not exist', $command)); } elseif (!is_subclass_of($command, 'Piwik\\Plugin\\ConsoleCommand')) { Log::warning(sprintf('Cannot add command %s, class does not extend Piwik\\Plugin\\ConsoleCommand', $command)); } else { $console->add(new $command()); } } $console->run(); }
protected function execute(InputInterface $input, OutputInterface $output) { $url = $input->getOption('url'); if ($input->getOption('piwik-domain') && !$url) { $_SERVER['argv'][] = '--url=' . $input->getOption('piwik-domain'); } if (is_string($url) && $url && in_array($url, array('http://', 'https://'))) { // see http://dev.piwik.org/trac/ticket/5180 and http://forum.piwik.org/read.php?2,115274 throw new \InvalidArgumentException('No valid URL given. If you have specified a valid URL try --piwik-domain instead of --url'); } if ($input->getOption('verbose')) { Log::getInstance()->setLogLevel(Log::VERBOSE); } include PIWIK_INCLUDE_PATH . '/misc/cron/archive.php'; }
private function addCommandIfExists($command) { if (!class_exists($command)) { Log::warning(sprintf('Cannot add command %s, class does not exist', $command)); } elseif (!is_subclass_of($command, 'Piwik\\Plugin\\ConsoleCommand')) { Log::warning(sprintf('Cannot add command %s, class does not extend Piwik\\Plugin\\ConsoleCommand', $command)); } else { /** @var Command $commandInstance */ $commandInstance = new $command(); // do not add the command if it already exists; this way we can add the command ourselves in tests if (!$this->has($commandInstance->getName())) { $this->add($commandInstance); } } }
/** * Purges old data from the following tables: * - log_visit * - log_link_visit_action * - log_conversion * - log_conversion_item * - log_action * * @param int $deleteLogsOlderThan The number of days after which log entires are considered old. * Visits and related data whose age is greater than this number * will be purged. */ public function purgeData($deleteLogsOlderThan) { $dateUpperLimit = Date::factory("today")->subDay($deleteLogsOlderThan); $this->logDeleter->deleteVisitsFor($start = null, $dateUpperLimit->getDatetime()); $logTables = self::getDeleteTableLogTables(); // delete unused actions from the log_action table (but only if we can lock tables) if (Db::isLockPrivilegeGranted()) { $this->rawLogDao->deleteUnusedLogActions(); } else { $logMessage = get_class($this) . ": LOCK TABLES privilege not granted; skipping unused actions purge"; Log::warning($logMessage); } // optimize table overhead after deletion Db::optimizeTables($logTables); }
protected function execute(InputInterface $input, OutputInterface $output) { $systemCheck = new SystemCheck(); $systemCheck->checkRedisIsInstalled(); $trackerEnvironment = new Environment('tracker'); $trackerEnvironment->init(); Log::unsetInstance(); $trackerEnvironment->getContainer()->get('Piwik\\Access')->setSuperUserAccess(false); $trackerEnvironment->getContainer()->get('Piwik\\Plugin\\Manager')->setTrackerPluginsNotToLoad(array('Provider')); Tracker::loadTrackerEnvironment(); if (OutputInterface::VERBOSITY_VERY_VERBOSE <= $output->getVerbosity()) { $GLOBALS['PIWIK_TRACKER_DEBUG'] = true; } $backend = Queue\Factory::makeBackend(); $queueManager = Queue\Factory::makeQueueManager($backend); if (!$queueManager->canAcquireMoreLocks()) { $trackerEnvironment->destroy(); $this->writeSuccessMessage($output, array("Nothing to proccess. Already max number of workers in process.")); return; } $shouldProcess = false; foreach ($queueManager->getAllQueues() as $queue) { if ($queue->shouldProcess()) { $shouldProcess = true; break; } } if (!$shouldProcess) { $trackerEnvironment->destroy(); $this->writeSuccessMessage($output, array("No queue currently needs processing")); return; } $output->writeln("<info>Starting to process request sets, this can take a while</info>"); register_shutdown_function(function () use($queueManager) { $queueManager->unlock(); }); $startTime = microtime(true); $processor = new Processor($queueManager); $processor->setNumberOfMaxBatchesToProcess(1000); $tracker = $processor->process(); $neededTime = microtime(true) - $startTime; $numRequestsTracked = $tracker->getCountOfLoggedRequests(); $requestsPerSecond = $this->getNumberOfRequestsPerSecond($numRequestsTracked, $neededTime); Piwik::postEvent('Tracker.end'); $trackerEnvironment->destroy(); $this->writeSuccessMessage($output, array(sprintf('This worker finished queue processing with %sreq/s (%s requests in %02.2f seconds)', $requestsPerSecond, $numRequestsTracked, $neededTime))); }
private static function getErrorResponse(Exception $ex) { $debugTrace = $ex->getTraceAsString(); $message = $ex->getMessage(); $isHtmlMessage = method_exists($ex, 'isHtmlMessage') && $ex->isHtmlMessage(); if (!$isHtmlMessage && Request::isApiRequest($_GET)) { $outputFormat = strtolower(Common::getRequestVar('format', 'xml', 'string', $_GET + $_POST)); $response = new ResponseBuilder($outputFormat); return $response->getResponseException($ex); } elseif (!$isHtmlMessage) { $message = Common::sanitizeInputValue($message); } $logo = new CustomLogo(); $logoHeaderUrl = false; $logoFaviconUrl = false; try { $logoHeaderUrl = $logo->getHeaderLogoUrl(); $logoFaviconUrl = $logo->getPathUserFavicon(); } catch (Exception $ex) { try { Log::debug($ex); } catch (\Exception $otherEx) { // DI container may not be setup at this point } } $result = Piwik_GetErrorMessagePage($message, $debugTrace, true, true, $logoHeaderUrl, $logoFaviconUrl); try { /** * Triggered before a Piwik error page is displayed to the user. * * This event can be used to modify the content of the error page that is displayed when * an exception is caught. * * @param string &$result The HTML of the error page. * @param Exception $ex The Exception displayed in the error page. */ Piwik::postEvent('FrontController.modifyErrorPage', array(&$result, $ex)); } catch (ContainerDoesNotExistException $ex) { // this can happen when an error occurs before the Piwik environment is created } return $result; }
protected function execute(InputInterface $input, OutputInterface $output) { $url = $input->getOption('url') ?: $input->getOption('piwik-domain'); if (empty($url)) { throw new \InvalidArgumentException("The --url argument is not set. It should be set to your Piwik URL, for example: --url=http://example.org/piwik/."); } if (is_string($url) && $url && in_array($url, array('http://', 'https://'))) { // see https://github.com/piwik/piwik/issues/5180 and http://forum.piwik.org/read.php?2,115274 throw new \InvalidArgumentException('No valid URL given. If you have specified a valid URL try --piwik-domain instead of --url'); } if ($input->getOption('verbose')) { Log::getInstance()->setLogLevel(Log::VERBOSE); } $archiver = $this->makeArchiver($url, $input); try { $archiver->main(); } catch (Exception $e) { $archiver->logFatalError($e->getMessage()); } }
public function doRun(InputInterface $input, OutputInterface $output) { $this->initPiwikHost($input); $this->initConfig($output); try { self::initPlugins(); } catch (\Exception $e) { // Piwik not installed yet, no config file? } Translate::reloadLanguage('en'); $commands = $this->getAvailableCommands(); foreach ($commands as $command) { if (!class_exists($command)) { Log::warning(sprintf('Cannot add command %s, class does not exist', $command)); } elseif (!is_subclass_of($command, 'Piwik\\Plugin\\ConsoleCommand')) { Log::warning(sprintf('Cannot add command %s, class does not extend Piwik\\Plugin\\ConsoleCommand', $command)); } else { $this->add(new $command()); } } return parent::doRun($input, $output); }
/** * Computes the total number of unique visitors who visited at least one site in, * a set of sites and the number of unique visitors that visited all of the sites * in the set. * * Comparison is done in dates for the UTC time, not for the site specific time. * * Performance: The SQL query this method executes was tested on a Piwik instance * with 13 million visits total. Computing data for 4 sites with no * date limit took 13s to complete. * * @param int[] $idSites The IDs of the sites for whom unique visitor counts should be * computed. * @param Date $startDate The lower bound of the date range of the visits to check. * @param Date $endDate The upper bound of the date range of the visits to check. * @param Segment $segment An optional segment to apply to the visits set before aggregation. * To supply no segment, use `new Segment()`. * @return int[] Returns two metrics: **nb_total_visitors** and **nb_shared_visitors**. * * **nb_total_visitors** is the total number of unique visitors who visited * at least one site in the list. * * **nb_shared_visitors** is the total number of unique visitors who visited * every site in the list. * @throws Exception if less than 2 site IDs are supplied, */ public function getCommonVisitorCount($idSites, Date $startDate, Date $endDate, Segment $segment) { Log::debug("%s::%s('%s', '%s', '%s', '%s') called", "Model\\DistinctMetricsAggregator", __FUNCTION__, $idSites, $startDate, $endDate, $segment); if (count($idSites) == 1) { throw new Exception(Piwik::translate('InterSites_PleasSupplyAtLeastTwoDifferentSites')); } $select = "config_id, COUNT(DISTINCT idsite) AS sitecount"; $from = array('log_visit'); $where = 'visit_last_action_time >= ? AND visit_last_action_time <= ? AND idsite IN (' . Common::getSqlStringFieldsArray($idSites) . ')'; $orderBy = false; $groupBy = 'config_id'; $startDateTime = new \DateTime($startDate->toString()); $endDateTime = new \DateTime($endDate->toString()); $bind = array_merge(array($startDateTime->format("Y-m-d 00:00:00"), $endDateTime->format("Y-m-d 23:59:59")), $idSites); $innerQuery = $segment->getSelectQuery($select, $from, $where, $bind, $orderBy, $groupBy); $wholeQuery = "SELECT COUNT(sitecount_by_config.config_id) AS nb_total_visitors,\n SUM(IF(sitecount_by_config.sitecount >= " . count($idSites) . ", 1, 0)) AS nb_shared_visitors\n FROM ( {$innerQuery['sql']} ) AS sitecount_by_config"; $result = Db::fetchRow($wholeQuery, $innerQuery['bind']); // nb_shared_visitors can be NULL if there are no visits if ($result['nb_shared_visitors'] === null) { $result['nb_shared_visitors'] = 0; } Log::debug("%s::%s() returned '%s'", "Model\\DistinctMetricsAggregator", __FUNCTION__, $result); return $result; }
/** * Returns the number of referrer domains that link to the current site. * * @return int */ public function getReferrerDomainCount() { try { $majesticInfo = $this->getMajesticInfo(); return $majesticInfo['referrer_domains_count']; } catch (Exception $e) { Log::info($e); return 0; } }
/** * Batch insert into table from CSV (or other delimited) file. * * @param string $tableName Name of table * @param array $fields Field names * @param string $filePath Path name of a file. * @param array $fileSpec File specifications (delimiter, line terminator, etc) * * @throws Exception * @return bool True if successful; false otherwise */ public static function createTableFromCSVFile($tableName, $fields, $filePath, $fileSpec) { // Chroot environment: prefix the path with the absolute chroot path $chrootPath = Config::getInstance()->General['absolute_chroot_path']; if (!empty($chrootPath)) { $filePath = $chrootPath . $filePath; } // On Windows, MySQL expects forward slashes as directory separators if (SettingsServer::isWindows()) { $filePath = str_replace('\\', '/', $filePath); } $query = "\n\t\t\t\t'{$filePath}'\n\t\t\tREPLACE\n\t\t\tINTO TABLE\n\t\t\t\t`" . $tableName . "`"; if (isset($fileSpec['charset'])) { $query .= ' CHARACTER SET ' . $fileSpec['charset']; } $fieldList = '(' . join(',', $fields) . ')'; $query .= "\n\t\t\tFIELDS TERMINATED BY\n\t\t\t\t'" . $fileSpec['delim'] . "'\n\t\t\tENCLOSED BY\n\t\t\t\t'" . $fileSpec['quote'] . "'\n\t\t"; if (isset($fileSpec['escape'])) { $query .= " ESCAPED BY '" . $fileSpec['escape'] . "'"; } $query .= "\n\t\t\tLINES TERMINATED BY\n\t\t\t\t'" . $fileSpec['eol'] . "'\n\t\t\t{$fieldList}\n\t\t"; /* * First attempt: assume web server and MySQL server are on the same machine; * this requires that the db user have the FILE privilege; however, since this is * a global privilege, it may not be granted due to security concerns */ $keywords = array(''); /* * Second attempt: using the LOCAL keyword means the client reads the file and sends it to the server; * the LOCAL keyword may trigger a known PHP PDO\MYSQL bug when MySQL not built with --enable-local-infile * @see http://bugs.php.net/bug.php?id=54158 */ $openBaseDir = ini_get('open_basedir'); $safeMode = ini_get('safe_mode'); if (empty($openBaseDir) && empty($safeMode)) { // php 5.x - LOAD DATA LOCAL INFILE is disabled if open_basedir restrictions or safe_mode enabled $keywords[] = 'LOCAL '; } $exceptions = array(); foreach ($keywords as $keyword) { $queryStart = 'LOAD DATA ' . $keyword . 'INFILE '; $sql = $queryStart . $query; try { $result = @Db::exec($sql); if (empty($result) || $result < 0) { continue; } return true; } catch (Exception $e) { // echo $sql . ' ---- ' . $e->getMessage(); $code = $e->getCode(); $message = $e->getMessage() . ($code ? "[{$code}]" : ''); if (!Db::get()->isErrNo($e, '1148')) { Log::info("LOAD DATA INFILE failed... Error was: %s", $message); } $exceptions[] = "\n Try #" . (count($exceptions) + 1) . ': ' . $queryStart . ": " . $message; } } if (count($exceptions)) { throw new Exception(implode(",", $exceptions)); } return false; }
public static function install() { foreach (self::getScopes() as $scope) { $model = new Model($scope); try { $maxCustomVars = 5; $customVarsToAdd = $maxCustomVars - $model->getCurrentNumCustomVars(); for ($index = 0; $index < $customVarsToAdd; $index++) { $model->addCustomVariable(); } } catch (\Exception $e) { Log::warning('Failed to add custom variable: ' . $e->getMessage()); } } }
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(); } }
private function recreateLogSingleton($backend, $level = 'INFO') { $newEnv = new Environment('test', array('ini.log.log_writers' => array($backend), 'ini.log.log_level' => $level, 'ini.log.string_message_format' => self::STRING_MESSAGE_FORMAT, 'ini.log.logger_file_path' => self::getLogFileLocation(), 'Psr\\Log\\LoggerInterface' => \DI\get('Monolog\\Logger'))); $newEnv->init(); $newMonologLogger = $newEnv->getContainer()->make('Psr\\Log\\LoggerInterface'); $oldLogger = new Log($newMonologLogger); Log::setSingletonInstance($oldLogger); }
private function fetchIntersectedWithThisBySegment(DataTable $table, $segmentValue) { $segmentStr = $this->thisReportDimensionSegment->getSegment() . "==" . urlencode($segmentValue); // TODO: segment + report API method query params should be stored in DataTable metadata so we don't have to access it here $originalSegment = Common::getRequestVar('segment', false); if (!empty($originalSegment)) { $segmentStr = $originalSegment . ';' . $segmentStr; } Log::debug("PivotByDimension: Fetching intersected with segment '%s'", $segmentStr); $params = array('segment' => $segmentStr) + $this->getRequestParamOverride($table); return $this->pivotDimensionReport->fetch($params); }
/** * Password reset confirmation action. Finishes the password reset process. * Users visit this action from a link supplied in an email. */ public function confirmResetPassword() { $errorMessage = null; $login = Common::getRequestVar('login', ''); $resetToken = Common::getRequestVar('resetToken', ''); try { $this->passwordResetter->confirmNewPassword($login, $resetToken); } catch (Exception $ex) { Log::debug($ex); $errorMessage = $ex->getMessage(); } if (is_null($errorMessage)) { // if success, show login w/ success message return $this->resetPasswordSuccess(); } else { // show login page w/ error. this will keep the token in the URL return $this->login($errorMessage); } }
/** * Drops all archive tables. */ public static function deleteArchiveTables() { foreach (ArchiveTableCreator::getTablesArchivesInstalled() as $table) { Log::debug("Dropping table {$table}"); Db::query("DROP TABLE IF EXISTS `{$table}`"); } ArchiveTableCreator::refreshTableList($forceReload = true); }