Laravel sortByDesc chain with multiple chain - laravel

I am trying to sort eloquent collection using sortByDesc. It works for first sorting but chaining with more columns doesn't give proper result. Here is the query and code I am trying
$data = Divrank::where('division_id', $id)->with(['team.player1', 'team.player2'])->with('meta')->orderBy('position', 'asc')->get();
foreach($data as $k=>$t){
if ($t->meta) { // it has ranks informations
$t->totalSets = $t->meta->totalSets;
$t->totalGames = $t->meta->totalGames;
$t->points = $t->meta->points;
} else {
$t->totalSets = 0;
$t->totalGames = 0;
$t->points = 0;
}
unset($data[$k]->meta);
}
//return $data;
return $data->sortByDesc('points')->sortByDesc('totalSets')->sortByDesc('totalGames');
If I remove ->sortByDesc('totalSets')->sortByDesc('totalGames') then it shows correct formate.
Any ideas how to achieve this? Thank you.

Ok, got it, I need to do reverse sorting. $data->sortByDesc('totalGames')->sortByDesc('totalSets')->sortByDesc('points'); this works. It will sort first with games, then sets and then points..

Related

Refactoring multiple same queries with different value

Is there a better way to refactor this code? It's basically the same line with different values. I thought of doing a for loop but maybe there's another way.
$date = $request->date;
$underConsideration = Application::whereDate('created_at',$date)->where('status','Under consideration')->count();
$phoneScreened = Application::whereDate('created_at',$date)->where('status','Phone screened')->count();
$interviewed = Application::whereDate('created_at',$date)->where('status','Interviewed')->count();
$offerExtended = Application::whereDate('created_at',$date)->where('status','Offer extended')->count();
You should create a separate method for this.
public function myMethod()
{
$under_consideration = $this->fetchApplicationData($request, 'Under consideration');
$phone_screened = $this->fetchApplicationData($request, 'Phone screened');
$interviewed = $this->fetchApplicationData($request, 'Interviewed');
$offer_extended = $this->fetchApplicationData($request, 'Offer extended');
}
private function fetchApplicationData($request, $status)
{
return Application::
whereDate('created_at', $request->date)
->where('status', $status)
->count();
}
That is a much cleaner code.
However, I advise that you should put the items:
Under consideration, Phone screened, Interviewed, Offer extended
into a separate table on the database and just save the status_id on your main table.
One of the major advantage on this is the speed. For example, your client wants to know all record that has a status of Interviewed for a certain date span. Database searching against integer is a lot faster than string.
You could create a method to handle the select operations. Something like:
public function yourExisitingMethod() {
$date = $request->date;
$underConsideration = getData($date,'Under consideration');
$phoneScreened = getData($date,'Phone screened');
$interviewed = getData($date,'Interviewed');
$offerExtended = getData($date,'Offer extended');
}
public function getData($date, $status) {
$data = Application::whereDate('created_at',$date)->where('status',$status)->count();
return $data;
}
This would at the very least improve the maintainability of your code, and in my opinion improves reusability and readability.

Multiple Eloquent Where statements with multiple parameters

