Using Magento’s back-office, after saving a category which was linked to many products, only the first 1000 products (or 2000, or x000, depending on host configuration) are kept.
All other category/product links are deleted from the catalog_category_product table in the database.
This occurs even though no checkboxes have been unchecked in the products grid (Category Products tab).
No error message is displayed or logged.
Tracing data posted from the browser to the server doesn’t reveal any missing product IDs, but even if you check more products on the back-office grid, when finally saving the category, the server only keeps the first x000 and removes other IDs…
Though some answers can be found on other websites, I thought it was worth sharing this on StackOverflow…
The source of the problem can be found in
Mage_Adminhtml_Catalog_CategoryController, where thesaveAction()method retrieves a big POSTed string (category_products, encoded like a query string), which is processed by PHP functionparse_str():Alas! As from version 5.3.9 of PHP, there is a new configuration setting called
max_input_vars, which limits the number of input variables that may be accepted.This limit is mainly applied to
$_GET,$_POSTand$_COOKIEsuperglobals, but is also used internally by theparse_str()function!(See PHP manual)
Depending on the
php.iniconfiguration of your host, the number of products linked to a category is therefore limited by this setting…One solution is to increase the value of
max_input_vars, inphp.inior in.htaccess:This can even be done more safely by changing this setting only for admin pages (adapt the LocationMatch pattern to your own back-office URL style):
(Source)
This only solves the problem until one of your categories reaches the new max number of products…
Another solution would be to fix Magento’s code in order not to use the parse_str() function at this point.
For instance, in
Mage_Adminhtml_Catalog_CategoryController,saveAction()method, replace:with:
(Source)
It’s hard to decide which solution is the best, since the first one makes your server more vulnerable to attacks (as the
max_input_varsis meant to mitigate the possibility of denial of service attacks which use hash collisions), and the second solution makes you modify a Magento core class, which can lead to further problems in future Magento upgrades…Hope this is useful anyway, I struggled some time before I could find out why some categories kept loosing some products!