diff --git a/src/ZfcDatagrid/Column/Action/Button.php b/src/ZfcDatagrid/Column/Action/Button.php index 99ce2efe..eef83b6d 100644 --- a/src/ZfcDatagrid/Column/Action/Button.php +++ b/src/ZfcDatagrid/Column/Action/Button.php @@ -42,6 +42,6 @@ public function toHtml () $attributes = implode(' ', $attributes); - return '' . $this->getLabel() . ''; + return '' . $this->getLabel() . ''; } } diff --git a/src/ZfcDatagrid/DataSource/DataSourceInterface.php b/src/ZfcDatagrid/DataSource/DataSourceInterface.php index c069d418..b338a00f 100644 --- a/src/ZfcDatagrid/DataSource/DataSourceInterface.php +++ b/src/ZfcDatagrid/DataSource/DataSourceInterface.php @@ -1,9 +1,6 @@ cache; } + /** + * Set the cache id + * + * @param string $id + */ public function setCacheId($id) { $this->cacheId = (string) $id; } + /** + * Get the cache id + * + * @return string + */ public function getCacheId() { if ($this->cacheId === null) { @@ -397,6 +409,11 @@ public function getDataSource() return $this->dataSource; } + /** + * Datasource defined? + * + * @return boolean + */ public function hasDataSource() { if ($this->dataSource !== null) { @@ -469,6 +486,11 @@ public function getParameters() return $this->parameters; } + /** + * Has parameters? + * + * @return boolean + */ public function hasParameters() { if (count($this->getParameters()) > 0) { @@ -478,6 +500,11 @@ public function hasParameters() return false; } + /** + * Set the base url + * + * @param string $url + */ public function setUrl($url) { $this->url = $url; @@ -492,11 +519,21 @@ public function getUrl() return $this->url; } + /** + * Set the export renderers (overwrite the config) + * + * @param array $renderers + */ public function setExportRenderers(array $renderers = array()) { $this->exportRenderers = $renderers; } + /** + * Get the export renderers + * + * @return array + */ public function getExportRenderers() { if ($this->exportRenderers === null) { @@ -540,6 +577,10 @@ public function getColumnByUniqueId($id) return null; } + /** + * + * @param boolean $mode + */ public function setUserFilterDisabled($mode = true) { $this->isUserFilterEnabled = (bool) ! $mode; @@ -573,6 +614,10 @@ public function getRowClickAction() return $this->rowClickAction; } + /** + * + * @return boolean + */ public function hasRowClickAction() { if (is_object($this->rowClickAction)) { @@ -595,7 +640,37 @@ public function setRenderer($name = null) } /** - * Return the current renderer and give him some knowledge about the rest + * Get the current renderer name + * + * @return string + */ + public function getRendererName() + { + $options = $this->getOptions(); + $parameterName = $options['generalParameterNames']['rendererType']; + + if ($this->forceRenderer !== null) { + // A special renderer was given -> use is + $rendererName = $this->forceRenderer; + } else { + // DEFAULT + if ($this->getRequest() instanceof ConsoleRequest) { + $rendererName = $options['settings']['default']['renderer']['console']; + } else { + $rendererName = $options['settings']['default']['renderer']['http']; + } + } + + // From request + if ($this->getRequest() instanceof HttpRequest && $this->getRequest()->getQuery($parameterName) != '') { + $rendererName = $this->getRequest()->getQuery($parameterName); + } + + return $rendererName; + } + + /** + * Return the current renderer * * @return \ZfcDatagrid\Renderer\AbstractRenderer */ @@ -623,6 +698,8 @@ public function getRenderer() $renderer->setTitle($this->getTitle()); $renderer->setColumns($this->getColumns()); $renderer->setCacheId($this->getCacheId()); + $renderer->setCacheData($this->getCache() + ->getItem($this->getCacheId())); $this->renderer = $renderer; } else { @@ -633,61 +710,32 @@ public function getRenderer() return $this->renderer; } - /** - * Get the current renderer name - * - * @return string - */ - public function getRendererName() + public function isDataLoaded() { - $options = $this->getOptions(); - $parameterName = $options['generalParameterNames']['rendererType']; - - if ($this->forceRenderer !== null) { - // A special renderer was given -> use is - $rendererName = $this->forceRenderer; - } else { - // DEFAULT - if ($this->getRequest() instanceof ConsoleRequest) { - $rendererName = $options['settings']['default']['renderer']['console']; - } else { - $rendererName = $options['settings']['default']['renderer']['http']; - } - } - - //From request - if ($this->getRequest() instanceof HttpRequest && $this->getRequest()->getQuery($parameterName) != '') { - $rendererName = $this->getRequest()->getQuery($parameterName); - } - - return $rendererName; + return (bool) $this->isDataLoaded; } /** - * Prepare all variables for the view - * - title - * - data - * - grid - * - ... + * Load the data */ - public function execute() + public function loadData() { + if ($this->isDataLoaded === true) { + return true; + } + if ($this->isInit() !== true) { - throw new \Exception('The init() method has to be called, before you can call execute()!'); + throw new \Exception('The init() method has to be called, before you can call loadData()!'); } if ($this->hasDataSource() === false) { - throw new \Exception('No datasource defined! So no grid to display...'); + throw new \Exception('No datasource defined! Please call "setDataSource()" first"'); } /** - * Read cache + * Apply cache */ $renderer = $this->getRenderer(); - $renderer->setCacheData($this->getCache() - ->getItem($this->getCacheId())); - - $this->isExecuted = true; /** * Step 1) Apply needed columns + filters + sort @@ -714,6 +762,7 @@ public function execute() $this->getDataSource()->addFilter($filter); } } + /** * Save cache */ @@ -769,20 +818,49 @@ public function execute() $prepareData->prepare(); $this->preparedData = $prepareData->getData(); + $this->isDataLoaded = true; + } + + /** + * @deprecated use render() instead! + */ + public function execute(){ + if($this->isRendered() === false){ + $this->render(); + } + } + /** + * Render the grid + */ + public function render() + { + if($this->isDataLoaded() === false){ + $this->loadData(); + } + /** * Step 4) Render the data to the defined output format (HTML, PDF...) * - Styling the values based on column (and value) */ + $renderer = $this->getRenderer(); + $renderer->setTitle($this->getTitle()); $renderer->setPaginator($this->getPaginator()); $renderer->setData($this->getPreparedData()); $renderer->prepareViewModel($this); $this->response = $renderer->execute(); + + $this->isRendered = true; } - public function isExecuted() + /** + * Is already rendered? + * + * @return boolean + */ + public function isRendered() { - return (bool) $this->isExecuted; + return (bool) $this->isRendered; } /** @@ -793,7 +871,7 @@ public function isExecuted() public function getPaginator() { if ($this->paginator === null) { - throw new \Exception('Paginator is only available, after the grid has been executed!'); + throw new \Exception('Paginator is only available after calling "loadData()"'); } return $this->paginator; @@ -831,7 +909,7 @@ public function getToolbarTemplate() public function setViewModel(ViewModel $viewModel) { if ($this->viewModel !== null) { - throw new \Exception('A viewModel is already set (did you already called execute()?)'); + throw new \Exception('A viewModel is already set (did you already called render()?)'); } $this->viewModel = $viewModel; @@ -856,8 +934,8 @@ public function getViewModel() */ public function getResponse() { - if (! $this->isExecuted()) { - $this->execute(); + if (! $this->isRendered()) { + $this->render(); } return $this->response; diff --git a/src/ZfcDatagrid/Renderer/TCPDF/Renderer.php b/src/ZfcDatagrid/Renderer/TCPDF/Renderer.php index aee8a3e6..8c08157d 100644 --- a/src/ZfcDatagrid/Renderer/TCPDF/Renderer.php +++ b/src/ZfcDatagrid/Renderer/TCPDF/Renderer.php @@ -5,40 +5,39 @@ namespace ZfcDatagrid\Renderer\TCPDF; use ZfcDatagrid\Renderer\AbstractRenderer; -use ZfcDatagrid\Column; -use TCPDF; use Zend\Http\Response\Stream as ResponseStream; use Zend\Http\Headers; +use TCPDF; class Renderer extends AbstractRenderer { private $columnsToExport; - + private $columnsPositionX = array(); - + /** - * + * * @var TCPDF */ private $pdf; - - public function getName () + + public function getName() { return 'TCPDF'; } - public function isExport () + public function isExport() { return true; } - public function isHtml () + public function isHtml() { return false; } - public function execute () + public function execute() { $this->initPdf(); @@ -63,23 +62,24 @@ public function execute () $pageHeight = $pdf->getPageHeight(); $pageHeight -= 10; - foreach($this->getData() as $row){ + foreach ($this->getData() as $row) { $rowHeight = $this->getRowHeight($row); $y = $pdf->GetY(); $usedHeight = $y + $rowHeight; if ($usedHeight > $pageHeight) { - //Height is more than the pageHeight -> create a new page - if($rowHeight < $pageHeight){ - //If the row height is more than the page height, than we would have a problem, if we add a new page - //because it will overflow anyway... + // Height is more than the pageHeight -> create a new page + if ($rowHeight < $pageHeight) { + // If the row height is more than the page height, than we would have a problem, if we add a new page + // because it will overflow anyway... $pdf->AddPage(); $this->printTableHeader(); } } + $pageBeforeRow = $pdf->getPage(); $this->printTableRow($row, $rowHeight); } @@ -115,8 +115,8 @@ public function execute () return $response; } - - public function initPdf(){ + public function initPdf() + { $options = $this->getOptions(); $optionsRenderer = $this->getOptionsRenderer(); @@ -130,68 +130,82 @@ public function initPdf(){ $pdf = new TCPDF($orientation, 'mm', $papersize); - $margins = $optionsRenderer['margins']; + $margins = $optionsRenderer['margins']; $pdf->SetMargins($margins['left'], $margins['top'], $margins['right']); $pdf->SetAutoPageBreak(true, $margins['bottom']); $pdf->setHeaderMargin($margins['header']); $pdf->setFooterMargin($margins['footer']); $header = $optionsRenderer['header']; - $pdf->setHeaderFont(array('Helvetica', '', 13)); - $pdf->setHeaderData('/'.$header['logo'], $header['logoWidth'], $this->getTitle()); + $pdf->setHeaderFont(array( + 'Helvetica', + '', + 13 + )); + $pdf->setHeaderData('/' . $header['logo'], $header['logoWidth'], $this->getTitle()); $this->pdf = $pdf; } - + /** * * @return TCPDF */ - public function getPdf(){ + public function getPdf() + { return $this->pdf; } - + /** - * Decide which columns we want to display DO NOT display HTML, actions, ... After we have all -> resize the width to the paper format - * + * Decide which columns we want to display DO NOT display HTML, actions, . + * + * + * + * + * + * .. After we have all -> resize the width to the paper format + * * @return multitype:\ZfcDatagrid\Column\AbstractColumn */ - public function getColumnsToExport(){ - if(is_array($this->columnsToExport)){ + public function getColumnsToExport() + { + if (is_array($this->columnsToExport)) { return $this->columnsToExport; } $columnsToExport = array(); foreach ($this->getColumns() as $column) { /* @var $column \ZfcDatagrid\Column\AbstractColumn */ - if($column->isHidden() === false){ + if ($column->isHidden() === false) { - switch(get_class($column)){ + switch (get_class($column)) { case 'ZfcDatagrid\Column\Standard': $columnsToExport[] = $column; break; - + + case 'ZfcDatagrid\Column\Image': + $columnsToExport[] = $column; + break; + case 'ZfcDatagrid\Column\Icon': $columnsToExport[] = $column; break; - } } - } $this->columnsToExport = $columnsToExport; return $this->columnsToExport; } - + /** * Calculates the column width, based on the papersize and orientation * * @param array $columns */ - protected function calculateColumnWidth (array $columns) + protected function calculateColumnWidth(array $columns) { // First make sure the columns width is 100 "percent" $this->calculateColumnWidthPercent($columns); @@ -209,40 +223,55 @@ protected function calculateColumnWidth (array $columns) $column->setWidth($column->getWidth() * $factor); } } - - public function getRowHeight(array $row){ - + + /** + * + * @param array $row + * @return number + */ + public function getRowHeight(array $row) + { $options = $this->getOptions(); $optionsRenderer = $this->getOptionsRenderer(); $sizePoint = $optionsRenderer['style']['data']['size']; - //Points to MM + // Points to MM $size = $sizePoint / 2.83464566929134; $pdf = $this->getPdf(); $rowHeight = $size + 4; - foreach($this->getColumnsToExport() as $column){ + foreach ($this->getColumnsToExport() as $column) { /* @var $column \ZfcDatagrid\Column\AbstractColumn */ $height = 1; - switch(get_class($column)){ - + switch (get_class($column)) { + case 'ZfcDatagrid\Column\Standard': - if($row[$column->getUniqueId()] != ''){ - $count = $pdf->getNumLines($row[$column->getUniqueId()], $column->getWidth()); + if ($row[$column->getUniqueId()] != '') { + // Old Version... + // $count = $pdf->getNumLines($row[$column->getUniqueId()], $column->getWidth()); + // $height = $count * $size + 4; + + // New Version... + $height = $pdf->getStringHeight($column->getWidth(), $row[$column->getUniqueId()]); - $height = $count * $size + 4; + //include borders top/bottom + $height += 2; } break; - + case 'ZfcDatagrid\Column\Icon': + //"min" height for such a column $height = 10; break; - + + case 'ZfcDatagrid\Column\Image': + //"min" height for such a column + $height = 15; + break; } - - if($height > $rowHeight){ + if ($height > $rowHeight) { $rowHeight = $height; } } @@ -250,94 +279,143 @@ public function getRowHeight(array $row){ return $rowHeight; } - protected function printTableHeader(){ - + protected function printTableHeader() + { $this->setFontHeader(); $pdf = $this->getPdf(); - + $currentPage = $pdf->getPage(); $y = $pdf->GetY(); foreach ($this->getColumnsToExport() as $column) { /* @var $column \ZfcDatagrid\Column\AbstractColumn */ $x = $pdf->GetX(); + $pdf->setPage($currentPage); + $this->columnsPositionX[$column->getUniqueId()] = $x; - + $label = $this->getTranslator()->translate($column->getLabel()); - //Do not wrap header labels, it will look very ugly, that's why max height is set to 7! + // Do not wrap header labels, it will look very ugly, that's why max height is set to 7! $pdf->MultiCell($column->getWidth(), 7, $label, 1, 'L', true, 2, $x, $y, true, 0, false, true, 7); } } - - protected function printTableRow(array $row, $rowHeight){ - - + + protected function printTableRow(array $row, $rowHeight) + { $pdf = $this->getPdf(); + $currentPage = $pdf->getPage(); $y = $pdf->GetY(); - foreach ($this->getColumnsToExport() as $column) { + foreach ($this->getColumnsToExport() as $column) { /* @var $column \ZfcDatagrid\Column\AbstractColumn */ + $pdf->setPage($currentPage); $x = $this->columnsPositionX[$column->getUniqueId()]; $this->setFontData(); /* * Styles - */ + */ if ($column->hasStyles() === true) { foreach ($column->getStyles() as $style) { /* @var $style \ZfcDatagrid\Column\Style\AbstractStyle */ if ($style->isApply($row) === true) { switch (get_class($style)) { - + case 'ZfcDatagrid\Column\Style\Bold': $this->setBold(); break; - + case 'ZfcDatagrid\Column\Style\Italic': $this->setItalic(); break; - + case 'ZfcDatagrid\Column\Style\Color': $this->setColor($style->getRgbArray()); break; - + default: throw new \Exception('Not defined yet: "' . get_class($style) . '"'); - + break; } } } } - $text = ''; - switch(get_class($column)){ + switch (get_class($column)) { case 'ZfcDatagrid\Column\Standard': $text = $row[$column->getUniqueId()]; break; - + case 'ZfcDatagrid\Column\Icon': $text = ''; $link = K_BLANK_IMAGE; - if($column->getIconLink() != ''){ + if ($column->getIconLink() != '') { $link = $column->getIconLink(); } $pdf->Image($link, $x + 1, $y + 1, 0, 0, '', '', 'L', true); break; + + case 'ZfcDatagrid\Column\Image': + $text = ''; + $link = K_BLANK_IMAGE; + if ($row[$column->getUniqueId()] != '') { + $link = $row[$column->getUniqueId()]; + } + list($width, $height) = $this->calcImageSize($pdf, $link, $column->getWidth() - 2, $rowHeight - 2); + // Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array()) { + $pdf->Image($link, $x + 1, $y + 1, $width, $height, '', '', 'L', true, 300, '', false, false, 0, false, false, true, false, array()); + break; } - $pdf->MultiCell($column->getWidth(), $rowHeight, $text, 1, 'L', true, 2, $x, $y, true, 0); - + //MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0, $valign='T', $fitcell=false) + $pdf->MultiCell($column->getWidth(), $rowHeight, $text, 1, 'L', false, 1, $x, $y, true, 0); + } + } + + /** + * + * @param TCPDF $pdf + * @param string $image + * @param number $maxWidth + * @param number $maxHeight + * @return array + */ + private function calcImageSize(TCPDF $pdf, $image, $maxWidth, $maxHeight) + { + list ($width, $height) = getimagesize($image); + + $width = $pdf->pixelsToUnits($width); + $height = $pdf->pixelsToUnits($height); + $ratio = $width / $height; + + $widthDiff = $maxWidth - $width; + $heightDiff = $maxHeight - $height; + + if ($widthDiff < ($heightDiff * $ratio)) { + // resize based on width + $widthPdf = $maxWidth; + $heightPdf = $maxWidth % $ratio; + } else { + // resize based on height + $widthPdf = $maxHeight % $ratio; + $heightPdf = $maxHeight; } + + return array( + $widthPdf, + $heightPdf + ); } - - public function setFontHeader(){ + + public function setFontHeader() + { $options = $this->getOptions(); $optionsRenderer = $this->getOptionsRenderer(); $style = $optionsRenderer['style']['header']; @@ -346,16 +424,17 @@ public function setFontHeader(){ $size = $style['size']; $color = $style['color']; $background = $style['background-color']; - + $pdf = $this->getPdf(); $pdf->setFont($font, '', $size); $pdf->SetTextColor($color[0], $color[1], $color[2]); $pdf->SetFillColor($background[0], $background[1], $background[2]); - //"BOLD" fake + // "BOLD" fake $pdf->setTextRenderingMode(0.15, true, false); } - - public function setFontData(){ + + public function setFontData() + { $options = $this->getOptions(); $optionsRenderer = $this->getOptionsRenderer(); $style = $optionsRenderer['style']['data']; @@ -364,20 +443,22 @@ public function setFontData(){ $size = $style['size']; $color = $style['color']; $background = $style['background-color']; - + $pdf = $this->getPdf(); $pdf->setFont($font, '', $size); $pdf->SetTextColor($color[0], $color[1], $color[2]); $pdf->SetFillColor($background[0], $background[1], $background[2]); $pdf->setTextRenderingMode(); } - - public function setBold(){ + + public function setBold() + { $pdf = $this->getPdf(); $pdf->setTextRenderingMode(0.15, true, false); } - - public function setItalic(){ + + public function setItalic() + { $options = $this->getOptions(); $optionsRenderer = $this->getOptionsRenderer(); $style = $optionsRenderer['style']['data']; @@ -385,14 +466,15 @@ public function setItalic(){ $size = $style['size']; $pdf = $this->getPdf(); - $pdf->setFont($font.'I', '', $size); + $pdf->setFont($font . 'I', '', $size); } - + /** - * - * @param array $rgb + * + * @param array $rgb */ - public function setColor(array $rgb){ + public function setColor(array $rgb) + { $pdf = $this->getPdf(); $pdf->SetTextColor($rgb['red'], $rgb['green'], $rgb['blue']); } diff --git a/tests/ZfcDatagridTest/Column/Action/ButtonTest.php b/tests/ZfcDatagridTest/Column/Action/ButtonTest.php index 715f29c1..14dade4b 100644 --- a/tests/ZfcDatagridTest/Column/Action/ButtonTest.php +++ b/tests/ZfcDatagridTest/Column/Action/ButtonTest.php @@ -27,7 +27,7 @@ public function testLabel () $button->setLabel('My label'); $this->assertEquals('My label', $button->getLabel()); - $html = 'My label'; + $html = 'My label'; $this->assertEquals($html, $button->toHtml()); } } \ No newline at end of file diff --git a/tests/ZfcDatagridTest/DataSource/ZendSelect/FilterTest.php b/tests/ZfcDatagridTest/DataSource/ZendSelect/FilterTest.php index 8bf56bef..b29def97 100644 --- a/tests/ZfcDatagridTest/DataSource/ZendSelect/FilterTest.php +++ b/tests/ZfcDatagridTest/DataSource/ZendSelect/FilterTest.php @@ -73,7 +73,7 @@ public function testBasic() $this->assertInstanceOf('Zend\Db\Sql\Select', $this->filterSelect->getSelect()); $this->assertInstanceOf('Zend\Db\Sql\Sql', $this->filterSelect->getSql()); - //Test two filters + // Test two filters $filter = new \ZfcDatagrid\Filter(); $filter->setFromColumn($this->column, '~myValue,123'); @@ -92,6 +92,25 @@ public function testBasic() $this->assertEquals(2, count($predicates)); } + /** + * + * @param unknown $predicates + * @param number $part + * + * @return \Zend\Db\Sql\Predicate\Predicate + */ + private function getWherePart($predicates, $part = 0) + { + /* @var $predicateSet \Zend\Db\Sql\Predicate\PredicateSet */ + $predicateSet = $predicates[0][1]; + + $pred = $predicateSet->getPredicates(); + $where = $pred[$part][1]; + $wherePred = $where->getPredicates(); + + return $wherePred[0][1]; + } + public function testLike() { $filter = new \ZfcDatagrid\Filter(); @@ -107,45 +126,36 @@ public function testLike() $predicates = $where->getPredicates(); $this->assertEquals(1, count($predicates)); - //First nesting + // First nesting $this->assertEquals(2, count($predicates[0])); - /* @var $predicateSet \Zend\Db\Sql\Predicate\PredicateSet */ - $predicateSet = $predicates[0][1]; - - $where = $predicateSet->getPredicates()[0][1]; - $like = $where->getPredicates()[0][1]; + $like = $this->getWherePart($predicates, 0); $this->assertInstanceOf('Zend\Db\Sql\Predicate\Like', $like); $this->assertEquals('%myValue%', $like->getLike()); - - $where = $predicateSet->getPredicates()[1][1]; - $like = $where->getPredicates()[0][1]; + + $like = $this->getWherePart($predicates, 1); $this->assertInstanceOf('Zend\Db\Sql\Predicate\Like', $like); $this->assertEquals('%123%', $like->getLike()); } - + public function testLikeLeft() { $filter = new \ZfcDatagrid\Filter(); $filter->setFromColumn($this->column, '~%myValue,123'); - + $filterSelect = clone $this->filterSelect; $filterSelect->applyFilter($filter); - + $select = $filterSelect->getSelect(); /* @var $where \Zend\Db\Sql\Where */ $where = $select->getRawState('where'); - + $predicates = $where->getPredicates(); - - //First nesting + + // First nesting $this->assertEquals(2, count($predicates[0])); - - /* @var $predicateSet \Zend\Db\Sql\Predicate\PredicateSet */ - $predicateSet = $predicates[0][1]; - - $where = $predicateSet->getPredicates()[0][1]; - $like = $where->getPredicates()[0][1]; + + $like = $this->getWherePart($predicates, 0); $this->assertInstanceOf('Zend\Db\Sql\Predicate\Like', $like); } }