Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/job-board.corals.io/Corals/modules/Marketplace/Classes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/job-board.corals.io/Corals/modules/Marketplace/Classes/Shop.php
<?php

namespace Corals\Modules\Marketplace\Classes;


use Corals\Foundation\Search\Search;
use Corals\Modules\Marketplace\Models\Attribute;
use Corals\Modules\Marketplace\Models\Brand;
use Corals\Modules\Marketplace\Models\Category;
use Corals\Modules\Marketplace\Models\OrderItem;
use Corals\Modules\Marketplace\Models\Product;
use Corals\Modules\Marketplace\Models\SKU;
use Corals\Modules\Marketplace\Models\Tag;
use Corals\Modules\Utility\Models\Rating\Rating;
use Corals\Settings\Facades\Settings;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Cookie;

class Shop
{
    public $page_limit;

    public function __construct()
    {
        $this->page_limit = Settings::get('marketplace_appearance_page_limit', 15);
    }

    public function getFeaturedProducts()
    {
        $products = Product::active()->featured()->get();

        return $products;
    }

    protected function productsPublicBaseQuery($store = null)
    {
        $query = Product::active()
            ->join('marketplace_sku', 'marketplace_sku.product_id', '=', 'marketplace_products.id')
            ->join('marketplace_stores', 'marketplace_products.store_id', '=', 'marketplace_stores.id')
            ->groupBy('marketplace_sku.product_id', 'marketplace_products.id');

        if ($store) {
            $query->where('marketplace_products.store_id', $store->id);
        }
        return $query;
    }

    /**
     * @param Request $request
     * @return mixed
     */
    public function getProducts(Request $request, $store = null)
    {
        if ($request->input('store')) {
            $store = \Corals\Modules\Marketplace\Models\Store::query()->active()->where('slug',
                $request->input('store'))->first();
        }

        $products = $this->productsPublicBaseQuery($store);

        foreach ($request->all() as $filter => $value) {
            $filterMethod = $filter . 'QueryBuilderFilter';
            if (method_exists($this, $filterMethod) && !empty($value)) {
                $products = $this->{$filterMethod}($products, $value);
            }
        }


        $products = $products->addSelect('marketplace_products.*')->paginate($this->page_limit);

        return $products;
    }

    /**
     * @param Request|null $request
     * @return mixed
     */
    public function getAllActiveProducts(Request $request = null)
    {
        $products = $this->productsPublicBaseQuery();

        return $products->get();
    }

    protected function sortQueryBuilderFilter($products, $sortOption)
    {
        switch ($sortOption) {
            case 'popular':
                break;
            case 'low_high_price':
                $products = $products->addSelect(\DB::raw('min(marketplace_sku.regular_price) as sku_price'))->orderBy('sku_price',
                    'asc');
                break;
            case 'high_low_price':
                $products = $products->addSelect(\DB::raw('max(marketplace_sku.regular_price) as sku_price'))->orderBy('sku_price',
                    'desc');
                break;
            case 'average_rating':
                $stores = $products->leftJoin('utility_avg_ratings', function ($join) {
                    $join->on('avgreviewable_ID', '=', 'marketplace_products.id')
                        ->where('utility_avg_ratings.avgreviewable_type', getMorphAlias(Product::class));
                })->orWhereNull('utility_avg_ratings.id')
                    ->orderBy('avg', 'desc');
                break;
            case 'a_z_order':
                $products = $products->orderBy('marketplace_products.name', 'asc');
                break;
            case 'z_a_order':
                $products = $products->orderBy('marketplace_products.name', 'desc');
                break;
            case 'recently_added':
                $products = $products->orderBy('marketplace_products.created_at', 'desc');
                break;
            case 'top_seller':
                $products = $products->orderBy('marketplace_products.total_sales', 'desc');
                break;
        }
        return $products;
    }

    protected function searchQueryBuilderFilter($products, $search_term)
    {
        $search = new Search();

        $config = [
            'title_weight' => \Settings::get('marketplace_search_title_weight'),
            'content_weight' => \Settings::get('marketplace_search_content_weight'),
            'enable_wildcards' => \Settings::get('marketplace_search_enable_wildcards')
        ];

        $products = $search->AddSearchPart($products, $search_term, Product::class, $config);

        return $products;
    }

