1

我用函数 getRooms() 创建了块。它应该返回房间集合。但是由于搜索的条件很多,我需要对其他表进行joinLeft查询。

public function getRooms(){

    $rooms = array();

    $productId = $this->getRequest()->getParam('product'); 

    $from = $this->getRequest()->getParam('from');
    $to = $this->getRequest()->getParam('to');

    $fromStamp = strtotime( $from );
    $toStamp = strtotime( $to );

    $rooms = Mage::getModel('reservation/roomtypes')->getCollection();

    $newInventoryTable = $rooms->getTable('reservation/newinventory');

    $datefilters =  array('filter1'=>$fromStamp, 'filter2'=>$toStamp );
    $dateconditions = array( 'filter1' => $cond1, 'filter2' => array('from'=>'ni.date_from','to'=>'ni.date_to') );

    $datecond = "({$fromStamp} >= ni.date_from and {$fromStamp} <= ni.date_to) or ({$toStamp} >= ni.date_from and {$toStamp} <= ni.date_to) OR ni.date_from is NULL";
    $rooms = $rooms
                    ->addFieldToSelect('id')
                    ->addFieldToSelect('room_type')
                    ->addFieldToSelect('room_price_per_night')
                    ->addFieldToSelect('second_night_price')
                    ->addFieldToSelect('room_quantity')
                    ->addFieldToFilter("main_table.entity_id", $productId )
                    ->getSelect()
                    ->where( $datecond )
                    ->joinLeft( array("ni"=>$newInventoryTable), "main_table.id = ni.room_type_id", "SUM(ni.rooms_count)  AS rooms_reserved" )
                    ->group("main_table.id")
                    ->having("((`room_quantity`-`rooms_reserved`) > 0) OR (`rooms_reserved` is NULL) ");



$rooms = $rooms->query();
$rooms = $rooms->FetchAll();
    return $rooms;
}

我已经正确创建了 sql-query,但 FetchAll() 给了我 Array()。因为我已经使用了低级 Zend db API。我想要获取 Varien Collection 并使用它的神奇 getField() 功能。

换句话说,我想留在 Magento 级别。那么如何使用 Magento 方法重写 leftJoin、group、运算符?

4

2 回答 2

2

尝试查看此文档: http: //www.magentocommerce.com/wiki/1_-_installation_and_configuration/using_collections_in_magento

我认为你不应该使用addFieldToSelect()但是addFieldToFilter()

这是一个加入的例子

$collection = Mage::getModel('module/model_name')->getCollection();
$collection->getSelect()->join( array('table_alias'=>$this->getTable('module/table_name')), 'main_table.foreign_id = table_alias.primary_key', array('table_alias.*'), 'schema_name_if_different');
于 2012-10-17T16:39:14.587 回答
1

落入那个简单的把戏非常简单。您已经正确地完成了所有操作,除了......当您完成此操作时,您已将Zend_Db_Select实例分配给您的变量:$room

$rooms = $rooms
                ....
                ->getSelect()
                ....

相反,您应该做的是将过滤器分配给$select,但使用其$collection本身进行操作。顺便说一句,您不需要将您的收藏重新分配给自己以应用过滤器。这是你应该如何做的:

$rooms = Mage::getModel('reservation/roomtypes')->getCollection();

$newInventoryTable = $rooms->getTable('reservation/newinventory');

$datefilters =  array('filter1'=>$fromStamp, 'filter2'=>$toStamp );
$dateconditions = array( 'filter1' => $cond1, 'filter2' => array('from'=>'ni.date_from','to'=>'ni.date_to') );

$datecond = "({$fromStamp} >= ni.date_from and {$fromStamp} <= ni.date_to) or ({$toStamp} >= ni.date_from and {$toStamp} <= ni.date_to) OR ni.date_from is NULL";
$rooms->addFieldToSelect('id')
                ->addFieldToSelect('room_type')
                ->addFieldToSelect('room_price_per_night')
                ->addFieldToSelect('second_night_price')
                ->addFieldToSelect('room_quantity')
                ->addFieldToFilter("main_table.entity_id", $productId );
$rooms->getSelect()
                ->where( $datecond )
                ->joinLeft( array("ni"=>$newInventoryTable), "main_table.id = ni.room_type_id", "SUM(ni.rooms_count)  AS rooms_reserved" )
                ->group("main_table.id")
                ->having("((`room_quantity`-`rooms_reserved`) > 0) OR (`rooms_reserved` is NULL) ");
return $rooms;

现在说几句为什么你在退货之前不需要load收集。Magento在操作集合时具有延迟加载原则。它包含有关选择和内部过滤器的所有信息,但直到需要输出数据的地方(例如foreach循环)才将查询提取到数据库。然后load触发方法并_items用对象填充受保护的属性。通过这种方式,您仍然可以添加或删除过滤器并修改Block对象甚至.phtml模板中的选择对象 - 当然不鼓励这样做,但有时是最快和最简单的方法。

So you don't need to query or fetch or load collection to insert it into foreach loop and get the desired array-like behavior (thanks to Iterator interface).

于 2012-10-17T22:12:02.817 回答