diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 99c0344e..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Tag a new seat-docker release -on: - release: - types: [released] - -jobs: - build: - name: Checkout and tag - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - repository: eveseat/seat-docker - ssh-key: '${{ secrets.SEAT_DOCKER_REPO }}' - - run: | - git config user.name github-actions - git config user.email github-actions@github.com - currver=`cat version` - a=(${currver//./ }) - newrelease=${a[2]} - newrelease=$((newrelease+1)) - newver="${a[0]}.${a[1]}.${newrelease}" - echo $newver > version - git add version - git commit -m "bump to version $newver" - git push - git tag -a "$newver" -m "src: $GITHUB_REPOSITORY commit: ${GITHUB_SHA: -8}" - git push origin --tags - diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 074eb550..db73397f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,23 +2,25 @@ name: Unit Testing on: push: - branches: [ "master" ] + branches: [ "5.0.x" ] pull_request: - branches: [ "master" ] + branches: [ "5.0.x" ] permissions: contents: read jobs: - build: + tests: runs-on: ubuntu-latest strategy: fail-fast: true matrix: - php: [7.4] + php: [8.1, 8.2] + stability: [prefer-stable] + name: PHP ${{ matrix.php }} - ${{ matrix.stability }} steps: - uses: actions/checkout@v3 @@ -28,10 +30,24 @@ jobs: php-version: ${{ matrix.php }} extensions: curl, gmp, json, mbstring, openssl tools: composer:v2 - coverage: none + coverage: xdebug - name: Install dependencies - run: composer update --prefer-dist --no-interaction --no-progress + run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress - - name: Execute tests - run: vendor/bin/phpunit --verbose + - name: Download Codeclimate Tools + if: ${{ github.event_name != 'pull_request' }} + run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter && chmod +x ./cc-test-reporter + + - name: Init Codeclimate Tools + if: ${{ github.event_name != 'pull_request' }} + run: ./cc-test-reporter before-build + + - name: Run Tests + run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml + + - name: Publish code coverage + if: ${{ github.event_name != 'pull_request' }} + env: + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + run: ./cc-test-reporter after-build -t clover \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e09b7125..00000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: php -php: - - 7.3 -before_script: - - pecl install -o -f redis <<<"" - - COMPOSER_MEMORY_LIMIT=-1 composer update - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build -script: - - vendor/bin/phpunit -c phpunit.xml -after_script: - - ./cc-test-reporter after-build diff --git a/composer.json b/composer.json index 44d375b9..cd76a773 100644 --- a/composer.json +++ b/composer.json @@ -10,33 +10,40 @@ ], "autoload": { "psr-4": { - "Seat\\Services\\": "src/" + "Seat\\Services\\": "src/", + "Seat\\Services\\Database\\Seeders\\": "src/database/seeders/" }, "files": [ "src/Helpers/helpers.php" ] }, + "autoload-dev": { + "psr-4": { + "Seat\\Tests\\Services\\": "tests/" + } + }, "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": "^7.3", + "php": "^8.1", + "ext-dom": "*", "ext-gmp": "*", "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", "composer-runtime-api": "^2.0", - "coduo/php-humanizer": "^3.0", - "composer/semver": "^2.0", - "doctrine/dbal": "^2.9", - "guzzlehttp/guzzle": "^6.3", - "laravel/framework": "^6.2", - "web-token/jwt-easy": "^2.1", - "web-token/jwt-signature-algorithm-hmac": "^2.1", - "web-token/jwt-signature-algorithm-rsa": "^2.1", - "web-token/jwt-signature-algorithm-ecdsa": "^2.1" + "coduo/php-humanizer": "^4.0", + "composer/semver": "^3.0", + "doctrine/dbal": "^3.0", + "eveseat/eseye": "^3.1", + "guzzlehttp/guzzle": "^7.0", + "laravel/framework": "^10.0", + "psr/simple-cache": "^3.0", + "psr/log": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.0", + "orchestra/testbench": "^8.0" }, "extra": { "laravel": { diff --git a/phpunit.xml b/phpunit.xml index 72259af9..89ec3f3c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,17 +1,20 @@ - - - - ./src/ - - - - - ./tests/ReportParser - - + + + + + ./tests/ReportParser + + + ./tests/InjectedRelations + + + ./tests/CleanCCPHtml + + + + + ./src/ + + diff --git a/src/AbstractSeatPlugin.php b/src/AbstractSeatPlugin.php index d430d10e..a6c205c5 100644 --- a/src/AbstractSeatPlugin.php +++ b/src/AbstractSeatPlugin.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +37,7 @@ abstract class AbstractSeatPlugin extends ServiceProvider * Return an URI to a CHANGELOG.md file or an API path which will be providing changelog history. * * @example https://raw.githubusercontent.com/eveseat/seat/master/LICENSE + * * @exemple https://api.github.com/repos/eveseat/web/releases * * @return string|null @@ -146,10 +147,8 @@ abstract public function getPackagistVendorName(): string; * Return the plugin installed version. * * @return string - * - * @deprecated This method will be non longer overridable in the future. */ - public function getVersion(): string + final public function getVersion(): string { $name = sprintf('%s/%s', $this->getPackagistVendorName(), $this->getPackagistPackageName()); @@ -201,7 +200,7 @@ final public function registerPermissions(string $permissions_path, string $scop final public function registerApiAnnotationsPath($paths) { // ensure current annotation setting is an array of path or transform into it - $current_annotations = config('l5-swagger.paths.annotations', []); + $current_annotations = config('l5-swagger.documentations.default.paths.annotations', []); if (! is_array($current_annotations)) $current_annotations = [$current_annotations]; @@ -211,7 +210,7 @@ final public function registerApiAnnotationsPath($paths) // merge paths together and update config config([ - 'l5-swagger.paths.annotations' => array_unique(array_merge($current_annotations, $paths)), + 'l5-swagger.documentations.default.paths.annotations' => array_unique(array_merge($current_annotations, $paths)), ]); } @@ -231,4 +230,22 @@ final public function registerSdeTables($tables) 'seat.sde.tables' => array_unique(array_merge($current_tables, $tables)), ]); } + + /** + * Register database seeders in the stack. + * + * @param string|array $classes + * @return void + */ + final public function registerDatabaseSeeders(string|array $classes) + { + $current_seeders = config('seat.seeders', []); + + if (! is_array($classes)) + $classes = [$classes]; + + config([ + 'seat.seeders' => array_unique(array_merge($current_seeders, $classes)), + ]); + } } diff --git a/src/Commands/Seat/Admin/Email.php b/src/Commands/Seat/Admin/Email.php index bd032968..67dbb761 100644 --- a/src/Commands/Seat/Admin/Email.php +++ b/src/Commands/Seat/Admin/Email.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Commands/Seat/Version.php b/src/Commands/Seat/Version.php index 9b05c72b..996f5d57 100644 --- a/src/Commands/Seat/Version.php +++ b/src/Commands/Seat/Version.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Config/services.config.php b/src/Config/services.config.php index a4f02b1e..1a9082e7 100644 --- a/src/Config/services.config.php +++ b/src/Config/services.config.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Contracts/EsiClient.php b/src/Contracts/EsiClient.php new file mode 100644 index 00000000..815473d6 --- /dev/null +++ b/src/Contracts/EsiClient.php @@ -0,0 +1,104 @@ + null, // Hit Type // Event Values - 'ec' => null, // Event Category - 'ea' => null, // Event Action - 'el' => null, // Event Label - 'ev' => null, // Event Value + 'ec' => null, // Event Category + 'ea' => null, // Event Action + 'el' => null, // Event Label + 'ev' => null, // Event Value // Exception Values - 'exd' => null, // Exception Description - 'exf' => null, // Is Fatal Exception? + 'exd' => null, // Exception Description + 'exf' => null, // Is Fatal Exception? ]; /** * @param mixed $offset * @return bool */ - public function offsetExists($offset) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->data); @@ -67,7 +67,7 @@ public function offsetExists($offset) * @param mixed $offset * @return mixed */ - public function offsetGet($offset) + public function offsetGet(mixed $offset): mixed { return $this->data[$offset]; @@ -77,7 +77,7 @@ public function offsetGet($offset) * @param mixed $offset * @param mixed $value */ - public function offsetSet($offset, $value) + public function offsetSet(mixed $offset, mixed $value): void { $this->data[$offset] = $value; @@ -86,14 +86,14 @@ public function offsetSet($offset, $value) /** * @param mixed $offset */ - public function offsetUnset($offset) + public function offsetUnset(mixed $offset): void { unset($this->data[$offset]); } /** - * @param $key + * @param $key * @return mixed */ public function __get($key) @@ -103,8 +103,8 @@ public function __get($key) } /** - * @param $key - * @param $val + * @param $key + * @param $val */ public function __set($key, $val) { @@ -113,11 +113,11 @@ public function __set($key, $val) } /** - * @param $key - * @param $val + * @param $key + * @param $val * @return $this */ - public function set($key, $val) + public function set($key, $val): self { $this->__set($key, $val); diff --git a/src/Helpers/UserAgentBuilder.php b/src/Helpers/UserAgentBuilder.php new file mode 100644 index 00000000..9ce30b09 --- /dev/null +++ b/src/Helpers/UserAgentBuilder.php @@ -0,0 +1,179 @@ +product = $product; + + return $this; + } + + /** + * Set the version of the product. + * + * @param string $version + * @return $this + */ + public function version(string $version): UserAgentBuilder { + $this->version = $version; + + return $this; + } + + /** + * Configures the product and version of the user agent for a seat plugin. + * + * @param string|AbstractSeatPlugin $plugin A plugin service provider instance or the FCQN of the service provider (e.g. MyServiceProvider::class) + * @return $this + */ + public function seatPlugin(string|AbstractSeatPlugin $plugin): UserAgentBuilder { + if(is_string($plugin)){ + $plugin = new $plugin(null); + } + + $this->packagist($plugin->getPackagistVendorName(), $plugin->getPackagistPackageName()); + + return $this; + } + + /** + * Configures the product and version of the user agent for a packagist package. + * + * @param string $vendor The packagist vendor name + * @param string $package The packagist package name + * @return $this + */ + public function packagist(string $vendor, string $package): UserAgentBuilder { + $this->product = sprintf('%s:%s', $vendor, $package); + $this->version = $this->getPackageVersion($vendor, $package); + + return $this; + } + + /** + * Adds a comment containing the product and version of the user agent for a seat plugin. + * + * @param string|AbstractSeatPlugin $plugin A plugin service provider instance or the FCQN of the service provider (e.g. MyServiceProvider::class) + * @return $this + */ + public function commentSeatPlugin(string|AbstractSeatPlugin $plugin): UserAgentBuilder { + if(is_string($plugin)){ + $plugin = new $plugin(null); + } + + $this->commentPackagist($plugin->getPackagistVendorName(), $plugin->getPackagistPackageName()); + + return $this; + } + + /** + * Adds a comment containing the product and version of the user agent for a packagist package. + * + * @param string $vendor The packagist vendor name + * @param string $package The packagist package name + * @return $this + */ + public function commentPackagist(string $vendor, string $package): UserAgentBuilder { + $this->comment(sprintf('%s:%s/%s', $vendor, $package, $this->getPackageVersion($vendor, $package))); + + return $this; + } + + /** + * Add a comment to the user agent. + * + * @param string $comment the comment + * @return $this + */ + public function comment(string $comment): UserAgentBuilder { + $this->comments[] = $comment; + + return $this; + } + + /** + * Adds a reasonable set of default comments for any seat plugin. + * + * @return $this + * + * @throws SettingException + */ + public function defaultComments(): UserAgentBuilder { + $this->comment(sprintf('(admin contact: %s)', setting('admin_contact', true) ?? 'not specified')); + $this->comment('(https://github.com/eveseat/seat)'); + $this->commentPackagist('eveseat', 'seat'); + $this->commentPackagist('eveseat', 'web'); + $this->commentPackagist('eveseat', 'eveapi'); + + return $this; + } + + /** + * Assembles the user agent form its product, version, and comments into a string. + * + * @return string The user agent + */ + public function build(): string { + if($this->product === null || $this->version === null) { + throw new \Error('version or product not set.'); + } + + return sprintf('%s/%s %s', $this->product, $this->version, implode(' ', $this->comments)); + } + + /** + * Gets the installed version of a packagist package. + * + * @param string $vendor The packagist vendor name + * @param string $package The packagist package name + * @return string + */ + private function getPackageVersion(string $vendor, string $package): string { + try { + return InstalledVersions::getPrettyVersion(sprintf('%s/%s', $vendor, $package)) ?? 'unknown'; + } catch (OutOfBoundsException $e) { + return 'unknown'; + } + } +} diff --git a/src/Helpers/helpers.php b/src/Helpers/helpers.php index 83af546d..f02955d8 100644 --- a/src/Helpers/helpers.php +++ b/src/Helpers/helpers.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ function carbon($data = null) * Return the time difference from now in a * format that humans can read. * - * @param $time + * @param $time * @return string */ function human_diff($time) @@ -84,8 +84,8 @@ function img(string $type, string $variation, ?int $id, int $size, array $attr = /** * Return a formatted number. * - * @param $number - * @param $dec + * @param $number + * @param $dec * @return string * * @throws \Seat\Services\Exceptions\SettingException @@ -104,7 +104,7 @@ function number($number, $dec = 2) * Return a shortened number with a suffix. * Depends on php5-intl. * - * @param $number + * @param $number * @return bool|string */ function number_metric($number) @@ -125,6 +125,17 @@ function number_metric($number) */ function clean_ccp_html($html, $acceptable_tags = '
') { + if (empty($html)) + return ''; + + // CCP's rich text might be encapsulated in u''. Remove the u' + $html = preg_match("/u'(.*)'/", $html, $match) ? $match[1] : $html; + + // handle escaped UTF-8 data + // taken from https://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha + $html = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) { + return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UTF-16BE'); + }, $html); // Handle Unicode cases. $html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'); @@ -157,7 +168,7 @@ function clean_ccp_html($html, $acceptable_tags = '
') * Attempt to 'thread' evemails based on the separator * that is automatically added using the eve client. * - * @param $message + * @param $message * @return \Illuminate\Support\Collection */ function evemail_threads($message) @@ -171,11 +182,11 @@ function evemail_threads($message) // Message headers array. $headers = [ - 'subject' => null, - 'from' => null, - 'sent' => null, - 'to' => null, - 'message' => null, + 'subject' => null, + 'from' => null, + 'sent' => null, + 'to' => null, + 'message' => null, 'headers_ok' => false, ]; @@ -298,7 +309,7 @@ function number_roman($number) { $map = [ - 'M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90, 'L' => 50, + 'M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90, 'L' => 50, 'XL' => 40, 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1, ]; diff --git a/src/Image/Eve.php b/src/Image/Eve.php index 04df18d4..c3453f85 100644 --- a/src/Image/Eve.php +++ b/src/Image/Eve.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -136,7 +136,7 @@ public function __construct(string $type, string $variation, ?int $id, int $size * Attempt to detect the image type based on the * range in which an integer falls. * - * @param $id + * @param $id * @return string */ public function detect_type($id) @@ -213,7 +213,7 @@ public function html() } /** - * @param $size + * @param $size * @return string */ public function url($size) diff --git a/src/Socialite/EveOnline/Checker/Claim/NameChecker.php b/src/Items/EveType.php similarity index 56% rename from src/Socialite/EveOnline/Checker/Claim/NameChecker.php rename to src/Items/EveType.php index 8b009834..a23fcf48 100644 --- a/src/Socialite/EveOnline/Checker/Claim/NameChecker.php +++ b/src/Items/EveType.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,34 +20,34 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -namespace Seat\Services\Socialite\EveOnline\Checker\Claim; +namespace Seat\Services\Items; -use Jose\Component\Checker\ClaimChecker; -use Jose\Component\Checker\InvalidClaimException; +use Seat\Services\Contracts\HasTypeID; /** - * Class NameChecker. - * - * @package Seat\Services\Socialite\EveOnline\Checker\Claim + * A basic implementation of HasTypeID. */ -class NameChecker implements ClaimChecker +class EveType implements HasTypeID { - private const NAME = 'name'; + protected int $type_id; /** - * {@inheritdoc} + * @param int|HasTypeID $type_id */ - public function checkClaim($value): void + public function __construct(int|HasTypeID $type_id) { - if (! is_string($value)) - throw new InvalidClaimException('"name" must be a string.', self::NAME, $value); + if($type_id instanceof HasTypeID){ + $type_id = $type_id->getTypeID(); + } + + $this->type_id = $type_id; } /** - * {@inheritdoc} + * @return int The type id */ - public function supportedClaim(): string + public function getTypeID(): int { - return self::NAME; + return $this->type_id; } } diff --git a/src/Items/EveTypeWithAmount.php b/src/Items/EveTypeWithAmount.php new file mode 100644 index 00000000..a8b4a37b --- /dev/null +++ b/src/Items/EveTypeWithAmount.php @@ -0,0 +1,52 @@ +amount = $amount; + } + + /** + * @return int The amount of items + */ + public function getAmount(): int + { + return $this->amount; + } +} diff --git a/src/Items/PriceableEveType.php b/src/Items/PriceableEveType.php new file mode 100644 index 00000000..6d00de93 --- /dev/null +++ b/src/Items/PriceableEveType.php @@ -0,0 +1,61 @@ +price = 0; + } + + /** + * @return float The price of this item stack + */ + public function getPrice(): float + { + return $this->price; + } + + /** + * @param float $price The new price of this item stack + * @return void + */ + public function setPrice(float $price): void + { + $this->price = $price; + } +} diff --git a/src/Jobs/Analytics.php b/src/Jobs/Analytics.php index df3bdcfd..6ce5db55 100644 --- a/src/Jobs/Analytics.php +++ b/src/Jobs/Analytics.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -157,7 +157,7 @@ private function send($type, array $query) $client = new Client([ 'base_uri' => 'https://www.google-analytics.com/', - 'timeout' => 5.0, + 'timeout' => 5.0, ]); // Check if we are in debug mode @@ -172,17 +172,17 @@ private function send($type, array $query) // Required Fields // https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#required - 'v' => 1, // Protocol Version + 'v' => 1, // Protocol Version 'tid' => $this->tracking_id, // Google Tracking-ID 'cid' => $this->getClientID(), // Unique Client-ID - 't' => $type, // Event + 't' => $type, // Event // Optional Fields 'aip' => 1, // Anonymize the IP of the calling client - 'an' => 'SeAT', // App Name + 'an' => 'SeAT', // App Name // Versions of the currently installed packages. - 'av' => $versions->implode(', '), + 'av' => $versions->implode(', '), // User Agent is comprised of OS Name(s), Release(r) // and Machine Type(m). Examples: @@ -191,7 +191,7 @@ private function send($type, array $query) // // See: // http://php.net/manual/en/function.php-uname.php - 'ua' => 'SeAT/' . php_uname('s') . + 'ua' => 'SeAT/' . php_uname('s') . '/' . php_uname('r') . '/' . php_uname('m'), diff --git a/src/Listeners/RunDeferredMigrations.php b/src/Listeners/RunDeferredMigrations.php new file mode 100644 index 00000000..a4b2467f --- /dev/null +++ b/src/Listeners/RunDeferredMigrations.php @@ -0,0 +1,39 @@ +make(DeferredMigrationRegistry::class); + + $registry->runMigrations(); + } +} diff --git a/src/Models/ExtensibleModel.php b/src/Models/ExtensibleModel.php new file mode 100644 index 00000000..4861a2a8 --- /dev/null +++ b/src/Models/ExtensibleModel.php @@ -0,0 +1,127 @@ +make(InjectedRelationRegistry::class); + $extension_class = $extension_registry->getExtensionClassFor($this::class, $key); + + // check if we have an injected relation + if($extension_class){ + // we have an injected relation + // since what we are doing is not intended, we have to roughly reimplement laravel's code from here on + + //check if relation data is cached + // the relation cache continues to work even for 'fake' relations, but we have to manually call it + if($this->relationLoaded($key)){ + return $this->getRelationValue($key); + } + + // it is NOT cached, we have to load it and put it into the cache + // get relation from extension + $extension_class_instance = new $extension_class; + $relation = $extension_class_instance->$key($this); + + // the following code is taken from laravel's \Illuminate\Database\Eloquent\Concerns\HasAttributes::getRelationshipFromMethod + // check if we actually got a relation returned + if (! $relation instanceof Relation) { + if (is_null($relation)) { + throw new LogicException(sprintf( + '%s::%s must return a relationship instance, but "null" was returned. Was the "return" keyword used?', static::class, $key + )); + } + + throw new LogicException(sprintf( + '%s::%s must return a relationship instance.', static::class, $key + )); + } + + return tap($relation->getResults(), function ($results) use ($key) { + $this->setRelation($key, $results); + }); + } + + // use the default behaviour if no relation is injected + return parent::__get($key); + } + + /** + * Redirects calls to injected relations or behaves like a normal class. + * + * @param string $method + * @param $parameters + * @return mixed + * + * @throws BindingResolutionException + */ + public function __call($method, $parameters) + { + // fetch injected relations + $extension_registry = app()->make(InjectedRelationRegistry::class); + $extension_class = $extension_registry->getExtensionClassFor($this::class, $method); + + // check if we have an injected relation + if($extension_class) { + // return the injected relation + $extension_class_instance = new $extension_class; + + return $extension_class_instance->$method($this); + } + + // use the default behaviour if no relation is injected + return parent::__call($method, $parameters); + } + + /** + * Injects relations into this model. + * + * @param string $extension_class the class that provides the injected relations + * @return void + * + * @throws BindingResolutionException + * @throws InjectedRelationConflictException A conflict arises when trying to inject two relations with the same name into a target. + */ + public static function injectRelationsFrom(string $extension_class): void { + $registry = app()->make(InjectedRelationRegistry::class); + $registry->injectRelations(static::class, $extension_class); + } +} diff --git a/src/Models/GlobalSetting.php b/src/Models/GlobalSetting.php index 98a22efb..4f97e59b 100644 --- a/src/Models/GlobalSetting.php +++ b/src/Models/GlobalSetting.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,14 +22,12 @@ namespace Seat\Services\Models; -use Illuminate\Database\Eloquent\Model; - /** * Class GlobalSetting. * * @package Seat\Services\Models */ -class GlobalSetting extends Model +class GlobalSetting extends ExtensibleModel { /** * @var array diff --git a/src/Models/Note.php b/src/Models/Note.php index 5493ba6d..8086aac8 100644 --- a/src/Models/Note.php +++ b/src/Models/Note.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,14 +23,13 @@ namespace Seat\Services\Models; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Model; /** * Class Note. * * @package Seat\Services\Models */ -class Note extends Model +class Note extends ExtensibleModel { /** * @var array diff --git a/src/Models/Schedule.php b/src/Models/Schedule.php index 9efcd5eb..c76d3ca7 100644 --- a/src/Models/Schedule.php +++ b/src/Models/Schedule.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,14 +22,12 @@ namespace Seat\Services\Models; -use Illuminate\Database\Eloquent\Model; - /** * Class Schedule. * * @package Seat\Services\Models */ -class Schedule extends Model +class Schedule extends ExtensibleModel { /** * @var array diff --git a/src/Models/UserSetting.php b/src/Models/UserSetting.php index cdc4ddbf..d4c0c579 100644 --- a/src/Models/UserSetting.php +++ b/src/Models/UserSetting.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,14 +22,12 @@ namespace Seat\Services\Models; -use Illuminate\Database\Eloquent\Model; - /** * Class UserSetting. * * @package Seat\Services\Models */ -class UserSetting extends Model +class UserSetting extends ExtensibleModel { /** * @var array diff --git a/src/ReportParser/Elements/Element.php b/src/ReportParser/Elements/Element.php index 1cb209f3..e9c1b6bb 100644 --- a/src/ReportParser/Elements/Element.php +++ b/src/ReportParser/Elements/Element.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ public function __construct(array $fields) } /** - * @param $field + * @param $field */ public function add($field) { @@ -55,7 +55,7 @@ public function add($field) } /** - * @param $field + * @param $field */ public function remove($field) { @@ -81,7 +81,7 @@ public function isEmpty(): bool } /** - * @param $name + * @param $name * @return mixed * * @throws \ErrorException diff --git a/src/ReportParser/Elements/Group.php b/src/ReportParser/Elements/Group.php index dda728a1..253fc3e8 100644 --- a/src/ReportParser/Elements/Group.php +++ b/src/ReportParser/Elements/Group.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Exceptions/EmptyReportException.php b/src/ReportParser/Exceptions/EmptyReportException.php index 100c803f..58ec39b8 100644 --- a/src/ReportParser/Exceptions/EmptyReportException.php +++ b/src/ReportParser/Exceptions/EmptyReportException.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Exceptions/InvalidReportElementException.php b/src/ReportParser/Exceptions/InvalidReportElementException.php index 162e9686..93fae489 100644 --- a/src/ReportParser/Exceptions/InvalidReportElementException.php +++ b/src/ReportParser/Exceptions/InvalidReportElementException.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Exceptions/InvalidReportException.php b/src/ReportParser/Exceptions/InvalidReportException.php index 730525b5..2fde5129 100644 --- a/src/ReportParser/Exceptions/InvalidReportException.php +++ b/src/ReportParser/Exceptions/InvalidReportException.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Exceptions/InvalidReportGroupException.php b/src/ReportParser/Exceptions/InvalidReportGroupException.php index cd5f5407..6af50f9f 100644 --- a/src/ReportParser/Exceptions/InvalidReportGroupException.php +++ b/src/ReportParser/Exceptions/InvalidReportGroupException.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Exceptions/MissingReportGroupException.php b/src/ReportParser/Exceptions/MissingReportGroupException.php index 147681c2..89cbd8c5 100644 --- a/src/ReportParser/Exceptions/MissingReportGroupException.php +++ b/src/ReportParser/Exceptions/MissingReportGroupException.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Exceptions/MissingReportHeaderException.php b/src/ReportParser/Exceptions/MissingReportHeaderException.php index 5b2710f6..a7999e4e 100644 --- a/src/ReportParser/Exceptions/MissingReportHeaderException.php +++ b/src/ReportParser/Exceptions/MissingReportHeaderException.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/Parsers/MoonReport.php b/src/ReportParser/Parsers/MoonReport.php index 2f9826ce..f692e5de 100644 --- a/src/ReportParser/Parsers/MoonReport.php +++ b/src/ReportParser/Parsers/MoonReport.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/ReportParser/ReportParser.php b/src/ReportParser/ReportParser.php index 3fb61a96..017a097e 100644 --- a/src/ReportParser/ReportParser.php +++ b/src/ReportParser/ReportParser.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Seeding/AbstractScheduleSeeder.php b/src/Seeding/AbstractScheduleSeeder.php new file mode 100644 index 00000000..433c6a4b --- /dev/null +++ b/src/Seeding/AbstractScheduleSeeder.php @@ -0,0 +1,62 @@ +getSchedules(); + foreach ($schedules as $job) { + if (! DB::table('schedules')->where('command', $job['command'])->exists()) { + DB::table('schedules')->insert($job); + } + } + + // drop deprecated commands + DB::table('schedules')->whereIn('command', $this->getDeprecatedSchedules())->delete(); + } +} diff --git a/src/Services/DeferredMigrationRegistry.php b/src/Services/DeferredMigrationRegistry.php new file mode 100644 index 00000000..981c54dc --- /dev/null +++ b/src/Services/DeferredMigrationRegistry.php @@ -0,0 +1,45 @@ + + */ + protected array $deferred_migrations = []; + + public function schedule(Closure $migration): void { + $this->deferred_migrations[] = $migration; + } + + public function runMigrations(): void { + logger()->info(sprintf('[Deferred Migrations] Running %d deferred migrations', count($this->deferred_migrations))); + + foreach ($this->deferred_migrations as $migration){ + $migration(); + } + } +} diff --git a/src/Services/InjectedRelationRegistry.php b/src/Services/InjectedRelationRegistry.php new file mode 100644 index 00000000..2a5c6d9a --- /dev/null +++ b/src/Services/InjectedRelationRegistry.php @@ -0,0 +1,100 @@ + + */ + private array $relations = []; + + /** + * Injects all relations from a class into a model. + * + * @param string $target_model the model to inject relations into + * @param string $extension_class the class to take the relations from + * @return void + * + * @throws InjectedRelationConflictException A conflict arises when trying to inject two relations with the same name into a target. + */ + public function injectRelations(string $target_model, string $extension_class): void + { + $methods = get_class_methods($extension_class); + + foreach ($methods as $relation_name){ + $this->injectSingleRelation($target_model, $extension_class, $relation_name); + } + } + + /** + * Injects a single relation into a model. + * + * @param string $model the model to inject the relation into + * @param string $extension_class the class holding the relation function + * @param string $relation the name of the relation to be injected. The method providing the relation in $extension_class must have the same name, and the relation will be accessible under this name. + * @return void + * + * @throws InjectedRelationConflictException A conflict arises when trying to inject two relations with the same name into a target. + */ + public function injectSingleRelation(string $model, string $extension_class, string $relation): void + { + $key = $this->getInjectionTargetKey($model, $relation); + + // check for conflicts, as there can't be two relations with the same name + if(array_key_exists($key, $this->relations)) { + $conflict = $this->relations[$key]; + throw new InjectedRelationConflictException(sprintf('Relation \'%s\' from \'%s\' is name-conflicting with \'%s\'', $relation, $model, $conflict)); + } + + $this->relations[$key] = $extension_class; + } + + /** + * Searches for injected relations for a model. + * + * @param string $model the model to search for + * @param string $relation the relation name to search for + * @return string|null the class providing the injected relation, or null if there is no injected relation + */ + public function getExtensionClassFor(string $model, string $relation): ?string + { + return $this->relations[$this->getInjectionTargetKey($model, $relation)] ?? null; + } + + /** + * Generates a key for $this->$relations. + * + * @param string $model the injection target class + * @param string $relation_name the relation name + * @return string a key to use with $this->$relations + */ + private function getInjectionTargetKey(string $model, string $relation_name): string { + return sprintf('%s.%s', $model, $relation_name); + } +} diff --git a/src/ServicesServiceProvider.php b/src/ServicesServiceProvider.php index 4e9746f8..ed79a1b6 100644 --- a/src/ServicesServiceProvider.php +++ b/src/ServicesServiceProvider.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,9 +22,14 @@ namespace Seat\Services; +use Illuminate\Database\Events\MigrationsEnded; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Event; use Seat\Services\Commands\Seat\Admin\Email; use Seat\Services\Commands\Seat\Version; +use Seat\Services\Listeners\RunDeferredMigrations; +use Seat\Services\Services\DeferredMigrationRegistry; +use Seat\Services\Services\InjectedRelationRegistry; class ServicesServiceProvider extends AbstractSeatPlugin { @@ -75,6 +80,9 @@ public function boot() // Inform Laravel how to load migrations $this->add_migrations(); + + // add event listener + $this->add_event_listeners(); } /** @@ -87,6 +95,14 @@ public function register() $this->mergeConfigFrom( __DIR__ . '/Config/services.config.php', 'services.config'); + + $this->app->singleton(InjectedRelationRegistry::class, function () { + return new InjectedRelationRegistry(); + }); + + $this->app->singleton(DeferredMigrationRegistry::class, function () { + return new DeferredMigrationRegistry(); + }); } private function addCommands() @@ -97,6 +113,11 @@ private function addCommands() ]); } + private function add_event_listeners(): void + { + Event::listen(MigrationsEnded::class, RunDeferredMigrations::class); + } + /** * Set the path for migrations which should * be migrated by laravel. More informations: diff --git a/src/Settings/Profile.php b/src/Settings/Profile.php index 32b460c2..cf327298 100644 --- a/src/Settings/Profile.php +++ b/src/Settings/Profile.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,13 +38,10 @@ class Profile extends Settings */ public static $options = [ - 'sidebar' => ['sidebar-full', 'sidebar-collapse'], - 'skins' => [ - 'default', 'jet', - ], + 'sidebar' => ['sidebar-full', 'sidebar-collapse'], 'thousand_seperator' => [' ', ',', '.'], - 'decimal_seperator' => [',', '.'], - 'mail_threads' => ['yes', 'no'], + 'decimal_seperator' => [',', '.'], + 'mail_threads' => ['yes', 'no'], ]; /** @@ -61,30 +58,4 @@ class Profile extends Settings * @var string */ protected static $scope = 'user'; - - /** - * @var array - */ - protected static $defaults = [ - - // UI - 'sidebar' => 'sidebar-full', - 'skin' => 'skin-black', - 'language' => 'en', - 'mail_threads' => 'yes', - - // A groups main character_id - 'main_character_id' => 0, - - // Numbers - 'thousand_seperator' => ' ', - 'decimal_seperator' => '.', - - // Notifications - 'email_notifications' => 'no', - 'email_address' => '', - - // Multi factor authentication - 'require_mfa' => 'no', - ]; } diff --git a/src/Settings/Seat.php b/src/Settings/Seat.php index c4a5b5b5..182b874e 100644 --- a/src/Settings/Seat.php +++ b/src/Settings/Seat.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,12 +38,12 @@ class Seat extends Settings */ public static $options = [ - 'registration' => ['yes', 'no'], - 'force_min_mask' => ['yes', 'no'], - 'allow_sso' => ['yes', 'no'], - 'allow_tracking' => ['yes', 'no'], + 'registration' => ['yes', 'no'], + 'force_min_mask' => ['yes', 'no'], + 'allow_sso' => ['yes', 'no'], + 'allow_tracking' => ['yes', 'no'], 'require_activation' => ['yes', 'no'], - 'cleanup_data' => ['yes', 'no'], + 'cleanup_data' => ['yes', 'no'], ]; /** @@ -60,109 +60,4 @@ class Seat extends Settings * @var string */ protected static $scope = 'global'; - - /** - * @var array - */ - protected static $defaults = [ - - // User Registration - 'registration' => 'yes', - - // Admin contact - 'admin_contact' => 'seatadmin@localhost.local', - - // Cleanup data in the database for users - // that have been deleted. - 'cleanup_data' => 'no', - - // The number of workers to spawn. - 'queue_workers' => 4, - - // Allow Usage Tracking - 'allow_tracking' => 'yes', - - // Currently Installed SDE Version - 'installed_sde' => null, - - // API Updater Class Constraint. This value should - // be stored as a json string! - 'api_constraint' => '', - - // Require Email Activation - 'require_activation' => 'yes', - - // Default Scopes asked for SSO Authentication - 'sso_scopes' => [ - [ - 'id' => 0, - 'name' => 'default', - 'default' => true, - 'scopes' => [ - 'publicData', - 'esi-alliances.read_contacts.v1', - 'esi-assets.read_assets.v1', - 'esi-assets.read_corporation_assets.v1', - 'esi-bookmarks.read_character_bookmarks.v1', - 'esi-bookmarks.read_corporation_bookmarks.v1', - 'esi-calendar.read_calendar_events.v1', - 'esi-characters.read_agents_research.v1', - 'esi-characters.read_blueprints.v1', - 'esi-characters.read_chat_channels.v1', - 'esi-characters.read_contacts.v1', - 'esi-characters.read_corporation_roles.v1', - 'esi-characters.read_fatigue.v1', - 'esi-characters.read_fw_stats.v1', - 'esi-characters.read_loyalty.v1', - 'esi-characters.read_medals.v1', - 'esi-characters.read_notifications.v1', - 'esi-characters.read_opportunities.v1', - 'esi-characters.read_standings.v1', - 'esi-characters.read_titles.v1', - 'esi-characterstats.read.v1', - 'esi-clones.read_clones.v1', - 'esi-clones.read_implants.v1', - 'esi-contracts.read_character_contracts.v1', - 'esi-contracts.read_corporation_contracts.v1', - 'esi-corporations.read_blueprints.v1', - 'esi-corporations.read_contacts.v1', - 'esi-corporations.read_container_logs.v1', - 'esi-corporations.read_corporation_membership.v1', - 'esi-corporations.read_divisions.v1', - 'esi-corporations.read_facilities.v1', - 'esi-corporations.read_fw_stats.v1', - 'esi-corporations.read_medals.v1', - 'esi-corporations.read_standings.v1', - 'esi-corporations.read_starbases.v1', - 'esi-corporations.read_structures.v1', - 'esi-corporations.read_titles.v1', - 'esi-corporations.track_members.v1', - 'esi-fittings.read_fittings.v1', - 'esi-fleets.read_fleet.v1', - 'esi-industry.read_character_jobs.v1', - 'esi-industry.read_character_mining.v1', - 'esi-industry.read_corporation_jobs.v1', - 'esi-industry.read_corporation_mining.v1', - 'esi-killmails.read_corporation_killmails.v1', - 'esi-killmails.read_killmails.v1', - 'esi-location.read_location.v1', - 'esi-location.read_online.v1', - 'esi-location.read_ship_type.v1', - 'esi-mail.read_mail.v1', - 'esi-markets.read_character_orders.v1', - 'esi-markets.read_corporation_orders.v1', - 'esi-markets.structure_markets.v1', - 'esi-planets.manage_planets.v1', - 'esi-planets.read_customs_offices.v1', - 'esi-search.search_structures.v1', - 'esi-skills.read_skillqueue.v1', - 'esi-skills.read_skills.v1', - 'esi-ui.open_window.v1', - 'esi-universe.read_structures.v1', - 'esi-wallet.read_character_wallet.v1', - 'esi-wallet.read_corporation_wallets.v1', - ], - ], - ], - ]; } diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index 9a32e8e2..e567811a 100644 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,6 +61,17 @@ abstract class Settings */ protected static $scope = 'global'; + /** + * Register new setting with its default value. + * + * @param string $name + * @param mixed $value + */ + public static function define(string $name, $value) + { + static::$defaults[$name] = $value; + } + /** * Retrieve a setting by name. * @@ -106,8 +117,8 @@ public static function get($name, $for_id = null) /** * Determine the unique prefix for the key by name. * - * @param $name - * @param $for_id + * @param $name + * @param $for_id * @return string * * @throws \Seat\Services\Exceptions\SettingException @@ -135,7 +146,7 @@ public static function get_key_prefix($name, $for_id = null) * dont have an already logged in session, well then * we make the $for_id null. * - * @param $for_id + * @param $for_id * @return int|null */ public static function get_affected_id($for_id) @@ -182,7 +193,7 @@ public static function set($name, $value, $for_id = null) $db = new static::$model; $db->fill([ - 'name' => $name, + 'name' => $name, 'value' => $encoded_value, ]); diff --git a/src/Socialite/EveOnline/Checker/Claim/AzpChecker.php b/src/Socialite/EveOnline/Checker/Claim/AzpChecker.php deleted file mode 100644 index 1d543237..00000000 --- a/src/Socialite/EveOnline/Checker/Claim/AzpChecker.php +++ /dev/null @@ -1,71 +0,0 @@ -client_id = $client_id; - } - - /** - * {@inheritdoc} - */ - public function checkClaim($value): void - { - if (! is_string($value)) - throw new InvalidClaimException('"azp" must be a string.', self::NAME, $value); - - if ($value !== $this->client_id) - throw new InvalidClaimException('"azp" must match the originating application.', self::NAME, $value); - } - - /** - * {@inheritdoc} - */ - public function supportedClaim(): string - { - return self::NAME; - } -} diff --git a/src/Socialite/EveOnline/Checker/Claim/ScpChecker.php b/src/Socialite/EveOnline/Checker/Claim/ScpChecker.php deleted file mode 100644 index 1deabb9e..00000000 --- a/src/Socialite/EveOnline/Checker/Claim/ScpChecker.php +++ /dev/null @@ -1,74 +0,0 @@ -scopes = $scopes; - } - - /** - * {@inheritdoc} - */ - public function checkClaim($value): void - { - if (! is_array($value) && ! is_string($value)) - throw new InvalidClaimException('"scp" must be an array of scopes.', self::NAME, $value); - - if (! is_array($value)) - $value = [$value]; - - if (! empty(array_diff($this->scopes, $value))) - throw new InvalidClaimException('"scp" contains scopes which does not match requested ones or miss some requested scopes.', self::NAME, $value); - } - - /** - * {@inheritdoc} - */ - public function supportedClaim(): string - { - return self::NAME; - } -} diff --git a/src/Socialite/EveOnline/Checker/Claim/SubEveCharacterChecker.php b/src/Socialite/EveOnline/Checker/Claim/SubEveCharacterChecker.php deleted file mode 100644 index 3a74b75d..00000000 --- a/src/Socialite/EveOnline/Checker/Claim/SubEveCharacterChecker.php +++ /dev/null @@ -1,56 +0,0 @@ -supported_types = $supported_types; - $this->protected_header = $protected_header; - } - - /** - * {@inheritdoc} - */ - public function checkHeader($value): void - { - if (! is_string($value)) - throw new InvalidHeaderException('"typ" must be a string.', self::HEADER_NAME, $value); - - if (! in_array($value, $this->supported_types, true)) - throw new InvalidHeaderException('Unsupported type.', self::HEADER_NAME, $value); - } - - /** - * {@inheritdoc} - */ - public function supportedHeader(): string - { - return self::HEADER_NAME; - } - - /** - * {@inheritdoc} - */ - public function protectedHeaderOnly(): bool - { - return $this->protected_header; - } -} diff --git a/src/Socialite/EveOnline/EveOnlineExtendSocialite.php b/src/Socialite/EveOnline/EveOnlineExtendSocialite.php index 1d1612fe..15cbeb73 100644 --- a/src/Socialite/EveOnline/EveOnlineExtendSocialite.php +++ b/src/Socialite/EveOnline/EveOnlineExtendSocialite.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Socialite/EveOnline/Provider.php b/src/Socialite/EveOnline/Provider.php index dba08693..b32a33f6 100644 --- a/src/Socialite/EveOnline/Provider.php +++ b/src/Socialite/EveOnline/Provider.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,16 +22,11 @@ namespace Seat\Services\Socialite\EveOnline; -use Jose\Component\Core\JWKSet; -use Jose\Easy\Load; +use GuzzleHttp\Client; +use Seat\Eseye\Checker\EsiTokenValidator; +use Seat\Eseye\Configuration; use Seat\Services\Exceptions\EveImageException; use Seat\Services\Image\Eve; -use Seat\Services\Socialite\EveOnline\Checker\Claim\AzpChecker; -use Seat\Services\Socialite\EveOnline\Checker\Claim\NameChecker; -use Seat\Services\Socialite\EveOnline\Checker\Claim\OwnerChecker; -use Seat\Services\Socialite\EveOnline\Checker\Claim\ScpChecker; -use Seat\Services\Socialite\EveOnline\Checker\Claim\SubEveCharacterChecker; -use Seat\Services\Socialite\EveOnline\Checker\Header\TypeChecker; use SocialiteProviders\Manager\OAuth2\AbstractProvider; use SocialiteProviders\Manager\OAuth2\User; @@ -99,13 +94,13 @@ protected function mapUserToObject(array $user) } return (new User)->setRaw($user)->map([ - 'id' => $character_id, - 'name' => $user['name'], - 'nickname' => $user['name'], + 'id' => $character_id, + 'name' => $user['name'], + 'nickname' => $user['name'], 'character_owner_hash' => $user['owner'], - 'scopes' => is_array($user['scp']) ? $user['scp'] : [$user['scp']], - 'expires_on' => $user['exp'], - 'avatar' => $avatar, + 'scopes' => is_array($user['scp']) ? $user['scp'] : [$user['scp']], + 'expires_on' => $user['exp'], + 'avatar' => $avatar, ]); } @@ -117,65 +112,43 @@ protected function mapUserToObject(array $user) */ protected function getTokenFields($code) { - return array_merge(parent::getTokenFields($code), ['grant_type' => 'authorization_code']); - } - - /** - * @return string - */ - private function getJwkUri(): string - { - $response = $this->getHttpClient() - ->get('https://login.eveonline.com/.well-known/oauth-authorization-server'); - - $metadata = json_decode($response->getBody()); + $fields = [ + 'grant_type' => 'authorization_code', + 'code' => $code, + 'redirect_uri' => $this->redirectUrl, + ]; + + if ($this->usesPKCE()) { + $fields['code_verifier'] = $this->request->session()->pull('code_verifier'); + } - return $metadata->jwks_uri; + return $fields; } /** - * @return array An array representing the JWK Key Sets + * @param string $access_token + * @return array + * + * @throws \Exception */ - private function getJwkSets(): array + private function validateJwtToken(string $access_token): array { - $jwk_uri = $this->getJwkUri(); + $config = Configuration::getInstance(); + $config->http_client = Client::class; - $response = $this->getHttpClient() - ->get($jwk_uri); + $validator = new EsiTokenValidator(); - return json_decode($response->getBody(), true); + return $validator->validateToken(config('eseye.esi.auth.client_id'), $access_token); } /** - * @param string $access_token - * @return array - * - * @throws \Exception + * {@inheritDoc} */ - private function validateJwtToken(string $access_token): array + protected function getTokenHeaders($code) { - $scopes = session()->pull('scopes', []); - - // pulling JWK sets from CCP - $sets = $this->getJwkSets(); - - // loading JWK Sets Manager - $jwk_sets = JWKSet::createFromKeyData($sets); - - // attempt to parse the JWT and collect payload - $jws = Load::jws($access_token) - ->algs(['RS256', 'ES256', 'HS256']) - ->exp() - ->iss('login.eveonline.com') - ->header('typ', new TypeChecker(['JWT'], true)) - ->claim('scp', new ScpChecker($scopes)) - ->claim('sub', new SubEveCharacterChecker()) - ->claim('azp', new AzpChecker(config('esi.eseye_client_id'))) - ->claim('name', new NameChecker()) - ->claim('owner', new OwnerChecker()) - ->keyset($jwk_sets) - ->run(); - - return $jws->claims->all(); + return [ + 'Accept' => 'application/json', + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret), + ]; } } diff --git a/src/Traits/NotableTrait.php b/src/Traits/NotableTrait.php index c690c689..68c549be 100644 --- a/src/Traits/NotableTrait.php +++ b/src/Traits/NotableTrait.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,9 +46,9 @@ public static function addNote( return Note::create([ 'object_type' => __CLASS__, - 'object_id' => $object_id, - 'title' => $title, - 'note' => $note, + 'object_id' => $object_id, + 'title' => $title, + 'note' => $note, ]); } diff --git a/src/Traits/VersionsManagementTrait.php b/src/Traits/VersionsManagementTrait.php index 1886c1f0..92abc522 100644 --- a/src/Traits/VersionsManagementTrait.php +++ b/src/Traits/VersionsManagementTrait.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2015_10_30_140512_create_eve_notification_types_table.php b/src/database/migrations/2015_10_30_140512_create_eve_notification_types_table.php index 471cf8f2..2e6a7930 100644 --- a/src/database/migrations/2015_10_30_140512_create_eve_notification_types_table.php +++ b/src/database/migrations/2015_10_30_140512_create_eve_notification_types_table.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2015_11_28_053529_create_user_settings_table.php b/src/database/migrations/2015_11_28_053529_create_user_settings_table.php index 3389e2c1..f81de939 100644 --- a/src/database/migrations/2015_11_28_053529_create_user_settings_table.php +++ b/src/database/migrations/2015_11_28_053529_create_user_settings_table.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2015_11_28_071315_create_global_settings_table.php b/src/database/migrations/2015_11_28_071315_create_global_settings_table.php index df0aa8d6..ca14823a 100644 --- a/src/database/migrations/2015_11_28_071315_create_global_settings_table.php +++ b/src/database/migrations/2015_11_28_071315_create_global_settings_table.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2015_12_01_201414_create_schedules_table.php b/src/database/migrations/2015_12_01_201414_create_schedules_table.php index ba0e46e7..65f2e034 100644 --- a/src/database/migrations/2015_12_01_201414_create_schedules_table.php +++ b/src/database/migrations/2015_12_01_201414_create_schedules_table.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2016_11_19_065120_create_notes_table.php b/src/database/migrations/2016_11_19_065120_create_notes_table.php index c8bd6059..fe40014c 100644 --- a/src/database/migrations/2016_11_19_065120_create_notes_table.php +++ b/src/database/migrations/2016_11_19_065120_create_notes_table.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2016_11_29_195441_convert_value_from_string_to_text.php b/src/database/migrations/2016_11_29_195441_convert_value_from_string_to_text.php index 4ead3602..fa8532d3 100644 --- a/src/database/migrations/2016_11_29_195441_convert_value_from_string_to_text.php +++ b/src/database/migrations/2016_11_29_195441_convert_value_from_string_to_text.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2018_05_18_185619_move_settings_to_groups.php b/src/database/migrations/2018_05_18_185619_move_settings_to_groups.php index 1144e672..a8fe69ba 100644 --- a/src/database/migrations/2018_05_18_185619_move_settings_to_groups.php +++ b/src/database/migrations/2018_05_18_185619_move_settings_to_groups.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2018_09_12_181511_create_historical_prices_table.php b/src/database/migrations/2018_09_12_181511_create_historical_prices_table.php index 4ef3415d..3d23d508 100644 --- a/src/database/migrations/2018_09_12_181511_create_historical_prices_table.php +++ b/src/database/migrations/2018_09_12_181511_create_historical_prices_table.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2018_10_05_064533_alter_historical_prices_columns.php b/src/database/migrations/2018_10_05_064533_alter_historical_prices_columns.php index 90e8bc41..7503c6ee 100644 --- a/src/database/migrations/2018_10_05_064533_alter_historical_prices_columns.php +++ b/src/database/migrations/2018_10_05_064533_alter_historical_prices_columns.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2020_04_27_231132_convert_sso_scopes_to_list.php b/src/database/migrations/2020_04_27_231132_convert_sso_scopes_to_list.php index c0cb8ecf..7745f41a 100644 --- a/src/database/migrations/2020_04_27_231132_convert_sso_scopes_to_list.php +++ b/src/database/migrations/2020_04_27_231132_convert_sso_scopes_to_list.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,9 +42,9 @@ public function up() $new_sso_scopes = [ [ - 'id' => 0, - 'name' => 'default', - 'scopes' => json_decode($sso_scopes->value), + 'id' => 0, + 'name' => 'default', + 'scopes' => json_decode($sso_scopes->value), 'default' => true, ], ]; diff --git a/src/database/migrations/2020_05_10_101541_drop_historical_prices.php b/src/database/migrations/2020_05_10_101541_drop_historical_prices.php index 73e5ba9d..aa9f13a1 100644 --- a/src/database/migrations/2020_05_10_101541_drop_historical_prices.php +++ b/src/database/migrations/2020_05_10_101541_drop_historical_prices.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/migrations/2021_01_02_120325_convert_chinese_language_value.php b/src/database/migrations/2021_01_02_120325_convert_chinese_language_value.php index 4a984191..051ae616 100644 --- a/src/database/migrations/2021_01_02_120325_convert_chinese_language_value.php +++ b/src/database/migrations/2021_01_02_120325_convert_chinese_language_value.php @@ -3,7 +3,7 @@ /* * This file is part of SeAT * - * Copyright (C) 2015 to 2022 Leon Jacobs + * Copyright (C) 2015 to present Leon Jacobs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/database/seeders/PluginDatabaseSeeder.php b/src/database/seeders/PluginDatabaseSeeder.php new file mode 100644 index 00000000..45d39e74 --- /dev/null +++ b/src/database/seeders/PluginDatabaseSeeder.php @@ -0,0 +1,43 @@ +command->info('Running all unique registered seeders'); + $this->call(array_unique($seeders)); + $this->command->info('Registered seeders run complete'); + + } +} diff --git a/tests/CleanCCPHtml/CleanCCPHtmlTest.php b/tests/CleanCCPHtml/CleanCCPHtmlTest.php new file mode 100644 index 00000000..a6db93e1 --- /dev/null +++ b/tests/CleanCCPHtml/CleanCCPHtmlTest.php @@ -0,0 +1,25 @@ +assertEquals('test', clean_ccp_html("u'test'")); + } + + public function testWithoutEncapsulation() + { + $this->assertEquals('test', clean_ccp_html('test')); + // also test that the other feature continue to work + $this->assertEquals('test', clean_ccp_html('test')); + } + + public function testEscapedUnicodeDecoding() + { + $this->assertEquals('创 ä 😀', clean_ccp_html('\u521b รค ๐Ÿ˜€')); + } +} \ No newline at end of file diff --git a/tests/InjectedRelations/Extensions/ModelAExtension.php b/tests/InjectedRelations/Extensions/ModelAExtension.php new file mode 100644 index 00000000..49cb87de --- /dev/null +++ b/tests/InjectedRelations/Extensions/ModelAExtension.php @@ -0,0 +1,13 @@ +hasOne(ModelB::class); + } +} \ No newline at end of file diff --git a/tests/InjectedRelations/InjectedRelationsTest.php b/tests/InjectedRelations/InjectedRelationsTest.php new file mode 100644 index 00000000..e6ebf182 --- /dev/null +++ b/tests/InjectedRelations/InjectedRelationsTest.php @@ -0,0 +1,131 @@ +set('database.default', 'testbench'); + $app['config']->set('database.connections.testbench', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => '', + ]); + $app['config']->set('database.redis.client', 'mock'); + } + + /** + * @param \Illuminate\Foundation\Application $app + * @return array|string[] + */ + protected function getPackageProviders($app) + { + return [ + ServicesServiceProvider::class + ]; + } + + /** + * Define database migrations. + * + * @return void + */ + protected function defineDatabaseMigrations() + { + $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); + } + + /** + * Test if InjectedRelationRegistry works + * @throws \Seat\Services\Exceptions\InjectedRelationConflictException + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function testRegistry(){ + ModelA::injectRelationsFrom(ModelAExtension::class); + $registry = app()->make(InjectedRelationRegistry::class); + + $this->assertEquals(ModelAExtension::class,$registry->getExtensionClassFor(ModelA::class,'modelBInjected')); + $this->assertEquals(null,$registry->getExtensionClassFor(ModelA::class,'doesntexist')); + } + + /** + * Test if registering the same relation twice errors + * @throws \Illuminate\Contracts\Container\BindingResolutionException + * @throws \Seat\Services\Exceptions\InjectedRelationConflictException + */ + public function testInjectionConflict(){ + $this->expectException(InjectedRelationConflictException::class); + ModelA::injectRelationsFrom(ModelAExtension::class); + ModelA::injectRelationsFrom(ModelAExtension::class); + } + + /** + * Test if injected relations are working + * @return void + * @throws InjectedRelationConflictException + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function testInjectedRelations(){ + $a = ModelA::factory()->create(); + ModelB::factory() + ->for($a) + ->create(); + + ModelA::injectRelationsFrom(ModelAExtension::class); + + // factory might already trigger the cache, therefore make sure we have new models + $a = ModelA::first(); + $b = ModelB::first(); + + // ensure normal relations are still working + // b->a + $this->assertNotEquals(null, $b->modelA->id); + $this->assertEquals($a->id, $b->modelA->id); + // a->b + $this->assertNotEquals(null, $a->modelB->id); + $this->assertEquals($b->id, $a->modelB->id); + + //test injected relationship + // as attributes + $this->assertNotEquals(null, $a->modelBInjected->id); + $this->assertEquals($b->id, $a->modelBInjected->id); + // as function calls + $this->assertNotEquals(null, $a->modelBInjected()->first()->id); + $this->assertEquals($b->id, $a->modelBInjected()->first()->id); + } + + /** + * Test if eager loading with 'with' works + * @throws InjectedRelationConflictException + * @throws BindingResolutionException + */ + public function testEagerLoading(){ + $a = ModelA::factory()->create(); + $b = ModelB::factory() + ->for($a) + ->create(); + + ModelA::injectRelationsFrom(ModelAExtension::class); + + $result = ModelA::with("modelBInjected")->first(); + $loaded_relations = $result->getRelations(); + + $this->assertArrayHasKey('modelBInjected', $loaded_relations); + + $model_b = $loaded_relations['modelBInjected']; + $this->assertInstanceOf(ModelB::class, $model_b); + $this->assertEquals($model_b->id, $b->id); + } +} \ No newline at end of file diff --git a/tests/InjectedRelations/Models/ModelA.php b/tests/InjectedRelations/Models/ModelA.php new file mode 100644 index 00000000..ed2340d5 --- /dev/null +++ b/tests/InjectedRelations/Models/ModelA.php @@ -0,0 +1,31 @@ +hasOne(ModelB::class); + } +} \ No newline at end of file diff --git a/tests/InjectedRelations/Models/ModelB.php b/tests/InjectedRelations/Models/ModelB.php new file mode 100644 index 00000000..3bd19315 --- /dev/null +++ b/tests/InjectedRelations/Models/ModelB.php @@ -0,0 +1,31 @@ +belongsTo(ModelA::class); + } +} \ No newline at end of file diff --git a/tests/ReportParser/Elements/ElementTest.php b/tests/ReportParser/Elements/ElementTest.php index 39dc2621..6e92b526 100644 --- a/tests/ReportParser/Elements/ElementTest.php +++ b/tests/ReportParser/Elements/ElementTest.php @@ -1,5 +1,8 @@ ['/../../artifacts/moon_report.txt'], @@ -22,21 +24,21 @@ public function correctFormatProvider(): array ]; } - public function malformedElementsProvider(): array + public static function malformedElementsProvider(): array { return [ 'no elements' => ['/../../artifacts/moon_report_without_elements.txt'] ]; } - public function malformedGroupsProvider(): array + public static function malformedGroupsProvider(): array { return [ 'no groups' => ['/../../artifacts/moon_report_without_groups.txt'] ]; } - public function malformedHeaderProvider(): array + public static function malformedHeaderProvider(): array { return [ 'no header' => ['/../../artifacts/moon_report_without_header.txt'] diff --git a/tests/database/factories/ModelAFactory.php b/tests/database/factories/ModelAFactory.php new file mode 100644 index 00000000..7c70fddc --- /dev/null +++ b/tests/database/factories/ModelAFactory.php @@ -0,0 +1,44 @@ +ModelA::factory() + ]; + } +} diff --git a/src/Socialite/EveOnline/Checker/Claim/OwnerChecker.php b/tests/database/migrations/2023_07_27_053529_create_relation_injection_testing_models.php similarity index 56% rename from src/Socialite/EveOnline/Checker/Claim/OwnerChecker.php rename to tests/database/migrations/2023_07_27_053529_create_relation_injection_testing_models.php index 629235d2..fff9bb07 100644 --- a/src/Socialite/EveOnline/Checker/Claim/OwnerChecker.php +++ b/tests/database/migrations/2023_07_27_053529_create_relation_injection_testing_models.php @@ -20,34 +20,38 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -namespace Seat\Services\Socialite\EveOnline\Checker\Claim; +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; -use Jose\Component\Checker\ClaimChecker; -use Jose\Component\Checker\InvalidClaimException; -/** - * Class OwnerChecker. - * - * @package Seat\Services\Socialite\EveOnline\Checker\Claim - */ -class OwnerChecker implements ClaimChecker +class CreateRelationInjectionTestingModels extends Migration { - private const NAME = 'owner'; - /** - * {@inheritdoc} + * Run the migrations. + * + * @return void */ - public function checkClaim($value): void + public function up() { - if (! is_string($value)) - throw new InvalidClaimException('"owner" must be a string.', self::NAME, $value); + Schema::create('model_a', function (Blueprint $table) { + $table->increments('id'); + }); + + Schema::create('model_b', function (Blueprint $table) { + $table->increments('id'); + $table->integer('model_a_id')->unsigned(); + }); } /** - * {@inheritdoc} + * Reverse the migrations. + * + * @return void */ - public function supportedClaim(): string + public function down() { - return self::NAME; + + Schema::drop('model_a'); + Schema::drop('model_m'); } }