From 2b89bcd27db6fcf6470ba07ef20a610e71fdf79d Mon Sep 17 00:00:00 2001 From: Matthew Gamble Date: Wed, 20 May 2015 10:45:42 +1000 Subject: [PATCH 1/3] Clone a collection's select object when cloning the collection PHP object cloning is shallow. Therefore, any objects owned by the cloned object are also owned by the original object, because it's all passed around by reference. This means that if the select object is modified after the clone, this will still affect the original collection's select object. This creates problems when you have collections that modify the select object in the _beforeLoad() method. We encountered issues when exporting the Sales Transactions grid, where it would complain that it had already added a column name correlation whenever it reached the 2nd page when exporting a collection. This was happening because it was using the same shared select object from the original collection. To get around this, we now clone the original select object, and manually set it on the cloned collection on each iteration of the loop, using reflection to do so. This appears to work fine for all grids, and is a general improvement. It is worth noting that this exact issue is probably why Magento never made exporting possible on some grids, such as the Sales Transactions grid. --- .../BL/CustomGrid/Model/Grid/Rewriter/Abstract.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php b/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php index 4c3d7b4..24d4b28 100644 --- a/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php +++ b/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php @@ -259,9 +259,18 @@ public function _exportIterateCollection($callback, array $args) $break = false; $first = false; $count = null; - + + if ($originalCollection instanceof Varien_Data_Collection_Db) { + $selectProperty = new ReflectionProperty(get_class($originalCollection), "_select"); + $selectProperty->setAccessible(true); + $originalSelect = $originalCollection->getSelect(); + } while ($break !== true) { $collection = clone $originalCollection; + if ($originalCollection instanceof Varien_Data_Collection_Db) { + $select = clone $originalSelect; + $selectProperty->setValue($collection, $select); + } $collection->setPageSize($pageSize); $collection->setCurPage($page); From 1ac040122ef9869d431717f6dc7df5bc47be9485 Mon Sep 17 00:00:00 2001 From: Matthew Gamble Date: Tue, 19 May 2015 18:58:09 +1000 Subject: [PATCH 2/3] Fix for transactions grid collection not being reloaded properly The extension relies on the fact that a new collection object is created during the second call to _prepareCollection(). This doesn't happen with the transactions grid, because it always first looks to see if there is a collection already set. It does this because there is a subclass which also creates a collection, and utilises this class to do most of the work. We don't need this for the main transactions grid, so we unset the collection before calling _prepareCollection() for the 2nd time. This makes everything work a lot more nicely. --- .../BL/CustomGrid/Model/Grid/Exporter.php | 3 +- .../Model/Grid/Rewriter/Abstract.php | 15 ++++- .../Model/Grid/Type/Sales/Transactions.php | 64 +++++++++++++++++++ .../BL/CustomGrid/etc/customgrid.xml | 7 +- 4 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 app/code/community/BL/CustomGrid/Model/Grid/Type/Sales/Transactions.php diff --git a/app/code/community/BL/CustomGrid/Model/Grid/Exporter.php b/app/code/community/BL/CustomGrid/Model/Grid/Exporter.php index ea90f90..8ecd851 100644 --- a/app/code/community/BL/CustomGrid/Model/Grid/Exporter.php +++ b/app/code/community/BL/CustomGrid/Model/Grid/Exporter.php @@ -76,8 +76,9 @@ protected function _exportTo($format, $config = null) $typeModel->beforeGridExport($format, null); /** @var $layout Mage_Core_Model_Layout */ $layout = Mage::getSingleton('core/layout'); + /** @var $gridBlock Mage_Adminhtml_Block_Widget_Grid */ $gridBlock = $layout->createBlock($gridModel->getBlockType()); - + if (is_array($config)) { $gridBlock->blcg_setExportConfig($config); } diff --git a/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php b/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php index 24d4b28..61d9204 100644 --- a/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php +++ b/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php @@ -16,7 +16,7 @@ abstract class BL_CustomGrid_Model_Grid_Rewriter_Abstract extends BL_CustomGrid_Object { const REWRITE_CODE_VERSION = 3; // bump this value when significant changes are made to the rewriting code - + /** * Return the fixed base of the rewriting class names used by the extension * @@ -108,7 +108,14 @@ protected function _getRewriteCode($blcgClassName, $originalClassName, $blockTyp { return 'class ' . $blcgClassName . ' extends ' . $originalClassName . ' { + /** + * @var BL_CustomGrid_Model_Grid + */ private $_blcg_gridModel = null; + + /** + * @var BL_CustomGrid_Model_Grid_Type_Abstract + */ private $_blcg_typeModel = null; private $_blcg_filterParam = null; private $_blcg_exportConfig = null; @@ -160,6 +167,12 @@ public function setCollection($collection) return $return; } + + public function blcg_unsetCollection() + { + $this->_collection = null; + return $this; + } public function getCollection() { diff --git a/app/code/community/BL/CustomGrid/Model/Grid/Type/Sales/Transactions.php b/app/code/community/BL/CustomGrid/Model/Grid/Type/Sales/Transactions.php new file mode 100644 index 0000000..13aa3ad --- /dev/null +++ b/app/code/community/BL/CustomGrid/Model/Grid/Type/Sales/Transactions.php @@ -0,0 +1,64 @@ + + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class BL_CustomGrid_Model_Grid_Type_Sales_Transactions extends BL_CustomGrid_Model_Grid_Type_Abstract +{ + /** + * @return string[]|string + */ + protected function _getSupportedBlockTypes() + { + return array('adminhtml/sales_transactions_grid'); + } + + /** + * Do some actions before grid collection is prepared + * + * @param Mage_Adminhtml_Block_Widget_Grid $gridBlock Grid block + * @param bool $firstTime Whether this is the first (= incomplete) grid collection preparation + * @return BL_CustomGrid_Model_Grid_Type_Sales_Transactions + */ + public function beforeGridPrepareCollection(Mage_Adminhtml_Block_Widget_Grid $gridBlock, $firstTime = true) + { + if (!$firstTime) { + $gridBlock->blcg_addCollectionCallback( + 'before_prepare', + array($this, 'removeFirstTimeCollection'), + array(), + true + ); + } + return $this; + } + + /** + * When calling _prepareCollection(), this grid by default looks to see if one is already set, rather + * than just overriding any existing collection. This is unique in Magento, and causes all sorts of + * problems because the collection has already been loaded. + * + * @param Mage_Adminhtml_Block_Widget_Grid $gridBlock + * @param Varien_Data_Collection_Db $collection + * @param bool $firstTime + */ + public function removeFirstTimeCollection( + Mage_Adminhtml_Block_Widget_Grid $gridBlock, + Varien_Data_Collection_Db $collection, + $firstTime + ) { + if (!$firstTime) { + $gridBlock->blcg_unsetCollection(); + } + } +} diff --git a/app/code/community/BL/CustomGrid/etc/customgrid.xml b/app/code/community/BL/CustomGrid/etc/customgrid.xml index 04a7f0b..cd881f7 100644 --- a/app/code/community/BL/CustomGrid/etc/customgrid.xml +++ b/app/code/community/BL/CustomGrid/etc/customgrid.xml @@ -489,7 +489,12 @@ - + + + Transactions + 240000 + + Other 1000000000 From 4812ef5708a8722e63fc686c5f51371d4ab0cb39 Mon Sep 17 00:00:00 2001 From: Matthew Gamble Date: Mon, 3 Aug 2015 17:11:18 +1000 Subject: [PATCH 3/3] Bump rewrite code version to reflect new changes --- .../community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php b/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php index 61d9204..43bf14d 100644 --- a/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php +++ b/app/code/community/BL/CustomGrid/Model/Grid/Rewriter/Abstract.php @@ -15,7 +15,7 @@ abstract class BL_CustomGrid_Model_Grid_Rewriter_Abstract extends BL_CustomGrid_Object { - const REWRITE_CODE_VERSION = 3; // bump this value when significant changes are made to the rewriting code + const REWRITE_CODE_VERSION = 4; // bump this value when significant changes are made to the rewriting code /** * Return the fixed base of the rewriting class names used by the extension