Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Implement PHPStan #596

Closed
wants to merge 16 commits into from
42 changes: 42 additions & 0 deletions .github/workflows/analyse.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: analyse

on:
push:
branches:
- master
- '*.x'
pull_request:

jobs:
analyse:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
php: [8.3]
stability: [prefer-stable]
include:
- laravel: 10.*
testbench: 8.*
- laravel: 11.*
testbench: 9.*

steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
token: ${{ secrets.RAPIDEZ_ACTIONS_ACCOUNT_PAT }}

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
coverage: none

- name: Install dependencies
run: |
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
composer update --${{ matrix.stability }} --prefer-dist --no-interaction
- name: Analyse
run: composer analyse
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
"tormjens/eventy": "^0.8"
},
"require-dev": {
"larastan/larastan": "^2.9",
"laravel/dusk": "^8.2",
"orchestra/testbench": "^9.4",
"orchestra/testbench-dusk": "^9.7",
"phpstan/phpstan": "^1.12",
"phpunit/phpunit": "^10.5.34|^11.3.5"
},
"autoload": {
Expand Down Expand Up @@ -61,6 +63,7 @@
}
},
"scripts": {
"analyse": "phpstan --memory-limit=256M",
"dusk:prepare": [
"./vendor/bin/dusk-updater detect --auto-update",
"@php -r \"file_exists('phpunit.dusk.xml') || copy('phpunit.dusk.xml.dist', 'phpunit.dusk.xml'); \""
Expand Down
1 change: 1 addition & 0 deletions config/rapidez/models.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
'category' => Rapidez\Core\Models\Category::class,
'category_product' => Rapidez\Core\Models\CategoryProduct::class,
'customer' => Rapidez\Core\Models\Customer::class,
'customer_group' => Rapidez\Core\Models\CustomerGroup::class,
'config' => Rapidez\Core\Models\Config::class,
'oauth_token' => Rapidez\Core\Models\OauthToken::class,
'option_swatch' => Rapidez\Core\Models\OptionSwatch::class,
Expand Down
11 changes: 11 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
includes:
- ./vendor/larastan/larastan/extension.neon

parameters:
paths:
- src/
- tests/
- routes/
ignoreErrors:
Jade-GG marked this conversation as resolved.
Show resolved Hide resolved
- '#^Result of static method TorMorten\\Eventy\\Events::#'
level: 1
16 changes: 12 additions & 4 deletions src/Actions/DecodeJwt.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Lcobucci\JWT\Validation\Constraint\SignedWith;
use Lcobucci\JWT\Validation\ConstraintViolation;
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
use Rapidez\Core\Exceptions\DecryptionException;

class DecodeJwt
{
Expand All @@ -25,11 +26,18 @@ public function __invoke(string $jwt): UnencryptedToken

public static function decode(string $jwt): UnencryptedToken
{
if ($jwt === '') {
throw new DecryptionException('JWT cannot be empty.');
}

foreach (static::getKeys() as $key) {
try {
/** @var \Lcobucci\JWT\Signer $signer */
$signer = new (config('rapidez.jwt.signed_with'));

return (new JwtFacade)->parse(
$jwt,
new SignedWith(new (config('rapidez.jwt.signed_with')), $key),
new SignedWith($signer, $key),
new LooseValidAt(new SystemClock(new DateTimeZone(date_default_timezone_get())))
);
} catch (RequiredConstraintsViolated $exception) {
Expand All @@ -39,11 +47,11 @@ public static function decode(string $jwt): UnencryptedToken
}
}

throw $exception;
throw $exception ?? new DecryptionException('No crypt key defined.');
}

/**
* @return Collection<Key>
* @return Collection<int, covariant Key>
*/
public static function getKeys(): Collection
{
Expand All @@ -55,6 +63,6 @@ public static function getKeys(): Collection

public static function isJwt(string $jwt): bool
{
return preg_match('/^(?:[\w-]*\.){2}[\w-]*$/', $jwt);
return boolval(preg_match('/^(?:[\w-]*\.){2}[\w-]*$/', $jwt));
}
}
4 changes: 3 additions & 1 deletion src/Auth/MagentoCustomerTokenGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Auth\TokenGuard;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Rapidez\Core\Models\Customer;

class MagentoCustomerTokenGuard extends TokenGuard implements Guard
{
Expand All @@ -30,6 +31,7 @@ public function user()
/**
* Validate a user's credentials.
*
* @param array<string, string> $credentials
* @return bool
*/
public function validate(array $credentials = [])
Expand All @@ -41,7 +43,7 @@ public function validate(array $credentials = [])
return (bool) $this->retrieveByToken($credentials[$this->inputKey]);
}

protected function retrieveByToken($token)
protected function retrieveByToken(string $token): ?Customer
{
return config('rapidez.models.customer')::whereToken($token)->first();
Jade-GG marked this conversation as resolved.
Show resolved Hide resolved
}
Expand Down
3 changes: 2 additions & 1 deletion src/Casts/Children.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

/** @implements CastsAttributes<object|array<int, object>, object|string> */
class Children implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
Expand All @@ -25,7 +26,7 @@ public function get($model, $key, $value, $attributes)
}
}

$child->images = isset($child->images) ? collect($child?->images)->sortBy('position')->pluck('value')->toArray() : [];
$child->images = isset($child->images) ? collect($child->images)->sortBy('position')->pluck('value')->toArray() : [];

unset($child->special_from_date, $child->special_to_date);
}
Expand Down
1 change: 1 addition & 0 deletions src/Casts/CommaSeparatedToArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

