mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 06:56:05 +00:00
api action
This commit is contained in:
53
application/Espo/Core/Api/Action.php
Normal file
53
application/Espo/Core/Api/Action.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Api;
|
||||
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
|
||||
/**
|
||||
* A route action.
|
||||
*/
|
||||
interface Action
|
||||
{
|
||||
/**
|
||||
* Process.
|
||||
*
|
||||
* @param Request $request A request.
|
||||
* @param Response $response A response. Passed empty, to be written in the method.
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws NotFound
|
||||
* @throws Error
|
||||
*/
|
||||
public function process(Request $request, Response $response): void;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class ActionHandler implements RequestHandlerInterface
|
||||
|
||||
$this->afterProceed($responseWrapped);
|
||||
|
||||
return $responseWrapped->getResponse();
|
||||
return $responseWrapped->toPsr7();
|
||||
}
|
||||
|
||||
private function beforeProceed(): void
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace Espo\Core\Api;
|
||||
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Authentication\AuthenticationFactory;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\Log;
|
||||
use Espo\Core\ApplicationUser;
|
||||
@@ -44,10 +45,12 @@ use LogicException;
|
||||
|
||||
/**
|
||||
* Processes requests. Handles authentication. Obtains a controller name, action, body from a request.
|
||||
* Then passes them to the action processor.
|
||||
* Then passes them to the action processor or processes an action class.
|
||||
*/
|
||||
class RequestProcessor
|
||||
{
|
||||
private const DEFAULT_CONTENT_TYPE = 'application/json';
|
||||
|
||||
public function __construct(
|
||||
private AuthenticationFactory $authenticationFactory,
|
||||
private AuthBuilderFactory $authBuilderFactory,
|
||||
@@ -56,7 +59,8 @@ class RequestProcessor
|
||||
private Log $log,
|
||||
private ApplicationUser $applicationUser,
|
||||
private ControllerActionProcessor $actionProcessor,
|
||||
private MiddlewareProvider $middlewareProvider
|
||||
private MiddlewareProvider $middlewareProvider,
|
||||
private InjectableFactory $injectableFactory
|
||||
) {}
|
||||
|
||||
public function process(
|
||||
@@ -84,7 +88,7 @@ class RequestProcessor
|
||||
$processData->getRoute()->getAdjustedRoute()
|
||||
);
|
||||
|
||||
return $responseWrapped->getResponse();
|
||||
return $responseWrapped->toPsr7();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +113,7 @@ class RequestProcessor
|
||||
$authResult = $apiAuth->process($request, $response);
|
||||
|
||||
if (!$authResult->isResolved()) {
|
||||
return $response->getResponse();
|
||||
return $response->toPsr7();
|
||||
}
|
||||
|
||||
if ($authResult->isResolvedUseNoAuth()) {
|
||||
@@ -118,7 +122,7 @@ class RequestProcessor
|
||||
|
||||
ob_start();
|
||||
|
||||
$response = $this->proceed($processData, $psrRequest, $response);
|
||||
$response = $this->processAfterAuth($processData, $psrRequest, $request, $response);
|
||||
|
||||
ob_clean();
|
||||
|
||||
@@ -128,12 +132,19 @@ class RequestProcessor
|
||||
/**
|
||||
* @throws BadRequest
|
||||
*/
|
||||
private function proceed(
|
||||
private function processAfterAuth(
|
||||
ProcessData $processData,
|
||||
Psr7Request $request,
|
||||
RequestWrapper $requestWrapped,
|
||||
ResponseWrapper $responseWrapped
|
||||
): Psr7Response {
|
||||
|
||||
$actionClassName = $processData->getRoute()->getActionClassName();
|
||||
|
||||
if ($actionClassName) {
|
||||
return $this->processAction($actionClassName, $requestWrapped, $responseWrapped);
|
||||
}
|
||||
|
||||
$controller = $this->getControllerName($processData);
|
||||
$action = $processData->getRouteParams()['action'] ?? null;
|
||||
$method = $request->getMethod();
|
||||
@@ -163,6 +174,29 @@ class RequestProcessor
|
||||
return $dispatcher->handle($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<Action> $actionClassName
|
||||
*/
|
||||
private function processAction(
|
||||
string $actionClassName,
|
||||
RequestWrapper $requestWrapped,
|
||||
ResponseWrapper $responseWrapped
|
||||
): Psr7Response {
|
||||
|
||||
/** @var Action $action */
|
||||
$action = $this->injectableFactory->create($actionClassName);
|
||||
|
||||
$action->process($requestWrapped, $responseWrapped);
|
||||
|
||||
$response = $responseWrapped->toPsr7();
|
||||
|
||||
if (!$response->getHeader('Content-Type')) {
|
||||
$response = $response->withHeader('Content-Type', self::DEFAULT_CONTENT_TYPE);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function getControllerName(ProcessData $processData): string
|
||||
{
|
||||
$controllerName = $processData->getRouteParams()['controller'] ?? null;
|
||||
|
||||
@@ -43,21 +43,16 @@ use stdClass;
|
||||
*/
|
||||
class RequestWrapper implements ApiRequest
|
||||
{
|
||||
private Psr7Request $request;
|
||||
private string $basePath;
|
||||
private ?stdClass $parsedBody = null;
|
||||
/** @var array<string,string> */
|
||||
private array $routeParams;
|
||||
|
||||
/**
|
||||
* @param array<string, string> $routeParams
|
||||
*/
|
||||
public function __construct(Psr7Request $request, string $basePath = '', array $routeParams = [])
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->basePath = $basePath;
|
||||
$this->routeParams = $routeParams;
|
||||
}
|
||||
public function __construct(
|
||||
private Psr7Request $psr7Request,
|
||||
private string $basePath = '',
|
||||
private array $routeParams = []
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get a route or query parameter. Route params have a higher priority.
|
||||
@@ -80,7 +75,7 @@ class RequestWrapper implements ApiRequest
|
||||
return $this->getRouteParam($name);
|
||||
}
|
||||
|
||||
return $this->request->getQueryParams()[$name] ?? null;
|
||||
return $this->psr7Request->getQueryParams()[$name] ?? null;
|
||||
}
|
||||
|
||||
public function hasRouteParam(string $name): bool
|
||||
@@ -94,7 +89,7 @@ class RequestWrapper implements ApiRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,string>
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getRouteParams(): array
|
||||
{
|
||||
@@ -103,12 +98,12 @@ class RequestWrapper implements ApiRequest
|
||||
|
||||
public function hasQueryParam(string $name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->request->getQueryParams());
|
||||
return array_key_exists($name, $this->psr7Request->getQueryParams());
|
||||
}
|
||||
|
||||
public function getQueryParam(string $name): ?string
|
||||
{
|
||||
$value = $this->request->getQueryParams()[$name] ?? null;
|
||||
$value = $this->psr7Request->getQueryParams()[$name] ?? null;
|
||||
|
||||
if (!is_string($value)) {
|
||||
return null;
|
||||
@@ -119,21 +114,21 @@ class RequestWrapper implements ApiRequest
|
||||
|
||||
public function getQueryParams(): array
|
||||
{
|
||||
return $this->request->getQueryParams();
|
||||
return $this->psr7Request->getQueryParams();
|
||||
}
|
||||
|
||||
public function getHeader(string $name): ?string
|
||||
{
|
||||
if (!$this->request->hasHeader($name)) {
|
||||
if (!$this->psr7Request->hasHeader($name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->request->getHeaderLine($name);
|
||||
return $this->psr7Request->getHeaderLine($name);
|
||||
}
|
||||
|
||||
public function hasHeader(string $name): bool
|
||||
{
|
||||
return $this->request->hasHeader($name);
|
||||
return $this->psr7Request->hasHeader($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,16 +136,16 @@ class RequestWrapper implements ApiRequest
|
||||
*/
|
||||
public function getHeaderAsArray(string $name): array
|
||||
{
|
||||
if (!$this->request->hasHeader($name)) {
|
||||
if (!$this->psr7Request->hasHeader($name)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->request->getHeader($name);
|
||||
return $this->psr7Request->getHeader($name);
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->request->getMethod();
|
||||
return $this->psr7Request->getMethod();
|
||||
}
|
||||
|
||||
public function getContentType(): ?string
|
||||
@@ -161,7 +156,7 @@ class RequestWrapper implements ApiRequest
|
||||
|
||||
$contentType = explode(
|
||||
';',
|
||||
$this->request->getHeader('Content-Type')[0]
|
||||
$this->psr7Request->getHeader('Content-Type')[0]
|
||||
)[0];
|
||||
|
||||
return strtolower($contentType);
|
||||
@@ -169,9 +164,9 @@ class RequestWrapper implements ApiRequest
|
||||
|
||||
public function getBodyContents(): ?string
|
||||
{
|
||||
$contents = $this->request->getBody()->getContents();
|
||||
$contents = $this->psr7Request->getBody()->getContents();
|
||||
|
||||
$this->request->getBody()->rewind();
|
||||
$this->psr7Request->getBody()->rewind();
|
||||
|
||||
return $contents;
|
||||
}
|
||||
@@ -223,7 +218,7 @@ class RequestWrapper implements ApiRequest
|
||||
in_array($contentType, ['application/x-www-form-urlencoded', 'multipart/form-data']) &&
|
||||
$contents
|
||||
) {
|
||||
$parsedBody = $this->request->getParsedBody();
|
||||
$parsedBody = $this->psr7Request->getParsedBody();
|
||||
|
||||
if (is_array($parsedBody)) {
|
||||
$this->parsedBody = (object) $parsedBody;
|
||||
@@ -243,7 +238,7 @@ class RequestWrapper implements ApiRequest
|
||||
|
||||
public function getCookieParam(string $name): ?string
|
||||
{
|
||||
$params = $this->request->getCookieParams();
|
||||
$params = $this->psr7Request->getCookieParams();
|
||||
|
||||
return $params[$name] ?? null;
|
||||
}
|
||||
@@ -253,19 +248,19 @@ class RequestWrapper implements ApiRequest
|
||||
*/
|
||||
public function getServerParam(string $name)
|
||||
{
|
||||
$params = $this->request->getServerParams();
|
||||
$params = $this->psr7Request->getServerParams();
|
||||
|
||||
return $params[$name] ?? null;
|
||||
}
|
||||
|
||||
public function getUri(): UriInterface
|
||||
{
|
||||
return $this->request->getUri();
|
||||
return $this->psr7Request->getUri();
|
||||
}
|
||||
|
||||
public function getResourcePath(): string
|
||||
{
|
||||
$path = $this->request->getUri()->getPath();
|
||||
$path = $this->psr7Request->getUri()->getPath();
|
||||
|
||||
return substr($path, strlen($this->basePath));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
namespace Espo\Core\Api;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Psr7Response;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,45 +39,45 @@ use Espo\Core\Api\Response as ApiResponse;
|
||||
*/
|
||||
class ResponseWrapper implements ApiResponse
|
||||
{
|
||||
public function __construct(private Psr7Response $response)
|
||||
public function __construct(private Psr7Response $psr7Response)
|
||||
{
|
||||
// Slim adds Authorization header. It's not needed.
|
||||
$this->response = $this->response->withoutHeader('Authorization');
|
||||
$this->psr7Response = $this->psr7Response->withoutHeader('Authorization');
|
||||
}
|
||||
|
||||
public function setStatus(int $code, ?string $reason = null): Response
|
||||
{
|
||||
$this->response = $this->response->withStatus($code, $reason ?? '');
|
||||
$this->psr7Response = $this->psr7Response->withStatus($code, $reason ?? '');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHeader(string $name, string $value): Response
|
||||
{
|
||||
$this->response = $this->response->withHeader($name, $value);
|
||||
$this->psr7Response = $this->psr7Response->withHeader($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addHeader(string $name, string $value): Response
|
||||
{
|
||||
$this->response = $this->response->withAddedHeader($name, $value);
|
||||
$this->psr7Response = $this->psr7Response->withAddedHeader($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeader(string $name): ?string
|
||||
{
|
||||
if (!$this->response->hasHeader($name)) {
|
||||
if (!$this->psr7Response->hasHeader($name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->response->getHeaderLine($name);
|
||||
return $this->psr7Response->getHeaderLine($name);
|
||||
}
|
||||
|
||||
public function hasHeader(string $name): bool
|
||||
{
|
||||
return $this->response->hasHeader($name);
|
||||
return $this->psr7Response->hasHeader($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,29 +85,29 @@ class ResponseWrapper implements ApiResponse
|
||||
*/
|
||||
public function getHeaderAsArray(string $name): array
|
||||
{
|
||||
if (!$this->response->hasHeader($name)) {
|
||||
if (!$this->psr7Response->hasHeader($name)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->response->getHeader($name);
|
||||
return $this->psr7Response->getHeader($name);
|
||||
}
|
||||
|
||||
public function writeBody(string $string): Response
|
||||
{
|
||||
$this->response->getBody()->write($string);
|
||||
$this->psr7Response->getBody()->write($string);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setBody(StreamInterface $body): Response
|
||||
{
|
||||
$this->response = $this->response->withBody($body);
|
||||
$this->psr7Response = $this->psr7Response->withBody($body);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResponse(): Psr7Response
|
||||
public function toPsr7(): Psr7Response
|
||||
{
|
||||
return $this->response;
|
||||
return $this->psr7Response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,17 +35,27 @@ class Route
|
||||
|
||||
/**
|
||||
* @param array<string, string> $params
|
||||
* @param ?class-string<Action> $actionClassName
|
||||
*/
|
||||
public function __construct(
|
||||
string $method,
|
||||
private string $route,
|
||||
private string $adjustedRoute,
|
||||
private array $params,
|
||||
private bool $noAuth
|
||||
private bool $noAuth,
|
||||
private ?string $actionClassName
|
||||
) {
|
||||
$this->method = strtoupper($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?class-string<Action>
|
||||
*/
|
||||
public function getActionClassName(): ?string
|
||||
{
|
||||
return $this->actionClassName;
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->method;
|
||||
|
||||
@@ -100,6 +100,6 @@ class PortalClient implements RunnerParameterized
|
||||
{
|
||||
$this->errorOutput->processWithBodyPrinting($request, $response, $exception);
|
||||
|
||||
(new ResponseEmitter())->emit($response->getResponse());
|
||||
(new ResponseEmitter())->emit($response->toPsr7());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ class Starter
|
||||
catch (NotFound $exception) {
|
||||
$this->errorOutput->processWithBodyPrinting($requestWrapped, $responseWrapped, $exception);
|
||||
|
||||
(new ResponseEmitter())->emit($responseWrapped->getResponse());
|
||||
(new ResponseEmitter())->emit($responseWrapped->toPsr7());
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ class Starter
|
||||
$authRequired
|
||||
);
|
||||
|
||||
(new ResponseEmitter())->emit($responseWrapped->getResponse());
|
||||
(new ResponseEmitter())->emit($responseWrapped->toPsr7());
|
||||
}
|
||||
|
||||
private function processRequest(
|
||||
|
||||
@@ -54,7 +54,8 @@ class Route extends BaseRoute
|
||||
$route->getRoute(),
|
||||
$path,
|
||||
$route->getParams(),
|
||||
$route->noAuth()
|
||||
$route->noAuth(),
|
||||
$route->getActionClassName()
|
||||
);
|
||||
|
||||
$newRouteList[] = $newRoute;
|
||||
|
||||
@@ -149,7 +149,7 @@ class ClientManager
|
||||
$this->writeHeaders($response);
|
||||
$response->writeBody($body);
|
||||
|
||||
(new ResponseEmitter())->emit($response->getResponse());
|
||||
(new ResponseEmitter())->emit($response->toPsr7());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,11 +40,12 @@ use Espo\Core\Utils\Resource\PathProvider;
|
||||
* method: string,
|
||||
* noAuth?: bool,
|
||||
* params?: array<string, mixed>,
|
||||
* actionClassName: ?class-string<\Espo\Core\Api\Action>
|
||||
* }
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
/** @var ?(RouteArrayShape[]) */
|
||||
/** @var ?RouteArrayShape[] */
|
||||
private $data = null;
|
||||
private string $cacheKey = 'routes';
|
||||
private string $routesFileName = 'routes.json';
|
||||
@@ -77,7 +78,8 @@ class Route
|
||||
$item['route'],
|
||||
$item['adjustedRoute'],
|
||||
$item['params'] ?? [],
|
||||
$item['noAuth'] ?? false
|
||||
$item['noAuth'] ?? false,
|
||||
$item['actionClassName'] ?? null
|
||||
);
|
||||
},
|
||||
$this->data
|
||||
@@ -242,8 +244,8 @@ class Route
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $newRoute
|
||||
* @param array<int, array<string, mixed>> $routeList
|
||||
* @param RouteArrayShape $newRoute
|
||||
* @param array<int, RouteArrayShape> $routeList
|
||||
*/
|
||||
static private function isRouteInList(array $newRoute, array $routeList): bool
|
||||
{
|
||||
|
||||
@@ -33,184 +33,23 @@ use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Record\SearchParamsFetcher;
|
||||
|
||||
use Espo\Modules\Crm\Tools\Activities\FetchParams as ActivitiesFetchParams;
|
||||
use Espo\Modules\Crm\Tools\Calendar\FetchParams;
|
||||
use Espo\Modules\Crm\Tools\Activities\Service as Service;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Service as CalendarService;
|
||||
use Espo\Entities\User;
|
||||
|
||||
use stdClass;
|
||||
use Exception;
|
||||
|
||||
class Activities
|
||||
{
|
||||
private const MAX_CALENDAR_RANGE = 123;
|
||||
|
||||
private User $user;
|
||||
private Acl $acl;
|
||||
private SearchParamsFetcher $searchParamsFetcher;
|
||||
private Service $service;
|
||||
private CalendarService $calendarService;
|
||||
|
||||
public function __construct(
|
||||
User $user,
|
||||
Acl $acl,
|
||||
SearchParamsFetcher $searchParamsFetcher,
|
||||
Service $service,
|
||||
CalendarService $calendarService
|
||||
) {
|
||||
$this->user = $user;
|
||||
$this->acl = $acl;
|
||||
$this->searchParamsFetcher = $searchParamsFetcher;
|
||||
$this->service = $service;
|
||||
$this->calendarService = $calendarService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,stdClass>
|
||||
* @throws Forbidden
|
||||
* @throws BadRequest
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getActionListCalendarEvents(Request $request): array
|
||||
{
|
||||
if (!$this->acl->check('Calendar')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
$isAgenda = $request->getQueryParam('agenda') === 'true';
|
||||
|
||||
if (empty($from) || empty($to)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (strtotime($to) - strtotime($from) > self::MAX_CALENDAR_RANGE * 24 * 3600) {
|
||||
throw new Forbidden('Too long range.');
|
||||
}
|
||||
|
||||
$scopeList = null;
|
||||
|
||||
if ($request->getQueryParam('scopeList') !== null) {
|
||||
$scopeList = explode(',', $request->getQueryParam('scopeList'));
|
||||
}
|
||||
|
||||
$userId = $request->getQueryParam('userId');
|
||||
$userIdList = $request->getQueryParam('userIdList');
|
||||
$teamIdList = $request->getQueryParam('teamIdList');
|
||||
|
||||
$fetchParams = FetchParams
|
||||
::create(
|
||||
DateTime::fromString($from),
|
||||
DateTime::fromString($to)
|
||||
)
|
||||
->withScopeList($scopeList);
|
||||
|
||||
if ($teamIdList) {
|
||||
$teamIdList = explode(',', $teamIdList);
|
||||
|
||||
return self::itemListToRaw(
|
||||
$this->calendarService->fetchForTeams($teamIdList, $fetchParams)
|
||||
);
|
||||
}
|
||||
|
||||
if ($userIdList) {
|
||||
$userIdList = explode(',', $userIdList);
|
||||
|
||||
return self::itemListToRaw(
|
||||
$this->calendarService->fetchForUsers($userIdList, $fetchParams)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$userId) {
|
||||
$userId = $this->user->getId();
|
||||
}
|
||||
|
||||
$fetchParams = $fetchParams
|
||||
->withIsAgenda($isAgenda)
|
||||
->withWorkingTimeRanges();
|
||||
|
||||
return self::itemListToRaw(
|
||||
$this->calendarService->fetch($userId, $fetchParams)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarItem[] $itemList
|
||||
* @return stdClass[]
|
||||
*/
|
||||
private static function itemListToRaw(array $itemList): array
|
||||
{
|
||||
return array_map(fn (CalendarItem $item) => $item->getRaw(), $itemList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getActionGetTimeline(Request $request): stdClass
|
||||
{
|
||||
if (!$this->acl->check('Calendar')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
|
||||
if (empty($from) || empty($to)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (strtotime($to) - strtotime($from) > self::MAX_CALENDAR_RANGE * 24 * 3600) {
|
||||
throw new Forbidden('Too long range.');
|
||||
}
|
||||
|
||||
$scopeList = null;
|
||||
|
||||
if ($request->getQueryParam('scopeList') !== null) {
|
||||
$scopeList = explode(',', $request->getQueryParam('scopeList'));
|
||||
}
|
||||
|
||||
$userId = $request->getQueryParam('userId');
|
||||
$userIdList = $request->getQueryParam('userIdList');
|
||||
|
||||
if ($userIdList) {
|
||||
$userIdList = explode(',', $userIdList);
|
||||
}
|
||||
else {
|
||||
$userIdList = [];
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
$userIdList[] = $userId;
|
||||
}
|
||||
|
||||
$fetchParams = FetchParams
|
||||
::create(
|
||||
DateTime::fromString($from . ':00'),
|
||||
DateTime::fromString($to . ':00')
|
||||
)
|
||||
->withScopeList($scopeList);
|
||||
|
||||
$map = $this->calendarService->fetchTimelineForUsers($userIdList, $fetchParams);
|
||||
|
||||
$result = (object) [];
|
||||
|
||||
foreach ($map as $userId => $itemList) {
|
||||
$result->$userId = self::itemListToRaw($itemList);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
private User $user,
|
||||
private Acl $acl,
|
||||
private SearchParamsFetcher $searchParamsFetcher,
|
||||
private Service $service
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @throws Forbidden
|
||||
@@ -378,38 +217,4 @@ class Activities
|
||||
'list' => $result->getValueMapList(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws BadRequest
|
||||
* @throws Forbidden
|
||||
* @throws Error
|
||||
*/
|
||||
public function getActionBusyRanges(Request $request): stdClass
|
||||
{
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
$userIdListString = $request->getQueryParam('userIdList');
|
||||
|
||||
if (!$from || !$to || !$userIdListString) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$userIdList = explode(',', $userIdListString);
|
||||
|
||||
$map = $this->calendarService->fetchBusyRangesForUsers(
|
||||
$userIdList,
|
||||
DateTime::fromString($from),
|
||||
DateTime::fromString($to),
|
||||
$request->getQueryParam('entityType'),
|
||||
$request->getQueryParam('entityId')
|
||||
);
|
||||
|
||||
$result = (object) [];
|
||||
|
||||
foreach ($map as $userId => $itemList) {
|
||||
$result->$userId = self::itemListToRaw($itemList);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,17 @@
|
||||
{
|
||||
"route": "/Activities",
|
||||
"method": "get",
|
||||
"params": {
|
||||
"controller": "Activities",
|
||||
"action": "listCalendarEvents"
|
||||
}
|
||||
"actionClassName": "Espo\\Modules\\Crm\\Tools\\Calendar\\Api\\GetCalendar"
|
||||
},
|
||||
{
|
||||
"route": "/Timeline",
|
||||
"method": "get",
|
||||
"params": {
|
||||
"controller": "Activities",
|
||||
"action": "getTimeline"
|
||||
}
|
||||
"actionClassName": "Espo\\Modules\\Crm\\Tools\\Calendar\\Api\\GetTimeline"
|
||||
},
|
||||
{
|
||||
"route": "/Timeline/busyRanges",
|
||||
"method": "get",
|
||||
"actionClassName": "Espo\\Modules\\Crm\\Tools\\Calendar\\Api\\GetBusyRanges"
|
||||
},
|
||||
{
|
||||
"route": "/Activities/:scope/:id/:name/list/:entityType",
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\Calendar\Api;
|
||||
|
||||
use Espo\Core\Api\Action;
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Api\Response;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Utils\Json;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Service;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Busy-ranges.
|
||||
*/
|
||||
class GetBusyRanges implements Action
|
||||
{
|
||||
public function __construct(private Service $calendarService) {}
|
||||
|
||||
public function process(Request $request, Response $response): void
|
||||
{
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
$userIdListString = $request->getQueryParam('userIdList');
|
||||
|
||||
if (!$from || !$to || !$userIdListString) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$userIdList = explode(',', $userIdListString);
|
||||
|
||||
$map = $this->calendarService->fetchBusyRangesForUsers(
|
||||
$userIdList,
|
||||
DateTime::fromString($from),
|
||||
DateTime::fromString($to),
|
||||
$request->getQueryParam('entityType'),
|
||||
$request->getQueryParam('entityId')
|
||||
);
|
||||
|
||||
$result = (object) [];
|
||||
|
||||
foreach ($map as $userId => $itemList) {
|
||||
$result->$userId = self::itemListToRaw($itemList);
|
||||
}
|
||||
|
||||
$response->writeBody(Json::encode($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarItem[] $itemList
|
||||
* @return stdClass[]
|
||||
*/
|
||||
private static function itemListToRaw(array $itemList): array
|
||||
{
|
||||
return array_map(fn (CalendarItem $item) => $item->getRaw(), $itemList);
|
||||
}
|
||||
}
|
||||
142
application/Espo/Modules/Crm/Tools/Calendar/Api/GetCalendar.php
Normal file
142
application/Espo/Modules/Crm/Tools/Calendar/Api/GetCalendar.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\Calendar\Api;
|
||||
|
||||
use Espo\Core\Api\Action;
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Api\Response;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Utils\Json;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Modules\Crm\Tools\Calendar\FetchParams;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Service;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Calendar events.
|
||||
*/
|
||||
class GetCalendar implements Action
|
||||
{
|
||||
private const MAX_CALENDAR_RANGE = 123;
|
||||
|
||||
public function __construct(
|
||||
private Service $calendarService,
|
||||
private Acl $acl,
|
||||
private User $user
|
||||
) {}
|
||||
|
||||
public function process(Request $request, Response $response): void
|
||||
{
|
||||
if (!$this->acl->check('Calendar')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
$isAgenda = $request->getQueryParam('agenda') === 'true';
|
||||
|
||||
if (empty($from) || empty($to)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (strtotime($to) - strtotime($from) > self::MAX_CALENDAR_RANGE * 24 * 3600) {
|
||||
throw new Forbidden('Too long range.');
|
||||
}
|
||||
|
||||
$scopeList = null;
|
||||
|
||||
if ($request->getQueryParam('scopeList') !== null) {
|
||||
$scopeList = explode(',', $request->getQueryParam('scopeList'));
|
||||
}
|
||||
|
||||
$userId = $request->getQueryParam('userId');
|
||||
$userIdList = $request->getQueryParam('userIdList');
|
||||
$teamIdList = $request->getQueryParam('teamIdList');
|
||||
|
||||
$fetchParams = FetchParams
|
||||
::create(
|
||||
DateTime::fromString($from),
|
||||
DateTime::fromString($to)
|
||||
)
|
||||
->withScopeList($scopeList);
|
||||
|
||||
if ($teamIdList) {
|
||||
$teamIdList = explode(',', $teamIdList);
|
||||
|
||||
$raw = self::itemListToRaw(
|
||||
$this->calendarService->fetchForTeams($teamIdList, $fetchParams)
|
||||
);
|
||||
|
||||
$response->writeBody(Json::encode($raw));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($userIdList) {
|
||||
$userIdList = explode(',', $userIdList);
|
||||
|
||||
$raw = self::itemListToRaw(
|
||||
$this->calendarService->fetchForUsers($userIdList, $fetchParams)
|
||||
);
|
||||
|
||||
$response->writeBody(Json::encode($raw));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$userId) {
|
||||
$userId = $this->user->getId();
|
||||
}
|
||||
|
||||
$fetchParams = $fetchParams
|
||||
->withIsAgenda($isAgenda)
|
||||
->withWorkingTimeRanges();
|
||||
|
||||
$raw = self::itemListToRaw(
|
||||
$this->calendarService->fetch($userId, $fetchParams)
|
||||
);
|
||||
|
||||
$response->writeBody(Json::encode($raw));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarItem[] $itemList
|
||||
* @return stdClass[]
|
||||
*/
|
||||
private static function itemListToRaw(array $itemList): array
|
||||
{
|
||||
return array_map(fn (CalendarItem $item) => $item->getRaw(), $itemList);
|
||||
}
|
||||
}
|
||||
116
application/Espo/Modules/Crm/Tools/Calendar/Api/GetTimeline.php
Normal file
116
application/Espo/Modules/Crm/Tools/Calendar/Api/GetTimeline.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Tools\Calendar\Api;
|
||||
|
||||
use Espo\Core\Api\Action;
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Api\Response;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Utils\Json;
|
||||
use Espo\Modules\Crm\Tools\Calendar\FetchParams;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem;
|
||||
use Espo\Modules\Crm\Tools\Calendar\Service;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Get timeline items.
|
||||
*/
|
||||
class GetTimeline implements Action
|
||||
{
|
||||
private const MAX_CALENDAR_RANGE = 123;
|
||||
|
||||
public function __construct(
|
||||
private Service $calendarService,
|
||||
private Acl $acl
|
||||
) {}
|
||||
|
||||
public function process(Request $request, Response $response): void
|
||||
{
|
||||
if (!$this->acl->check('Calendar')) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
|
||||
if (empty($from) || empty($to)) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (strtotime($to) - strtotime($from) > self::MAX_CALENDAR_RANGE * 24 * 3600) {
|
||||
throw new Forbidden('Too long range.');
|
||||
}
|
||||
|
||||
$scopeList = null;
|
||||
|
||||
if ($request->getQueryParam('scopeList') !== null) {
|
||||
$scopeList = explode(',', $request->getQueryParam('scopeList'));
|
||||
}
|
||||
|
||||
$userId = $request->getQueryParam('userId');
|
||||
$userIdList = $request->getQueryParam('userIdList');
|
||||
|
||||
$userIdList = $userIdList ? explode(',', $userIdList) : [];
|
||||
|
||||
if ($userId) {
|
||||
$userIdList[] = $userId;
|
||||
}
|
||||
|
||||
$fetchParams = FetchParams
|
||||
::create(
|
||||
DateTime::fromString($from . ':00'),
|
||||
DateTime::fromString($to . ':00')
|
||||
)
|
||||
->withScopeList($scopeList);
|
||||
|
||||
$map = $this->calendarService->fetchTimelineForUsers($userIdList, $fetchParams);
|
||||
|
||||
$result = (object) [];
|
||||
|
||||
foreach ($map as $userId => $itemList) {
|
||||
$result->$userId = self::itemListToRaw($itemList);
|
||||
}
|
||||
|
||||
$response->writeBody(Json::encode($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarItem[] $itemList
|
||||
* @return stdClass[]
|
||||
*/
|
||||
private static function itemListToRaw(array $itemList): array
|
||||
{
|
||||
return array_map(fn (CalendarItem $item) => $item->getRaw(), $itemList);
|
||||
}
|
||||
}
|
||||
@@ -328,7 +328,7 @@ define('crm:views/scheduler/scheduler', ['view', 'lib!vis'], function (Dep, Vis)
|
||||
let toString = to.utc().format(this.getDateTime().internalDateTimeFormat);
|
||||
|
||||
let url =
|
||||
'Activities/action/busyRanges?from=' + fromString + '&to=' + toString +
|
||||
'Timeline/busyRanges?from=' + fromString + '&to=' + toString +
|
||||
'&userIdList=' + encodeURIComponent(this.userIdList.join(',')) +
|
||||
'&entityType=' + this.model.entityType;
|
||||
|
||||
|
||||
@@ -101,83 +101,83 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
['Crm']
|
||||
);
|
||||
|
||||
$expected = array (
|
||||
array (
|
||||
$expected = [
|
||||
[
|
||||
'adjustedRoute' => '/Custom/{scope}/{id}/{name}',
|
||||
'route' => '/Custom/:scope/:id/:name',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Custom',
|
||||
'action' => 'list',
|
||||
'scope' => ':scope',
|
||||
'id' => ':id',
|
||||
'name' => ':name',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Activities/{scope}/{id}/{name}',
|
||||
'route' => '/Activities/:scope/:id/:name',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Activities',
|
||||
'action' => 'list',
|
||||
'scope' => ':scope',
|
||||
'id' => ':id',
|
||||
'name' => ':name',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Activities',
|
||||
'route' => '/Activities',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Activities',
|
||||
'action' => 'listCalendarEvents',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/App/user',
|
||||
'route' => '/App/user',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'App',
|
||||
'action' => 'user',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Metadata',
|
||||
'route' => '/Metadata',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Metadata',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/{controller}/action/{action}',
|
||||
'route' => '/:controller/action/:action',
|
||||
'method' => 'post',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => ':controller',
|
||||
'action' => ':action',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/{controller}/action/{action}',
|
||||
'route' => '/:controller/action/:action',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => ':controller',
|
||||
'action' => ':action',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$expectedItemList = array_map(
|
||||
function (array $item) {
|
||||
@@ -186,7 +186,8 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
$item['route'],
|
||||
$item['adjustedRoute'],
|
||||
$item['params'] ?? [],
|
||||
$item['noAuth'] ?? false
|
||||
$item['noAuth'] ?? false,
|
||||
null
|
||||
);
|
||||
},
|
||||
$expected
|
||||
@@ -206,80 +207,80 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
['Crm', 'Test']
|
||||
);
|
||||
|
||||
$expected = array (
|
||||
array (
|
||||
$expected = [
|
||||
[
|
||||
'adjustedRoute' => '/Activities/{scope}/{id}/{name}',
|
||||
'route' => '/Activities/:scope/:id/:name',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Activities',
|
||||
'action' => 'list',
|
||||
'scope' => ':scope',
|
||||
'id' => ':id',
|
||||
'name' => ':name',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Activities',
|
||||
'route' => '/Activities',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Activities',
|
||||
'action' => 'listCalendarEvents',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Test',
|
||||
'route' => '/Test',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Test',
|
||||
'action' => 'listCalendarEvents',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/App/user',
|
||||
'route' => '/App/user',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'App',
|
||||
'action' => 'user',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Metadata',
|
||||
'route' => '/Metadata',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Metadata',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/{controller}/action/{action}',
|
||||
'route' => '/:controller/action/:action',
|
||||
'method' => 'post',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => ':controller',
|
||||
'action' => ':action',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/{controller}/action/{action}',
|
||||
'route' => '/:controller/action/:action',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => ':controller',
|
||||
'action' => ':action',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$expectedItemList = array_map(
|
||||
function (array $item) {
|
||||
@@ -288,7 +289,8 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
$item['route'],
|
||||
$item['adjustedRoute'],
|
||||
$item['params'] ?? [],
|
||||
$item['noAuth'] ?? false
|
||||
$item['noAuth'] ?? false,
|
||||
null
|
||||
);
|
||||
},
|
||||
$expected
|
||||
@@ -308,80 +310,80 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
['Crm', 'Test']
|
||||
);
|
||||
|
||||
$expected = array (
|
||||
array (
|
||||
$expected = [
|
||||
[
|
||||
'adjustedRoute' => '/Activities/{scope}/{id}/{name}',
|
||||
'route' => '/Activities/:scope/:id/:name',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Test',
|
||||
'action' => 'list',
|
||||
'scope' => ':scope',
|
||||
'id' => ':id',
|
||||
'name' => ':name',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Activities',
|
||||
'route' => '/Activities',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Activities',
|
||||
'action' => 'listCalendarEvents',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Test',
|
||||
'route' => '/Test',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Test',
|
||||
'action' => 'listCalendarEvents',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/App/user',
|
||||
'route' => '/App/user',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'App',
|
||||
'action' => 'user',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/Metadata',
|
||||
'route' => '/Metadata',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => 'Metadata',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/{controller}/action/{action}',
|
||||
'route' => '/:controller/action/:action',
|
||||
'method' => 'post',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => ':controller',
|
||||
'action' => ':action',
|
||||
),
|
||||
),
|
||||
array (
|
||||
],
|
||||
],
|
||||
[
|
||||
'adjustedRoute' => '/{controller}/action/{action}',
|
||||
'route' => '/:controller/action/:action',
|
||||
'method' => 'get',
|
||||
'params' =>
|
||||
array (
|
||||
[
|
||||
'controller' => ':controller',
|
||||
'action' => ':action',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$expectedItemList = array_map(
|
||||
function (array $item) {
|
||||
@@ -390,7 +392,8 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
$item['route'],
|
||||
$item['adjustedRoute'],
|
||||
$item['params'] ?? [],
|
||||
$item['noAuth'] ?? false
|
||||
$item['noAuth'] ?? false,
|
||||
false
|
||||
);
|
||||
},
|
||||
$expected
|
||||
@@ -459,7 +462,8 @@ class RouteTest extends \PHPUnit\Framework\TestCase
|
||||
$item['route'],
|
||||
$item['adjustedRoute'],
|
||||
$item['params'] ?? [],
|
||||
$item['noAuth'] ?? false
|
||||
$item['noAuth'] ?? false,
|
||||
false
|
||||
);
|
||||
},
|
||||
$expected
|
||||
|
||||
Reference in New Issue
Block a user