Ürün koleksiyonunu düz olmayan bir özelliğe göre filtreleme


14

Aşağıdakileri yapıyorum:

$productCollection = Mage::getModel('catalog/product')
    ->getCollection();

$productCollection
    ->addAttributeToFilter('my_attribute', 1);

my_attribute düz tablolarda değil, ancak düz tablolar etkindir.

Koleksiyonun tamamını almaya devam ediyorum.

Nedeni şu şekildedir \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect:

$columns = $this->getEntity()->getAttributeForSelect($attributeCode);

Hayır $this->getEntity(), Mage_Catalog_Model_Resource_Product_Flatdüz alanları alan bir örnektir - ve hiçbiri bulunmazsa, yalnızca null değerini döndürür.

Toplama filtresine düz olmayan bir özellik eklemenin temiz bir yolu nedir?

Benim durumumda, düz tabloya öznitelik eklemek mantıklı değil.


Merhaba efendim, karışıklığı çözmek için yeterli misiniz? Ne demek non-flat attribute? Teşekkür It zaten kafa karıştırıcı karmakarışık do not make magento .ve
Pratik

Ben düz dizinde olmayan özellikler hakkında konuşuyorum. Bunlar "Ürün Listesinde Kullanılanlar" "Hayır" olarak ayarlanmış olanlardır.
Alex

Yanıtlar:


18

Gerekli masaya kendiniz katılabilirsiniz.

$productCollection = Mage::getModel('catalog/product')
->getCollection();

$table = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getBackend()->getTable();
$attributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getAttributeId();

$productCollection->getSelect()->join(array('attributeTable' => $table), 'e.entity_id = attributeTable.entity_id', array('my_attribute' => 'attributeTable.value'))
                            ->where("attributeTable.attribute_id = ?", $attributeId)
                            ->where("attributeTable.value = ?", 1);

Store_id ile de katılmak isteyebilirsiniz.


Sanırım hala tüm mağazaların ürünlerini alamama problemim olacaktı. (sorumu ilk başta bu problemi görmediğimde). Görünüşe göre yassı endeksleri tamamen devre dışı bırakmak istiyorum.
Alex

Tüm ürünlere ihtiyacınız varsa, düz masalar arkadaşınız olmayacak, evet.
Matthias Zeis

Sanırım sorunuzu değiştirmek veya cevabımı kabul etmek isteyebilirsiniz (ki bu orijinal soru için işe yarar).
Matthias Zeis

awasome .. concept
Amit Bera

15

Kesmek (CE 1.6.2.0+), koşulu bir dizi olarak iletmek ve buna inanıp inanmamanın amaçlandığı gibi çalışmasını sağlamaktır:

$collection->addFieldToFilter(array(array('attribute' => 'my_attribute', 'eq' => 1)));

Neden işe yaradığına dair bir ipucu var mı?
Alex

