Magento - cms / page collection - 应用过滤器仅返回给定商店ID唯一的页面(即不分配给其他商店)

时间:2012-05-13 11:59:55

标签: magento magento-1.5

我可以使用:

Mage::getModel('cms/page')->getCollection()->addStoreFilter($store_id);

检索按商店标识过滤的CMS网页集合。

但是如何删除那些也分配给其他商店的呢?

ie:我不希望它返回将“所有商店视图”作为商店视图的商品。 (或分配给该CMS页面的任何其他商店ID。)它必须仅返回该商店唯一的页面。

我正在扩展Aitoc权限模块,以便Store Admins无法查看或编辑可能影响其他商店的CMS页面和静态块。这涉及从网格中过滤这些项目。

4 个答案:

答案 0 :(得分:4)

没有本地收集方法可以执行此操作,因此您需要

  1. cms_page_store表中查询给定商店特有的页面

  2. 在过滤器中使用上面的结果

  3. 我没有对以下内容进行全面测试,但是应该工作(如果没有,那么它将为您提供一个良好的开端)

    $page     = Mage::getModel('cms/page');
    $resource = $page->getResource();
    $read     = $resource->getReadConnection();
    
    #$select   = $read->query('SELECT page_id FROM ' . $resource->getTable('cms/page_store') . ' GROUP BY store_id');
    
    //set total count to look for.  1 means the page only appears once.
    $total_stores_count_to_look_for = '1';
    
    //get the table name.  Need to pass through getTable to ensure any prefix used is added
    $table_name                     = $resource->getTable('cms/page_store');
    
    //aggregate count select from the cmd_page_store database
    //greater than 0 ensures the "all stores" pages aren't selected
    $select = $read->query('SELECT page_id as total
    FROM '.$table_name.' 
    WHERE store_id > 0 
    GROUP BY page_id
    HAVING count(page_id) = ?',array($total_stores_count_to_look_for));
    
    //fetch all the rows, which will be page ids
    $ids   = $select->fetchAll(); 
    
    //query for pages using IDs from above
    $pages = Mage::getModel('cms/page')->getCollection()->addFieldToFilter('page_id',array('in'=>$ids));
    
    foreach($pages as $page)
    {
        var_dump($page->getData());
    }
    

    如果您有成千上万的CMS页面,则可能需要更改cms/page集合的select以加入聚合表数据。我将把它作为练习留给读者,因为那种连接可能会变得棘手。

答案 1 :(得分:4)

$collection = Mage::getModel('cms/page')->getCollection();
$collection->getSelect()
    ->join(
        array('cps' => $collection->getTable('cms/page_store')),
        'cps.page_id = main_table.page_id AND cps.store_id != 0',
        array('store_id')
    )
    ->columns(array('stores_count' => new Zend_Db_Expr('COUNT(cps.store_id)')))
    ->group('main_table.page_id')
    ->having('stores_count = ?', 1)
    ->having('cps.store_id = ?', $storeId)
;

答案 2 :(得分:1)

融合Alan和Vitaly提出的解决方案的一些元素和我自己繁琐的理解,我通过以下代码实现了我所需要的。

为了进入上下文,我正在扩展Aitoc权限模块,以便Store Admins无法查看或编辑可能影响其他商店的CMS页面和静态块。这涉及从网格中过滤这些项目。

$collection = Mage::getModel('cms/page')->getCollection();
$collection->addStoreFilter(Mage::helper('aitpermissions')->getStoreIds());
$conn = Mage::getSingleton('core/resource')->getConnection('core_read');
$page_ids = array();
foreach($collection as $key=>$item) {
    $page_id = $item->getId();
    $results = $conn->fetchAll("SELECT * FROM cms_page_store 
                                WHERE page_id = ".$page_id.";");
    $count = 0;
    $arr_stores = array();
    foreach($results as $row) {
        $arr_stores[] = $row['store_id'];
        $count++;
    }

    //We dont want to show the item if any of the following are true:
       //The store id = 0 (Means its assigned to All Stores)
       //There is more than one store assigned to this CMS page         
    if( in_array('0',$arr_stores) || $count>1) {
            //This removes results from the grid (but oddly not the paging)
        $collection->removeItemByKey($key); 
    }
    else {
        //build an array which we will use to remove results from the paging
        $page_ids[] = $page_id; 
    }
}

//This removes results from paging (but not the grid)
$collection->addFieldToFilter('page_id',array('in'=>$page_ids)); 

我不确定为什么我需要使用两种不同的方法来过滤分页和网格。  该网站使用magento 1.5,因此可能存在与此相关的问题。

无论哪种方式,这个解决方案对我有用。

答案 3 :(得分:0)

我的解决方案是通过join将字段store_id添加到页面集合中,并使用集合方法addFieldToFilter()。

$pages = Mage::getModel('cms/page')->getCollection();

$pages->getSelect()->joinInner(
     array('cms_page_store' => 'cms_page_store'),
     'main_table.page_id = cms_page_store.page_id',
     array()
);

$pages->addFieldToFilter('store_id', ['in' => [1, 2]]);