циклический просмотр коллекции продуктов и сохранение продуктов изменяет значения атрибутов непреднамеренных изменений - PullRequest
1 голос
/ 19 апреля 2011

Я запускаю цикл по коллекции продуктов, как показано ниже

$productCollection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('small_image')
    ->addAttributeToSelect('thumbnail')
    ->addAttributeToSelect('image')
    ->addAttributeToSelect('sku');

foreach($productCollection as $product){
    $product->setSmallImage($product->getImage());
    $product->setThumbnail($product->getImage());
    $product->save();
}

Я устанавливаю другие типы изображений так же, как базовое изображение, потому что клиент забыл установить их в листе импорта. По какой-то причине, делая это, он устанавливает видимость всех продуктов в каталог, поиск. Предполагается, что многие из моих продуктов «не видны по отдельности», так что, конечно, это все испортило.

Любая идея, почему это значение изменится, и есть ли другие значения, которые могут измениться в зависимости от того, как я перебрал коллекцию продуктов?

Я думаю, что это потому, что я удалил addAttributeToSelect (*) и сделал это специфично для двух атрибутов, но при попытке сделать коллекцию товаров из 18 тыс. Продуктов она выкидывалась

Ответы [ 2 ]

4 голосов
/ 19 апреля 2011

Хорошо, вот что я нашел. При сохранении объекта в Magento он будет вызывать обычный метод абстрактного сохранения модели, который затем вызывает $this->_getResource()->save($this);, который вызывает метод абстрактного сохранения сущности, который в итоге получает метод /app/code/core/Mage/Eav/Model/Entity/Abstract.php and its _beforeSave(), который вызывает метод walkAttributes($partMethod, array $args=array()).

В течение долгого времени все атрибуты загружаются в объект Resource объекта. Метод walkAttributes проходит все атрибуты, связанные с сущностью, и вызывает этот метод call_user_func_array (array ($ instance, $ method), $ args); и в моем случае это вызов метода beforeSave для атрибута, как вы можете видеть здесь

/app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Abstract.php
public function beforeSave($object)
    {
        $attrCode = $this->getAttribute()->getAttributeCode();
        if (!$object->hasData($attrCode) && $this->getDefaultValue()) {
            $object->setData($attrCode, $this->getDefaultValue());
        }
    }

Таким образом, любой атрибут, который не имеет никаких данных и имеет значение по умолчанию, это значение по умолчанию применяется к объекту, в смысле перезаписывает мои данные, которые действительно установлены, просто не загруженные в мой объект. Я предполагаю, что лучший способ перебрать тысячи продуктов - это задать для pageSize число, которое ваш сервер может обработать, а затем вы можете установить addAttributeToSelect ('*'). Однако я не знаю, как лучше всего обойти это правильно, поэтому я могу просто загрузить продукт в цикл for и не устанавливать атрибут для выбора всего.

Вот моя попытка перебрать всю коллекцию, пожалуйста, опубликуйте любые улучшения

$productCollection = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*')->setPageSize(200);
for ($i = 1; $i <= $productCollection->getLastPageNumber(); $i++) {
    if ($productCollection->isLoaded()) {
        $productCollection->clear();
        $productCollection->setPage($i);
        $productCollection->setPageSize(200);
    }
    foreach ($productCollection as $product) {
        echo $product->getId() . "\n\n";
    }
    echo $i . "\n\n";
}

Я бы хотел услышать еще какие-либо комментарии по поводу того, является ли это правильным мышлением или объяснением проблемы.

0 голосов
/ 07 сентября 2011

Я на самом деле нашел лучший способ перебрать большую коллекцию, которая заключается в использовании модели итератора ресурсов, и вот учебник, как это сделать от ребят из Fontis

http://www.fontis.com.au/blog/magento/loading-large-collections

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...