3
Bu, eav koleksiyonu addFieldToFileriçin bir sarıcı olduğu için çalışır addAttributeToFilterve bu özelliği bir dizi olarak geçirme seçeneği vardır:if (is_array($attribute)) { $sqlArr = array(); foreach ($attribute as $condition) { $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '('.implode(') OR (', $sqlArr).')'; }
Marius

@Marius, bu bir hack olmadığı anlamına mı geliyor? : P Kullanım konusunda iyi hissedebilir miyim?
Erfan

3
@Erfan. bu bir hack değil. bu bir özellik.
Marius

Tatlı. Ürün tablo uygulamasının (eav / flat) bir koleksiyonu filtrelemek kadar basit şeyler için soyutlanmaması hala tuhaf. Bu her zaman kodumda addAttributeToFilter yerine addFieldToFilter kullanmanız gerektiği anlamına mı geliyor, çünkü eav veya flat kullanıp kullanmadığını bilmiyorum? Yine de addAttributeToFilter'ın amacı nedir?
Erfan

6

ColinM cevabı işleri nedeni kodda olduğu app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php'nin addAttributeToFilteryöntemiyle. Bu dizi biçimini kullanırsanız, çağırmaz addAttributeToSelect. Düz modda, addAttributeToSelectöznitelik düz tabloda değilse sessizce başarısız olur.

(aşağıda benim cevabın bir yeniden karma /programming/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - Ben Görgü kurallarının ne olduğundan emin değilim ama bunu yararlı bulacağımı biliyorum)

Ben düz olmayan öznitelikleri seçme ve filtreleme düz mod toplama için "temiz" bir çözüm istedim, hangi:

  • özelliğin admin'de belirli ayarlara sahip olmasını gerektirmez (bir kullanıcı tarafından eklenebilir veya kullanıcı arabiriminde gizli olabilir)
  • hem düz hem de düz olmayan mod için çalışır

İlişkili ürün koleksiyonunu kullandım, ancak bu tüm EAV koleksiyonları için geçerlidir.

Hata kodu:

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToSelect( 'my_custom_attribute' )
    ->addAttributeToFilter( 'my_custom_attribute', 3 )
;

Düz modda, yukarıdaki kod, düz tabloda yer almıyorsa, niteliği sessizce seçemez veya filtreleyemez.

Seçime ekleniyor:

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->joinAttribute( 'my_custom_attribute', 'catalog_product/my_custom_attribute', 'entity_id', null, 'left' )
    ->addAttributeToSelect( 'my_custom_attribute' )
;

joinAttributeYöntem istenen özellik için sorguya katılmak ekler. Özellik zaten düz tablodayken hala çalışır, ancak yalnızca düz tabloyu kullanmaktan biraz daha az verimli olacaktır.

Bu ürünlerde ayarlanmamışsa leftürünleri getirmesini sağlamak için orada bir birleşim kullandım my_custom_attribute. innerYalnızca my_custom_attributeayarlanan satırlarla ilgileniyorsanız bunu değiştirin .

Filtreye ekleme (yukarıdaki ColinM uyarınca):

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToFilter( array( array( 'attribute' => 'my_custom_attribute', 'eq' => 3 ) ) )
;

Yukarıdaki kod, filtreyi seçmenin yanı sıra seçime ekleyecektir.

(CE 1.6.2.0'da test edilmiştir)


4

Gelen Mage_Rssmodül, düz tabloları devre dışı bırakmak için bir hacky-yöntem kullanılır. Düz tabloların yönetici deposunda her zaman kapalı olduğu gerçeğini kullanırlar ve bu nedenle yönetici deposunu taklit ederler.

class Mage_Rss_Helper_Data {

[...]

/**
 * Disable using of flat catalog and/or product model to prevent limiting results to single store. Probably won't
 * work inside a controller.
 *
 * @return null
 */
public function disableFlat()
{
    /* @var $flatHelper Mage_Catalog_Helper_Product_Flat */
    $flatHelper = Mage::helper('catalog/product_flat');
    if ($flatHelper->isEnabled()) {
        /* @var $emulationModel Mage_Core_Model_App_Emulation */
        $emulationModel = Mage::getModel('core/app_emulation');
        // Emulate admin environment to disable using flat model - otherwise we won't get global stats
        // for all stores
        $emulationModel->startEnvironmentEmulation(0, Mage_Core_Model_App_Area::AREA_ADMINHTML);
    }
}

Emülasyonu başlattıktan sonra, emulationModel->stopEnvironmentEmulation()


Bu cevap 3 gün önce neredeydi? ; _;
sg3s

Tam burada? 20.
Alex

1

özniteliği oluşturduğunuzda, söz konusu nitelik Global düzeyde ve filtrelenebilir olmalıdır. Bu şekilde layared navigasyonda kullanılabilir. Ayrıca, özelliğin bir açılır liste veya çoklu seçim olmasını gerektirir. Çekirdek dosyaları bu durumda ihtiyaçlarınıza uyacak şekilde değiştirmemeye şahsen tavsiye ederim.


Öznitelik ön uç filtresinde istemiyorum - sadece iç kullanım için bir koleksiyon filtreleme yapmak istiyorum.
Alex
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.