Catching product attribute update massaction event - magento

I am trying to listen to the "catalog_product_save_before" and "catalog_product_save_after" events which are correctly triggered when I save individual product from admin interface.
But, these events are not triggered when I use the "update attributes" action for multiple product selections, from the product list grid. Is there any event which is triggered whenever a product attribute is updated ?? I know I need to write different observer function for csv upload but I need the event for grid action "Update attributes"..
Thanks in advance.
Cheers..

Got this to work out!!
I used this event : catalog_product_attribute_update_before
This give an array with changed attributes and product ids :
[attributes_data] => Array
(
[price_markup] => 10
)
[product_ids] => Array
(
[0] => 6
)
[store_id] => 0
Hope this helps ..
Cheers!!!

this might be a vague answer, I am not sure what you try to do with the attribute but maybe have a look into the Mage_Indexer module. Its bit more complex but it listens to all events or at least Magento takes care of notifying it if something is outdated or has changed.
And also if something goes funky with your data, rerunning your indexer should clean up all the data in an ideal world.

Related

Laravel mailchimp event properties are empty in template

Did my research and found nothing about this topic.
In the docs: https://mailchimp.com/developer/marketing/guides/track-outside-activity-events/#create-an-event
Apparently said how to create an event with options, using the library that they said which in PHP is:
composer require mailchimp/transactional
I can ping, do all the simple requests without problem
but some options for events are not even avaliable, for example:
$options = new \MailchimpMarketing\Model\Events();
there is no 'Model' or Events in that namespace,
then of course I looked how this event is build in other languages and I give a try to pass parameters to the event like this:
$options = ["name" => "my-event-name", "properties" => ['PASSLINK' => 'test']];
$response = $mailchimp->lists->createListMemberEvent(
env('MC_AUDIENCE_ID'),
"somemember#gmail.com",
$options
);
200 status response, Event is trigger, mail received
but in the template used, nothing is passed:
I used in that template that event property like this:
*|EVENT:PASSLINK|*
also tried lowercase
*|EVENT:passlink|*
Same result
don't know what else to do
I had a similar issue. Seems that for a journey, the event property merge tag *|EVENT:PROPERTY|* does not work. They only work for classic automation. May be that is the issue.
Same issue here.
I tried all these combination of EVENT properties.
None of them works..
*|EVENT:name|*
*|EVENT:NAME|*
*|EVENT:PROPERTIES|*
*|EVENT:properties|*
*|EVENT:PROPERTIES:CODE|*
*|EVENT:properties:code|*

How to add / remove elements from array that is in Request

