Magento - Collection OR AND filter - magento

I want to select products collection with condition "A or (B and C)" by using AddAttributeToFilter, but I have no idea..
Can someone help me?

$collection = Mage::getModel('xyz/abc')->getCollection();
$collection->addAttributeToFilter(
array(
array('attribute'=> 'someattribute','like' => 'value'),
array('attribute'=> 'otherattribute','like' => 'value'),
array('attribute'=> 'anotherattribute','like' => 'value'),
)
);
$collection->addAttributeToFilter('status', array('eq' => 1));
Transnational will be look like
WHERE ((someattribute LIKE 'value') OR (otherattribute LIKE 'value') OR (anotherattribute LIKE 'value')) and status=1
You can also visit this link for more info
Magento addFieldToFilter: Two fields, match as OR, not AND

Related

How to filter Magento collection for a date or null

I have some Magento code that I'm trying to use to filter a collection of products. I want to find all products where the date is BEFORE a certain date OR the date hasn't been set (ie is null).
I have:
function getProduct($product_id) {
global $proxy, $sessionId, $conn, $start_date, $time_to_run;
if ($product_id == 'all') {
$result=Mage::getModel("catalog/product")
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('price_adjust_active', array('null' => true))
->addAttributeToFilter('price_adjust_active', '1')
->addAttributeToFilter(array(
array('attribute'=> 'price_adjust_last_run','lt' => date('Y-m-d H:i:s', $time_to_run)),
array('attribute'=> 'price_adjust_last_run', 'null' => true)
))
->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
->setOrder('entity_id', 'DESC')
->setPageSize(1);
} else {
$result=Mage::getModel("catalog/product")
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('entity_id', array('eq' => $product_id))
->addAttributeToFilter('price_adjust_active', array('null' => true))
->addAttributeToFilter('price_adjust_active', '1')
->addAttributeToFilter(array(
array('attribute'=> 'price_adjust_last_run','lt' => date('Y-m-d H:i:s', $time_to_run)),
array('attribute'=> 'price_adjust_last_run', 'null' => true)
))
->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
->setOrder('entity_id', 'DESC')
->setPageSize(1);
}
and I can successfully filter out the products with the dates set before my specified date. I just can't get the "null" attribute to work. As you can see from my code, I have 2 different filters in there, and neither of them seem to give me the desired results.
The two faulty attempts are:
->addAttributeToFilter('price_adjust_active', array('null' => true))
or
array('attribute'=> 'price_adjust_last_run', 'null' => true)
Magento has a special way to filter dates instead of just using a straight greater or less than.
Try this...
->addAttributeToFilter('price_adjust_last_run', array('or'=> array(
0 => array(
'date' => true,
'from' => date('Y-m-d H:i:s', $time_to_run - 1)
),
1 => array('is' => new Zend_Db_Expr('null')))
), 'left')
You are setting date to true and then you'll probably want to make sure to subtract 1 second from your $time_to_run variable.
This works similarly with addFieldToFilter() as well.

Magento OR query

I would like to use OR in magento mysql query, I am looking for an equivalent in magento
where (is_in_stock=0 and show_in_front=1) and (is_in_stock=1 and show_in_front=1)
I know following can be used for 'OR', but am not sure how to produce an equiavlent query as above;
->addAttributeToFilter(
array(
'attribute' => 'is_in_stock',
'eq' => '0',
),
Following is example code for OR condition
$collection->addAttributeToFilter(
array(
array('attribute'=> 'attribute1','like' => 'value1'),
array('attribute'=> 'attribute2','like' => 'value2'),
array('attribute'=> 'attribute3','like' => 'value3'),
)
);
Please check this query
//OR Condition
->addAttributeToFilter(array(array('attribute' => 'is_in_stock','eq' => '0'),array('attribute' => 'show_in_front','eq' => '1')));
//And Condition
->addAttributeToFilter('is_in_stock', array('eq' => '1'));
->addAttributeToFilter('show_in_front', array('eq' => '1'));

Magento - how to get more values from addAttributeToFilter?

Hello I hope someone can help me figure out what to do!
I need to get several results from magento. The following code works:
private $_orderstatusToFilter = array("processing", "done");
->addAttributeToFilter('status',array('eq' => $this->_orderstatusToFilter[0]))
this line above shows all the values from one var which is:_orderstatusToFilter = processing. Now I would like to also get all the values where 'status' = (_orderstatusToFilter =) done.
->addAttributeToFilter('status',array('eq' => $this->_orderstatusToFilter[0], 'eq' => $this->_orderstatusToFilter[1]))
There are no results if I run the code.
What to do?
You can try to take out condition like in sample below
$statusCondition = array(
array(
'eq' => $this->_orderstatusToFilter[0]
),
array(
'eq' => $this->_orderstatusToFilter[1]
)
);
->addAttributeToFilter('status', $statusCondition);
Or use IN condition instead
->addAttributeToFilter('id', array('in' => $_orderstatusToFilter));

Error trying to group in Magento join

I'm facing the error in title with Magento. I'm trying to group the records in the grid by county, which is one of the fields obtained in the join, not the main table. When I run the SQL query generated against DB it runs as expected but when trying to access the grid in Magento, I get that error. This is my join:
$collection = Mage::getModel('sales/order_address')->getCollection();
$collection
->addAttributeToSelect('region')
->addAttributeToSelect('city')
->addAttributeToFilter('address_type', 'shipping')
->addAttributeToFilter('region', 'California')
->addAttributeToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter(array('status', 'status'),
array(
array('eq' => 'complete'),
array('eq' => 'processing')
));
$collection->getSelect()->joinLeft(
array('order' => 'sales_flat_order'),
'order.entity_id = main_table.parent_id',
array('status' => 'order.status',
'created_at' => 'order.created_at',
'grand_total' => 'SUM(order.grand_total)'))
->joinLeft(
array('order_tax' => 'sales_order_tax'),
'order_tax.order_id = main_table.parent_id',
array('county' => 'order_tax.title',
'tax_amount' => 'SUM(order_tax.amount)',
'tax_rate' => 'order_tax.percent'))
->group('county')
->group('city')
->distinct(true);
And this is the generated SQL:
SELECT DISTINCT `main_table`.`region`, `main_table`.`city`, `order`.`status`, `order`.`created_at`, SUM(order.grand_total) AS `grand_total`, `order_tax`.`title` AS `county`, SUM(order_tax.amount) AS `tax_amount`, `order_tax`.`percent` AS `tax_rate` FROM `sales_flat_order_address` AS `main_table` LEFT JOIN `mvmt_sales_flat_order` AS `order` ON order.entity_id = main_table.parent_id LEFT JOIN `mvmt_sales_order_tax` AS `order_tax` ON order_tax.order_id = main_table.parent_id WHERE (address_type = 'shipping') AND (region = 'California') AND (created_at >= '2013-08-01 00:00:00' AND created_at <= '2013-12-31 00:00:00') AND ((status = 'complete') OR (status = 'processing')) GROUP BY `county`, `city`
Does someone knows what is happening here and why SQL is accepting the query but not Magento?
Thanks for the help in advance.
$collection = Mage::getModel('sales/order_address')->getCollection();
$collection
->addAttributeToSelect('region')
->addAttributeToSelect('country_id')
->addAttributeToSelect('city')
->addAttributeToFilter('address_type', 'shipping')
->addAttributeToFilter('region', 'California')
->addAttributeToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter(array('status', 'status'),
array(
array('eq' => 'Pending'),
array('eq' => 'processing')
));
$collection->getSelect()->joinLeft(
array('order' => 'sales_flat_order'),
'order.entity_id = main_table.parent_id',
array('order.status','order.created_at','SUM(order.grand_total)'));
$collection->getSelect()
->joinLeft(
array('order_tax' => 'sales_order_tax'),
'order_tax.order_id = main_table.parent_id',
array('order_tax.title','SUM(order_tax.amount)','order_tax.percent'))
->group('country_id')
->group('city')
->distinct(true);
Hope this will work for you. :)
Best of luck.

Magento: Get products without images using collections

I would like to filter a product collection by image not null. The easiest way should be the methods mentioned here, but this doesn't work: the returned collection has no elements.
I think that the problem here is that products that never had an image have no relationship between product/media_gallery tables. As a consequence, when Magento tries to filter using all these conditions, the returned collection is empty. It doesn't take into account that it might not be any type of relationship between the involved tables.
$collection->addAttributeToFilter(array(
array (
'attribute' => 'image',
'like' => 'no_selection'
),
array (
'attribute' => 'image', // null fields
'null' => true
),
array (
'attribute' => 'image', // empty, but not null
'eq' => ''
),
array (
'attribute' => 'image', // check for information that doesn't conform to Magento's formatting
'nlike' => '%/%/%'
),
));
I guess I should use a joinLeft condition, but I have not idea how it should be. Could please anyone help me on this?
I found a very interesting query that should do the trick. But I need to apply this to my collection:
SELECT *
FROM `catalog_product_entity` AS a
LEFT JOIN `catalog_product_entity_media_gallery` AS b ON a.entity_id = b.entity_id
WHERE b.value IS NULL
Thanks
To apply the query to your products collection, you can use
$collection->getSelect()
->joinLeft(
array('_gallery_table' => $collection->getTable('catalog/product_attribute_media_gallery')),
'e.entity_id = _gallery_table.entity_id',
array()
)
->where('_gallery_table.value IS NULL');
Same answer but for magento 2:
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
........
/**
* #var CollectionFactory
*/
public $productCollectionFactory;
........
$collection = $this->productCollectionFactory->create();
$collection->addAttributeToSelect('*');
$collection->getSelect()
->joinLeft(
['gallery_table' => $collection->getTable('catalog_product_entity_media_gallery_value_to_entity')],
'e.entity_id = gallery_table.entity_id',
[]
)
->where('gallery_table.value_id IS NULL');

Resources