Support exporting to CSV, JSON and PDF

This commit is contained in:
Eric Lippmann 2018-07-31 13:34:25 +02:00
parent a646da44f0
commit 059a59b119
3 changed files with 154 additions and 2 deletions

View file

@ -2,9 +2,9 @@
namespace Icinga\Module\Businessprocess\Controllers;
use Icinga\Date\DateFormatter;
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\State\MonitoringState;
use Icinga\Module\Businessprocess\Storage\ConfigDiff;
use Icinga\Module\Businessprocess\BpNode;
use Icinga\Module\Businessprocess\Html\Element;
use Icinga\Module\Businessprocess\Html\HtmlString;
use Icinga\Module\Businessprocess\Html\HtmlTag;
@ -16,14 +16,18 @@ use Icinga\Module\Businessprocess\Renderer\Renderer;
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
use Icinga\Module\Businessprocess\Renderer\TreeRenderer;
use Icinga\Module\Businessprocess\Simulation;
use Icinga\Module\Businessprocess\State\MonitoringState;
use Icinga\Module\Businessprocess\Storage\ConfigDiff;
use Icinga\Module\Businessprocess\Storage\LegacyConfigRenderer;
use Icinga\Module\Businessprocess\Web\Component\ActionBar;
use Icinga\Module\Businessprocess\Web\Component\RenderedProcessActionBar;
use Icinga\Module\Businessprocess\Web\Component\Tabs;
use Icinga\Module\Businessprocess\Web\Controller;
use Icinga\Module\Businessprocess\Web\Url;
use Icinga\Util\Json;
use Icinga\Web\Notification;
use Icinga\Web\Widget\Tabextension\DashboardAction;
use Icinga\Web\Widget\Tabextension\OutputFormat;
class ProcessController extends Controller
{
@ -95,7 +99,12 @@ class ProcessController extends Controller
$this->redirectNow($this->url()->with('unlocked', true));
}
$this->handleFormatRequest($bp, $node);
$this->prepareControls($bp, $renderer);
$this->tabs()->extend(new OutputFormat());
$missing = $bp->getMissingChildren();
if (! empty($missing)) {
if (($count = count($missing)) > 10) {
@ -527,4 +536,65 @@ class ProcessController extends Controller
return $tabs;
}
protected function handleFormatRequest(BpConfig $bp, BpNode $node = null)
{
$desiredContentType = $this->getRequest()->getHeader('Accept');
if ($desiredContentType === 'application/json') {
$desiredFormat = 'json';
} elseif ($desiredContentType === 'text/csv') {
$desiredFormat = 'csv';
} else {
$desiredFormat = strtolower($this->params->get('format', 'html'));
}
switch ($desiredFormat) {
case 'json':
$response = $this->getResponse();
$response
->setHeader('Content-Type', 'application/json')
->setHeader('Cache-Control', 'no-store')
->setHeader(
'Content-Disposition',
'inline; filename=' . $this->getRequest()->getActionName() . '.json'
)
->appendBody(Json::sanitize($node !== null ? $node->toArray() : $bp->toArray()))
->sendResponse();
exit;
case 'csv':
$csv = fopen('php://temp', 'w');
fputcsv($csv, ['Path', 'Name', 'State', 'Since']);
foreach ($node !== null ? $node->toArray(null, true) : $bp->toArray(true) as $node) {
$data = [$node['path'], $node['name']];
if (isset($node['state'])) {
$data[] = $node['state'];
}
if (isset($node['since'])) {
$data[] = DateFormatter::formatDateTime($node['since']);
}
fputcsv($csv, $data);
}
$response = $this->getResponse();
$response
->setHeader('Content-Type', 'text/csv')
->setHeader('Cache-Control', 'no-store')
->setHeader(
'Content-Disposition',
'attachment; filename=' . $this->getRequest()->getActionName() . '.csv'
)
->sendHeaders();
rewind($csv);
fpassthru($csv);
exit;
}
}
}

View file

@ -837,4 +837,41 @@ class BpConfig
return count($this->listBpNodes()) === 0;
}
/**
* Export the config to array
*
* @param bool $flat If false, children will be added to the array key children, else the array will be flat
*
* @return array
*/
public function toArray($flat = false)
{
$data = [
'name' => $this->getTitle(),
'path' => $this->getTitle()
];
$children = [];
foreach ($this->getChildren() as $node) {
if ($flat) {
$children = array_merge($children, $node->toArray($data, $flat));
} else {
$children[] = $node->toArray($data, $flat);
}
}
if ($flat) {
$data = [$data];
if (! empty($children)) {
$data = array_merge($data, $children);
}
} else {
$data['children'] = $children;
}
return $data;
}
}

View file

@ -395,4 +395,49 @@ abstract class Node
{
unset($this->parents);
}
/**
* Export the node to array
*
* @param array $parent The node's parent. Used to construct the path to the node
* @param bool $flat If false, children will be added to the array key children, else the array will be flat
*
* @return array
*/
public function toArray(array $parent = null, $flat = false)
{
$data = [
'name' => $this->getAlias(),
'state' => $this->getStateName(),
'since' => $this->getLastStateChange()
];
if ($parent !== null) {
$data['path'] = $parent['path'] . '!' . $this->getAlias();
} else {
$data['path'] = $this->getAlias();
}
$children = [];
foreach ($this->getChildren() as $node) {
if ($flat) {
$children = array_merge($children, $node->toArray($data, $flat));
} else {
$children[] = $node->toArray($data, $flat);
}
}
if ($flat) {
$data = [$data];
if (! empty($children)) {
$data = array_merge($data, $children);
}
} else {
$data['children'] = $children;
}
return $data;
}
}