Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorThomas Steur <thomas.steur@googlemail.com>2014-08-04 00:44:33 +0400
committerThomas Steur <thomas.steur@googlemail.com>2014-08-06 11:02:56 +0400
commit49b24c2e0cfbc1839b80d95f67f04f4420d8630f (patch)
tree5f3beef4c2fb07e5c141d358287f3a7972243a25 /core
parent6da08c8c9dfa30d6925a40fe75110c10a3e7ada9 (diff)
refs #5896 started to move rendering code from response builder in other classes which also allows plugins to define their own render formats
Diffstat (limited to 'core')
-rw-r--r--core/API/ApiRenderer.php126
-rw-r--r--core/API/ResponseBuilder.php336
-rw-r--r--core/DataTable/Renderer.php46
-rw-r--r--core/DataTable/Renderer/Console.php13
-rw-r--r--core/DataTable/Renderer/Csv.php15
-rw-r--r--core/DataTable/Renderer/Html.php25
-rw-r--r--core/DataTable/Renderer/Json.php27
-rw-r--r--core/DataTable/Renderer/Php.php22
-rw-r--r--core/DataTable/Renderer/Rss.php21
-rw-r--r--core/DataTable/Renderer/Xml.php31
-rw-r--r--core/Piwik.php17
11 files changed, 202 insertions, 477 deletions
diff --git a/core/API/ApiRenderer.php b/core/API/ApiRenderer.php
new file mode 100644
index 0000000000..ada1e3cd5d
--- /dev/null
+++ b/core/API/ApiRenderer.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\API;
+
+use Piwik\Common;
+use Piwik\DataTable\Renderer;
+use Piwik\DataTable;
+use Exception;
+use Piwik\Piwik;
+use Piwik\Plugin;
+
+/**
+ * API renderer
+ */
+abstract class ApiRenderer
+{
+ protected $request;
+
+ final public function __construct($request)
+ {
+ $this->request = $request;
+ $this->init();
+ }
+
+ protected function init() {}
+
+ abstract public function sendHeader();
+
+ public function renderSuccess($message)
+ {
+ return 'Success:' . $message;
+ }
+
+ public function renderException($message, \Exception $exception)
+ {
+ return $message;
+ }
+
+ public function renderScalar($scalar)
+ {
+ $dataTable = new DataTable\Simple();
+ $dataTable->addRowsFromArray(array($scalar));
+ return $this->renderDataTable($dataTable);
+ }
+
+ public function renderDataTable($dataTable)
+ {
+ $renderer = $this->buildDataTableRenderer($dataTable);
+ return $renderer->render();
+ }
+
+ public function renderArray($array)
+ {
+ $renderer = $this->buildDataTableRenderer($array);
+ return $renderer->render();
+ }
+
+ public function renderObject($object)
+ {
+ $exception = new Exception('The API cannot handle this data structure.');
+ return $this->renderException($exception->getMessage(), $exception);
+ }
+
+ public function renderResource($resource)
+ {
+ $exception = new Exception('The API cannot handle this data structure.');
+ return $this->renderException($exception->getMessage(), $exception);
+ }
+
+ /**
+ * @param $dataTable
+ * @return Renderer
+ */
+ protected function buildDataTableRenderer($dataTable)
+ {
+ $format = self::getFormatFromClass(get_class($this));
+ $renderer = Renderer::factory($format);
+ $renderer->setTable($dataTable);
+ $renderer->setRenderSubTables(Common::getRequestVar('expanded', false, 'int', $this->request));
+ $renderer->setHideIdSubDatableFromResponse(Common::getRequestVar('hideIdSubDatable', false, 'int', $this->request));
+
+ return $renderer;
+ }
+
+ /**
+ * @param string $format
+ * @param array $request
+ * @return ApiRenderer
+ * @throws Exception
+ */
+ public static function factory($format, $request)
+ {
+ $formatToCheck = '\\' . ucfirst(strtolower($format));
+
+ $rendererClassnames = Plugin\Manager::getInstance()->findMultipleComponents('Renderer', 'Piwik\\API\\ApiRenderer');
+
+ foreach ($rendererClassnames as $klassName) {
+ if (Common::stringEndsWith($klassName, $formatToCheck)) {
+ return new $klassName($request);
+ }
+ }
+
+ $availableRenderers = array();
+ foreach ($rendererClassnames as $rendererClassname) {
+ $availableRenderers[] = self::getFormatFromClass($rendererClassname);
+ }
+
+ $availableRenderers = implode(', ', $availableRenderers);
+ @header('Content-Type: text/plain; charset=utf-8');
+ throw new Exception(Piwik::translate('General_ExceptionInvalidRendererFormat', array($format, $availableRenderers)));
+ }
+
+ private static function getFormatFromClass($klassname)
+ {
+ $klass = explode('\\', $klassname);
+
+ return strtolower(end($klass));
+ }
+
+}
diff --git a/core/API/ResponseBuilder.php b/core/API/ResponseBuilder.php
index 54c6cc664d..4eb0f9a1c8 100644
--- a/core/API/ResponseBuilder.php
+++ b/core/API/ResponseBuilder.php
@@ -13,17 +13,18 @@ use Piwik\API\DataTableManipulator\Flattener;
use Piwik\API\DataTableManipulator\LabelFilter;
use Piwik\API\DataTableManipulator\ReportTotalsCalculator;
use Piwik\Common;
-use Piwik\DataTable\Renderer\Json;
use Piwik\DataTable\Renderer;
-use Piwik\DataTable\Simple;
+use Piwik\DataTable\DataTableInterface;
use Piwik\DataTable;
+use Piwik\Piwik;
/**
*/
class ResponseBuilder
{
- private $request = null;
private $outputFormat = null;
+ private $apiRenderer = null;
+ private $request = null;
private $apiModule = false;
private $apiMethod = false;
@@ -34,8 +35,9 @@ class ResponseBuilder
*/
public function __construct($outputFormat, $request = array())
{
- $this->request = $request;
$this->outputFormat = $outputFormat;
+ $this->request = $request;
+ $this->apiRenderer = ApiRenderer::factory($outputFormat, $request);
}
/**
@@ -70,61 +72,21 @@ class ResponseBuilder
$this->apiModule = $apiModule;
$this->apiMethod = $apiMethod;
- if($this->outputFormat == 'original') {
- @header('Content-Type: text/plain; charset=utf-8');
- }
- return $this->renderValue($value);
- }
-
- /**
- * Returns an error $message in the requested $format
- *
- * @param Exception $e
- * @throws Exception
- * @return string
- */
- public function getResponseException(Exception $e)
- {
- $format = strtolower($this->outputFormat);
-
- if ($format == 'original') {
- throw $e;
- }
+ $this->apiRenderer->sendHeader();
- try {
- $renderer = Renderer::factory($format);
- } catch (Exception $exceptionRenderer) {
- return "Error: " . $e->getMessage() . " and: " . $exceptionRenderer->getMessage();
- }
-
- $e = $this->decorateExceptionWithDebugTrace($e);
-
- $renderer->setException($e);
-
- if ($format == 'php') {
- $renderer->setSerialize($this->caseRendererPHPSerialize());
- }
-
- return $renderer->renderException();
- }
-
- /**
- * @param $value
- * @return string
- */
- protected function renderValue($value)
- {
// when null or void is returned from the api call, we handle it as a successful operation
if (!isset($value)) {
- return $this->handleSuccess();
+ if (ob_get_contents()) {
+ return null;
+ }
+
+ return $this->apiRenderer->renderSuccess('ok');
}
// If the returned value is an object DataTable we
// apply the set of generic filters if asked in the URL
// and we render the DataTable according to the format specified in the URL
- if ($value instanceof DataTable
- || $value instanceof DataTable\Map
- ) {
+ if ($value instanceof DataTableInterface) {
return $this->handleDataTable($value);
}
@@ -137,26 +99,38 @@ class ResponseBuilder
return $this->handleArray($value);
}
- // original data structure requested, we return without process
- if ($this->outputFormat == 'original') {
- return $value;
+ if (is_object($value)) {
+ return $this->apiRenderer->renderObject($value);
}
- if (is_object($value)
- || is_resource($value)
- ) {
- return $this->getResponseException(new Exception('The API cannot handle this data structure.'));
+ if (is_resource($value)) {
+ return $this->apiRenderer->renderResource($value);
}
- // bool // integer // float // serialized object
- return $this->handleScalar($value);
+ return $this->apiRenderer->renderScalar($value);
+ }
+
+ /**
+ * Returns an error $message in the requested $format
+ *
+ * @param Exception $e
+ * @throws Exception
+ * @return string
+ */
+ public function getResponseException(Exception $e)
+ {
+ $e = $this->decorateExceptionWithDebugTrace($e);
+ $message = $this->formatExceptionMessage($e);
+
+ $this->apiRenderer->sendHeader();
+ return $this->apiRenderer->renderException($message, $e);
}
/**
* @param Exception $e
* @return Exception
*/
- protected function decorateExceptionWithDebugTrace(Exception $e)
+ private function decorateExceptionWithDebugTrace(Exception $e)
{
// If we are in tests, show full backtrace
if (defined('PIWIK_PATH_TEST_TO_ROOT')) {
@@ -165,137 +139,25 @@ class ResponseBuilder
} else {
$message = $e->getMessage() . "\n \n --> To temporarily debug this error further, set const PIWIK_PRINT_ERROR_BACKTRACE=true; in index.php";
}
- return new Exception($message);
- }
- return $e;
- }
- /**
- * Returns true if the user requested to serialize the output data (&serialize=1 in the request)
- *
- * @param mixed $defaultSerializeValue Default value in case the user hasn't specified a value
- * @return bool
- */
- protected function caseRendererPHPSerialize($defaultSerializeValue = 1)
- {
- $serialize = Common::getRequestVar('serialize', $defaultSerializeValue, 'int', $this->request);
- if ($serialize) {
- return true;
- }
- return false;
- }
-
- /**
- * Apply the specified renderer to the DataTable
- *
- * @param DataTable|array $dataTable
- * @return string
- */
- protected function getRenderedDataTable($dataTable)
- {
- $format = strtolower($this->outputFormat);
-
- // if asked for original dataStructure
- if ($format == 'original') {
- // by default "original" data is not serialized
- if ($this->caseRendererPHPSerialize($defaultSerialize = 0)) {
- $dataTable = serialize($dataTable);
- }
- return $dataTable;
- }
-
- $method = Common::getRequestVar('method', '', 'string', $this->request);
-
- $renderer = Renderer::factory($format);
- $renderer->setTable($dataTable);
- $renderer->setRenderSubTables(Common::getRequestVar('expanded', false, 'int', $this->request));
- $renderer->setHideIdSubDatableFromResponse(Common::getRequestVar('hideIdSubDatable', false, 'int', $this->request));
-
- if ($format == 'php') {
- $renderer->setSerialize($this->caseRendererPHPSerialize());
- $renderer->setPrettyDisplay(Common::getRequestVar('prettyDisplay', false, 'int', $this->request));
- } else if ($format == 'html') {
- $renderer->setTableId($this->request['method']);
- } else if ($format == 'csv' || $format == 'tsv') {
- $renderer->setConvertToUnicode(Common::getRequestVar('convertToUnicode', true, 'int', $this->request));
- }
-
- // prepare translation of column names
- if ($format == 'html' || $format == 'csv' || $format == 'tsv' || $format = 'rss') {
- $renderer->setApiMethod($method);
- $renderer->setIdSite(Common::getRequestVar('idSite', false, 'int', $this->request));
- $renderer->setTranslateColumnNames(Common::getRequestVar('translateColumnNames', false, 'int', $this->request));
+ return new Exception($message);
}
- return $renderer->render();
+ return $e;
}
- /**
- * Returns a success $message in the requested $format
- *
- * @param string $message
- * @return string
- */
- protected function handleSuccess($message = 'ok')
+ private function formatExceptionMessage(Exception $exception)
{
- // return a success message only if no content has already been buffered, useful when APIs return raw text or html content to the browser
- if (!ob_get_contents()) {
- switch ($this->outputFormat) {
- case 'xml':
- @header("Content-Type: text/xml;charset=utf-8");
- $return =
- "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" .
- "<result>\n" .
- "\t<success message=\"" . $message . "\" />\n" .
- "</result>";
- break;
- case 'json':
- @header("Content-Type: application/json");
- $return = '{"result":"success", "message":"' . $message . '"}';
- break;
- case 'php':
- $return = array('result' => 'success', 'message' => $message);
- if ($this->caseRendererPHPSerialize()) {
- $return = serialize($return);
- }
- break;
-
- case 'csv':
- @header("Content-Type: application/vnd.ms-excel");
- @header("Content-Disposition: attachment; filename=piwik-report-export.csv");
- $return = "message\n" . $message;
- break;
-
- default:
- $return = 'Success:' . $message;
- break;
- }
- return $return;
+ $message = $exception->getMessage();
+ if (\Piwik_ShouldPrintBackTraceWithMessage()) {
+ $message .= "\n" . $exception->getTraceAsString();
}
- }
- /**
- * Converts the given scalar to an data table
- *
- * @param mixed $scalar
- * @return string
- */
- protected function handleScalar($scalar)
- {
- $dataTable = new Simple();
- $dataTable->addRowsFromArray(array($scalar));
- return $this->getRenderedDataTable($dataTable);
+ return Renderer::formatValueXml($message);
}
- /**
- * Handles the given data table
- *
- * @param DataTable $datatable
- * @return string
- */
protected function handleDataTable($datatable)
{
- // process request
$label = $this->getLabelFromRequest($this->request);
// if requested, flatten nested tables
@@ -345,120 +207,28 @@ class ResponseBuilder
$filter = new LabelFilter($this->apiModule, $this->apiMethod, $this->request);
$datatable = $filter->filter($label, $datatable, $addLabelIndex);
}
- return $this->getRenderedDataTable($datatable);
+
+ return $this->apiRenderer->renderDataTable($datatable);
}
- /**
- * Converts the given simple array to a data table
- *
- * @param array $array
- * @return string
- */
protected function handleArray($array)
{
- if ($this->outputFormat == 'original') {
- // we handle the serialization. Because some php array have a very special structure that
- // couldn't be converted with the automatic DataTable->addRowsFromSimpleArray
- // the user may want to request the original PHP data structure serialized by the API
- // in case he has to setup serialize=1 in the URL
- if ($this->caseRendererPHPSerialize($defaultSerialize = 0)) {
- return serialize($array);
- }
- return $array;
- }
-
- $multiDimensional = $this->handleMultiDimensionalArray($array);
- if ($multiDimensional !== false) {
- return $multiDimensional;
+ $firstArray = null;
+ $firstKey = null;
+ if (!empty($array)) {
+ $firstArray = reset($array);
+ $firstKey = key($array);
}
- $isAssoc = ($array !== array_values($array));
+ $isAssoc = !empty($firstArray) && is_numeric($firstKey) && is_array($firstArray) && !Piwik::isMultiDimensionalArray($array) && count(array_filter(array_keys($firstArray), 'is_string'));
if ($isAssoc) {
- $dataTable = new DataTable();
- $dataTable->addRowsFromSimpleArray($array);
-
- return $this->handleDataTable($dataTable);
- }
-
- return $this->getRenderedDataTable($array);
- }
+ // $dataTable = DataTable::makeFromSimpleArray($array);
- /**
- * Is this a multi dimensional array?
- * Multi dim arrays are not supported by the Datatable renderer.
- * We manually render these.
- *
- * array(
- * array(
- * 1,
- * 2 => array( 1,
- * 2
- * )
- * ),
- * array( 2,
- * 3
- * )
- * );
- *
- * @param array $array
- * @return string|bool false if it isn't a multidim array
- */
- protected function handleMultiDimensionalArray($array)
- {
- $first = reset($array);
- foreach ($array as $first) {
- if (is_array($first)) {
- foreach ($first as $value) {
- // Yes, this is a multi dim array
- if (is_array($value)) {
- switch ($this->outputFormat) {
- case 'json':
- @header("Content-Type: application/json");
- return self::convertMultiDimensionalArrayToJson($array);
- break;
-
- case 'php':
- if ($this->caseRendererPHPSerialize($defaultSerialize = 0)) {
- return serialize($array);
- }
- return $array;
-
- case 'xml':
- @header("Content-Type: text/xml;charset=utf-8");
- return $this->getRenderedDataTable($array);
- default:
- break;
- }
- }
- }
- }
+ // return $this->handleDataTable($dataTable);
}
- return false;
- }
- /**
- * Render a multidimensional array to Json
- * Handle DataTable|Set elements in the first dimension only, following case does not work:
- * array(
- * array(
- * DataTable,
- * 2 => array(
- * 1,
- * 2
- * ),
- * ),
- * );
- *
- * @param array $array can contain scalar, arrays, DataTable and Set
- * @return string
- */
- public static function convertMultiDimensionalArrayToJson($array)
- {
- $jsonRenderer = new Json();
- $jsonRenderer->setTable($array);
- $renderedReport = $jsonRenderer->render();
- return $renderedReport;
+ return $this->apiRenderer->renderArray($array);
}
/**
diff --git a/core/DataTable/Renderer.php b/core/DataTable/Renderer.php
index 679d261f3f..ddcde91cf3 100644
--- a/core/DataTable/Renderer.php
+++ b/core/DataTable/Renderer.php
@@ -111,22 +111,6 @@ abstract class Renderer
abstract public function render();
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- abstract public function renderException();
-
- protected function getExceptionMessage()
- {
- $message = $this->exception->getMessage();
- if (\Piwik_ShouldPrintBackTraceWithMessage()) {
- $message .= "\n" . $this->exception->getTraceAsString();
- }
- return self::renderHtmlEntities($message);
- }
-
- /**
* @see render()
* @return string
*/
@@ -144,29 +128,14 @@ abstract class Renderer
public function setTable($table)
{
if (!is_array($table)
- && !($table instanceof DataTable)
- && !($table instanceof DataTable\Map)
+ && !($table instanceof DataTableInterface)
) {
- throw new Exception("DataTable renderers renderer accepts only DataTable and Map instances, and arrays.");
+ throw new Exception("DataTable renderers renderer accepts only DataTable, Simple and Map instances, and arrays.");
}
$this->table = $table;
}
/**
- * Set the Exception to be rendered
- *
- * @param Exception $exception to be rendered
- * @throws Exception
- */
- public function setException($exception)
- {
- if (!($exception instanceof Exception)) {
- throw new Exception("The exception renderer accepts only an Exception object.");
- }
- $this->exception = $exception;
- }
-
- /**
* @var array
*/
protected static $availableRenderers = array('xml',
@@ -209,17 +178,6 @@ abstract class Renderer
}
/**
- * Returns $rawData after all applicable characters have been converted to HTML entities.
- *
- * @param String $rawData data to be converted
- * @return String
- */
- protected static function renderHtmlEntities($rawData)
- {
- return self::formatValueXml($rawData);
- }
-
- /**
* Format a value to xml
*
* @param string|number|bool $value value to format
diff --git a/core/DataTable/Renderer/Console.php b/core/DataTable/Renderer/Console.php
index b9d8cc33a7..88161165fc 100644
--- a/core/DataTable/Renderer/Console.php
+++ b/core/DataTable/Renderer/Console.php
@@ -31,23 +31,10 @@ class Console extends Renderer
*/
public function render()
{
- $this->renderHeader();
return $this->renderTable($this->table);
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- public function renderException()
- {
- $this->renderHeader();
- $exceptionMessage = $this->getExceptionMessage();
- return 'Error: ' . $exceptionMessage;
- }
-
- /**
* Sets the prefix to be used
*
* @param string $str new prefix
diff --git a/core/DataTable/Renderer/Csv.php b/core/DataTable/Renderer/Csv.php
index cf28d3ca6c..ae7d2acbb3 100644
--- a/core/DataTable/Renderer/Csv.php
+++ b/core/DataTable/Renderer/Csv.php
@@ -93,18 +93,6 @@ class Csv extends Renderer
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- function renderException()
- {
- @header('Content-Type: text/html; charset=utf-8');
- $exceptionMessage = $this->getExceptionMessage();
- return 'Error: ' . $exceptionMessage;
- }
-
- /**
* Enables / Disables unicode converting
*
* @param $bool
@@ -353,8 +341,7 @@ class Csv extends Renderer
}
// silent fail otherwise unit tests fail
- @header('Content-Type: application/vnd.ms-excel');
- @header('Content-Disposition: attachment; filename="' . $fileName . '"');
+ @header('Content-Disposition: attachment; filename="' . $fileName . '"', true);
ProxyHttp::overrideCacheControlHeaders();
}
diff --git a/core/DataTable/Renderer/Html.php b/core/DataTable/Renderer/Html.php
index eb130ec05b..e193ebfdc5 100644
--- a/core/DataTable/Renderer/Html.php
+++ b/core/DataTable/Renderer/Html.php
@@ -29,27 +29,18 @@ class Html extends Renderer
*
* @param string $id
*/
- function setTableId($id)
+ public function setTableId($id)
{
$this->tableId = str_replace('.', '_', $id);
}
/**
- * Output HTTP Content-Type header
- */
- protected function renderHeader()
- {
- @header('Content-Type: text/html; charset=utf-8');
- }
-
- /**
* Computes the dataTable output and returns the string/binary
*
* @return string
*/
- function render()
+ public function render()
{
- $this->renderHeader();
$this->tableStructure = array();
$this->allColumns = array();
$this->i = 0;
@@ -58,18 +49,6 @@ class Html extends Renderer
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- function renderException()
- {
- $this->renderHeader();
- $exceptionMessage = $this->getExceptionMessage();
- return nl2br($exceptionMessage);
- }
-
- /**
* Computes the output for the given data table
*
* @param DataTable $table
diff --git a/core/DataTable/Renderer/Json.php b/core/DataTable/Renderer/Json.php
index ae1bf3ef05..adfd499b8f 100644
--- a/core/DataTable/Renderer/Json.php
+++ b/core/DataTable/Renderer/Json.php
@@ -27,28 +27,10 @@ class Json extends Renderer
*/
public function render()
{
- $this->renderHeader();
return $this->renderTable($this->table);
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- function renderException()
- {
- $this->renderHeader();
-
- $exceptionMessage = $this->getExceptionMessage();
- $exceptionMessage = str_replace(array("\r\n", "\n"), "", $exceptionMessage);
-
- $result = json_encode(array('result' => 'error', 'message' => $exceptionMessage));
-
- return $this->jsonpWrap($result);
- }
-
- /**
* Computes the output for the given data table
*
* @param DataTable $table
@@ -112,15 +94,6 @@ class Json extends Renderer
return $str;
}
- /**
- * Sends the http header for json file
- */
- protected function renderHeader()
- {
- self::sendHeaderJSON();
- ProxyHttp::overrideCacheControlHeaders();
- }
-
public static function sendHeaderJSON()
{
@header('Content-Type: application/json; charset=utf-8');
diff --git a/core/DataTable/Renderer/Php.php b/core/DataTable/Renderer/Php.php
index a1475f1969..56360b939c 100644
--- a/core/DataTable/Renderer/Php.php
+++ b/core/DataTable/Renderer/Php.php
@@ -71,8 +71,6 @@ class Php extends Renderer
*/
public function render($dataTable = null)
{
- $this->renderHeader();
-
if (is_null($dataTable)) {
$dataTable = $this->table;
}
@@ -88,26 +86,6 @@ class Php extends Renderer
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- public function renderException()
- {
- $this->renderHeader();
-
- $exceptionMessage = $this->getExceptionMessage();
-
- $return = array('result' => 'error', 'message' => $exceptionMessage);
-
- if ($this->serialize) {
- $return = serialize($return);
- }
-
- return $return;
- }
-
- /**
* Produces a flat php array from the DataTable, putting "columns" and "metadata" on the same level.
*
* For example, when a originalRender() would be
diff --git a/core/DataTable/Renderer/Rss.php b/core/DataTable/Renderer/Rss.php
index 691f1f25b9..8adda661be 100644
--- a/core/DataTable/Renderer/Rss.php
+++ b/core/DataTable/Renderer/Rss.php
@@ -31,23 +31,10 @@ class Rss extends Renderer
*/
function render()
{
- $this->renderHeader();
return $this->renderTable($this->table);
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- function renderException()
- {
- header('Content-type: text/plain');
- $exceptionMessage = $this->getExceptionMessage();
- return 'Error: ' . $exceptionMessage;
- }
-
- /**
* Computes the output for the given data table
*
* @param DataTable $table
@@ -101,14 +88,6 @@ class Rss extends Renderer
}
/**
- * Sends the xml file http header
- */
- protected function renderHeader()
- {
- @header('Content-Type: text/xml; charset=utf-8');
- }
-
- /**
* Returns the RSS file footer
*
* @return string
diff --git a/core/DataTable/Renderer/Xml.php b/core/DataTable/Renderer/Xml.php
index a18e475d04..9eb7db914b 100644
--- a/core/DataTable/Renderer/Xml.php
+++ b/core/DataTable/Renderer/Xml.php
@@ -30,32 +30,12 @@ class Xml extends Renderer
*
* @return string
*/
- function render()
+ public function render()
{
- $this->renderHeader();
return '<?xml version="1.0" encoding="utf-8" ?>' . "\n" . $this->renderTable($this->table);
}
/**
- * Computes the exception output and returns the string/binary
- *
- * @return string
- */
- function renderException()
- {
- $this->renderHeader();
-
- $exceptionMessage = $this->getExceptionMessage();
-
- $return = '<?xml version="1.0" encoding="utf-8" ?>' . "\n" .
- "<result>\n" .
- "\t<error message=\"" . $exceptionMessage . "\" />\n" .
- "</result>";
-
- return $return;
- }
-
- /**
* Converts the given data table to an array
*
* @param DataTable|DataTable/Map $table data table to convert
@@ -430,13 +410,4 @@ class Xml extends Renderer
}
return $out;
}
-
- /**
- * Sends the XML headers
- */
- protected function renderHeader()
- {
- // silent fail because otherwise it throws an exception in the unit tests
- @header('Content-Type: text/xml; charset=utf-8');
- }
}
diff --git a/core/Piwik.php b/core/Piwik.php
index 4c4f6fba74..befe249923 100644
--- a/core/Piwik.php
+++ b/core/Piwik.php
@@ -742,6 +742,23 @@ class Piwik
return false;
}
+ public static function isMultiDimensionalArray($array)
+ {
+ $first = reset($array);
+ foreach ($array as $first) {
+ if (is_array($first)) {
+ foreach ($first as $value) {
+ // Yes, this is a multi dim array
+ if (is_array($value)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
/**
* Returns the class name of an object without its namespace.
*