Magento 2.2 - Cannot update attribute values - magento

I've created some custom product attributes with REST API, correctly populated them and assigned values to products.
Everything works fine in dev environment whereas I got difficulties in staging environment, even though values and settings are the same, even in the DB.
If, for example, I want to update the value of "is_filterable" option in an existing attribute from the backend, Magento says it saved the attribute correctly, but actually no changes are made.
I've tried to update with a PUT call to REST API with correct values, but I'm able to update only the attribute labels,
This is the json i'm passing to "products/attributes/my_attr"
{"attribute":{"attribute_code":"my_attr","attribute_id":174,"scope":"Global","default_frontend_label":"my_attr","frontend_labels":
[{"store_id":1,"label":"my_attr"}],"frontend_input":"select","is_searchable":true,
"is_visible_in_advanced_search":true,"is_comparable":true,"is_filterable":true}}
And this is the Json response, where you can see it is totally ignoring the values for is_filterable and scope.
{"is_wysiwyg_enabled":false,"is_html_allowed_on_front":false,"used_for_sort_by":
true,"is_filterable":false,"is_filterable_in_search":false,"is_used_in_grid":
true,"is_visible_in_grid":true,"is_filterable_in_grid":true,"position":0,
"apply_to"[], "is_searchable":"0","is_visible_in_advanced_search":"0",
"is_comparable":"0","is_used_for_promo_rules":"0","is_visible_on_front":"0",
"used_in_product_listing":"0","is_visible":true,"scope":"global",
"attribute_id":174,"attribute_code":"taglia","frontend_input":"select",
"entity_type_id":"4","is_required":false,"....
Obviously I've reindexed and cleared caches continuously.
The only way I managed to change those values is directly from the DB.
I'm going to try with an extension but I'm not sure to succeed.
I've seen there was an issue that should have been fixed in older Magento versions and actually other attributes work fine.
Any clue?
EDIT
With a different set of parameters in the call, I managed to change the attribute values, but still no luck from the backend.
This is the updated request (array version)
$data = [
"attribute" => [
"attribute_code" => $my_opt,
"attribute_id" => 173,
"entity_type_id" => 4,
"scope" => "global",
"default_frontend_label" => $my_opt,
"frontend_labels" => [
["store_id" => 1,
"label" => $my_opt ]
],
"frontend_input" => "select",
"is_wysiwyg_enabled" => true,
"is_html_allowed_on_front" => true,
"used_for_sort_by" => true,
"is_filterable" => true,
"is_filterable_in_search" => true,
"is_used_in_grid" => true,
"is_visible_in_grid" => true,
"is_filterable_in_grid" => true,
"position" => 1,
"is_searchable" => true,
"is_visible_in_advanced_search" => true,
"is_comparable" => true,
"is_used_for_promo_rules" => true,
"is_visible_on_front" => true,
"used_in_product_listing" => true,
"is_visible" => true
]
];
EDIT2: Moreover, if I try to update some info from the backend, Magento resets the values of the default view store label to empty and the "use in layered navigation" to "No". Stranger at any try.
EDIT 3
seems like the most possible issue can be caused by duplicated values in these dropdown attributes, but I carefully removed all of them from
eav_attribute_option
eav_attribute_option_value
in the db, but actually removing options only, works from the backend too, whereas the creation of new options is not working

This is not a definitive solution, for which I will create a new question to which someone hopefully will be able to answer, but I wanted to post at least what the true problem is.
Actually, I observed that everything was working until a certain amount of options, and after that, no matter what the values were, it quit working.
Actually I experienced it also in the dev environment, for which the limit was higher, but for an attribute with more than 1300 options, nothing was working as well.
So looking around I found out this is a php memory problem and that you have to increase the value of
max_input_vars=100000
whereas by default is only 1000.
someone suggest also other parameters, but this is actually the most used.
The problem that remains, is that I still have not found the good values to have my attributes with many options, to work.

Related

Comparing laravel collections

I have two collections: "Instructions" and "Known". Basically I am taking a new set of "Instructions" and checking whether anything is different to what is "Known".
So, the quantity is not massive. I retrieve the info:
$Instructions = Instruction::all();
$Knowns = Known::all();
Now, I'm looking for the differences, and I've tried each of these three methods:
$IssuesFound = $Instructions->diff($Knowns);
$IssuesFound = $Instructions->diffKeys($Knowns);
$IssuesFound = $Instructions->diffAssoc($Knowns);
The thing is, an "Instruction" or "Known" is an item with 17 attributes, and anyone of those attributes can be different. I want to compare the attributes of an "Instruction" with the matching attribute of a "Known". (Both items have the same keys, bot items have a Reference attribute to act as a unique identifier.
What I'm finding is that theese methods give me the item that is different, but doesn't tell me which individual attributes are the mismatch.
foreach ($IssuesFound as $issue)
{
dd($issue);
}
So a method like $IssuesFound = $Instructions->diffKeys($Knowns); will come up with item xxx being different, but I can't see how to find out which attribute of the item it is that is different. Not unless I start nesting loops and iterating through all the attributes - which I'm trying to avoid.
How do I do it?
Thanks in advance. (Laravel 5.6)
Straight from laravel docs, diffAssoc will return what you are asking:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6
]);
$diff = $collection->diffAssoc([
'color' => 'yellow',
'type' => 'fruit',
'remain' => 3,
'used' => 6
]);
$diff->all();
// ['color' => 'orange', 'remain' => 6]
You get the attribute from the FIRST collection that is different on the SECOND collection, therefore if you get 3 attributes when calling $diff->all() you will know WHICH attributes ARE DIFFERENT, so you could access them or do whatever you want to, if you post more specific results of what you are getting and what you are trying we can help, but I think you are just not thinking how to use these methods