    protected function featuredQueryBuilderFilter($products, $featured)
    {
        if ($featured) {
            $products = $products->featured();
        }

        return $products;
    }

    private function attributesColumnMapping()
    {
        $attributes = Attribute::query()->whereHas('categories')->get();


        $attributesColumnMapping = [];

        foreach ($attributes as $attribute) {
            switch ($attribute->type) {
                case 'checkbox':
                case 'text':
                case 'date':
                    $attributesColumnMapping[$attribute->id]['column'] = 'string_value';
                    $attributesColumnMapping[$attribute->id]['operation'] = 'like';
                    break;
                case 'textarea':
                    $attributesColumnMapping[$attribute->id]['column'] = 'text_value';
                    $attributesColumnMapping[$attribute->id]['operation'] = 'like';
                    break;
                case 'number':
                case 'select':
                case 'multi_values':
                case 'radio':
                    $attributesColumnMapping[$attribute->id]['column'] = 'number_value';
                    $attributesColumnMapping[$attribute->id]['operation'] = '=';
                    break;
                default:
                    $attributesColumnMapping[$attribute->id]['column'] = 'string_value';
                    $attributesColumnMapping[$attribute->id]['operation'] = '=';
            }
        }

        return $attributesColumnMapping;
    }

    protected function optionsQueryBuilderFilter($products, $attributes)
    {
        $attributesColumnMapping = $this->attributesColumnMapping();

        $attributes = array_filter($attributes, function ($value) {
            return !empty($value);
        });

        if (empty($attributes)) {
            return $products;
        }


        foreach ($attributes as $key => $value) {
            $products = $products->join("marketplace_sku_options as attribute_$key", "attribute_$key.sku_id", '=',
                'marketplace_sku.id');

            $value = isset($attributesColumnMapping[$key]['operation']) && $attributesColumnMapping[$key]['operation'] == 'like' ? '%' . $value . '%' : $value;
            if (is_array($value)) {
                $products = $products->where("attribute_$key." . $attributesColumnMapping[$key]['column'] ?? 'string_value',
                    $value);
            } else {
                $products = $products->where("attribute_$key." . $attributesColumnMapping[$key]['column'] ?? 'string_value',
                    $attributesColumnMapping[$key]['operation'] ?? '=', $value);
            }
        }

        return $products;
    }

    protected function priceQueryBuilderFilter($products, $price)
    {
        if (!is_array($price)) {
            return $products;
        }

        $minPrice = \Arr::get($price, 'min', 0);
        $maxPrice = \Arr::get($price, 'max', 999999);

        if ($this->getSKUMinPrice() != $minPrice || $this->getSKUMaxPrice() != $maxPrice) {
            $products = $products->whereBetween('marketplace_sku.regular_price', [$minPrice, $maxPrice]);
        }

        return $products;
    }

    protected function categoryQueryBuilderFilter($products, $category, $status = 'active')
    {
        /**
         * check if category is array or a single value
         */
        $queryMethod = 'where';

        if (is_array($category)) {
            $queryMethod = 'whereIn';
        }

        $orQueryMethod = 'or' . ucfirst($queryMethod);

        /**
         * get the related categories
         */
        $categories = Category::{$queryMethod}('marketplace_categories.id', $category)
            ->orWhere(function ($parent) use ($queryMethod, $category) {
                $parent->{$queryMethod}('marketplace_categories.parent_id', $category)
                    ->where('marketplace_categories.parent_id', '<>', 0);
            })->{$orQueryMethod}('marketplace_categories.slug', $category)->pluck('id')->toArray();

        /**
         * add categories query to products query
         */
        $products = $products->join('marketplace_category_product', 'marketplace_category_product.product_id',
            'marketplace_products.id')
            ->join('marketplace_categories', 'marketplace_category_product.category_id', 'marketplace_categories.id')
            ->where(function ($query) use ($categories) {
                $query->whereIn('marketplace_categories.id', $categories);
            });

        if (!empty($status)) {
            $products->where('marketplace_categories.status', $status);
        }

        return $products;
    }

