Ich kann versuchen zu verwenden addExpressionFieldToSelect
.
Sie finden die Methode in Mage_Core_Model_Resource_Db_Collection_Abstract
.
In Ihrem Fall sollte es ungefähr so aussehen: (Dies ist nur eine Annahme, Sie könnten einige Fehler bekommen, aber die Idee ist in Ordnung)
$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');
Das addExpressionFieldToSelect
funktioniert so:
Der erste Parameter ist der Alias des Ausdrucks (Name des virtuellen Feldes).
Der zweite Parameter ist der Ausdruck. Ersetzen Sie die Feldnamen durch umlaufende Platzhalter. {{...}}
Der dritte Parameter ist die Platzhalterkorrespondenz (ohne {{}}
). In Ihrem Fall latitide
entspricht der Platzhalter dem latitude
Feld und {{latitude}}
wird durch ersetzt latitude
. Gleiches gilt für longitude
.
[EDIT]
Es gibt ein Problem beim Hinzufügen von Paginierung der $collection
wie folgt
$collection->setCurPage(1)->setPageSize(5);
Hier ist die Rückverfolgung des Problems. Wenn die Sammlung geladen wird, wird dies aufgerufen _renderLimit()
. Die Methode sieht so aus
protected function _renderLimit()
{
if($this->_pageSize){
$this->_select->limitPage($this->getCurPage(), $this->_pageSize);
}
return $this;
}
Das ruft also getCurPage()
(siehe Varien_Data_Collection
Klasse).
getCurPage
hat eine zusätzliche Überprüfung, um festzustellen, ob die Seitenzahl nicht außerhalb des maximalen Bereichs liegt, sodass die Gesamtzahl der Seiten in berechnet wird getLastPageNumber()
.
Das Problem hierbei ist, dass Magento die Spalten in der Auswahl zur Berechnung der Sammlungsgröße zurücksetzt. Darin Varien_Data_Collection_Db::getSelectCountSql
ist folgendes:
$countSelect->reset(Zend_Db_Select::COLUMNS);
Durch Zurücksetzen der Spalten erhalten Sie diese SQL
SELECT COUNT(*) FROM `table_name_here` AS `main_table` HAVING (distance < 10)
Dies erzeugt den Fehler.
Ich sehe hier 2 Optionen.
Sie überschreiben in Ihrer Auflistungsklasse die Methode getSelectCountSql
und entfernen das Zurücksetzen der Spalte:
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;
}
Sie überschreiben die getCurPage()
Methode zum Überspringen der Bereichsüberprüfung:
public function getCurPage($displacement = 0){
if (!empty($this->_curPage)){
return $this->_curPage + $displacement;
}
return 1;
}
[EDIT TO EDIT]
Um die übrigen Module nicht zu beeinträchtigen, können Sie die getCurPage
Methode folgendermaßen überschreiben :
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;
}
Wenn Sie nun Ihre having
Methode verwenden möchten, fügen Sie diese einfach Ihrer Sammlung hinzu
$collection->setDirectCurPage(1);