OctoberCMS Should this throw an error?

If I (incorrectly) define a belongsToMany as follows (Note the ] after the table key):
public $belongsToMany = [
'phonetypes' => [
'NigglesLogic\Suitespots\Models\Phonetype',
'table' => 'niggleslogic_suitespots_contact_phonetypes'],
'pivot' => ['phone_number']
];
I can view the page and no error is thrown. However the pivot data does not show.
If I change the above to this (with the ] after the pivot key, where I intended it to be):
public $belongsToMany = [
'phonetypes' => [
'NigglesLogic\Suitespots\Models\Phonetype',
'table' => 'niggleslogic_suitespots_contact_phonetypes',
'pivot' => ['phone_number']
]
];
The pivot data is shown when I refresh the page.
I realize that I made a typing error but I should OctoberCMS at least warn me about this situation?
Hmm, code structure of October CMS mostly check configuration and if its not correctly formatted then it ignore that thing.
Why ? : Because October CMS is based on Laravel and all the relational configuration is passed to the Laravel then it will initialize relations.
so it's really hard to predict what kind of mistake user will made, it's rather easy to just use key which needed for configuration and ignore rest.
So in your case: (I have rewritten your code in proper structure)
public $belongsToMany = [
'phonetypes' => [
'NigglesLogic\Suitespots\Models\Phonetype',
'table' => 'niggleslogic_suitespots_contact_phonetypes'
],
'pivot' => ['phone_number']
];
You can see that after restructuring it looks like we have defined 2 relations, one is phonetypes and other pivot, so when we try to fetch one of them
in first case [phonetypes] : it can not find proper relational data from table, but table exists so it returns null not an error
in second case [pivot] : we are not using it as we dont consider it as relation, still if we try to use it, it will not find table phone_number so it may throw an error.
for detecting error we need something like more predictable behavior.
[ Yes October CMS could show you a warning but to show that warning they need to write more code and it seems code size get double if they check everything :( ]
(we can not show warning for this) for ex if we define route:
Route::get('/som-item', function() { ...code... })
see, I mistakenly write /som-item but but, I need to use /some-item url so laravel can not able to give me warning about this as its correct route for it, it will show me that /some-item not defined error BUT it will not tell me that dude you did spelling mistake kind of WARNING :).
[ we don't see warning until we get some AI in code :) ]

Mongodb update document through ruby not working

I want to update documents in MongoDB via Ruby code. I have document ids of documents I want to update only a specific field. I tried the following code.
collection.update({"_id".to_s => doc_id},{"$set"=> {"selected" => "false"}})
and also
collection.update({"_id".to_s => doc_id},{"selected" => "false"})
Both commands execute without any error but the database remains unaffected.
According to the documentation, the way to update a document are
collection.update({"_id" => id}, doc)
or
collection.update({"_id" => id}, {"$set" => {"name" => "MongoDB Ruby"}})
The ID is expected to be a valid id. I'm not sure if a string is accepted, in case make sure to convert it to a BSON::ObjectId.
collection.update({"_id" => BSON::ObjectId.from_string(doc_id) }, {"$set" => {"selected" => "false" }})
Make sure to check the command returns true.
Also note that if you are using a driver version < 1.8, you should be using :safe => true.
The driver will send a getlasterror command after every write to ensure that the write succeeded by default. Prior to version 1.8 of the driver, writes were not acknowledged by default and it was necessary to explicitly specify the option ':safe => true' for write confirmation. This is no longer the case.

magento add last login to customer grid

I am new to Magento. I am trying to add a last login value displaying on customer grid. it returns a null value. I have read other tutorials, but it does not help much. The Magento version is 1.7. Here is my code:
$customer = Mage::getSingleton('customer/session')->getCustomer();
$logCustomer = Mage::getModel('log/customer')->load($customer ->getId());
$lastVisited = $logCustomer->getLoginAt();
$this->addColumn('$lastVisited', array(
'header' => Mage::helper('customer')->__('Last Login'),
'type' => 'datetime',
'align' => 'center',
'index' => '$lastVisited',
'gmtoffset' => true
));
Magento stores the login time in the following table:
log_customer
But also, this data is cleaned periodically (see: Mage_Log_Model_Resource_Log::_cleanCustomers which is triggered via Magento cron).
There are different ways to approach your task.
1) Non-persistent - I am just interested to see recent data (I can ignore that log_customer is cleaned periodically)
In this case you can just rely on the data from log_customer and display it in Manage Customers Grid.
Extend Mage_Adminhtml_Block_Customer_Grid and in _prepareCollection add the following:
$collection->getSelect()->columns(array('last_login_at' => new Zend_Db_Expr ("(SELECT login_at
FROM `log_customer`
WHERE customer_id =e.entity_id
ORDER BY log_id DESC
LIMIT 1)")));
before: $this->setCollection($collection);
Note: use the proper Magento function to get log_customer table name, my query is just for example
2) Persistent - I want to always to see the data
add a new attribute to the customer entity called: last_login_at
(datetime).
add an observer to custom_login event to update this
attribute.
use addColumn function in the grid to display this new attribute.
#user1414056
Regarding your code:
bixe made a fair point related to '$lastVisited' (this just shows
lack of experience in php programming
you seem to also be new to programming (in general) because the addColumn is called only once... do how do you expect your code to make sense?
With a better understanding of Zend Framework and OOP Programming in general you will be able to actually work and get things done with Magento.
Your '$lastVisited' can't work : in php variables are evaluated in a String only when they're in a double quote.
EDIT:
Ok the column system of magento only display value when they're available in the collection linked to the grid..
You'll have to add the log information you want to display in the grid collection.
For an example, take a look at Mage_Adminhtml_Block_Customer_Online_Grid::_prepareCollection()
When it's done, you will add your column with :
$this->addColumn('login_at', array(
'header' => Mage::helper('customer')->__('Last Login'),
'type' => 'datetime',
'align' => 'center',
'index' => 'login_at',
'gmtoffset' => true
));

Re-order sort orders in toolbar

What is the best way to re-order the available sort orders shown in the product list toolbar? Currently, we have 3 sorting options available: Name, Price, Most Popular (in that order). I want to have Most Popular be the left-most item since it is our default sort option. I can write a custom module to extend "getAvailableSortOrders" or something like that, but I thought there had to be an easier way. Anyone have a recommendation?
Brian
The best way I've found so far is to make a copy of
/app/code/core/Mage/Catalog/Model/Config.php
at
/app/code/local/Mage/Catalog/Model/Config.php
and then edit your local copy of the file at line 341
//before
$options = array(
'position' => Mage::helper('catalog')->__('Position')
);
//after
$options = array(
'name' => Mage::helper('catalog')->__('Name'),
'price' => Mage::helper('catalog')->__('Price'),
'position' => Mage::helper('catalog')->__('Best Value')
);
I wanted name to be first, followed by price, and I wanted position to be renamed "Best Value" on the frontend. Since position wouldn't really mean anything to a customer.
I was inspired by this comment on Inchoo.
#jon.niesen: your solution worked only partially. I had no problems renaming 'position' but when it comes to renaming 'name', Magento was very stubborn on this and was still displaying "Name" in the select drop down box.
Maybe in 1.4.1.1 "Name" is hardcoded or something?

Resources