Wow this is our first tutorial about Magento 2, how create you custom nav tab in customer view (backend side)
Get the Extension in Github
Magento 2 offer structured technique :
Steps :
A – declare your module inside app/code/Ibnab/ComparedProduct/etc/ create module.xml with code :
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> <module name="Ibnab_ComparedProduct" setup_version="1.0.0" schema_version="1.0.0"> <sequence> <module name="Magento_Customer"/> </sequence> </module> </config>
you can go to official doc for more infos : http://devdocs.magento.com/guides/v2.0/extension-dev-guide/bk-extension-dev-guide.html
B – now we need add our tab link in the left side (backend customer view) and related to grid of all
product in compare for specific customer :
Magento 2 use small layout snippets every path (handle) inside an xml file example :
customer_index_edit for adminhtml (admin/customer/index/edit) is inside app/code/Ibnab/ComparedProduct/view/adminhtml/customer_index_edit.xml
yes two new technique small snippets and in the same folder of your extension
ok create app/code/Ibnab/ComparedProduct/view/adminhtml/customer_index_edit.xml and put this code for add the link tab and infos and override the default view :
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="customer_form"> <block class="Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\Compared" name="customer_edit_tab_compared"> <action method="setTabLabel"> <argument name="label" xsi:type="string">Product Compared</argument> </action> </block> </referenceBlock> </body> </page>
See the label of the tab link is Product Compared and the class of tab is Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\Compared create inside app/Ibnab/ComparedProduct/Block/Adminhtml/Edit/Tab/Compared and put you code :
<?php /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab; use Magento\Customer\Controller\RegistryConstants; use Magento\Ui\Component\Layout\Tabs\TabInterface; /** * Customer account form block */ class Compared extends \Magento\Backend\Block\Template implements TabInterface { /** * Core registry * * @var \Magento\Framework\Registry */ protected $_coreRegistry; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Registry $registry * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Framework\Registry $registry, ) { $this->_coreRegistry = $registry; parent::__construct($context, $data); } /** * @return string|null */ public function getCustomerId() { return $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID); } /** * @return \Magento\Framework\Phrase */ public function getTabLabel() { return __('Product Compare'); } /** * @return \Magento\Framework\Phrase */ public function getTabTitle() { return __('Product Compare'); } /** * @return bool */ public function canShowTab() { if ($this->getCustomerId()) { return true; } return false; } /** * @return bool */ public function isHidden() { if ($this->getCustomerId()) { return false; } return true; } /** * Tab class getter * * @return string */ public function getTabClass() { return ''; } /** * Return URL link to Tab content * * @return string */ public function getTabUrl() { return $this->getUrl('compared/*/compare', ['_current' => true]); } /** * Tab should be loaded trough Ajax call * * @return bool */ public function isAjaxLoaded() { return true; } }
- You can see is implements from TabInterface and the more important function in this class is : getTabUrl() and isAjaxLoaded() :
getTabUrl() contain the code return $this->getUrl('compared/*/compare', ['_current' => true]); equal go to action or file compare and execute the complete path of your controller in Magento 2 is
app/code/Ibnab/ComparedProduct/Controller/Adminhtml/Index/Compare.php Magento 2 go to this file and finding the function execute() and execute the code , ok complete code of file is :
<?php /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Ibnab\ComparedProduct\Controller\Adminhtml\Index; class Compare extends \Magento\Customer\Controller\Adminhtml\Index { /** * Customer compare grid * * @return \Magento\Framework\View\Result\Layout */ public function execute() { $this->initCurrentCustomer(); $resultLayout = $this->resultLayoutFactory->create(); return $resultLayout; } }
As you see is load the layout , the name of layout is compared_index_compare.xml Magento 2 take get from function getTabUrl() :
public function getTabUrl() { return $this->getUrl('compared/*/compare', ['_current' => true]); }
C : Ok create app/code/Ibnab/ComparedProduct/view/adminhtml/compared_index_compare.xml for loading the grid :
<?xml version="1.0"?> <!-- /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ --> <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd"> <container name="root" label="Root"> <block class="Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\View\Compared" name="comparedproduct.edit.tab.compared"/> </container> </layout>
D - Now we need create our file Compared.php of our grid :
<?php /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\View; use Magento\Customer\Controller\RegistryConstants; /** * Adminhtml customer recent orders grid block */ class Compared extends \Magento\Backend\Block\Widget\Grid\Extended { /** * Core registry * * @var \Magento\Framework\Registry|null */ protected $_coreRegistry = null; /** * @var \Magento\Sales\Model\Resource\Order\Grid\CollectionFactory */ protected $_collectionFactory; /** * Constructor * * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\Sales\Model\Resource\Order\Grid\CollectionFactory $collectionFactory * @param \Magento\Framework\Registry $coreRegistry * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory $collectionFactory, \Magento\Framework\Registry $coreRegistry, ) { $this->_logger = $logger; $this->_coreRegistry = $coreRegistry; $this->_collectionFactory = $collectionFactory; parent::__construct($context, $backendHelper, $data); } /** * Initialize the orders grid. * * @return void */ protected function _construct() { parent::_construct(); $this->setId('comparedproduct_view_compared_grid'); $this->setDefaultSort('created_at', 'desc'); $this->setSortable(false); $this->setPagerVisibility(false); $this->setFilterVisibility(false); } /** * {@inheritdoc} */ protected function _preparePage() { $this->getCollection()->setPageSize(5)->setCurPage(1); } /** * {@inheritdoc} */ protected function _prepareCollection() { $collection = $this->_collectionFactory->create()->setCustomerId( $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID) $this->setCollection($collection); return parent::_prepareCollection(); } /** * {@inheritdoc} */ protected function _prepareColumns() { $this->addColumn( 'product_id', ['header' => __('ID'), 'index' => 'product_id', 'type' => 'number', 'width' => '100px'] ); $this->addColumn( 'product_name', [ 'header' => __('Product Name'), 'index' => 'name', ] ); $this->addColumn( 'product_price', [ 'header' => __('Product Price'), 'index' => 'price', ] ); return parent::_prepareColumns(); } /** * Get headers visibility * * @return bool * * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ public function getHeadersVisibility() { return $this->getCollection()->getSize() >= 0; } /** * {@inheritdoc} */ public function getRowUrl($row) { return $this->getUrl('catalog/product/edit', ['id' => $row->getProductId()]); } }
in function :
public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory $collectionFactory, \Magento\Framework\Registry $coreRegistry, ) { $this->_logger = $logger; $this->_coreRegistry = $coreRegistry; $this->_collectionFactory = $collectionFactory; parent::__construct($context, $backendHelper, $data); }
I add my custom factory \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory the new technique of Magento 2 based on DI and Factory Pattern , for getting instance of model class or collection class you need pass by injected the factory object to construct function ,and this factory object give you the ability of create object and create your query or any operation in my example I want a collection of items in compare from the class Magento\Catalog\Model\Resource\Product\Compare\Item\Collection in path folder :
app/code/ Magento/Catalog/Model/Resource/Product/Compare/Item/Collection.php I can't instanced directly but I need get the factory \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory and use the method create for getting the object but in new logic of Magento 2 you can put by injecion and use without search how get the factory form doc go to :
http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html
- The _prepareCollection() get my custom selected collection of items in compare , I use the current user from registry and useProductItem() from my object item collection
- The _prepareColumns() the columns and index from collection you can use custom renderer
Comments