Beispiel #1
0
 /**
  * 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));
     });
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
 /**
  * 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);
 }
Beispiel #6
0
 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;
 }
Beispiel #8
0
 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);
 }
Beispiel #11
0
 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
         }
     }
 }
Beispiel #13
0
 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
     }
 }
Beispiel #14
0
 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();
 }
Beispiel #15
0
 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';
 }
Beispiel #16
0
 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);
         }
     }
 }
Beispiel #17
0
 /**
  * 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;
 }
Beispiel #20
0
 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());
     }
 }
Beispiel #21
0
 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;
     }
 }
Beispiel #24
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;
 }
Beispiel #25
0
 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());
         }
     }
 }
Beispiel #26
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();
     }
 }
Beispiel #27
0
 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);
 }
Beispiel #28
0
 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);
 }
Beispiel #29
0
 /**
  * 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);
     }
 }
Beispiel #30
0
 /**
  * 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);
 }