diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7f7dcc3..7f71d0b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,9 +17,8 @@ jobs: strategy: matrix: php-version: - - "7.3" - - "7.4" - "8.0" + - "8.1" operating-system: - ubuntu-latest - windows-latest diff --git a/README.md b/README.md index e926673..ebd47db 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,11 @@ Some meta values are collected into helper classes: ## Compatibility list -| Corcel WooCommerce | Laravel | PHP version | -| ----------------------------------------------------- | -------------- | ------------- | -| [1.x](https://github.com/corcel/woocommerce/tree/1.x) | 6.x, 7.x | >= 7.2 | -| 2.x (master) | 6.x, 7.x, 8.x | >= 7.3 \| 8.0 | +| Corcel WooCommerce | Laravel | PHP version | Supported | +| ----------------------------------------------------- | -------------- | ------------- | ------------------ | +| 3.x (master) | 9.x | >= 8.0.3 | :white_check_mark: | +| [2.x](https://github.com/corcel/woocommerce/tree/2.x) | 6.x, 7.x, 8.x | >= 7.3 \| 8.0 | :white_check_mark: | +| [1.x](https://github.com/corcel/woocommerce/tree/1.x) | 6.x, 7.x | >= 7.2 | :x: | ## Installation diff --git a/composer.json b/composer.json index 0d4cb11..61c845e 100644 --- a/composer.json +++ b/composer.json @@ -11,18 +11,18 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/database": "^6.0|^7.0|^8.0", - "illuminate/support": "^6.0|^7.0|^8.0", - "jgrossi/corcel": "^3.0|^4.0|^5.0", - "nesbot/carbon": "^2.0" + "php": "^8.0.3", + "illuminate/database": "^9.0", + "illuminate/support": "^9.0", + "jgrossi/corcel": "^6.0", + "nesbot/carbon": "^2.53.1" }, "require-dev": { - "orchestra/testbench": "^4.0|^5.0|^6.0", - "phpstan/phpstan": "^0.12.46", + "orchestra/testbench": "^7.0", + "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^9.4", - "laravel/legacy-factories": "^1.0", - "nunomaduro/larastan": "^0.7.13" + "nunomaduro/larastan": "^2.0", + "laravel/pint": "^0.2.0" }, "autoload": { "psr-4": { @@ -31,7 +31,8 @@ }, "autoload-dev": { "psr-4": { - "Tests\\": "tests/" + "Tests\\": "tests/", + "Database\\Factories\\": "tests/database/factories/" } } } diff --git a/phpstan.neon b/phpstan.neon index 8e8ef25..343b1dc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,12 +6,12 @@ parameters: - src - tests - level: 8 + level: max noUnnecessaryCollectionCall: false stubFiles: - - tests/stubs/Taxonomy.php.stub + - stubs/Corcel.stub ignoreErrors: - diff --git a/src/Model/Builder/OrderBuilder.php b/src/Model/Builder/OrderBuilder.php index ccfc499..3f11fba 100644 --- a/src/Model/Builder/OrderBuilder.php +++ b/src/Model/Builder/OrderBuilder.php @@ -1,4 +1,5 @@ + */ use HasRelationsThroughMeta; /** * @inheritDoc * - * @var string[] + * @var array */ protected $appends = [ 'order_count', ]; + /** + * Create a new factory instance for the model. + * + * @return CustomerFactory + */ + protected static function newFactory(): CustomerFactory + { + return CustomerFactory::new(); + } + /** * Get order count attribute. * @@ -33,13 +51,15 @@ class Customer extends User */ protected function getOrderCountAttribute(): int { - return (int) $this->getMeta('_order_count'); + $count = $this->getMeta('_order_count'); + + return is_numeric($count) ? (int) $count : 0; } /** * Get the related orders. * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return HasMany<\Illuminate\Database\Eloquent\Model> */ public function orders(): HasMany { diff --git a/src/Model/Item.php b/src/Model/Item.php index d98886c..643782d 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -1,4 +1,5 @@ |array> */ protected static $aliases = [ 'id' => 'order_item_id', @@ -50,7 +54,7 @@ class Item extends Model /** * @inheritDoc * - * @var string[] + * @var array */ protected $appends = [ 'quantity', @@ -82,14 +86,26 @@ class Item extends Model */ public $timestamps = false; + /** + * Create a new factory instance for the model. + * + * @return ItemFactory + */ + protected static function newFactory(): ItemFactory + { + return ItemFactory::new(); + } + /** * Get the line subtotal attribute. * * @return string|null */ - protected function getLineSubtotalAttribute() + protected function getLineSubtotalAttribute(): ?string { - return $this->getMeta('_line_subtotal'); + $lineSubtotal = $this->getMeta('_line_subtotal'); + + return is_scalar($lineSubtotal) ? (string) $lineSubtotal : null; } /** @@ -97,9 +113,11 @@ protected function getLineSubtotalAttribute() * * @return string|null */ - protected function getLineSubtotalTaxAttribute() + protected function getLineSubtotalTaxAttribute(): ?string { - return $this->getMeta('_line_subtotal_tax'); + $lineSubtotalTax = $this->getMeta('_line_subtotal_tax'); + + return is_scalar($lineSubtotalTax) ? (string) $lineSubtotalTax : null; } /** @@ -107,9 +125,11 @@ protected function getLineSubtotalTaxAttribute() * * @return string|null */ - protected function getLineTaxAttribute() + protected function getLineTaxAttribute(): ?string { - return $this->getMeta('_line_tax'); + $lineTax = $this->getMeta('_line_tax'); + + return is_scalar($lineTax) ? (string) $lineTax : null; } /** @@ -117,9 +137,11 @@ protected function getLineTaxAttribute() * * @return string|null */ - protected function getLineTotalAttribute() + protected function getLineTotalAttribute(): ?string { - return $this->getMeta('_line_total'); + $lineTotal = $this->getMeta('_line_total'); + + return is_scalar($lineTotal) ? (string) $lineTotal : null; } /** @@ -127,9 +149,11 @@ protected function getLineTotalAttribute() * * @return string|null */ - protected function getQuantityAttribute() + protected function getQuantityAttribute(): ?string { - return $this->getMeta('_qty'); + $quantity = $this->getMeta('_qty'); + + return is_scalar($quantity) ? (string) $quantity : null; } /** @@ -137,15 +161,17 @@ protected function getQuantityAttribute() * * @return string|null */ - protected function getTaxClassAttribute() + protected function getTaxClassAttribute(): ?string { - return $this->getMeta('_tax_class'); + $taxClass = $this->getMeta('_tax_class'); + + return is_scalar($taxClass) ? (string) $taxClass : null; } /** * @inheritDoc * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return HasMany */ public function meta(): HasMany { @@ -155,7 +181,7 @@ public function meta(): HasMany /** * Get the related order. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return BelongsTo */ public function order(): BelongsTo { @@ -165,7 +191,7 @@ public function order(): BelongsTo /** * Get the related product. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return BelongsTo */ public function product(): BelongsTo { diff --git a/src/Model/Meta/ItemMeta.php b/src/Model/Meta/ItemMeta.php index 3c1930e..37e9cda 100644 --- a/src/Model/Meta/ItemMeta.php +++ b/src/Model/Meta/ItemMeta.php @@ -1,4 +1,5 @@ > */ protected static $aliases = [ 'customer_id' => ['meta' => '_customer_user'], @@ -45,7 +50,7 @@ class Order extends Post /** * @inheritDoc * - * @var string[] + * @var array */ protected $appends = [ 'currency', @@ -66,6 +71,16 @@ class Order extends Post */ protected $postType = 'shop_order'; + /** + * Create a new factory instance for the model. + * + * @return OrderFactory + */ + protected static function newFactory(): OrderFactory + { + return OrderFactory::new(); + } + /** * @inheritDoc */ @@ -81,7 +96,9 @@ public function newEloquentBuilder($builder): OrderBuilder */ protected function getCurrencyAttribute(): ?string { - return $this->getMeta('_order_currency'); + $currency = $this->getMeta('_order_currency'); + + return is_scalar($currency) ? (string) $currency : null; } /** @@ -91,7 +108,9 @@ protected function getCurrencyAttribute(): ?string */ protected function getTotalAttribute(): ?string { - return $this->getMeta('_order_total'); + $total = $this->getMeta('_order_total'); + + return is_scalar($total) ? (string) $total : null; } /** @@ -101,7 +120,9 @@ protected function getTotalAttribute(): ?string */ protected function getShippingAttribute(): ?string { - return $this->getMeta('_order_shipping'); + $shipping = $this->getMeta('_order_shipping'); + + return is_scalar($shipping) ? (string) $shipping : null; } /** @@ -111,7 +132,9 @@ protected function getShippingAttribute(): ?string */ protected function getTaxAttribute(): ?string { - return $this->getMeta('_order_tax'); + $tax = $this->getMeta('_order_tax'); + + return is_scalar($tax) ? (string) $tax : null; } /** @@ -121,7 +144,9 @@ protected function getTaxAttribute(): ?string */ protected function getShippingTaxAttribute(): ?string { - return $this->getMeta('_order_shipping_tax'); + $shippingTax = $this->getMeta('_order_shipping_tax'); + + return is_scalar($shippingTax) ? (string) $shippingTax : null; } /** @@ -139,13 +164,13 @@ public function getStatusAttribute(): string /** * Get the completed date attribute. * - * @return \Carbon\Carbon|null + * @return Carbon|null */ protected function getDateCompletedAttribute(): ?Carbon { $value = $this->getMeta('_date_completed'); - if ($value !== null) { + if (is_numeric($value)) { return Carbon::createFromTimestamp($value); } @@ -155,7 +180,7 @@ protected function getDateCompletedAttribute(): ?Carbon */ $value = $this->getMeta('_completed_date'); - if ($value !== null) { + if (is_string($value)) { $datetime = Carbon::createFromFormat('Y-m-d H:i:s', $value); return $datetime !== false ? $datetime : null; @@ -167,13 +192,13 @@ protected function getDateCompletedAttribute(): ?Carbon /** * Get the paid date attribute. * - * @return \Carbon\Carbon|null + * @return Carbon|null */ public function getDatePaidAttribute(): ?Carbon { $value = $this->getMeta('_date_paid'); - if ($value !== null) { + if (is_numeric($value)) { return Carbon::createFromTimestamp($value); } @@ -183,7 +208,7 @@ public function getDatePaidAttribute(): ?Carbon */ $value = $this->getMeta('_paid_date'); - if ($value !== null) { + if (is_string($value)) { $datetime = Carbon::createFromFormat('Y-m-d H:i:s', $value); return $datetime !== false ? $datetime : null; @@ -195,7 +220,7 @@ public function getDatePaidAttribute(): ?Carbon /** * Get the payment attribute. * - * @return \Corcel\WooCommerce\Support\Payment + * @return Payment */ public function getPaymentAttribute(): Payment { @@ -205,7 +230,7 @@ public function getPaymentAttribute(): Payment /** * Get the related customer. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return BelongsTo */ public function customer(): BelongsTo { @@ -215,7 +240,7 @@ public function customer(): BelongsTo /** * Get related items. * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return HasMany */ public function items(): HasMany { diff --git a/src/Model/Product.php b/src/Model/Product.php index b62a730..5b6545b 100644 --- a/src/Model/Product.php +++ b/src/Model/Product.php @@ -1,4 +1,5 @@ $crosssells + * @property Collection $upsells + * @property BaseCollection $gallery + * @property Collection $categories + * @property Collection $items + * @property Collection $productTypes + * @property Collection $tags */ class Product extends Post { + use HasFactory; use Aliases; use MetaFields; + + /** + * @use HasRelationsThroughMeta<\Illuminate\Database\Eloquent\Model> + */ use HasRelationsThroughMeta; /** * Preloaded product attributes list. * - * @var \Illuminate\Database\Eloquent\Collection<\Corcel\WooCommerce\Model\ProductAttribute> + * @var Collection */ protected static $productAttributes; /** * @inheritDoc * - * @var string[] + * @var array */ protected $appends = [ 'price', @@ -92,6 +100,16 @@ protected static function boot() static::$productAttributes = ProductAttribute::all()->keyBy('attribute_name'); } + /** + * Create a new factory instance for the model. + * + * @return ProductFactory + */ + protected static function newFactory(): ProductFactory + { + return ProductFactory::new(); + } + /** * Get the price attribute. * @@ -99,7 +117,9 @@ protected static function boot() */ protected function getPriceAttribute(): ?string { - return $this->getMeta('_price'); + $price = $this->getMeta('_price'); + + return is_scalar($price) ? (string) $price : null; } /** @@ -109,7 +129,9 @@ protected function getPriceAttribute(): ?string */ protected function getRegularPriceAttribute(): ?string { - return $this->getMeta('_regular_price'); + $regularPrice = $this->getMeta('_regular_price'); + + return is_scalar($regularPrice) ? (string) $regularPrice : null; } /** @@ -119,7 +141,9 @@ protected function getRegularPriceAttribute(): ?string */ protected function getSalePriceAttribute(): ?string { - return $this->getMeta('_sale_price'); + $salePrice = $this->getMeta('_sale_price'); + + return is_scalar($salePrice) ? (string) $salePrice : null; } /** @@ -129,7 +153,7 @@ protected function getSalePriceAttribute(): ?string */ protected function getOnSaleAttribute(): bool { - return !empty($this->sale_price) && $this->sale_price < $this->regular_price; + return ! empty($this->sale_price) && $this->sale_price < $this->regular_price; } /** @@ -139,7 +163,9 @@ protected function getOnSaleAttribute(): bool */ protected function getSkuAttribute(): ?string { - return $this->getMeta('_sku'); + $sku = $this->getMeta('_sku'); + + return is_scalar($sku) ? (string) $sku : null; } /** @@ -149,7 +175,9 @@ protected function getSkuAttribute(): ?string */ protected function getTaxStatusAttribute(): ?string { - return $this->getMeta('_tax_status'); + $taxStatus = $this->getMeta('_tax_status'); + + return is_scalar($taxStatus) ? (string) $taxStatus : null; } /** @@ -169,7 +197,9 @@ public function getIsTaxableAttribute(): bool */ protected function getWeightAttribute(): ?string { - return $this->getMeta('_weight'); + $weight = $this->getMeta('_weight'); + + return is_scalar($weight) ? (string) $weight : null; } /** @@ -179,7 +209,9 @@ protected function getWeightAttribute(): ?string */ protected function getLengthAttribute(): ?string { - return $this->getMeta('_length'); + $length = $this->getMeta('_length'); + + return is_scalar($length) ? (string) $length : null; } /** @@ -189,7 +221,9 @@ protected function getLengthAttribute(): ?string */ protected function getWidthAttribute(): ?string { - return $this->getMeta('_width'); + $width = $this->getMeta('_width'); + + return is_scalar($width) ? (string) $width : null; } /** @@ -199,7 +233,9 @@ protected function getWidthAttribute(): ?string */ protected function getHeightAttribute(): ?string { - return $this->getMeta('_height'); + $height = $this->getMeta('_height'); + + return is_scalar($height) ? (string) $height : null; } /** @@ -229,7 +265,9 @@ protected function getIsDownloadableAttribute(): bool */ protected function getStockAttribute(): ?string { - return $this->getMeta('_stock'); + $stock = $this->getMeta('_stock'); + + return is_scalar($stock) ? (string) $stock : null; } /** @@ -245,7 +283,7 @@ protected function getInStockAttribute(): bool /** * Get the product attributes attribute. * - * @return \Illuminate\Support\Collection<\Corcel\WooCommerce\Model\ProductAttribute> + * @return BaseCollection */ protected function getAttributesAttribute(): BaseCollection { @@ -270,15 +308,20 @@ protected function getAttributesAttribute(): BaseCollection /** * Get the cross-sells attribute. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ protected function getCrosssellsAttribute(): Collection { $crosssells = $this->getMeta('_crosssell_ids'); + + if (! is_string($crosssells)) { + return static::newCollection(); + } + $crosssells = unserialize($crosssells); if (empty($crosssells)) { - return new Collection(); + return static::newCollection(); } return static::query()->whereIn('ID', $crosssells)->get(); @@ -287,15 +330,20 @@ protected function getCrosssellsAttribute(): Collection /** * Get the up-sells attribute. * - * @return \Illuminate\Database\Eloquent\Collection + * @return Collection */ public function getUpsellsAttribute(): Collection { $upsells = $this->getMeta('_upsell_ids'); + + if (! is_string($upsells)) { + return static::newCollection(); + } + $upsells = unserialize($upsells); if (empty($upsells)) { - return new Collection(); + return static::newCollection(); } return static::query()->whereIn('ID', $upsells)->get(); @@ -304,7 +352,7 @@ public function getUpsellsAttribute(): Collection /** * Get the gallery attribute. * - * @return \Illuminate\Support\Collection<\Corcel\Model\Attachment> + * @return BaseCollection */ public function getGalleryAttribute(): BaseCollection { @@ -316,12 +364,12 @@ public function getGalleryAttribute(): BaseCollection $attachmentsId = $this->getMeta('_product_image_gallery'); - if (empty($attachmentsId)) { + if (! is_string($attachmentsId) || empty($attachmentsId)) { return $gallery; } $attachmentsId = explode(',', $attachmentsId); - $attachments = Attachment::query()->whereIn('ID', $attachmentsId)->get(); + $attachments = Attachment::query()->whereIn('ID', $attachmentsId)->get(); return $gallery->merge($attachments); } @@ -333,13 +381,16 @@ public function getGalleryAttribute(): BaseCollection */ protected function getTypeAttribute(): ?string { - return $this->productTypes->pluck('term.name')->first(); + /** @var BaseCollection */ + $productTypeNames = $this->productTypes->pluck('term.name'); + + return $productTypeNames->first(); } /** * Get the related categories. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + * @return BelongsToMany */ public function categories(): BelongsToMany { @@ -354,7 +405,7 @@ public function categories(): BelongsToMany /** * Get the related items. * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return HasMany<\Illuminate\Database\Eloquent\Model> */ public function items(): HasMany { @@ -369,7 +420,7 @@ public function items(): HasMany /** * Get the related product types. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + * @return BelongsToMany */ public function productTypes(): BelongsToMany { @@ -384,7 +435,7 @@ public function productTypes(): BelongsToMany /** * Get the related tags. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + * @return BelongsToMany */ public function tags(): BelongsToMany { diff --git a/src/Model/ProductAttribute.php b/src/Model/ProductAttribute.php index 266ea66..6bb6df3 100644 --- a/src/Model/ProductAttribute.php +++ b/src/Model/ProductAttribute.php @@ -1,4 +1,5 @@ + * @var Collection */ - public $terms; + public Collection $terms; /** * The model aliases. * - * @var string[] + * @var array */ protected static $aliases = [ 'id' => 'attribute_id', @@ -49,7 +50,7 @@ class ProductAttribute extends Model /** * @inheritDoc * - * @var string[] + * @var array */ protected $casts = [ 'attribute_public' => 'bool', @@ -68,7 +69,7 @@ class ProductAttribute extends Model /** * Set the product terms. * - * @param \Illuminate\Support\Collection $terms + * @param Collection $terms */ public function setTerms(Collection $terms): void { diff --git a/src/Model/ProductCategory.php b/src/Model/ProductCategory.php index ef6d7eb..56456ab 100644 --- a/src/Model/ProductCategory.php +++ b/src/Model/ProductCategory.php @@ -1,4 +1,5 @@ + */ class Address implements Arrayable, Jsonable { /** * The model instance. * - * @var \Corcel\Model + * @var Model */ - protected $model; + protected Model $model; /** * The address type. * * @var string */ - protected $type; + protected string $type; /** * The address attributes. * - * @var mixed[] + * @var array */ - protected $attributes = []; + protected array $attributes = []; /** * The address constructor. * - * @param \Corcel\Model $model - * @param string $type + * @param Model $model + * @param string $type */ public function __construct(Model $model, string $type) { $this->model = $model; - $this->type = $type; + $this->type = $type; $this->parseAttributes(); } @@ -65,7 +69,7 @@ protected function parseAttributes(): void /** * List of the attribute keys. * - * @return string[] + * @return array */ protected function attributeKeys(): array { @@ -94,7 +98,7 @@ protected function attributeKeys(): array /** * Get meta key for given attribute name. * - * @param string $key + * @param string $key * @return string */ protected function getMetaKey(string $key): string @@ -126,7 +130,7 @@ protected function metaKeyPattern(): string /** * @inheritDoc * - * @return mixed[] + * @return array */ public function toArray(): array { @@ -136,7 +140,7 @@ public function toArray(): array /** * @inheritDoc * - * @param int $options + * @param int $options * @return string */ public function toJson($options = 0): string @@ -153,7 +157,7 @@ public function toJson($options = 0): string /** * Magic method to get address attributes. * - * @param string $key + * @param string $key * @return mixed */ public function __get(string $key) diff --git a/src/Support/BillingAddress.php b/src/Support/BillingAddress.php index 06286e4..2db14d9 100644 --- a/src/Support/BillingAddress.php +++ b/src/Support/BillingAddress.php @@ -1,4 +1,5 @@ + */ class Payment implements Arrayable, Jsonable { /** @@ -15,38 +19,42 @@ class Payment implements Arrayable, Jsonable * * @var string|null */ - public $method; + public ?string $method = null; /** * The payment method title. * * @var string|null */ - public $method_title; + public ?string $method_title = null; /** * The payment transation identificator. * * @var string|null */ - public $transaction_id; + public ?string $transaction_id = null; /** * The payment constructor. * - * @param \Corcel\WooCommerce\Model\Order $order + * @param Order $order */ public function __construct(Order $order) { - $this->method = $order->getMeta('_payment_method'); - $this->method_title = $order->getMeta('_payment_method_title'); - $this->transaction_id = $order->getMeta('_transaction_id'); + $method = $order->getMeta('_payment_method'); + $methodTitle = $order->getMeta('_payment_method_title'); + $transactionId = $order->getMeta('_transaction_id'); + + $this->method = is_scalar($method) ? (string) $method : null; + $this->method_title = is_scalar($methodTitle) ? (string) $methodTitle : null; + $this->transaction_id = is_scalar($transactionId) ? (string) $transactionId : null; } /** * @inheritDoc * - * @return mixed[] + * @return array */ public function toArray(): array { @@ -60,7 +68,7 @@ public function toArray(): array /** * @inheritDoc * - * @param int $options + * @param int $options * @return string */ public function toJson($options = 0): string diff --git a/src/Support/ShippingAddress.php b/src/Support/ShippingAddress.php index e8b38e6..04c79bf 100644 --- a/src/Support/ShippingAddress.php +++ b/src/Support/ShippingAddress.php @@ -1,4 +1,5 @@ + * * @throws InvalidArgumentException * @throws LogicException */ public function hasManyThroughMeta(string $related, string $metaKey, string $foreignKey = null, string $localKey = null): HasMany { + /** @var Model */ $model = $this->newRelatedInstance($related); - $meta = $this->metaInstance($model); + $meta = $this->metaInstance($model); $foreignKey = $foreignKey ?: $this->getForeignKey(); - $localKey = $localKey ?: $this->getKeyName(); + $localKey = $localKey ?: $this->getKeyName(); return $this->hasMany($related, $meta->qualifyColumn('meta_value')) ->leftJoin($meta->getTable(), $this->joinClause( @@ -45,14 +51,15 @@ public function hasManyThroughMeta(string $related, string $metaKey, string $for /** * Make meta model instance. * - * @param \Illuminate\Database\Eloquent\Model $model + * @param \Illuminate\Database\Eloquent\Model $model * @return \Corcel\Model\Meta\Meta + * * @throws InvalidArgumentException * @throws LogicException */ private function metaInstance(Model $model): Meta { - if (!method_exists($model, 'meta')) { + if (! method_exists($model, 'meta')) { throw new LogicException(sprintf( 'The model "%s" must have defined "meta" method. Adding "%s" trait will likely solve this problem.', get_class($model), @@ -62,7 +69,7 @@ private function metaInstance(Model $model): Meta $meta = $model->meta()->getRelated(); - if (!$meta instanceof Meta) { + if (! $meta instanceof Meta) { throw new InvalidArgumentException(sprintf( 'The meta method of "%s" model must extends "%s" model.', get_class($meta), @@ -76,9 +83,9 @@ private function metaInstance(Model $model): Meta /** * Build join clause between model and meta tables. * - * @param string $localKey - * @param string $foreignKey - * @param string $metaKey + * @param string $localKey + * @param string $foreignKey + * @param string $metaKey * @return Closure */ private function joinClause(string $localKey, string $foreignKey, string $metaKey): Closure diff --git a/src/WooCommerce.php b/src/WooCommerce.php index d0c7586..632a029 100644 --- a/src/WooCommerce.php +++ b/src/WooCommerce.php @@ -1,4 +1,5 @@ loadMigrationsFrom([ '--database' => 'wp', '--realpath' => true, - '--path' => __DIR__ . '/database/migrations', + '--path' => __DIR__.'/database/migrations', ]); - - $this->withFactories(__DIR__ . '/database/factories'); } /** * @inheritDoc * - * @param \Illuminate\Foundation\Application $app + * @param \Illuminate\Foundation\Application $app * @return void */ protected function getEnvironmentSetUp($app): void @@ -39,7 +38,7 @@ protected function getEnvironmentSetUp($app): void /** * Configure database. * - * @param \Illuminate\Foundation\Application $app + * @param \Illuminate\Foundation\Application $app * @return void */ private function configureDatabaseConfig($app): void diff --git a/tests/Unit/Model/CustomerTest.php b/tests/Unit/Model/CustomerTest.php index 18ada3d..c9fee08 100644 --- a/tests/Unit/Model/CustomerTest.php +++ b/tests/Unit/Model/CustomerTest.php @@ -1,4 +1,5 @@ createCustomer(); - /** @var \Corcel\WooCommerce\Model\Order */ - $order = factory(Order::class)->create(); - $order->createMeta('_customer_user', $customer->ID); // @phpstan-ignore-line + /** @var Order */ + $order = Order::factory()->create(); + $order->createMeta('_customer_user', $customer->ID); $this->assertTrue($customer->orders()->get()->first()->is($order)); // @phpstan-ignore-line - /** @var \Corcel\WooCommerce\Model\Order */ - $order = factory(Order::class)->create(); - $order->createMeta('_customer_user', $customer->ID); // @phpstan-ignore-line + /** @var Order */ + $order = Order::factory()->create(); + $order->createMeta('_customer_user', $customer->ID); $this->assertSame(2, $customer->orders()->count()); // @phpstan-ignore-line } private function createCustomer(): Customer { - return factory(Customer::class)->create(); + /** @var Customer */ + return Customer::factory()->create(); } } diff --git a/tests/Unit/Model/ItemTest.php b/tests/Unit/Model/ItemTest.php index 88e6b16..dce7d77 100644 --- a/tests/Unit/Model/ItemTest.php +++ b/tests/Unit/Model/ItemTest.php @@ -1,4 +1,5 @@ create(); - $item = $this->createItem(['order_id' => $order->ID]); + /** @var Order */ + $order = Order::factory()->create(); + $item = $this->createItem(['order_id' => $order->ID]); $this->assertTrue($item->order->is($order)); } @@ -69,19 +71,22 @@ public function testRelatedOrder(): void public function testRelatedProduct(): void { /** @var \Corcel\WooCommerce\Model\Product */ - $product = factory(Product::class)->create(); + $product = Product::factory()->create(); $item = $this->createItem(); - $item->createMeta('_product_id', $product->ID); // @phpstan-ignore-line + $item->createMeta('_product_id', $product->ID); $this->assertTrue($item->product->is($product)); } /** - * @param mixed[] $attributes + * @param mixed[] $attributes */ private function createItem(array $attributes = []): Item { - return factory(Item::class)->create($attributes); + /** @var Item */ + $item = Item::factory()->create($attributes); + + return $item; } } diff --git a/tests/Unit/Model/OrderTest.php b/tests/Unit/Model/OrderTest.php index 5769e43..1b5cb39 100644 --- a/tests/Unit/Model/OrderTest.php +++ b/tests/Unit/Model/OrderTest.php @@ -1,4 +1,5 @@ create(); + /** @var Order */ + $order = Order::factory()->create(); $array = $order->toArray(); $this->assertArrayHasKey('currency', $array); @@ -135,13 +137,13 @@ public function testArrayHasAppendedValues(): void public function testRelatedCustomer(): void { - /** @var \Corcel\WooCommerce\Model\Customer */ - $customer = factory(Customer::class)->create(); + /** @var Customer */ + $customer = Customer::factory()->create(); $order = $this->createOrder(); - $order->createMeta('_customer_user', $customer->ID); // @phpstan-ignore-line + $order->createMeta('_customer_user', $customer->ID); - /** @var \Corcel\WooCommerce\Model\Customer */ + /** @var Customer */ $orderCustomer = $order->customer; $this->assertTrue($orderCustomer->is($customer)); @@ -158,16 +160,19 @@ public function testRelatedItems(): void { $order = $this->createOrder(); - $item = factory(Item::class, 3)->create(['order_id' => $order->ID]); // @phpstan-ignore-line + $item = Item::factory()->count(3)->create(['order_id' => $order->ID]); $this->assertSame(3, $order->items->count()); } /** - * @param mixed[] $attributes + * @param mixed[] $attributes */ private function createOrder(array $attributes = []): Order { - return factory(Order::class)->create($attributes); + /** @var Order */ + $order = Order::factory()->create($attributes); + + return $order; } } diff --git a/tests/Unit/Model/ProductAttributeTest.php b/tests/Unit/Model/ProductAttributeTest.php index bef0ae3..59c7848 100644 --- a/tests/Unit/Model/ProductAttributeTest.php +++ b/tests/Unit/Model/ProductAttributeTest.php @@ -1,10 +1,11 @@ create(); + /** @var \Illuminate\Database\Eloquent\Collection */ + $crosssellProducts = Product::factory()->count(2)->create(); $product = $this->createProduct(); $product->createMeta('_crosssell_ids', serialize($crosssellProducts->pluck('ID')->toArray())); $this->assertSame(2, $product->crosssells->count()); + // @phpstan-ignore-next-line $this->assertTrue($product->crosssells->first()->is($crosssellProducts->first())); } @@ -176,12 +179,14 @@ public function testEmptyCrosssells(): void public function testUpsellsProperty(): void { - $upsellProducts = factory(Product::class, 3)->create(); + /** @var \Illuminate\Database\Eloquent\Collection */ + $upsellProducts = Product::factory()->count(3)->create(); $product = $this->createProduct(); $product->createMeta('_upsell_ids', serialize($upsellProducts->pluck('ID')->toArray())); $this->assertSame(3, $product->upsells->count()); + // @phpstan-ignore-next-line $this->assertTrue($product->upsells->first()->is($upsellProducts->first())); } @@ -197,18 +202,24 @@ public function testRelatedItems(): void { $product = $this->createProduct(); - $firstItem = factory(Item::class)->create(); - $firstItem->createMeta('_product_id', $product->ID); // @phpstan-ignore-line + /** @var Item */ + $firstItem = Item::factory()->create(); + $firstItem->createMeta('_product_id', $product->ID); - $secondItem = factory(Item::class)->create(); - $secondItem->createMeta('_product_id', $product->ID); // @phpstan-ignore-line + /** @var Item */ + $secondItem = Item::factory()->create(); + $secondItem->createMeta('_product_id', $product->ID); $this->assertSame(2, $product->items->count()); + // @phpstan-ignore-next-line $this->assertTrue($product->items->first()->is($firstItem)); } private function createProduct(): Product { - return factory(Product::class)->create(); + /** @var Product */ + $product = Product::factory()->create(); + + return $product; } } diff --git a/tests/Unit/Support/AddressTest.php b/tests/Unit/Support/AddressTest.php index 449abb2..f593179 100644 --- a/tests/Unit/Support/AddressTest.php +++ b/tests/Unit/Support/AddressTest.php @@ -1,4 +1,5 @@ expectException(InvalidArgumentException::class); - $model = factory(Item::class)->create(); + /** @var Item */ + $model = Item::factory()->create(); new Address($model, 'billing'); } @@ -24,12 +26,14 @@ public function testInvalidJson(): void { $this->expectException(InvalidArgumentException::class); - $order = factory(Order::class)->create(); - $address = new class($order, 'billing') extends Address { + /** @var Order */ + $order = Order::factory()->create(); + $address = new class($order, 'billing') extends Address + { public function toArray(): array { return [ - fopen('php://input', 'r'), + 'invalid' => fopen('php://input', 'r'), ]; } }; diff --git a/tests/Unit/Support/BillingAddressTest.php b/tests/Unit/Support/BillingAddressTest.php index 6cb93a2..b8ecd6c 100644 --- a/tests/Unit/Support/BillingAddressTest.php +++ b/tests/Unit/Support/BillingAddressTest.php @@ -1,4 +1,5 @@ create(); + /** @var Order */ + $order = Order::factory()->create(); $order->createMeta(self::ORDER_META_FIELDS); return new BillingAddress($order); @@ -121,7 +123,8 @@ private function createOrderBillingAddress(): BillingAddress private function createCustomerBillingAddress(): BillingAddress { - $customer = factory(Customer::class)->create(); + /** @var Customer */ + $customer = Customer::factory()->create(); $customer->createMeta(self::CUSTOMER_META_FIELDS); return new BillingAddress($customer); diff --git a/tests/Unit/Support/PaymentTest.php b/tests/Unit/Support/PaymentTest.php index aac62cf..6d3abf1 100644 --- a/tests/Unit/Support/PaymentTest.php +++ b/tests/Unit/Support/PaymentTest.php @@ -1,4 +1,5 @@ createPayment(); - $array = [ + $array = [ 'method' => 'test', 'method_title' => 'Test', 'transaction_id' => 'tid-000', @@ -34,7 +35,7 @@ public function testToArrayMethod(): void public function testToJsonMethod(): void { $payment = $this->createPayment(); - $json = '{"method":"test","method_title":"Test","transaction_id":"tid-000"}'; + $json = '{"method":"test","method_title":"Test","transaction_id":"tid-000"}'; $this->assertSame($json, $payment->toJson()); } @@ -43,12 +44,14 @@ public function testInvalidJson(): void { $this->expectException(InvalidArgumentException::class); - $order = factory(Order::class)->create(); - $payment = new class($order) extends Payment { + /** @var Order */ + $order = Order::factory()->create(); + $payment = new class($order) extends Payment + { public function toArray(): array { return [ - fopen('php://input', 'r'), + 'invalid' => fopen('php://input', 'r'), ]; } }; @@ -58,7 +61,8 @@ public function toArray(): array private function createPayment(): Payment { - $order = factory(Order::class)->create(); + /** @var Order */ + $order = Order::factory()->create(); $order->createMeta([ '_payment_method' => 'test', '_payment_method_title' => 'Test', diff --git a/tests/Unit/Support/ShippingAddressTest.php b/tests/Unit/Support/ShippingAddressTest.php index fefe8fc..be0e71c 100644 --- a/tests/Unit/Support/ShippingAddressTest.php +++ b/tests/Unit/Support/ShippingAddressTest.php @@ -1,4 +1,5 @@ create(); + /** @var Order */ + $order = Order::factory()->create(); $order->createMeta(self::ORDER_META_FIELDS); return new ShippingAddress($order); @@ -111,7 +113,8 @@ private function createOrderShippingAddress(): ShippingAddress private function createCustomerShippingAddress(): ShippingAddress { - $customer = factory(Customer::class)->create(); + /** @var Customer */ + $customer = Customer::factory()->create(); $customer->createMeta(self::CUSTOMER_META_FIELDS); return new ShippingAddress($customer); diff --git a/tests/Unit/Traits/HasRelationsThroughMetaTest.php b/tests/Unit/Traits/HasRelationsThroughMetaTest.php index b2eb997..b294a0e 100644 --- a/tests/Unit/Traits/HasRelationsThroughMetaTest.php +++ b/tests/Unit/Traits/HasRelationsThroughMetaTest.php @@ -1,4 +1,5 @@ expectException(LogicException::class); - $model = new class() extends Model { + $model = new class() extends Model + { + /** + * @use HasRelationsThroughMeta<\Illuminate\Database\Eloquent\Model> + */ use HasRelationsThroughMeta; + /** + * @return HasMany<\Illuminate\Database\Eloquent\Model> + */ public function relatedObjects(): HasMany { return $this->hasManyThroughMeta(Model::class, '_meta_key', 'foreign_key', 'local_key'); @@ -32,7 +40,11 @@ public function testInvalidMeta(): void { $this->expectException(InvalidArgumentException::class); - $model = new class() extends Model { + $model = new class() extends Model + { + /** + * @use HasRelationsThroughMeta<\Illuminate\Database\Eloquent\Model> + */ use HasRelationsThroughMeta; /** @var \Corcel\Model */ @@ -43,13 +55,20 @@ public function setRelatedModel(Model $relatedModel): void $this->relatedModel = $relatedModel; } + /** + * @return HasMany<\Illuminate\Database\Eloquent\Model> + */ public function relatedObjects(): HasMany { return $this->hasManyThroughMeta(get_class($this->relatedModel), '_meta_key', 'foreign_key', 'local_key'); } }; - $model->setRelatedModel(new class() extends Model { + $model->setRelatedModel(new class() extends Model + { + /** + * @return HasMany<\Corcel\Model> + */ public function meta(): HasMany { return $this->hasMany(Model::class); diff --git a/tests/Unit/WooCommerceTest.php b/tests/Unit/WooCommerceTest.php index 389182f..a0544f1 100644 --- a/tests/Unit/WooCommerceTest.php +++ b/tests/Unit/WooCommerceTest.php @@ -1,4 +1,5 @@ define(Customer::class, function (Faker $faker) { - $name = $faker->firstName; +/** + * @extends Factory + */ +class CustomerFactory extends Factory +{ + protected $model = Customer::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + $name = $this->faker->firstName; - return [ - 'user_login' => Str::lower(Str::ascii($name)), - 'user_pass' => bcrypt('secret'), - 'user_nicename' => $name, - 'user_email' => $faker->email, - 'user_url' => $faker->url, - 'user_registered' => $faker->dateTime, - 'user_activation_key' => Str::random(10), - 'user_status' => 0, - 'display_name' => $name, - ]; -}); + return [ + 'user_login' => Str::lower(Str::ascii($name)), + 'user_pass' => bcrypt('secret'), + 'user_nicename' => $name, + 'user_email' => $this->faker->email, + 'user_url' => $this->faker->url, + 'user_registered' => $this->faker->dateTime, + 'user_activation_key' => Str::random(10), + 'user_status' => 0, + 'display_name' => $name, + ]; + } +} diff --git a/tests/database/factories/ItemFactory.php b/tests/database/factories/ItemFactory.php index 5841b7d..aa3d446 100644 --- a/tests/database/factories/ItemFactory.php +++ b/tests/database/factories/ItemFactory.php @@ -1,15 +1,30 @@ define(Item::class, function (Faker $faker) { - return [ - 'order_item_name' => $faker->words(mt_rand(2, 4), true), - 'order_item_type' => $faker->randomElement(['line_item', 'tax', 'coupon']), - 'order_id' => $faker->numberBetween(1, 10000), - ]; -}); +use Illuminate\Database\Eloquent\Factories\Factory; + +/** + * @extends Factory + */ +class ItemFactory extends Factory +{ + protected $model = Item::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ + 'order_item_name' => $this->faker->words(mt_rand(2, 4), true), + 'order_item_type' => $this->faker->randomElement(['line_item', 'tax', 'coupon']), + 'order_id' => $this->faker->numberBetween(1, 10000), + ]; + } +} diff --git a/tests/database/factories/OrderFactory.php b/tests/database/factories/OrderFactory.php index 42fe82f..552ce43 100644 --- a/tests/database/factories/OrderFactory.php +++ b/tests/database/factories/OrderFactory.php @@ -1,100 +1,155 @@ define(Order::class, function (Faker $faker) { - $createdAt = DateTimeImmutable::createFromMutable($faker->dateTime('now', 'Europe/Warsaw')); - $createdAtGMT = $createdAt->setTimezone(new DateTimeZone('UTC')); +/** + * @extends Factory + */ +class OrderFactory extends Factory +{ + protected $model = Order::class; - return [ - 'post_author' => $faker->numberBetween(1, 100), - 'post_date' => $createdAt->format('Y-m-d H:i:s'), - 'post_date_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), - 'post_content' => '', - 'post_title' => sprintf('Order – %s', $createdAt->format('F j, Y @ h:i A')), - 'post_excerpt' => '', - 'post_status' => 'wc-completed', - 'comment_status' => 'closed', - 'ping_status' => 'closed', - 'post_password' => '', - 'post_name' => '', - 'to_ping' => '', - 'pinged' => '', - 'post_modified' => $createdAt->format('Y-m-d H:i:s'), - 'post_modified_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), - 'post_content_filtered' => '', - 'post_parent' => 0, - 'guid' => 'http://woocommerce.example/?post_type=shop_order&p=1', - 'menu_order' => 0, - 'post_type' => 'shop_order', - 'post_mime_type' => '', - 'comment_count' => 0, - ]; -}); + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + $createdAt = DateTimeImmutable::createFromMutable($this->faker->dateTime('now', 'Europe/Warsaw')); + $createdAtGMT = $createdAt->setTimezone(new DateTimeZone('UTC')); -$factory->state(Order::class, 'pending', [ - 'post_status' => 'wc-pending', -]); + return [ + 'post_author' => $this->faker->numberBetween(1, 100), + 'post_date' => $createdAt->format('Y-m-d H:i:s'), + 'post_date_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), + 'post_content' => '', + 'post_title' => sprintf('Order – %s', $createdAt->format('F j, Y @ h:i A')), + 'post_excerpt' => '', + 'post_status' => 'wc-completed', + 'comment_status' => 'closed', + 'ping_status' => 'closed', + 'post_password' => '', + 'post_name' => '', + 'to_ping' => '', + 'pinged' => '', + 'post_modified' => $createdAt->format('Y-m-d H:i:s'), + 'post_modified_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), + 'post_content_filtered' => '', + 'post_parent' => 0, + 'guid' => 'http://woocommerce.example/?post_type=shop_order&p=1', + 'menu_order' => 0, + 'post_type' => 'shop_order', + 'post_mime_type' => '', + 'comment_count' => 0, + ]; + } -$factory->state(Order::class, 'cancelled', [ - 'post_status' => 'wc-cancelled', -]); + /** + * Applies pending state to model. + * + * @return Factory + */ + public function pending(): Factory + { + return $this->state(fn () => ['post_status' => 'wc-pending']); + } -$factory->state(Order::class, 'refunded', [ - 'post_status' => 'wc-refunded', -]); + /** + * Applies cancelling state to model. + * + * @return Factory + */ + public function cancelled(): Factory + { + return $this->state(fn () => ['post_status' => 'wc-cancelled']); + } -$factory->state(Order::class, 'withMeta', []); -$factory->state(Order::class, 'withShipping', []); -$factory->state(Order::class, 'paid', []); + /** + * Applies refunded state to model. + * + * @return Factory + */ + public function refunded(): Factory + { + return $this->state(fn () => ['post_status' => 'wc-refunded']); + } -$factory->afterCreatingState(Order::class, 'withMeta', function (Order $order, Faker $faker) { - $order->createMeta([ - '_order_currency' => $faker->currencyCode, - '_order_total' => $faker->randomFloat(2, 0, 200), - '_order_tax' => $faker->randomFloat(2, 0, 200), - '_date_completed' => $faker->dateTime->format('Y-m-d H:i:s'), - '_billing_first_name' => $faker->firstName, - '_billing_last_name' => $faker->lastName, - '_billing_company' => $faker->optional()->company, - '_billing_address_1' => $faker->streetAddress, - '_billing_address_2' => $faker->optional()->secondaryAddress, - '_billing_city' => $faker->city, - '_billing_state' => $faker->state, - '_billing_postcode' => $faker->postcode, - '_billing_country' => $faker->country, - '_billing_email' => $faker->email, - '_billing_phone' => $faker->phoneNumber, - ]); -}); + /** + * Applies withMeta state to model. + * + * @return Factory + */ + public function withMeta(): Factory + { + return $this->afterCreating(function (Order $order) { + $order->createMeta([ + '_order_currency' => $this->faker->currencyCode, + '_order_total' => $this->faker->randomFloat(2, 0, 200), + '_order_tax' => $this->faker->randomFloat(2, 0, 200), + '_date_completed' => $this->faker->dateTime->format('Y-m-d H:i:s'), + '_billing_first_name' => $this->faker->firstName, + '_billing_last_name' => $this->faker->lastName, + '_billing_company' => $this->faker->optional()->company, + '_billing_address_1' => $this->faker->streetAddress, + '_billing_address_2' => $this->faker->optional()->secondaryAddress, + '_billing_city' => $this->faker->city, + '_billing_state' => $this->faker->state, + '_billing_postcode' => $this->faker->postcode, + '_billing_country' => $this->faker->country, + '_billing_email' => $this->faker->email, + '_billing_phone' => $this->faker->phoneNumber, + ]); + }); + } -$factory->afterCreatingState(Order::class, 'withShipping', function (Order $order, Faker $faker) { - $order->createMeta([ - '_order_shipping' => $faker->randomFloat(2, 0, 200), - '_order_shipping_tax' => $faker->randomFloat(2, 0, 200), - '_shipping_first_name' => $faker->firstName, - '_shipping_last_name' => $faker->lastName, - '_shipping_company' => $faker->optional()->company, - '_shipping_address_1' => $faker->streetAddress, - '_shipping_address_2' => $faker->optional()->secondaryAddress, - '_shipping_city' => $faker->city, - '_shipping_state' => $faker->state, - '_shipping_postcode' => $faker->postcode, - '_shipping_country' => $faker->country, - ]); -}); + /** + * Applies withShipping state to model. + * + * @return Factory + */ + public function withShipping(): Factory + { + return $this->afterCreating(function (Order $order) { + $order->createMeta([ + '_order_shipping' => $this->faker->randomFloat(2, 0, 200), + '_order_shipping_tax' => $this->faker->randomFloat(2, 0, 200), + '_shipping_first_name' => $this->faker->firstName, + '_shipping_last_name' => $this->faker->lastName, + '_shipping_company' => $this->faker->optional()->company, + '_shipping_address_1' => $this->faker->streetAddress, + '_shipping_address_2' => $this->faker->optional()->secondaryAddress, + '_shipping_city' => $this->faker->city, + '_shipping_state' => $this->faker->state, + '_shipping_postcode' => $this->faker->postcode, + '_shipping_country' => $this->faker->country, + ]); + }); + } -$factory->afterCreatingState(Order::class, 'paid', function (Order $order, Faker $faker) { - $paymentMethod = $faker->word; + /** + * Applies paid state to model. + * + * @return Factory + */ + public function paid(): Factory + { + return $this->afterCreating(function (Order $order) { + $paymentMethod = $this->faker->word; - $order->createMeta([ - '_date_paid' => $faker->dateTime->format('Y-m-d H:i:s'), - '_payment_method' => $paymentMethod, - '_payment_method_title' => ucfirst($paymentMethod), - '_transaction_id' => $faker->asciify('*******'), - ]); -}); + $order->createMeta([ + '_date_paid' => $this->faker->dateTime->format('Y-m-d H:i:s'), + '_payment_method' => $paymentMethod, + '_payment_method_title' => ucfirst($paymentMethod), + '_transaction_id' => $this->faker->asciify('*******'), + ]); + }); + } +} diff --git a/tests/database/factories/ProductFactory.php b/tests/database/factories/ProductFactory.php index 7906a54..8178360 100644 --- a/tests/database/factories/ProductFactory.php +++ b/tests/database/factories/ProductFactory.php @@ -1,39 +1,56 @@ define(Product::class, function (Faker $faker) { - $createdAt = DateTimeImmutable::createFromMutable($faker->dateTime('now', 'Europe/Warsaw')); - $createdAtGMT = $createdAt->setTimezone(new DateTimeZone('UTC')); - $name = $faker->sentence; +/** + * @extends Factory + */ +class ProductFactory extends Factory +{ + protected $model = Product::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + $createdAt = DateTimeImmutable::createFromMutable($this->faker->dateTime('now', 'Europe/Warsaw')); + $createdAtGMT = $createdAt->setTimezone(new DateTimeZone('UTC')); + $name = $this->faker->sentence; - return [ - 'post_author' => $faker->numberBetween(1, 100), - 'post_date' => $createdAt->format('Y-m-d H:i:s'), - 'post_date_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), - 'post_content' => $faker->paragraphs(mt_rand(1, 5), true), - 'post_title' => $name, - 'post_excerpt' => $faker->paragraph, - 'post_status' => 'publish', - 'comment_status' => 'open', - 'ping_status' => 'closed', - 'post_password' => '', - 'post_name' => Str::title($name), - 'to_ping' => '', - 'pinged' => '', - 'post_modified' => $createdAt->format('Y-m-d H:i:s'), - 'post_modified_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), - 'post_content_filtered' => '', - 'post_parent' => 0, - 'guid' => 'http://woocommerce.example/?post_type=product&p=1', - 'menu_order' => 0, - 'post_type' => 'product', - 'post_mime_type' => '', - 'comment_count' => 0, - ]; -}); + return [ + 'post_author' => $this->faker->numberBetween(1, 100), + 'post_date' => $createdAt->format('Y-m-d H:i:s'), + 'post_date_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), + 'post_content' => $this->faker->paragraphs(mt_rand(1, 5), true), + 'post_title' => $name, + 'post_excerpt' => $this->faker->paragraph, + 'post_status' => 'publish', + 'comment_status' => 'open', + 'ping_status' => 'closed', + 'post_password' => '', + 'post_name' => Str::title($name), + 'to_ping' => '', + 'pinged' => '', + 'post_modified' => $createdAt->format('Y-m-d H:i:s'), + 'post_modified_gmt' => $createdAtGMT->format('Y-m-d H:i:s'), + 'post_content_filtered' => '', + 'post_parent' => 0, + 'guid' => 'http://woocommerce.example/?post_type=product&p=1', + 'menu_order' => 0, + 'post_type' => 'product', + 'post_mime_type' => '', + 'comment_count' => 0, + ]; + } +} diff --git a/tests/database/migrations/2020_01_01_000000_create_options_table.php b/tests/database/migrations/2020_01_01_000000_create_options_table.php index cc44b17..184dd0b 100644 --- a/tests/database/migrations/2020_01_01_000000_create_options_table.php +++ b/tests/database/migrations/2020_01_01_000000_create_options_table.php @@ -1,4 +1,5 @@