1

I have a store collection. And it has the following fields

 [0] => Array
    (
        [location_id] => 5
        [title] => Los Angeles
        [description] => 
        [status] => 1
        [sort_order] => 0
        [country_id] => US
        [region_id] => 1
        [city] => Los Angeles
        [street] => 1605 W. Olympic Blvd. 
        [zip] => 90015
        [phone] => (213)639-2100
        [zoom] => 16
        [latitude] => 34.0497
        [longitude] => -118.275
        [image] => location/d/o/download_1_.jpeg
        [custom_marker] => location/d/o/download_1.png
        [store_location_code] => 1
        [store_manager] => Mike
        [store_email] => la@icuracao.com
        [fax] => (213)639-2196
        [distance] => 37.97125176816877
    )

distance is not a column in db how to sort the store collection in the ascending order of distance app/code/Aheadworks/StoreLocator/Model/Location.php

<?php
/**
  * Copyright 2018 aheadWorks. All rights reserved.
  * See LICENSE.txt for license details.
  */

  namespace Aheadworks\StoreLocator\Model;

 use Aheadworks\StoreLocator\Api\Data\LocationInterface;
  use Aheadworks\StoreLocator\Api\Data\LocationInterfaceFactory;
 use Aheadworks\StoreLocator\Model\ResourceModel\Location as ResourceModelLocation;
 use Magento\Framework\Api\DataObjectHelper;
 use Magento\Framework\Data\Collection\AbstractDb;
 use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\Context;
 use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
 use Magento\Framework\Registry;
  use Magento\Store\Model\StoreManagerInterface;

  /**
 * Class Location.
 */
 class Location extends AbstractModel
 {
/**
 * @var string
 */
protected $_eventPrefix = 'location';

/**
 * @var string
 */
protected $_eventObject = 'location';

/**
 * @var array
 */
protected static $searchFields = ['country_id', 'region_id', 'city', 'zip'];

/**
 * @var StoreManagerInterface
 */
protected $storeManager;

/**
 * @var LocationInterfaceFactory
 */
protected $locationDataFactory;

/**
 * @var DataObjectHelper
 */
protected $dataObjectHelper;

/**
 * @param Context $context
 * @param Registry $registry
 * @param StoreManagerInterface $storeManager
 * @param ResourceModelLocation $resource
 * @param LocationInterfaceFactory $locationDataFactory
 * @param DataObjectHelper $dataObjectHelper
 * @param AbstractDb $resourceCollection
 * @param array $data
 */
public function __construct(
    Context $context,
    Registry $registry,
    StoreManagerInterface $storeManager,
    ResourceModelLocation $resource,
    LocationInterfaceFactory $locationDataFactory,
    DataObjectHelper $dataObjectHelper,
    AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->storeManager = $storeManager;
    $this->locationDataFactory = $locationDataFactory;
    $this->dataObjectHelper = $dataObjectHelper;
    parent::__construct(
        $context,
        $registry,
        $resource,
        $resourceCollection,
        $data
    );
}

/**
 * {@inheritdoc}
 */
public function _construct()
{
    $this->_init(ResourceModelLocation::class);
}

/**
 * @return LocationInterface
 */
public function getDataModel()
{
    $locationData = $this->getData();
    $locationDataObject = $this->locationDataFactory->create();

    $this->dataObjectHelper->populateWithArray(
        $locationDataObject,
        $locationData,
        LocationInterface::class
    );

    return $locationDataObject;
}

/**
 * Retrieve location collection model populated with data.
 *
 * @param array $filters
 * @return AbstractCollection
 */
public function getLocationCollectionBySearch(array $filters = [])
{
    $collection = $this->getCollection();

    if (isset($filters['radius']) && isset($filters['measurement'])) {
        $collection->addRadiusFilter(
            $filters['radius'],
            $filters['measurement'],
            $filters['latitude'],
            $filters['longitude']

        );
    }

    foreach ($filters as $filter => $value) {
        if ($value && in_array($filter, self::$searchFields)) {
            $collection->addFieldToFilter($filter, $value);
        }
    }

    $collection->addStoreFilter($this->storeManager->getStore()->getId());

    $collection->addFieldToFilter('status', 1);
    // if (!empty($filters) && (!empty($filters['street']))) {
    //   $collection->addOrder("distance","ASC");
    // }
    $collection = $collection->load();



    return $collection;
}
}

app/code/Aheadworks/StoreLocator/Controller/Index/Index.php

  namespace Aheadworks\StoreLocator\Controller\Index;

 use Aheadworks\StoreLocator\Helper\Config;
 use Aheadworks\StoreLocator\Model\Location;
 use Magento\Framework\App\Action\Action;
 use Magento\Framework\App\Action\Context;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\View\Result\Page;
 use Magento\Framework\View\Result\PageFactory;

/**
  * Class Index.
  */
class Index extends Action
 {
/**
 * @var PageFactory
 */
protected $resultPageFactory;

/**
 * @var Location
 */
protected $locationModel;

/**
 * @var Config
 */
protected $helperConfig;

/**
 * @param Context $context
 * @param PageFactory $resultPageFactory
 * @param Location $locationModel
 * @param Config $helperConfig
 */
public function __construct(
    Context $context,
    PageFactory $resultPageFactory,
    Location $locationModel,
    Config $helperConfig
) {
    $this->resultPageFactory = $resultPageFactory;
    $this->locationModel = $locationModel;
    $this->helperConfig = $helperConfig;
    parent::__construct($context);
}

/**
 * Default page
 *
 * @return Page
 * @throws LocalizedException
 */
public function execute()
{
    $postData = $this->getRequest()->getPostValue();
    $searchPostData = [];
    if ($postData) {
        $searchPostData = $postData['search'];
    }

    /** @var \Magento\Framework\View\Result\Page $resultPage */
    $resultPage = $this->resultPageFactory->create();
    $resultPage->getLayout()->initMessages();
    $resultPage->getConfig()->getTitle()->set($this->helperConfig->getTitle());

    if (isset($searchPostData)) {
        $resultPage->getLayout()->getBlock('aw_store_locator_search')->setData($searchPostData);
    }

    $collection = $this->locationModel->getLocationCollectionBySearch($searchPostData);
    $collection = $this->sortCollection($collection, function($a, $b) {
      return (int)($a->getDistance() >= $b->getDistance());
    });
    echo "<pre>";
    print_r($collection->getData());die;
    foreach($collection as $store)
    {
      $sorter[]=$store->getDistance();
    }
    // echo "<pre>";
    // print_r($sorter);
    // exit();
    $locationBlock = $resultPage->getLayout()->getBlock('aw_store_locator_location');
    if ($locationBlock) {
        $locationBlock->setCollection($collection);
    }

    $mapBlock = $resultPage->getLayout()->getBlock('aw_store_locator_map');
    // echo "<pre>";
    // print_r(getLayout()->getBlock('aw_store_locator_map'));
    // exit();
    if ($mapBlock) {
                $mapBlock->setCollection($collection);
    }

    return $resultPage;
}



protected function sortCollection($collection, callable $sorter) {
    $collectionReflection = new \ReflectionObject($collection);
    $itemsPropertyReflection = $collectionReflection->getItems();
    $itemsPropertyReflection->setAccessible(true); // Make it accessible

    $collectionItems = $itemsPropertyReflection->getValue($collection);

    usort($collectionItems, $sorter);

    $itemsPropertyReflection->setValue($collection, $collectionItems);

    $itemsPropertyReflection->setAccessible(false); // Return restriction back

    return $collection;
}

}
  • 1
    Is sorting after loading a best practice? – Nismath vi Oct 23 '18 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.