Вопрос: Исключение, возникающее в Varien_File_Uploader при использовании XMLRPC для изменения категорий


Я использую XMLRPC-API Magento (1.6.2.0) для назначения / удаления продуктов из категории. Недавно я просмотрел журналы исключений и заметил, что существует множество исключений. Всякий раз, когда я обновляю категорию, возникает следующая ошибка:

2012-03-14T10:35:33+00:00 ERR (3): 
exception 'Exception' with message '$_FILES array is empty' in /path/to/magento/includes/src/Varien_File_Uploader.php:461
Stack trace:
#0 /path/to/magento/includes/src/Varien_File_Uploader.php(149): Varien_File_Uploader->_setUploadFileId('image')
#1 /path/to/magento/includes/src/Mage_Catalog_Model_Category_Attribute_Backend_Image.php(57): Varien_File_Uploader->__construct('image')
#2 [internal function]: Mage_Catalog_Model_Category_Attribute_Backend_Image->afterSave(Object(Mage_Catalog_Model_Category))
#3 /path/to/magento/includes/src/__default.php(39967): call_user_func_array(Array, Array)
#4 /path/to/magento/includes/src/__default.php(40958): Mage_Eav_Model_Entity_Abstract->walkAttributes('backend/afterSa...', Array)
#5 /path/to/magento/includes/src/Mage_Catalog_Model_Resource_Category.php(235): Mage_Eav_Model_Entity_Abstract->_afterSave(Object(Mage_Catalog_Model_Category))
#6 /path/to/magento/includes/src/__default.php(40434): Mage_Catalog_Model_Resource_Category->_afterSave(Object(Mage_Catalog_Model_Category))
#7 /path/to/magento/includes/src/__default.php(5593): Mage_Eav_Model_Entity_Abstract->save(Object(Mage_Catalog_Model_Category))
#8 /path/to/magento/includes/src/Mage_Catalog_Model_Category_Api.php(528): Mage_Core_Model_Abstract->save()
#9 [internal function]: Mage_Catalog_Model_Category_Api->removeProduct(23, '2743')
#10 /path/to/magento/includes/src/Mage_Api_Model_Server_Handler_Abstract.php(292): call_user_func_array(Array, Array)
#11 [internal function]: Mage_Api_Model_Server_Handler_Abstract->call('[removed]', 'category.remove...', Array)
#12 /path/to/magento/includes/src/Zend_Server_Abstract.php(232): call_user_func_array(Array, Array)
#13 /path/to/magento/includes/src/Zend_XmlRpc_Server.php(599): Zend_Server_Abstract->_dispatch(Object(Zend_Server_Method_Definition), Array)
#14 /path/to/magento/includes/src/Zend_XmlRpc_Server.php(337): Zend_XmlRpc_Server->_handle(Object(Zend_XmlRpc_Request_Http))
#15 /path/to/magento/includes/src/Mage_Api_Model_Server_Adapter_Xmlrpc.php(105): Zend_XmlRpc_Server->handle()
#16 /path/to/magento/includes/src/Mage_Api_Model_Server.php(84): Mage_Api_Model_Server_Adapter_Xmlrpc->run()
#17 /path/to/magento/app/code/core/Mage/Api/controllers/XmlrpcController.php(39): Mage_Api_Model_Server->run()
#18 /path/to/magento/includes/src/__default.php(13333): Mage_Api_XmlrpcController->indexAction()
#19 /path/to/magento/includes/src/__default.php(17589): Mage_Core_Controller_Varien_Action->dispatch('index')
#20 /path/to/magento/includes/src/__default.php(17180): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#21 /path/to/magento/includes/src/__default.php(19672): Mage_Core_Controller_Varien_Front->dispatch()
#22 /path/to/magento/app/Mage.php(640): Mage_Core_Model_App->run(Array)
#23 /path/to/magento/index.php(80): Mage::run('brillen', 'website')
#24 {main}

Категория успешно обновлена, но я все еще удивляюсь, почему это происходит.


4


источник


Ответы:


Обходной путь:

Добавьте этот переписать в пользовательский модуль (то есть каталог) в config.xml

    <models>
        <catalogextended>
            <class>Myname_Catalogextended_Model</class>
        </catalogextended>
        <catalog>
            <rewrite>
                <category_attribute_backend_image>Myname_Catalogextended_Model_Category_Attribute_Backend_Image</category_attribute_backend_image>
            </rewrite>
        </catalog>
    </models>

И добавьте этот файл:

app/code/local/Myname/Catalogextended/Model/Category/Attribute/Backend/Image.php

Содержит:

