Piwik\Plugins\ScheduledReports\API::generateReport PHP Method

generateReport() public method

Generates a report file.
public generateReport ( integer $idReport, string $date, boolean | false | string $language = false, boolean | false | integer $outputType = false, boolean | false | string $period = false, boolean | false | string $reportFormat = false, boolean | false | array $parameters = false ) : array | void
$idReport integer ID of the report to generate.
$date string YYYY-MM-DD
$language boolean | false | string If not passed, will use default language.
$outputType boolean | false | integer 1 = download report, 2 = save report to disk, 3 = output report in browser, 4 = return report content to caller, defaults to download
$period boolean | false | string Defaults to 'day'. If not specified, will default to the report's period set when creating the report
$reportFormat boolean | false | string 'pdf', 'html' or any other format provided via the ScheduledReports.getReportFormats hook
$parameters boolean | false | array array of parameters
return array | void
    public function generateReport($idReport, $date, $language = false, $outputType = false, $period = false, $reportFormat = false, $parameters = false)
    {
        Piwik::checkUserIsNotAnonymous();
        // load specified language
        if (empty($language)) {
            $language = Translate::getLanguageDefault();
        }
        /** @var Translator $translator */
        $translator = StaticContainer::get('Piwik\\Translation\\Translator');
        $translator->setCurrentLanguage($language);
        $reports = $this->getReports($idSite = false, $_period = false, $idReport);
        $report = reset($reports);
        $idSite = $report['idsite'];
        $login = $report['login'];
        $reportType = $report['type'];
        $this->checkUserHasViewPermission($login, $idSite);
        // override report period
        if (empty($period)) {
            $period = $report['period'];
        }
        // override report format
        if (!empty($reportFormat)) {
            self::validateReportFormat($reportType, $reportFormat);
            $report['format'] = $reportFormat;
        } else {
            $reportFormat = $report['format'];
        }
        // override and/or validate report parameters
        $report['parameters'] = json_decode(self::validateReportParameters($reportType, empty($parameters) ? $report['parameters'] : $parameters), true);
        // available reports
        $availableReportMetadata = \Piwik\Plugins\API\API::getInstance()->getReportMetadata($idSite);
        // we need to lookup which reports metadata are registered in this report
        $reportMetadata = array();
        foreach ($availableReportMetadata as $metadata) {
            if (in_array($metadata['uniqueId'], $report['reports'])) {
                $reportMetadata[] = $metadata;
            }
        }
        // the report will be rendered with the first 23 rows and will aggregate other rows in a summary row
        // 23 rows table fits in one portrait page
        $initialFilterTruncate = Common::getRequestVar('filter_truncate', false);
        $_GET['filter_truncate'] = Config::getInstance()->General['scheduled_reports_truncate'];
        $prettyDate = null;
        $processedReports = array();
        $segment = self::getSegment($report['idsegment']);
        foreach ($reportMetadata as $action) {
            $apiModule = $action['module'];
            $apiAction = $action['action'];
            $apiParameters = array();
            if (isset($action['parameters'])) {
                $apiParameters = $action['parameters'];
            }
            $mustRestoreGET = false;
            // all Websites dashboard should not be truncated in the report
            if ($apiModule == 'MultiSites') {
                $mustRestoreGET = $_GET;
                $_GET['enhanced'] = true;
                if ($apiAction == 'getAll') {
                    $_GET['filter_truncate'] = false;
                    $_GET['filter_limit'] = -1;
                    // show all websites in all websites report
                    // when a view/admin user created a report, workaround the fact that "Super User"
                    // is enforced in Scheduled tasks, and ensure Multisites.getAll only return the websites that this user can access
                    $userLogin = $report['login'];
                    if (!empty($userLogin) && !Piwik::hasTheUserSuperUserAccess($userLogin)) {
                        $_GET['_restrictSitesToLogin'] = $userLogin;
                    }
                }
            }
            $params = array('idSite' => $idSite, 'period' => $period, 'date' => $date, 'apiModule' => $apiModule, 'apiAction' => $apiAction, 'apiParameters' => $apiParameters, 'flat' => 1, 'idGoal' => false, 'language' => $language, 'serialize' => 0, 'format' => 'original');
            if ($segment != null) {
                $params['segment'] = urlencode($segment['definition']);
            } else {
                $params['segment'] = false;
            }
            try {
                $processedReport = Request::processRequest('API.getProcessedReport', $params);
            } catch (\Exception $ex) {
                // NOTE: can't use warning or error because the log message will appear in the UI as a notification
                $this->logger->info("Error getting '?{report}' when generating scheduled report: {exception}", array('report' => http_build_query($params), 'exception' => $ex->getMessage()));
                $this->logger->debug($ex);
                continue;
            }
            $processedReport['segment'] = $segment;
            // TODO add static method getPrettyDate($period, $date) in Period
            $prettyDate = $processedReport['prettyDate'];
            if ($mustRestoreGET) {
                $_GET = $mustRestoreGET;
            }
            $processedReports[] = $processedReport;
        }
        // restore filter truncate parameter value
        if ($initialFilterTruncate !== false) {
            $_GET['filter_truncate'] = $initialFilterTruncate;
        }
        /**
         * Triggered when generating the content of scheduled reports.
         *
         * This event can be used to modify the report data or report metadata of one or more reports
         * in a scheduled report, before the scheduled report is rendered and delivered.
         *
         * TODO: list data available in $report or make it a new class that can be documented (same for
         *       all other events that use a $report)
         *
         * @param array &$processedReports The list of processed reports in the scheduled
         *                                 report. Entries includes report data and metadata for each report.
         * @param string $reportType A string ID describing how the scheduled report will be sent, eg,
         *                           `'sms'` or `'email'`.
         * @param string $outputType The output format of the report, eg, `'html'`, `'pdf'`, etc.
         * @param array $report An array describing the scheduled report that is being
         *                      generated.
         */
        Piwik::postEvent(self::PROCESS_REPORTS_EVENT, array(&$processedReports, $reportType, $outputType, $report));
        $reportRenderer = null;
        /**
         * Triggered when obtaining a renderer instance based on the scheduled report output format.
         *
         * Plugins that provide new scheduled report output formats should use this event to
         * handle their new report formats.
         *
         * @param ReportRenderer &$reportRenderer This variable should be set to an instance that
         *                                        extends {@link Piwik\ReportRenderer} by one of the event
         *                                        subscribers.
         * @param string $reportType A string ID describing how the report is sent, eg,
         *                           `'sms'` or `'email'`.
         * @param string $outputType The output format of the report, eg, `'html'`, `'pdf'`, etc.
         * @param array $report An array describing the scheduled report that is being
         *                      generated.
         */
        Piwik::postEvent(self::GET_RENDERER_INSTANCE_EVENT, array(&$reportRenderer, $reportType, $outputType, $report));
        if (is_null($reportRenderer)) {
            throw new Exception("A report renderer was not supplied in the event " . self::GET_RENDERER_INSTANCE_EVENT);
        }
        // init report renderer
        $reportRenderer->setIdSite($idSite);
        $reportRenderer->setLocale($language);
        // render report
        $description = str_replace(array("\r", "\n"), ' ', $report['description']);
        list($reportSubject, $reportTitle) = self::getReportSubjectAndReportTitle(Common::unsanitizeInputValue(Site::getNameFor($idSite)), $report['reports']);
        // if reporting for a segment, use the segment's name in the title
        if (is_array($segment) && strlen($segment['name'])) {
            $reportTitle .= " - " . $segment['name'];
        }
        $filename = "{$reportTitle} - {$prettyDate} - {$description}";
        $reportRenderer->renderFrontPage($reportTitle, $prettyDate, $description, $reportMetadata, $segment);
        array_walk($processedReports, array($reportRenderer, 'renderReport'));
        switch ($outputType) {
            case self::OUTPUT_SAVE_ON_DISK:
                $outputFilename = strtoupper($reportFormat) . ' ' . ucfirst($reportType) . ' Report - ' . $idReport . '.' . $date . '.' . $idSite . '.' . $language;
                $outputFilename = $reportRenderer->sendToDisk($outputFilename);
                $additionalFiles = $this->getAttachments($reportRenderer, $report, $processedReports, $prettyDate);
                return array($outputFilename, $prettyDate, $reportSubject, $reportTitle, $additionalFiles);
                break;
            case self::OUTPUT_INLINE:
                $reportRenderer->sendToBrowserInline($filename);
                break;
            case self::OUTPUT_RETURN:
                return $reportRenderer->getRenderedReport();
                break;
            default:
            case self::OUTPUT_DOWNLOAD:
                $reportRenderer->sendToBrowserDownload($filename);
                break;
        }
    }