Skip to content

Commit

Permalink
Merge branch '8.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammad-Alavi committed Dec 16, 2024
2 parents 933f9d1 + 0079ec6 commit 4cd122d
Show file tree
Hide file tree
Showing 127 changed files with 1,885 additions and 1,963 deletions.
543 changes: 275 additions & 268 deletions composer.lock

Large diffs are not rendered by default.

205 changes: 205 additions & 0 deletions config/apiato.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
<?php

return [
/*
|--------------------------------------------------------------------------
| Enable / Disable Hashed ID
|--------------------------------------------------------------------------
*/
'hash-id' => env('HASH_ID', true),

'api' => [
/*
|--------------------------------------------------------------------------
| API URL
|--------------------------------------------------------------------------
*/
'url' => env('API_URL', 'http://localhost'),

/*
|--------------------------------------------------------------------------
| API Prefix
|--------------------------------------------------------------------------
*/
'prefix' => env('API_PREFIX', '/'),

/*
|--------------------------------------------------------------------------
| API Version Prefix
|--------------------------------------------------------------------------
*/
'enable_version_prefix' => true,

/*
|--------------------------------------------------------------------------
| Access Token Expiration Time
|--------------------------------------------------------------------------
|
| In Minutes. Default to 1,440 minutes = 1 day
|
*/
'expires-in' => env('API_TOKEN_EXPIRES', 1440),

/*
|--------------------------------------------------------------------------
| Refresh Token Expiration Time
|--------------------------------------------------------------------------
|
| In Minutes. Default to 43,200 minutes = 30 days
|
*/
'refresh-expires-in' => env('API_REFRESH_TOKEN_EXPIRES', 43200),

/*
|--------------------------------------------------------------------------
| Enable Disable API Debugging
|--------------------------------------------------------------------------
|
| If enabled, the Error Exception trace will be injected in the JSON
| response, and it will be logged in the default Log file.
|
*/
'debug' => env('API_DEBUG', false),

/*
|--------------------------------------------------------------------------
| Enable/Disable Implicit Grant
|--------------------------------------------------------------------------
*/
'enabled-implicit-grant' => env('API_ENABLE_IMPLICIT_GRANT', true),

/*
|--------------------------------------------------------------------------
| Rate Limit (throttle)
|--------------------------------------------------------------------------
|
| Attempts per minutes.
| `attempts` is the number of attempts per `expires` in minutes.
|
*/
'throttle' => [
'enabled' => env('GLOBAL_API_RATE_LIMIT_ENABLED', true),
'attempts' => env('GLOBAL_API_RATE_LIMIT_ATTEMPTS_PER_MIN', '30'),
'expires' => env('GLOBAL_API_RATE_LIMIT_EXPIRES_IN_MIN', '1'),
],
],

'requests' => [
/*
|--------------------------------------------------------------------------
| Allow Roles to access all Routes
|--------------------------------------------------------------------------
|
| Define a list of roles that do not need to go through the "hasAccess"
| check in Requests. These roles automatically pass this check. This is
| useful, if you want to make all routes accessible for admin users.
|
| Usage: ['admin', 'editor']
| Default: []
|
*/
'allow-roles-to-access-all-routes' => [
env('ADMIN_ROLE', 'admin'),
],

/*
|--------------------------------------------------------------------------
| Force Request Header to Contain header
|--------------------------------------------------------------------------
|
| By default, users can send request without defining the accept header and
| setting it to [ accept = application/json ].
| To force the users to define that header, set this to true.
| When set to true, a PHP exception will be thrown preventing users from access
| When set to false, the header will contain a warning message.
|
*/
'force-accept-header' => false,

/*
|--------------------------------------------------------------------------
| Force Valid Request Include Parameters
|--------------------------------------------------------------------------
|
| By default, users can request to include additional resources into the
| response by using the ?include=... query parameter. The requested top-level
| resource also responds with all available includes. However, the user may
| still request an invalid (i.e., not available) include parameter. This flag
| determines, how to proceed in such a case:
| When set to true, a PHP Exception will be thrown (default)
| When set to false, this invalid include will be skipped
|
*/
'force-valid-includes' => true,

/*
|--------------------------------------------------------------------------
| Use ETags
|--------------------------------------------------------------------------
|
| This option appends an "ETag" HTTP Header to the Response. This ETag is a
| calculated hash of the content to be delivered.
| Clients can add an "If-None-Match" HTTP Header to the Request and submit
| an (old) ETag. These ETags are validated. If they match (are the same),
| an empty BODY with HTTP STATUS 304 (not modified) is returned!
|
*/
'use-etag' => false,

'params' => [
// TODO: BC: remove this after removing its usage in ResponseTrait in Core
'filter' => 'fieldset',
],

/*
|--------------------------------------------------------------------------
| Sparse Fieldsets
|--------------------------------------------------------------------------
|
| Sparse Fieldsets are a feature of the JSON API spec that allows clients to request only a subset of the
| attributes for a specific resource type. This can be useful for improving performance by reducing the amount
| of data that needs to be transferred over the network.
|
| @see https://jsonapi.org/format/#fetching-sparse-fieldsets
|
*/
'sparse_fieldsets' => [
// The name of key in the request to where we should look for the fields to return.
'request_key' => 'fields',
],
],

'seeders' => [
/*
|--------------------------------------------------------------------------
| Special seeders for apiato:seed-deploy & apiato:seed-test commands
|--------------------------------------------------------------------------
|
*/
'deployment' => null,
'testing' => null,
],

'tests' => [
/*
|--------------------------------------------------------------------------
| In order to be able to create testing user in your tests using test helpers, tests needs to know
| the name of the user model.This is working by default but if you are using another
| user model you should update this config.
| This user model MUST have a factory defined.
|--------------------------------------------------------------------------
|
*/
'user-class' => null,

/*
|--------------------------------------------------------------------------
| In order to be able to create admin testing user in your tests using test helpers, tests needs to know
| the name of the admin state in user factory. This is working by default but if you are using another
| user model or you have changed the default admin state name you should update this config.
|--------------------------------------------------------------------------
|
*/
'user-admin-state' => 'admin',
],
];
3 changes: 1 addition & 2 deletions src/Abstracts/Exceptions/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Apiato\Core\Abstracts\Exceptions;

