Magento 2 Override by preference not working - magento

Everything seems right but my overriding is not working
Trying to override a Model from
vendor/magento/module-catalog-url-rewrite/Model/ProductUrlPathGenerator.php
Path for di.xml app/code/Rltsquare/Customrewrite/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Rltsquare\Customrewrite\Model\CatalogUrlRewrite\ProductUrlPathGenerator" />
</config>
Path for Model file after overriding
app/code/Rltsquare/Customrewrite/Model/CatalogUrlRewrite/ProductUrlPathGenerator.php
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Rltsquare\Customrewrite\Model\CatalogUrlRewrite;
use Magento\Store\Model\Store;
class ProductUrlPathGenerator extends \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator
{
protected function prepareProductUrlKey(\Magento\Catalog\Model\Product $product)
{
$urlKey = $product->getUrlKey();
return 'products/'.$product->formatUrlKey($urlKey === '' || $urlKey === null ? $product->getName() : $urlKey);
}
}
Do i have to compile or run any other command after this type of overriding (preference)

Related

Magento 2 append custom attribute to product name

I would like to add 2 custom attributes after the product name EVERYWHERE in the magento 2 shop.
Like "Productname Attribute1 Attribute2"
Is this possible and how? Do i need to modify every page or is there a way to act directly on the product name rendering for the whole system?
thanks
Fot that you have to create extension. Please check my code
Create folder in app/code/Magenest
Create sub folder in app/code/Magenest/Sample
Now create registration.php with following code
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magenest_Sample',
__DIR__
);
Create etc folder in app/code/Magenest/Sample/
Create module.xml in etc folder with following code
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magenest_Sample" setup_version="2.0.0">
</module></config>
Create folder in frontend in app/code/Magenest/Sample/etc/
Create a file di.xml file in app/code/Magenest/Sample/etc/frontend with following code
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Model\Product" type="Magenest\Sample\Model\Product"/>
</config>
Now create a Model folder in app/Magenest/Sample/
Create Product.php in Model folder with following code
<?php
namespace Magenest\Sample\Model;
class Product extends \Magento\Catalog\Model\Product
{
public function getName()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($this->_getData('entity_id'));
$myattribute = $product->getResource()->getAttribute('putyourcustomattribute')->getFrontend()->getValue($product);
$changeNamebyPreference = $this->_getData('name') . ' '. $myattribute;
return $changeNamebyPreference;
}
}

How to get the custom order attributes in default order Api response in magento 2.3