I have a parsing problem where I want to get all of the people with a particular subscription but not people who have another type of subscription. The subscriptions are stored in a comma delineated list in the subscriptions table in the subscriptions column. Here is the code I have so far:
$includeQuery = [];
foreach ($includeSegment as $include) {
$singleQuery = ['subscriptions','like', '%'.$include.'%', 'or'];
array_push($includeQuery, $singleQuery);
}
$excludeQuery = [];
foreach ($excludeSegment as $exclude) {
$singleQuery = ['subscriptions', 'not like', '%'.$exclude.'%', 'or'];
array_push($excludeQuery, $singleQuery);
}
$included = Subscription::where($excludeQuery)->where($includeQuery)->get();
I get results back but some of them have the excluded subscriptions in them.
use whereIn and whereNotIn instead :
Subscription::whereIn($includeSegment)->whereNotIn($excludeSegment)->get();
then you dont need to also iterate segments once they are arrays of strings
The problem with code above was in the boolean parameter I had "or" instead of "and". So only if all of the subscriptions for a particular user were present would the record get thrown out. Here is the updated code:
$includeQuery = [];
foreach ($includeSegment as $include) {
$singleQuery = ['subscriptions','like', '%'.$include.'%', 'or'];
array_push($includeQuery, $singleQuery);
}
$excludeQuery = [];
foreach ($excludeSegment as $exclude) {
$singleQuery = ['subscriptions', 'not like', '%'.$exclude.'%', 'and'];
array_push($excludeQuery, $singleQuery);
}
// $included = Subscription::where($excludeQuery)->where($includeQuery)->get();
$included = DB::table('subscriptions')
->join('app_users', 'app_users.customer_number', '=', 'subscriptions.customer_number')
->join('app_datas', 'app_datas.customer_number', '=', 'subscriptions.customer_number')
->where($includeQuery)
->where($excludeQuery)
->select('app_datas.device_token')
->get();

Laravel 5.1 How to join two collections of objects

All warehouses tables have differemt number of columns. So I can't use union inside a query. But I hate this way to join this collection of objects.
There is a better (clear) way?
Thx :)
public function index()
{
$warehouses1 = Farm_warehouse::all();
$warehouses2 = Butchery_warehouse::all();
$warehouses3 = Grape_warehouse::all();
$warehouses4 = Iron_warehouse::all();
$warehouses5 = Rice_warehouse::all();
$warehouses6 = Silk_warehouse::all();
$warehouses7 = Wood_warehouse::all();
$warehouses2 = $warehouses1->merge($warehouses2);
$warehouses3 = $warehouses2->merge($warehouses3);
$warehouses4 = $warehouses3->merge($warehouses4);
$warehouses5 = $warehouses4->merge($warehouses5);
$warehouses6 = $warehouses5->merge($warehouses6);
$warehouses = $warehouses6->merge($warehouses7);
return view('warehouses.index', compact('warehouses'));
}
This may not be the improvement you are looking for but couldn't you chain it together like this?
public function index()
{
$warehouses = Farm_warehouse::all();
$warehouses->merge(Butchery_warehouse::all());
$warehouses->merge(Grape_warehouse::all());
$warehouses->merge(Iron_warehouse::all());
$warehouses->merge(Rice_warehouse::all());
$warehouses->merge(Silk_warehouse::all());
$warehouses->merge(Wood_warehouse::all());
return view('warehouses.index', compact('warehouses'));
}
I think that's a bit easier to read, but may be you can extract it out to a base Warehouse Model or try digging into the Collection class for something more fruitful. Hope this helps.

Magento Quick Search - showing results from given category first

I'm looking to have the normal quick search, with the addition of one feature: results from a given category come first.
So far I have modified protected function _getProductCollection() in Mage_CatalogSearch_Block_Result and this works, but it ignores the custom search results (e.g. by price or name) which I want to be applied within the two groups of results.
My additional code is:
$initial = $this->_productCollection->getAllIds();
$this->_productCollection->addCategoryFilter(Mage::getModel('catalog/category')->load(3));
$newids = $this->_productCollection->getAllIds();//$this->_productCollection->getAllIds();
$merged_ids = array_merge($newids, $initial);
$merged_ids = array_unique($merged_ids);
$this->_productCollection->addCategoryFilter(Mage::getModel('catalog/category')->load(2));
$this->_productCollection->getSelect()->order("find_in_set(e.entity_id,'".implode(',',$merged_ids)."')");
Where cat 2 is the root category.
So, where is the collection being sorted? If I move this there that should do the trick I believe (?).
It may not work in everyone's situation, but adding the following worked for me:
$this->_productCollection->setOrder($this->getRequest()->getParam('order'), $this->getRequest()->getParam('dir'));
So I ended up with a protected function _getProductCollection() of:
protected function _getProductCollection()
{
if (is_null($this->_productCollection)) {
$this->_productCollection = $this->getListBlock()->getLoadedProductCollection();
}
$this->_productCollection->setOrder($this->getRequest()->getParam('order'), $this->getRequest()->getParam('dir'));
$initial = $this->_productCollection->getAllIds();
$this->_productCollection->addCategoryFilter(Mage::getModel('catalog/category')->load(3));
$newids = $this->_productCollection->getAllIds();//$this->_productCollection->getAllIds();
$merged_ids = array_merge($newids, $initial);
$merged_ids = array_unique($merged_ids);
$this->_productCollection->addCategoryFilter(Mage::getModel('catalog/category')->load(2));
$this->_productCollection->getSelect()->order("find_in_set(e.entity_id,'".implode(',',$merged_ids)."')");
return $this->_productCollection;
}

