Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ReportRenderer.php 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik;
  10. use Exception;
  11. use Piwik\API\Request;
  12. use Piwik\DataTable\Row;
  13. use Piwik\DataTable\Simple;
  14. use Piwik\DataTable;
  15. use Piwik\Plugins\ImageGraph\API;
  16. use Piwik\BaseFactory;
  17. /**
  18. * A Report Renderer produces user friendly renderings of any given Piwik report.
  19. * All new Renderers must be copied in ReportRenderer and added to the $availableReportRenderers.
  20. */
  21. abstract class ReportRenderer extends BaseFactory
  22. {
  23. const DEFAULT_REPORT_FONT = 'dejavusans';
  24. const REPORT_TEXT_COLOR = "68,68,68";
  25. const REPORT_TITLE_TEXT_COLOR = "126,115,99";
  26. const TABLE_HEADER_BG_COLOR = "228,226,215";
  27. const TABLE_HEADER_TEXT_COLOR = "37,87,146";
  28. const TABLE_CELL_BORDER_COLOR = "231,231,231";
  29. const TABLE_BG_COLOR = "249,250,250";
  30. const HTML_FORMAT = 'html';
  31. const PDF_FORMAT = 'pdf';
  32. const CSV_FORMAT = 'csv';
  33. private static $availableReportRenderers = array(
  34. self::PDF_FORMAT,
  35. self::HTML_FORMAT,
  36. self::CSV_FORMAT,
  37. );
  38. protected static function getClassNameFromClassId($rendererType)
  39. {
  40. return 'Piwik\ReportRenderer\\' . self::normalizeRendererType($rendererType);
  41. }
  42. protected static function getInvalidClassIdExceptionMessage($rendererType)
  43. {
  44. return Piwik::translate(
  45. 'General_ExceptionInvalidReportRendererFormat',
  46. array(self::normalizeRendererType($rendererType), implode(', ', self::$availableReportRenderers))
  47. );
  48. }
  49. protected static function normalizeRendererType($rendererType)
  50. {
  51. return ucfirst(strtolower($rendererType));
  52. }
  53. /**
  54. * Initialize locale settings.
  55. * If not called, locale settings defaults to 'en'
  56. *
  57. * @param string $locale
  58. */
  59. abstract public function setLocale($locale);
  60. /**
  61. * Save rendering to disk
  62. *
  63. * @param string $filename without path & without format extension
  64. * @return string path of file
  65. */
  66. abstract public function sendToDisk($filename);
  67. /**
  68. * Send rendering to browser with a 'download file' prompt
  69. *
  70. * @param string $filename without path & without format extension
  71. */
  72. abstract public function sendToBrowserDownload($filename);
  73. /**
  74. * Output rendering to browser
  75. *
  76. * @param string $filename without path & without format extension
  77. */
  78. abstract public function sendToBrowserInline($filename);
  79. /**
  80. * Get rendered report
  81. */
  82. abstract public function getRenderedReport();
  83. /**
  84. * Generate the first page.
  85. *
  86. * @param string $reportTitle
  87. * @param string $prettyDate formatted date
  88. * @param string $description
  89. * @param array $reportMetadata metadata for all reports
  90. * @param array $segment segment applied to all reports
  91. */
  92. abstract public function renderFrontPage($reportTitle, $prettyDate, $description, $reportMetadata, $segment);
  93. /**
  94. * Render the provided report.
  95. * Multiple calls to this method before calling outputRendering appends each report content.
  96. *
  97. * @param array $processedReport @see API::getProcessedReport()
  98. */
  99. abstract public function renderReport($processedReport);
  100. /**
  101. * Get report attachments, ex. graph images
  102. *
  103. * @param $report
  104. * @param $processedReports
  105. * @param $prettyDate
  106. * @return array
  107. */
  108. abstract public function getAttachments($report, $processedReports, $prettyDate);
  109. /**
  110. * Append $extension to $filename
  111. *
  112. * @static
  113. * @param string $filename
  114. * @param string $extension
  115. * @return string filename with extension
  116. */
  117. protected static function appendExtension($filename, $extension)
  118. {
  119. return $filename . "." . $extension;
  120. }
  121. /**
  122. * Return $filename with temp directory and delete file
  123. *
  124. * @static
  125. * @param $filename
  126. * @return string path of file in temp directory
  127. */
  128. protected static function getOutputPath($filename)
  129. {
  130. $outputFilename = PIWIK_USER_PATH . '/tmp/assets/' . $filename;
  131. $outputFilename = SettingsPiwik::rewriteTmpPathWithInstanceId($outputFilename);
  132. @chmod($outputFilename, 0600);
  133. @unlink($outputFilename);
  134. return $outputFilename;
  135. }
  136. protected static function writeFile($filename, $extension, $content)
  137. {
  138. $filename = self::appendExtension($filename, $extension);
  139. $outputFilename = self::getOutputPath($filename);
  140. $emailReport = @fopen($outputFilename, "w");
  141. if (!$emailReport) {
  142. throw new Exception ("The file : " . $outputFilename . " can not be opened in write mode.");
  143. }
  144. fwrite($emailReport, $content);
  145. fclose($emailReport);
  146. return $outputFilename;
  147. }
  148. protected static function sendToBrowser($filename, $extension, $contentType, $content)
  149. {
  150. $filename = ReportRenderer::appendExtension($filename, $extension);
  151. ProxyHttp::overrideCacheControlHeaders();
  152. header('Content-Description: File Transfer');
  153. header('Content-Type: ' . $contentType);
  154. header('Content-Disposition: attachment; filename="' . str_replace('"', '\'', basename($filename)) . '";');
  155. header('Content-Length: ' . strlen($content));
  156. echo $content;
  157. }
  158. protected static function inlineToBrowser($contentType, $content)
  159. {
  160. header('Content-Type: ' . $contentType);
  161. echo $content;
  162. }
  163. /**
  164. * Convert a dimension-less report to a multi-row two-column data table
  165. *
  166. * @static
  167. * @param $reportMetadata array
  168. * @param $report DataTable
  169. * @param $reportColumns array
  170. * @return array DataTable $report & array $columns
  171. */
  172. protected static function processTableFormat($reportMetadata, $report, $reportColumns)
  173. {
  174. $finalReport = $report;
  175. if (empty($reportMetadata['dimension'])) {
  176. $simpleReportMetrics = $report->getFirstRow();
  177. if ($simpleReportMetrics) {
  178. $finalReport = new Simple();
  179. foreach ($simpleReportMetrics->getColumns() as $metricId => $metric) {
  180. $newRow = new Row();
  181. $newRow->addColumn("label", $reportColumns[$metricId]);
  182. $newRow->addColumn("value", $metric);
  183. $finalReport->addRow($newRow);
  184. }
  185. }
  186. $reportColumns = array(
  187. 'label' => Piwik::translate('General_Name'),
  188. 'value' => Piwik::translate('General_Value'),
  189. );
  190. }
  191. return array(
  192. $finalReport,
  193. $reportColumns,
  194. );
  195. }
  196. public static function getStaticGraph($reportMetadata, $width, $height, $evolution, $segment)
  197. {
  198. $imageGraphUrl = $reportMetadata['imageGraphUrl'];
  199. if ($evolution && !empty($reportMetadata['imageGraphEvolutionUrl'])) {
  200. $imageGraphUrl = $reportMetadata['imageGraphEvolutionUrl'];
  201. }
  202. $requestGraph = $imageGraphUrl .
  203. '&outputType=' . API::GRAPH_OUTPUT_PHP .
  204. '&format=original&serialize=0' .
  205. '&filter_truncate=' .
  206. '&width=' . $width .
  207. '&height=' . $height .
  208. ($segment != null ? '&segment=' . urlencode($segment['definition']) : '');
  209. $request = new Request($requestGraph);
  210. try {
  211. $imageGraph = $request->process();
  212. // Get image data as string
  213. ob_start();
  214. imagepng($imageGraph);
  215. $imageGraphData = ob_get_contents();
  216. ob_end_clean();
  217. imagedestroy($imageGraph);
  218. return $imageGraphData;
  219. } catch (Exception $e) {
  220. throw new Exception("ImageGraph API returned an error: " . $e->getMessage() . "\n");
  221. }
  222. }
  223. }