I have created a new custom order attribute named delivery_date and shown the same in sales order grid but i am not getting the custom attribute in my order Api response.
The error I am getting is Fatal error: Uncaught Error: Call to undefined method Magento\Sales\Api\Data\OrderExtension::setTipAndTrickAttribute()
Please help.
app/code/Amos/CustomOrder/etc/di.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid" type="Magento\Sales\Model\ResourceModel\Grid">
<arguments>
<argument name="columns" xsi:type="array">
<item name="delivery_date" xsi:type="string">sales_order.delivery_date</item>
<item name="no_of_days" xsi:type="string">sales_order.no_of_days</item>
<item name="no_of_crew" xsi:type="string">sales_order.no_of_crew</item>
</argument>
</arguments>
</virtualType>
</config>
app/code/Amos/CustomOrder/etc/events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_order_load_after">
<observer name="sales_order_load_delivery_date" instance="Magestore\TipAndTrick\Observer\Sales\OrderLoadAfter" />
</event>
</config>
Amos/CustomOrder/etc/extension_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
<attribute code="delivery_date" type="string" />
</extension_attributes>
</config>
Amos/CustomOrder/Observer/Sales/OrderLoadAfter.php
<?php
namespace Amos\CustomOrder\Observer\Sales;
use Magento\Framework\Event\ObserverInterface;
class OrderLoadAfter implements ObserverInterface
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
$order = $observer->getOrder();
$extensionAttributes = $order->getExtensionAttributes();
if ($extensionAttributes === null) {
$extensionAttributes = $this->getOrderExtensionDependency();
}
$attr = $order->getData('delivery_date');
$extensionAttributes->setTipAndTrickAttribute($attr);
$order->setExtensionAttributes($extensionAttributes);
}
private function getOrderExtensionDependency()
{
$orderExtension = \Magento\Framework\App\ObjectManager::getInstance()->get(
'\Magento\Sales\Api\Data\OrderExtension'
);
return $orderExtension;
}
}
To answer your question about the error you're using the wrong magic function. Your magic functions for that attribute is setDeliveryDate().
You also need to make sure your events.xml has the right class for the observer.
<observer name="sales_order_load_delivery_date" instance="Magestore\TipAndTrick\Observer\Sales\OrderLoadAfter" />
While your observer class is: Amos\CustomOrder\Observer\Sales\OrderLoadAfter
When you are using example material try not to forget to change the class, namespace and functions names among other things when you need to. You may also need an order repository plugin to actually get it into the API response.
<type name="Magento\Sales\Api\OrderRepositoryInterface">
<plugin name="your_name_here_extension_attribute"
type="<Vendor>\<Module>\Plugin\OrderRepositoryPlugin" />
</type>
Yes agree with above answer, you will need to write order repository plugin with get and getlist methods to get it into the API response.
Below are the code snippet
public function afterGet(OrderRepositoryInterface $subject, OrderInterface $order)
{
$this->addDeliveryDate($order);
return $order;
}
public function afterGetList(OrderRepositoryInterface $subject, OrderSearchResultInterface $searchResult)
{
$orders = $searchResult->getItems();
foreach ($orders as $order) {
$this->addDeliveryDate($order);
}
return $searchResult;
}
private function addDeliveryDate($order)
{
$adddeliveryDate = $order->getData(self::DELIVERY_DATE);
$extensionAttributes = $order->getExtensionAttributes() ?: $this->extensionFactory->create();
$extensionAttributes->setDeliveryDate($adddeliveryDate);
$order->setExtensionAttributes($extensionAttributes);
return $order;
}

Magento 2 - Display/Show Custom module on homepage

I am in new Magento 2 and have created a custom module, its working fine with the url(http:///modulename/index/test) but need to call it on home page. I mean when home page loaded, module would be called automatically. How it possible?
Below is the steps which I followed during module creation -
Step 1: Created the Namespace and module folder
Step 2: Created etc/module.xml file
<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Ignvia_HelloWorld" setup_version="1.0.0">
</module>
Step 3: Created etc/registration.php file
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Ignvia_HelloWorld',
DIR
);
Step 4: Created etc/frontend/routes.xml file
<?xml version="1.0" ?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route frontName="helloworld" id="helloworld">
<module name="Igniva_HelloWorld"/>
</route>
</router>
Step 5: Created Controller/Index/Test.php
<?php
namespace Igniva\HelloWorld\Controller\Index;
class Test extends \Magento\Framework\App\Action\Action
{
protected $_pageFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory)
{
$this->_pageFactory = $pageFactory;
return parent::__construct($context);
}
public function execute()
{
echo "Hello World";
exit;
}
}
Thanks.
To load your custom module in homepage, your code should be called in cms_index_index layout(not in core file).you have to define in custom file.

Magento 2 Add to wish list return to the product detail page