/**
 * Save uploaded file and set its name to category
 *
 * @param Varien_Object $object
 */
public function afterSave($object)
{
    $value = $object->getData($this->getAttribute()->getName());

    if (is_array($value) && !empty($value['delete'])) {
        $object->setData($this->getAttribute()->getName(), '');
        $this->getAttribute()->getEntity()
            ->saveAttribute($object, $this->getAttribute()->getName());
        return;
    }

    /* Workaround to avoid exception '$_FILES array is empty' when assiging
     * products to a category or creating a category with the API.
     * Inspired by http://www.magentocommerce.com/bug-tracking/issue/?issue=11597
     */
    if (!isset($_FILES) || count($_FILES) == 0)
    {
        return;
    }

    $path = Mage::getBaseDir('media') . DS . 'catalog' . DS . 'category' . DS;

    try {
        $uploader = new Mage_Core_Model_File_Uploader($this->getAttribute()->getName());
        $uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
        $uploader->setAllowRenameFiles(true);
        $result = $uploader->save($path);

        $object->setData($this->getAttribute()->getName(), $result['file']);
        $this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
    } catch (Exception $e) {
        if ($e->getCode() != Mage_Core_Model_File_Uploader::TMP_NAME_EMPTY) {
            Mage::logException($e);
        }
        /** @TODO ??? */
        return;
    }
  }
}


3



«Официальное» исправление включено в Magento 2:

class Mage_Catalog_Model_Category_Attribute_Backend_Image extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{

    /**
    * Save uploaded file and set its name to category
    *
    * @param Varien_Object $object
    * @return Mage_Catalog_Model_Category_Attribute_Backend_Image
    */
    public function afterSave($object)
    {
        $value = $object->getData($this->getAttribute()->getName());

        // if no image was set - nothing to do
        if (empty($value) && empty($_FILES)) {
            return $this;
        }

        if (is_array($value) && !empty($value['delete'])) {
            $object->setData($this->getAttribute()->getName(), '');
            $this->getAttribute()->getEntity()
                ->saveAttribute($object, $this->getAttribute()->getName());
            return $this;
        }

        $path = Mage::getBaseDir('media') . DS . 'catalog' . DS . 'category' . DS;

        try {
            $uploader = new Mage_Core_Model_File_Uploader($this->getAttribute()->getName());
            $uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
            $uploader->setAllowRenameFiles(true);
            $result = $uploader->save($path);

            $object->setData($this->getAttribute()->getName(), $result['file']);
            $this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
        } catch (Exception $e) {
            if ($e->getCode() != Mage_Core_Model_File_Uploader::TMP_NAME_EMPTY) {
                Mage::logException($e);
            }
            /** @TODO ??? */
        }
        return $this;
    }
}

https://github.com/magento/magento2/blob/0c3e67e9c25cbddcb6c957b00164552b9110cf3b/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php


6



Другой вариант, вдохновленный Mondane Ответ:

  • копировать /app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php в /app/code/local/Mage/Catalog/Model/Category/Attribute/Backend/Image.php
  • (если у вас нет пути CREATE IT)

после этого отредактируйте созданный файл

замените функцию afterSave на этот код

public function afterSave($object)
{
    $value = $object->getData($this->getAttribute()->getName());

    if (is_array($value) && !empty($value['delete'])) {
        $object->setData($this->getAttribute()->getName(), '');
        $this->getAttribute()->getEntity()
            ->saveAttribute($object, $this->getAttribute()->getName());
        return;
    }

    /* Workaround to avoid exception '$_FILES array is empty' when assiging
     * products to a category or creating a category with the API.
     * Inspired by http://www.magentocommerce.com/bug-tracking/issue/?issue=11597
     */
    if (!isset($_FILES) || count($_FILES) == 0)
    {
        return;
    }

    $path = Mage::getBaseDir('media') . DS . 'catalog' . DS . 'category' . DS;

    try {
        $uploader = new Mage_Core_Model_File_Uploader($this->getAttribute()->getName());
        $uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
        $uploader->setAllowRenameFiles(true);
        $result = $uploader->save($path);

        $object->setData($this->getAttribute()->getName(), $result['file']);
        $this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
    } catch (Exception $e) {
        if ($e->getCode() != Mage_Core_Model_File_Uploader::TMP_NAME_EMPTY) {
            Mage::logException($e);
        }
        /** @TODO ??? */
        return;
    }
  }
}

сделав это, вы замените пурпурный код, не вовлекаясь в основные файлы, beacause magento автоматически возьмет этот файл, прежде чем взять исходный файл


3