使用XMLRPC修改类别时,Varien_File_Uploader中引发异常

时间:2012-03-14 10:59:07

标签: php magento

我正在使用Magento(1.6.2.0)XMLRPC-API来分配/删除某个类别的产品。我最近查看了异常日志,发现有很多异常。每当我更新类别时,都会发生以下错误:

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}

该类别已成功更新,但我仍然想知道为什么会这样。

3 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:3)

解决方法:

将此重写添加到config.xml

中的自定义模块(即catalogextended)
    <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;
    }
  }
}

答案 2 :(得分:3)

Mondane答案启发的其他选项是:

  • copy /app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php to /app/code/local/Mage/Catalog/Model/Category/Attribute/Backend/Image.php < / LI>
  • (如果您没有路径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;
    }
  }
}

通过这样做,您将替换magento代码而不涉及核心文件,因为magento将在获取原始文件之前自动获取此文件