    protected function brandQueryBuilderFilter($products, $brand)
    {
        $products = $products
            ->join('marketplace_brands', 'marketplace_brands.id', '=', 'marketplace_products.brand_id')
            ->where(function ($query) use ($brand) {
                $queryMethod = 'where';

                if (is_array($brand)) {
                    $queryMethod = 'whereIn';
                }

                $orQueryMethod = 'or' . ucfirst($queryMethod);

                $query->{$queryMethod}('marketplace_brands.id', $brand)
                    ->{$orQueryMethod}('marketplace_brands.slug', $brand);
            });

        return $products;
    }

    /**
     * @param $category_id
     * @param bool $count
     * @return mixed
     */
    public function getCategoryAvailableProducts($category_id, $count = false, $exclude = [], $limit = null)
    {
        if ($store = \Store::getStore()) {
            $products = $store->products();
        } else {
            $products = Product::query();
        }

        $products->active();

        if ($exclude) {
            $products->whereNotIn('marketplace_products.id', $exclude);
        }

        $products = $this->categoryQueryBuilderFilter($products, $category_id);

        if ($count) {
            $products = $products->count();
        } else {
            $limit = $limit ?? $this->page_limit;
            $products = $products->select('marketplace_products.*')->paginate($limit);
        }

        return $products;
    }

    public function getBrandAvailableProducts($brand, $count = false)
    {
        $products = Product::query()->active();

        $products = $this->brandQueryBuilderFilter($products, $brand);

        if ($count) {
            $products = $products->count();
        } else {
            $products = $products->select('marketplace_products.*')->paginate($this->page_limit);
        }

        return $products;
    }

    protected function tagQueryBuilderFilter($products, $tag, $status = 'active')
    {
        $products = $products->join('marketplace_product_tag', 'marketplace_product_tag.product_id',
            'marketplace_products.id')
            ->join('marketplace_tags', 'marketplace_product_tag.tag_id', 'marketplace_tags.id')
            ->where(function ($query) use ($tag) {
                $queryMethod = 'where';

                if (is_array($tag)) {
                    $queryMethod = 'whereIn';
                }

                $orQueryMethod = 'or' . ucfirst($queryMethod);

                $query->{$queryMethod}('marketplace_tags.id', $tag)
                    ->{$orQueryMethod}('marketplace_tags.slug', $tag);
            });

        if (!empty($status)) {
            $products->where('marketplace_tags.status', $status);
        }

        return $products;
    }

    /**
     * @param $tag_id
     * @return mixed
     */
    public function getTagAvailableProducts($tag_id)
    {
        $products = Product::query()->active();

        $products = $this->tagQueryBuilderFilter($products, $tag_id);

        $products = $products->select('marketplace_products.*')
            ->paginate($this->page_limit);

        return $products;
    }

    /**
     * @param bool $root
     * @return mixed
     */
    public function getActiveCategories($root = true)
    {
        if ($store = \Store::getStore()) {
            $categories = $store->productCategories();
        } else {
            $categories = Category::active();
        }

        if ($root) {
            $categories = $categories->where(function ($q) {
                $q->whereNull('parent_id')->orWhere('parent_id', 0);
            });
        }

        $categories = $categories->get()->unique();

//        $categories = $categories->map(function ($category, $key) {
//            $category['products_count'] = $this->getCategoryAvailableProducts($category->id, true);
//            return $category;
//        });

        return $categories;
    }

    /**
     * @return mixed
     */
    public function getActiveBrands($categories)
    {
        $store = \Store::getStore();

        if (!$categories & !$store) {
            return new Collection();
        }


        $brands = Brand::query()->active();

        if ($categories) {
            if ($categories != "all") {
                if (!is_array($categories)) {
                    $categories = [$categories];
                }
                $brands = $brands->whereHas('categories', function ($query) use ($categories) {
                    $query->where('marketplace_categories.slug', $categories);
                });
            }
        }


        $brands = $brands
            ->leftJoin('marketplace_products', 'marketplace_products.brand_id', '=', 'marketplace_brands.id')
            ->select(\DB::raw('count(marketplace_products.id) as products_count'), 'marketplace_brands.*')
            ->groupBy('marketplace_products.brand_id', 'marketplace_brands.id');

        if ($store) {
            $brands->where('marketplace_products.store_id', $store->id);
        }

        $brands = $brands->get();

        return $brands;
    }