/** @implements CastsAttributes<array<int, string>, string> */
class CommaSeparatedToArray implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
Expand Down
1 change: 1 addition & 0 deletions src/Casts/CommaSeparatedToIntegerArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

/** @implements CastsAttributes<array<int, int>, string> */
class CommaSeparatedToIntegerArray implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
Expand Down
1 change: 1 addition & 0 deletions src/Casts/DecodeHtmlEntities.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

/** @implements CastsAttributes<string|null, string|null> */
class DecodeHtmlEntities implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
Expand Down
1 change: 1 addition & 0 deletions src/Casts/Multiselect.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

/** @implements CastsAttributes<array<int, \Rapidez\Core\Models\OptionValue>|float|int|string|false|null, string|null> */
class Multiselect implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
Expand Down
Empty file removed src/Casts/QuoteItems.php
Empty file.
30 changes: 29 additions & 1 deletion src/Commands/ElasticsearchIndexCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ abstract class ElasticsearchIndexCommand extends Command
{
public ElasticsearchIndexer $indexer;

/** @var array<string, mixed> */
public array $mapping = [];

/** @var array<string, mixed> */
public array $settings = [];

/** @var array<int, string> */
public array $synonymsFor = [];

public function __construct(ElasticsearchIndexer $indexer)
Expand All @@ -21,18 +26,32 @@ public function __construct(ElasticsearchIndexer $indexer)
$this->indexer = $indexer;
}

/**
* @param callable|iterable<int, object|null> $items
* @param callable|array<int, string>|null $dataFilter
*/
public function indexAllStores(string $indexName, callable|iterable $items, callable|array|null $dataFilter = null, callable|string $id = 'entity_id'): void
{
$this->indexStores(Rapidez::getStores(), $indexName, $items, $dataFilter, $id);
}

/**
* @param array<int, Store|array<string, mixed>> $stores
* @param callable|iterable<int, object|null> $items
* @param callable|array<int, string>|null $dataFilter
*/
public function indexStores(array $stores, string $indexName, callable|iterable $items, callable|array|null $dataFilter = null, callable|string $id = 'entity_id'): void
{
foreach ($stores as $store) {
$this->indexStore($store, $indexName, $items, $dataFilter, $id);
}
}

/**
* @param Store|array<string, mixed> $store
* @param callable|iterable<int, object|null> $items
* @param callable|array<int, string>|null $dataFilter
*/
public function indexStore(Store|array $store, string $indexName, callable|iterable $items, callable|array|null $dataFilter = null, callable|string $id = 'entity_id'): void
{
$storeName = $store['name'] ?? $store['code'] ?? reset($store);
Expand All @@ -49,13 +68,22 @@ public function indexStore(Store|array $store, string $indexName, callable|itera
}
}