Magento - get bundled products where a simple product belongs to

I want to show all bundles on a simple product's page and so need to retrieve the information. I searched and tried a lot. This post sounds promising, but is either not working or maybe not for my problem:
Magento - get a list of bundled product ids from a product id
I found a solution for grouped products but this can't be applied here.
$grouped_product_model = Mage::getModel('bundle/product_selection');
$groupedParentId = $grouped_product_model->getParentIdsByChild($product->getId());
I found the table catalog_product_bundle_selection to be the right place to search, but I wonder if there is a clean way and existing function to search this table by product_id than just to hack this.
I didn't find a solution in Mage_Bundle.
What did I miss?
After getting first aid from vrnet I wrote a new block class, so I can update the layout
class Thomaier_Catalog_Block_Product_View_BundledSelect extends Mage_Catalog_Block_Product_View
{
protected $_simpleProducts = array( '3' ); // just an example
public function getBundles() {
$bundleIds = array();
$bundlesCollectionModel = Mage::getResourceModel('bundle/selection_collection');
$bundlesCollection = $bundlesCollectionModel->getSelect()
->where('`selection`.`product_id` in (' . join(',', (array)$this->_simpleProducts) . ')');
foreach ($bundlesCollection as $bundleItem) {
$bundleIds[] = $bundleItem->getParentProductId();
}
...
}
}
I skipped some parts. As I mentioned in the comment, the SQL query works fine when I try it in phpmyadmin, but $bundleItem is not created and ->load() throws an exception.
Thanks for advice.
Below is a method I wrote for a client having the same request with an extra : the ability to shuffle the result.
Hope it helps.
protected $_simpleProducts = array(); // Array with IDs of simple products you want bundles from.
protected $_shuffle = false;
public function getBundles() {
$bundleIds = array();
/*Rather than using a collection model
and make operations with getSelect,
a more elegant way is to extend
Mage_Bundle_Model_Mysql4_Selection_Collection
with a method that would be something like
setProductIdsFilter($productIds)*/
$bundlesCollectionModel = Mage::getResourceModel('bundle/selection_collection');
$bundlesCollection = $bundleCollectionModel->getSelect()
->where('`selection`.`product_id` in (' . join(',', (array)$this->_simpleProducts) . ')');
foreach ($bundlesCollection as $bundleItem) {
$bundleIds[] = $bundleItem->getParentProductId();
}
if (count($bundleIds)) {
$allowBundles = Mage::getResourceModel('catalog/product_collection')
->addIdFilter($bundleIds)
->addFieldToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
if ($this->_shuffle) {
$allowBundles->getSelect()->order('rand()');
}
if ($allowBundles->count()) {
return $allowBundles;
}
}
return;
The following is the best way to work with these. This way you do not rely on a custom query but instead you can use the core methods:
$bundlesCollection = Mage::getResourceModel('bundle/selection')
->getParentIdsByChild($simple_product_ids_array_or_int);
foreach ($bundlesCollection as $bundleProdId) {
//do anything you want with the bundleProdId array elements
}

Resources