use Exception as BaseException;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;

abstract class Exception extends BaseException
Expand All @@ -17,7 +16,7 @@ public function __construct(
\Throwable|null $previous = null,
) {
// Detect and set the running environment
$this->environment = Config::get('app.env');
$this->environment = config('app.env');

parent::__construct($this->prepareMessage($message), $this->prepareStatusCode($code), $previous);
}
Expand Down
3 changes: 1 addition & 2 deletions src/Abstracts/Notifications/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
namespace Apiato\Core\Abstracts\Notifications;

use Illuminate\Notifications\Notification as LaravelNotification;
use Illuminate\Support\Facades\Config;

abstract class Notification extends LaravelNotification
{
public function via($notifiable): array
{
return Config::get('notification.channels');
return config('notification.channels');
}
}
10 changes: 10 additions & 0 deletions src/Abstracts/Providers/EventServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@

namespace Apiato\Core\Abstracts\Providers;

use Apiato\Core\Foundation\Facades\Apiato;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as LaravelEventServiceProvider;

abstract class EventServiceProvider extends LaravelEventServiceProvider
{
public function shouldDiscoverEvents(): bool
{
return true;
}

protected function discoverEventsWithin(): array
{
return array_map(static fn (string $path) => $path . '/Listeners', Apiato::getAllContainerPaths());
}
}
38 changes: 24 additions & 14 deletions src/Abstracts/Repositories/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,45 @@

use Apiato\Core\Traits\CanEagerLoadTrait;
use Apiato\Core\Traits\HasRequestCriteriaTrait;
use Illuminate\Support\Facades\Request;
use Prettus\Repository\Contracts\CacheableInterface as PrettusCacheable;
use Prettus\Repository\Contracts\CacheableInterface;
use Prettus\Repository\Criteria\RequestCriteria;
use Prettus\Repository\Eloquent\BaseRepository as PrettusRepository;
use Prettus\Repository\Traits\CacheableRepository as PrettusCacheableRepository;
use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Traits\CacheableRepository;

