diff --git a/src/Concerns/Filterable.php b/src/Concerns/Filterable.php index 3edd8814..2dc97bdb 100644 --- a/src/Concerns/Filterable.php +++ b/src/Concerns/Filterable.php @@ -35,7 +35,7 @@ public function scopeFilter(Builder $query, Request $request): Builder { foreach ($request->except('filter') as $name => $value) { if ($this->hasNamedScope($name) && ! is_null($value)) { - $query = $this->callNamedScope($name, [$query, $value]); + $this->callNamedScope($name, [$query, $value]); } } @@ -46,12 +46,12 @@ public function scopeFilter(Builder $query, Request $request): Builder * Exclude the given models from the query. * * @param \Illuminate\Database\Eloquent\Builder $query - * @param int|string|array $value + * @param array $value * @return \Illuminate\Database\Eloquent\Builder */ - public function scopeExclude(Builder $query, $value): Builder + public function scopeExclude(Builder $query, array $value): Builder { - return $query->whereNotIn('id', (array) $value); + return $query->whereNotIn($query->qualifyColumn('id'), $value); } /** @@ -87,7 +87,8 @@ public function scopeState(Builder $query, string $value): Builder public function scopeSort(Builder $query, array $value = []): Builder { return $query->orderBy( - $value['by'] ?? 'created_at', $value['order'] ?? 'desc' + $query->qualifyColumn($value['by'] ?? 'created_at'), + $value['order'] ?? 'desc' ); } } diff --git a/src/Models/Address.php b/src/Models/Address.php index b0c27aac..9a6f6ba2 100644 --- a/src/Models/Address.php +++ b/src/Models/Address.php @@ -160,6 +160,6 @@ public function toBreadcrumb(Request $request): string */ public function scopeSearch(Builder $query, string $value): Builder { - return $query->where('alias', 'like', "{$value}%"); + return $query->where($query->qualifyColumn('alias'), 'like', "{$value}%"); } } diff --git a/src/Models/Cart.php b/src/Models/Cart.php index cc503cd1..db07e056 100644 --- a/src/Models/Cart.php +++ b/src/Models/Cart.php @@ -118,7 +118,7 @@ public function unlock(): void */ public function scopeLocked(Builder $query): Builder { - return $query->where('locked', true); + return $query->where($query->qualifyColumn('locked'), true); } /** @@ -129,7 +129,7 @@ public function scopeLocked(Builder $query): Builder */ public function scopeUnlocked(Builder $query): Builder { - return $query->where('locked', false); + return $query->where($query->qualifyColumn('locked'), false); } /** @@ -140,8 +140,7 @@ public function scopeUnlocked(Builder $query): Builder */ public function scopeExpired(Builder $query): Builder { - return $query->whereNull('user_id')->where( - 'updated_at', '<', Carbon::now()->subDays(3) - ); + return $query->whereNull($query->qualifyColumn('user_id')) + ->where($query->qualifyColumn('updated_at'), '<', Carbon::now()->subDays(3)); } } diff --git a/src/Models/Category.php b/src/Models/Category.php index 20707d62..bf60e855 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -76,6 +76,6 @@ public function toBreadcrumb(Request $request): string */ public function scopeSearch(Builder $query, string $value): Builder { - return $query->where('name', 'like', "{$value}%"); + return $query->where($query->qualifyColumn('name'), 'like', "{$value}%"); } } diff --git a/src/Models/Medium.php b/src/Models/Medium.php index dedb56f5..6a5eeccb 100644 --- a/src/Models/Medium.php +++ b/src/Models/Medium.php @@ -188,7 +188,7 @@ public function url(string $conversion = null): string */ public function scopeSearch(Builder $query, string $value): Builder { - return $query->where('name', 'like', "{$value}%"); + return $query->where($query->qualifyColumn('name'), 'like', "{$value}%"); } /** @@ -202,9 +202,9 @@ public function scopeType(Builder $query, string $value): Builder { switch ($value) { case 'image': - return $query->where('mime_type', 'like', 'image%'); + return $query->where($query->qualifyColumn('mime_type'), 'like', 'image%'); case 'file': - return $query->where('mime_type', 'not like', 'image%'); + return $query->where($query->qualifyColumn('mime_type'), 'not like', 'image%'); default: return $query; } diff --git a/src/Models/Order.php b/src/Models/Order.php index 49b32fe2..45792386 100644 --- a/src/Models/Order.php +++ b/src/Models/Order.php @@ -288,12 +288,12 @@ public function scopeSearch(Builder $query, string $value): Builder * Scope a query to only include orders with the given status. * * @param \Illuminate\Database\Eloquent\Builder $query - * @param array|string $status + * @param string $status * @return \Illuminate\Database\Eloquent\Builder */ - public function scopeStatus(Builder $query, $status): Builder + public function scopeStatus(Builder $query, string $status): Builder { - return $query->whereIn('status', (array) $status); + return $query->where($query->qualifyColumn('status'), $status); } /** diff --git a/src/Models/Product.php b/src/Models/Product.php index 4e0f2c1a..1448b182 100644 --- a/src/Models/Product.php +++ b/src/Models/Product.php @@ -226,8 +226,8 @@ public function resolveChildRouteBinding($childType, $value, $field): ?Model public function scopeSearch(Builder $query, string $value): Builder { return $query->where(static function (Builder $query) use ($value): Builder { - return $query->where('name', 'like', "{$value}%") - ->orWhere('inventory->sku', 'like', "{$value}%"); + return $query->where($query->qualifyColumn('name'), 'like', "{$value}%") + ->orWhere($query->qualifyColumn('inventory->sku'), 'like', "{$value}%"); }); } @@ -244,4 +244,26 @@ public function scopeCategory(Builder $query, int $value): Builder return $query->where($query->getModel()->qualifyColumn('id'), $value); }); } + + /** + * Scope the query only to the models that are out of stock. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeOutOfStock(Builder $query): Builder + { + return $query->where($query->qualifyColumn('inventory->quantity'), '=', 0); + } + + /** + * Scope the query only to the models that are in stock. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeInStock(Builder $query): Builder + { + return $query->where($query->qualifyColumn('inventory->quantity'), '>', 0); + } } diff --git a/src/Models/Transaction.php b/src/Models/Transaction.php index aa83cdbe..85a12bf2 100644 --- a/src/Models/Transaction.php +++ b/src/Models/Transaction.php @@ -162,7 +162,7 @@ public function driver(string $driver): Contract */ public function scopePayment(Builder $query): Builder { - return $query->where('type', 'payment'); + return $query->where($query->qualifyColumn('type'), 'payment'); } /** @@ -173,7 +173,7 @@ public function scopePayment(Builder $query): Builder */ public function scopeRefund(Builder $query): Builder { - return $query->where('type', 'refund'); + return $query->where($query->qualifyColumn('type'), 'refund'); } /** @@ -184,7 +184,7 @@ public function scopeRefund(Builder $query): Builder */ public function scopeCompleted(Builder $query): Builder { - return $query->whereNotNull('completed_at'); + return $query->whereNotNull($query->qualifyColumn('completed_at')); } /** @@ -195,6 +195,6 @@ public function scopeCompleted(Builder $query): Builder */ public function scopePending(Builder $query): Builder { - return $query->whereNull('completed_at'); + return $query->whereNull($query->qualifyColumn('completed_at')); } } diff --git a/src/Models/User.php b/src/Models/User.php index bbc6f768..055aa4a9 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -187,8 +187,8 @@ public function toBreadcrumb(Request $request): string public function scopeSearch(Builder $query, string $value): Builder { return $query->where(static function (Builder $query) use ($value): Builder { - return $query->where('name', 'like', "{$value}%") - ->orWhere('email', 'like', "{$value}%"); + return $query->where($query->qualifyColumn('name'), 'like', "{$value}%") + ->orWhere($query->qualifyColumn('email'), 'like', "{$value}%"); }); } } diff --git a/src/Models/Variant.php b/src/Models/Variant.php index b2f06c07..683b938b 100644 --- a/src/Models/Variant.php +++ b/src/Models/Variant.php @@ -144,6 +144,6 @@ public function price(string $type = 'default', string $currency = null): ?float */ public function scopeSearch(Builder $query, string $value): Builder { - return $query->where('alias', 'like', "{$value}%"); + return $query->where($query->qualifyColumn('alias'), 'like', "{$value}%"); } } diff --git a/tests/Unit/AddressTest.php b/tests/Unit/AddressTest.php index 38e8ea9f..7d6f19da 100644 --- a/tests/Unit/AddressTest.php +++ b/tests/Unit/AddressTest.php @@ -141,7 +141,7 @@ public function it_has_query_scopes() $address->addressable()->associate($this->user)->save(); $this->assertSame( - $address->newQuery()->where('alias', 'like', 'test%')->toSql(), + $address->newQuery()->where('bazar_addresses.alias', 'like', 'test%')->toSql(), $address->newQuery()->search('test')->toSql() ); } diff --git a/tests/Unit/CartTest.php b/tests/Unit/CartTest.php index bb3a8e83..23fceb74 100644 --- a/tests/Unit/CartTest.php +++ b/tests/Unit/CartTest.php @@ -111,19 +111,20 @@ public function it_can_be_locked() public function it_has_query_scopes() { $this->assertSame( - $this->cart->newQuery()->where('locked', true)->toSql(), + $this->cart->newQuery()->where('bazar_carts.locked', true)->toSql(), $this->cart->newQuery()->locked()->toSql() ); $this->assertSame( - $this->cart->newQuery()->where('locked', false)->toSql(), + $this->cart->newQuery()->where('bazar_carts.locked', false)->toSql(), $this->cart->newQuery()->unlocked()->toSql() ); $this->assertSame( - $this->cart->newQuery()->whereNull('user_id')->where( - 'updated_at', '<', Carbon::now()->subDays(3) - )->toSql(), + $this->cart->newQuery() + ->whereNull('bazar_carts.user_id') + ->where('bazar_carts.updated_at', '<', Carbon::now()->subDays(3)) + ->toSql(), $this->cart->newQuery()->expired()->toSql() ); } diff --git a/tests/Unit/CategoryTest.php b/tests/Unit/CategoryTest.php index 7019aae1..04d6d0b3 100644 --- a/tests/Unit/CategoryTest.php +++ b/tests/Unit/CategoryTest.php @@ -52,7 +52,7 @@ public function it_is_breadcrumbable() public function it_has_query_scopes() { $this->assertSame( - $this->category->newQuery()->where('name', 'like', 'test%')->toSql(), + $this->category->newQuery()->where('bazar_categories.name', 'like', 'test%')->toSql(), $this->category->newQuery()->search('test')->toSql() ); } diff --git a/tests/Unit/FilterTest.php b/tests/Unit/FilterTest.php index c66886e2..ac0bbde2 100644 --- a/tests/Unit/FilterTest.php +++ b/tests/Unit/FilterTest.php @@ -25,15 +25,16 @@ public function a_product_query_can_be_filtered() 'category' => 1, ]); - $query = Product::query()->where(function ($query) { - $query->where('name', 'like', 'test%') - ->orWhere('inventory->sku', 'like', 'test%'); - })->withTrashed() - ->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc') - ->whereHas('categories', function ($query) { - return $query->where('bazar_categories.id', 1); - }); + $query = Product::query() + ->where(function ($query) { + $query->where('bazar_products.name', 'like', 'test%') + ->orWhere('bazar_products.inventory->sku', 'like', 'test%'); + })->withTrashed() + ->whereNotIn('bazar_products.id', [1, 2]) + ->orderBy('bazar_products.created_at', 'desc') + ->whereHas('categories', function ($query) { + return $query->where('bazar_categories.id', 1); + }); $this->assertSame( $query->toSql(), Product::filter($request)->toSql() @@ -52,16 +53,17 @@ public function an_order_query_can_be_filtered() 'user' => 1, ]); - $query = Order::query()->whereHas('address', function ($query) { - $query->where('bazar_addresses.first_name', 'like', 'test%') - ->orWhere('bazar_addresses.last_name', 'like', 'test%'); - })->withTrashed() - ->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc') - ->whereIn('status', ['in_progress']) - ->whereHas('user', function ($query) { - return $query->where('users.id', 1); - }); + $query = Order::query() + ->whereHas('address', function ($query) { + $query->where('bazar_addresses.first_name', 'like', 'test%') + ->orWhere('bazar_addresses.last_name', 'like', 'test%'); + })->withTrashed() + ->whereNotIn('bazar_orders.id', [1, 2]) + ->orderBy('bazar_orders.created_at', 'desc') + ->where('bazar_orders.status', 'in_progress') + ->whereHas('user', function ($query) { + return $query->where('users.id', 1); + }); $this->assertSame( $query->toSql(), Order::filter($request)->toSql() @@ -79,10 +81,11 @@ public function a_medium_query_can_be_filtered() 'type' => 'image', ]); - $query = Medium::query()->where('name', 'like', 'test%') - ->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc') - ->where('mime_type', 'like', 'image%'); + $query = Medium::query() + ->where('bazar_media.name', 'like', 'test%') + ->whereNotIn('bazar_media.id', [1, 2]) + ->orderBy('bazar_media.created_at', 'desc') + ->where('bazar_media.mime_type', 'like', 'image%'); $this->assertSame( $query->toSql(), Medium::filter($request)->toSql() @@ -98,9 +101,10 @@ public function an_address_query_can_be_filtered() 'sort' => ['by' => 'created_at', 'order' => 'desc'], ]); - $query = Address::query()->where('alias', 'like', 'test%') - ->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc'); + $query = Address::query() + ->where('bazar_addresses.alias', 'like', 'test%') + ->whereNotIn('bazar_addresses.id', [1, 2]) + ->orderBy('bazar_addresses.created_at', 'desc'); $this->assertSame( $query->toSql(), Address::filter($request)->toSql() @@ -116,9 +120,10 @@ public function a_category_query_can_be_filtered() 'sort' => ['by' => 'created_at', 'order' => 'desc'], ]); - $query = Category::query()->where('name', 'like', 'test%') - ->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc'); + $query = Category::query() + ->where('bazar_categories.name', 'like', 'test%') + ->whereNotIn('bazar_categories.id', [1, 2]) + ->orderBy('bazar_categories.created_at', 'desc'); $this->assertSame( $query->toSql(), Category::filter($request)->toSql() @@ -135,11 +140,12 @@ public function a_user_query_can_be_filtered() 'sort' => ['by' => 'created_at', 'order' => 'desc'], ]); - $query = User::query()->where(function ($query) { - $query->where('name', 'like', 'test%') - ->orWhere('email', 'like', 'test%'); - })->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc'); + $query = User::query() + ->where(function ($query) { + $query->where('users.name', 'like', 'test%') + ->orWhere('users.email', 'like', 'test%'); + })->whereNotIn('users.id', [1, 2]) + ->orderBy('users.created_at', 'desc'); $this->assertSame( $query->toSql(), User::filter($request)->toSql() @@ -156,10 +162,11 @@ public function a_variant_query_can_be_filtered() 'sort' => ['by' => 'created_at', 'order' => 'desc'], ]); - $query = Variant::query()->where('alias', 'like', 'test%') - ->onlyTrashed() - ->whereNotIn('id', [1, 2]) - ->orderBy('created_at', 'desc'); + $query = Variant::query() + ->where('bazar_variants.alias', 'like', 'test%') + ->onlyTrashed() + ->whereNotIn('bazar_variants.id', [1, 2]) + ->orderBy('bazar_variants.created_at', 'desc'); $this->assertSame( $query->toSql(), Variant::filter($request)->toSql() diff --git a/tests/Unit/MediumTest.php b/tests/Unit/MediumTest.php index 97e01a52..9f1b1a1a 100644 --- a/tests/Unit/MediumTest.php +++ b/tests/Unit/MediumTest.php @@ -72,17 +72,17 @@ public function it_has_path() public function it_has_query_scopes() { $this->assertSame( - $this->medium->newQuery()->where('name', 'like', 'test%')->toSql(), + $this->medium->newQuery()->where('bazar_media.name', 'like', 'test%')->toSql(), $this->medium->newQuery()->search('test')->toSql() ); $this->assertSame( - $this->medium->newQuery()->where('mime_type', 'not like', 'image%')->toSql(), + $this->medium->newQuery()->where('bazar_media.mime_type', 'not like', 'image%')->toSql(), $this->medium->newQuery()->type('file')->toSql() ); $this->assertSame( - $this->medium->newQuery()->where('mime_type', 'like', 'image%')->toSql(), + $this->medium->newQuery()->where('bazar_media.mime_type', 'like', 'image%')->toSql(), $this->medium->newQuery()->type('image')->toSql() ); diff --git a/tests/Unit/OrderTest.php b/tests/Unit/OrderTest.php index 1072408f..64a1d1d5 100644 --- a/tests/Unit/OrderTest.php +++ b/tests/Unit/OrderTest.php @@ -115,7 +115,7 @@ public function it_has_query_scopes() ); $this->assertSame( - $this->order->newQuery()->whereIn('status', ['pending'])->toSql(), + $this->order->newQuery()->where('bazar_orders.status', 'pending')->toSql(), $this->order->newQuery()->status('pending')->toSql() ); diff --git a/tests/Unit/ProductTest.php b/tests/Unit/ProductTest.php index efc6d446..f434dbb3 100644 --- a/tests/Unit/ProductTest.php +++ b/tests/Unit/ProductTest.php @@ -130,8 +130,8 @@ public function it_has_query_scopes() { $this->assertSame( $this->product->newQuery()->where(function ($q) { - $q->where('name', 'like', 'test%') - ->orWhere('inventory->sku', 'like', 'test%'); + $q->where('bazar_products.name', 'like', 'test%') + ->orWhere('bazar_products.inventory->sku', 'like', 'test%'); })->toSql(), $this->product->newQuery()->search('test')->toSql() ); @@ -142,5 +142,15 @@ public function it_has_query_scopes() })->toSql(), $this->product->newQuery()->category(1)->toSql() ); + + $this->assertSame( + $this->product->newQuery()->where('bazar_products.inventory->quantity', '=', 0)->toSql(), + $this->product->newQuery()->outOfStock()->toSql() + ); + + $this->assertSame( + $this->product->newQuery()->where('bazar_products.inventory->quantity', '>', 0)->toSql(), + $this->product->newQuery()->inStock()->toSql() + ); } } diff --git a/tests/Unit/TransactionTest.php b/tests/Unit/TransactionTest.php index b16cd84d..d3753627 100644 --- a/tests/Unit/TransactionTest.php +++ b/tests/Unit/TransactionTest.php @@ -62,22 +62,22 @@ public function it_can_be_completed() public function it_has_query_scopes() { $this->assertSame( - $this->transaction->newQuery()->where('type', 'payment')->toSql(), + $this->transaction->newQuery()->where('bazar_transactions.type', 'payment')->toSql(), $this->transaction->newQuery()->payment()->toSql() ); $this->assertSame( - $this->transaction->newQuery()->where('type', 'refund')->toSql(), + $this->transaction->newQuery()->where('bazar_transactions.type', 'refund')->toSql(), $this->transaction->newQuery()->refund()->toSql() ); $this->assertSame( - $this->transaction->newQuery()->whereNotNull('completed_at')->toSql(), + $this->transaction->newQuery()->whereNotNull('bazar_transactions.completed_at')->toSql(), $this->transaction->newQuery()->completed()->toSql() ); $this->assertSame( - $this->transaction->newQuery()->whereNull('completed_at')->toSql(), + $this->transaction->newQuery()->whereNull('bazar_transactions.completed_at')->toSql(), $this->transaction->newQuery()->pending()->toSql() ); } diff --git a/tests/Unit/UserTest.php b/tests/Unit/UserTest.php index 5ab58135..a66e034c 100644 --- a/tests/Unit/UserTest.php +++ b/tests/Unit/UserTest.php @@ -82,8 +82,8 @@ public function it_has_query_scopes() { $this->assertSame( $this->user->newQuery()->where(function ($q) { - $q->where('name', 'like', 'test%') - ->orWhere('email', 'like', 'test%'); + $q->where('users.name', 'like', 'test%') + ->orWhere('users.email', 'like', 'test%'); })->toSql(), $this->user->newQuery()->search('test')->toSql() ); diff --git a/tests/Unit/VariantTest.php b/tests/Unit/VariantTest.php index f292e54f..03dc403d 100644 --- a/tests/Unit/VariantTest.php +++ b/tests/Unit/VariantTest.php @@ -53,7 +53,7 @@ public function it_is_breadcrumbable() public function it_has_query_scopes() { $this->assertSame( - $this->variant->newQuery()->where('alias', 'like', 'test%')->toSql(), + $this->variant->newQuery()->where('bazar_variants.alias', 'like', 'test%')->toSql(), $this->variant->newQuery()->search('test')->toSql() ); }