Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 48
ProductRepository
0.00% covered (danger)
0.00%
0 / 1
14.29% covered (danger)
14.29%
1 / 7
240
0.00% covered (danger)
0.00%
0 / 48
 filter
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 5
 search
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 9
 baseQuery
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 11
 withTaxonomy
0.00% covered (danger)
0.00%
0 / 1
30
0.00% covered (danger)
0.00%
0 / 2
 anonymous function
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
0 / 0
 sortBy
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 10
 paginate
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
<?php
namespace Mtc\Shop\Repositories;
use Illuminate\Http\Request;
use Mtc\Core\Admin\Node;
use Mtc\Core\Taxonomy;
use Mtc\Shop\Contracts\ProductRepositoryContract;
use Mtc\Shop\Product;
class ProductRepository implements ProductRepositoryContract
{
    protected $query = null;
    public function filter(Request $request)
    {
        return $this->search($request->input('query'))
            ->baseQuery()
            ->withTaxonomy($request->input('selected'))
            ->sortBy($request->input('sort_by'))
            ->paginate();
    }
    protected function search($query)
    {
        if (empty($query)) {
            $this->query = Node::query();
        } else {
            $this->query = Node::whereIn(
                'nodes.id',
                Node::search($query)
                    ->where('nodeable_type', Product::class)
                    ->get()
                    ->pluck('id')
            );
        }
        return $this;
    }
    protected function baseQuery()
    {
        $this->query->select(
                [
                    'nodes.id',
                    'nodes.title',
                    'nodes.description',
                    'nodes.slug',
                    'nodes.nodeable_id',
                    'nodes.nodeable_type',
                    'po.sort_price as price',
                    'nodes.url',
                ]
            )->join(
                'products as po',
                'nodes.nodeable_id',
                '=',
                'po.id'
            )->with(['nodeable', 'nodeable.media'])
            ->where('nodeable_type', Product::class)
            ->public();
        return $this;
    }
    protected function withTaxonomy($selected)
    {
        $selected = collect($selected)->pluck('id');
        $selected = Taxonomy::whereIn('id', $selected)->get();
        $selected = $selected->reject(function($item) use ($selected) {
            foreach ($selected as $option) {
                if ($item->isAncestorOf($option)) {
                    return true;
                }
            }
            return false;
        })->map(function($item) {
            // Return a list of these taxonomy ids and their children
            return \DB::table('taxonomies')
                ->where('id', '=', $item->id)
                ->orWhere(function($query) use ($item) {
                    $query->where('id', '>=', $item->lft)
                        ->where('id', '<=', $item->rgt);
                })
                ->pluck('id');
        })->collapse()
        ->toArray();
        if (is_array($selected) && !empty($selected)) {
            $this->query->join(
                'node_taxonomy as nt',
                'nt.node_id',
                '=',
                'nodes.id'
            )->whereIn('nt.taxonomy_id', $selected);
        }
        return $this;
    }
    protected function sortBy($method)
    {
        switch($method) {
            default:
            case 'new-additions':
                $this->query->orderBy('nodes.created_at', 'desc');
                break;
            case 'price-asc':
                $this->query->orderBy('po.sort_price', 'asc');
                break;
            case 'price-desc':
                $this->query->orderBy('po.sort_price', 'desc');
                break;
        }
        return $this;
    }
    protected function paginate()
    {
        return $this->query->paginate();
    }
}