abstract class Repository extends PrettusRepository implements PrettusCacheable
abstract class Repository extends BaseRepository implements CacheableInterface
{
use HasRequestCriteriaTrait;
use CanEagerLoadTrait;
use PrettusCacheableRepository {
PrettusCacheableRepository::paginate as cacheablePaginate;
use CacheableRepository {
CacheableRepository::paginate as cacheablePaginate;
}

// TODO: BC: set return type to void
/**
* Define the maximum number of entries per page that is returned.
* Set to 0 to "disable" this feature.
*/
protected int $maxPaginationLimit = 0;

protected bool|null $allowDisablePagination = null;

public function boot()
{
parent::boot();

$this->eagerLoadRequestedRelations();
if ($this->shouldEagerLoadIncludes()) {
$this->eagerLoadRequestedIncludes();
}
}

/**
* Define the maximum number of entries per page that is returned.
* Set to 0 to "disable" this feature.
* Enable or disable eager loading of relations requested by the client via "include" query parameter.
*/
protected int $maxPaginationLimit = 0;

protected bool|null $allowDisablePagination = null;
public function shouldEagerLoadIncludes(): bool
{
// TODO: BC: disable it by default for v8 and enable by default for v13
return false;
}

/**
* This function relies on strict conventions:
Expand Down Expand Up @@ -106,7 +116,7 @@ public function setPaginationLimit($limit): mixed
{
// the priority is for the function parameter, if not available then take
// it from the request if available and if not keep it null.
return $limit ?? Request::get('limit');
return $limit ?? request()?->input('limit');
}

public function wantsToSkipPagination(mixed $limit): bool
Expand Down
6 changes: 4 additions & 2 deletions src/Abstracts/Requests/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Illuminate\Foundation\Http\FormRequest as LaravelRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;

abstract class Request extends LaravelRequest
{
Expand Down Expand Up @@ -117,7 +116,7 @@ public function hasAccess(User|null $user = null): bool
$user = $user ?: $this->user();

if ($user) {
$autoAccessRoles = Config::get('apiato.requests.allow-roles-to-access-all-routes');
$autoAccessRoles = config('apiato.requests.allow-roles-to-access-all-routes');
// there are some roles defined that will automatically grant access
if (!empty($autoAccessRoles)) {
$hasAutoAccessByRole = $user->hasAnyRole($autoAccessRoles);
Expand Down Expand Up @@ -173,6 +172,7 @@ protected function hasAnyRoleAccess($user): array
* Be sure you know what you do!
*
* @throws IncorrectIdException
* @throws \Throwable
*/
public function mapInput(array $fields): void
{
Expand Down Expand Up @@ -200,6 +200,7 @@ public function mapInput(array $fields): void
* @param null $keys
*
* @throws IncorrectIdException
* @throws \Throwable
*/
public function all($keys = null): array
{
Expand Down Expand Up @@ -233,6 +234,7 @@ protected function mergeUrlParametersWithRequestData(array $requestData): array
* This method mimics the $request->input() method but works on the "decoded" values.
*
* @throws IncorrectIdException
* @throws \Throwable
*/
public function getInputByKey($key = null, $default = null): mixed
{
Expand Down
2 changes: 0 additions & 2 deletions src/Abstracts/Tests/PhpUnit/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Apiato\Core\Traits\TestCaseTrait;
use Apiato\Core\Traits\TestTraits\PhpUnit\TestAssertionHelperTrait;
use Apiato\Core\Traits\TestTraits\PhpUnit\TestAuthHelperTrait;
use Apiato\Core\Traits\TestTraits\PhpUnit\TestDatabaseProfilerTrait;
use Apiato\Core\Traits\TestTraits\PhpUnit\TestRequestHelperTrait;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
Expand All @@ -21,7 +20,6 @@ abstract class TestCase extends LaravelTestCase
use TestAssertionHelperTrait;
use HashIdTrait;
use LazilyRefreshDatabase;
use TestDatabaseProfilerTrait;

/**
* The base URL to use while testing the application.
Expand Down
3 changes: 1 addition & 2 deletions src/Abstracts/Transformers/Transformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Apiato\Core\Exceptions\CoreInternalErrorException;
use Apiato\Core\Exceptions\UnsupportedFractalIncludeException;
use Illuminate\Support\Facades\Config;
use League\Fractal\Resource\Collection;
use League\Fractal\Resource\Item;
use League\Fractal\Resource\Primitive;
Expand Down Expand Up @@ -47,7 +46,7 @@ protected function callIncludeMethod(Scope $scope, $includeName, $data)
try {
return parent::callIncludeMethod($scope, $includeName, $data);
} catch (\ErrorException $exception) {
if (Config::get('apiato.requests.force-valid-includes', true)) {
if (config('apiato.requests.force-valid-includes', true)) {
throw new UnsupportedFractalIncludeException($exception->getMessage());
}
} catch (\Exception $exception) {
Expand Down
Loading

0 comments on commit 4cd122d

Please sign in to comment.