    public function getFeaturedBrands()
    {
        $featuredBrands = Brand::active()->featured()->get();

        return $featuredBrands;
    }

    public function getFeaturedCategories()
    {
        $featuredCategories = Category::active()->featured()->get();

        $featuredCategories = $featuredCategories->map(function ($category, $key) {
            $category['starting_from_price'] = SKU::join('marketplace_products', 'marketplace_products.id', '=',
                'marketplace_sku.product_id')
                ->join('marketplace_category_product', 'marketplace_category_product.product_id',
                    'marketplace_products.id')
                ->join('marketplace_categories', 'marketplace_category_product.category_id',
                    'marketplace_categories.id')
                ->where('marketplace_categories.id', $category->id)
                ->orWhere('marketplace_categories.parent_id', $category->id)->min('regular_price');

            return $category;
        });

        return $featuredCategories;
    }

    public function getSKUMinPrice()
    {
        if ($store = \Store::getStore()) {
            return (int)$store->skus()->min('regular_price');
        } else {
            return (int)SKU::min('regular_price');
        }
    }

    public function getSKUMaxPrice()
    {
        if ($store = \Store::getStore()) {
            return (int)$store->skus()->max('regular_price');
        } else {
            return (int)SKU::max('regular_price');
        }
    }

    public function checkActiveKey($value, $compareWithKey)
    {
        if (request()->has($compareWithKey)) {
            $compareWithValue = request()->get($compareWithKey);

            if (is_array($compareWithValue)) {
                return array_search($value, $compareWithValue) !== false;
            } else {
                return $value == $compareWithValue;
            }
        }

        return false;
    }

    /**
     * @return string
     */
    public function getAttributesForFilters($categories)
    {
        if (!$categories) {
            $categories = [];
        }

        if (!is_array($categories)) {
            $categories = [$categories];
        }

        $attributes = Attribute::query()->whereHas('categories', function ($query) use ($categories) {
            $query->whereIn('slug', $categories);
        })->get();

        $filters = '';

        foreach ($attributes as $attribute) {
            $filters .= \Category::renderAttribute($attribute, null, ['as_filter' => true]);
        }

        return $filters;
    }

    /**
     * @param int $take
     * @return array
     */
    public function getTopSellers($take = 3)
    {
        // Top Sellers
        $orderItems = OrderItem::select('sku_code', \DB::raw('count(*) as sku_count'))
            ->where('type', 'Product')
            ->groupBy('sku_code')
            ->orderBy('sku_count', 'desc')
            ->take($take)
            ->get();

        $products = collect([]);

        foreach ($orderItems as $orderItem) {
            if ($orderItem->sku && $product = optional($orderItem->sku)->product()->active()->first()) {
                $products->push($product);
            }
        }
        if ($products->count() == 0) {
            $products = Product::query()->active()->orderByRaw('RAND()')->take($take)->get();
        }
        return $products;
    }

    /**
     * @param int $take
     * @return mixed
     */
    public function getNewArrivals($take = 3)
    {
        $products = $this->productsPublicBaseQuery();

        return $products->select('marketplace_products.*')->orderBy('marketplace_products.created_at',
            'desc')->take($take)->get();
    }

    /**
     * @param int $take
     * @return mixed
     */
    public function getBestRated($take = 3)
    {
        $products = $this->productsPublicBaseQuery();

        $products = $products->addSelect('marketplace_products.*');

        $products = $products->leftJoin('utility_ratings', 'reviewrateable_id', '=', 'marketplace_products.id')
            ->where('utility_ratings.reviewrateable_type', Product::class)
            ->orderBy('averageReviewRateable', 'desc')
            ->addSelect(\DB::raw('ROUND(AVG(rating), 2) as averageReviewRateable'))
            ->take($take)->get();
        if ($products->count() == 0) {
            $products = Product::query()->active()->orderByRaw('RAND()')->take($take)->get();
        }
        return $products;
    }


