├── config
└── yii.php
├── src
├── Http
│ ├── DummyResponse.php
│ └── YiiApplicationMiddleware.php
├── Yii
│ ├── Mail
│ │ └── SwiftMailer.php
│ ├── Log
│ │ ├── Logger.php
│ │ ├── Target.php
│ │ └── Illuminated.php
│ ├── Di
│ │ └── Container.php
│ ├── Db
│ │ └── Connection.php
│ ├── I18n
│ │ └── I18n.php
│ ├── Web
│ │ ├── User.php
│ │ ├── Response.php
│ │ ├── Request.php
│ │ └── Session.php
│ └── Caching
│ │ └── Cache.php
├── YiiIlluminateServiceProvider.php
└── Console
│ └── RenameNamespaceCommand.php
├── UPGRADE.md
├── database
└── migrations
│ └── initial_migration.php.stub.php
├── LICENSE.md
├── CHANGELOG.md
├── composer.json
└── README.md
/config/yii.php:
--------------------------------------------------------------------------------
1 | [
15 | 'defaultEntryScript' => 'legacy/web/index.php',
16 | 'cleanup' => true,
17 | //'bootstrap' => 'config/bootstrap.php',
18 | /*'container' => [
19 | '__class' => Yii2tech\Illuminate\Yii\Di\Container::class,
20 | ],*/
21 | /*'logger' => [
22 | '__class' => Yii2tech\Illuminate\Yii\Log\Logger::class,
23 | ],*/
24 | ],
25 | ];
26 |
--------------------------------------------------------------------------------
/src/Http/DummyResponse.php:
--------------------------------------------------------------------------------
1 |
20 | * @since 1.0
21 | */
22 | class DummyResponse extends Response
23 | {
24 | /**
25 | * {@inheritdoc}
26 | */
27 | public function send(): static
28 | {
29 | return $this;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/UPGRADE.md:
--------------------------------------------------------------------------------
1 | Upgrading Instructions for Yii2 to Laravel Migration Package
2 | ============================================================
3 |
4 | !!!IMPORTANT!!!
5 |
6 | The following upgrading instructions are cumulative. That is,
7 | if you want to upgrade from version A to version C and there is
8 | version B between A and C, you need to following the instructions
9 | for both A and B.
10 |
11 | Upgrade from 1.2.1
12 | ------------------
13 |
14 | * Minimal required PHP version has been raised to 8.0. Make sure to update your environment accordingly.
15 |
16 |
17 | Upgrade from 1.1.2
18 | ------------------
19 |
20 | * Virtual property `Yii2tech\Illuminate\Yii\Db\Connection::$laravelConnection` renamed to `Yii2tech\Illuminate\Yii\Db\Connection::$illuminateConnection`.
21 | Check references to this property and methods defining it in your code and fix them accordingly.
22 |
23 | * Method `Yii2tech\Illuminate\Yii\Web\User::convertLaravelIdentity()` renamed to `Yii2tech\Illuminate\Yii\Web\User::convertIlluminateIdentity()`.
24 | Check references to this method in your code and fix them accordingly.
25 |
26 |
27 | Upgrade from 1.0.0
28 | ------------------
29 |
30 | * "illuminate/*" package requirements were raised to 6.0. Make sure to upgrade your code accordingly.
31 |
--------------------------------------------------------------------------------
/src/Yii/Mail/SwiftMailer.php:
--------------------------------------------------------------------------------
1 | [
20 | * 'mailer' => Yii2tech\Illuminate\Yii\Mail\SwiftMailer::class,
21 | * // ...
22 | * ],
23 | * // ...
24 | * ];
25 | * ```
26 | *
27 | * @see https://github.com/yiisoft/yii2-swiftmailer
28 | * @see \yii\swiftmailer\Mailer
29 | * @see \Illuminate\Mail\MailServiceProvider
30 | *
31 | * @author Paul Klimov
32 | * @since 1.0
33 | */
34 | class SwiftMailer extends \yii\swiftmailer\Mailer
35 | {
36 | /**
37 | * {@inheritdoc}
38 | */
39 | protected function createSwiftMailer()
40 | {
41 | return \Illuminate\Container\Container::getInstance()->make('swift.mailer');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/database/migrations/initial_migration.php.stub.php:
--------------------------------------------------------------------------------
1 | -p -h
15 | * ```
16 | *
17 | * Then copy content of the created dump file into '<<statement(<<run();
26 | * ```
27 | *
28 | * @author Paul Klimov
29 | * @since 1.0
30 | */
31 | class Logger extends \yii\log\Logger
32 | {
33 | use Illuminated;
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function init(): void
39 | {
40 | Component::init(); // skip parent init, avoiding `register_shutdown_function()` call.
41 | }
42 |
43 | /**
44 | * {@inheritdoc}
45 | */
46 | public function log($message, $level, $category = 'application'): void
47 | {
48 | $level = $this->convertLogLevel($level);
49 | $context = [
50 | 'category' => $category,
51 | ];
52 | if (! is_string($message)) {
53 | // exceptions may not be serializable if in the call stack somewhere is a Closure
54 | if ($message instanceof \Throwable) {
55 | $context['exception'] = $message;
56 | $message = (string) $message;
57 | } else {
58 | $message = VarDumper::export($message);
59 | }
60 | }
61 |
62 | $this->getIlluminateLogger()->log($level, $message, $context);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Yii/Log/Target.php:
--------------------------------------------------------------------------------
1 | [
20 | * 'log' => [
21 | * 'targets' => [
22 | * [
23 | * 'class' => Yii2tech\Illuminate\Yii\Log\Target::class,
24 | * ],
25 | * // ...
26 | * ],
27 | * ],
28 | * // ...
29 | * ],
30 | * // ...
31 | * ];
32 | * ```
33 | *
34 | * @author Paul Klimov
35 | * @since 1.0
36 | */
37 | class Target extends \yii\log\Target
38 | {
39 | use Illuminated;
40 |
41 | /**
42 | * {@inheritdoc}
43 | */
44 | public function export()
45 | {
46 | foreach ($this->messages as $message) {
47 | [$text, $level, $category, $timestamp] = $message;
48 | $context = [
49 | 'time' => $timestamp,
50 | 'category' => $category,
51 | ];
52 |
53 | if (! is_string($text)) {
54 | // exceptions may not be serializable if in the call stack somewhere is a Closure
55 | if ($text instanceof \Throwable) {
56 | $context['exception'] = $text;
57 | $text = (string) $text;
58 | } else {
59 | $text = VarDumper::export($text);
60 | }
61 | }
62 |
63 | $this->getIlluminateLogger()->log($this->convertLogLevel($level), $text, $context);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Yii2 to Laravel Migration Package Change Log
2 | ============================================
3 |
4 | 1.3.2, April 3, 2025
5 | --------------------
6 |
7 | - Enh #15: Added support for "illuminate/*" 12.0 (klimov-paul)
8 |
9 |
10 | 1.3.1, March 25, 2024
11 | ---------------------
12 |
13 | - Enh: Added support for "illuminate/*" 11.0 (klimov-paul)
14 |
15 |
16 | 1.3.0, March 2, 2023
17 | --------------------
18 |
19 | - Bug: Fixed compatibility with "symfony/http-foundation" 6.x for `DummyResponse::send()` (klimov-paul)
20 | - Bug #13: Fixed `Yii2tech\Illuminate\Yii\Log\Logger` and `Yii2tech\Illuminate\Yii\Caching\Cache` unable to pick up default related Illuminate object (klimov-paul)
21 | - Enh: Added support for "illuminate/support" 10.0 (klimov-paul)
22 |
23 |
24 | 1.2.1, February 9, 2022
25 | -----------------------
26 |
27 | - Enh: Added support for "illuminate/*" 9.0 (klimov-paul)
28 |
29 |
30 | 1.2.0, September 9, 2020
31 | ------------------------
32 |
33 | - Enh: Added support for "illuminate/*" 8.0 (klimov-paul)
34 | - Chg: Virtual property `Connection::$laravelConnection` renamed to `Connection::$illuminateConnection` (klimov-paul)
35 | - Chg: Method `User::convertLaravelIdentity()` renamed to `User::convertIlluminateIdentity()` (klimov-paul)
36 |
37 |
38 | 1.1.2, July 24, 2020
39 | --------------------
40 |
41 | - Bug #8: Fixes environment determining (leandrogehlen)
42 | - Enh #7: `Yii2tech\Illuminate\Yii\Web\Request` now picks up URI info from illuminate one (klimov-paul)
43 |
44 |
45 | 1.1.1, March 4, 2020
46 | --------------------
47 |
48 | - Bug #3: Fixed `Yii2tech\Illuminate\Yii\Di\Container` and `Yii2tech\Illuminate\Yii\Caching\Cache` unable to pick up default related Illuminate object (klimov-paul)
49 | - Enh: Added support for "illuminate/*" 7.0 (klimov-paul)
50 |
51 |
52 | 1.1.0, September 6, 2019
53 | ------------------------
54 |
55 | - Enh: Added support for "illuminate/*" 6.0 (klimov-paul)
56 |
57 |
58 | 1.0.0, March 11, 2019
59 | ---------------------
60 |
61 | - Initial release.
62 |
--------------------------------------------------------------------------------
/src/YiiIlluminateServiceProvider.php:
--------------------------------------------------------------------------------
1 |
17 | * @since 1.0
18 | */
19 | class YiiIlluminateServiceProvider extends ServiceProvider
20 | {
21 | /**
22 | * Register any application services.
23 | */
24 | public function register(): void
25 | {
26 | $this->registerPublications();
27 | }
28 |
29 | /**
30 | * Bootstrap the application services.
31 | */
32 | public function boot(): void
33 | {
34 | if ($this->app->runningInConsole()) {
35 | $this->bootCommands();
36 | }
37 | }
38 |
39 | /**
40 | * Register resources to be published by the publish command.
41 | */
42 | protected function registerPublications(): void
43 | {
44 | if (! $this->app->runningInConsole()) {
45 | return;
46 | }
47 |
48 | $this->publishes([
49 | __DIR__ . '/../config/yii.php' => $this->app->make('path.config').DIRECTORY_SEPARATOR.'yii.php',
50 | ], 'config');
51 |
52 | if (! class_exists(\InitialMigration::class)) {
53 | $timestamp = date('Y_m_d_His', time());
54 |
55 | $this->publishes([
56 | __DIR__.'/../database/migrations/initial_migration.php.stub.php' => $this->app->databasePath().'/migrations/'.$timestamp.'_initial_migration.php',
57 | ], 'migrations');
58 | }
59 | }
60 |
61 | /**
62 | * Boots provided console commands.
63 | */
64 | protected function bootCommands(): void
65 | {
66 | $this->commands([
67 | RenameNamespaceCommand::class,
68 | ]);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yii2tech/illuminate",
3 | "description": "Yii2 to Laravel Migration Package",
4 | "keywords": ["yii2", "laravel", "illuminate", "migration", "switch"],
5 | "license": "BSD-3-Clause",
6 | "support": {
7 | "issues": "https://github.com/yii2tech/illuminate/issues",
8 | "wiki": "https://github.com/yii2tech/illuminate/wiki",
9 | "source": "https://github.com/yii2tech/illuminate"
10 | },
11 | "authors": [
12 | {
13 | "name": "Paul Klimov",
14 | "email": "klimov.paul@gmail.com"
15 | }
16 | ],
17 | "require": {
18 | "php": ">= 8.0",
19 | "yiisoft/yii2": "~2.0.14",
20 | "illuminate/console": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
21 | "illuminate/http": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
22 | "illuminatech/array-factory": "^1.2.6"
23 | },
24 | "require-dev": {
25 | "illuminate/auth": "*",
26 | "illuminate/cache": "*",
27 | "illuminate/config": "*",
28 | "illuminate/database": "*",
29 | "illuminate/events": "*",
30 | "illuminate/hashing": "*",
31 | "illuminate/log": "*",
32 | "illuminate/translation": "*",
33 | "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3 || ^10.5"
34 | },
35 | "repositories": [
36 | {
37 | "type": "composer",
38 | "url": "https://asset-packagist.org"
39 | }
40 | ],
41 | "autoload": {
42 | "psr-4": {
43 | "Yii2tech\\Illuminate\\": "src"
44 | }
45 | },
46 | "autoload-dev": {
47 | "psr-4": {
48 | "Yii2tech\\Illuminate\\Test\\": "tests"
49 | }
50 | },
51 | "extra": {
52 | "branch-alias": {
53 | "dev-master": "1.0.x-dev"
54 | },
55 | "laravel": {
56 | "providers": [
57 | "Yii2tech\\Illuminate\\YiiIlluminateServiceProvider"
58 | ]
59 | }
60 | },
61 | "config": {
62 | "allow-plugins": {
63 | "yiisoft/yii2-composer": true
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Yii/Log/Illuminated.php:
--------------------------------------------------------------------------------
1 |
24 | * @since 1.0
25 | */
26 | trait Illuminated
27 | {
28 | /**
29 | * @var \Illuminate\Log\Logger laravel logger instance.
30 | */
31 | private $_illuminateLogger;
32 |
33 | /**
34 | * @return \Psr\Log\LoggerInterface
35 | */
36 | public function getIlluminateLogger(): LoggerInterface
37 | {
38 | if ($this->_illuminateLogger === null) {
39 | $this->_illuminateLogger = $this->defaultIlluminateLogger();
40 | }
41 |
42 | return $this->_illuminateLogger;
43 | }
44 |
45 | /**
46 | * @param \Psr\Log\LoggerInterface $laravelLogger
47 | * @return static self reference.
48 | */
49 | public function setIlluminateLogger(LoggerInterface $laravelLogger): self
50 | {
51 | $this->_illuminateLogger = $laravelLogger;
52 |
53 | return $this;
54 | }
55 |
56 | /**
57 | * Returns default value for {@see $illuminateLogger}
58 | *
59 | * @return \Psr\Log\LoggerInterface logger instance.
60 | */
61 | protected function defaultIlluminateLogger(): LoggerInterface
62 | {
63 | return \Illuminate\Support\Facades\Log::getFacadeRoot();
64 | }
65 |
66 | /**
67 | * Converts Yii log level into PSR one.
68 | *
69 | * @param int $level Yii log level.
70 | * @return string PSR log level.
71 | */
72 | protected function convertLogLevel($level): string
73 | {
74 | $matches = [
75 | Logger::LEVEL_ERROR => LogLevel::ERROR,
76 | Logger::LEVEL_WARNING => LogLevel::WARNING,
77 | Logger::LEVEL_INFO => LogLevel::INFO,
78 | Logger::LEVEL_TRACE => LogLevel::DEBUG,
79 | Logger::LEVEL_PROFILE => LogLevel::DEBUG,
80 | Logger::LEVEL_PROFILE_BEGIN => LogLevel::DEBUG,
81 | Logger::LEVEL_PROFILE_END => LogLevel::DEBUG,
82 | ];
83 |
84 | if (isset($matches[$level])) {
85 | return $matches[$level];
86 | }
87 |
88 | return LogLevel::INFO;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/Yii/Di/Container.php:
--------------------------------------------------------------------------------
1 | run();
27 | * ```
28 | *
29 | * @see \Illuminate\Contracts\Container\Container
30 | *
31 | * @property \Illuminate\Contracts\Container\Container $illuminateContainer related Laravel DI container.
32 | *
33 | * @author Paul Klimov
34 | * @since 1.0
35 | */
36 | class Container extends \yii\di\Container
37 | {
38 | /**
39 | * @var \Illuminate\Contracts\Container\Container related Laravel DI container.
40 | */
41 | private $_illuminateContainer;
42 |
43 | /**
44 | * @return \Illuminate\Contracts\Container\Container
45 | */
46 | public function getIlluminateContainer(): ContainerContract
47 | {
48 | if ($this->_illuminateContainer === null) {
49 | $this->_illuminateContainer = $this->defaultIlluminateContainer();
50 | }
51 |
52 | return $this->_illuminateContainer;
53 | }
54 |
55 | /**
56 | * @param \Illuminate\Contracts\Container\Container $illuminateContainer
57 | * @return static self reference.
58 | */
59 | public function setIlluminateContainer(ContainerContract $illuminateContainer): self
60 | {
61 | $this->_illuminateContainer = $illuminateContainer;
62 |
63 | return $this;
64 | }
65 |
66 | /**
67 | * @return \Illuminate\Contracts\Container\Container default Laravel DI container.
68 | */
69 | protected function defaultIlluminateContainer(): ContainerContract
70 | {
71 | return \Illuminate\Container\Container::getInstance();
72 | }
73 |
74 | /**
75 | * {@inheritdoc}
76 | */
77 | public function get($class, $params = [], $config = [])
78 | {
79 | if ($this->getIlluminateContainer()->has($class)) {
80 | return $this->getIlluminateContainer()->get($class);
81 | }
82 |
83 | return parent::get($class, $params, $config);
84 | }
85 |
86 | /**
87 | * {@inheritdoc}
88 | */
89 | public function has($class): bool
90 | {
91 | if ($this->getIlluminateContainer()->has($class)) {
92 | return true;
93 | }
94 |
95 | return parent::has($class);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Yii/Db/Connection.php:
--------------------------------------------------------------------------------
1 | [
26 | * 'db' => Yii2tech\Illuminate\Yii\Db\Connection::class,
27 | * // ...
28 | * ],
29 | * // ...
30 | * ];
31 | * ```
32 | *
33 | * @see \Illuminate\Database\Connection
34 | *
35 | * @property \Illuminate\Database\Connection $illuminateConnection related Laravel DB connection.
36 | *
37 | * @author Paul Klimov
38 | * @since 1.0
39 | */
40 | class Connection extends \yii\db\Connection
41 | {
42 | /**
43 | * @var \Illuminate\Database\Connection Laravel DB connection instance.
44 | */
45 | private $_illuminateConnection;
46 |
47 | /**
48 | * {@inheritdoc}
49 | */
50 | public function open(): void
51 | {
52 | if ($this->pdo !== null) {
53 | return;
54 | }
55 |
56 | $this->pdo = $this->getIlluminateConnection()->getPdo();
57 | }
58 |
59 | /**
60 | * {@inheritdoc}
61 | */
62 | public function close(): void
63 | {
64 | if ($this->pdo === null) {
65 | return;
66 | }
67 |
68 | $this->getIlluminateConnection()->disconnect();
69 |
70 | $this->pdo = null;
71 | }
72 |
73 | /**
74 | * @param LaravelConnection $connection Laravel DB connection to be used.
75 | * @return static self reference.
76 | */
77 | public function setIlluminateConnection(LaravelConnection $connection): self
78 | {
79 | $this->_illuminateConnection = $connection;
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * Returns Laravel DB connection instance.
86 | *
87 | * @return \Illuminate\Database\Connection connection instance.
88 | */
89 | public function getIlluminateConnection(): LaravelConnection
90 | {
91 | if ($this->_illuminateConnection === null) {
92 | $this->_illuminateConnection = $this->defaultIlluminateConnection();
93 | }
94 |
95 | return $this->_illuminateConnection;
96 | }
97 |
98 | /**
99 | * Defines default Laravel connection.
100 | *
101 | * @return LaravelConnection Laravel connection instance.
102 | */
103 | protected function defaultIlluminateConnection(): LaravelConnection
104 | {
105 | return DB::connection();
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Yii2 to Laravel Migration Package
6 |
7 |
8 |
9 | This extension allows running Yii2 and Laravel applications simultaneously at the same project,
10 | facilitating graceful migration from Yii2 to Laravel.
11 |
12 | For license information check the [LICENSE](LICENSE.md)-file.
13 |
14 | [](https://packagist.org/packages/yii2tech/illuminate)
15 | [](https://packagist.org/packages/yii2tech/illuminate)
16 | [](https://github.com/yii2tech/illuminate/actions)
17 |
18 |
19 | Installation
20 | ------------
21 |
22 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
23 |
24 | Either run
25 |
26 | ```
27 | php composer.phar require --prefer-dist yii2tech/illuminate
28 | ```
29 |
30 | or add
31 |
32 | ```json
33 | "yii2tech/illuminate": "*"
34 | ```
35 |
36 | to the require section of your composer.json.
37 |
38 |
39 | Why switch from Yii2 to Laravel?
40 | --------------------------------
41 |
42 | It is sad to admit, but Yii is outdated technology, which does not keep up with the modern trends.
43 | The core team stick to the BC-keep policy too much since 2.0 release, which make Yii2 lacking of many modern approaches
44 | and features.
45 | While it is common requirement of the modern web project to provide "single page application" based on modern
46 | JS frameworks like ReactJS, EmberJS, VueJS and so on, Yii keeps enforcing JQuery, facilitating its usage and requiring
47 | its installation.
48 | The BC breaking changes, which are supposed to change the situation, like accepting PSR standards for caching and logging,
49 | separating JQuery from the Yii core and so on, are frozen till the future 3.0 release, which can not be expected in any
50 | near future.
51 |
52 | Even when Yii 3.0 will be released, it will hold many BC breaking changes and totally different architecture concept,
53 | regarding of DI and Service Locator usage. This will make migration from Yii 2.x to Yii 3.0 to be the matter of entire
54 | project rewrite, as it already was for migration from Yii 1.x to Yii 2.0. If this is inevitable fate of your project,
55 | why not start code migration now, choosing more reliable technology as its target?
56 | Laravel is most popular PHP framework with solid commercial background and large community. Choosing it will likely bring
57 | good foundation for your project in the long term.
58 |
59 | **Heads up!** Whether to switch from one technology to another or not - is **your own** choice. You take the responsibility
60 | for this decision, and you will have to deal with it consequences. Do not blame anyone else for the troubles and obstacles
61 | you will have to face on the chosen path.
62 |
63 |
64 | Usage
65 | -----
66 |
67 | Migration of existing project from one PHP framework to another can not be done by single day. Most likely you have spent
68 | several months or even years creating your current codebase, and its update will also take much time.
69 |
70 | This extension allows running Yii2 and Laravel applications simultaneously at the same project, allowing resolving of
71 | incoming HTTP requests by one of these applications depending on, which one has a matching route defined for it.
72 | This means all URL routes defined in Yii application will continue to function, while new ones may be resolved by
73 | Laravel. This facilitates graceful migration from one framework to another, allowing progressive transfer of the
74 | URL routes handling (e.g. controllers) from Yii2 to Laravel.
75 |
76 | **Heads up!** This package provides tools and libraries helping project migration, however, do not expect it somehow
77 | magically do all the job for you. The package helps solving basic problems and supports the quick start for the process,
78 | but most of the toil will lay on your shoulders. Be ready for it.
79 |
80 |
81 | Documentation
82 | -------------
83 |
84 | Documentation is at [docs/README.md](docs/README.md).
85 |
--------------------------------------------------------------------------------
/src/Console/RenameNamespaceCommand.php:
--------------------------------------------------------------------------------
1 |
18 | * @since 1.0
19 | */
20 | class RenameNamespaceCommand extends Command
21 | {
22 | use ConfirmableTrait;
23 |
24 | /**
25 | * {@inheritdoc}
26 | */
27 | protected $name = 'namespace:rename';
28 |
29 | /**
30 | * {@inheritdoc}
31 | */
32 | protected $signature = 'namespace:rename {path}
33 | {--from=app : Namespace to be renamed}
34 | {--to=legacy : New namespace name}
35 | {--force : Force the operation to run when in production}';
36 |
37 | /**
38 | * {@inheritdoc}
39 | */
40 | protected $description = 'Renames root namespace around PHP files in the specified directory.';
41 |
42 | /**
43 | * Execute the console command.
44 | *
45 | * @return mixed
46 | */
47 | public function handle()
48 | {
49 | $path = $this->argument('path');
50 |
51 | $namespaceFrom = trim($this->option('from'), '\\');
52 | $namespaceTo = trim($this->option('to'), '\\');
53 |
54 | if (! $this->confirmToProceed("Namespace '{$namespaceFrom}' will be changed to '{$namespaceTo}' will be replaced at '{$path}' files.")) {
55 | return;
56 | }
57 |
58 | $totalCount = 0;
59 | $modifiedCount = 0;
60 |
61 | foreach ($this->findFiles($path) as $file) {
62 | $totalCount++;
63 |
64 | if ($this->renameNamespace($file, $namespaceFrom, $namespaceTo)) {
65 | $this->line('Modified: '.$file->getPathname());
66 | $modifiedCount++;
67 | }
68 | }
69 |
70 | $this->info("Processed: {$totalCount} files. Modified: {$modifiedCount} files.");
71 | }
72 |
73 | /**
74 | * Finds the files for the replacement.
75 | *
76 | * @param string $path path to directory to be searched.
77 | * @return \Iterator|\Symfony\Component\Finder\SplFileInfo[] found files.
78 | */
79 | protected function findFiles($path): iterable
80 | {
81 | return Finder::create()
82 | ->files()
83 | ->ignoreDotFiles(true)
84 | ->ignoreVCS(true)
85 | ->name('*.php')
86 | ->in($path)
87 | ->getIterator();
88 | }
89 |
90 | /**
91 | * Renames namespace usages in given PHP file.
92 | *
93 | * @param string $file file name.
94 | * @param string $namespaceFrom namespace to be renamed
95 | * @param string $namespaceTo new namespace name.
96 | * @return bool whether file has been updated or not.
97 | */
98 | protected function renameNamespace(string $file, string $namespaceFrom, string $namespaceTo): bool
99 | {
100 | $content = file_get_contents($file);
101 |
102 | $newContent = preg_replace_callback('/^(namespace\\s+)(\\\\?'.preg_quote($namespaceFrom).')([^\\s]*;)(\\s*)$/m', function ($matches) use ($namespaceTo) {
103 | return $matches[1].$namespaceTo.$matches[3].$matches[4];
104 | }, $content);
105 |
106 | $newContent = preg_replace_callback('/^(use\\s+)(\\\\?'.preg_quote($namespaceFrom).')([^\\s]*;)(\\s*)$/m', function ($matches) use ($namespaceTo) {
107 | return $matches[1].$namespaceTo.$matches[3].$matches[4];
108 | }, $newContent);
109 |
110 | $newContent = preg_replace_callback('/(\\\\?)('.preg_quote($namespaceFrom).')(\\\\[^\\s]+::class)/m', function ($matches) use ($namespaceTo) {
111 | return $matches[1].$namespaceTo.$matches[3];
112 | }, $newContent);
113 |
114 | $newContent = preg_replace_callback('/(@see \\\\?)('.preg_quote($namespaceFrom).')(\\\\[^\\s]+\\s+)/m', function ($matches) use ($namespaceTo) {
115 | return $matches[1].$namespaceTo.$matches[3];
116 | }, $newContent);
117 |
118 | if (sha1($content) !== sha1($newContent)) {
119 | file_put_contents($file, $newContent);
120 |
121 | return true;
122 | }
123 |
124 | return false;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/Yii/I18n/I18n.php:
--------------------------------------------------------------------------------
1 | [
27 | * 'i18n' => [
28 | * 'class' => Yii2tech\Illuminate\Yii\I18n\I18n::class,
29 | * 'illuminateCategories' => [
30 | * 'auth',
31 | * 'validation',
32 | * ],
33 | * ],
34 | * // ...
35 | * ],
36 | * // ...
37 | * ];
38 | * ```
39 | *
40 | * @see \Illuminate\Translation\Translator
41 | *
42 | * @property \Illuminate\Translation\Translator $illuminateTranslator related Laravel translator.
43 | *
44 | * @author Paul Klimov
45 | * @since 1.0
46 | */
47 | class I18n extends \yii\i18n\I18N
48 | {
49 | /**
50 | * @var string[] list of translation categories, which should be passed to {@see $illuminateTranslator}.
51 | * Messages from these categories will be translated directly via Laravel translator without involving Yii.
52 | * Translation message key will be composed by concatenation of category, dot symbol ('.') and message.
53 | */
54 | public $illuminateCategories = [];
55 |
56 | /**
57 | * @var \Illuminate\Translation\Translator related Laravel translator.
58 | */
59 | private $_illuminateTranslator;
60 |
61 | /**
62 | * @return \Illuminate\Translation\Translator
63 | */
64 | public function getIlluminateTranslator(): Translator
65 | {
66 | if ($this->_illuminateTranslator === null) {
67 | $this->_illuminateTranslator = $this->defaultIlluminateTranslator();
68 | }
69 |
70 | return $this->_illuminateTranslator;
71 | }
72 |
73 | /**
74 | * @param \Illuminate\Translation\Translator $illuminateTranslator
75 | * @return static self reference.
76 | */
77 | public function setIlluminateTranslator(Translator $illuminateTranslator): self
78 | {
79 | $this->_illuminateTranslator = $illuminateTranslator;
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * @return Translator default Laravel translator.
86 | */
87 | protected function defaultIlluminateTranslator(): Translator
88 | {
89 | return \Illuminate\Container\Container::getInstance()->make('translator');
90 | }
91 |
92 | /**
93 | * {@inheritdoc}
94 | */
95 | public function translate($category, $message, $params, $language): string
96 | {
97 | if (in_array($category, $this->illuminateCategories, true)) {
98 | return $this->getIlluminateTranslator()->get($category.'.'.$message, $params, $language);
99 | }
100 |
101 | return parent::translate($category, $message, $params, $language);
102 | }
103 |
104 | /**
105 | * {@inheritdoc}
106 | */
107 | public function format($message, $params, $language): string
108 | {
109 | $params = (array) $params;
110 |
111 | $message = parent::format($message, $params, $language);
112 |
113 | return $this->makeReplacements($message, $params);
114 | }
115 |
116 | /**
117 | * Make the Laravel-like place-holder replacements on a translated message.
118 | * It replaces placeholders, marked by ':', which are not processed with original {@see format()} method.
119 | *
120 | * @param string $message raw message.
121 | * @param array $params the parameters that will be used for the replacement.
122 | * @return string the formatted message.
123 | */
124 | protected function makeReplacements($message, array $params)
125 | {
126 | if (empty($params)) {
127 | return $message;
128 | }
129 |
130 | uksort($params, function ($a, $b) {
131 | if (mb_strlen($a) > mb_strlen($b)) {
132 | return -1;
133 | }
134 |
135 | return 1;
136 | });
137 |
138 | foreach ($params as $key => $value) {
139 | $message = str_replace(
140 | [':'.$key, ':'.Str::upper($key), ':'.Str::ucfirst($key)],
141 | [$value, Str::upper($value), Str::ucfirst($value)],
142 | $message
143 | );
144 | }
145 |
146 | return $message;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/Yii/Web/User.php:
--------------------------------------------------------------------------------
1 | [
26 | * 'user' => Yii2tech\Illuminate\Yii\Web\User::class,
27 | * // ...
28 | * ],
29 | * // ...
30 | * ];
31 | * ```
32 | *
33 | * @see \Illuminate\Auth\AuthManager
34 | *
35 | * @property \Illuminate\Auth\AuthManager $illuminateAuthManager related Laravel auth manager.
36 | *
37 | * @author Paul Klimov
38 | * @since 1.0
39 | */
40 | class User extends \yii\web\User
41 | {
42 | /**
43 | * @var string|null guard to be used while retrieving identity from Laravel auth manager.
44 | */
45 | public $guard;
46 |
47 | /**
48 | * @var \yii\web\IdentityInterface|bool user identity.
49 | */
50 | private $_identity = false;
51 |
52 | /**
53 | * @var \Illuminate\Auth\AuthManager related Laravel auth manager.
54 | */
55 | private $_illuminateAuthManager;
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | public function getIdentity($autoRenew = true)
61 | {
62 | if ($this->_identity === false) {
63 | $identity = $this->getIlluminateAuthManager()->guard($this->guard)->user();
64 | if ($identity !== null) {
65 | $identity = $this->convertIlluminateIdentity($identity);
66 | }
67 |
68 | $this->_identity = $identity;
69 | }
70 |
71 | return $this->_identity;
72 | }
73 |
74 | /**
75 | * {@inheritdoc}
76 | */
77 | public function setIdentity($identity): void
78 | {
79 | parent::setIdentity($identity);
80 |
81 | $this->_identity = $identity;
82 | }
83 |
84 | /**
85 | * @return \Illuminate\Auth\AuthManager
86 | */
87 | public function getIlluminateAuthManager(): AuthManager
88 | {
89 | if ($this->_illuminateAuthManager === null) {
90 | $this->_illuminateAuthManager = $this->defaultIlluminateAuthManager();
91 | }
92 |
93 | return $this->_illuminateAuthManager;
94 | }
95 |
96 | /**
97 | * @param \Illuminate\Auth\AuthManager $authManager
98 | * @return static self reference.
99 | */
100 | public function setIlluminateAuthManager(AuthManager $authManager): self
101 | {
102 | $this->_illuminateAuthManager = $authManager;
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * @return \Illuminate\Auth\AuthManager default Laravel auth manager.
109 | */
110 | protected function defaultIlluminateAuthManager(): AuthManager
111 | {
112 | return Container::getInstance()->make('auth');
113 | }
114 |
115 | /**
116 | * {@inheritdoc}
117 | */
118 | public function switchIdentity($identity, $duration = 0): void
119 | {
120 | $this->setIdentity($identity);
121 |
122 | if ($identity === null) {
123 | $this->getIlluminateAuthManager()->guard($this->guard)->logout();
124 |
125 | return;
126 | }
127 |
128 | if ($identity instanceof BaseActiveRecord) {
129 | $id = $identity->getPrimaryKey();
130 | } else {
131 | $id = $identity->id;
132 | }
133 |
134 | $this->getIlluminateAuthManager()->guard($this->guard)->loginUsingId($id);
135 | }
136 |
137 | /**
138 | * Converts Laravel identity into Yii one.
139 | *
140 | * @param mixed $identity Laravel identity.
141 | * @return IdentityInterface Yii compatible identity instance.
142 | */
143 | protected function convertIlluminateIdentity($identity): IdentityInterface
144 | {
145 | if ($identity instanceof Model) {
146 | $id = $identity->getKey();
147 | $attributes = $identity->getAttributes();
148 | } elseif ($identity instanceof Authenticatable) {
149 | $id = $identity->getAuthIdentifier();
150 | $attributes = [];
151 | } elseif (is_array($identity) && isset($identity['id'])) {
152 | $id = $identity['id'];
153 | $attributes = $identity;
154 | } else {
155 | throw new RuntimeException('Unable to convert identity from "'.print_r($identity, true).'"');
156 | }
157 |
158 | $identityClass = $this->identityClass;
159 | if (! empty($attributes) && is_subclass_of($identityClass, BaseActiveRecord::class)) {
160 | $record = new $identityClass;
161 | call_user_func([$identityClass, 'populateRecord'], $record, $attributes);
162 |
163 | return $record;
164 | }
165 |
166 | return call_user_func([$identityClass, 'findIdentity'], $id);
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/Yii/Caching/Cache.php:
--------------------------------------------------------------------------------
1 | [
23 | * 'cache' => Yii2tech\Illuminate\Yii\Caching\Cache::class,
24 | * // ...
25 | * ],
26 | * // ...
27 | * ];
28 | * ```
29 | *
30 | * > Note: by default this component will not allow you to share particular cache keys between Yii and Laravel,
31 | * since Yii uses special prefix for the cache keys and stores data in serialized state. If you wish to share same
32 | * cache key you should disable {@see \yii\caching\Cache::$keyPrefix} and {@see \yii\caching\Cache::$serializer}.
33 | *
34 | * @see \yii\caching\Cache::$keyPrefix
35 | * @see \yii\caching\Cache::$serializer
36 | * @see \Illuminate\Contracts\Cache\Repository
37 | *
38 | * @property \Illuminate\Contracts\Cache\Repository $illuminateCache related Laravel cache repository.
39 | *
40 | * @author Paul Klimov
41 | * @since 1.0
42 | */
43 | class Cache extends \yii\caching\Cache
44 | {
45 | /**
46 | * @var \Illuminate\Contracts\Cache\Repository related Laravel cache repository.
47 | */
48 | private $_illuminateCache;
49 |
50 | /**
51 | * @return \Illuminate\Contracts\Cache\Repository
52 | */
53 | public function getIlluminateCache(): Repository
54 | {
55 | if ($this->_illuminateCache === null) {
56 | $this->_illuminateCache = $this->defaultIlluminateCache();
57 | }
58 |
59 | return $this->_illuminateCache;
60 | }
61 |
62 | /**
63 | * @param \Illuminate\Contracts\Cache\Repository $illuminateCache
64 | * @return static self reference.
65 | */
66 | public function setIlluminateCache(Repository $illuminateCache): self
67 | {
68 | $this->_illuminateCache = $illuminateCache;
69 |
70 | return $this;
71 | }
72 |
73 | /**
74 | * @return \Illuminate\Contracts\Cache\Repository default cache repository.
75 | */
76 | protected function defaultIlluminateCache(): Repository
77 | {
78 | return \Illuminate\Support\Facades\Cache::getFacadeRoot()->store();
79 | }
80 |
81 | /**
82 | * {@inheritdoc}
83 | */
84 | protected function getValue($key)
85 | {
86 | return $this->getIlluminateCache()->get($key, false);
87 | }
88 |
89 | /**
90 | * {@inheritdoc}
91 | */
92 | protected function setValue($key, $value, $duration): bool
93 | {
94 | $this->getIlluminateCache()->put($key, $value, $this->convertDuration($duration));
95 |
96 | return true;
97 | }
98 |
99 | /**
100 | * {@inheritdoc}
101 | */
102 | protected function addValue($key, $value, $duration): bool
103 | {
104 | return $this->getIlluminateCache()->add($key, $value, $this->convertDuration($duration));
105 | }
106 |
107 | /**
108 | * {@inheritdoc}
109 | */
110 | protected function deleteValue($key): bool
111 | {
112 | return $this->getIlluminateCache()->forget($key);
113 | }
114 |
115 | /**
116 | * {@inheritdoc}
117 | */
118 | protected function flushValues(): bool
119 | {
120 | return $this->getIlluminateCache()->clear();
121 | }
122 |
123 | /**
124 | * {@inheritdoc}
125 | */
126 | protected function getValues($keys)
127 | {
128 | return $this->getIlluminateCache()->getMultiple($keys, false);
129 | }
130 |
131 | /**
132 | * {@inheritdoc}
133 | */
134 | protected function setValues($data, $duration): array
135 | {
136 | $this->getIlluminateCache()->setMultiple($data, $this->convertDuration($duration));
137 |
138 | return [];
139 | }
140 |
141 | /**
142 | * {@inheritdoc}
143 | */
144 | protected function addValues($data, $duration): array
145 | {
146 | $values = $this->multiGet(array_keys($data));
147 |
148 | $failedKeys = [];
149 | $newValues = [];
150 |
151 | foreach ($values as $key => $value) {
152 | if ($value !== false) {
153 | $failedKeys[] = $key;
154 | continue;
155 | }
156 |
157 | $newValues[$key] = $data[$key];
158 | }
159 |
160 | $this->setValues($newValues, $duration);
161 |
162 | return $failedKeys;
163 | }
164 |
165 | /**
166 | * Converts cache duration specification from Yii to Laravel.
167 | *
168 | * @param float|int|null $duration cache duration in seconds, zero - means infinite.
169 | * @return float|int|null cache duration in seconds, `null` means infinite.
170 | */
171 | protected function convertDuration($duration)
172 | {
173 | return $duration == 0 ? null : $duration;
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/Yii/Web/Response.php:
--------------------------------------------------------------------------------
1 | [
26 | * 'response' => Yii2tech\Illuminate\Yii\Web\Response::class,
27 | * // ...
28 | * ],
29 | * // ...
30 | * ];
31 | * ```
32 | *
33 | * Usage of this component also allows returning of the response generated by Laravel from Yii controller. For example:
34 | *
35 | * ```php
36 | * class FooController extends \yii\web\Controller
37 | * {
38 | * public function actionFoo()
39 | * {
40 | * // ...
41 | * return Yii::$app->response->setIlluminateResponse(redirect('foo/create')->withInput());
42 | * }
43 | * }
44 | * ```
45 | *
46 | * @see \Illuminate\Http\Response
47 | * @see \Yii2tech\Illuminate\Http\YiiApplicationMiddleware
48 | *
49 | * @property \Illuminate\Http\Response $illuminateResponse related Laravel response.
50 | *
51 | * @author Paul Klimov
52 | * @since 1.0
53 | */
54 | class Response extends \yii\web\Response
55 | {
56 | /**
57 | * @var \Illuminate\Http\Response|null related Laravel response.
58 | */
59 | private $_illuminateResponse;
60 |
61 | /**
62 | * @param bool $create whether to create a response, if it is empty.
63 | * @return \Illuminate\Http\Response|null
64 | */
65 | public function getIlluminateResponse(bool $create = false): ?IlluminateResponse
66 | {
67 | if ($create && $this->_illuminateResponse === null) {
68 | $this->_illuminateResponse = $this->createIlluminateResponse();
69 | }
70 |
71 | return $this->_illuminateResponse;
72 | }
73 |
74 | /**
75 | * @param \Illuminate\Http\Response|null $illuminateResponse
76 | * @return static reference.
77 | */
78 | public function setIlluminateResponse(?IlluminateResponse $illuminateResponse): self
79 | {
80 | $this->_illuminateResponse = $illuminateResponse;
81 |
82 | return $this;
83 | }
84 |
85 | /**
86 | * Creates default {@see $illuminateResponse} instance.
87 | *
88 | * @return \Illuminate\Http\Response Laravel response instance.
89 | */
90 | protected function createIlluminateResponse(): IlluminateResponse
91 | {
92 | return \Illuminate\Container\Container::getInstance()->make(IlluminateResponse::class);
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | public function clear(): void
99 | {
100 | parent::clear();
101 |
102 | $this->setIlluminateResponse(null);
103 | }
104 |
105 | /**
106 | * {@inheritdoc}
107 | */
108 | public function send(): void
109 | {
110 | if ($this->getIlluminateResponse() !== null) {
111 | $this->isSent = true;
112 |
113 | return;
114 | }
115 |
116 | parent::send();
117 | }
118 |
119 | /**
120 | * {@inheritdoc}
121 | */
122 | protected function prepare(): void
123 | {
124 | if ($this->stream === null) {
125 | // avoid usage of response bridge for file sending, since it may cause PHP memory error.
126 | $response = $this->getIlluminateResponse();
127 | if ($response === null) {
128 | $this->setIlluminateResponse($this->createIlluminateResponse());
129 | }
130 | }
131 |
132 | parent::prepare();
133 | }
134 |
135 | /**
136 | * {@inheritdoc}
137 | */
138 | protected function sendHeaders(): void
139 | {
140 | $response = $this->getIlluminateResponse();
141 | if ($response === null) {
142 | parent::sendHeaders();
143 |
144 | return;
145 | }
146 |
147 | if (headers_sent($file, $line)) {
148 | throw new HeadersAlreadySentException($file, $line);
149 | }
150 |
151 | $response->setProtocolVersion($this->version);
152 | $response->setStatusCode($this->getStatusCode(), $this->statusText);
153 |
154 | foreach ($this->getHeaders() as $name => $values) {
155 | $response->headers->set($name, $values);
156 | }
157 |
158 | $this->sendCookies();
159 | }
160 |
161 | /**
162 | * {@inheritdoc}
163 | */
164 | protected function sendCookies(): void
165 | {
166 | $response = $this->getIlluminateResponse();
167 | if ($response === null) {
168 | parent::sendCookies();
169 |
170 | return;
171 | }
172 |
173 | $request = Yii::$app->getRequest();
174 | if ($request->enableCookieValidation) {
175 | if ($request->cookieValidationKey == '') {
176 | throw new InvalidConfigException(get_class($request) . '::$cookieValidationKey must be configured with a secret key.');
177 | }
178 | $validationKey = $request->cookieValidationKey;
179 | }
180 |
181 | foreach ($this->getCookies() as $cookie) {
182 | $value = $cookie->value;
183 | if ($cookie->expire != 1 && isset($validationKey)) {
184 | $value = Yii::$app->getSecurity()->hashData(serialize([$cookie->name, $value]), $validationKey);
185 | }
186 |
187 | $response->headers->setCookie(new Cookie($cookie->name, $value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->secure, $cookie->httpOnly));
188 | }
189 | }
190 |
191 | /**
192 | * {@inheritdoc}
193 | */
194 | protected function sendContent(): void
195 | {
196 | $response = $this->getIlluminateResponse();
197 | if ($response === null) {
198 | parent::sendContent();
199 |
200 | return;
201 | }
202 |
203 | if ($this->stream === null) {
204 | $response->setContent($this->content);
205 |
206 | return;
207 | }
208 |
209 | ob_start();
210 | ob_implicit_flush(false);
211 |
212 | try {
213 | parent::sendContent();
214 |
215 | $response->setContent(ob_get_clean());
216 | } catch (\Throwable $e) {
217 | if (!@ob_end_clean()) {
218 | ob_clean();
219 | }
220 | throw $e;
221 | }
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/src/Http/YiiApplicationMiddleware.php:
--------------------------------------------------------------------------------
1 | middleware(Yii2tech\Illuminate\Http\YiiApplicationMiddleware::class)
51 | * ->where('fallbackPlaceholder', '.*')
52 | * ->fallback();
53 | * ```
54 | *
55 | * Each middleware instance is automatically configured from the configuration key 'yii.middleware' using [array factory](https://github.com/illuminatech/array-factory).
56 | *
57 | * @see \Illuminatech\ArrayFactory\FactoryContract
58 | * @see \Yii2tech\Illuminate\Yii\Web\Response
59 | * @see DummyResponse
60 | *
61 | * @author Paul Klimov
62 | * @since 1.0
63 | */
64 | class YiiApplicationMiddleware
65 | {
66 | /**
67 | * @var string default path to Yii application entry script relative to the project base path.
68 | * This value will be used only in case entry script is not specified as a middleware parameter.
69 | */
70 | public $defaultEntryScript = 'legacy/web/index.php';
71 |
72 | /**
73 | * @var string|null path to bootstrap file, which should be included before defining constants and including `Yii.php`.
74 | */
75 | public $bootstrap;
76 |
77 | /**
78 | * @var array|null array configuration for Yii DI container to be applied during Yii bootstrap.
79 | * If not set - container will not be explicitly setup.
80 | * @see FactoryContract::make()
81 | *
82 | * Example:
83 | *
84 | * ```php
85 | * [
86 | * '__class' => Yii2tech\Illuminate\Yii\Di\Container::class,
87 | * ]
88 | * ```
89 | */
90 | public $container;
91 |
92 | /**
93 | * @var array|null array configuration for Yii logger to be applied during Yii bootstrap.
94 | * If not set - logger will not be explicitly setup.
95 | * @see FactoryContract::make()
96 | *
97 | * Example:
98 | *
99 | * ```php
100 | * [
101 | * '__class' => Yii2tech\Illuminate\Yii\Log\Logger::class,
102 | * ]
103 | * ```
104 | */
105 | public $logger;
106 |
107 | /**
108 | * @var bool whether to perform cleanup of Yii application.
109 | */
110 | public $cleanup = true;
111 |
112 | /**
113 | * @var \Illuminate\Contracts\Foundation\Application Laravel application instance.
114 | */
115 | protected $app;
116 |
117 | /**
118 | * Constructor.
119 | *
120 | * @param Application $app Laravel application instance.
121 | */
122 | public function __construct(Application $app)
123 | {
124 | $this->app = $app;
125 |
126 | $this->getFactory()->configure($this, $this->app->get('config')->get('yii.middleware', []));
127 | }
128 |
129 | /**
130 | * Returns related array factory for components creation and configuration.
131 | *
132 | * @return FactoryContract array factory instance.
133 | */
134 | public function getFactory(): FactoryContract
135 | {
136 | return $this->app->make(FactoryContract::class);
137 | }
138 |
139 | /**
140 | * Handle an incoming request, attempting to resolve it via Yii web application.
141 | *
142 | * @param \Illuminate\Http\Request $request request to be processed.
143 | * @param \Closure $next next pipeline request handler.
144 | * @param string|null $entryScript path to Yii application entry script relative to the project base path.
145 | * @return mixed
146 | */
147 | public function handle(Request $request, Closure $next, ?string $entryScript = null)
148 | {
149 | $this->bootstrapYii();
150 |
151 | try {
152 | return $this->runYii($entryScript);
153 | } catch (YiiHttpException $e) {
154 | $this->cleanup();
155 |
156 | if ($e->statusCode == 404) {
157 | // If Yii indicates page does not exist - pass its resolving to Laravel
158 | return $next($request);
159 | }
160 |
161 | throw new HttpException($e->statusCode, $e->getMessage(), $e, [], $e->getCode());
162 | } catch (YiiExitException $e) {
163 | // In case Yii requests application termination - request is considered as handled
164 | return $this->createResponse();
165 | }
166 | }
167 |
168 | /**
169 | * Makes preparations for Yii application run.
170 | */
171 | protected function bootstrapYii()
172 | {
173 | if ($this->bootstrap) {
174 | require $this->bootstrap;
175 | }
176 |
177 | defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER', false);
178 |
179 | defined('YII_DEBUG') or define('YII_DEBUG', $this->app->get('config')->get('app.debug', false));
180 |
181 | if (! defined('YII_ENV')) {
182 | $environment = $this->app->get('config')->get('app.env', 'production');
183 | switch ($environment) {
184 | case 'production':
185 | $environment = 'prod';
186 | break;
187 | case 'local':
188 | case 'development':
189 | $environment = 'dev';
190 | break;
191 | case 'testing':
192 | $environment = 'test';
193 | break;
194 | }
195 |
196 | define('YII_ENV', $environment);
197 | }
198 |
199 | if (! class_exists('Yii')) {
200 | require $this->app->make('path.base').'/vendor/yiisoft/yii2/Yii.php';
201 | }
202 |
203 | if ($this->container) {
204 | Yii::$container = $this->getFactory()->make($this->container);
205 | }
206 |
207 | if ($this->logger) {
208 | Yii::setLogger($this->getFactory()->make($this->logger));
209 | }
210 | }
211 |
212 | /**
213 | * Runs Yii application from the given entry PHP script.
214 | *
215 | * @param string|null $entryScript path to Yii application entry script relative to the project base path.
216 | * @return \Illuminate\Http\Response HTTP response instance.
217 | */
218 | protected function runYii(?string $entryScript = null): Response
219 | {
220 | if ($entryScript === null) {
221 | $entryScript = $this->defaultEntryScript;
222 | }
223 |
224 | $entryScript = $this->app->make('path.base').DIRECTORY_SEPARATOR.$entryScript;
225 |
226 | require $entryScript;
227 |
228 | return $this->createResponse();
229 | }
230 |
231 | /**
232 | * Performs clean up after running Yii application in case {@see $cleanup} is enabled.
233 | */
234 | protected function cleanup()
235 | {
236 | if ($this->cleanup) {
237 | $this->terminateYii();
238 | }
239 | }
240 |
241 | /**
242 | * Preforms clean up after running Yii application.
243 | */
244 | protected function terminateYii()
245 | {
246 | Yii::$classMap = [];
247 | Yii::$aliases = [];
248 |
249 | Yii::setLogger(null);
250 | Yii::$app = null;
251 | Yii::$container = null;
252 | }
253 |
254 | /**
255 | * Creates HTTP response for this middleware.
256 | * In case Yii application uses response, which allows its conversion into Laravel one, such conversion will be perfromed.
257 | * Otherwise a dummy response will be generated.
258 | * This method performs automatic clean up.
259 | *
260 | * @see \Yii2tech\Illuminate\Yii\Web\Response
261 | * @see DummyResponse
262 | *
263 | * @return \Illuminate\Http\Response HTTP response instance.
264 | */
265 | protected function createResponse(): Response
266 | {
267 | if (headers_sent()) {
268 | $this->cleanup();
269 |
270 | return new DummyResponse();
271 | }
272 |
273 | $yiiResponse = Yii::$app ? Yii::$app->get('response') : null;
274 |
275 | $this->cleanup();
276 |
277 | if ($yiiResponse instanceof \Yii2tech\Illuminate\Yii\Web\Response) {
278 | return $yiiResponse->getIlluminateResponse(true);
279 | }
280 |
281 | return new DummyResponse();
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/src/Yii/Web/Request.php:
--------------------------------------------------------------------------------
1 | [
26 | * 'request' => [
27 | * 'class' => Yii2tech\Illuminate\Yii\Web\Request::class,
28 | * ],
29 | * // ...
30 | * ],
31 | * // ...
32 | * ];
33 | * ```
34 | *
35 | * @see \Illuminate\Http\Request
36 | *
37 | * @author Paul Klimov
38 | * @since 1.0
39 | */
40 | class Request extends \yii\web\Request
41 | {
42 | /**
43 | * {@inheritdoc}
44 | */
45 | public $csrfParam = '_token';
46 |
47 | /**
48 | * @var bool whether to use CSRF generation/validation supplied by Laravel.
49 | * If enabled make sure {@see $csrfParam} is set to '_token'.
50 | */
51 | public $useIlluminateCsrfValildation = false;
52 |
53 | /**
54 | * @var \Illuminate\Http\Request related Laravel HTTP request.
55 | */
56 | private $_illuminateRequest;
57 |
58 | /**
59 | * @var \yii\web\HeaderCollection request headers.
60 | */
61 | private $_headers;
62 |
63 | /**
64 | * @var string raw body content.
65 | */
66 | private $_rawBody;
67 |
68 | /**
69 | * @var array|null the request body parameters.
70 | */
71 | private $_bodyParams;
72 |
73 | /**
74 | * @return \Illuminate\Http\Request
75 | */
76 | public function getIlluminateRequest(): IlluminateRequest
77 | {
78 | if ($this->_illuminateRequest === null) {
79 | $this->_illuminateRequest = $this->defaultIlluminateRequest();
80 | }
81 |
82 | return $this->_illuminateRequest;
83 | }
84 |
85 | /**
86 | * @param \Illuminate\Http\Request $illuminateRequest
87 | * @return static self reference.
88 | */
89 | public function setIlluminateRequest(IlluminateRequest $illuminateRequest): self
90 | {
91 | $this->_illuminateRequest = $illuminateRequest;
92 |
93 | return $this;
94 | }
95 |
96 | /**
97 | * @return \Illuminate\Http\Request default related Laravel HTTP request.
98 | */
99 | protected function defaultIlluminateRequest(): IlluminateRequest
100 | {
101 | return \Illuminate\Container\Container::getInstance()->make('request');
102 | }
103 |
104 | /**
105 | * {@inheritdoc}
106 | */
107 | public function getHeaders()
108 | {
109 | if ($this->_headers === null) {
110 | $this->_headers = new HeaderCollection();
111 | foreach ($this->getIlluminateRequest()->headers->all() as $name => $values) {
112 | $this->_headers->set($name, $values);
113 | }
114 | }
115 |
116 | return $this->_headers;
117 | }
118 |
119 | /**
120 | * {@inheritdoc}
121 | */
122 | public function getMethod(): string
123 | {
124 | return $this->getIlluminateRequest()->getMethod();
125 | }
126 |
127 | /**
128 | * {@inheritdoc}
129 | */
130 | public function getRawBody()
131 | {
132 | if ($this->_rawBody === null) {
133 | $this->_rawBody = $this->getIlluminateRequest()->getContent();
134 | }
135 |
136 | return $this->_rawBody;
137 | }
138 |
139 | /**
140 | * {@inheritdoc}
141 | */
142 | public function setRawBody($rawBody): void
143 | {
144 | $this->_rawBody = $rawBody;
145 | }
146 |
147 | /**
148 | * {@inheritdoc}
149 | */
150 | public function getBodyParams()
151 | {
152 | if ($this->_bodyParams === null) {
153 | $illuminateRequest = $this->getIlluminateRequest();
154 | if ($illuminateRequest->isJson()) {
155 | $this->_bodyParams = $illuminateRequest->json()->all();
156 | } elseif ($this->getContentType() === 'application/x-www-form-urlencoded') {
157 | $this->_bodyParams = $illuminateRequest->request->all();
158 | } else {
159 | $this->_bodyParams = parent::getBodyParams();
160 | }
161 | }
162 |
163 | return $this->_bodyParams;
164 | }
165 |
166 | /**
167 | * {@inheritdoc}
168 | */
169 | public function setBodyParams($values)
170 | {
171 | $this->_bodyParams = $values;
172 | }
173 |
174 | /**
175 | * {@inheritdoc}
176 | * @since 1.1.2
177 | */
178 | public function getScriptUrl()
179 | {
180 | try {
181 | return parent::getScriptUrl();
182 | } catch (InvalidConfigException $e) {
183 | // Illuminate request does not provide script URL, thus set up a mock, if Yii fails to determine it
184 | $this->setScriptUrl('/index.php');
185 | }
186 |
187 | return parent::getScriptUrl();
188 | }
189 |
190 | /**
191 | * {@inheritdoc}
192 | * @since 1.1.2
193 | */
194 | protected function resolveRequestUri()
195 | {
196 | return $this->getIlluminateRequest()->getRequestUri();
197 | }
198 |
199 | /**
200 | * {@inheritdoc}
201 | */
202 | protected function loadCookies()
203 | {
204 | $cookies = [];
205 | if ($this->enableCookieValidation) {
206 | if ($this->cookieValidationKey == '') {
207 | throw new InvalidConfigException(get_class($this) . '::$cookieValidationKey must be configured with a secret key.');
208 | }
209 | foreach ($this->getIlluminateRequest()->cookies as $name => $value) {
210 | if (! is_string($value)) {
211 | continue;
212 | }
213 | $data = Yii::$app->getSecurity()->validateData($value, $this->cookieValidationKey);
214 | if ($data === false) {
215 | continue;
216 | }
217 | $data = @unserialize($data);
218 | if (is_array($data) && isset($data[0], $data[1]) && $data[0] === $name) {
219 | $cookies[$name] = Yii::createObject([
220 | 'class' => \yii\web\Cookie::class,
221 | 'name' => $name,
222 | 'value' => $data[1],
223 | 'expire' => null,
224 | ]);
225 | }
226 | }
227 | } else {
228 | foreach ($this->getIlluminateRequest()->cookies as $name => $value) {
229 | $cookies[$name] = Yii::createObject([
230 | 'class' => \yii\web\Cookie::class,
231 | 'name' => $name,
232 | 'value' => $value,
233 | 'expire' => null,
234 | ]);
235 | }
236 | }
237 |
238 | return $cookies;
239 | }
240 |
241 | /**
242 | * {@inheritdoc}
243 | */
244 | public function getCsrfToken($regenerate = false)
245 | {
246 | if (! $this->useIlluminateCsrfValildation) {
247 | return parent::getCsrfToken($regenerate);
248 | }
249 |
250 | if ($regenerate) {
251 | return $this->generateCsrfToken();
252 | }
253 |
254 | return $this->loadCsrfToken();
255 | }
256 |
257 | /**
258 | * {@inheritdoc}
259 | */
260 | protected function loadCsrfToken()
261 | {
262 | if (! $this->useIlluminateCsrfValildation) {
263 | return parent::loadCsrfToken();
264 | }
265 |
266 | return $this->getIlluminateRequest()->session()->token();
267 | }
268 |
269 | /**
270 | * {@inheritdoc}
271 | */
272 | protected function generateCsrfToken()
273 | {
274 | if (! $this->useIlluminateCsrfValildation) {
275 | return parent::generateCsrfToken();
276 | }
277 |
278 | $session = $this->getIlluminateRequest()->session();
279 | $session->regenerateToken();
280 |
281 | return $session->token();
282 | }
283 |
284 | /**
285 | * {@inheritdoc}
286 | */
287 | public function validateCsrfToken($clientSuppliedToken = null)
288 | {
289 | if (! $this->useIlluminateCsrfValildation) {
290 | return parent::validateCsrfToken($clientSuppliedToken);
291 | }
292 |
293 | $method = $this->getMethod();
294 | // only validate CSRF token on non-"safe" methods https://tools.ietf.org/html/rfc2616#section-9.1.1
295 | if (!$this->enableCsrfValidation || in_array($method, ['GET', 'HEAD', 'OPTIONS'], true)) {
296 | return true;
297 | }
298 |
299 | $trueToken = $this->getCsrfToken();
300 |
301 | if ($clientSuppliedToken !== null) {
302 | return $this->validateCsrfTokenInternal($clientSuppliedToken, $trueToken);
303 | }
304 |
305 | return $this->validateCsrfTokenInternal($this->getBodyParam($this->csrfParam), $trueToken)
306 | || $this->validateCsrfTokenInternal($this->getCsrfTokenFromHeader(), $trueToken);
307 | }
308 |
309 | /**
310 | * Validates CSRF token.
311 | * @see \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::tokensMatch()
312 | *
313 | * @param string $clientSuppliedToken The masked client-supplied token.
314 | * @param string $trueToken The masked true token.
315 | * @return bool
316 | */
317 | private function validateCsrfTokenInternal($clientSuppliedToken, $trueToken): bool
318 | {
319 | if (! is_string($clientSuppliedToken)) {
320 | return false;
321 | }
322 |
323 | return hash_equals($trueToken, $clientSuppliedToken);
324 | }
325 |
326 | /**
327 | * Get all of the input and files for the request.
328 | *
329 | * @param array|null $keys input keys to retrieve, `null` means all input.
330 | * @return array input data.
331 | */
332 | public function all($keys = null): array
333 | {
334 | return $this->getIlluminateRequest()->all($keys);
335 | }
336 |
337 | /**
338 | * Runs Laravel validation on request data.
339 | * @see \Illuminate\Foundation\Providers\FoundationServiceProvider::registerRequestValidation()
340 | * @see \Illuminate\Validation\Factory::validate()
341 | *
342 | * @param array $rules validation rules.
343 | * @param array $messages error messages.
344 | * @param array $customAttributes
345 | * @return array validated data.
346 | *
347 | * @throws \Illuminate\Validation\ValidationException if validation fails.
348 | */
349 | public function validate(array $rules, array $messages = [], array $customAttributes = []): array
350 | {
351 | return $this->getIlluminateRequest()->validate($rules, $messages, $customAttributes);
352 | }
353 | }
354 |
--------------------------------------------------------------------------------
/src/Yii/Web/Session.php:
--------------------------------------------------------------------------------
1 | [
25 | * 'session' => Yii2tech\Illuminate\Yii\Web\Session::class,
26 | * // ...
27 | * ],
28 | * // ...
29 | * ];
30 | * ```
31 | *
32 | * > Note: usage of this component requires Yii application running within {@see \Illuminate\Session\Middleware\StartSession} middleware.
33 | *
34 | * @see \Illuminate\Session\Store
35 | *
36 | * @property \Illuminate\Session\Store $illuminateSession related Laravel session instance.
37 | *
38 | * @author Paul Klimov
39 | * @since 1.0
40 | */
41 | class Session extends \yii\web\Session
42 | {
43 | /**
44 | * {@inheritdoc}
45 | */
46 | public $flashParam = '__yii_flash';
47 |
48 | /**
49 | * @var \Illuminate\Session\Store
50 | */
51 | private $_illuminateSession;
52 |
53 | /**
54 | * @return \Illuminate\Session\Store Laravel session store.
55 | */
56 | public function getIlluminateSession(): Store
57 | {
58 | if ($this->_illuminateSession === null) {
59 | $this->_illuminateSession = $this->defaultIlluminateSession();
60 | }
61 |
62 | return $this->_illuminateSession;
63 | }
64 |
65 | /**
66 | * @param \Illuminate\Session\Store $session Laravel session store.
67 | * @return static self reference.
68 | */
69 | public function setIlluminateSession(Store $session): self
70 | {
71 | $this->_illuminateSession = $session;
72 |
73 | return $this;
74 | }
75 |
76 | /**
77 | * @return Store session store instance.
78 | */
79 | protected function defaultIlluminateSession(): Store
80 | {
81 | return \Illuminate\Support\Facades\Session::getFacadeRoot()->driver();
82 | }
83 |
84 | /**
85 | * {@inheritdoc}
86 | */
87 | public function init(): void
88 | {
89 | Component::init(); // skip parent init, avoiding `register_shutdown_function()` call.
90 | }
91 |
92 | /**
93 | * {@inheritdoc}
94 | */
95 | public function open(): void
96 | {
97 | if ($this->getIsActive()) {
98 | return;
99 | }
100 |
101 | $this->getIlluminateSession()->start();
102 | }
103 |
104 | /**
105 | * {@inheritdoc}
106 | */
107 | public function close(): void
108 | {
109 | if ($this->getIsActive()) {
110 | $this->getIlluminateSession()->save();
111 | }
112 | }
113 |
114 | /**
115 | * {@inheritdoc}
116 | */
117 | public function destroy(): void
118 | {
119 | if ($this->getIsActive()) {
120 | $this->getIlluminateSession()->invalidate();
121 | }
122 | }
123 |
124 | /**
125 | * {@inheritdoc}
126 | */
127 | public function getIsActive(): bool
128 | {
129 | return $this->getIlluminateSession()->isStarted();
130 | }
131 |
132 | /**
133 | * {@inheritdoc}
134 | */
135 | public function getId()
136 | {
137 | return $this->getIlluminateSession()->getId();
138 | }
139 |
140 | /**
141 | * {@inheritdoc}
142 | */
143 | public function setId($value): void
144 | {
145 | $this->getIlluminateSession()->setId($value);
146 | }
147 |
148 | /**
149 | * {@inheritdoc}
150 | */
151 | public function regenerateID($deleteOldSession = false): void
152 | {
153 | if ($this->getIsActive()) {
154 | $this->getIlluminateSession()->regenerate($deleteOldSession);
155 | }
156 | }
157 |
158 | /**
159 | * {@inheritdoc}
160 | */
161 | public function getName()
162 | {
163 | return $this->getIlluminateSession()->getName();
164 | }
165 |
166 | /**
167 | * {@inheritdoc}
168 | */
169 | public function setName($value): void
170 | {
171 | $this->getIlluminateSession()->setName($value);
172 | }
173 |
174 | /**
175 | * {@inheritdoc}
176 | */
177 | public function getIterator()
178 | {
179 | $this->open();
180 |
181 | return new ArrayIterator($this->getIlluminateSession()->all());
182 | }
183 |
184 | /**
185 | * {@inheritdoc}
186 | */
187 | public function getCount(): int
188 | {
189 | $this->open();
190 |
191 | return count($this->getIlluminateSession()->all());
192 | }
193 |
194 | /**
195 | * {@inheritdoc}
196 | */
197 | public function get($key, $defaultValue = null)
198 | {
199 | $this->open();
200 |
201 | return $this->getIlluminateSession()->get($key, $defaultValue);
202 | }
203 |
204 | /**
205 | * {@inheritdoc}
206 | */
207 | public function set($key, $value)
208 | {
209 | $this->open();
210 |
211 | $this->getIlluminateSession()->put($key, $value);
212 | }
213 |
214 | /**
215 | * {@inheritdoc}
216 | */
217 | public function remove($key)
218 | {
219 | $this->open();
220 |
221 | return $this->getIlluminateSession()->pull($key);
222 | }
223 |
224 | /**
225 | * {@inheritdoc}
226 | */
227 | public function removeAll(): void
228 | {
229 | $this->open();
230 | $this->getIlluminateSession()->flush();
231 | }
232 |
233 | /**
234 | * {@inheritdoc}
235 | */
236 | public function has($key): bool
237 | {
238 | $this->open();
239 |
240 | return $this->getIlluminateSession()->has($key);
241 | }
242 |
243 | // Flash :
244 |
245 | /**
246 | * {@inheritdoc}
247 | */
248 | protected function updateFlashCounters(): void
249 | {
250 | $counters = $this->get($this->flashParam, []);
251 | if (is_array($counters)) {
252 | foreach ($counters as $key => $count) {
253 | if ($count > 0) {
254 | unset($counters[$key]);
255 | $this->remove($key);
256 | } elseif ($count == 0) {
257 | $counters[$key]++;
258 | }
259 | }
260 | $this->set($this->flashParam, $counters);
261 | } else {
262 | // fix the unexpected problem that flashParam doesn't return an array
263 | $this->remove($this->flashParam);
264 | }
265 | }
266 |
267 | /**
268 | * {@inheritdoc}
269 | */
270 | public function getFlash($key, $defaultValue = null, $delete = false)
271 | {
272 | $counters = $this->get($this->flashParam, []);
273 | if (isset($counters[$key])) {
274 | $value = $this->get($key, $defaultValue);
275 | if ($delete) {
276 | $this->removeFlash($key);
277 | } elseif ($counters[$key] < 0) {
278 | // mark for deletion in the next request
279 | $counters[$key] = 1;
280 | $this->set($this->flashParam, $counters);
281 | }
282 |
283 | return $value;
284 | }
285 |
286 | return $defaultValue;
287 | }
288 |
289 | /**
290 | * {@inheritdoc}
291 | */
292 | public function getAllFlashes($delete = false): array
293 | {
294 | $counters = $this->get($this->flashParam, []);
295 | $flashes = [];
296 |
297 | $session = $this->getIlluminateSession()->all();
298 |
299 | foreach (array_keys($counters) as $key) {
300 | if (array_key_exists($key, $session)) {
301 | $flashes[$key] = $session[$key];
302 | if ($delete) {
303 | unset($counters[$key], $session[$key]);
304 | $this->remove($key);
305 | } elseif ($counters[$key] < 0) {
306 | // mark for deletion in the next request
307 | $counters[$key] = 1;
308 | }
309 | } else {
310 | unset($counters[$key]);
311 | }
312 | }
313 |
314 | $this->set($this->flashParam, $counters);
315 |
316 | return $flashes;
317 | }
318 |
319 | /**
320 | * {@inheritdoc}
321 | */
322 | public function setFlash($key, $value = true, $removeAfterAccess = true): void
323 | {
324 | $counters = $this->get($this->flashParam, []);
325 | $counters[$key] = $removeAfterAccess ? -1 : 0;
326 |
327 | $this->set($key, $value);
328 | $this->set($this->flashParam, $counters);
329 | }
330 |
331 | /**
332 | * {@inheritdoc}
333 | */
334 | public function addFlash($key, $value = true, $removeAfterAccess = true): void
335 | {
336 | $counters = $this->get($this->flashParam, []);
337 | $counters[$key] = $removeAfterAccess ? -1 : 0;
338 |
339 | $this->set($this->flashParam, $counters);
340 | $session = $this->getIlluminateSession()->all();
341 |
342 | if (empty($session[$key])) {
343 | $session[$key] = [$value];
344 | } elseif (is_array($session[$key])) {
345 | $session[$key][] = $value;
346 | } else {
347 | $session[$key] = [$session[$key], $value];
348 | }
349 |
350 | $this->set($key, $session[$key]);
351 | }
352 |
353 | /**
354 | * {@inheritdoc}
355 | */
356 | public function removeFlash($key)
357 | {
358 | $counters = $this->get($this->flashParam, []);
359 | $session = $this->getIlluminateSession()->all();
360 | $value = isset($session[$key], $counters[$key]) ? $session[$key] : null;
361 | unset($counters[$key]);
362 | $this->remove($key);
363 | $this->set($this->flashParam, $counters);
364 |
365 | return $value;
366 | }
367 |
368 | /**
369 | * {@inheritdoc}
370 | */
371 | public function removeAllFlashes(): void
372 | {
373 | $counters = $this->get($this->flashParam, []);
374 | foreach (array_keys($counters) as $key) {
375 | $this->remove($key);
376 | }
377 | $this->remove($this->flashParam);
378 | }
379 |
380 | /**
381 | * {@inheritdoc}
382 | */
383 | public function hasFlash($key): bool
384 | {
385 | return $this->getFlash($key) !== null;
386 | }
387 |
388 | // ArrayAccess :
389 |
390 | /**
391 | * {@inheritdoc}
392 | */
393 | public function offsetExists($offset)
394 | {
395 | $this->open();
396 | $session = $this->getIlluminateSession()->all();
397 |
398 | return isset($session[$offset]);
399 | }
400 |
401 | /**
402 | * {@inheritdoc}
403 | */
404 | public function offsetGet($offset)
405 | {
406 | $this->open();
407 |
408 | return $this->getIlluminateSession()->get($offset);
409 | }
410 |
411 | /**
412 | * {@inheritdoc}
413 | */
414 | public function offsetSet($offset, $item)
415 | {
416 | $this->open();
417 |
418 | $this->getIlluminateSession()->put($offset, $item);
419 | }
420 |
421 | /**
422 | * {@inheritdoc}
423 | */
424 | public function offsetUnset($offset)
425 | {
426 | $this->open();
427 |
428 | $this->getIlluminateSession()->forget($offset);
429 | }
430 | }
431 |
--------------------------------------------------------------------------------