Currently in Magento 2 after add the product to wish list it move to the wish list page. I am trying to move it back to the product detail page. So for it i try to override the Magento\Wishlist\Controller\Index\Add with the di preference
<preference for="Magento\Wishlist\Controller\Index\Add"
type="Eguana\CustomWishlist\Controller\Rewrite\Index\Add" />
And for it my controller is like this
namespace Eguana\CustomWishlist\Controller\Rewrite\Index;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\Action;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Controller\ResultFactory;
/**
* #SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Add extends \Magento\Wishlist\Controller\Index\Add
{
public function __construct(Action\Context $context, \Magento\Customer\Model\Session $customerSession, \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider, ProductRepositoryInterface $productRepository, Validator $formKeyValidator)
{
parent::__construct($context, $customerSession, $wishlistProvider, $productRepository, $formKeyValidator);
}
/**
* Adding new item
*
* #return \Magento\Framework\Controller\Result\Redirect
* #throws NotFoundException
* #SuppressWarnings(PHPMD.CyclomaticComplexity)
* #SuppressWarnings(PHPMD.NPathComplexity)
* #SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function execute()
{
echo 'abc';
}
}
My module.xml file is like this
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Eguana_CustomWishlist" setup_version="2.1.3">
<sequence>
<module name="Magento_Wishlist" />
</sequence>
</module>
</config>
But it is still calling the Magento Wishlist module controller. Can you please let me know is there any issue in my overriding process? Thank you very much.
In Magento2 Magento\Wishlist\Controller\Index\Add is overriden by another core module MultipleWishlist module Magento\MultipleWishlist\Controller\Index\Add so if you want to override the wishlist add controller then you should override the MultipleWishlist add controller.
I hope it will work for you and will save your time.
Thanks Abbas
In your module di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<preference for="Magento\MultipleWishlist\Controller\Index\Add" type="Vendor\Module\Controller\MultipleWishlist\Add" />
<preference for="Magento\Wishlist\Controller\Index\Add" type="Vendor\Module\Controller\Wishlist\Add" />
</config>
Note : In override controller of MultipleWhislist
namespace Vendor\Module\Controller\MultipleWishlist;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Customer\Model\Session;
use Magento\Framework\App\Action;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\MultipleWishlist\Model\WishlistEditor;
use Magento\Wishlist\Controller\WishlistProviderInterface;
class Add extends \Vendor\Module\Controller\Wishlist\Add
{
It's working fine.

Magento 1.4 - Displaying some products under specific category

Hi
I have assigned 20 products to a category called Phone, I would like to create a module to retrieve these products and displayed as a list format. Could someone tell me how to do this?
thanks
To create a widget (which you can insert via the cms) that uses a category to do something, begin by creating a standard module structure with:
/Block
/etc
/Helper
/Model
Note that in my code samples and filenames below you will need to replace [Namespace], [Module], and [module] with the appropriate namespace and module that you want to use. Case is important!
Begin by creating app/code/local/[Namespace]/[Module]/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<[Namespace]_[Module]>
<version>0.0.1</version>
</[Namespace]_[Module]>
</modules>
<global>
<helpers>
<[module]>
<class>[Namespace]_[Module]_Helper</class>
</[module]>
</helpers>
<blocks>
<[module]>
<class>[Namespace]_[Module]_Block</class>
</[module]>
</blocks>
<models>
<[module]>
<class>[Namespace]_[Module]_Model</class>
</[module]>
</models>
</global>
</config>
Then create a app/code/local/[Namespace]/[Module]/etc/widget.xml This widget includes a setting called "selected_category"
<?xml version="1.0"?>
<widgets>
<[module]_category type="[module]/category">
<name>[Module]: Category</name>
<description type="desc">Adds a [module] for a category.</description>
<parameters>
<selected_category>
<label>Categories</label>
<visible>1</visible>
<required>1</required>
<type>select</type>
<source_model>[module]/catopt</source_model>
</selected_category>
</parameters>
</[module]_category>
</widgets>
Then the obligatory Helper file in app/code/local/[Namespace]/[Module]/Helper/Data.php
<?php
class [Namespace]_[Module]_Helper_Data extends Mage_Core_Helper_Abstract
{
}
Then a model to allow the user to select the category in the widget dialog box. This goes in app/code/local/[Namespace]/[Module]/Model/Catopt.php
<?php
class [Namespace]_[Module]_Model_Catopt
{
public function toOptionArray()
{
$category = Mage::getModel('catalog/category');
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
$arr = array();
if ($ids){
foreach ($ids as $id){
$cat = Mage::getModel('catalog/category');
$cat->load($id);
array_push($arr, array('value' => $id, 'label' => $cat->getName().' ('.$cat->getProductCount().')'));
}
}
uasort($arr, array($this, 'labelsort'));
return $arr;
}
function labelsort($a, $b){
if ( $a['label'] == $b['label'] )
return 0;
else if ( $a['label'] < $b['label'] )
return -1;
else
return 1;
}
}
Finally on the module side of things a block which goes in app/code/local/[Namespace]/[Module]/Block/Category.php This block is using a custom .phtml file for it's display but you can change that to use anything else you might need to show by changing the type of block and input to setTemplate.
<?php
class [Namespace]_[Module]_Block_Category
extends Mage_Core_Block_Template
implements Mage_Widget_Block_Interface
{
/**
* A model to serialize attributes
* #var Varien_Object
*/
protected $_serializer = null;
/**
* Initialization
*/
protected function _construct()
{
$this->_serializer = new Varien_Object();
$this->setTemplate('[module]/[module].phtml');
parent::_construct();
}
public function getCategory(){
return $this->getData('selected_category');
}
}
Don't forget to add a module install file under /app/etc/modules/[Namespace]_[Module].xml like this
<?xml version="1.0"?>
<config>
<modules>
<[Namespace]_[Module]>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Cms />
</depends>
</[Namespace]_[Module]>
</modules>
</config>
Lastly you need to create a template file to display the block content. This will go under /app/design/frontend/default/default/template/[module]/[module].phtml
This .phtml file can use $this->getCategory() to get the category and go from there. You can easily customize the block included in these samples to display the default magento product list grids instead of using a custom .phtml file.
No need to create a module. just place this in a block in your layout: It will show all the products linked to the specified category (id=XXX).
<!-- Show all products linked to this category -->
<block type="catalog/product_list" name="best_sellers" template="catalog/product/list.phtml">
<action method="setCategoryId">
<category_id>XXX</category_id>
</action>
</block>
Update:
You can create a module that overide the "Mage_Catalog_Block_Product_List", and add a method to limit a certain number of products.
1- Create "app/code/local/[Namespace]/Catalog/etc/config.xml" and put this in it:
<config>
<modules>
<[Namespace]_Catalog>
<version>0.1.0</version>
</[Namespace]_Catalog>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<product_list>[Namespace]_Catalog_Block_Product_List</product_list>
</rewrite>
</catalog>
</blocks>
</global>
</config>
2- Override the Block by creating the class: "app/code/local/[Namespace]/Catalog/Block/Product/List.php"
class [Namespace]_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_List
{
/**
* Default number of product to show.
*
* #var int default = 5
*/
private $_productCount = 5;
/**
* Initialize the number of product to show.
*
* #param int $count
* #return Mage_Catalog_Block_Product_List
*/
public function setProductCount($count)
{
$this->_productCount = intval($count);
return $this;
}
/**
* Get the number of product to show.
*
* #return int
*/
public function getProductCount()
{
return $this->_productCount;
}
}
3- Overide your theme to add the product limit feature:
copy "app/design/frontend/default/default/template/catalog/product/list.phtml" to "app/design/frontend/default/[your_theme]/template/catalog/product/list.phtml"
// Insert between the foreachs and <li> for the list mode and grid mode
<?php if($_iterator < $this->getProductCount()) : ?>
...
// Insert between the foreachs and <li> for the list mode and grid mode
<?php endif; ?>
4- In the home page content tab, add this line where you want it:
// category_id = Procucts linked to this category
// product_count = Maximum number of product
{{block type="catalog/product_list" category_id="7" product_count="3" template="catalog/product/list.phtml"}}
Hope this help someone.
Thanks for the informative post. For those of you who are not so fluent in PHP but landed on this page because you were looking for a solution to display a product name list from a given category I managed to find a solution by simply modifying someone else's template file. For this solution I found the best suited extension was:
http://www.cubewebsites.com/blog/magento/extensions/freebie-magento-featured-products-widget-version-2/
(find the latest version on github: https://github.com/cubewebsites/Cube-Category-Featured-Products/tags).
After logging in and out and clearing the cache I was able to insert the widget into a static block and modify the .phtml file used to produce the custom view that I wanted.
The widget looked like this when inserted:
{{widget type="categoryfeatured/list" template="categoryfeatured/block.phtml" categories="118" num_products="10" products_per_row="1" product_type="all"}}.
I simply opened
app/design/frontend/base/default/template/categoryfeatured/block.phtml
copied it's contents and created a new .phtml file called category_product_listing.phtml
and then pointed the widget instance to the new .phtml file as follows:
{{widget type="categoryfeatured/list" template="categoryfeatured/category_product_listing.phtml" categories="118" num_products="10" products_per_row="1" product_type="all"}}.
I then went through this .phtml file with my basic understanding of PHP and removed all items like images, add to cart buttons, reviews, etc. until I was left with just the basic linked product title as well as the category title left intact.
I hope this helps someone as I spent hours trying to figure this out.

Resources