Skip to content

Commit

Permalink
Merge pull request #4 from pedro-teixeira/issue-4-pt-make-it-exportable
Browse files Browse the repository at this point in the history
Make it exportable
  • Loading branch information
Pedro Teixeira committed Apr 16, 2013
2 parents 86ef611 + 073c16b commit b97add7
Show file tree
Hide file tree
Showing 11 changed files with 337 additions and 48 deletions.
12 changes: 12 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ public function getConfigTreeBuilder()
->end()
->end()
->end()
->arrayNode('export')
->addDefaultsIfNotSet()
->children()
->scalarNode('enabled')
->defaultValue(true)
->end()
->scalarNode('path')
->defaultValue('/tmp/')
->end()
->end()
->end()
->end()
->end()
->end()
->end();
Expand Down
25 changes: 25 additions & 0 deletions Grid/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ class Column
*/
protected $renderType = 'text';

/**
* @var bool
*/
protected $exportOnly = false;

/**
* @var \PedroTeixeira\Bundle\GridBundle\Grid\Render\RenderAbstract
*/
Expand Down Expand Up @@ -266,6 +271,26 @@ public function getRenderType()
return $this->renderType;
}

/**
* @param boolean $exportOnly
*
* @return Column
*/
public function setExportOnly($exportOnly)
{
$this->exportOnly = $exportOnly;

return $this;
}

/**
* @return boolean
*/
public function getExportOnly()
{
return $this->exportOnly;
}

/**
* Return render
*
Expand Down
200 changes: 181 additions & 19 deletions Grid/GridAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ abstract class GridAbstract
*/
protected $ajax;

/**
* @var bool
*/
protected $exportable;

/**
* @var bool
*/
protected $export;

/**
* @var string
*/
protected $fileHash;

/**
* @var string
*/
Expand All @@ -79,8 +94,16 @@ public function __construct(\Symfony\Component\DependencyInjection\Container $co

$this->columns = array();
$this->url = null;

$this->ajax = $this->request->isXmlHttpRequest() ? true : false;

$this->exportable = $this->container->getParameter('pedro_teixeira_grid.export.enabled');
$this->export = $this->request->query->get('export', false);
$this->fileHash = $this->request->query->get('file_hash', null);
if (is_null($this->fileHash)) {
$this->fileHash = uniqid();
}

$now = new \DateTime();
$this->name = md5($now->format('Y-m-d H:i:s:u'));
}
Expand All @@ -101,6 +124,22 @@ public function isAjax()
return $this->ajax;
}

/**
* @return bool Check if it's an export call
*/
public function isExport()
{
return $this->export;
}

/**
* @return bool
*/
public function isResponseAnswer()
{
return ($this->isAjax() || $this->isExport());
}

/**
* @param string $name
*
Expand Down Expand Up @@ -145,6 +184,26 @@ public function getUrl()
return $this->url;
}

/**
* @param boolean $exportable
*
* @return GridAbstract
*/
public function setExportable($exportable)
{
$this->exportable = $exportable;

return $this;
}

/**
* @return boolean
*/
public function getExportable()
{
return $this->exportable;
}

/**
* @param \Doctrine\ORM\QueryBuilder $queryBuilder
*
Expand Down Expand Up @@ -199,6 +258,17 @@ public function getColumnsCount()
return count($this->getColumns());
}

/**
* @return string
*/
protected function getExportFileName()
{
$exportPath = $this->container->getParameter('pedro_teixeira_grid.export.path');
$exportFile = $exportPath . $this->getName() . '_' . $this->fileHash . '.csv';

return $exportFile;
}

