2

I am trying to add some custom filters to the Dataflow export in Magento. First up, is exporting products with no images.

I created app/code/local/Mage/Mycompany/Model/Catalog/Convert/Adapter/Product.php

class Mage_Mycompany_Model_Catalog_Convert_Adapter_Product
    extends Mage_Catalog_Model_Convert_Adapter_Product
{
    /**
     * Load product collection Id(s)
     */
    public function load()
    {
        parent::load();

        $filters = $this->_parseVars();

        if (isset($filters['hasImage'])) {
            $hasImage = (bool)$filters['hasImage'];

            try {
                /*
                 * Try to filter by the image field.
                 * See one of the three options below...
                 */
            } catch (Exception $e) {
                $message = Mage::helper('eav')->__('There was a problem filtering by `hasImage`. Error: %s', $e->getMessage());
                $this->addException($message, Varien_Convert_Exception::FATAL);
            }
        }

        return $this;
    }
}

In my profile XML, I changed <action type="catalog/convert_adapter_product" method="load"> to <action type="mycompany/catalog_convert_adapter_product" method="load"> and added <var name="filter/hasImage"><![CDATA[1]]></var>

Failed filter #1

$filterArray = array();
$filterArray['alias']       = 'hasImage';
$filterArray['attribute']   = 'catalog_product/entity_varchar';
$filterArray['field']       = 'value';
$filterArray['bind']        = 'product_id=entity_id';
$filterArray['joinType']    = 'inner';

if ($hasImage) {
    $filterArray['cond'] = "{{table}}.attribute_id = 106 AND {{table}}.value != 'no_selection' AND {{table}}.value IS NOT NULL";
} else {
    $filterArray['cond'] = "{{table}}.attribute_id = 106 AND ({{table}}.value = 'no_selection' OR {{table}}.value IS NULL)";
}

$this->setJoinField($filterArray);

Failed filter #2

if ($hasImage) {
    $this->_filter[] = array(
        'attribute' => 'hasImage',
        'notnull'   => 1,
        'neq'       => 'no_selection'
    );
} else {
    $this->_filter[] = array(
        'attribute' => 'hasImage',
        'null'      => 1
    );
    $this->_filter[] = array(
        'attribute' => 'hasImage',
        'eq'        => 'no_selection'
    );
}

$this->setJoinAttr(array(
    'alias'     => 'hasImage',
    'attribute' => 'catalog_product/entity_varchar',
    'bind'      => 'entity_id',
    //'cond'      => array('notnull'=>'','neq'=>'no_selection'),
    'cond'      => "{{table}}.attribute_id = 106",
    'joinType'  => 'inner'
));

Failed filter #3

if (!($entityType = $this->getVar('entity_type'))
|| !(Mage::getResourceSingleton($entityType) instanceof Mage_Eav_Model_Entity_Interface)) {
    $this->addException(Mage::helper('eav')->__('Invalid entity specified'), Varien_Convert_Exception::FATAL);
}

$collection = $this->_getCollectionForLoad($entityType);

$parentEntityIds = $collection->getAllIds();

if ($hasImage) {
    $hasImageFilter = array('notnull'=>'', 'neq'=>'no_selection');
    $collection
        ->addAttributeToFilter('image', $hasImageFilter)
        ->addAttributeToFilter('small_image', $hasImageFilter)
        ->addAttributeToFilter('thumbnail', $hasImageFilter);
} else {
    $collection
        ->addAttributeToFilter(array(
            array('attribute' => 'image', 'null' => 1),
            array('attribute' => 'image', 'eq' => 'no_selection')
        ))
        ->addAttributeToFilter(array(
            array('attribute' => 'small_image', 'null' => 1),
            array('attribute' => 'small_image', 'eq' => 'no_selection')
        ))
        ->addAttributeToFilter(array(
            array('attribute' => 'thumbnail', 'null' => 1),
            array('attribute' => 'thumbnail', 'eq' => 'no_selection')
        ));
}

/**
 * Load collection ids
 */
$thisEntityIds = $collection->getAllIds();

$entityIds = array_intersect($parentEntityIds, $thisEntityIds);

$this->setData($entityIds);

I know that this code is being hit. I can die('here'); and that works. But it's not having the desired filtering affect at all.

I can't find a single tutorial on creating custom filters for Dataflow, so any help is appreciated.

1 Answer 1

2

This is how I eventually solved my problem:

class Mage_Mymodule_Model_Catalog_Convert_Adapter_Product
    extends Mage_Catalog_Model_Convert_Adapter_Product
{
    /**
     * Load product collection Id(s)
     */
    public function load()
    {
        parent::load();

        $filters = $this->_parseVars();

        if (isset($filters['hasImage'])) {
            $hasImage = (bool)$filters['hasImage'];

            try {
                if (!($entityType = $this->getVar('entity_type'))
                || !(Mage::getResourceSingleton($entityType) instanceof Mage_Eav_Model_Entity_Interface)) {
                    $this->addException(Mage::helper('eav')->__('Invalid entity specified'), Varien_Convert_Exception::FATAL);
                }

                $collection = $this->_getCollectionForLoad($entityType);

                if ($hasImage) {
                    $collection
                        ->addAttributeToFilter('image', array('notnull'=>'', 'neq'=>'no_selection'))
                        ->addAttributeToFilter('small_image', array('notnull'=>'', 'neq'=>'no_selection'))
                        ->addAttributeToFilter('thumbnail', array('notnull'=>'', 'neq'=>'no_selection'));
                } else {
                    $collection
                        ->addAttributeToFilter('image', array('no_selection', 'null'))
                        ->addAttributeToFilter('small_image', array('no_selection', 'null'))
                        ->addAttributeToFilter('thumbnail', array('no_selection', 'null'));
                }

                /**
                 * $collection is not a reference, so we need to pass the product IDs
                 * to $this->setData() so that our attribute filters are applied.
                 */
                $entityIds = $collection->getAllIds();
                $this->setData($entityIds);
            } catch (Exception $e) {
                $message = Mage::helper('eav')->__('There was a problem filtering by `hasImage`. Error: %s', $e->getMessage());
                $this->addException($message, Varien_Convert_Exception::FATAL);
            }
        }

        return $this;
    }
}

I'd love to know how I can use $this->setJoinField or parent::setFilter or $this->setJoinAttr to do the same thing, as the parent class does for qty and price. I'll leave my answer unchecked for a few days to see if someone can help me find a better answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.