I have been trying to filter the coupon coupons for hours now.
I tried to manipulate the function mapAssociatedEntities in the file /vendor/magento/module-sales-rule/Model/ResourceModel/Rule/Collection.php with a plugin, but I can't get it to work and now I'm hoping for your help.
/etc/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<type name="Magento\SalesRule\Model\ResourceModel\Rule\Collection">
<plugin name="coupon_restricted_plugin" type="Vendor\Modul\Plugin\CouponCollectionPlugin" sortOrder="1"/>
</type>
</config>
/app/code/Vendor/Modul/Plugin/CouponCollectionPlugin.php
<?php
namespace Vendor\Modul\Plugin;
class CouponCollectionPlugin
{
public function aroundMapAssociatedEntities(
\Magento\SalesRule\Model\ResourceModel\Rule\Collection $subject,
\Closure $proceed,
$entityType,
$objectField
){
var_dump('Here: ' . __METHOD__.__FUNCTION__'<br>');
$result = $proceed($entityType, $objectField);
return $result;
}
}
I also like to take another way to override the mapAssociatedEntities function.
I need to narrow down the coupon codes to the user
Edit// Magento 2.4.5-p1
Related
I encountered a problem where my new module is not found when I tried to browse it.
Here is the detail of the code.
Ced/CsTermsAndServices/etc/Module.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Ced_TermsAndServices" setup_version="1.0.0">
</module>
</config>
Ced/CsTermsAndServices/registration.php
<?PHP
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Ced_TermsAndServices',
__DIR__
);
Ced/CsTermsAndServices/etc/frontend/routes.xml
<?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="cstermsandservices" id="cstermsandservices">
<module name="Ced_TermsAndServices"/>
</route>
</router>
</config>
Ced/CsTermsAndServices/Controller/Index/Index.php
<?php
namespace Ced\CsTermsAndServices\Controller\Index;
class Index 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;
}
}
The expected route supposed to be
http://localhost/cstermsandservices/index/index
But the result ended up as 404 not found.
Any fix to this?
1)make sure you have vendor/module-name vendor_module-name convention is followed( in your case modules name should be Ced_CsTermsAndServices if you want to follow current directory structure)
2) module.xml file name should be in all lower case
Hope this will work
Happy Magento
Been spending the last 1 day to find a fix for this.
Basically everything works normal if I delete all the contents of generated folder and then generate the files dynamically by accessing the pages rather than doing setup:di:compile.
On the production though, I'm forced to do setup:di:compile and I end up with this certain admin module page being empty.
This is the controller of the page:
namespace Eadesigndev\AWB\Controller\Adminhtml\Index;
use Eadesigndev\Awb\Api\AwbRepositoryInterface;
use Eadesigndev\Awb\Model\Awb;
use Eadesigndev\Awb\Model\AwbFactory;
use Eadesigndev\Awb\Helper\Data as DataHelper;
use Magento\Framework\Registry;
use Magento\Backend\App\Action\Context;
use Magento\Backend\Model\Session;
use Magento\Framework\View\Result\PageFactory;
use Magento\Backend\App\Action;
class Edit extends Action
{
/**
* Authorization level of a basic admin session
*
*
*/
const ADMIN_RESOURCE = 'Eadesigndev_Awb::awb';
protected $resultPageFactory;
private $awbRepository;
private $awbFactory;
private $registry;
private $session;
private $dataHelper;
private $awbModel;
public function __construct(
Context $context,
PageFactory $resultPageFactory,
AwbRepositoryInterface $awbRepository,
AwbFactory $awbFactory,
Awb $awbModel,
Registry $registry,
DataHelper $dataHelper
) {
$this->resultPageFactory = $resultPageFactory;
$this->awbRepository = $awbRepository;
$this->awbFactory = $awbFactory;
$this->registry = $registry;
$this->awbModel = $awbModel;
$this->session = $context->getSession();
$this->dataHelper = $dataHelper;
parent::__construct($context);
}
/**
* Edit action new awb.
*
* #return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
$id = $this->getRequest()->getParam('entity_id');
if ($id) {
$model = $this->awbRepository->getById($id);
if (!$model->getEntityId()) {
$this->messageManager->addErrorMessage(__('This field no longer exists.'));
/** \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create();
return $resultRedirect->setPath('*/*/');
}
} else {
echo '3';
$model = $this->awbFactory->create();
}
/** #var Session $data */
$data = $this->session->getFormData(true);
if (!empty($data)) {
$model->setData($data);
}
$this->registry->register('awb_data', $model);
echo 'wat';
/** #var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->addBreadcrumb(__('Edit new Awb'), __('Edit new Awb'));
$resultPage->getConfig()->getTitle()->prepend(__('Edit new Awb'));
echo 'pac';
return $resultPage;
}
the controller currently returns a blank page with my debug strings:
3watpac
in /vendor/eadesignro/awb/Block/Adminhtml/Xtea I have the next files:
Edit (folder)
Edit.php
EditAwb.php
in /vendor/eadesignro/awb/view/adminhtml/layout I have the next files:
shipping_awb_index_edit.xml
shipping_awb_index_editawb.xml
shipping_awb_index_index.xml
Content of shipping_awb_index_edit.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="editor"/>
<head></head>
<body>
<referenceContainer name="content">
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit" name="awb_edit"/>
</referenceContainer>
<referenceContainer name="left">
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit\Tabs" name="awb_edit_tabs">
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit\Tab\General" name="awb_edit_tab_general"/>
<action method="addTab">
<argument name="name" xsi:type="string">general_section</argument>
<argument name="block" xsi:type="string">awb_edit_tab_general</argument>
</action>
<block class="Eadesigndev\Awb\Block\Adminhtml\Xtea\Edit\Tab\Curier" name="awb_edit_tab_curier"/>
<action method="addTab">
<argument name="name" xsi:type="string">curier_section</argument>
<argument name="block" xsi:type="string">awb_edit_tab_curier</argument>
</action>
</block>
</referenceContainer>
</body>
</page>
This is the page:
magento_admin_secreturl/shipping_awb/index/edit/key/xxxxxx
these are the routers:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="shipping_awb" frontName="shipping_awb">
<module name="Eadesigndev_Awb" before="Magento_Backend"/>
</route>
<route id="edit_awb" frontName="edit_awb">
<module name="Eadesigndev_Awb" before="Magento_Backend"/>
</route>
</router>
</config>
Any possible idea on why $this->resultPageFactory->create(); is simply returning nothing on production but working on development?
The index page works both on production and dev without any problem.
I can provide more info if needed, thank you!
The problem was a CAPSLOCK mistake in the namespace.
namespace Eadesigndev\AWB\Controller\Adminhtml\Index;
should have been
namespace Eadesigndev\Awb\Controller\Adminhtml\Index;
notice the 'AWB' becoming 'Awb'.
Apparently in development mode, the namespaces are not case-sensitive? or perhaps they are all transformed to capslock. If anyone has a clue, leave a comment, thanks!
For anyone who is still getting a blank page in Admin Controller, but the alternative solutions (case-sensitive) doesn't work for you, you may try running php bin/magento setup:di:compile.
This helped me.
I want to save order data in custom Table After order success.
app/code/VendorName/Checkout/etc/event.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="checkout_onepage_controller_success_action">
<observer name="MyObserver" instance="VendorName\Checkout\Observer\MyObserver" />
</event>
</config>
app/code/VendorName/Checkout/Observer/MyObserver.php
<?php
namespace VendorName\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface;
class MyObserver implements ObserverInterface
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
$orderIds = $observer->getEvent()->getOrderIds();
echo $orderId = $orderIds[0]; exit;
}
}
Event is not trigger success.phtml is redirected.
The event.xml file name should be events.xml. After renaming file check again
If still the problem, put your events file to
app/code/VendorName/Checkout/etc/frontend/events.xml
Confirm if the plugin installed by executing
php bin/magento module:status
If the module is not listed, execute
php bin/magento setup:upgrade
Heyo, been working on a magento theme for a little while now (... and my understanding of the system is slowly but steadily growing). I need to start working on some custom modules soon, and so I'm starting with this little project to get my bearings:
I found a little bit of code to manage a specific task that I have been copying and pasting into template files:
<?php
$ids = $_product->getCategoryIds();
$cat = Mage::getModel('catalog/category')->load($ids[0]);
$isFF = false;
foreach ($ids as $key=>$val) {
$cat = Mage::getModel('catalog/category')->load($val);
$name = $cat->getName();
if ( $name === 'Fast Fulfillment' ) {
$isFF = true;
}
}
if ($isFF) { echo '<span class="ff-logo"></span>'; }
?>
Very simple. I'm just checking to see if a product is in a specific category, and producing an element if it is. (I know there are about 5 solid ways of doing this... this is the one I went with).
I need to test this every time a product block is displayed, and have, up till now, been replicating this code to make it work. It does work, but is backasswards (I shouldn't be putting logic into the view layer).
Ok - so, lets make a simple module to share the functionality:
local/WACI/ProductFlag/etc/config.xml
<config>
<modules>
<WACI_ProductFlag>
<version>0.1.0</version>
</WACI_ProductFlag>
</modules>
<global>
<blocks>
<WACI_ProductFlag>
<class>WACI_ProductFlag_Block_View</class>
</WACI_ProductFlag>
</blocks>
</global>
</config>
etc/modules/WACI_All.xml
<config>
<modules>
<WACI_CustomPageLayouts>
<codePool>local</codePool>
<active>true</active>
</WACI_CustomPageLayouts>
</modules>
<modules>
<WACI_ProductFlag>
<codePool>local</codePool>
<active>true</active>
</WACI_ProductFlag>
</modules>
</config>
Now, for the Class ... I'm not really sure if a Block or a Helper is appropriate. I went with Block, but - idk... I'm probably wrong (tutorials for this stuff vary wildly).
local/WACI/ProductFlag/Block/View.php
<?php
/**
* WACI
*
* #codepool Local
* #category View
* #package WACI
* #module ProductFlag
*/
class WACI_ProductFlag_Block_View extends Mage_Core_Block_Template
{
private $_focus;
private $_isFF = false;
public function getIsFF( $product ){
$this->_focus = "FF";
$isFF = false;
$ids = $product->getCategoryIds();
$cat = Mage::getModel('catalog/category')->load($ids[0]);
foreach ($ids as $key=>$val) {
$cat = Mage::getModel('catalog/category')->load($val);
$name = $cat->getName();
if ( $name === 'Fast Fulfillment' ) {
$isFF = true;
}
}
}
protected function _toHtml(){
$html = parent::_toHtml();
if ($this->_focus === "FF") {
if ($this->_isFF){
$html .= '<span class="ff-logo"></span>';
}
}
return $html;
}
}
?>
Hopefully its clear that I only want to output a string based on the input of any given product. Should I be overriding the _toHtml() to deliver the string? Again. Probably not...
in my local.xml I reference the block:
<catalog_product_view>
<reference name="content">
<reference name="product.info">
<block type="WACI/ProductFlag" name="product.flag" as="productFlag" output="toHtml" />...
... I'm not clear if this instantiates this class? I don't think so. I'm not really sure how to address it in my product/view/media.phtml anyway, given that I need to call a method with a parameter.
I don't think I need a template file, given that I'm just outputting a string, but I don't think I've seen block modules without an associated template. Maybe a helper class is appropriate then?
Whatever the case, it ain't workin.
I either get a fatal error saying my media class has no getIsFF() method (not surprising), or just nothing shows up. My config files are correct, but that's about it, I think.
Jebus. I'm all turned around.
Can someone with Mage skillz clarify this simple issue and point me in the right direction?
Cheers!
No advice? Well = I sussed out this slightly modified and working solution:
local/WACI/ProductFlag/etc/config.xml
<config>
<modules>
<WACI_ProductFlag>
<version>0.1.0</version>
</WACI_ProductFlag>
</modules>
<global>
<blocks>
<productflag>
<class>WACI_ProductFlag_Block</class>
</productflag>
</blocks>
<helpers>
<productflag>
<class>WACI_ProductFlag_Helper</class>
</productflag>
</helpers>
</global>
</config>
local/WACI/ProductFlag/Helper/Flag.php
class WACI_ProductFlag_Helper_Flag extends Mage_Core_Helper_Abstract
{
private $_isFF = false;
public function getIsFF( $product ){
$html = '';
$ids = $product->getCategoryIds();
$cat = Mage::getModel('catalog/category')->load($ids[0]);
foreach ($ids as $key=>$val) {
$cat = Mage::getModel('catalog/category')->load($val);
$name = $cat->getName();
if ( $name === 'Fast Fulfillment' ) {
$this->_isFF = true;
}
}
if($this->_isFF) {
$html = '<span class="ff-logo"></span>';
}
return $html;
}
}
and call it up in any template file via the simple:
<?php echo $this->helper('productflag/flag')->getIsFF($_product); ?>
I'm still not sure if this is exactly appropriate to the magento way of doing things - ie the model calls, I think, should be relegated to their own class and dropped in a Model folder.
Whatever the case - and for anyone else trying to figure this stuff out - as I monkeyed around with it I slowly realized the intent of the config.xml file is to add available factory classes to the blocks/helpers/model pools - and that the path is to the containing directory. The helper call in the template file, then, identifies the "short name" of the directory and then the actual class name.
ie - You could have multiple classes of helpers:
<?php echo $this->helper('productflag/class_one')->someMethod($_product); ?>
<?php echo $this->helper('productflag/class_two')->someOtherMethod($_product); ?>
<?php echo $this->helper('productflag/class_three')->yetAnotherMethod($_product); ?>
So... One step closer.
I'm trying to write an observer that will export order data when an order is placed. I haven't written any modules before. Basing my implementation on this article: http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method
so far I'm just trying to trigger some dummy code to write to a file. I'm not getting anything showing in my log, and the file's not being modified. The apache user has permission for the directory. I've disabled configuration caching in the Magento settings. I'm a little confused on some of the naming conventions; I just tried to follow the example. Anyone know where I'm going wrong?
in magento/app/etc/modules/Feed.xml:
<?xml version="1.0"?>
<config>
<modules>
<Feed_Sales>
<codePool>local</codePool>
<active>true</active>
</Feed_Sales>
</modules>
</config>
in magento/app/code/local/Feed/Sales/etc/config.xml:
<?xml version="1.0"?>
<config>
<global>
<models>
<feedsales>
<class>Feed_Sales_Model</class>
</feedsales>
</models>
<events>
<sales_order_place_after>
<observers>
<feed_sales_order_observer>
<type>singleton</type>
<class>sales/order_observer</class><!-- I've also tried Feed_Sales_Model_Order_Observer here -->
<method>export_new_order</method>
</feed_sales_order_observer>
</observers>
</sales_order_place_after>
</events>
</global>
</config>
in magento/app/code/local/Feed/Sales/Model/Order/Observer.php:
<?php
class Feed_Sales_Model_Order_Observer
{
public function __contruct()
{
}
/**
* Exports new orders to an xml file
* #param Varien_Event_Observer $observer
* #return Feed_Sales_Model_Order_Observer
*/
public function export_new_order($observer)
{
Mage::log("reached export_new_order");
try
{
$dumpFile = fopen('/home/jorelli/new_orders/testdump', 'w+');
fwrite($dumpFile, 'this is a test!');
}
catch (Exception $e)
{
Mage::log("order export failed.\n");
}
return $this;
}
}
?>
Magento 1.4 on Debian Lenny with Apache2 if it should matter for any reason.
Read my articles, they'll help you understand what's going on from a naming convention standpoint and get you grounded in some of Magento's conventions/assumptions.
Looking at the samples above, you have a few things not quite right.
First, your file in the etc folder is named wrong
magento/app/etc/modules/Feed.xml
This file needs to be named Packagename_Modulename, so you probably want
magento/app/etc/modules/Feed_Sales.xml
Look at System -> Configuration -> Advanced to see if your module shows up. If it does, you'll have named this file correctly. Without this, the module you created isn't being loaded into the system, and your code never has a chance to run.
Next, you're specifying the class incorrectly. You say
sales/order_observer
but that first part of the URI (sales) is incorrect. You defined your models section as
<models>
<feedsales> <!-- this is your model part -->
<class>Feed_Sales_Model</class>
</feedsales>
</models>
which means you want
feedsales/order_observer
Checkout the Class/URI tab of Commerce Bug and try entering some URIs (like sales/order) to get a better idea of what's going on here.
Another quick tip, when you're trying to get your handler setup, do it for an event that fires on every page load. Then, once you have your method being called, you can switch it to the specific event you want and not have to go through the entire purchase process.
Finally, and I realize you were copying examples, consider putting your module in a folder named something other than Sales. I find mimicking the names of Magento core folders only add an extra layer of confusion, which is not what you need while you're learning the system.
The problem seems to be with your observer declaration. Give this a try:
<events>
<sales_order_place_after>
<observers>
<feed_sales_order_observer>
<type>singleton</type>
<class>feedsales/order_observer</class>
<method>export_new_order</method>
</feed_sales_order_observer>
</observers>
</sales_order_place_after>
</events>
Holy crap. I was stupid. I tested it out with a command line script, like I do with a lot of things, but that particular file was only writeable by the command line interpreter, not the Apache interpreter. I should have left the office earlier last night.
Well for the record, this is how you trigger an action on order placement. I'll leave it up for posterity.
better use this event instead of sales_order_save_after and checkout_onepage_controller_success_action
checkout_submit_all_after
it will work even site not redirected to success page because of some errors like internet issue and all.
try to use below code my requirement also same
namespace Custom\Checkout\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Simplexml\Element as SimpleXMLElement;
class Afterplaceorder implements ObserverInterface
{
protected $_request;
protected $_layout;
protected $_dir;
protected $jsonHelper;
protected $timezone;
protected $_io;
protected $_RandomBytes;
public function __construct(
\Magento\Framework\View\Element\Context $context,
\Magento\Framework\Filesystem\DirectoryList $dir,
\Magento\Framework\Json\Helper\Data $jsonHelper,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone,
\Magento\Framework\Filesystem\Io\File $io,
\Magento\Framework\Math\Random $RandomBytes
){
$this->_layout = $context->getLayout();
$this->_request = $context->getRequest();
$this->_dir = $dir;
$this->jsonHelper = $jsonHelper;
$this->timezone = $timezone;
$this->_io = $io;
$this->_RandomBytes = $RandomBytes;
}
/**
* #param \Magento\Framework\Event\Observer $observer
* #return void
*/
public function execute(EventObserver $observer)
{
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/orderdata.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$order = $observer->getData('order');
$quote = $observer->getQuote();
try{
// function defination to convert array to xml
function array_to_xml( $data, &$xml_data ) {
foreach( $data as $key => $value ) {
if( is_numeric($key) ){
$key = 'item'.$key; //dealing with <0/>..<n/> issues
}
if( is_array($value) ) {
$subnode = $xml_data->addChild($key);
array_to_xml($value, $subnode);
} else {
$xml_data->addChild("$key",htmlspecialchars("$value"));
}
}
}
$data = array('total_stud' => 500);
// creating object of SimpleXMLElement
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><order></order>');
// function call to convert array to xml
array_to_xml($orderDeatails,$xml_data);
//saving generated xml file;
if ( ! file_exists($this->_dir->getPath('var').'/api/order')) {
$this->_io->mkdir($this->_dir->getPath('var').'/api/order', 0775);
}
$result = $xml_data->asXML($this->_dir->getRoot().'/var/api/order/order_'.$order->getIncrementId().'.xml');
}catch(\Exception $e){
$logger->info(print_r('error-> '.$e->getMessage(),true));
}
}
}
hope it will help you!
Happy Coding!!