ubah ke docker mode

This commit is contained in:
servdal
2025-07-16 07:36:13 +07:00
parent 6871d14f94
commit 9471bf22f5
15161 changed files with 112 additions and 0 deletions

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) ARCANEDEV <arcanedev.maroc@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+50
View File
@@ -0,0 +1,50 @@
# Support [![Packagist License][badge_license]](LICENSE.md) [![For Laravel][badge_laravel]][link-github-repo]
[![Github Workflow Status][badge_build]][link-github-status]
[![Coverage Status][badge_coverage]][link-scrutinizer]
[![Scrutinizer Code Quality][badge_quality]][link-scrutinizer]
[![SensioLabs Insight][badge_insight]][link-insight]
[![Github Issues][badge_issues]][link-github-issues]
[![Packagist][badge_package]][link-packagist]
[![Packagist Release][badge_release]][link-packagist]
[![Packagist Downloads][badge_downloads]][link-packagist]
*By [ARCANEDEV&copy;](http://www.arcanedev.net/)*
Support package is a collection of helpers and tools for ARCANEDEV + Laravel projects.
Feel free to check out the [releases](https://github.com/ARCANEDEV/Support/releases), [license](LICENSE.md), and [contribution guidelines](CONTRIBUTING.md).
## Contribution
Any ideas are welcome. Feel free to submit any issues or pull requests, please check the [contribution guidelines](CONTRIBUTING.md).
## Security
If you discover any security related issues, please email arcanedev.maroc@gmail.com instead of using the issue tracker.
## Credits
- [ARCANEDEV][link-author]
- [All Contributors][link-contributors]
[badge_license]: http://img.shields.io/packagist/l/arcanedev/support.svg?style=flat-square
[badge_laravel]: https://img.shields.io/badge/Laravel-5.1%20to%2010.x-orange.svg?style=flat-square
[badge_build]: https://img.shields.io/github/workflow/status/ARCANEDEV/Support/run-tests?style=flat-square
[badge_coverage]: https://img.shields.io/scrutinizer/coverage/g/ARCANEDEV/Support.svg?style=flat-square
[badge_quality]: https://img.shields.io/scrutinizer/g/ARCANEDEV/Support.svg?style=flat-square
[badge_insight]: https://img.shields.io/sensiolabs/i/de0353dd-df17-4656-b9c0-1eea95aa30a2.svg?style=flat-square
[badge_issues]: https://img.shields.io/github/issues/ARCANEDEV/Support.svg?style=flat-square
[badge_package]: https://img.shields.io/badge/package-arcanedev/support-blue.svg?style=flat-square
[badge_release]: https://img.shields.io/packagist/v/arcanedev/support.svg?style=flat-square
[badge_downloads]: https://img.shields.io/packagist/dt/arcanedev/support.svg?style=flat-square
[link-author]: https://github.com/arcanedev-maroc
[link-github-repo]: https://github.com/ARCANEDEV/Support
[link-github-status]: https://github.com/ARCANEDEV/Support/actions
[link-github-issues]: https://github.com/ARCANEDEV/Support/issues
[link-contributors]: https://github.com/ARCANEDEV/Support/graphs/contributors
[link-packagist]: https://packagist.org/packages/arcanedev/support
[link-scrutinizer]: https://scrutinizer-ci.com/g/ARCANEDEV/Support/?branch=master
[link-insight]: https://insight.sensiolabs.com/projects/de0353dd-df17-4656-b9c0-1eea95aa30a2
+51
View File
@@ -0,0 +1,51 @@
{
"name": "arcanedev/support",
"description": "ARCANEDEV Support Helpers",
"keywords": ["arcanedev", "arcanesoft", "support", "laravel"],
"homepage": "https://github.com/ARCANEDEV/Support",
"authors": [
{
"name": "ARCANEDEV",
"email": "[email protected]",
"homepage": "https://github.com/arcanedev-maroc"
}
],
"type": "library",
"license": "MIT",
"require": {
"php": "^8.1",
"illuminate/contracts": "^10.0",
"illuminate/support": "^10.0"
},
"require-dev": {
"laravel/framework": "^10.0",
"orchestra/testbench-core": "^8.0",
"phpunit/phpunit": "^10.0"
},
"autoload": {
"psr-4": {
"Arcanedev\\Support\\": "src/"
},
"files": ["helpers.php"]
},
"autoload-dev": {
"psr-4": {
"Arcanedev\\Support\\Tests\\": "tests/"
}
},
"scripts": {
"test": "phpunit --colors=always",
"test:dox": "phpunit --testdox --colors=always",
"test:cov": "phpunit --coverage-html coverage"
},
"extra": {
"branch-alias": {
"dev-develop": "10.x-dev"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
+43
View File
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
if ( ! function_exists('laravel_version')) {
/**
* Get laravel version or check if the same version
*
* @param string|null $version
*
* @return string|bool
*/
function laravel_version(string $version = null) {
$appVersion = app()->version();
if (is_null($version)) {
return $appVersion;
}
return substr($appVersion, 0, strlen($version)) === $version;
}
}
if ( ! function_exists('route_is')) {
/**
* Check if route(s) is the current route.
*
* @param array|string $routes
*
* @return bool
*/
function route_is($routes): bool
{
if ( ! is_array($routes)) {
$routes = [$routes];
}
/** @var Illuminate\Routing\Router $router */
$router = app('router');
return call_user_func_array([$router, 'is'], $routes);
}
}
+54
View File
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Console;
use Illuminate\Console\Command as IlluminateCommand;
use Symfony\Component\Console\Helper\TableSeparator;
/**
* Class Command
*
* @author ARCANEDEV <[email protected]>
*/
abstract class Command extends IlluminateCommand
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Execute the console command.
*/
abstract public function handle();
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Create table separator
*
* @return \Symfony\Component\Console\Helper\TableSeparator
*/
protected function tableSeparator()
{
return new TableSeparator;
}
/**
* Display frame the text info.
*
* @param string $text
*/
protected function frame(string $text)
{
$line = '+'.str_repeat('-', strlen($text) + 4).'+';
$this->info($line);
$this->info("| $text |");
$this->info($line);
}
}
@@ -0,0 +1,184 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Database;
use Closure;
use Illuminate\Database\Migrations\Migration as IlluminateMigration;
use Illuminate\Database\Schema\Builder;
/**
* Class Migration
*
* @author ARCANEDEV <[email protected]>
*/
abstract class Migration extends IlluminateMigration
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The table name.
*
* @var string|null
*/
protected $table;
/**
* The table prefix.
*
* @var string|null
*/
protected $prefix;
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Get a schema builder instance for the connection.
*
* @return \Illuminate\Database\Schema\Builder
*/
protected function getSchemaBuilder(): Builder
{
/** @var \Illuminate\Database\DatabaseManager $db */
$db = app()->make('db');
return $db->connection($this->hasConnection() ? $this->getConnection() : null)
->getSchemaBuilder();
}
/**
* Set the migration connection name.
*
* @param string $connection
*
* @return $this
*/
public function setConnection($connection)
{
$this->connection = $connection;
return $this;
}
/**
* Get the prefixed table name.
*
* @return string
*/
public function getTableName()
{
return $this->hasPrefix()
? $this->prefix.$this->table
: $this->table;
}
/**
* Set the table name.
*
* @param string $table
*
* @return $this
*/
public function setTable($table)
{
$this->table = $table;
return $this;
}
/**
* Set the prefix name.
*
* @param string $prefix
*
* @return $this
*/
public function setPrefix($prefix)
{
$this->prefix = $prefix;
return $this;
}
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Migrate to database.
*/
abstract public function up(): void;
/**
* Rollback the migration.
*/
public function down(): void
{
$this->getSchemaBuilder()->dropIfExists($this->getTableName());
}
/**
* Create Table Schema.
*
* @param \Closure $blueprint
*/
protected function createSchema(Closure $blueprint): void
{
$this->getSchemaBuilder()->create($this->getTableName(), $blueprint);
}
/**
* Modify a table on the schema.
*
* @param \Closure $callback
*/
protected function table(Closure $callback): void
{
$this->getSchemaBuilder()->table($this->getTableName(), $callback);
}
/* -----------------------------------------------------------------
| Check Methods
| -----------------------------------------------------------------
*/
/**
* Check if connection exists.
*
* @return bool
*/
protected function hasConnection(): bool
{
return $this->isNotEmpty($this->getConnection());
}
/**
* Check if table has prefix.
*
* @return bool
*/
protected function hasPrefix(): bool
{
return $this->isNotEmpty($this->prefix);
}
/**
* Check if the value is not empty.
*
* @param string|null $value
*
* @return bool
*/
private function isNotEmpty($value): bool
{
return ! (is_null($value) || empty($value));
}
}
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Database;
use Illuminate\Database\Eloquent\Model;
/**
* Class PrefixedModel
*
* @author ARCANEDEV <[email protected]>
*/
abstract class PrefixedModel extends Model
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The table prefix.
*
* @var string|null
*/
protected $prefix;
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Get the table associated with the model.
*
* @return string
*/
public function getTable()
{
return $this->getPrefix().parent::getTable();
}
/**
* Get the prefix table associated with the model.
*
* @return string
*/
public function getPrefix(): string
{
return $this->isPrefixed() ? $this->prefix : '';
}
/**
* Set the prefix table associated with the model.
*
* @param string|null $prefix
*
* @return $this
*/
public function setPrefix(?string $prefix)
{
$this->prefix = $prefix;
return $this;
}
/* -----------------------------------------------------------------
| Check Methods
| -----------------------------------------------------------------
*/
/**
* Check if table is prefixed.
*
* @return bool
*/
public function isPrefixed(): bool
{
return ! is_null($this->prefix);
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Database;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Seeder as IlluminateSeeder;
/**
* Class Seeder
*
* @author ARCANEDEV <[email protected]>
*/
abstract class Seeder extends IlluminateSeeder
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* Seeder collection.
*
* @var array
*/
protected $seeds = [];
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Run the database seeds.
*/
public function run(): void
{
Eloquent::unguard();
foreach ($this->seeds as $seed) {
$this->call($seed);
}
Eloquent::reguard();
}
}
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Exceptions;
use Exception;
/**
* Class PackageException
*
* @author ARCANEDEV <[email protected]>
*/
class PackageException extends Exception
{
public static function unspecifiedName(): self
{
return new static('You must specify the vendor/package name.');
}
}
@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Middleware;
use Closure;
use Illuminate\Http\{JsonResponse, Request, Response};
/**
* Class VerifyJsonRequest
*
* @author ARCANEDEV <[email protected]>
*/
class VerifyJsonRequest
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* Supported request method verbs.
*
* @var array
*/
protected $methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|array|null $methods
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $methods = null)
{
if ($this->isJsonRequestValid($request, $methods)) {
return $next($request);
}
return $this->jsonErrorResponse();
}
/* -----------------------------------------------------------------
| Check Methods
| -----------------------------------------------------------------
*/
/**
* Validate json Request.
*
* @param \Illuminate\Http\Request $request
* @param string|array|null $methods
*
* @return bool
*/
protected function isJsonRequestValid(Request $request, $methods)
{
$methods = $this->getMethods($methods);
if ( ! in_array($request->method(), $methods)) {
return false;
}
return $request->isJson();
}
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Get the error as json response.
*
* @return \Illuminate\Http\JsonResponse
*/
protected function jsonErrorResponse()
{
$data = [
'status' => 'error',
'code' => $statusCode = Response::HTTP_BAD_REQUEST,
'message' => 'Request must be JSON',
];
return new JsonResponse($data, $statusCode);
}
/**
* Get request methods.
*
* @param string|array|null $methods
*
* @return array
*/
protected function getMethods($methods): array
{
$methods = $methods ?? $this->methods;
if (is_string($methods)) {
$methods = (array) $methods;
}
return is_array($methods) ? array_map('strtoupper', $methods) : [];
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider;
use Illuminate\Support\Facades\Gate;
/**
* Class AuthorizationServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class AuthorizationServiceProvider extends AuthServiceProvider
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Define policies.
*
* @param string $class
* @param array $policies
*/
protected function defineMany($class, array $policies)
{
foreach ($policies as $ability => $method) {
Gate::define($ability, "$class@$method");
}
}
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
/**
* Class CommandServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class CommandServiceProvider extends ServiceProvider
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The commands to be registered.
*
* @var array
*/
protected $commands = [];
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Boot the service provider.
*/
public function boot()
{
$this->commands($this->commands);
}
/**
* Get the provided commands.
*
* @return array
*/
public function provides()
{
return $this->commands;
}
}
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
/**
* Trait HasAssets
*
* @author ARCANEDEV <[email protected]>
*/
trait HasAssets
{
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Get the assets path.
*
* @return string
*/
protected function getAssetsFolder(): string
{
return realpath($this->getBasePath().DIRECTORY_SEPARATOR.'assets');
}
/**
* Get the assets destination path.
*
* @return string
*/
protected function assetsDestinationPath(): string
{
return base_path('assets'.DIRECTORY_SEPARATOR.$this->getPackageName());
}
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Publish the assets.
*/
protected function publishAssets(): void
{
$this->publishes([
$this->getAssetsFolder() => $this->assetsDestinationPath(),
], $this->getPublishedTags('assets'));
}
}
@@ -0,0 +1,152 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
use Illuminate\Support\Str;
/**
* Trait HasConfig
*
* @author ARCANEDEV <[email protected]>
*/
trait HasConfig
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* Merge multiple config files into one instance (package name as root key)
*
* @var bool
*/
protected $multiConfigs = false;
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Get config folder.
*
* @return string
*/
protected function getConfigFolder(): string
{
return realpath($this->getBasePath().DIRECTORY_SEPARATOR.'config');
}
/**
* Get config key.
*
* @param bool $withVendor
* @param string $separator
*
* @return string
*/
protected function getConfigKey(bool $withVendor = false, string $separator = '.'): string
{
$package = Str::slug($this->getPackageName());
return $withVendor
? Str::slug($this->getVendorName()).$separator.$package
: $package;
}
/**
* Get config file path.
*
* @return string
*/
protected function getConfigFile(): string
{
return $this->getConfigFolder().DIRECTORY_SEPARATOR."{$this->getPackageName()}.php";
}
/**
* Get the config files (paths).
*
* @return array|false
*/
protected function configFilesPaths()
{
return glob($this->getConfigFolder().DIRECTORY_SEPARATOR.'*.php');
}
/**
* Register configs.
*
* @param string $separator
*/
protected function registerConfig(string $separator = '.'): void
{
$this->multiConfigs
? $this->registerMultipleConfigs($separator)
: $this->registerSingleConfig();
}
/**
* Register a single config file.
*/
protected function registerSingleConfig(): void
{
$this->mergeConfigFrom($this->getConfigFile(), $this->getConfigKey());
}
/**
* Register all package configs.
*
* @param string $separator
*/
protected function registerMultipleConfigs(string $separator = '.'): void
{
foreach ($this->configFilesPaths() as $path) {
$key = $this->getConfigKey(true, $separator).$separator.basename($path, '.php');
$this->mergeConfigFrom($path, $key);
}
}
/**
* Publish the config file.
*
* @param string|null $path
*/
protected function publishConfig(?string $path = null): void
{
$this->multiConfigs
? $this->publishMultipleConfigs()
: $this->publishSingleConfig($path);
}
/**
* Publish a single config file.
*
* @param string|null $path
*/
protected function publishSingleConfig(?string $path = null): void
{
$this->publishes([
$this->getConfigFile() => $path ?: config_path("{$this->getPackageName()}.php"),
], $this->getPublishedTags('config'));
}
/**
* Publish multiple config files.
*/
protected function publishMultipleConfigs(): void
{
$paths = [];
$package = $this->getConfigKey(true, DIRECTORY_SEPARATOR);
foreach ($this->configFilesPaths() as $file) {
$paths[$file] = config_path($package.DIRECTORY_SEPARATOR.basename($file));
}
$this->publishes($paths, $this->getPublishedTags('config'));
}
}
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
/**
* Trait HasFactories
*
* @author ARCANEDEV <[email protected]>
*/
trait HasFactories
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Get the migrations path.
*
* @return string
*/
protected function getFactoriesPath(): string
{
return $this->getBasePath().DIRECTORY_SEPARATOR.'database'.DIRECTORY_SEPARATOR.'factories';
}
/**
* Publish the factories.
*
* @param string|null $path
*/
protected function publishFactories(?string $path = null): void
{
$this->publishes([
$this->getFactoriesPath() => $path ?: database_path('factories'),
], $this->getPublishedTags('factories'));
}
/**
* Load the factories.
*/
protected function loadFactories(): void
{
$this->loadFactoriesFrom($this->getFactoriesPath());
}
}
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
/**
* Trait HasMigrations
*
* @author ARCANEDEV <[email protected]>
*/
trait HasMigrations
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Get the migrations path.
*
* @return string
*/
protected function getMigrationsPath(): string
{
return $this->getBasePath().DIRECTORY_SEPARATOR.'database'.DIRECTORY_SEPARATOR.'migrations';
}
/**
* Publish the migration files.
*
* @param string|null $path
*/
protected function publishMigrations(?string $path = null): void
{
$this->publishes([
$this->getMigrationsPath() => $path ?: database_path('migrations')
], $this->getPublishedTags('migrations'));
}
/**
* Load the migrations files.
*/
protected function loadMigrations(): void
{
$this->loadMigrationsFrom($this->getMigrationsPath());
}
}
@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
/**
* Trait HasTranslations
*
* @author ARCANEDEV <[email protected]>
*/
trait HasTranslations
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Get the translations' folder name.
*/
protected function getTranslationsFolderName(): string
{
return 'translations';
}
/**
* Get the translations' path.
*/
protected function getTranslationsPath(): string
{
return $this->getBasePath().DIRECTORY_SEPARATOR.$this->getTranslationsFolderName();
}
/**
* Get the destination views path.
*/
protected function getTranslationsDestinationPath(): string
{
return $this->app->langPath(
'vendor'.DIRECTORY_SEPARATOR.$this->getPackageName()
);
}
/**
* Publish the translations.
*/
protected function publishTranslations(?string $path = null): void
{
$this->publishes([
$this->getTranslationsPath() => $path ?: $this->getTranslationsDestinationPath(),
], $this->getPublishedTags('translations'));
}
/**
* Load the translations files.
*/
protected function loadTranslations(): void
{
$packagePath = $this->getTranslationsPath();
$vendorPath = $this->getTranslationsDestinationPath();
$this->loadTranslationsFrom($packagePath, $this->getPackageName());
$this->loadJsonTranslationsFrom(file_exists($vendorPath) ? $vendorPath : $packagePath);
}
}
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
/**
* Trait HasViews
*
* @author ARCANEDEV <[email protected]>
*/
trait HasViews
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Get the base views path.
*
* @return string
*/
protected function getViewsPath(): string
{
return $this->getBasePath().DIRECTORY_SEPARATOR.'views';
}
/**
* Get the destination views path.
*
* @return string
*/
protected function getViewsDestinationPath(): string
{
return $this->app['config']['view.paths'][0].DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.$this->getPackageName();
}
/**
* Publish the views.
*
* @param string|null $path
*/
protected function publishViews(?string $path = null): void
{
$this->publishes([
$this->getViewsPath() => $path ?: $this->getViewsDestinationPath(),
], $this->getPublishedTags('views'));
}
/**
* Load the views files.
*/
protected function loadViews(): void
{
$this->loadViewsFrom($this->getViewsPath(), $this->getPackageName());
}
}
@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers\Concerns;
/**
* Trait InteractsWithApplication
*
* @author ARCANEDEV <[email protected]>
*/
trait InteractsWithApplication
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Register multiple service providers.
*
* @param array $providers
*/
protected function registerProviders(array $providers)
{
foreach ($providers as $provider) {
$this->registerProvider($provider);
}
}
/**
* Register a service provider.
*
* @param \Illuminate\Support\ServiceProvider|string $provider
* @param bool $force
*
* @return \Illuminate\Support\ServiceProvider
*/
protected function registerProvider($provider, $force = false)
{
return $this->app->register($provider, $force);
}
/**
* Register a console service provider.
*
* @param \Illuminate\Support\ServiceProvider|string $provider
* @param bool $force
*
* @return \Illuminate\Support\ServiceProvider|null
*/
protected function registerConsoleServiceProvider($provider, $force = false)
{
if ($this->app->runningInConsole()) {
return $this->registerProvider($provider, $force);
}
return null;
}
/**
* Register the package's custom Artisan commands when running in console.
*
* @param array $commands
*/
protected function registerCommands(array $commands)
{
if ($this->app->runningInConsole()) {
$this->commands($commands);
}
}
/**
* Register a binding with the container.
*
* @param string $abstract
* @param \Closure|string|null $concrete
* @param bool $shared
*/
protected function bind($abstract, $concrete = null, $shared = false)
{
$this->app->bind($abstract, $concrete, $shared);
}
/**
* Register a shared binding in the container.
*
* @param string|array $abstract
* @param \Closure|string|null $concrete
*/
protected function singleton($abstract, $concrete = null)
{
$this->app->singleton($abstract, $concrete);
}
}
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
use Illuminate\Support\Facades\Event;
/**
* Class EventServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class EventServiceProvider extends ServiceProvider
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The event handler mappings for the application.
*
* @var array
*/
protected $listen = [];
/**
* The subscriber classes to register.
*
* @var array
*/
protected $subscribe = [];
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Get the events and handlers.
*
* @return array
*/
public function listens()
{
return $this->listen;
}
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Register the application's event listeners.
*/
public function boot()
{
foreach ($this->listens() as $event => $listeners) {
foreach ($listeners as $listener) {
Event::listen($event, $listener);
}
}
foreach ($this->subscribe as $subscriber) {
Event::subscribe($subscriber);
}
}
/**
* {@inheritdoc}
*/
public function register()
{
//
}
}
@@ -0,0 +1,194 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
use Arcanedev\Support\Exceptions\PackageException;
use Arcanedev\Support\Providers\Concerns\{
HasAssets, HasConfig, HasFactories, HasMigrations, HasTranslations, HasViews
};
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
use ReflectionClass;
/**
* Class PackageServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class PackageServiceProvider extends ServiceProvider
{
/* -----------------------------------------------------------------
| Traits
| -----------------------------------------------------------------
*/
use HasAssets,
HasConfig,
HasFactories,
HasMigrations,
HasTranslations,
HasViews;
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* Vendor name.
*
* @var string
*/
protected $vendor = 'arcanedev';
/**
* Package name.
*
* @var string|null
*/
protected $package;
/**
* Package base path.
*
* @var string
*/
protected $basePath;
/* -----------------------------------------------------------------
| Constructor
| -----------------------------------------------------------------
*/
/**
* Create a new service provider instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
*/
public function __construct(Application $app)
{
parent::__construct($app);
$this->basePath = $this->resolveBasePath();
}
/**
* Resolve the base path of the package.
*
* @return string
*/
protected function resolveBasePath()
{
return dirname(
(new ReflectionClass($this))->getFileName(), 2
);
}
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Get the base path of the package.
*
* @return string
*/
public function getBasePath()
{
return $this->basePath;
}
/**
* Get the vendor name.
*
* @return string
*/
protected function getVendorName(): string
{
return $this->vendor;
}
/**
* Get the package name.
*
* @return string|null
*/
protected function getPackageName(): ?string
{
return $this->package;
}
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Register the service provider.
*/
public function register()
{
parent::register();
$this->checkPackageName();
}
/* -----------------------------------------------------------------
| Package Methods
| -----------------------------------------------------------------
*/
/**
* Publish all the package files.
*/
protected function publishAll(): void
{
$this->publishAssets();
$this->publishConfig();
$this->publishFactories();
$this->publishMigrations();
$this->publishTranslations();
$this->publishViews();
}
/* -----------------------------------------------------------------
| Check Methods
| -----------------------------------------------------------------
*/
/**
* Check package name.
*
* @throws \Arcanedev\Support\Exceptions\PackageException
*/
protected function checkPackageName(): void
{
if (empty($this->getVendorName()) || empty($this->getPackageName())) {
throw PackageException::unspecifiedName();
}
}
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Get the published tags.
*
* @param string $tag
*
* @return array
*/
protected function getPublishedTags(string $tag): array
{
$package = $this->getPackageName();
return array_map(function ($name) {
return Str::slug($name);
}, [$this->getVendorName(), $package, $tag, $package.'-'.$tag]);
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
use Arcanedev\Support\Routing\Concerns\RegistersRouteClasses;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as IlluminateServiceProvider;
/**
* Class RouteServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class RouteServiceProvider extends IlluminateServiceProvider
{
/* -----------------------------------------------------------------
| Traits
| -----------------------------------------------------------------
*/
use RegistersRouteClasses;
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
use Arcanedev\Support\Providers\Concerns\InteractsWithApplication;
use Illuminate\Support\ServiceProvider as IlluminateServiceProvider;
/**
* Class ServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class ServiceProvider extends IlluminateServiceProvider
{
/* -----------------------------------------------------------------
| Traits
| -----------------------------------------------------------------
*/
use InteractsWithApplication;
}
@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Providers;
use Illuminate\Contracts\View\Factory as ViewFactory;
/**
* Class ViewComposerServiceProvider
*
* @author ARCANEDEV <[email protected]>
*/
abstract class ViewComposerServiceProvider extends ServiceProvider
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* Register the composer classes.
*
* @var array
*/
protected $composerClasses = [
// 'view-name' => 'class'
];
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Boot the view composer service provider.
*/
public function boot()
{
$this->registerComposerClasses();
}
/**
* Register the view composer classes.
*/
protected function registerComposerClasses()
{
foreach ($this->composerClasses as $view => $class) {
$this->composer($view, $class);
}
}
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Get the view factory instance.
*
* @return \Illuminate\Contracts\View\Factory
*/
protected function view()
{
return $this->app->make(ViewFactory::class);
}
/**
* Register a view composer event.
*
* @param array|string $views
* @param \Closure|string $callback
*
* @return array
*/
public function composer($views, $callback)
{
return $this->view()->composer($views, $callback);
}
}
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Routing\Concerns;
/**
* Trait RegistersRouteClasses
*
* @author ARCANEDEV <[email protected]>
*/
trait RegistersRouteClasses
{
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Map route classes.
*
* @param iterable $routes
*/
protected static function mapRouteClasses(iterable $routes): void
{
foreach ($routes as $route) {
if (method_exists($route, 'map')) {
app()->call("{$route}@map");
}
}
}
/**
* Bind route classes.
*
* @param iterable $routes
*/
protected static function bindRouteClasses(iterable $routes): void
{
foreach ($routes as $route) {
if (method_exists($route, 'bindings')) {
app()->call("{$route}@bindings");
}
}
}
}
@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Routing;
use Arcanedev\Support\Routing\Concerns\RegistersRouteClasses;
use Illuminate\Contracts\Routing\Registrar;
use Illuminate\Routing\Router;
use Illuminate\Support\Traits\ForwardsCalls;
/**
* Class RouteRegistrar
*
* @author ARCANEDEV <[email protected]>
*
* @method \Illuminate\Routing\RouteRegistrar bind(string $key, \Closure $binder)
* @method void map()
* @method void bindings()
*
* @mixin \Illuminate\Routing\RouteRegistrar
*/
abstract class RouteRegistrar
{
/* -----------------------------------------------------------------
| Traits
| -----------------------------------------------------------------
*/
use RegistersRouteClasses,
ForwardsCalls;
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Pass dynamic methods onto the router instance.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->forwardCallToRouter(
app(Router::class), $method, $parameters
);
}
/**
* Pass dynamic methods onto the router instance.
*
* @param \Illuminate\Contracts\Routing\Registrar $router
* @param string $method
* @param array $parameters
*
* @return mixed
*/
protected function forwardCallToRouter(Registrar $router, $method, $parameters)
{
return $this->forwardCallTo($router, $method, $parameters);
}
}
+241
View File
@@ -0,0 +1,241 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support;
/**
* Class Stub
*
* @author ARCANEDEV <[email protected]>
*/
class Stub
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The stub path.
*
* @var string
*/
protected $path;
/**
* The base path of stub file.
*
* @var string|null
*/
protected static $basePath = null;
/**
* The replacements array.
*
* @var array
*/
protected $replaces = [];
/* -----------------------------------------------------------------
| Constructor
| -----------------------------------------------------------------
*/
/**
* Create a new instance.
*
* @param string $path
* @param array $replaces
*/
public function __construct($path, array $replaces = [])
{
$this->setPath($path);
$this->setReplaces($replaces);
}
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Get stub path.
*
* @return string
*/
public function getPath(): string
{
$path = $this->path;
if ( ! empty(static::$basePath)) {
$path = static::$basePath.DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR);
}
return $path;
}
/**
* Set stub path.
*
* @param string $path
*
* @return $this
*/
public function setPath(string $path): self
{
$this->path = $path;
return $this;
}
/**
* Get base path.
*
* @return string|null
*/
public static function getBasePath(): ?string
{
return static::$basePath;
}
/**
* Set base path.
*
* @param string $path
*/
public static function setBasePath(string $path)
{
static::$basePath = $path;
}
/**
* Get replacements.
*
* @return array
*/
public function getReplaces(): array
{
return $this->replaces;
}
/**
* Set replacements array.
*
* @param array $replaces
*
* @return $this
*/
public function setReplaces(array $replaces = []): self
{
$this->replaces = $replaces;
return $this;
}
/**
* Set replacements array.
*
* @param array $replaces
*
* @return $this
*/
public function replaces(array $replaces = []): self
{
return $this->setReplaces($replaces);
}
/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
*/
/**
* Create new self instance.
*
* @param string $path
* @param array $replaces
*
* @return $this
*/
public static function create(string $path, array $replaces = []): self
{
return new static($path, $replaces);
}
/**
* Create new self instance from full path.
*
* @param string $path
* @param array $replaces
*
* @return $this
*/
public static function createFromPath(string $path, array $replaces = []): self
{
return tap(new static($path, $replaces), function (self $stub) {
$stub->setBasePath('');
});
}
/**
* Get stub contents.
*
* @return string
*/
public function render(): string
{
return $this->getContents();
}
/**
* Save stub to base path.
*
* @param string $filename
*
* @return bool
*/
public function save(string $filename): bool
{
return $this->saveTo(self::getBasePath(), $filename);
}
/**
* Save stub to specific path.
*
* @param string $path
* @param string $filename
*
* @return bool
*/
public function saveTo(string $path, string $filename): bool
{
return file_put_contents($path.DIRECTORY_SEPARATOR.$filename, $this->render()) !== false;
}
/**
* Get stub contents.
*
* @return string|mixed
*/
public function getContents()
{
$contents = file_get_contents($this->getPath());
foreach ($this->getReplaces() as $search => $replace) {
$contents = str_replace('$'.strtoupper($search).'$', $replace, $contents);
}
return $contents;
}
/**
* Handle magic method __toString.
*
* @return string
*/
public function __toString(): string
{
return $this->render();
}
}
+75
View File
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
namespace Arcanedev\Support\Validation;
use Illuminate\Contracts\Validation\Rule as RuleContract;
/**
* Class Rule
*
* @author ARCANEDEV <[email protected]>
*/
abstract class Rule implements RuleContract
{
/* -----------------------------------------------------------------
| Properties
| -----------------------------------------------------------------
*/
/**
* The message that should be used when validation fails.
*
* @var string|array
*/
protected $message;
/* -----------------------------------------------------------------
| Getters & Setters
| -----------------------------------------------------------------
*/
/**
* Set the message that should be used when the rule fails.
*
* @param string|array $message
*
* @return $this
*/
public function withMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get the validation error message.
*
* @return string|array
*/
public function message()
{
return $this->message;
}
/* -----------------------------------------------------------------
| Other Methods
| -----------------------------------------------------------------
*/
/**
* Fail if the validation rule.
*
* @param string|array $message
*
* @return bool
*/
protected function fail($message): bool
{
$this->withMessage($message);
return false;
}
}