Tôi có thể thử sử dụng addExpressionFieldToSelect
.
Bạn có thể tìm thấy phương pháp trong Mage_Core_Model_Resource_Db_Collection_Abstract
.
Trong trường hợp của bạn, nó phải là một cái gì đó như thế này: (Đây chỉ là một giả định, bạn có thể gặp một số lỗi, nhưng ý tưởng là ok)
$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
$collection->addExpressionFieldToSelect('distance', '( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( {{latitude}}) ) * cos( radians( {{longitude}}) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( {{latitude}}) ) ) )', array('latitude'=>'latitude', 'longitude'=>'longitude'));
$collection->getSelect()->having('distance > 10');
Các addExpressionFieldToSelect
công việc như thế này:
tham số đầu tiên là bí danh của biểu thức (tên trường ảo).
Tham số thứ hai là biểu thức. Thay thế tên trường bằng giữ chỗ arround {{...}}
Tham số thứ ba là sự tương ứng giữ chỗ (không có {{}}
). Trong trường hợp của bạn latitide
giữ chỗ tương ứng với latitude
trường vì vậy {{latitude}}
sẽ được thay thế bằng latitude
. Cùng đi cho longitude
.
[EDIT]
Có một vấn đề khi thêm phân trang vào $collection
như thế này
$collection->setCurPage(1)->setPageSize(5);
Đây là nền tảng của vấn đề. Khi bộ sưu tập được tải, nó được gọi _renderLimit()
. Phương pháp này trông như thế này
protected function _renderLimit()
{
if($this->_pageSize){
$this->_select->limitPage($this->getCurPage(), $this->_pageSize);
}
return $this;
}
Vì vậy, cuộc gọi này getCurPage()
(xem Varien_Data_Collection
lớp).
getCurPage
có một xác minh bổ sung để xem nếu số trang không nằm ngoài phạm vi tối đa để nó tính tổng số trang trong đó getLastPageNumber()
.
Vấn đề ở đây là Magento đặt lại các cột trong phần chọn để tính kích thước bộ sưu tập. Trong Varien_Data_Collection_Db::getSelectCountSql
đó có cái này:
$countSelect->reset(Zend_Db_Select::COLUMNS);
Bằng cách đặt lại các cột, bạn kết thúc với sql này
SELECT COUNT(*) FROM `table_name_here` AS `main_table` HAVING (distance < 10)
Đây là những gì tạo ra lỗi.
Tôi thấy 2 lựa chọn ở đây.
Bạn ghi đè trong lớp bộ sưu tập của mình phương thức getSelectCountSql
và xóa thiết lập lại cột:
public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
//$countSelect->reset(Zend_Db_Select::COLUMNS);//comment this line
$countSelect->columns('COUNT(*)');
return $countSelect;
}
Bạn ghi đè getCurPage()
phương thức để bỏ qua xác thực phạm vi:
public function getCurPage($displacement = 0){
if (!empty($this->_curPage)){
return $this->_curPage + $displacement;
}
return 1;
}
[CHỈNH SỬA EDIT]
Để tránh ảnh hưởng đến các mô-đun còn lại, bạn có thể ghi đè getCurPage
phương thức như sau:
public function getCurPage($displacement = 0){
if (!$this->getDirectCurPage()){//if a specific flag is not set behave as default
return parent::getCurPage($displacement);
}
if (!empty($this->_curPage)){
return $this->_curPage + $displacement;
}
return 1;
}
Bây giờ khi bạn muốn sử dụng having
phương thức của mình, chỉ cần thêm nó vào bộ sưu tập của bạn
$collection->setDirectCurPage(1);