    public function appendCategories(&$result, $categories, $parentId)
    {
        if ($parentId == -1) {
            $parentCategories = $categories;
        } else {
            $parentCategories = $categories->where('parent_id', $parentId);
        }

        foreach ($parentCategories as $category) {
            $this->appendSingle($result, $category);

            $this->appendCategories($result[$category->id]['children'], $categories, $category->id);
        }
    }

    public function appendSingle(&$result, $category)
    {
        $result[$category->id] = [
            'id' => $category->id,
            'name' => $category->name,
            'slug' => $category->slug,
            'products_count' => 0,
            'children' => []
        ];
    }

    public function getCategoriesHierarchy()
    {
        if ($store = \Store::getStore()) {
            $categories = $store->productCategories();
        } else {
            $categories = Category::active();
        }

        $categories = $categories->get()->unique();

        $parentId = null;

        if (($categories->where('parent_id', null))->isEmpty()) {
            $parentId = -1;
        }

        $cacheKey = 'shop_categories';

        if ($store) {
            $cacheKey .= '_store_' . $store->id;
        }

        if (Cache::has($cacheKey)) {
            $result = Cache::get($cacheKey);
        } else {
            $result = [];

            $this->appendCategories($result, $categories, $parentId);

            Cache::put($cacheKey, $result, 1440);
        }

        return $result;
    }

    public function getRandomTags($limit = 10)
    {
        $tags = Tag::query()
            ->active()
            ->inRandomOrder()
            ->whereHas('products')
            ->take($limit)
            ->get();

        return $tags;
    }

    public function getRandomProductsOfCategories(array $categories, $exclude = [])
    {
        if (empty($categories)) {
            return collect([]);
        }

        $products = $this->getCategoryAvailableProducts($categories, $count = false, $exclude, $limit = 12);

        return $products;
    }

    public function getLatestReviews()
    {
        return Rating::query()
            ->where('reviewrateable_type', getMorphAlias(Product::class))
            ->approved()
            ->latest()
            ->take(10)
            ->with('reviewrateable')
            ->get();
    }

    public function trackUserAction($model, $action)
    {
        switch (class_basename($model)) {
            case 'Product':
                switch ($action) {
                    case 'view_product':
                        $name = $this->getProductCookieName($action);

                        $currentProductsList = json_decode(Cookie::get($name), true) ?? [];

                        $currentProductsList[] = $model->id;

                        Cookie::queue($name, json_encode(array_unique($currentProductsList)), 86400);

                        $name = $this->getProductCategoriesCookieName($action);

                        $currentCategoriesList = json_decode(Cookie::get($name), true) ?? [];

                        $currentCategoriesList = array_merge($currentCategoriesList,
                            $model->activeCategories->pluck('id')->toArray());

                        Cookie::queue($name, json_encode(array_unique($currentCategoriesList)), 86400);
                        break;
                }
                break;
        }
    }

    protected function getProductCookieName($prefix = '')
    {
        return sprintf('%s_products_%s', $prefix, user() ? user()->id : 'guest');
    }

    protected function getProductCategoriesCookieName($prefix = '')
    {
        return sprintf('%s_categories_%s', $prefix, user() ? user()->id : 'guest');
    }

    public function getRecentlyViewedProducts($limit = 10)
    {
        $name = $this->getProductCookieName('view_product');

        $productsList = json_decode(Cookie::get($name), true) ?? [];

        if (empty($productsList)) {
            return collect([]);
        }

        return Product::query()->whereIn('id', $productsList)
            ->inRandomOrder()
            ->take($limit)
            ->active()
            ->get();
    }

    public function getProductsBasedOnViewedCategories($limit = 10)
    {
        $name = $this->getProductCategoriesCookieName('view_product');

        $categoriesList = json_decode(Cookie::get($name), true) ?? [];

        if (empty($categoriesList)) {
            return collect([]);
        }

        $products = Product::query()
            ->active()
            ->limit($limit)
            ->inRandomOrder();

        return $this->categoryQueryBuilderFilter($products, $categoriesList)
            ->select('marketplace_products.*')
            ->get();
    }
}

Spamworldpro Mini