My request looks like this
Array
(
[name] => Eugene A
[address] => Array
(
[billing] => Array
(
[address] => aaa
)
[shipping] => Array
(
[address] => bbb
)
)
)
I need to delete the shipping address. But how?
I can only delete both addresses,
$request->request->remove('address');
but I don't want it.
I want to delete only shipping address, like so
$request->request->remove('address.shipping');
But it is not working for me
Laravel 5.6
Update
Why do I need it?
Easy. I have abstracted out my Form Request validation into a class that is a child to Illuminate\Foundation\Http\FormRequest.
I actually have few classes for validation. I call them one by one in a controller like so:
app()->make(CustomerPostRequest::class); // validate Customer information
app()->make(AddressSaveRequest::class); // validate Addresses
Why?
Now I can Mock this requests in unit-tests, and I can have my validation abstracted out. And I can use Address validation in many places.
But Now I need more flexibility. Why?
Because AddressSaveRequest rule looks like this
public function rules(): array
{
return [
'address.*.address' => [
'bail',
'required',
'string',
],
...
It validates all addresses.
But sometimes I don't want to validate shipping address, if the the chech_box - ship_to_the_same_address is ticked.
But I have my Address validator abstracted in separate file and it is used in many places. There are places where ship_to_the_same_address tick box is not presented.
Thus I cannot use 'required_unless:ship_to_same_address,yes',
And I cannot use
app()->makeWith(AddressSaveRequest::class, ['ship_to_the_same_address ' => 'yes']);
Because Taylor said ...when calling makeWith. In my opinion it should make a new instance each time this method is called because the given parameter array is dynamic.. And it does, and it does not work correctly with app()->instance(AddressSaveRequest::class, $addressSaveRequest); and cannot be mocked in unit tests.
Why Taylor decided it - I seriously don't know.
PS
And yes, I know that mocking requests is not recommended.
If you were trying to add or remove inputs from the Request itself:
You can add data to the request pretty easily by merging it in and letting Laravel handle which data source is being used:
$request->merge(['input' => 'value']);
That will merge in the input named input into the input source for the Request.
For removing inputs you could try to replace all the inputs without that particular input in the replacement:
$request->replace($request->except('address.shipping'));
Just one idea to try.
Try this:
$request->except(['address.shipping']);
Details: Laravel Request
Laravel has a helper method called array_forget, which does exactly what it sounds like:
$requestArray = $request->all();
$newArray = array_forget($requestArray, 'address.shipping')
Documentation
After the edit to the main question with why some inputs of the request are to be deleted, my main answer isn't correct anymore. User Lagbox has the correct answer for the question that was asked.
However, I would like to note that another solution would be to have seperate Request classes with validation. One for placing an order (assuming it is a system where someone can order stuff) where ship_to_same_address is present and another one for things like updating your account, like PlaceOrderRequest and UpdateAccountRequest classes.

Drupal Commerce Order object extra data

How might it be possible to get Commerce-Product-Display information in a Commerce-Order object?
The issue is I need to publish a Commerce-Product-Display node when a user has made a payment to publish the node. I am using Rules to detect the payment and attempt to publish the node.
My problem is, because the Completing the checkout process Rules event only has data for a Commerce-Order, and the Commerce-Order does not have information for the Product nor the Product display, I am unable to publish the node.
OK, so here's my new answer based on the new info you provided in your question
=================================
So this is probably a little more complicated than you expected, but not impossible! Two things are important:
the line-items that are attached to your order will contain your products and
you will need to use a rule component, in order to be able to have an additional 'condition-action' combo inside your rule action
Here is how to do it:
In your rule that is triggered upon 'Completing the checkout process', add a loop in your 'Actions' section. You should see 'Add loop' right next to 'Add action'. We'll use this loop to iterate through all the commerce-line-items in your order: that's where the products are hiding
When configuring the loop, tell it to iterate through 'commerce-order:commerce-line-items' and either rename, or remember what it's going to call each line item as it goes through it.
Now - as it's going through each of your order's line items, we'll want to call an entire new rule with its own set of 'condition' and 'action'. The condition we need is to check that the line item contains the product you expect, and the action can be whatever you want - publish a node based on a certain field or whatever. In my case, the action will just be sending an email to prove I found a product. When we need condition-action sets within a rule, we need to create a rule component!!
Go to /admin/config/workflow/rules/components to create a new rule component to run for each of the above items. Click the 'Add new component' link at the top of the page
Select 'Rule' from the drop-down options, since this will be a component that contains both a condition and an action
Name the rule, and in the 'Variables' section, we have to let it know we're going to pass it a parameter to work with. In our case, it will be the commerce line item that is currently being iterated through.
Add two conditions to your component (or whatever checks you think are necessary). I added 'Entity is of type' => Commerce Line item and 'Entity has field' => commerce_product. So this runs for all my products at the moment.
The condition I set on my component is to send an email, and I filled in the following for the body of the email: [line-item:commerce_product], and it prints out the product's name beautifully in the email each time I've tested checking out!
But first - how do I call this component for each of my line item types after I save it?? Read on:
After the component is saved, Add an action to your loop:
From now on, at the very bottom of your actions, you'll see a brand new 'Components' section, and in your case, you should only have one now. Select it to call it for each item:
Last step will be to fill in the parameter to pass to this component, which is obviously the list_item you're currently on, or whatever the computer name of the current item was if you changed it.
Save and test!
Whew! It's a little complicated, but I hope it puts you in the right direction!
The way rules work in Drupal is that not all fields are shown for your entity by default in the actions. What you need to do is prompt Rules to recognize your object as a certain type of node in order for the Rule to add all of its appropriate fields.
You can do this either by
using the 'Content is of type' under the Node section check (and select your Commerce Display node type or
directly using the 'Entity has field' check under the Entities section to check for a specific field you want to use.
Either of those should prompt Rules to recognize the type of entity you're working with and populate the Actions with the necessary fields.
Let us know if this works!

Magento adding actions In orders

I'm using Magento Community 1.7. When I go to Sales-->Orders I see all the orders. Currently I can tick certain orders and, using the action dropdown, I can print invoices, cancel, hold etc. I'm wondering if there is anyway that I can add actions like "Requires Refund", "Fraud". The actions wouldn't neccessarily have to do anything just change the status so I can see clearly for later the status of these orders. Any ideas?
In order to add more actions you need to override this method Mage_Adminhtml_Block_Sales_Order_Grid::_prepareMassaction().
For each action you add, you will need a method in the controller you send it to.
Take for example the action Cancel. It is added to the mass action block like this:
$this->getMassactionBlock()->addItem('cancel_order', array(
'label'=> Mage::helper('sales')->__('Cancel'),
'url' => $this->getUrl('*/sales_order/massCancel'),
));
and the corresponding method is Mage_Adminhtml_Sales_OrderController::massCancelAction()

Magento - Call to undefined method Mage_Catalog_Model_Product_Type_Simple::getConfigurableAttributesAsArray

I'm getting the following error when I hit a configurable product using the saveRow method from /app/code/local/Mage/Catalog/Model/Convert/Adapter/Productimport.php:
[05-Jul-2011 18:12:32] PHP Fatal error: Call to undefined method Mage_Catalog_Model_Product_Type_Simple::getConfigurableAttributesAsArray() in /home/gp/public_html/app/code/local/Mage/Catalog/Model/Convert/Adapter/Productimport.php on line 107
My problem is a little different to others I've come across online perhaps in that I'm calling saveRow() from my own script that is building and maintaining a list of products, downloaded from my supplier by xml feed, in a temporary database before then using magento to add or update them in my site's catalog.
require_once($_SERVER['DOCUMENT_ROOT']."/app/code/local/Mage/Catalog/Model/Convert/Adapter/Productimport.php");
$MageProducts = new Mage_Catalog_Model_Convert_Adapter_Productimport();
...
...
foreach($products as $product) {
$result = $MageProducts->saveRow($product);
}
The first time I hit a configurable product I get this error but if I immediately hit refresh the script runs right past that product and all the way through to the end, passing many simple/configurable product sets on its way, without failing.
Line 107 of ProductImport.php is this line
$cspa = $product->getTypeInstance()->getConfigurableAttributesAsArray($product);
For some reason the $product->getTypeInstance is returning Mage_Catalog_Model_Product_Type_Simple but only the first time in a session?!
If I add print_r($product->getTypeInstance()) just before that line I get the following for a configurable product
Mage_Catalog_Model_Product_Type_Simple Object ( [_product:protected] => Mage_Catalog_Model_Product Object ( [_cacheTag:protected] => catalog_product [_eventPrefix:protected] => catalog_product [_eventObject:protected] => product [_canAffectOptions:protected] => [_typeInstance:protected] => Mage_Catalog_Model_Product_Type_Simple Object *RECURSION* [_typeInstanceSingleton:protected] => Mage_Catalog_Model_Product_Type_Configurable Object ( [_usedProductAttributeIds:protected] => _cache_instance_used_product_attribute_ids....
Which is clearly wrong...
I want to be able to use my script through cron, but this error is stopping me from doing that so I desperately need some help to fix - can anyone offer some advice?
Before this:
$product->getTypeInstance()->getConfigurableAttributesAsArray($product);
Check $product->isConfigurable();. If it is, only run:
$product->getTypeInstance()->getConfigurableAttributesAsArray($product);
I know this was asked long back but still for anybody who faces this issue in future. I struggled for a week almost and tried different solution found on internet. At last here we go, the issue was i had a simple product with the same sku as the configurable product i was trying to import.
That's work just for configurable items, so for this, first check if product is configurable with this code:
if($product->isConfigurable()){
$cspa = $product->getTypeInstance()->getConfigurableAttributesAsArray($product);
....

Resources