Question

J'ai créé une collection de magento comme celui-ci à la distance de latitude calculate longtemps.

$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
            $collection->getSelect()->columns(array('distance' => new Zend_Db_Expr("( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( latitude ) ) * cos( radians( longitude) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( latitude ) ) ) )")))
            ->having('distance <10')
            ->order('distance ' . Varien_Db_Select::SQL_ASC);

Mais j'obtiens l'erreur SQLSTATE [42S22]: La colonne est introuvable. 1054 Unknown column 'distance' dans 'clause having'

Quand imprimer objet de collection calcul La distance est droit. alors quel était le problème?

Mon problème est similaire, comme cette question problème en utilisant « avoir » dans la collecte Magento

J'utilise sur la collecte de pagination, si je retire classe alors il fonctionne en page parfaite. Mais je suis incapable de résoudre avec une solution fournie. Voici mon code de pagination.

En fonction _prepareLayout() je mets cette

$pager = $this->getLayout()->createBlock('page/html_pager', 'pager');
          $pager->setAvailableLimit(array(5=>5,10=>10,20=>20,'all'=>'all'));
          $pager->setCollection($this->getCollection());
          $this->setChild('pager', $pager);
          $this->getCollection()->load();
          return $this;

ajouter cette fonction également dans le fichier bloc

  public function getPagerHtml()
  {
    return $this->getChildHtml('pager');
  }

et appeler ce fichier dans phtml comme <?php echo $this->getPagerHtml(); ?>

Était-ce utile?

La solution

Je peux essayer d'utiliser addExpressionFieldToSelect.
Vous pouvez trouver la méthode Mage_Core_Model_Resource_Db_Collection_Abstract.
Dans votre cas, il devrait être quelque chose comme ceci: (Ceci est juste une hypothèse, vous pourriez obtenir quelques erreurs, mais l'idée est 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');

Le addExpressionFieldToSelect fonctionne comme ceci:
le premier paramètre est l'alias de l'expression (nom du champ virtuel).
Le second paramètre est l'expression. Remplacer les noms des champs avec des espaces réservés enveloppées arround {{...}}
Le troisième paramètre est la correspondance de l'espace réservé (sans {{}}). Dans votre cas espace réservé latitide correspond au champ de latitude si {{latitude}} sera remplacé par latitude. Même chose pour longitude.

[EDIT] Il y a un problème lors de l'ajout à la pagination $collection comme ceci

$collection->setCurPage(1)->setPageSize(5);  

Voici la trace de la question. Lorsque la collection est chargé ce qu'on appelle _renderLimit(). La méthode ressemble à ceci

protected function _renderLimit()
{
    if($this->_pageSize){
        $this->_select->limitPage($this->getCurPage(), $this->_pageSize);
    }

    return $this;
}

Donc, ce appels getCurPage() (voir classe Varien_Data_Collection).
getCurPage a une vérification supplémentaire pour voir si le numéro de page ne sont pas en dehors de la plage max il calcule le nombre total de pages dans getLastPageNumber().
Le problème ici est que Magento remet à zéro les colonnes de la sélection pour le calcul de la taille de la collection. En Varien_Data_Collection_Db::getSelectCountSql il y a ceci:

$countSelect->reset(Zend_Db_Select::COLUMNS);

Par reseting les colonnes vous vous retrouvez avec cette sql

SELECT COUNT(*) FROM `table_name_here` AS `main_table` HAVING (distance < 10)

est ce qui génère l'erreur.

Je vois 2 options ici.

  1. Vous override dans votre classe de collection la méthode getSelectCountSql et retirer la remise à zéro de la colonne:

    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;
    }
    
  2. Vous substituez la méthode de getCurPage() sauter la validation de la plage:

    public function getCurPage($displacement = 0){
        if (!empty($this->_curPage)){
            return $this->_curPage + $displacement;
        }
        return 1;
    }
    

[EDIT TO EDIT] Pour éviter d'affecter le reste des modules que vous pouvez remplacer la méthode getCurPage comme ceci:

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;
}

Maintenant, quand vous voulez utiliser votre méthode having simplement ajouter à votre collection

$collection->setDirectCurPage(1);

Autres conseils

Essayez d'utiliser ceci:

$collection = Mage::getModel('module/module')->getCollection()->addFieldToFilter('status',1);
            $collection->getSelect()->columns(array('distance' => new Zend_Db_Expr("( 6371 * acos( cos( radians(23.0130648) ) * cos( radians( latitude ) ) * cos( radians( longitude) - radians(72.4909026) ) + sin( radians(23.0130648) ) * sin( radians( latitude ) ) ) )")))
            ->addAttributeHaving('distance <10')
            ->addAttributeToSort('distance', Varien_Db_Select::SQL_ASC);

Vous pouvez essayer where() au lieu de having() que vous n'utilisez des déclarations de JOIN:

$collection->getSelect()->where('distance > ?', 10);
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top