/**
* Process the filters and return the result
*
Expand Down Expand Up @@ -253,26 +323,33 @@ public function getData()
$this->getQueryBuilder()->orderBy($sortIndex, $sortOrder);
}

$totalCount = Paginate::count($this->getQueryBuilder()->getQuery());
// Don't process grid for export
if (!$this->isExport()) {
$totalCount = Paginate::count($this->getQueryBuilder()->getQuery());

$totalPages = ceil($totalCount / $limit);
$totalPages = ($totalPages <= 0 ? 1 : $totalPages);
$totalPages = ceil($totalCount / $limit);
$totalPages = ($totalPages <= 0 ? 1 : $totalPages);

$page = ($page > $totalPages ? $totalPages : $page);
$page = ($page > $totalPages ? $totalPages : $page);

$queryOffset = (($page * $limit) - $limit);
$queryOffset = (($page * $limit) - $limit);

$this->getQueryBuilder()
->setFirstResult($queryOffset)
->setMaxResults($limit);
$this->getQueryBuilder()
->setFirstResult($queryOffset)
->setMaxResults($limit);

$response = array(
'page' => $page,
'page_count' => $totalPages,
'page_limit' => $limit,
'row_count' => $totalCount,
'rows' => array()
);
$response = array(
'page' => $page,
'page_count' => $totalPages,
'page_limit' => $limit,
'row_count' => $totalCount,
'rows' => array()
);
} else {
$response = array(
'rows' => array()
);
}

foreach ($this->getQueryBuilder()->getQuery()->getResult() as $key => $row) {

Expand All @@ -281,6 +358,10 @@ public function getData()
/** @var Column $column */
foreach ($this->columns as $column) {

if ($column->getExportOnly() && !$this->isExport()) {
continue;
}

$rowColumn = ' ';

// Array
Expand Down Expand Up @@ -316,7 +397,10 @@ public function getData()
);
}

$rowValue[$column->getField()] = $column->getRender()->setValue($rowColumn)->render();
$rowValue[$column->getField()] = $column->getRender()
->setValue($rowColumn)
->setStringOnly($this->isExport())
->render();
}

$response['rows'][$key] = $rowValue;
Expand All @@ -325,25 +409,103 @@ public function getData()
return $response;
}

/**
* @return array
*/
public function processGrid()
{
return $this->getData();
}

/**
* @return array
*/
public function processExport()
{
set_time_limit(0);

$exportFile = $this->getExportFileName();

$fileHandler = fopen($exportFile, 'w');

$columnsHeader = array();

/** @var Column $column */
foreach ($this->getColumns() as $column) {
if (!$column->getTwig()) {
$columnsHeader[$column->getField()] = $column->getName();
}
}

fputcsv($fileHandler, $columnsHeader);

$data = $this->getData();

foreach ($data['rows'] as $row) {

$rowContent = array();

foreach ($row as $key => $column) {
if (isset($columnsHeader[$key])) {
$rowContent[] = $column;
}
}

fputcsv($fileHandler, $rowContent);
}

fclose($fileHandler);

return array(
'file_hash' => $this->fileHash
);
}

/**
* Returns the an array with a GridView instance for normal requests and json for AJAX requests
*
* @throws \Exception
* @return GridView | \Symfony\Component\HttpFoundation\Response
*/
public function render()
{
if ($this->isAjax()) {
if ($this->isExport()) {

if (!$this->getExportable()) {
throw new \Exception('Export not allowed');
}

$data = $this->processExport();
} else {
$data = $this->processGrid();
}

$data = $this->getData();
$json = json_encode($data);

$response = new Response();
$response->setContent($json);
$response->headers->set('Content-Type', 'application/json');
$response->setContent($json);

return $response;
} else {
return new GridView($this, $this->container);
if ($this->isExport()) {

if (!$this->getExportable()) {
throw new \Exception('Export not allowed');
}

$exportFile = $this->getExportFileName();

$response = new Response();
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($exportFile) . '"');
$response->setContent(file_get_contents($exportFile));

return $response;
} else {
return new GridView($this, $this->container);
}
}
}
}
27 changes: 26 additions & 1 deletion Grid/Render/RenderAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ abstract class RenderAbstract
*/
protected $value;

/**
* @var bool
*/
protected $stringOnly = false;

/**
* @return string
*/
Expand All @@ -25,7 +30,7 @@ abstract public function render();
/**
* @param \Symfony\Component\DependencyInjection\Container $container
*
* @return \PedroTeixeira\Bundle\GridBundle\Grid\Filter\RenderAbstract
* @return \PedroTeixeira\Bundle\GridBundle\Grid\Render\RenderAbstract
*/
public function __construct(\Symfony\Component\DependencyInjection\Container $container)
{
Expand All @@ -51,4 +56,24 @@ public function getValue()
{
return $this->value;
}

/**
* @param boolean $stringOnly
*
* @return RenderAbstract
*/
public function setStringOnly($stringOnly)
{
$this->stringOnly = $stringOnly;

return $this;
}

/**
* @return boolean
*/
public function getStringOnly()
{
return $this->stringOnly;
}
}
Loading

0 comments on commit b97add7

Please sign in to comment.