├── public ├── favicon.ico ├── robots.txt ├── .htaccess └── index.php ├── .gitattributes ├── app └── Console │ ├── Commands │ ├── .gitkeep │ ├── stubs │ │ ├── controller.stub │ │ ├── controller.model.stub │ │ └── controller.model.paginate.stub │ └── ControllerMakeCommand.php │ └── Kernel.php ├── bootstrap ├── cache │ └── .gitignore ├── Console │ ├── stubs │ │ ├── model.pivot.stub │ │ ├── seeder.stub │ │ ├── controller.stub │ │ ├── resource.stub │ │ ├── resource-collection.stub │ │ ├── factory.stub │ │ ├── console.stub │ │ ├── model.stub │ │ ├── controller.model.stub │ │ └── controller.model.paginate.stub │ ├── ExceptionHandler.php │ ├── EnvironmentCommand.php │ ├── ArtisanFacade.php │ ├── PackageDiscoverCommand.php │ ├── ComposerScripts.php │ ├── ClosureCommand.php │ ├── ServeCommand.php │ ├── AutoloadCommand.php │ ├── ConsoleMakeCommand.php │ ├── SeedMakeCommand.php │ ├── IlluminateCaster.php │ ├── TinkerCommand.php │ ├── FactoryMakeCommand.php │ ├── VendorPublishCommand.php │ ├── PackageManifest.php │ ├── ProviderRepository.php │ ├── Artisan.php │ ├── ModelMakeCommand.php │ └── GeneratorCommand.php ├── Contracts │ └── Config.php ├── start.php ├── Config │ └── Config.php ├── autoload.php ├── helpers.php └── Container │ └── Application.php ├── storage ├── logs │ └── .gitignore ├── app │ ├── public │ │ └── .gitignore │ └── .gitignore └── framework │ ├── testing │ └── .gitignore │ ├── views │ └── .gitignore │ ├── cache │ ├── data │ │ └── .gitignore │ └── .gitignore │ ├── sessions │ └── .gitignore │ └── .gitignore ├── database ├── .gitignore ├── seeds │ └── DatabaseSeeder.php ├── migrations │ ├── 2014_10_12_100000_create_password_resets_table.php │ └── 2014_10_12_000000_create_users_table.php └── factories │ └── UserFactory.php ├── .github └── FUNDING.yml ├── .gitignore ├── routes ├── api.php └── console.php ├── server.php ├── .env.example ├── phpunit.xml ├── _ide_helper_models.php ├── artisan ├── composer.json ├── config ├── queue.php ├── app.php ├── cache.php └── database.php ├── README.md └── .phpstorm.meta.php /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /app/Console/Commands/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | *.sqlite-journal 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: 2 | - https://www.paypal.com/paypalme/luracast 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bootstrap/compiled.php 2 | /vendor 3 | composer.phar 4 | composer.lock 5 | .env 6 | .DS_Store 7 | Thumbs.db 8 | .idea 9 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /bootstrap/Console/stubs/model.pivot.stub: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /bootstrap/Console/stubs/controller.stub: -------------------------------------------------------------------------------- 1 | getMessage(); 14 | } 15 | 16 | /** 17 | * Register an application error handler. 18 | * 19 | * @param Closure $callback 20 | * 21 | * @return void 22 | */ 23 | public function error(Closure $callback) 24 | { 25 | array_unshift($this->handlers, $callback); 26 | } 27 | } -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./app/tests/ 16 | 17 | 18 | -------------------------------------------------------------------------------- /_ide_helper_models.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | 12 | 13 | namespace { 14 | /** 15 | * User 16 | * 17 | * @method static \Illuminate\Database\Eloquent\Builder|\User newModelQuery() 18 | * @method static \Illuminate\Database\Eloquent\Builder|\User newQuery() 19 | * @method static \Illuminate\Database\Eloquent\Builder|\User query() 20 | */ 21 | class User extends \Eloquent {} 22 | } 23 | 24 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /bootstrap/Console/EnvironmentCommand.php: -------------------------------------------------------------------------------- 1 | line('Current application environment: '.$this->laravel['env'].''); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment("All is well"); 20 | })->describe('Display an inspiring quote'); 21 | 22 | 23 | //Artisan::add(new MyCommand()); 24 | Artisan::add(new ControllerMakeCommand($app['files'])); 25 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /bootstrap/Console/stubs/console.stub: -------------------------------------------------------------------------------- 1 | $this->faker->name(), 20 | 'email' => $this->faker->unique()->safeEmail(), 21 | 'email_verified_at' => now(), 22 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 23 | 'remember_token' => Str::random(10), 24 | ]; 25 | } 26 | 27 | protected function withFaker() 28 | { 29 | return FakerFactory::create('en_US'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bootstrap/Console/ArtisanFacade.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 28 | } 29 | 30 | /** 31 | * Register the commands for the application. 32 | * 33 | * @return void 34 | */ 35 | protected function commands() 36 | { 37 | $this->load(__DIR__.'/Commands'); 38 | 39 | require base_path('routes/console.php'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /bootstrap/Console/PackageDiscoverCommand.php: -------------------------------------------------------------------------------- 1 | build(); 32 | 33 | foreach (array_keys($manifest->getManifest()) as $package) { 34 | $this->line("Discovered Package: {$package}"); 35 | } 36 | 37 | $this->info('Package manifest generated successfully.'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 35 | 36 | exit($status); -------------------------------------------------------------------------------- /bootstrap/Contracts/Config.php: -------------------------------------------------------------------------------- 1 | singleton('exception', function () use ($app) { 16 | return new ExceptionHandler(); 17 | }); 18 | 19 | 20 | $app->singleton('composer', function ($app) { 21 | return new Composer($app['files'], __DIR__ . '/..'); 22 | }); 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Handle Errors as Exceptions 27 | |-------------------------------------------------------------------------- 28 | | 29 | | Here we are converting errors as exceptions so that they are handled well 30 | | 31 | */ 32 | 33 | set_error_handler(function ($err_no, $err_str, $err_file, $err_line) { 34 | throw new ErrorException($err_str, 0, $err_no, $err_file, $err_line); 35 | }); 36 | 37 | /* 38 | |-------------------------------------------------------------------------- 39 | | Return The Application 40 | |-------------------------------------------------------------------------- 41 | | 42 | | This script returns the application instance. The instance is given to 43 | | the calling script so we can separate the building of the instances 44 | | from the actual running of the application and sending responses. 45 | | 46 | */ 47 | 48 | return $app; -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | 9 | /* 10 | |-------------------------------------------------------------------------- 11 | | Register The Auto Loader 12 | |-------------------------------------------------------------------------- 13 | | 14 | | Composer provides a convenient, automatically generated class loader 15 | | for our application. We just need to utilize it! We'll require it 16 | | into the script here so that we do not have to worry about the 17 | | loading of any our classes "manually". Feels great to relax. 18 | | 19 | */ 20 | 21 | use App\Http\Controllers\Home; 22 | use App\Http\Controllers\Reviews; 23 | use Luracast\Restler\Explorer\v2\Explorer; 24 | use Luracast\Restler\Restler; 25 | 26 | require __DIR__ . '/../bootstrap/autoload.php'; 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Configure your Web Application 31 | |-------------------------------------------------------------------------- 32 | | 33 | | Configure your favourite web app framework to handle web requests and 34 | | respond back. If you are using Restler 5 framework, you may simply uncomment 35 | | the code below and run the following command from the command line on the 36 | | project root folder 37 | | 38 | | composer require restler/framework 39 | | 40 | */ 41 | 42 | 43 | /* 44 | |-------------------------------------------------------------------------- 45 | | Run The Application 46 | |-------------------------------------------------------------------------- 47 | | 48 | | Once we have the application set up, we can simply let it handle the 49 | | request and response 50 | | 51 | */ 52 | // $r = new Restler(); 53 | // $r->addAPIClass('YourClassNameHere'); 54 | // $r->handle(); 55 | -------------------------------------------------------------------------------- /bootstrap/Console/ComposerScripts.php: -------------------------------------------------------------------------------- 1 | getComposer()->getConfig()->get('vendor-dir').'/autoload.php'; 18 | 19 | static::clearCompiled(); 20 | } 21 | 22 | /** 23 | * Handle the post-update Composer event. 24 | * 25 | * @param \Composer\Script\Event $event 26 | * @return void 27 | */ 28 | public static function postUpdate(Event $event) 29 | { 30 | require_once $event->getComposer()->getConfig()->get('vendor-dir').'/autoload.php'; 31 | 32 | static::clearCompiled(); 33 | } 34 | 35 | /** 36 | * Handle the post-autoload-dump Composer event. 37 | * 38 | * @param \Composer\Script\Event $event 39 | * @return void 40 | */ 41 | public static function postAutoloadDump(Event $event) 42 | { 43 | require_once $event->getComposer()->getConfig()->get('vendor-dir').'/autoload.php'; 44 | 45 | static::clearCompiled(); 46 | } 47 | 48 | /** 49 | * Clear the cached Laravel bootstrapping files. 50 | * 51 | * @return void 52 | */ 53 | protected static function clearCompiled() 54 | { 55 | $laravel = new Application(getcwd()); 56 | 57 | if (is_file($servicesPath = $laravel->getCachedServicesPath())) { 58 | @unlink($servicesPath); 59 | } 60 | 61 | if (is_file($packagesPath = $laravel->getCachedPackagesPath())) { 62 | @unlink($packagesPath); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/Console/Commands/stubs/controller.model.stub: -------------------------------------------------------------------------------- 1 | save(); 50 | return ${{ modelVariable }}; 51 | } 52 | 53 | /** 54 | * delete a {{ modelVariable }} by id 55 | * 56 | * @param int $id 57 | * @return {{ model }} 58 | * @throws HttpException 404 {{ modelVariable }} not found 59 | */ 60 | public function delete(int $id): {{ model }} 61 | { 62 | if (!${{ modelVariable }} = {{ model }}::find($id)) { 63 | throw new HttpException(404, '{{ modelVariable }} not found'); 64 | } 65 | ${{ modelVariable }}->delete(); 66 | return ${{ modelVariable }}; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /bootstrap/Console/stubs/controller.model.stub: -------------------------------------------------------------------------------- 1 | save(); 50 | return ${{ modelVariable }}; 51 | } 52 | 53 | /** 54 | * delete a {{ modelVariable }} by id 55 | * 56 | * @param int $id 57 | * @return {{ model }} 58 | * @throws HttpException 404 {{ modelVariable }} not found 59 | */ 60 | public function delete(int $id): {{ model }} 61 | { 62 | if (!${{ modelVariable }} = {{ model }}::find($id)) { 63 | throw new HttpException(404, '{{ modelVariable }} not found'); 64 | } 65 | ${{ modelVariable }}->delete(); 66 | return ${{ modelVariable }}; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/database", 3 | "description": "Get Laravel database for your non laravel projects. Built on top of illuminate/database to provide migration, seeding and artisan support", 4 | "keywords": [ 5 | "laravel", 6 | "database", 7 | "sql", 8 | "orm" 9 | ], 10 | "license": "MIT", 11 | "type": "project", 12 | "authors": [ 13 | { 14 | "name": "Arul Kumaran", 15 | "email": "arul@luracast.com" 16 | } 17 | ], 18 | "require": { 19 | "php": "^7.4|^8", 20 | "illuminate/cache": "^8", 21 | "illuminate/database": "^8", 22 | "illuminate/events": "^8", 23 | "illuminate/filesystem": "^8", 24 | "illuminate/pagination": "^8", 25 | "league/flysystem": "^1.0", 26 | "psy/psysh": "^0.10.4", 27 | "symfony/process": "^5", 28 | "vlucas/phpdotenv": "^5", 29 | "ext-json": "*" 30 | }, 31 | "require-dev": { 32 | "doctrine/dbal": "~2.10", 33 | "fakerphp/faker": "^1.19", 34 | "illuminate/console": "^8", 35 | "illuminate/view": "^8", 36 | "laravel/helpers": "^1" 37 | }, 38 | "suggest": { 39 | "doctrine/dbal": "Allow renaming columns and dropping SQLite columns." 40 | }, 41 | "autoload": { 42 | "files": [ 43 | ], 44 | "psr-4": { 45 | "App\\": "app/", 46 | "Bootstrap\\": "bootstrap/", 47 | "Database\\Factories\\": "database/factories/", 48 | "Database\\Seeders\\": "database/seeders/" 49 | } 50 | }, 51 | "minimum-stability": "dev", 52 | "prefer-stable": true, 53 | "config": { 54 | "preferred-install": "dist", 55 | "sort-packages": true, 56 | "optimize-autoloader": true 57 | }, 58 | "scripts": { 59 | "post-root-package-install": [ 60 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 61 | ], 62 | "post-autoload-dump": [ 63 | "Bootstrap\\Console\\ComposerScripts::postAutoloadDump", 64 | "@php artisan package:discover --ansi" 65 | ] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /bootstrap/Console/ClosureCommand.php: -------------------------------------------------------------------------------- 1 | callback = $callback; 33 | $this->signature = $signature; 34 | 35 | parent::__construct(); 36 | } 37 | 38 | /** 39 | * Execute the console command. 40 | * 41 | * @param InputInterface $input 42 | * @param OutputInterface $output 43 | * @return mixed 44 | * @throws ReflectionException 45 | */ 46 | protected function execute(InputInterface $input, OutputInterface $output) 47 | { 48 | $inputs = array_merge($input->getArguments(), $input->getOptions()); 49 | 50 | $parameters = []; 51 | 52 | foreach ((new ReflectionFunction($this->callback))->getParameters() as $parameter) { 53 | if (isset($inputs[$parameter->name])) { 54 | $parameters[$parameter->name] = $inputs[$parameter->name]; 55 | } 56 | } 57 | 58 | return (int) $this->laravel->call( 59 | $this->callback->bindTo($this, $this), $parameters 60 | ); 61 | } 62 | 63 | /** 64 | * Set the description for the command. 65 | * 66 | * @param string $description 67 | * @return ClosureCommand 68 | */ 69 | public function describe($description) 70 | { 71 | $this->setDescription($description); 72 | 73 | return $this; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /bootstrap/Console/ServeCommand.php: -------------------------------------------------------------------------------- 1 | checkPhpVersion(); 34 | 35 | chdir($this->laravel['path.base']); 36 | 37 | $host = $this->input->getOption('host'); 38 | 39 | $port = $this->input->getOption('port'); 40 | 41 | $public = $this->laravel['path.public']; 42 | 43 | $this->info("Web app development server started on http://{$host}:{$port}"); 44 | 45 | passthru('"' . PHP_BINARY . '"' . " -S {$host}:{$port} -t \"{$public}\" server.php"); 46 | } 47 | 48 | /** 49 | * Check the current PHP version is >= 5.4. 50 | * 51 | * @return void 52 | * 53 | * @throws \Exception 54 | */ 55 | protected function checkPhpVersion() 56 | { 57 | if (version_compare(PHP_VERSION, '5.4.0', '<')) { 58 | throw new \Exception('This PHP binary is not version 5.4 or greater.'); 59 | } 60 | } 61 | 62 | /** 63 | * Get the console command options. 64 | * 65 | * @return array 66 | */ 67 | protected function getOptions() 68 | { 69 | return array( 70 | array('host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on.', 'localhost'), 71 | 72 | array('port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on.', 8000), 73 | ); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /bootstrap/Console/AutoloadCommand.php: -------------------------------------------------------------------------------- 1 | composer = $composer; 37 | } 38 | /** 39 | * Execute the console command. 40 | * 41 | * @return void 42 | */ 43 | public function handle() 44 | { 45 | $this->composer->dumpOptimized(); 46 | foreach ($this->findWorkbenches() as $workbench) 47 | { 48 | $this->comment("Running for workbench [{$workbench['name']}]..."); 49 | $this->composer->setWorkingPath($workbench['path'])->dumpOptimized(); 50 | } 51 | } 52 | /** 53 | * Get all of the workbench directories. 54 | * 55 | * @return array 56 | */ 57 | protected function findWorkbenches() 58 | { 59 | $results = array(); 60 | foreach ($this->getWorkbenchComposers() as $file) 61 | { 62 | $results[] = array('name' => $file->getRelativePath(), 'path' => $file->getPath()); 63 | } 64 | return $results; 65 | } 66 | /** 67 | * Get all of the workbench composer files. 68 | * 69 | * @return \Symfony\Component\Finder\Finder 70 | */ 71 | protected function getWorkbenchComposers() 72 | { 73 | $workbench = $this->laravel['path.base'].'/workbench'; 74 | if ( ! is_dir($workbench)) return array(); 75 | return Finder::create()->files()->followLinks()->in($workbench)->name('composer.json')->depth('< 3'); 76 | } 77 | } -------------------------------------------------------------------------------- /bootstrap/Console/ConsoleMakeCommand.php: -------------------------------------------------------------------------------- 1 | option('command'), $stub); 44 | } 45 | 46 | /** 47 | * Get the stub file for the generator. 48 | * 49 | * @return string 50 | */ 51 | protected function getStub() 52 | { 53 | $relativePath = '/stubs/console.stub'; 54 | 55 | return file_exists($customPath = $this->laravel->basePath(trim($relativePath, '/'))) 56 | ? $customPath 57 | : __DIR__ . $relativePath; 58 | } 59 | 60 | /** 61 | * Get the default namespace for the class. 62 | * 63 | * @param string $rootNamespace 64 | * @return string 65 | */ 66 | protected function getDefaultNamespace($rootNamespace) 67 | { 68 | return $rootNamespace . '\Console\Commands'; 69 | } 70 | 71 | /** 72 | * Get the console command arguments. 73 | * 74 | * @return array 75 | */ 76 | protected function getArguments() 77 | { 78 | return [ 79 | ['name', InputArgument::REQUIRED, 'The name of the command'], 80 | ]; 81 | } 82 | 83 | /** 84 | * Get the console command options. 85 | * 86 | * @return array 87 | */ 88 | protected function getOptions() 89 | { 90 | return [ 91 | ['command', null, InputOption::VALUE_OPTIONAL, 'The terminal command that should be assigned', 'command:name'], 92 | ]; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /bootstrap/Console/stubs/controller.model.paginate.stub: -------------------------------------------------------------------------------- 1 | setPath($this->path) 32 | ); 33 | } 34 | 35 | /** 36 | * get a {{ modelVariable }} by id 37 | * 38 | * @param int $id 39 | * @return {{ model }} 40 | * 41 | * @throws HttpException 404 {{ modelVariable }} not found 42 | */ 43 | public function get(int $id): {{ model }} 44 | { 45 | if (!${{ modelVariable }} = {{ model }}::find($id)) { 46 | throw new HttpException(404, '{{ modelVariable }} not found'); 47 | } 48 | return ${{ modelVariable }}; 49 | } 50 | 51 | /** 52 | * create new {{ modelVariable }} 53 | * 54 | * @param {{ model }} ${{ modelVariable }} 55 | * @return {{ model }} 56 | * 57 | * @status 201 58 | */ 59 | public function post({{ model }} ${{ modelVariable }}): {{ model }} 60 | { 61 | ${{ modelVariable }}->save(); 62 | return ${{ modelVariable }}; 63 | } 64 | 65 | /** 66 | * delete a {{ modelVariable }} by id 67 | * 68 | * @param int $id 69 | * @return {{ model }} 70 | * @throws HttpException 404 {{ modelVariable }} not found 71 | */ 72 | public function delete(int $id): {{ model }} 73 | { 74 | if (!${{ modelVariable }} = {{ model }}::find($id)) { 75 | throw new HttpException(404, '{{ modelVariable }} not found'); 76 | } 77 | ${{ modelVariable }}->delete(); 78 | return ${{ modelVariable }}; 79 | } 80 | 81 | public function __construct(ServerRequestInterface $request) 82 | { 83 | $this->path = $request->getUri()->getPath(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/Console/Commands/stubs/controller.model.paginate.stub: -------------------------------------------------------------------------------- 1 | setPath($this->path) 37 | ); 38 | } 39 | 40 | /** 41 | * get a {{ modelVariable }} by id 42 | * 43 | * @param int $id 44 | * @return {{ model }} 45 | * 46 | * @throws HttpException 404 {{ modelVariable }} not found 47 | */ 48 | public function get(int $id): {{ model }} 49 | { 50 | if (!${{ modelVariable }} = {{ model }}::find($id)) { 51 | throw new HttpException(404, '{{ modelVariable }} not found'); 52 | } 53 | return ${{ modelVariable }}; 54 | } 55 | 56 | /** 57 | * create new {{ modelVariable }} 58 | * 59 | * @param {{ model }} ${{ modelVariable }} 60 | * @return {{ model }} 61 | * 62 | * @status 201 63 | */ 64 | public function post({{ model }} ${{ modelVariable }}): {{ model }} 65 | { 66 | ${{ modelVariable }}->save(); 67 | return ${{ modelVariable }}; 68 | } 69 | 70 | /** 71 | * delete a {{ modelVariable }} by id 72 | * 73 | * @param int $id 74 | * @return {{ model }} 75 | * @throws HttpException 404 {{ modelVariable }} not found 76 | */ 77 | public function delete(int $id): {{ model }} 78 | { 79 | if (!${{ modelVariable }} = {{ model }}::find($id)) { 80 | throw new HttpException(404, '{{ modelVariable }} not found'); 81 | } 82 | ${{ modelVariable }}->delete(); 83 | return ${{ modelVariable }}; 84 | } 85 | 86 | public function __construct(ServerRequestInterface $request) 87 | { 88 | $this->path = $request->getUri()->getPath(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /bootstrap/Console/SeedMakeCommand.php: -------------------------------------------------------------------------------- 1 | composer = $composer; 53 | } 54 | 55 | /** 56 | * Execute the console command. 57 | * 58 | * @return void 59 | * @throws FileNotFoundException 60 | */ 61 | public function handle() 62 | { 63 | parent::handle(); 64 | 65 | $this->composer->dumpAutoloads(); 66 | } 67 | 68 | /** 69 | * Get the stub file for the generator. 70 | * 71 | * @return string 72 | */ 73 | protected function getStub() 74 | { 75 | return __DIR__.'/stubs/seeder.stub'; 76 | } 77 | 78 | /** 79 | * Get the destination class path. 80 | * 81 | * @param string $name 82 | * @return string 83 | */ 84 | protected function getPath($name) 85 | { 86 | return $this->laravel->databasePath().'/seeds/'.$name.'.php'; 87 | } 88 | 89 | /** 90 | * Parse the class name and format according to the root namespace. 91 | * 92 | * @param string $name 93 | * @return string 94 | */ 95 | protected function qualifyClass($name) 96 | { 97 | return $name; 98 | } 99 | 100 | /** 101 | * Get the model for the default guard's user provider. 102 | * 103 | * @return string|null 104 | */ 105 | protected function userProviderModel() 106 | { 107 | return null; 108 | } 109 | } -------------------------------------------------------------------------------- /bootstrap/Console/IlluminateCaster.php: -------------------------------------------------------------------------------- 1 | $property(); 50 | 51 | if (!is_null($val)) { 52 | $results[Caster::PREFIX_VIRTUAL . $property] = $val; 53 | } 54 | } catch (Exception $e) { 55 | // 56 | } 57 | } 58 | 59 | return $results; 60 | } 61 | 62 | /** 63 | * Get an array representing the properties of a collection. 64 | * 65 | * @param \Illuminate\Support\Collection $collection 66 | * 67 | * @return array 68 | */ 69 | public static function castCollection(Collection $collection) 70 | { 71 | return [ 72 | Caster::PREFIX_VIRTUAL . 'all' => $collection->all(), 73 | ]; 74 | } 75 | 76 | /** 77 | * Get an array representing the properties of a model. 78 | * 79 | * @param \Illuminate\Database\Eloquent\Model $model 80 | * 81 | * @return array 82 | */ 83 | public static function castModel(Model $model) 84 | { 85 | $attributes = array_merge( 86 | $model->getAttributes(), $model->getRelations() 87 | ); 88 | 89 | $visible = array_flip( 90 | $model->getVisible() ?: array_diff(array_keys($attributes), $model->getHidden()) 91 | ); 92 | 93 | $results = []; 94 | 95 | foreach (array_intersect_key($attributes, $visible) as $key => $value) { 96 | $results[(isset($visible[$key]) ? Caster::PREFIX_VIRTUAL : Caster::PREFIX_PROTECTED) . $key] = $value; 97 | } 98 | 99 | return $results; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_CONNECTION', 'sync'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Queue Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here you may configure the connection information for each server that 24 | | is used by your application. A default configuration has been added 25 | | for each back-end shipped with Laravel. You are free to add more. 26 | | 27 | | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'sync' => [ 34 | 'driver' => 'sync', 35 | ], 36 | 37 | 'database' => [ 38 | 'driver' => 'database', 39 | 'table' => 'jobs', 40 | 'queue' => 'default', 41 | 'retry_after' => 90, 42 | ], 43 | 44 | 'beanstalkd' => [ 45 | 'driver' => 'beanstalkd', 46 | 'host' => 'localhost', 47 | 'queue' => 'default', 48 | 'retry_after' => 90, 49 | 'block_for' => 0, 50 | ], 51 | 52 | 'sqs' => [ 53 | 'driver' => 'sqs', 54 | 'key' => env('AWS_ACCESS_KEY_ID'), 55 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 56 | 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 57 | 'queue' => env('SQS_QUEUE', 'your-queue-name'), 58 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 59 | ], 60 | 61 | 'redis' => [ 62 | 'driver' => 'redis', 63 | 'connection' => 'default', 64 | 'queue' => env('REDIS_QUEUE', 'default'), 65 | 'retry_after' => 90, 66 | 'block_for' => null, 67 | ], 68 | 69 | ], 70 | 71 | /* 72 | |-------------------------------------------------------------------------- 73 | | Failed Queue Jobs 74 | |-------------------------------------------------------------------------- 75 | | 76 | | These options configure the behavior of failed queue job logging so you 77 | | can control which database and table are used to store the jobs that 78 | | have failed. You may change them to any database / table you wish. 79 | | 80 | */ 81 | 82 | 'failed' => [ 83 | 'database' => env('DB_CONNECTION', 'mysql'), 84 | 'table' => 'failed_jobs', 85 | ], 86 | 87 | ]; 88 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | [ 20 | MigrationServiceProvider::class, 21 | /* 22 | * To add Redis support, 23 | * - run composer require illuminate/redis:7.10.* 24 | * - uncomment the line below 25 | */ 26 | // 'Illuminate\Redis\RedisServiceProvider', 27 | ], 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | Class Aliases 32 | |-------------------------------------------------------------------------- 33 | | 34 | | This array of class aliases will be registered when this application 35 | | is started. However, feel free to register as many as you wish as 36 | | the aliases are "lazy" loaded so they don't hinder performance. 37 | | 38 | */ 39 | 40 | 'aliases' => [ 41 | 'Artisan' => 'Bootstrap\Console\ArtisanFacade', 42 | 'Config' => 'Illuminate\Support\Facades\Config', 43 | 'Cache' => 'Illuminate\Support\Facades\Cache', 44 | 'DB' => 'Illuminate\Database\Capsule\Manager', 45 | 'Eloquent' => 'Illuminate\Database\Eloquent\Model', 46 | 'Event' => 'Illuminate\Support\Facades\Event', 47 | 'File' => 'Illuminate\Support\Facades\File', 48 | 'Schema' => 'Illuminate\Support\Facades\Schema', 49 | 'Seeder' => 'Illuminate\Database\Seeder', 50 | 'Redis' => 'Illuminate\Support\Facades\Redis', 51 | 'Queue' => 'Illuminate\Queue\Capsule\Manager', 52 | ], 53 | 54 | /* 55 | |-------------------------------------------------------------------------- 56 | | Application Timezone 57 | |-------------------------------------------------------------------------- 58 | | 59 | | Here you may specify the default timezone for your application, which 60 | | will be used by the PHP date and date-time functions. We have gone 61 | | ahead and set this to a sensible default for you out of the box. 62 | | 63 | */ 64 | 65 | 'timezone' => 'UTC', 66 | 67 | /* 68 | |-------------------------------------------------------------------------- 69 | | Application Locale Configuration 70 | |-------------------------------------------------------------------------- 71 | | 72 | | The application locale determines the default locale that will be used 73 | | by the translation service provider. You are free to set this value 74 | | to any of the locales which will be supported by the application. 75 | | 76 | */ 77 | 78 | 'locale' => 'en', 79 | 80 | ]; 81 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | 'file', 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | File Cache Location 24 | |-------------------------------------------------------------------------- 25 | | 26 | | When using the "file" cache driver, we need a location where the cache 27 | | files may be stored. A sensible default has been specified, but you 28 | | are free to change it to any other place on disk that you desire. 29 | | 30 | */ 31 | 32 | 'path' => storage_path('framework/cache/data'), 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | Database Cache Connection 37 | |-------------------------------------------------------------------------- 38 | | 39 | | When using the "database" cache driver you may specify the connection 40 | | that should be used to store the cached items. When this option is 41 | | null the default database connection will be utilized for cache. 42 | | 43 | */ 44 | 45 | 'connection' => null, 46 | 47 | /* 48 | |-------------------------------------------------------------------------- 49 | | Database Cache Table 50 | |-------------------------------------------------------------------------- 51 | | 52 | | When using the "database" cache driver we need to know the table that 53 | | should be used to store the cached items. A default table name has 54 | | been provided but you're free to change it however you deem fit. 55 | | 56 | */ 57 | 58 | 'table' => 'cache', 59 | 60 | /* 61 | |-------------------------------------------------------------------------- 62 | | Memcached Servers 63 | |-------------------------------------------------------------------------- 64 | | 65 | | Now you may specify an array of your Memcached servers that should be 66 | | used when utilizing the Memcached cache driver. All of the servers 67 | | should contain a value for "host", "port", and "weight" options. 68 | | 69 | */ 70 | 71 | 'memcached' => [ 72 | 73 | ['host' => '127.0.0.1', 'port' => 11211, 'weight' => 100], 74 | 75 | ], 76 | 77 | /* 78 | |-------------------------------------------------------------------------- 79 | | Cache Key Prefix 80 | |-------------------------------------------------------------------------- 81 | | 82 | | When utilizing a RAM based store such as APC or Memcached, there might 83 | | be other applications utilizing the same cache. So, we'll specify a 84 | | value to get prefixed to all our keys so we can avoid collisions. 85 | | 86 | */ 87 | 88 | 'prefix' => 'restler', 89 | 90 | ]; 91 | -------------------------------------------------------------------------------- /bootstrap/Console/TinkerCommand.php: -------------------------------------------------------------------------------- 1 | getApplication()->setCatchExceptions(false); 48 | $config = new Configuration; 49 | $config->setUpdateCheck(Checker::NEVER); 50 | $config->getPresenter()->addCasters( 51 | $this->getCasters() 52 | ); 53 | $shell = new Shell($config); 54 | $shell->addCommands($this->getCommands()); 55 | $shell->setIncludes($this->argument('include')); 56 | if ($code = $this->option('execute')) { 57 | try { 58 | $shell->execute($code); 59 | } finally { 60 | //$loader->unregister(); 61 | } 62 | 63 | return 0; 64 | } 65 | try { 66 | return $shell->run(); 67 | } finally { 68 | // $loader->unregister(); 69 | } 70 | } 71 | 72 | /** 73 | * Get artisan commands to pass through to PsySH. 74 | * 75 | * @return array 76 | */ 77 | protected function getCommands() 78 | { 79 | $commands = []; 80 | foreach ($this->getApplication()->all() as $name => $command) { 81 | if (in_array($name, $this->commandWhitelist)) { 82 | $commands[] = $command; 83 | } 84 | } 85 | 86 | return $commands; 87 | } 88 | 89 | /** 90 | * Get an array of Laravel tailored casters. 91 | * 92 | * @return array 93 | */ 94 | protected function getCasters() 95 | { 96 | return [ 97 | 'Illuminate\Foundation\Application' => 'Bootstrap\Console\IlluminateCaster::castApplication', 98 | 'Illuminate\Support\Collection' => 'Bootstrap\Console\IlluminateCaster::castCollection', 99 | 'Illuminate\Database\Eloquent\Model' => 'Bootstrap\Console\IlluminateCaster::castModel', 100 | ]; 101 | } 102 | 103 | /** 104 | * Get the console command arguments. 105 | * 106 | * @return array 107 | */ 108 | protected function getArguments() 109 | { 110 | return [ 111 | ['include', InputArgument::IS_ARRAY, 'Include file(s) before starting tinker'], 112 | ]; 113 | } 114 | 115 | /** 116 | * Get the console command options. 117 | * 118 | * @return array 119 | */ 120 | protected function getOptions() 121 | { 122 | return [ 123 | ['execute', null, InputOption::VALUE_OPTIONAL, 'Execute the given code using Tinker'], 124 | ]; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /bootstrap/Console/FactoryMakeCommand.php: -------------------------------------------------------------------------------- 1 | resolveStubPath('/stubs/factory.stub'); 41 | } 42 | 43 | /** 44 | * Resolve the fully-qualified path to the stub. 45 | * 46 | * @param string $stub 47 | * @return string 48 | */ 49 | protected function resolveStubPath($stub) 50 | { 51 | return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) 52 | ? $customPath 53 | : __DIR__.$stub; 54 | } 55 | 56 | /** 57 | * Build the class with the given name. 58 | * 59 | * @param string $name 60 | * @return string 61 | */ 62 | protected function buildClass($name) 63 | { 64 | $factory = class_basename(Str::ucfirst(str_replace('Factory', '', $name))); 65 | 66 | $namespaceModel = $this->option('model') 67 | ? $this->qualifyModel($this->option('model')) 68 | : $this->qualifyModel($this->guessModelName($name)); 69 | 70 | $model = class_basename($namespaceModel); 71 | 72 | if (Str::startsWith($namespaceModel, $this->rootNamespace().'Models')) { 73 | $namespace = Str::beforeLast('Database\\Factories\\'.Str::after($namespaceModel, $this->rootNamespace().'Models\\'), '\\'); 74 | } else { 75 | $namespace = 'Database\\Factories'; 76 | } 77 | 78 | $replace = [ 79 | '{{ factoryNamespace }}' => $namespace, 80 | 'NamespacedDummyModel' => $namespaceModel, 81 | '{{ namespacedModel }}' => $namespaceModel, 82 | '{{namespacedModel}}' => $namespaceModel, 83 | 'DummyModel' => $model, 84 | '{{ model }}' => $model, 85 | '{{model}}' => $model, 86 | '{{ factory }}' => $factory, 87 | '{{factory}}' => $factory, 88 | ]; 89 | 90 | return str_replace( 91 | array_keys($replace), array_values($replace), parent::buildClass($name) 92 | ); 93 | } 94 | 95 | /** 96 | * Get the destination class path. 97 | * 98 | * @param string $name 99 | * @return string 100 | */ 101 | protected function getPath($name) 102 | { 103 | $name = (string) Str::of($name)->replaceFirst($this->rootNamespace(), '')->finish('Factory'); 104 | 105 | return $this->laravel->databasePath().'/factories/'.str_replace('\\', '/', $name).'.php'; 106 | } 107 | 108 | /** 109 | * Guess the model name from the Factory name or return a default model name. 110 | * 111 | * @param string $name 112 | * @return string 113 | */ 114 | protected function guessModelName($name) 115 | { 116 | if (Str::endsWith($name, 'Factory')) { 117 | $name = substr($name, 0, -7); 118 | } 119 | 120 | $modelName = $this->qualifyModel(Str::after($name, $this->rootNamespace())); 121 | 122 | if (class_exists($modelName)) { 123 | return $modelName; 124 | } 125 | 126 | if (is_dir(app_path('Models/'))) { 127 | return $this->rootNamespace().'Models\Model'; 128 | } 129 | 130 | return $this->rootNamespace().'Model'; 131 | } 132 | 133 | /** 134 | * Get the console command options. 135 | * 136 | * @return array 137 | */ 138 | protected function getOptions() 139 | { 140 | return [ 141 | ['model', 'm', InputOption::VALUE_OPTIONAL, 'The name of the model'], 142 | ]; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Database 2 | 3 | Provides full laravel database functionality for your non laravel projects adds 4 | Migration, Seeding and Artisan support to Illuminate Database. 5 | 6 | It enables **artisan** command line tool with: 7 | 8 | ``` 9 | Available commands: 10 | 11 | db Start a new database CLI session 12 | dump-autoload Regenerate framework autoload files 13 | env Display the current framework environment 14 | help Display help for a command 15 | inspire Display an inspiring quote 16 | list List commands 17 | migrate Run the database migrations 18 | serve Serve the application on the PHP development server 19 | tinker Interact with your application 20 | 21 | db 22 | db:seed Seed the database with records 23 | db:wipe Drop all tables, views, and types 24 | 25 | make 26 | make:command Create a new Artisan command 27 | make:controller Create a new controller class 28 | make:factory Create a new model factory 29 | make:migration Create a new migration file 30 | make:model Create a new Eloquent model class 31 | make:seeder Create a new seeder class 32 | 33 | migrate 34 | migrate:fresh Drop all tables and re-run all migrations 35 | migrate:install Create the migration repository 36 | migrate:refresh Reset and re-run all migrations 37 | migrate:reset Rollback all database migrations 38 | migrate:rollback Rollback the last database migration 39 | migrate:status Show the status of each migration 40 | 41 | vendor 42 | vendor:publish Publish any publishable assets from vendor packages 43 | ``` 44 | 45 | [Laravel](https://github.com/laravel/laravel) is a web application framework with expressive, elegant syntax. 46 | We extracted the database functionality from it and made it available for other frameworks. 47 | 48 | The [Illuminate Database](https://github.com/illuminate/database) component is a full database toolkit for PHP, 49 | providing an expressive query builder, ActiveRecord style ORM, and schema builder. It currently supports 50 | MySQL, Postgres, MSSQL Server, and SQLite. We combined it with Illuminate FileSystem and Illuminate Console to 51 | make Artisan work with database related commands. 52 | 53 | ## Installation 54 | 55 | ### Install Composer 56 | 57 | Laravel Database utilizes [Composer](http://getcomposer.org/) to manage its dependencies. 58 | First, download a copy of the `composer.phar`. Once you have the PHAR archive, 59 | you can either keep it in your local project directory or move to `usr/local/bin` 60 | to use it globally on your system. On Windows, you can use the Composer 61 | [Windows installer](https://getcomposer.org/Composer-Setup.exe). 62 | 63 | ### Install Laravel Database 64 | 65 | Install Laravel Database by issuing the Composer create-project command in your terminal: 66 | 67 | composer create-project laravel/database --prefer-dist 68 | 69 | ## Usage Instructions 70 | 71 | From your public `index.php` include the `autoload.php` in `bootstrap` folder this internally uses composer autoloader. 72 | This enables lazy loading of all db related classes. It doest not boot the database engine until you call one 73 | of the DB related class. 74 | 75 | ### Adding More Components 76 | 77 | For instructions on how to add more laravel components or compatible third party service providers etc., 78 | read the comments in `app/config/app.php` file 79 | 80 | ### Practical Usage Example 81 | 82 | - [Restler Application Eloquent Template](https://github.com/Luracast/Restler-Application/tree/eloquent) enables 83 | restler framework application's to utilize the power and elegance of *eloquent* 84 | 85 | ## Official Documentation 86 | 87 | Documentation for the entire framework can be found on the [Laravel website](http://laravel.com/docs). 88 | Refer to all database related sections from there. 89 | 90 | 91 | ### Credits 92 | 93 | All the credits for the Laravel Database goes to the Laravel Framework developers. 94 | We are only putting the pieces together here 95 | 96 | ### Contributing 97 | 98 | **Issues and pull requests relating to this integration should be filed 99 | on the [laravel/database](http://github.com/Luracast/Laravel-Framework) repository.** 100 | 101 | ### License 102 | 103 | The Laravel Database is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) 104 | -------------------------------------------------------------------------------- /bootstrap/Console/VendorPublishCommand.php: -------------------------------------------------------------------------------- 1 | files = $files; 46 | } 47 | 48 | /** 49 | * Execute the console command. 50 | * 51 | * @return void 52 | */ 53 | public function handle() 54 | { 55 | $tags = $this->option('tag'); 56 | 57 | $tags = $tags ?: [null]; 58 | 59 | foreach ($tags as $tag) { 60 | $this->publishTag($tag); 61 | } 62 | } 63 | 64 | /** 65 | * Publishes the assets for a tag. 66 | * 67 | * @param string $tag 68 | * @return mixed 69 | */ 70 | private function publishTag($tag) 71 | { 72 | $paths = ServiceProvider::pathsToPublish( 73 | $this->option('provider'), $tag 74 | ); 75 | 76 | if (empty($paths)) { 77 | return $this->comment("Nothing to publish for tag [{$tag}]."); 78 | } 79 | 80 | foreach ($paths as $from => $to) { 81 | if ($this->files->isFile($from)) { 82 | $this->publishFile($from, $to); 83 | } elseif ($this->files->isDirectory($from)) { 84 | $this->publishDirectory($from, $to); 85 | } else { 86 | $this->error("Can't locate path: <{$from}>"); 87 | } 88 | } 89 | 90 | $this->info("Publishing complete for tag [{$tag}]!"); 91 | } 92 | 93 | /** 94 | * Publish the file to the given path. 95 | * 96 | * @param string $from 97 | * @param string $to 98 | * @return void 99 | */ 100 | protected function publishFile($from, $to) 101 | { 102 | if ($this->files->exists($to) && ! $this->option('force')) { 103 | return; 104 | } 105 | 106 | $this->createParentDirectory(dirname($to)); 107 | 108 | $this->files->copy($from, $to); 109 | 110 | $this->status($from, $to, 'File'); 111 | } 112 | 113 | /** 114 | * Publish the directory to the given directory. 115 | * 116 | * @param string $from 117 | * @param string $to 118 | * @return void 119 | */ 120 | protected function publishDirectory($from, $to) 121 | { 122 | $manager = new MountManager([ 123 | 'from' => new Flysystem(new LocalAdapter($from)), 124 | 'to' => new Flysystem(new LocalAdapter($to)), 125 | ]); 126 | 127 | foreach ($manager->listContents('from://', true) as $file) { 128 | if ($file['type'] === 'file' && (! $manager->has('to://'.$file['path']) || $this->option('force'))) { 129 | $manager->put('to://'.$file['path'], $manager->read('from://'.$file['path'])); 130 | } 131 | } 132 | 133 | $this->status($from, $to, 'Directory'); 134 | } 135 | 136 | /** 137 | * Create the directory to house the published files if needed. 138 | * 139 | * @param string $directory 140 | * @return void 141 | */ 142 | protected function createParentDirectory($directory) 143 | { 144 | if (! $this->files->isDirectory($directory)) { 145 | $this->files->makeDirectory($directory, 0755, true); 146 | } 147 | } 148 | 149 | /** 150 | * Write a status message to the console. 151 | * 152 | * @param string $from 153 | * @param string $to 154 | * @param string $type 155 | * @return void 156 | */ 157 | protected function status($from, $to, $type) 158 | { 159 | $from = str_replace(BASE, '', realpath($from)); 160 | 161 | $to = str_replace(BASE, '', realpath($to)); 162 | 163 | $this->line('Copied '.$type.' ['.$from.'] To ['.$to.']'); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /bootstrap/Console/PackageManifest.php: -------------------------------------------------------------------------------- 1 | files = $files; 56 | $this->basePath = $basePath; 57 | $this->manifestPath = $manifestPath; 58 | $this->vendorPath = $basePath.'/vendor'; 59 | } 60 | 61 | /** 62 | * Get all the service provider class names for all packages. 63 | * 64 | * @return array 65 | */ 66 | public function providers() 67 | { 68 | return $this->config('providers'); 69 | } 70 | 71 | /** 72 | * Get all the aliases for all packages. 73 | * 74 | * @return array 75 | */ 76 | public function aliases() 77 | { 78 | return $this->config('aliases'); 79 | } 80 | 81 | /** 82 | * Get all the values for all packages for the given configuration name. 83 | * 84 | * @param string $key 85 | * @return array 86 | */ 87 | public function config($key) 88 | { 89 | return collect($this->getManifest())->flatMap(function ($configuration) use ($key) { 90 | return (array) ($configuration[$key] ?? []); 91 | })->filter()->all(); 92 | } 93 | 94 | /** 95 | * Get the current package manifest. 96 | * 97 | * @return array 98 | */ 99 | public function getManifest() 100 | { 101 | if (! is_null($this->manifest)) { 102 | return $this->manifest; 103 | } 104 | 105 | if (! is_file($this->manifestPath)) { 106 | $this->build(); 107 | } 108 | 109 | return $this->manifest = is_file($this->manifestPath) ? 110 | $this->files->getRequire($this->manifestPath) : []; 111 | } 112 | 113 | /** 114 | * Build the manifest and write it to disk. 115 | * 116 | * @return void 117 | */ 118 | public function build() 119 | { 120 | $packages = []; 121 | 122 | if ($this->files->exists($path = $this->vendorPath.'/composer/installed.json')) { 123 | $installed = json_decode($this->files->get($path), true); 124 | 125 | $packages = $installed['packages'] ?? $installed; 126 | } 127 | 128 | $ignoreAll = in_array('*', $ignore = $this->packagesToIgnore()); 129 | 130 | $this->write(collect($packages)->mapWithKeys(function ($package) { 131 | return [$this->format($package['name']) => $package['extra']['laravel'] ?? []]; 132 | })->each(function ($configuration) use (&$ignore) { 133 | $ignore = array_merge($ignore, $configuration['dont-discover'] ?? []); 134 | })->reject(function ($configuration, $package) use ($ignore, $ignoreAll) { 135 | return $ignoreAll || in_array($package, $ignore); 136 | })->filter()->all()); 137 | } 138 | 139 | /** 140 | * Format the given package name. 141 | * 142 | * @param string $package 143 | * @return string 144 | */ 145 | protected function format($package) 146 | { 147 | return str_replace($this->vendorPath.'/', '', $package); 148 | } 149 | 150 | /** 151 | * Get all of the package names that should be ignored. 152 | * 153 | * @return array 154 | */ 155 | protected function packagesToIgnore() 156 | { 157 | if (! is_file($this->basePath.'/composer.json')) { 158 | return []; 159 | } 160 | 161 | return json_decode(file_get_contents( 162 | $this->basePath.'/composer.json' 163 | ), true)['extra']['laravel']['dont-discover'] ?? []; 164 | } 165 | 166 | /** 167 | * Write the given manifest array to disk. 168 | * 169 | * @param array $manifest 170 | * @return void 171 | * 172 | * @throws \Exception 173 | */ 174 | protected function write(array $manifest) 175 | { 176 | if (! is_writable($dirname = dirname($this->manifestPath))) { 177 | throw new Exception("The {$dirname} directory must be present and writable."); 178 | } 179 | 180 | $this->files->replace( 181 | $this->manifestPath, 'option('model')) { 45 | $stub = $this->option('paginate') 46 | ? '/stubs/controller.model.paginate.stub' 47 | : '/stubs/controller.model.stub'; 48 | } 49 | 50 | $stub = $stub ?? '/stubs/controller.stub'; 51 | 52 | return $this->resolveStubPath($stub); 53 | } 54 | 55 | /** 56 | * Resolve the fully-qualified path to the stub. 57 | * 58 | * @param string $stub 59 | * @return string 60 | */ 61 | protected function resolveStubPath($stub) 62 | { 63 | return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) 64 | ? $customPath 65 | : __DIR__ . $stub; 66 | } 67 | 68 | /** 69 | * Get the default namespace for the class. 70 | * 71 | * @param string $rootNamespace 72 | * @return string 73 | */ 74 | protected function getDefaultNamespace($rootNamespace) 75 | { 76 | return $rootNamespace . '\Http\Controllers'; 77 | } 78 | 79 | /** 80 | * Build the class with the given name. 81 | * 82 | * Remove the base controller import if we are already in base namespace. 83 | * 84 | * @param string $name 85 | * @return string 86 | * @throws FileNotFoundException 87 | */ 88 | protected function buildClass($name) 89 | { 90 | $controllerNamespace = $this->getNamespace($name); 91 | 92 | $replace = []; 93 | 94 | if ($this->option('model')) { 95 | $replace = $this->buildModelReplacements($replace); 96 | } 97 | 98 | $replace["use {$controllerNamespace}\Controller;\n"] = ''; 99 | 100 | return str_replace( 101 | array_keys($replace), 102 | array_values($replace), 103 | parent::buildClass($name) 104 | ); 105 | } 106 | 107 | 108 | /** 109 | * Build the model replacement values. 110 | * 111 | * @param array $replace 112 | * @return array 113 | */ 114 | protected function buildModelReplacements(array $replace) 115 | { 116 | $modelClass = $this->parseModel($this->option('model')); 117 | 118 | if (!class_exists($modelClass)) { 119 | if ($this->confirm("A {$modelClass} model does not exist. Do you want to generate it?", true)) { 120 | $this->call('make:model', ['name' => $modelClass]); 121 | } 122 | } 123 | 124 | return array_merge($replace, [ 125 | 'DummyFullModelClass' => $modelClass, 126 | '{{ namespacedModel }}' => $modelClass, 127 | '{{namespacedModel}}' => $modelClass, 128 | 'DummyModelClass' => class_basename($modelClass), 129 | '{{ model }}' => class_basename($modelClass), 130 | '{{model}}' => class_basename($modelClass), 131 | 'DummyModelVariable' => lcfirst(class_basename($modelClass)), 132 | '{{ modelVariable }}' => lcfirst(class_basename($modelClass)), 133 | '{{modelVariable}}' => lcfirst(class_basename($modelClass)), 134 | ]); 135 | } 136 | 137 | /** 138 | * Get the fully-qualified model class name. 139 | * 140 | * @param string $model 141 | * @return string 142 | * 143 | * @throws InvalidArgumentException 144 | */ 145 | protected function parseModel($model) 146 | { 147 | if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) { 148 | throw new InvalidArgumentException('Model name contains invalid characters.'); 149 | } 150 | 151 | $model = trim(str_replace('/', '\\', $model), '\\'); 152 | 153 | if (!Str::startsWith($model, $rootNamespace = $this->laravel->getNamespace())) { 154 | $model = $rootNamespace . 'Models\\' . $model; 155 | } 156 | 157 | return $model; 158 | } 159 | 160 | /** 161 | * Get the console command options. 162 | * 163 | * @return array 164 | */ 165 | protected function getOptions() 166 | { 167 | return [ 168 | ['force', null, InputOption::VALUE_NONE, 'Create the class even if the controller already exists'], 169 | ['paginate', 'p', InputOption::VALUE_NONE, 'Paginate the listing response when a model is used.'], 170 | ['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate a resource controller for the given model.'], 171 | ]; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | env('DB_CONNECTION', 'mysql'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Database Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here are each of the database connections setup for your application. 26 | | Of course, examples of configuring each database platform that is 27 | | supported by Laravel is shown below to make development simple. 28 | | 29 | | 30 | | All database work in Laravel is done through the PHP PDO facilities 31 | | so make sure you have the driver for your particular database of 32 | | choice installed on your machine before you begin development. 33 | | 34 | */ 35 | 36 | 'connections' => [ 37 | 38 | 'sqlite' => [ 39 | 'driver' => 'sqlite', 40 | 'url' => env('DATABASE_URL'), 41 | 'database' => env('DB_DATABASE', database_path('database.sqlite')), 42 | 'prefix' => '', 43 | 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), 44 | ], 45 | 46 | 'mysql' => [ 47 | 'driver' => 'mysql', 48 | 'url' => env('DATABASE_URL'), 49 | 'host' => env('DB_HOST', '127.0.0.1'), 50 | 'port' => env('DB_PORT', '3306'), 51 | 'database' => env('DB_DATABASE', 'database'), 52 | 'username' => env('DB_USERNAME', 'root'), 53 | 'password' => env('DB_PASSWORD', ''), 54 | 'unix_socket' => env('DB_SOCKET', ''), 55 | 'charset' => 'utf8mb4', 56 | 'collation' => 'utf8mb4_unicode_ci', 57 | 'prefix' => '', 58 | 'prefix_indexes' => true, 59 | 'strict' => true, 60 | 'engine' => null, 61 | 'options' => extension_loaded('pdo_mysql') ? array_filter([ 62 | PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), 63 | ]) : [], 64 | ], 65 | 66 | 'pgsql' => [ 67 | 'driver' => 'pgsql', 68 | 'url' => env('DATABASE_URL'), 69 | 'host' => env('DB_HOST', '127.0.0.1'), 70 | 'port' => env('DB_PORT', '5432'), 71 | 'database' => env('DB_DATABASE', 'forge'), 72 | 'username' => env('DB_USERNAME', 'forge'), 73 | 'password' => env('DB_PASSWORD', ''), 74 | 'charset' => 'utf8', 75 | 'prefix' => '', 76 | 'prefix_indexes' => true, 77 | 'schema' => 'public', 78 | 'sslmode' => 'prefer', 79 | ], 80 | 81 | 'sqlsrv' => [ 82 | 'driver' => 'sqlsrv', 83 | 'url' => env('DATABASE_URL'), 84 | 'host' => env('DB_HOST', 'localhost'), 85 | 'port' => env('DB_PORT', '1433'), 86 | 'database' => env('DB_DATABASE', 'forge'), 87 | 'username' => env('DB_USERNAME', 'forge'), 88 | 'password' => env('DB_PASSWORD', ''), 89 | 'charset' => 'utf8', 90 | 'prefix' => '', 91 | 'prefix_indexes' => true, 92 | ], 93 | 94 | ], 95 | 96 | /* 97 | |-------------------------------------------------------------------------- 98 | | Migration Repository Table 99 | |-------------------------------------------------------------------------- 100 | | 101 | | This table keeps track of all the migrations that have already run for 102 | | your application. Using this information, we can determine which of 103 | | the migrations on disk haven't actually been run in the database. 104 | | 105 | */ 106 | 107 | 'migrations' => 'migrations', 108 | 109 | /* 110 | |-------------------------------------------------------------------------- 111 | | Redis Databases 112 | |-------------------------------------------------------------------------- 113 | | 114 | | Redis is an open source, fast, and advanced key-value store that also 115 | | provides a richer body of commands than a typical key-value system 116 | | such as APC or Memcached. Laravel makes it easy to dig right in. 117 | | 118 | */ 119 | 120 | 'redis' => [ 121 | 122 | 'client' => env('REDIS_CLIENT', 'predis'), 123 | 124 | 'options' => [ 125 | 'cluster' => env('REDIS_CLUSTER', 'predis'), 126 | 'prefix' => Str::slug(env('APP_NAME', 'app'), '_') . '_database_', 127 | ], 128 | 129 | 'default' => [ 130 | 'url' => env('REDIS_URL'), 131 | 'host' => env('REDIS_HOST', '127.0.0.1'), 132 | 'password' => env('REDIS_PASSWORD', null), 133 | 'port' => env('REDIS_PORT', 6379), 134 | 'database' => env('REDIS_DB', 0), 135 | ], 136 | 137 | 'cache' => [ 138 | 'url' => env('REDIS_URL'), 139 | 'host' => env('REDIS_HOST', '127.0.0.1'), 140 | 'password' => env('REDIS_PASSWORD', null), 141 | 'port' => env('REDIS_PORT', 6379), 142 | 'database' => env('REDIS_CACHE_DB', 1), 143 | ], 144 | 145 | ], 146 | 147 | ]; 148 | -------------------------------------------------------------------------------- /bootstrap/Config/Config.php: -------------------------------------------------------------------------------- 1 | path = $path; 42 | $this->environment = $environment; 43 | if (!static::$instance) { 44 | static::$instance = $this; 45 | } 46 | } 47 | 48 | /** 49 | * Initialize the Config instance for a specific target path 50 | * 51 | * @param string $path folder path for the config files 52 | * @param string|null $environment path for fine tuning config files with overriding properties 53 | * 54 | * @return Config 55 | */ 56 | public static function init(string $path, string $environment = null): ?Config 57 | { 58 | if (!static::$instance) { 59 | static::$instance = new Config($path, $environment); 60 | } else { 61 | static::$instance->path = $path; 62 | static::$instance->environment = $environment; 63 | static::$instance->container = []; 64 | } 65 | 66 | return static::$instance; 67 | } 68 | 69 | public function get($key, $default = null) 70 | { 71 | return $this->offsetGet($key) ?: $default; 72 | } 73 | 74 | #[\ReturnTypeWillChange] 75 | public function offsetGet($offset) 76 | { 77 | return $this->offsetExists($offset) ? $this->container[$offset] : null; 78 | } 79 | 80 | public function offsetExists($offset): bool 81 | { 82 | if (isset($this->container[$offset])) { 83 | return true; 84 | } 85 | $name = strtok($offset, '.'); 86 | if (isset($this->container[$name])) { 87 | $p = $this->container[$name]; 88 | while (false !== ($name = strtok('.'))) { 89 | if (!isset($p[$name])) { 90 | return false; 91 | } 92 | $p = $p[$name]; 93 | } 94 | $this->container[$offset] = $p; 95 | 96 | return true; 97 | } else { 98 | //lazy load the config file 99 | if (is_readable("$this->path/$name.php")) { 100 | //merge environment file if available 101 | $this->container[$name] = include "$this->path/$name.php"; 102 | if (!empty($this->environment) && is_readable($file = "$this->path/$this->environment/$name.php")) { 103 | $this->container[$name] = array_replace_recursive($this->container[$name], (include $file)); 104 | } 105 | 106 | return $this->offsetExists($offset); 107 | } 108 | } 109 | 110 | return false; 111 | } 112 | 113 | public function set($key, $value = null) 114 | { 115 | if (is_array($key)) { 116 | foreach ($key as $innerKey => $innerValue) { 117 | static::arraySet($this->container, $innerKey, $innerValue); 118 | } 119 | } else { 120 | static::arraySet($this->container, $key, $value); 121 | } 122 | } 123 | 124 | /** 125 | * Set an array item to a given value using "dot" notation. 126 | * 127 | * If no key is given to the method, the entire array will be replaced. 128 | * 129 | * @param array $array 130 | * @param string|null $key 131 | * @param mixed $value 132 | * 133 | * @return array 134 | */ 135 | private static function arraySet(array &$array, ?string $key, $value): array 136 | { 137 | if (is_null($key)) { 138 | return $array = $value; 139 | } 140 | $keys = explode('.', $key); 141 | 142 | while (count($keys) > 1) { 143 | $key = array_shift($keys); 144 | 145 | // If the key doesn't exist at this depth, we will just create an empty array 146 | // to hold the next value, allowing us to create the arrays to hold final 147 | // values at the correct depth. Then we'll keep digging into the array. 148 | if (!isset($array[$key]) || !is_array($array[$key])) { 149 | $array[$key] = array(); 150 | } 151 | $array = &$array[$key]; 152 | } 153 | $array[array_shift($keys)] = $value; 154 | 155 | return $array; 156 | } 157 | 158 | #[\ReturnTypeWillChange] 159 | public function offsetSet($offset, $value) 160 | { 161 | if (is_null($offset)) { 162 | $this->container[] = $value; 163 | } else { 164 | $this->container[$offset] = $value; 165 | } 166 | } 167 | 168 | #[\ReturnTypeWillChange] 169 | public function offsetUnset($offset) 170 | { 171 | $this->container[$offset] = null; 172 | } 173 | 174 | /** 175 | * Determine if the given configuration value exists. 176 | * 177 | * @param string $key 178 | * @return bool 179 | */ 180 | public function has($key): bool 181 | { 182 | return $this->offsetExists($key); 183 | } 184 | 185 | public function all() 186 | { 187 | return $this->container; 188 | } 189 | 190 | /** 191 | * Prepend a value onto an array configuration value. 192 | * 193 | * @param string $key 194 | * @param mixed $value 195 | * @return void 196 | */ 197 | public function prepend($key, $value) 198 | { 199 | $this->container = [$key => $value] + $this->container; 200 | } 201 | 202 | /** 203 | * Push a value onto an array configuration value. 204 | * 205 | * @param string $key 206 | * @param mixed $value 207 | * @return void 208 | */ 209 | public function push($key, $value) 210 | { 211 | $this->container = $this->container + [$key => $value]; 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /bootstrap/Console/ProviderRepository.php: -------------------------------------------------------------------------------- 1 | app = $app; 43 | $this->files = $files; 44 | $this->manifestPath = $manifestPath; 45 | } 46 | 47 | /** 48 | * Register the application service providers. 49 | * 50 | * @param array $providers 51 | * @return void 52 | */ 53 | public function load(array $providers) 54 | { 55 | $manifest = $this->loadManifest(); 56 | 57 | // First we will load the service manifest, which contains information on all 58 | // service providers registered with the application and which services it 59 | // provides. This is used to know which services are "deferred" loaders. 60 | if ($this->shouldRecompile($manifest, $providers)) { 61 | $manifest = $this->compileManifest($providers); 62 | } 63 | 64 | // Next, we will register events to load the providers for each of the events 65 | // that it has requested. This allows the service provider to defer itself 66 | // while still getting automatically loaded when a certain event occurs. 67 | foreach ($manifest['when'] as $provider => $events) { 68 | $this->registerLoadEvents($provider, $events); 69 | } 70 | 71 | // We will go ahead and register all of the eagerly loaded providers with the 72 | // application so their services can be registered with the application as 73 | // a provided service. Then we will set the deferred service list on it. 74 | foreach ($manifest['eager'] as $provider) { 75 | $instance = $this->app->register($provider); 76 | //if (method_exists($instance, 'boot')) { 77 | //$instance->boot(); 78 | //} 79 | } 80 | 81 | $this->app->addDeferredServices($manifest['deferred']); 82 | } 83 | 84 | /** 85 | * Load the service provider manifest JSON file. 86 | * 87 | * @return array|null 88 | */ 89 | public function loadManifest() 90 | { 91 | // The service manifest is a file containing a JSON representation of every 92 | // service provided by the application and whether its provider is using 93 | // deferred loading or should be eagerly loaded on each request to us. 94 | if ($this->files->exists($this->manifestPath)) { 95 | $manifest = $this->files->getRequire($this->manifestPath); 96 | 97 | if ($manifest) { 98 | return array_merge(['when' => []], $manifest); 99 | } 100 | } 101 | } 102 | 103 | /** 104 | * Determine if the manifest should be compiled. 105 | * 106 | * @param array $manifest 107 | * @param array $providers 108 | * @return bool 109 | */ 110 | public function shouldRecompile($manifest, $providers) 111 | { 112 | return is_null($manifest) || $manifest['providers'] != $providers; 113 | } 114 | 115 | /** 116 | * Compile the application service manifest file. 117 | * 118 | * @param array $providers 119 | * @return array 120 | */ 121 | protected function compileManifest($providers) 122 | { 123 | // The service manifest should contain a list of all of the providers for 124 | // the application so we can compare it on each request to the service 125 | // and determine if the manifest should be recompiled or is current. 126 | $manifest = $this->freshManifest($providers); 127 | 128 | foreach ($providers as $provider) { 129 | $instance = $this->createProvider($provider); 130 | 131 | // When recompiling the service manifest, we will spin through each of the 132 | // providers and check if it's a deferred provider or not. If so we'll 133 | // add it's provided services to the manifest and note the provider. 134 | if ($instance->isDeferred()) { 135 | foreach ($instance->provides() as $service) { 136 | $manifest['deferred'][$service] = $provider; 137 | } 138 | 139 | $manifest['when'][$provider] = $instance->when(); 140 | } 141 | 142 | // If the service providers are not deferred, we will simply add it to an 143 | // array of eagerly loaded providers that will get registered on every 144 | // request to this application instead of "lazy" loading every time. 145 | else { 146 | $manifest['eager'][] = $provider; 147 | } 148 | } 149 | 150 | return $this->writeManifest($manifest); 151 | } 152 | 153 | /** 154 | * Create a fresh service manifest data structure. 155 | * 156 | * @param array $providers 157 | * @return array 158 | */ 159 | protected function freshManifest(array $providers) 160 | { 161 | return ['providers' => $providers, 'eager' => [], 'deferred' => []]; 162 | } 163 | 164 | /** 165 | * Create a new provider instance. 166 | * 167 | * @param string $provider 168 | * @return \Illuminate\Support\ServiceProvider 169 | */ 170 | public function createProvider($provider) 171 | { 172 | return new $provider($this->app); 173 | } 174 | 175 | /** 176 | * Write the service manifest file to disk. 177 | * 178 | * @param array $manifest 179 | * @return array 180 | * 181 | * @throws \Exception 182 | */ 183 | public function writeManifest($manifest) 184 | { 185 | if (!is_writable($dirname = dirname($this->manifestPath))) { 186 | throw new Exception("The {$dirname} directory must be present and writable."); 187 | } 188 | 189 | $this->files->replace( 190 | $this->manifestPath, 191 | ' []], $manifest); 195 | } 196 | 197 | /** 198 | * Register the load events for the given provider. 199 | * 200 | * @param string $provider 201 | * @param array $events 202 | * @return void 203 | */ 204 | protected function registerLoadEvents($provider, array $events) 205 | { 206 | if (count($events) < 1) { 207 | return; 208 | } 209 | 210 | $this->app->make('events')->listen($events, function () use ($provider) { 211 | $this->app->register($provider); 212 | }); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /bootstrap/Console/Artisan.php: -------------------------------------------------------------------------------- 1 | setName('Artisan'); 39 | $this->setCatchExceptions(true); 40 | } 41 | 42 | /** 43 | * Create and boot a new Console application. 44 | * 45 | * @param null $app 46 | * 47 | * @return Artisan 48 | */ 49 | public static function start($app = null): Artisan 50 | { 51 | if (static::$instance) { 52 | return static::$instance; 53 | } 54 | 55 | return static::make(); 56 | } 57 | 58 | /** 59 | * Create a new Console application. 60 | * 61 | * @param null $app 62 | * 63 | * @return Artisan 64 | */ 65 | public static function make($app = null): Artisan 66 | { 67 | if (!static::$instance) { 68 | /** @var Application $app */ 69 | $app = Facade::getFacadeApplication(); 70 | with($console = new static($app, $app['events'], Application::VERSION . '.*')) 71 | //->setExceptionHandler($app['exception']) 72 | ->setAutoExit(false); 73 | 74 | $app->instance('artisan', $console); 75 | static::registerServiceProviders($app); 76 | $console->add(new AutoloadCommand($app['composer'])); 77 | $console->add(new ServeCommand()); 78 | $console->add(new ModelMakeCommand($app['files'])); 79 | $console->add(new ConsoleMakeCommand($app['files'])); 80 | $console->add(new EnvironmentCommand()); 81 | $console->add(new VendorPublishCommand($app['files'])); 82 | $console->add(new FactoryMakeCommand($app['files'])); 83 | $console->add(new DbCommand()); 84 | $console->add(new DumpCommand()); 85 | $console->add(new WipeCommand()); 86 | 87 | /* 88 | use Illuminate\Database\Console\Migrations\FreshCommand; 89 | use Illuminate\Database\Console\Migrations\InstallCommand; 90 | use Illuminate\Database\Console\Migrations\MigrateCommand; 91 | use Illuminate\Database\Console\Migrations\MigrateMakeCommand; 92 | use Illuminate\Database\Console\Migrations\RefreshCommand; 93 | use Illuminate\Database\Console\Migrations\ResetCommand; 94 | use Illuminate\Database\Console\Migrations\RollbackCommand; 95 | use Illuminate\Database\Console\Migrations\StatusCommand; 96 | 97 | use Illuminate\Database\Migrations\DatabaseMigrationRepository; 98 | use Illuminate\Database\Migrations\MigrationCreator; 99 | use Illuminate\Database\Migrations\Migrator; 100 | 101 | // DB Migration Commands handled through service provider in config/app.php 102 | $app->instance( 103 | 'migration.repository', 104 | new DatabaseMigrationRepository($app['db'], "migrations") 105 | ); 106 | $app->instance( 107 | 'migrator', 108 | new Migrator($app['migration.repository'], $app['db'], $app['files'], $app['events']) 109 | ); 110 | $app->instance( 111 | 'migration.creator', 112 | new MigrationCreator($app['files'], $app->basePath('stubs')) 113 | ); 114 | $console->add(new InstallCommand($app['migration.repository'])); 115 | 116 | $console->add(new MigrateCommand($app['migrator'], $app['events'])); 117 | $console->add(new MigrateMakeCommand($app['migration.creator'], $app['composer'])); 118 | $console->add(new StatusCommand($app['migrator'])); 119 | $console->add(new RefreshCommand()); 120 | $console->add(new ResetCommand($app['migrator'])); 121 | $console->add(new RollbackCommand($app['migrator'])); 122 | $console->add(new FreshCommand()); 123 | */ 124 | 125 | // DB Seed Commands 126 | $console->add(new SeedCommand($app['db'])); 127 | $console->add(new SeedMakeCommand($app['files'], $app['composer'])); 128 | 129 | //Tinker Command 130 | $console->add(new TinkerCommand()); 131 | 132 | //Package AutoDiscovery 133 | $console->add(new PackageDiscoverCommand()); 134 | 135 | $app['events']->dispatch(new ArtisanStarting($console)); 136 | $console->bootstrap(); 137 | static::$instance = $console; 138 | } 139 | 140 | return static::$instance; 141 | } 142 | 143 | protected static function registerServiceProviders($app) 144 | { 145 | $providers = Collection::make($app->config['app.providers']) 146 | ->partition(function ($provider) { 147 | return strpos($provider, 'Illuminate\\') === 0; 148 | }); 149 | 150 | $providers->splice(1, 0, [$app->make(PackageManifest::class)->providers()]); 151 | 152 | $providers = $providers->collapse()->toArray(); 153 | 154 | foreach ($providers as $class) { 155 | /** @var ServiceProvider $instance */ 156 | $instance = new $class($app); 157 | $instance->register(); 158 | if (property_exists($instance, 'bindings')) { 159 | foreach ($instance->bindings as $key => $value) { 160 | $app->bind($key, $value); 161 | } 162 | } 163 | 164 | if (property_exists($instance, 'singletons')) { 165 | foreach ($instance->singletons as $key => $value) { 166 | $app->singleton($key, $value); 167 | } 168 | } 169 | if (method_exists($instance, 'boot')) { 170 | $instance->boot(); 171 | } 172 | } 173 | 174 | // (new ProviderRepository($app, new Filesystem, $app->getCachedServicesPath())) 175 | // ->load($providers->collapse()->toArray()); 176 | } 177 | 178 | /** 179 | * Register a Closure based command with the application. 180 | * 181 | * @param string $signature 182 | * @param Closure $callback 183 | * @return ClosureCommand 184 | */ 185 | public function command(string $signature, Closure $callback): ClosureCommand 186 | { 187 | $command = new ClosureCommand($signature, $callback); 188 | 189 | $this->add($command); 190 | 191 | return $command; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | load(); 52 | } 53 | 54 | $env = $app->detectEnvironment(getenv('APP_ENV') ?: 'development'); 55 | 56 | Facade::setFacadeApplication($app); 57 | 58 | $app->instance('config', new Config(app('path.config'), $env)); 59 | 60 | $app->singleton( 61 | 'events', 62 | function () use ($app) { 63 | return new Dispatcher($app); 64 | } 65 | ); 66 | $app->singleton( 67 | \Illuminate\Contracts\Events\Dispatcher::class, 68 | function () use ($app) { 69 | return $app['events']; 70 | } 71 | ); 72 | 73 | $app->singleton( 74 | 'files', 75 | function () use ($app) { 76 | return new Filesystem(); 77 | } 78 | ); 79 | 80 | $app->singleton( 81 | 'cache', 82 | function () use ($app) { 83 | return new CacheManager($app); 84 | } 85 | ); 86 | 87 | $app->singleton(PackageManifest::class, function () use ($app) { 88 | return new PackageManifest( 89 | new Filesystem, $app->basePath(), $app->getCachedPackagesPath() 90 | ); 91 | }); 92 | 93 | $app->singleton( 94 | 'db', 95 | function () use ($app) { 96 | $config = $app['config']; 97 | $default = $config['database.default']; 98 | $fetch = $config['database.fetch']; 99 | $db = new Database($app); 100 | $config['database.fetch'] = $fetch; 101 | $config['database.default'] = $default; 102 | $db->addConnection($config["database.connections.$default"]); 103 | $db->setEventDispatcher($app['events']); 104 | $db->setAsGlobal(); 105 | $db->bootEloquent(); 106 | 107 | $db->getDatabaseManager()->extend( 108 | 'mongodb', 109 | function ($config, $name) { 110 | $config['name'] = $name; 111 | return new Jenssegers\Mongodb\Connection($config); 112 | } 113 | ); 114 | return $db->getDatabaseManager(); 115 | } 116 | ); 117 | 118 | $app->singleton( 119 | 'queue', 120 | function () use ($app) { 121 | $config = $app['queue']; 122 | $default = $config['queue.default']; 123 | $connections = $config['queue.connections']; 124 | $config['queue.default'] = $default; 125 | $config['queue.connections'] = $connections; 126 | $queue = new Queue; 127 | $queue->addConnection($config['queue.connections'][$default]); 128 | $queue->setAsGlobal(); 129 | 130 | return $queue->getQueueManager(); 131 | } 132 | ); 133 | 134 | $app->singleton( 135 | 'queue.connection', 136 | function () use ($app) { 137 | return $app['queue']->connection(); 138 | } 139 | ); 140 | 141 | /* 142 | |-------------------------------------------------------------------------- 143 | | Pagination Support 144 | |-------------------------------------------------------------------------- 145 | */ 146 | Paginator::currentPathResolver( 147 | function () { 148 | return strtok($_SERVER["REQUEST_URI"], '?'); 149 | } 150 | ); 151 | 152 | Paginator::currentPageResolver( 153 | function ($pageName = 'page') { 154 | if (isset($_REQUEST[$pageName])) { 155 | $page = $_REQUEST[$pageName]; 156 | if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int)$page >= 1) { 157 | return $page; 158 | } 159 | } 160 | 161 | return 1; 162 | } 163 | ); 164 | 165 | /* 166 | |-------------------------------------------------------------------------- 167 | | Redis Support 168 | |-------------------------------------------------------------------------- 169 | */ 170 | $app->singleton( 171 | 'redis', 172 | function () use ($app) { 173 | return new Illuminate\Redis\Database($app['config']['database.redis']); 174 | } 175 | ); 176 | 177 | /* 178 | |-------------------------------------------------------------------------- 179 | | Register The Aliased Auto Loader 180 | |-------------------------------------------------------------------------- 181 | | 182 | | We register an auto-loader "before" the Composer loader that can load 183 | | aliased classes with out their namespaces. We'll add it to the stack here. 184 | | 185 | */ 186 | 187 | spl_autoload_register( 188 | function ($className) use ($app) { 189 | if (Model::class === $className) { 190 | include __DIR__ . '/../vendor/illuminate/database/Eloquent/Model.php'; 191 | $app['db']; 192 | return true; 193 | } 194 | if (Jenssegers\Mongodb\Eloquent\Model::class === $className) { 195 | //include __DIR__ . '/../vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Eloquent/Model.php'; 196 | $app['db']; 197 | return true; 198 | } 199 | if (isset($app['config']['app.aliases'][$className])) { 200 | $app['db']; //lazy initialization of DB 201 | return class_alias($app['config']['app.aliases'][$className], $className); 202 | } 203 | 204 | return false; 205 | }, 206 | true, 207 | true 208 | ); 209 | 210 | /* 211 | |-------------------------------------------------------------------------- 212 | | Configure Restler to adapt to Laravel structure 213 | |-------------------------------------------------------------------------- 214 | */ 215 | 216 | //$app['config']['app.aliases'] += Scope::$classAliases + ['Scope' => 'Luracast\Restler\Scope']; 217 | // 218 | //Defaults::$cacheDirectory = $app['config']['cache.path']; 219 | //HtmlFormat::$viewPath = $app['path'] . '/views'; 220 | //HtmlFormat::$cacheDirectory = $app['path.storage'] . '/views'; 221 | // 222 | //HtmlFormat::$template = 'blade'; 223 | ////Forms::$style = FormStyles::$bootstrap3; // for v4 and below 224 | //Forms::setStyles(new Bootstrap3Form); // for v5 225 | // 226 | //include BASE . '/routes/api.php'; 227 | -------------------------------------------------------------------------------- /bootstrap/Console/ModelMakeCommand.php: -------------------------------------------------------------------------------- 1 | option('force')) { 46 | return false; 47 | } 48 | 49 | if ($this->option('all')) { 50 | $this->input->setOption('factory', true); 51 | $this->input->setOption('migration', true); 52 | $this->input->setOption('seed', true); 53 | } 54 | 55 | if ($this->option('factory')) { 56 | $this->createFactory(); 57 | } 58 | 59 | if ($this->option('migration')) { 60 | $this->createMigration(); 61 | } 62 | 63 | if ($this->option('seed')) { 64 | $this->createSeeder(); 65 | } 66 | } 67 | 68 | /** 69 | * Get the default namespace for the class. 70 | * 71 | * @param string $rootNamespace 72 | * @return string 73 | */ 74 | protected function getDefaultNamespace($rootNamespace) 75 | { 76 | return $rootNamespace . '\Models'; 77 | } 78 | 79 | /** 80 | * Create a model factory for the model. 81 | * 82 | * @return void 83 | */ 84 | protected function createFactory() 85 | { 86 | $factory = Str::studly(class_basename($this->argument('name'))); 87 | 88 | $this->call('make:factory', [ 89 | 'name' => "{$factory}Factory", 90 | '--model' => $this->qualifyClass($this->getNameInput()), 91 | ]); 92 | } 93 | 94 | /** 95 | * Create a migration file for the model. 96 | * 97 | * @return void 98 | */ 99 | protected function createMigration() 100 | { 101 | $table = Str::snake(Str::pluralStudly(class_basename($this->argument('name')))); 102 | 103 | if ($this->option('pivot')) { 104 | $table = Str::singular($table); 105 | } 106 | 107 | $this->call('make:migration', [ 108 | 'name' => "create_{$table}_table", 109 | '--create' => $table, 110 | ]); 111 | } 112 | 113 | /** 114 | * Create a seeder file for the model. 115 | * 116 | * @return void 117 | */ 118 | protected function createSeeder() 119 | { 120 | $seeder = Str::studly(class_basename($this->argument('name'))); 121 | 122 | $this->call('make:seed', [ 123 | 'name' => "{$seeder}Seeder", 124 | ]); 125 | } 126 | 127 | protected function buildClass($name) 128 | { 129 | $replace = []; 130 | $replace = $this->buildReplacements($replace); 131 | return str_replace( 132 | array_keys($replace), array_values($replace), parent::buildClass($name) 133 | ); 134 | } 135 | 136 | /** 137 | * Build the model replacement values. 138 | * 139 | * @param array $replace 140 | * @return array 141 | */ 142 | protected function buildReplacements(array $replace) 143 | { 144 | $table = $this->option('table') 145 | ?? str_plural(strtolower( 146 | preg_replace('/([a-z])([A-Z])/', 147 | '$1_$2', 148 | class_basename($this->argument('name') 149 | )))); 150 | try { 151 | $fields = Schema::getColumnListing($table); 152 | }catch (Throwable $t){ 153 | //ignore 154 | $fields = []; 155 | } 156 | 157 | $hide = ['password', 'secret']; 158 | $avoid = ['id', 'ID', 'verified', 'active']; 159 | 160 | $timestamps = 'true'; 161 | $fillable = ''; 162 | $hidden = ''; 163 | $import = ''; 164 | $use = ''; 165 | 166 | $properties = ''; 167 | if (!empty($fields)) { 168 | foreach ($fields as $property) { 169 | if ($isDate = ends_with($property, '_at')) { 170 | $avoid[] = $property; 171 | } 172 | if ($is_id = ends_with($property, '_id')) { 173 | $avoid[] = $property; 174 | } 175 | list($type, $subType) = $this->guessType($property); 176 | $pt = in_array($property, $hide) 177 | ? '@property-write' 178 | : (in_array($property, $avoid) || $isDate ? '@property-read ' : '@property '); 179 | $properties .= "$pt $type \${$property}$subType\n * "; 180 | } 181 | 182 | $timestamps = in_array('created_at', $fields) ? 'true' : 'false'; 183 | $fields = array_diff($fields, $avoid); 184 | $hide = array_intersect($fields, $hide); 185 | 186 | $fillable = "'" . implode("',\n '", $fields) . "'"; 187 | 188 | if (in_array('deleted_at', $fields)) { 189 | $import = "use Illuminate\\Database\\Eloquent\\SoftDeletingTrait;\n\n"; 190 | $use = "use SoftDeletingTrait;\n\n protected \$dates = ['deleted_at'];\n "; 191 | } 192 | } 193 | 194 | if (!empty($hide)) { 195 | $hidden = "'" . implode("',\n '", $hide) . "'"; 196 | } 197 | return array_merge($replace, [ 198 | '{{ import }}' => $import, 199 | '{{ properties }}' => $properties, 200 | '{{ use }}' => $use, 201 | '{{ table }}' => $table, 202 | '{{ timestamps }}' => $timestamps, 203 | '{{ fillable }}' => $fillable, 204 | '{{ hidden }}' => $hidden, 205 | ]); 206 | } 207 | 208 | protected function guessType($name) 209 | { 210 | $subtype = ''; 211 | $type = 'string'; 212 | if (ends_with($name, '_at')) { 213 | //date field 214 | $subtype = ' {@type date}'; 215 | } elseif (ends_with($name, ['id', 'ID'])) { 216 | //int 217 | $type = 'int '; 218 | } // else //assume string 219 | 220 | return [$type, $subtype]; 221 | } 222 | 223 | /** 224 | * Get the stub file for the generator. 225 | * 226 | * @return string 227 | */ 228 | protected function getStub() 229 | { 230 | return __DIR__ . ($this->option('pivot') 231 | ? '/stubs/model.pivot.stub' 232 | : '/stubs/model.stub'); 233 | } 234 | 235 | /** 236 | * Get the console command options. 237 | * 238 | * @return array 239 | */ 240 | protected function getOptions() 241 | { 242 | return [ 243 | ['table', 't', InputOption::VALUE_OPTIONAL, 'The table name to be associated with the model.'], 244 | ['all', 'a', InputOption::VALUE_NONE, 'Generate a migration, seeder, factory, and resource controller for the model'], 245 | ['controller', 'c', InputOption::VALUE_NONE, 'Create a new controller for the model'], 246 | ['factory', 'f', InputOption::VALUE_NONE, 'Create a new factory for the model'], 247 | ['force', null, InputOption::VALUE_NONE, 'Create the class even if the model already exists'], 248 | ['migration', 'm', InputOption::VALUE_NONE, 'Create a new migration file for the model'], 249 | ['seed', 's', InputOption::VALUE_NONE, 'Create a new seeder file for the model'], 250 | ['pivot', 'p', InputOption::VALUE_NONE, 'Indicates if the generated model should be a custom intermediate table model'], 251 | ]; 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /bootstrap/Console/GeneratorCommand.php: -------------------------------------------------------------------------------- 1 | files = $files; 114 | } 115 | 116 | /** 117 | * Get the stub file for the generator. 118 | * 119 | * @return string 120 | */ 121 | abstract protected function getStub(); 122 | 123 | /** 124 | * Execute the console command. 125 | * 126 | * @return bool|null 127 | * 128 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException 129 | */ 130 | public function handle() 131 | { 132 | // First we need to ensure that the given name is not a reserved word within the PHP 133 | // language and that the class name will actually be valid. If it is not valid we 134 | // can error now and prevent from polluting the filesystem using invalid files. 135 | if ($this->isReservedName($this->getNameInput())) { 136 | $this->error('The name "' . $this->getNameInput() . '" is reserved by PHP.'); 137 | 138 | return false; 139 | } 140 | 141 | $name = $this->qualifyClass($this->getNameInput()); 142 | 143 | $path = $this->getPath($name); 144 | 145 | // Next, We will check to see if the class already exists. If it does, we don't want 146 | // to create the class and overwrite the user's code. So, we will bail out so the 147 | // code is untouched. Otherwise, we will continue generating this class' files. 148 | if ((!$this->hasOption('force') || 149 | !$this->option('force')) && 150 | $this->alreadyExists($this->getNameInput())) { 151 | $this->error($this->type . ' already exists!'); 152 | 153 | return false; 154 | } 155 | 156 | // Next, we will generate the path to the location where this class' file should get 157 | // written. Then, we will build the class and make the proper replacements on the 158 | // stub files so that it gets the correctly formatted namespace and class name. 159 | $this->makeDirectory($path); 160 | 161 | $this->files->put($path, $this->sortImports($this->buildClass($name))); 162 | 163 | $this->info($this->type . ' created successfully.'); 164 | } 165 | 166 | /** 167 | * Parse the class name and format according to the root namespace. 168 | * 169 | * @param string $name 170 | * @return string 171 | */ 172 | protected function qualifyClass($name) 173 | { 174 | $name = ltrim($name, '\\/'); 175 | 176 | $rootNamespace = $this->rootNamespace(); 177 | 178 | if (Str::startsWith($name, $rootNamespace)) { 179 | return $name; 180 | } 181 | 182 | $name = str_replace('/', '\\', $name); 183 | 184 | return $this->qualifyClass( 185 | $this->getDefaultNamespace(trim($rootNamespace, '\\')) . '\\' . $name 186 | ); 187 | } 188 | 189 | /** 190 | * Get the default namespace for the class. 191 | * 192 | * @param string $rootNamespace 193 | * @return string 194 | */ 195 | protected function getDefaultNamespace($rootNamespace) 196 | { 197 | return $rootNamespace; 198 | } 199 | 200 | /** 201 | * Determine if the class already exists. 202 | * 203 | * @param string $rawName 204 | * @return bool 205 | */ 206 | protected function alreadyExists($rawName) 207 | { 208 | return $this->files->exists($this->getPath($this->qualifyClass($rawName))); 209 | } 210 | 211 | /** 212 | * Get the destination class path. 213 | * 214 | * @param string $name 215 | * @return string 216 | */ 217 | protected function getPath($name) 218 | { 219 | $name = Str::replaceFirst($this->rootNamespace(), '', $name); 220 | 221 | return $this->laravel['path'] . '/' . str_replace('\\', '/', $name) . '.php'; 222 | } 223 | 224 | /** 225 | * Build the directory for the class if necessary. 226 | * 227 | * @param string $path 228 | * @return string 229 | */ 230 | protected function makeDirectory($path) 231 | { 232 | if (!$this->files->isDirectory(dirname($path))) { 233 | $this->files->makeDirectory(dirname($path), 0777, true, true); 234 | } 235 | 236 | return $path; 237 | } 238 | 239 | /** 240 | * Build the class with the given name. 241 | * 242 | * @param string $name 243 | * @return string 244 | * 245 | * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException 246 | */ 247 | protected function buildClass($name) 248 | { 249 | $stub = $this->files->get($this->getStub()); 250 | 251 | return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name); 252 | } 253 | 254 | /** 255 | * Replace the namespace for the given stub. 256 | * 257 | * @param string $stub 258 | * @param string $name 259 | * @return $this 260 | */ 261 | protected function replaceNamespace(&$stub, $name) 262 | { 263 | $searches = [ 264 | ['DummyNamespace', 'DummyRootNamespace', 'NamespacedDummyUserModel'], 265 | ['{{ namespace }}', '{{ rootNamespace }}', '{{ namespacedUserModel }}'], 266 | ['{{namespace}}', '{{rootNamespace}}', '{{namespacedUserModel}}'], 267 | ]; 268 | 269 | foreach ($searches as $search) { 270 | $stub = str_replace( 271 | $search, 272 | [$this->getNamespace($name), $this->rootNamespace(), $this->userProviderModel()], 273 | $stub 274 | ); 275 | } 276 | 277 | return $this; 278 | } 279 | 280 | /** 281 | * Get the full namespace for a given class, without the class name. 282 | * 283 | * @param string $name 284 | * @return string 285 | */ 286 | protected function getNamespace($name) 287 | { 288 | return trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); 289 | } 290 | 291 | /** 292 | * Replace the class name for the given stub. 293 | * 294 | * @param string $stub 295 | * @param string $name 296 | * @return string 297 | */ 298 | protected function replaceClass($stub, $name) 299 | { 300 | $class = str_replace($this->getNamespace($name) . '\\', '', $name); 301 | 302 | return str_replace(['DummyClass', '{{ class }}', '{{class}}'], $class, $stub); 303 | } 304 | 305 | /** 306 | * Alphabetically sorts the imports for the given stub. 307 | * 308 | * @param string $stub 309 | * @return string 310 | */ 311 | protected function sortImports($stub) 312 | { 313 | if (preg_match('/(?P(?:use [^;]+;$\n?)+)/m', $stub, $match)) { 314 | $imports = explode("\n", trim($match['imports'])); 315 | 316 | sort($imports); 317 | 318 | return str_replace(trim($match['imports']), implode("\n", $imports), $stub); 319 | } 320 | 321 | return $stub; 322 | } 323 | 324 | /** 325 | * Get the desired class name from the input. 326 | * 327 | * @return string 328 | */ 329 | protected function getNameInput() 330 | { 331 | return trim($this->argument('name')); 332 | } 333 | 334 | /** 335 | * Get the root namespace for the class. 336 | * 337 | * @return string 338 | */ 339 | protected function rootNamespace() 340 | { 341 | return $this->laravel->getNamespace(); 342 | } 343 | 344 | /** 345 | * Get the model for the default guard's user provider. 346 | * 347 | * @return string|null 348 | */ 349 | protected function userProviderModel() 350 | { 351 | $config = $this->laravel['config']; 352 | 353 | $provider = $config->get('auth.guards.' . $config->get('auth.defaults.guard') . '.provider'); 354 | 355 | return $config->get("auth.providers.{$provider}.model"); 356 | } 357 | 358 | /** 359 | * Checks whether the given name is reserved. 360 | * 361 | * @param string $name 362 | * @return bool 363 | */ 364 | protected function isReservedName($name) 365 | { 366 | $name = strtolower($name); 367 | 368 | return in_array($name, $this->reservedNames); 369 | } 370 | 371 | /** 372 | * Get the console command arguments. 373 | * 374 | * @return array 375 | */ 376 | protected function getArguments() 377 | { 378 | return [ 379 | ['name', InputArgument::REQUIRED, 'The name of the class'], 380 | ]; 381 | } 382 | } 383 | 384 | -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | 11 | * @see https://github.com/barryvdh/laravel-ide-helper 12 | */ 13 | override(new \Illuminate\Contracts\Container\Container, map([ 14 | '' => '@', 15 | 'app' => \Bootstrap\Container\Application::class, 16 | 'cache' => \Illuminate\Cache\CacheManager::class, 17 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 18 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 19 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 20 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 21 | 'composer' => \Illuminate\Support\Composer::class, 22 | 'db' => \Illuminate\Database\DatabaseManager::class, 23 | 'events' => \Illuminate\Events\Dispatcher::class, 24 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 25 | 'files' => \Illuminate\Filesystem\Filesystem::class, 26 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 27 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 28 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 29 | ])); 30 | override(\Illuminate\Container\Container::makeWith(0), map([ 31 | '' => '@', 32 | 'app' => \Bootstrap\Container\Application::class, 33 | 'cache' => \Illuminate\Cache\CacheManager::class, 34 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 35 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 36 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 37 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 38 | 'composer' => \Illuminate\Support\Composer::class, 39 | 'db' => \Illuminate\Database\DatabaseManager::class, 40 | 'events' => \Illuminate\Events\Dispatcher::class, 41 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 42 | 'files' => \Illuminate\Filesystem\Filesystem::class, 43 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 44 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 45 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 46 | ])); 47 | override(\Illuminate\Contracts\Container\Container::make(0), map([ 48 | '' => '@', 49 | 'app' => \Bootstrap\Container\Application::class, 50 | 'cache' => \Illuminate\Cache\CacheManager::class, 51 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 52 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 53 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 54 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 55 | 'composer' => \Illuminate\Support\Composer::class, 56 | 'db' => \Illuminate\Database\DatabaseManager::class, 57 | 'events' => \Illuminate\Events\Dispatcher::class, 58 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 59 | 'files' => \Illuminate\Filesystem\Filesystem::class, 60 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 61 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 62 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 63 | ])); 64 | override(\Illuminate\Contracts\Container\Container::makeWith(0), map([ 65 | '' => '@', 66 | 'app' => \Bootstrap\Container\Application::class, 67 | 'cache' => \Illuminate\Cache\CacheManager::class, 68 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 69 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 70 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 71 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 72 | 'composer' => \Illuminate\Support\Composer::class, 73 | 'db' => \Illuminate\Database\DatabaseManager::class, 74 | 'events' => \Illuminate\Events\Dispatcher::class, 75 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 76 | 'files' => \Illuminate\Filesystem\Filesystem::class, 77 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 78 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 79 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 80 | ])); 81 | override(\App::make(0), map([ 82 | '' => '@', 83 | 'app' => \Bootstrap\Container\Application::class, 84 | 'cache' => \Illuminate\Cache\CacheManager::class, 85 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 86 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 87 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 88 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 89 | 'composer' => \Illuminate\Support\Composer::class, 90 | 'db' => \Illuminate\Database\DatabaseManager::class, 91 | 'events' => \Illuminate\Events\Dispatcher::class, 92 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 93 | 'files' => \Illuminate\Filesystem\Filesystem::class, 94 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 95 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 96 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 97 | ])); 98 | override(\App::makeWith(0), map([ 99 | '' => '@', 100 | 'app' => \Bootstrap\Container\Application::class, 101 | 'cache' => \Illuminate\Cache\CacheManager::class, 102 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 103 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 104 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 105 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 106 | 'composer' => \Illuminate\Support\Composer::class, 107 | 'db' => \Illuminate\Database\DatabaseManager::class, 108 | 'events' => \Illuminate\Events\Dispatcher::class, 109 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 110 | 'files' => \Illuminate\Filesystem\Filesystem::class, 111 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 112 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 113 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 114 | ])); 115 | override(\app(0), map([ 116 | '' => '@', 117 | 'app' => \Bootstrap\Container\Application::class, 118 | 'cache' => \Illuminate\Cache\CacheManager::class, 119 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 120 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 121 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 122 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 123 | 'composer' => \Illuminate\Support\Composer::class, 124 | 'db' => \Illuminate\Database\DatabaseManager::class, 125 | 'events' => \Illuminate\Events\Dispatcher::class, 126 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 127 | 'files' => \Illuminate\Filesystem\Filesystem::class, 128 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 129 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 130 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 131 | ])); 132 | override(\resolve(0), map([ 133 | '' => '@', 134 | 'app' => \Bootstrap\Container\Application::class, 135 | 'cache' => \Illuminate\Cache\CacheManager::class, 136 | 'command.ide-helper.eloquent' => \Barryvdh\LaravelIdeHelper\Console\EloquentCommand::class, 137 | 'command.ide-helper.generate' => \Barryvdh\LaravelIdeHelper\Console\GeneratorCommand::class, 138 | 'command.ide-helper.meta' => \Barryvdh\LaravelIdeHelper\Console\MetaCommand::class, 139 | 'command.ide-helper.models' => \Barryvdh\LaravelIdeHelper\Console\ModelsCommand::class, 140 | 'composer' => \Illuminate\Support\Composer::class, 141 | 'db' => \Illuminate\Database\DatabaseManager::class, 142 | 'events' => \Illuminate\Events\Dispatcher::class, 143 | 'exception' => \Bootstrap\Console\ExceptionHandler::class, 144 | 'files' => \Illuminate\Filesystem\Filesystem::class, 145 | 'migration.creator' => \Illuminate\Database\Migrations\MigrationCreator::class, 146 | 'migration.repository' => \Illuminate\Database\Migrations\DatabaseMigrationRepository::class, 147 | 'migrator' => \Illuminate\Database\Migrations\Migrator::class, 148 | ])); 149 | 150 | override(\Illuminate\Support\Arr::add(0), type(0)); 151 | override(\Illuminate\Support\Arr::except(0), type(0)); 152 | override(\Illuminate\Support\Arr::first(0), elementType(0)); 153 | override(\Illuminate\Support\Arr::last(0), elementType(0)); 154 | override(\Illuminate\Support\Arr::get(0), elementType(0)); 155 | override(\Illuminate\Support\Arr::only(0), type(0)); 156 | override(\Illuminate\Support\Arr::prepend(0), type(0)); 157 | override(\Illuminate\Support\Arr::pull(0), elementType(0)); 158 | override(\Illuminate\Support\Arr::set(0), type(0)); 159 | override(\Illuminate\Support\Arr::shuffle(0), type(0)); 160 | override(\Illuminate\Support\Arr::sort(0), type(0)); 161 | override(\Illuminate\Support\Arr::sortRecursive(0), type(0)); 162 | override(\Illuminate\Support\Arr::where(0), type(0)); 163 | override(\array_add(0), type(0)); 164 | override(\array_except(0), type(0)); 165 | override(\array_first(0), elementType(0)); 166 | override(\array_last(0), elementType(0)); 167 | override(\array_get(0), elementType(0)); 168 | override(\array_only(0), type(0)); 169 | override(\array_prepend(0), type(0)); 170 | override(\array_pull(0), elementType(0)); 171 | override(\array_set(0), type(0)); 172 | override(\array_sort(0), type(0)); 173 | override(\array_sort_recursive(0), type(0)); 174 | override(\array_where(0), type(0)); 175 | override(\head(0), elementType(0)); 176 | override(\last(0), elementType(0)); 177 | override(\with(0), type(0)); 178 | override(\tap(0), type(0)); 179 | 180 | } 181 | -------------------------------------------------------------------------------- /bootstrap/helpers.php: -------------------------------------------------------------------------------- 1 | make($abstract, $parameters); 25 | } 26 | } 27 | 28 | if (! function_exists('app_path')) { 29 | /** 30 | * Get the path to the application folder. 31 | * 32 | * @param string $path 33 | * @return string 34 | */ 35 | function app_path($path = '') 36 | { 37 | return app()->path($path); 38 | } 39 | } 40 | 41 | if (! function_exists('base_path')) { 42 | /** 43 | * Get the path to the base of the install. 44 | * 45 | * @param string $path 46 | * @return string 47 | */ 48 | function base_path($path = '') 49 | { 50 | return app()->basePath($path); 51 | } 52 | } 53 | 54 | if (! function_exists('bcrypt')) { 55 | /** 56 | * Hash the given value against the bcrypt algorithm. 57 | * 58 | * @param string $value 59 | * @param array $options 60 | * @return string 61 | */ 62 | function bcrypt($value, $options = []) 63 | { 64 | return app('hash')->driver('bcrypt')->make($value, $options); 65 | } 66 | } 67 | 68 | if (! function_exists('broadcast')) { 69 | /** 70 | * Begin broadcasting an event. 71 | * 72 | * @param mixed|null $event 73 | * @return \Illuminate\Broadcasting\PendingBroadcast 74 | */ 75 | function broadcast($event = null) 76 | { 77 | return app(BroadcastFactory::class)->event($event); 78 | } 79 | } 80 | 81 | if (! function_exists('cache')) { 82 | /** 83 | * Get / set the specified cache value. 84 | * 85 | * If an array is passed, we'll assume you want to put to the cache. 86 | * 87 | * @param dynamic key|key,default|data,expiration|null 88 | * @return mixed|\Illuminate\Cache\CacheManager 89 | * 90 | * @throws \Exception 91 | */ 92 | function cache() 93 | { 94 | $arguments = func_get_args(); 95 | 96 | if (empty($arguments)) { 97 | return app('cache'); 98 | } 99 | 100 | if (is_string($arguments[0])) { 101 | return app('cache')->get(...$arguments); 102 | } 103 | 104 | if (! is_array($arguments[0])) { 105 | throw new Exception( 106 | 'When setting a value in the cache, you must pass an array of key / value pairs.' 107 | ); 108 | } 109 | 110 | return app('cache')->put(key($arguments[0]), reset($arguments[0]), $arguments[1] ?? null); 111 | } 112 | } 113 | 114 | if (! function_exists('config')) { 115 | /** 116 | * Get / set the specified configuration value. 117 | * 118 | * If an array is passed as the key, we will assume you want to set an array of values. 119 | * 120 | * @param array|string|null $key 121 | * @param mixed $default 122 | * @return mixed|Config 123 | */ 124 | function config($key = null, $default = null) 125 | { 126 | if (is_null($key)) { 127 | return app('config'); 128 | } 129 | 130 | if (is_array($key)) { 131 | return app('config')->set($key); 132 | } 133 | 134 | return app('config')->get($key, $default); 135 | } 136 | } 137 | 138 | if (! function_exists('config_path')) { 139 | /** 140 | * Get the configuration path. 141 | * 142 | * @param string $path 143 | * @return string 144 | */ 145 | function config_path($path = '') 146 | { 147 | return app()->configPath($path); 148 | } 149 | } 150 | 151 | if (! function_exists('database_path')) { 152 | /** 153 | * Get the database path. 154 | * 155 | * @param string $path 156 | * @return string 157 | */ 158 | function database_path($path = '') 159 | { 160 | return app()->databasePath($path); 161 | } 162 | } 163 | 164 | if (! function_exists('decrypt')) { 165 | /** 166 | * Decrypt the given value. 167 | * 168 | * @param string $value 169 | * @param bool $unserialize 170 | * @return mixed 171 | */ 172 | function decrypt($value, $unserialize = true) 173 | { 174 | return app('encrypter')->decrypt($value, $unserialize); 175 | } 176 | } 177 | 178 | if (! function_exists('dispatch')) { 179 | /** 180 | * Dispatch a job to its appropriate handler. 181 | * 182 | * @param mixed $job 183 | * @return \Illuminate\Foundation\Bus\PendingDispatch 184 | */ 185 | function dispatch($job) 186 | { 187 | return $job instanceof Closure 188 | ? new PendingClosureDispatch(CallQueuedClosure::create($job)) 189 | : new PendingDispatch($job); 190 | } 191 | } 192 | 193 | if (! function_exists('dispatch_sync')) { 194 | /** 195 | * Dispatch a command to its appropriate handler in the current process. 196 | * 197 | * Queueable jobs will be dispatched to the "sync" queue. 198 | * 199 | * @param mixed $job 200 | * @param mixed $handler 201 | * @return mixed 202 | */ 203 | function dispatch_sync($job, $handler = null) 204 | { 205 | return app(Dispatcher::class)->dispatchSync($job, $handler); 206 | } 207 | } 208 | 209 | if (! function_exists('dispatch_now')) { 210 | /** 211 | * Dispatch a command to its appropriate handler in the current process. 212 | * 213 | * @param mixed $job 214 | * @param mixed $handler 215 | * @return mixed 216 | * 217 | * @deprecated Will be removed in a future Laravel version. 218 | */ 219 | function dispatch_now($job, $handler = null) 220 | { 221 | return app(Dispatcher::class)->dispatchNow($job, $handler); 222 | } 223 | } 224 | 225 | if (! function_exists('encrypt')) { 226 | /** 227 | * Encrypt the given value. 228 | * 229 | * @param mixed $value 230 | * @param bool $serialize 231 | * @return string 232 | */ 233 | function encrypt($value, $serialize = true) 234 | { 235 | return app('encrypter')->encrypt($value, $serialize); 236 | } 237 | } 238 | 239 | if (!function_exists('env')) { 240 | /** 241 | * Gets the value of an environment variable. Supports boolean, empty and null. 242 | * 243 | * @param string $key 244 | * @param mixed $default 245 | * 246 | * @return mixed 247 | */ 248 | function env($key, $default = null) 249 | { 250 | $value = getenv($key); 251 | if ($value === false) { 252 | return value($default); 253 | } 254 | switch (strtolower($value)) { 255 | case 'true': 256 | case '(true)': 257 | return true; 258 | case 'false': 259 | case '(false)': 260 | return false; 261 | case 'empty': 262 | case '(empty)': 263 | return ''; 264 | case 'null': 265 | case '(null)': 266 | return; 267 | } 268 | if (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) { 269 | return substr($value, 1, -1); 270 | } 271 | 272 | return $value; 273 | } 274 | } 275 | 276 | if (! function_exists('event')) { 277 | /** 278 | * Dispatch an event and call the listeners. 279 | * 280 | * @param string|object $event 281 | * @param mixed $payload 282 | * @param bool $halt 283 | * @return array|null 284 | */ 285 | function event(...$args) 286 | { 287 | return app('events')->dispatch(...$args); 288 | } 289 | } 290 | 291 | if (! function_exists('info')) { 292 | /** 293 | * Write some information to the log. 294 | * 295 | * @param string $message 296 | * @param array $context 297 | * @return void 298 | */ 299 | function info($message, $context = []) 300 | { 301 | app('log')->info($message, $context); 302 | } 303 | } 304 | 305 | if (! function_exists('logger')) { 306 | /** 307 | * Log a debug message to the logs. 308 | * 309 | * @param string|null $message 310 | * @param array $context 311 | * @return \Illuminate\Log\LogManager|null 312 | */ 313 | function logger($message = null, array $context = []) 314 | { 315 | if (is_null($message)) { 316 | return app('log'); 317 | } 318 | 319 | return app('log')->debug($message, $context); 320 | } 321 | } 322 | 323 | if (! function_exists('logs')) { 324 | /** 325 | * Get a log driver instance. 326 | * 327 | * @param string|null $driver 328 | * @return \Illuminate\Log\LogManager|\Psr\Log\LoggerInterface 329 | */ 330 | function logs($driver = null) 331 | { 332 | return $driver ? app('log')->driver($driver) : app('log'); 333 | } 334 | } 335 | 336 | if (! function_exists('now')) { 337 | /** 338 | * Create a new Carbon instance for the current time. 339 | * 340 | * @param \DateTimeZone|string|null $tz 341 | * @return \Illuminate\Support\Carbon 342 | */ 343 | function now($tz = null) 344 | { 345 | return Date::now($tz); 346 | } 347 | } 348 | 349 | if (! function_exists('public_path')) { 350 | /** 351 | * Get the path to the public folder. 352 | * 353 | * @param string $path 354 | * @return string 355 | */ 356 | function public_path($path = '') 357 | { 358 | return app()->make('path.public').($path ? DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR) : $path); 359 | } 360 | } 361 | 362 | if (! function_exists('rescue')) { 363 | /** 364 | * Catch a potential exception and return a default value. 365 | * 366 | * @param callable $callback 367 | * @param mixed $rescue 368 | * @param bool $report 369 | * @return mixed 370 | */ 371 | function rescue(callable $callback, $rescue = null, $report = true) 372 | { 373 | try { 374 | return $callback(); 375 | } catch (Throwable $e) { 376 | if ($report) { 377 | report($e); 378 | } 379 | 380 | return value($rescue, $e); 381 | } 382 | } 383 | } 384 | 385 | if (! function_exists('resolve')) { 386 | /** 387 | * Resolve a service from the container. 388 | * 389 | * @param string $name 390 | * @param array $parameters 391 | * @return mixed 392 | */ 393 | function resolve($name, array $parameters = []) 394 | { 395 | return app($name, $parameters); 396 | } 397 | } 398 | 399 | if (! function_exists('resource_path')) { 400 | /** 401 | * Get the path to the resources folder. 402 | * 403 | * @param string $path 404 | * @return string 405 | */ 406 | function resource_path($path = '') 407 | { 408 | return app()->resourcePath($path); 409 | } 410 | } 411 | 412 | if (! function_exists('storage_path')) { 413 | /** 414 | * Get the path to the storage folder. 415 | * 416 | * @param string $path 417 | * @return string 418 | */ 419 | function storage_path($path = '') 420 | { 421 | return app('path.storage').($path ? DIRECTORY_SEPARATOR.$path : $path); 422 | } 423 | } 424 | 425 | if (! function_exists('today')) { 426 | /** 427 | * Create a new Carbon instance for the current date. 428 | * 429 | * @param \DateTimeZone|string|null $tz 430 | * @return \Illuminate\Support\Carbon 431 | */ 432 | function today($tz = null) 433 | { 434 | return Date::today($tz); 435 | } 436 | } 437 | 438 | 439 | if (! function_exists('view')) { 440 | /** 441 | * Get the evaluated view contents for the given view. 442 | * 443 | * @param string|null $view 444 | * @param \Illuminate\Contracts\Support\Arrayable|array $data 445 | * @param array $mergeData 446 | * @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory 447 | */ 448 | function view($view = null, $data = [], $mergeData = []) 449 | { 450 | $factory = app(ViewFactory::class); 451 | 452 | if (func_num_args() === 0) { 453 | return $factory; 454 | } 455 | 456 | return $factory->make($view, $data, $mergeData); 457 | } 458 | } 459 | -------------------------------------------------------------------------------- /bootstrap/Container/Application.php: -------------------------------------------------------------------------------- 1 | basePath = $basePath; 84 | static::setInstance($this); 85 | $this->instance('app', $this); 86 | $this->instance('path', $this->path()); 87 | $this->instance('path.base', $this->basePath()); 88 | $this->instance('path.config', $this->configPath()); 89 | $this->instance('path.public', $this->publicPath()); 90 | $this->instance('path.storage', $this->storagePath()); 91 | $this->instance('path.database', $this->databasePath()); 92 | $this->instance('path.resources', $this->resourcePath()); 93 | $this->instance('path.bootstrap', $this->bootstrapPath()); 94 | //$this->registerErrorHandling(); 95 | } 96 | 97 | /** 98 | * Get the path to the application "app" directory. 99 | * 100 | * @param string $path 101 | * @return string 102 | */ 103 | public function path($path = '') 104 | { 105 | $appPath = $this->appPath ?: $this->basePath('app'); 106 | 107 | return $appPath . ($path ? DIRECTORY_SEPARATOR . $path : $path); 108 | } 109 | 110 | /** 111 | * Get the base path for the application. 112 | * 113 | * @param string $path 114 | * 115 | * @return string 116 | */ 117 | public function basePath($path = ''): string 118 | { 119 | if (isset($this->basePath)) { 120 | return $this->basePath . ($path ? '/' . $path : $path); 121 | } 122 | $this->basePath = realpath(__DIR__ . '/../../'); 123 | 124 | return $this->basePath($path); 125 | } 126 | 127 | public function configPath($path = ''): string 128 | { 129 | return $this->basePath . DIRECTORY_SEPARATOR . 'config' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 130 | } 131 | 132 | public function publicPath() 133 | { 134 | return $this->basePath . DIRECTORY_SEPARATOR . 'public'; 135 | } 136 | 137 | /** 138 | * Get the storage path for the application. 139 | * 140 | * @param string|null $path 141 | * 142 | * @return string 143 | */ 144 | public function storagePath(string $path = null): string 145 | { 146 | return $this->storagePath ?: $this->basePath . DIRECTORY_SEPARATOR . 'storage'; 147 | } 148 | 149 | /** 150 | * Get the path to the database directory. 151 | * 152 | * @param string $path Optionally, a path to append to the database path 153 | * @return string 154 | */ 155 | public function databasePath($path = ''): string 156 | { 157 | return ($this->databasePath ?: $this->basePath . DIRECTORY_SEPARATOR . 'database') . 158 | ($path ? DIRECTORY_SEPARATOR . $path : $path); 159 | } 160 | 161 | public function resourcePath($path = ''): string 162 | { 163 | return $this->basePath . DIRECTORY_SEPARATOR . 'resources' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 164 | } 165 | 166 | public function bootstrapPath($path = ''): string 167 | { 168 | return $this->basePath . DIRECTORY_SEPARATOR . 'bootstrap' . ($path ? DIRECTORY_SEPARATOR . $path : $path); 169 | } 170 | 171 | /** 172 | * Determine if the application is running in the console. 173 | * 174 | * @return bool 175 | */ 176 | public function runningInConsole(): bool 177 | { 178 | return php_sapi_name() === 'cli'; 179 | } 180 | 181 | /** 182 | * @return string 183 | */ 184 | public function version(): string 185 | { 186 | return static::VERSION; 187 | } 188 | 189 | /** 190 | * Detect the application's current environment. 191 | * 192 | * @param array|string $environments 193 | * 194 | * @return string 195 | */ 196 | public function detectEnvironment($environments): string 197 | { 198 | $args = $_SERVER['argv'] ?? null; 199 | if (php_sapi_name() == 'cli' && !is_null($value = $this->getEnvironmentArgument($args))) { 200 | //running in console and env param is set 201 | return $this['env'] = head(array_slice(explode('=', $value), 1)); 202 | } else { 203 | //running as the web app 204 | 205 | if ($environments instanceof Closure) { 206 | // If the given environment is just a Closure, we will defer the environment check 207 | // to the Closure the developer has provided, which allows them to totally swap 208 | // the webs environment detection logic with their own custom Closure's code. 209 | return $this['env'] = call_user_func($environments); 210 | } elseif (is_array($environments)) { 211 | foreach ($environments as $environment => $hosts) { 212 | // To determine the current environment, we'll simply iterate through the possible 213 | // environments and look for the host that matches the host for this request we 214 | // are currently processing here, then return back these environment's names. 215 | foreach ((array)$hosts as $host) { 216 | if (str_is($host, gethostname())) { 217 | return $this['env'] = $environment; 218 | } 219 | } 220 | } 221 | } elseif (is_string($environments)) { 222 | return $this['env'] = $environments; 223 | } 224 | } 225 | 226 | return $this['env'] = 'production'; 227 | } 228 | 229 | /** 230 | * Get the environment argument from the console. 231 | * 232 | * @param array $args 233 | * 234 | * @return string|null 235 | */ 236 | private function getEnvironmentArgument(array $args): ?string 237 | { 238 | return array_first( 239 | $args, 240 | function ($k, $v) { 241 | return starts_with($v, '--env'); 242 | } 243 | ); 244 | } 245 | 246 | /** 247 | * Get or check the current application environment. 248 | * 249 | * @param string|array $environments 250 | * @return string|bool 251 | */ 252 | public function environment(...$environments) 253 | { 254 | if (count($environments) > 0) { 255 | $patterns = is_array($environments[0]) ? $environments[0] : $environments; 256 | 257 | return Str::is($patterns, $this['env']); 258 | } 259 | return $this['env']; 260 | } 261 | 262 | /** 263 | * Register an application error handler. 264 | * 265 | * @param Closure $callback 266 | * 267 | * @return void 268 | */ 269 | public function error(Closure $callback) 270 | { 271 | $this['exception']->error($callback); 272 | } 273 | 274 | /** 275 | * Get the application namespace. 276 | * 277 | * @return string 278 | * 279 | * @throws \RuntimeException 280 | */ 281 | public function getNamespace() 282 | { 283 | if (!is_null($this->namespace)) { 284 | return $this->namespace; 285 | } 286 | 287 | $composer = json_decode(file_get_contents($this->basePath('composer.json')), true); 288 | 289 | foreach ((array)data_get($composer, 'autoload.psr-4') as $namespace => $path) { 290 | foreach ((array)$path as $pathChoice) { 291 | if (realpath($this->path()) === realpath($this->basePath($pathChoice))) { 292 | return $this->namespace = $namespace; 293 | } 294 | } 295 | } 296 | 297 | throw new RuntimeException('Unable to detect application namespace.'); 298 | } 299 | 300 | public function runningUnitTests(): bool 301 | { 302 | return $this['env'] === 'testing'; 303 | } 304 | 305 | public function isDownForMaintenance() 306 | { 307 | return file_exists($this->storagePath() . '/framework/down'); 308 | } 309 | 310 | public function registerConfiguredProviders() 311 | { 312 | $providers = Collection::make($this->config['app.providers']) 313 | ->partition(function ($provider) { 314 | return strpos($provider, 'Illuminate\\') === 0; 315 | }); 316 | 317 | $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]); 318 | 319 | (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath())) 320 | ->load($providers->collapse()->toArray()); 321 | } 322 | 323 | /** 324 | * Get the path to the cached services.php file. 325 | * 326 | * @return string 327 | */ 328 | public function getCachedServicesPath(): string 329 | { 330 | return $this->normalizeCachePath('APP_SERVICES_CACHE', 'cache/services.php'); 331 | } 332 | 333 | /** 334 | * Normalize a relative or absolute path to a cache file. 335 | * 336 | * @param string $key 337 | * @param string $default 338 | * @return string 339 | */ 340 | protected function normalizeCachePath($key, $default): string 341 | { 342 | if (is_null($env = Env::get($key))) { 343 | return $this->bootstrapPath($default); 344 | } 345 | 346 | return Str::startsWith($env, $this->absoluteCachePathPrefixes) 347 | ? $env 348 | : $this->basePath($env); 349 | } 350 | 351 | public function addDeferredServices(array $services) 352 | { 353 | $this->deferredServices = array_merge($this->deferredServices, $services); 354 | } 355 | 356 | /** 357 | * Boot the application's service providers. 358 | * 359 | * @return void 360 | */ 361 | public function boot() 362 | { 363 | if ($this->isBooted()) { 364 | return; 365 | } 366 | 367 | // Once the application has booted we will also fire some "booted" callbacks 368 | // for any listeners that need to do work after this initial booting gets 369 | // finished. This is useful when ordering the boot-up processes we run. 370 | $this->fireAppCallbacks($this->bootingCallbacks); 371 | 372 | array_walk($this->serviceProviders, function ($p) { 373 | $this->bootProvider($p); 374 | }); 375 | 376 | $this->booted = true; 377 | 378 | $this->fireAppCallbacks($this->bootedCallbacks); 379 | } 380 | 381 | /** 382 | * Determine if the application has booted. 383 | * 384 | * @return bool 385 | */ 386 | public function isBooted(): bool 387 | { 388 | return $this->booted; 389 | } 390 | 391 | /** 392 | * Call the booting callbacks for the application. 393 | * 394 | * @param callable[] $callbacks 395 | * @return void 396 | */ 397 | protected function fireAppCallbacks(array $callbacks) 398 | { 399 | foreach ($callbacks as $callback) { 400 | $callback($this); 401 | } 402 | } 403 | 404 | /** 405 | * Boot the given service provider. 406 | * 407 | * @param \Illuminate\Support\ServiceProvider $provider 408 | * @return void 409 | */ 410 | protected function bootProvider(ServiceProvider $provider) 411 | { 412 | $provider->callBootingCallbacks(); 413 | 414 | if (method_exists($provider, 'boot')) { 415 | $this->call([$provider, 'boot']); 416 | } 417 | 418 | $provider->callBootedCallbacks(); 419 | } 420 | 421 | public function booted($callback) 422 | { 423 | $this->bootedCallbacks[] = $callback; 424 | 425 | if ($this->isBooted()) { 426 | $this->fireAppCallbacks([$callback]); 427 | } 428 | } 429 | 430 | public function bootstrapWith(array $bootstrappers) 431 | { 432 | $this->hasBeenBootstrapped = true; 433 | 434 | foreach ($bootstrappers as $bootstrapper) { 435 | $this['events']->dispatch('bootstrapping: ' . $bootstrapper, [$this]); 436 | 437 | $this->make($bootstrapper)->bootstrap($this); 438 | 439 | $this['events']->dispatch('bootstrapped: ' . $bootstrapper, [$this]); 440 | } 441 | } 442 | 443 | /** 444 | * Get the path to the cached packages.php file. 445 | * 446 | * @return string 447 | */ 448 | public function getCachedPackagesPath() 449 | { 450 | return $this->normalizeCachePath('APP_PACKAGES_CACHE', 'cache/packages.php'); 451 | } 452 | 453 | public function getLocale() 454 | { 455 | return $this['config']->get('app.locale'); 456 | } 457 | 458 | public function hasBeenBootstrapped(): bool 459 | { 460 | return $this->hasBeenBootstrapped; 461 | } 462 | 463 | public function loadDeferredProviders() 464 | { 465 | // We will simply spin through each of the deferred providers and register each 466 | // one and boot them if the application has booted. This should make each of 467 | // the remaining services available to this application for immediate use. 468 | foreach ($this->deferredServices as $service => $provider) { 469 | $this->loadDeferredProvider($service); 470 | } 471 | 472 | $this->deferredServices = []; 473 | } 474 | 475 | public function loadDeferredProvider($service) 476 | { 477 | if (!$this->isDeferredService($service)) { 478 | return; 479 | } 480 | 481 | $provider = $this->deferredServices[$service]; 482 | 483 | // If the service provider has not already been loaded and registered we can 484 | // register it with the application and remove the service from this list 485 | // of deferred services, since it will already be loaded on subsequent. 486 | if (!isset($this->loadedProviders[$provider])) { 487 | $this->registerDeferredProvider($provider, $service); 488 | } 489 | } 490 | 491 | public function isDeferredService($service): bool 492 | { 493 | return isset($this->deferredServices[$service]); 494 | } 495 | 496 | /** 497 | * Register a deferred provider and service. 498 | * 499 | * @param string $provider 500 | * @param string|null $service 501 | * @return void 502 | */ 503 | public function registerDeferredProvider($provider, $service = null) 504 | { 505 | // Once the provider that provides the deferred service has been registered we 506 | // will remove it from our local list of the deferred services with related 507 | // providers so that this container does not try to resolve it out again. 508 | if ($service) { 509 | unset($this->deferredServices[$service]); 510 | } 511 | 512 | $this->register($instance = new $provider($this)); 513 | 514 | if (!$this->isBooted()) { 515 | $this->booting(function () use ($instance) { 516 | $this->bootProvider($instance); 517 | }); 518 | } 519 | } 520 | 521 | /** 522 | * Register a service provider with the application. 523 | * 524 | * @param \Illuminate\Support\ServiceProvider|string $provider 525 | * @param bool $force 526 | * @return \Illuminate\Support\ServiceProvider 527 | */ 528 | public function register($provider, $force = false) 529 | { 530 | if (($registered = $this->getProvider($provider)) && !$force) { 531 | return $registered; 532 | } 533 | 534 | // If the given "provider" is a string, we will resolve it, passing in the 535 | // application instance automatically for the developer. This is simply 536 | // a more convenient way of specifying your service provider classes. 537 | if (is_string($provider)) { 538 | $provider = $this->resolveProvider($provider); 539 | } 540 | 541 | $provider->register(); 542 | 543 | // If there are bindings / singletons set as properties on the provider we 544 | // will spin through them and register them with the application, which 545 | // serves as a convenience layer while registering a lot of bindings. 546 | if (property_exists($provider, 'bindings')) { 547 | foreach ($provider->bindings as $key => $value) { 548 | $this->bind($key, $value); 549 | } 550 | } 551 | 552 | if (property_exists($provider, 'singletons')) { 553 | foreach ($provider->singletons as $key => $value) { 554 | $this->singleton($key, $value); 555 | } 556 | } 557 | 558 | $this->markAsRegistered($provider); 559 | 560 | // If the application has already booted, we will call this boot method on 561 | // the provider class so it has an opportunity to do its boot logic and 562 | // will be ready for any usage by this developer's application logic. 563 | if ($this->isBooted()) { 564 | $this->bootProvider($provider); 565 | } 566 | 567 | return $provider; 568 | } 569 | 570 | public function getProvider($provider) 571 | { 572 | return array_values($this->getProviders($provider))[0] ?? null; 573 | } 574 | 575 | public function getProviders($provider) 576 | { 577 | $name = is_string($provider) ? $provider : get_class($provider); 578 | 579 | return Arr::where($this->serviceProviders, function ($value) use ($name) { 580 | return $value instanceof $name; 581 | }); 582 | } 583 | 584 | /** 585 | * Resolve a service provider instance from the class name. 586 | * 587 | * @param string $provider 588 | * @return \Illuminate\Support\ServiceProvider 589 | */ 590 | public function resolveProvider($provider) 591 | { 592 | return new $provider($this); 593 | } 594 | 595 | protected function markAsRegistered($provider) 596 | { 597 | $this->serviceProviders[] = $provider; 598 | 599 | $this->loadedProviders[get_class($provider)] = true; 600 | } 601 | 602 | public function booting($callback) 603 | { 604 | $this->bootingCallbacks[] = $callback; 605 | } 606 | 607 | public function setLocale($locale) 608 | { 609 | $this['config']->set('app.locale', $locale); 610 | 611 | $this['translator']->setLocale($locale); 612 | //$this['events']->dispatch(new LocaleUpdated($locale)); 613 | } 614 | 615 | public function shouldSkipMiddleware(): bool 616 | { 617 | return $this->bound('middleware.disable') && 618 | $this->make('middleware.disable') === true; 619 | } 620 | 621 | public function terminate() 622 | { 623 | foreach ($this->terminatingCallbacks as $terminating) { 624 | $this->call($terminating); 625 | } 626 | } 627 | } 628 | --------------------------------------------------------------------------------