Skip to content

Commit a22b705

Browse files
committed
Init module
0 parents  commit a22b705

File tree

12 files changed

+490
-0
lines changed

12 files changed

+490
-0
lines changed

App/Application.php

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
/**
3+
* Copyright © OpenGento, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Opengento\Application\App;
9+
10+
use Exception;
11+
use InvalidArgumentException;
12+
use Magento\Framework\App;
13+
use Magento\Framework\App\ExceptionHandlerInterface;
14+
use Magento\Framework\App\FrontControllerInterface as FrontController;
15+
use Magento\Framework\App\HttpRequestInterface;
16+
use Magento\Framework\App\Response\Http;
17+
use Magento\Framework\App\Response\HttpInterface;
18+
use Magento\Framework\AppInterface;
19+
use Magento\Framework\Controller\ResultInterface;
20+
use Magento\Framework\Event\Manager;
21+
use Magento\Framework\ObjectManagerInterface;
22+
use Magento\Framework\Registry;
23+
24+
class Application implements AppInterface
25+
{
26+
public function __construct(
27+
private ObjectManagerInterface $objectManager,
28+
private Manager $eventManager,
29+
private Registry $registry,
30+
private ExceptionHandlerInterface $exceptionHandler,
31+
private Http $response,
32+
private App\Request\Http $request,
33+
) {}
34+
35+
/**
36+
* @inheritDoc
37+
*/
38+
public function launch(): HttpInterface
39+
{
40+
/** @var FrontController $frontController */
41+
$frontController = $this->objectManager->create(FrontController::class);
42+
43+
$response = $this->handleHead(
44+
$this->request,
45+
$this->handleResponse($frontController->dispatch($this->request))
46+
);
47+
48+
// This event gives possibility to launch something before sending output (allow cookie setting)
49+
$this->eventManager->dispatch(
50+
'controller_front_send_response_before',
51+
['request' => $this->request, 'response' => $response]
52+
);
53+
54+
return $response;
55+
}
56+
57+
/**
58+
* @inheritdoc
59+
*/
60+
public function catchException(App\Bootstrap $bootstrap, Exception $exception): bool
61+
{
62+
return $this->exceptionHandler->handle($bootstrap, $exception, $this->response, $this->request);
63+
}
64+
65+
private function handleResponse(ResultInterface|HttpInterface $result): ResultInterface|HttpInterface
66+
{
67+
// TODO: Temporary solution until all controllers return ResultInterface (MAGETWO-28359);
68+
return match (true) {
69+
$result instanceof ResultInterface => $this->handleLayoutResult($result),
70+
$result instanceof HttpInterface => $this->handleHttpResult($result),
71+
default => throw new InvalidArgumentException('Invalid return type.')
72+
};
73+
}
74+
75+
private function handleLayoutResult(ResultInterface $result): ResultInterface|HttpInterface
76+
{
77+
$this->registry->register('use_page_cache_plugin', true, true);
78+
$result->renderResult($this->response);
79+
80+
return $this->response;
81+
}
82+
83+
private function handleHttpResult(HttpInterface $result): ResultInterface|HttpInterface
84+
{
85+
$this->response->setContent($result->getContent());
86+
if ($this->response !== $result) { //do not double headers
87+
$this->response->getHeaders()?->addHeaders($result->getHeaders());
88+
}
89+
90+
return $this->response;
91+
}
92+
93+
private function handleHead(HttpRequestInterface $request, HttpInterface $response): HttpInterface
94+
{
95+
if ($request->isHead() && $response->getHttpResponseCode() === 200) {
96+
$contentLength = mb_strlen($response->getContent(), '8bit');
97+
$response->clearBody();
98+
$response->setHeader('Content-Length', $contentLength);
99+
}
100+
101+
return $response;
102+
}
103+
}

App/ReloadProcessor.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © OpenGento, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Opengento\Application\App;
9+
10+
use Magento\Framework\App\State\ReloadProcessorInterface;
11+
12+
class ReloadProcessor implements ReloadProcessorInterface
13+
{
14+
/**
15+
* @inerhitDoc
16+
*/
17+
public function reloadState(): void
18+
{
19+
// ToDo: we need to investigate this test in order to reset any missing state not handled natively by the framework:
20+
// ToDo: @see vendor/magento/magento2-base/dev/tests/integration/framework/Magento/TestFramework/ApplicationStateComparator
21+
}
22+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) OpenGento
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE

ObjectManager/AppBootstrap.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © OpenGento, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Opengento\Application;
9+
10+
use Magento\Framework\App\Bootstrap;
11+
use Magento\Framework\App\ObjectManagerFactory;
12+
use Magento\Framework\App\State\ReloadProcessorInterface;
13+
use Magento\Framework\AppInterface;
14+
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
15+
use Opengento\Application\AppObjectManagerFactory;
16+
17+
use function gc_collect_cycles;
18+
19+
class AppBootstrap extends Bootstrap
20+
{
21+
/**
22+
* @inerhitDoc
23+
*/
24+
public static function create($rootDir, array $initParams, ?ObjectManagerFactory $factory = null): static
25+
{
26+
self::populateAutoloader($rootDir, $initParams);
27+
28+
return new self($factory ?? self::createObjectManagerFactory($rootDir, $initParams), $rootDir, $initParams);
29+
}
30+
31+
/**
32+
* @inerhitDoc
33+
*/
34+
public static function createObjectManagerFactory($rootDir, array $initParams): AppObjectManagerFactory
35+
{
36+
return new AppObjectManagerFactory(
37+
self::createFilesystemDirectoryList($rootDir, $initParams),
38+
self::createFilesystemDriverPool($initParams),
39+
self::createConfigFilePool()
40+
);
41+
}
42+
43+
/**
44+
* @inerhitDoc
45+
*/
46+
public function createApplication($type, $arguments = []): ?AppInterface
47+
{
48+
$arguments['objectManager'] ??= $this->getObjectManager();
49+
50+
return parent::createApplication($type, $arguments);
51+
}
52+
53+
/**
54+
* @inerhitDoc
55+
*/
56+
public function run(AppInterface $application): void
57+
{
58+
parent::run($application);
59+
$objectManager = $this->getObjectManager();
60+
$reloadProcessor = $objectManager->get(ReloadProcessorInterface::class);
61+
$reloadProcessor->reloadState();
62+
if ($objectManager instanceof ResetAfterRequestInterface) {
63+
$objectManager->_resetState();
64+
}
65+
gc_collect_cycles();
66+
}
67+
}

ObjectManager/AppObjectManager.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
/**
3+
* Copyright © OpenGento, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Opengento\Application;
9+
10+
use Magento\Framework\App\ObjectManager;
11+
use Magento\Framework\ObjectManager\ConfigInterface;
12+
use Magento\Framework\ObjectManager\FactoryInterface;
13+
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
14+
use Magento\Framework\ObjectManager\Resetter\Resetter;
15+
use Magento\Framework\ObjectManager\Resetter\ResetterInterface;
16+
use ReflectionException;
17+
18+
class AppObjectManager extends ObjectManager implements ResetAfterRequestInterface
19+
{
20+
private ResetterInterface $resetter;
21+
22+
public function __construct(
23+
FactoryInterface $factory,
24+
ConfigInterface $config,
25+
array &$sharedInstances = []
26+
) {
27+
$this->resetter = new Resetter();
28+
parent::__construct($factory, $config, $sharedInstances);
29+
$this->resetter->setObjectManager($this);
30+
}
31+
32+
/**
33+
* @ingeritdoc
34+
* @throws ReflectionException
35+
*/
36+
public function _resetState(): void
37+
{
38+
$this->resetter->_resetState();
39+
}
40+
41+
/**
42+
* @ingeritdoc
43+
*/
44+
public function create($type, array $arguments = [])
45+
{
46+
$object = parent::create($type, $arguments);
47+
$this->resetter->addInstance($object);
48+
49+
return $object;
50+
}
51+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Copyright © OpenGento, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Opengento\Application;
9+
10+
use Magento\Framework\App\ObjectManagerFactory;
11+
use Opengento\Application\AppObjectManager;
12+
13+
class AppObjectManagerFactory extends ObjectManagerFactory
14+
{
15+
protected $_locatorClassName = AppObjectManager::class;
16+
}

ObjectManager/BootstrapPool.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright © OpenGento, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Opengento\Application;
9+
10+
use Magento\Framework\App\AreaList;
11+
use Magento\Framework\App\State;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\ObjectManager\ConfigLoaderInterface;
14+
use Opengento\Application\AppBootstrap;
15+
use Opengento\Application\AppObjectManagerFactory;
16+
17+
use function strtok;
18+
use function trim;
19+
20+
use const BP;
21+
22+
class BootstrapPool
23+
{
24+
private AppObjectManagerFactory $factory;
25+
private AreaList $areaList;
26+
27+
private array $bootstraps = [];
28+
29+
public function __construct()
30+
{
31+
$this->factory = AppBootstrap::createObjectManagerFactory(BP, $_SERVER);
32+
$this->areaList = $this->factory->create($_SERVER)->get(AreaList::class);
33+
}
34+
35+
/**
36+
* @throws LocalizedException
37+
*/
38+
public function get(): AppBootstrap
39+
{
40+
$areaCode = $this->areaList->getCodeByFrontName(strtok(trim($_SERVER['REQUEST_URI'], '/'), '/'));
41+
42+
return $this->bootstraps[$areaCode] ??= $this->createBootstrap($areaCode);
43+
}
44+
45+
/**
46+
* @throws LocalizedException
47+
*/
48+
private function createBootstrap(string $areaCode): AppBootstrap
49+
{
50+
$bootstrap = AppBootstrap::create(BP, $_SERVER, $this->factory);
51+
$globalObjectManager = $bootstrap->getObjectManager();
52+
$globalObjectManager->configure($globalObjectManager->get(ConfigLoaderInterface::class)->load($areaCode));
53+
$globalObjectManager->get(State::class)->setAreaCode($areaCode);
54+
55+
return $bootstrap;
56+
}
57+
}

0 commit comments

Comments
 (0)