/**
* @param Store|array<string, mixed> $store
* @param array<string, mixed> $mapping
* @param array<string, mixed> $settings
* @param array<int, string> $synonymsFor
*/
public function prepareIndexerWithStore(Store|array $store, string $indexName, array $mapping = [], array $settings = [], array $synonymsFor = []): void
{
Rapidez::setStore($store);
$this->indexer->prepare(config('rapidez.es_prefix') . '_' . $indexName . '_' . $store['store_id'], $mapping, $settings, $synonymsFor);
}

public function dataFrom(callable|iterable $items)
/**
* @param callable|iterable<int, object|null> $items
*/
public function dataFrom(callable|iterable $items): mixed
{
return value($items, config()->get('rapidez.store_code'));
}
Expand Down
24 changes: 22 additions & 2 deletions src/Commands/ElasticsearchIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ public function deleteIndex(string $index): void
$this->elasticsearch->indices()->delete(['index' => $index]);
}

public function index(iterable|object $data, callable|array|null $dataFilter, callable|string $id = 'entity_id'): void
/**
* @param iterable<int, object|null>|object|null $data
* @param callable|array<int, string>|null $dataFilter
*/
public function index(iterable|object|null $data, callable|array|null $dataFilter, callable|string $id = 'entity_id'): void
{
if (is_iterable($data)) {
$this->indexItems($data, $dataFilter, $id);
Expand All @@ -34,14 +38,21 @@ public function index(iterable|object $data, callable|array|null $dataFilter, ca
}
}

/**
* @param iterable<int, object|null> $items
* @param callable|array<int, string>|null $dataFilter
*/
public function indexItems(iterable $items, callable|array|null $dataFilter, callable|string $id = 'entity_id'): void
{
foreach ($items as $item) {
$this->indexItem($item, $dataFilter, $id);
}
}

public function indexItem(object $item, callable|array|null $dataFilter, callable|string $id = 'entity_id'): void
/**
* @param callable|array<int, string>|null $dataFilter
*/
public function indexItem(?object $item, callable|array|null $dataFilter, callable|string $id = 'entity_id'): void
{
if (is_null($item)) {
return;
Expand All @@ -68,6 +79,11 @@ public function indexItem(object $item, callable|array|null $dataFilter, callabl
IndexJob::dispatch($this->index, $currentId, $currentValues);
}

/**
* @param array<string, mixed> $mapping
* @param array<string, mixed> $settings
* @param array<int, string> $synonymsFor
*/
public function prepare(string $indexName, array $mapping = [], array $settings = [], array $synonymsFor = []): void
{
data_set($settings, 'index.analysis.analyzer.default', [
Expand Down Expand Up @@ -119,6 +135,10 @@ public function createAlias(string $indexName): void
$this->index = $this->alias . '_' . Carbon::now()->format('YmdHis');
}

/**
* @param array<string, mixed> $mapping
* @param array<string, mixed> $settings
*/
public function createIndex(string $index, array $mapping = [], array $settings = []): void
{
$this->elasticsearch->indices()->create([
Expand Down
14 changes: 10 additions & 4 deletions src/Commands/IndexCategoriesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rapidez\Core\Commands;

use Illuminate\Database\Eloquent\Collection;
use Rapidez\Core\Facades\Rapidez;
use TorMorten\Eventy\Facades\Eventy;

Expand All @@ -25,13 +26,18 @@ public function handle(): int
return 0;
}

public function getCategories()
/** @return Collection<int, \Rapidez\Core\Models\Category> */
public function getCategories(): Collection
{
return config('rapidez.models.category')::withEventyGlobalScopes('index.categories.scopes')
->select((new (config('rapidez.models.category')))->qualifyColumns(['entity_id', 'name', 'url_path']))
$categoryModel = config('rapidez.models.category');
/** @var \Rapidez\Core\Models\Category $categoryObject */
$categoryObject = new $categoryModel;

return $categoryModel::withEventyGlobalScopes('index.categories.scopes')
->select($categoryObject->qualifyColumns(['entity_id', 'name', 'url_path']))
->whereNotNull('url_key')
->whereNot('url_key', 'default-category')
->has('products')
->get() ?? [];
->get();
}
}
Loading
Loading