| Server IP : 172.67.71.254 / Your IP : 216.73.216.4 Web Server : nginx/1.27.1 System : Linux in-5 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64 User : arabianexpress ( 1872) PHP Version : 8.0.30 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /storage/v9321/leapdubai/public_html/wp-content/plugins/kirki/libraries/framework/ |
Upload File : |
<?php
/**
* Central application kernel that extends the service container and orchestrates plugin bootstrap.
* Resolves framework paths, registers core and app-defined service providers,
* and manages the boot lifecycle with before/after callbacks.
* Acts as the single entry point for binding services, aliases, and application configuration.
*
* @package Framework
*
* @since 1.0.0
*/
namespace Kirki\Framework;
\defined('ABSPATH') || exit;
use Kirki\Framework\Container;
use Kirki\Framework\Contracts\Request as RequestContract;
use Kirki\Framework\Console\CommandManager;
use Kirki\Framework\Console\Commands\FreshCommand;
use Kirki\Framework\Console\Commands\MakeClassCommand;
use Kirki\Framework\Console\Commands\MakeControllerCommand;
use Kirki\Framework\Console\Commands\MakeMigrationCommand;
use Kirki\Framework\Console\Commands\MakeModelCommand;
use Kirki\Framework\Console\Commands\MakeProviderCommand;
use Kirki\Framework\Console\Commands\MakeRequestCommand;
use Kirki\Framework\Console\Commands\MakeSeederCommand;
use Kirki\Framework\Console\Commands\MigrateCommand;
use Kirki\Framework\Console\Commands\SeedCommand;
use Kirki\Framework\Database\Connection\DatabaseManager;
use Kirki\Framework\Database\Schema\SchemaManager;
use Kirki\Framework\Managers\EventManager;
use Kirki\Framework\Managers\LogManager;
use Kirki\Framework\Managers\OptionManager;
use Kirki\Framework\Managers\PolicyManager;
use Kirki\Framework\ServiceProvider;
use Kirki\Framework\Filesystem\FileSystemServiceProvider;
use Kirki\Framework\Http\Request;
use Kirki\Framework\Managers\DateManager;
use Kirki\Framework\Filesystem\Path;
use Kirki\Framework\Http\Client\Request as ClientRequest;
use Kirki\Framework\CoreServiceProvider;
use Kirki\Framework\Wordpress\HookServiceProvider;
use Kirki\Framework\Supports\Facades\Command;
use Kirki\Framework\Supports\Facades\File;
use Kirki\Framework\Supports\Str;
use Kirki\Framework\Supports\Traits\Macroable;
use Exception;
use Kirki\Framework\Supports\Arr;
use InvalidArgumentException;
use RuntimeException;
class Application extends Container
{
use Macroable;
/**
* Base path
*
* @var string|null
*
* @since 1.0.0
*/
protected $base_path;
/**
* Bootstrap path
*
* @var string|null
*
* @since 1.0.0
*/
protected $bootstrap_path;
/**
* Config path
*
* @var string|null
*
* @since 1.0.0
*/
protected $config_path;
/**
* App path
*
* @var string|null
*
* @since 1.0.0
*/
protected $app_path;
/**
* Database path
*
* @var string|null
*
* @since 1.0.0
*/
protected $database_path;
/**
* Resources path
*
* @var string|null
*
* @since 1.0.0
*/
protected $resource_path;
/**
* Service providers
*
* @var array<string, ServiceProvider>
*
* @since 1.0.0
*/
protected $service_providers = [];
/**
* Mark the application booted or not
*
* @var bool
*
* @since 1.0.0
*/
protected bool $booted = \false;
/**
* Booting callbacks
*
* @var array<callable>
*
* @since 1.0.0
*/
protected array $booting_callbacks = [];
/**
* Booted callbacks
*
* @var array<callable>
*
* @since 1.0.0
*/
protected array $booted_callbacks = [];
/**
* The application namespace
*
* @var string
*
* @since 1.0.0
*/
protected string $namespace = '';
/**
* Cached namespaces resolved from composer PSR-4 paths.
*
* @var array<string, string>
*
* @since 1.0.0
*/
protected $namespace_paths = [];
/**
* The application prefix
*
* @var string
*
* @since 1.0.0
*/
protected string $prefix = '';
/**
* The application is in development mode
*
* @var string
*
* @since 1.0.0
*/
protected string $mode = 'production';
/**
* Create a new application instance
*
* @param string|null $base_path The base path of the application.
*
* @return void
*
* @since 1.0.0
*/
public function __construct(?string $base_path = null)
{
if ($base_path) {
$this->set_base_path($base_path);
}
$this->register_base_bindings();
$this->register_base_service_providers();
$this->register_base_aliases();
// $this->register_app_defined_providers();
// $this->register_app_defined_aliases();
}
/**
* Set the base path
*
* @param string $path The base path of the application.
*
* @return static
*
* @since 1.0.0
*/
public function set_base_path(string $path)
{
$this->base_path = \rtrim($path, '\\/');
$this->bind_inferred_paths();
return $this;
}
/**
* Binding the inferred paths
*
* @return void
*
* @since 1.0.0
*/
protected function bind_inferred_paths()
{
$this->instance('path', $this->path());
$this->instance('path.base', $this->base_path());
$this->instance('path.bootstrap', $this->bootstrap_path());
$this->instance('path.config', $this->config_path());
$this->instance('path.database', $this->database_path());
$this->instance('path.resource', $this->resource_path());
}
/**
* Registering the core bindings to the application container.
*
* @return void
*
* @since 1.0.0
*/
protected function register_base_bindings()
{
$this->instance('app', $this);
$this->instance(Container::class, $this);
}
/**
* Registering the core service providers to the application container.
*
* @return void
*
* @since 1.0.0
*/
protected function register_base_service_providers()
{
$this->register(new FileSystemServiceProvider($this));
$this->register(new CoreServiceProvider($this));
$this->register(new HookServiceProvider($this));
}
/**
* Registering the core CLI commands.
*
* @return void
*
* @since 1.0.0
*/
protected function register_base_cli_commands()
{
$commands = ['make:migration' => MakeMigrationCommand::class, 'migrate' => MigrateCommand::class, 'make:model' => MakeModelCommand::class, 'make:controller' => MakeControllerCommand::class, 'make:request' => MakeRequestCommand::class, 'make:seeder' => MakeSeederCommand::class, 'db:seed' => SeedCommand::class, 'migrate:fresh' => FreshCommand::class, 'make:provider' => MakeProviderCommand::class, 'make:class' => MakeClassCommand::class];
foreach ($commands as $command => $class) {
Command::register($command, $class);
}
}
/**
* Registering the core aliases for future use.
*
* @return void
*
* @since 1.0.0
*/
protected function register_base_aliases()
{
foreach (['db' => DatabaseManager::class, 'schema' => SchemaManager::class, 'option' => OptionManager::class, 'policy' => PolicyManager::class, 'event' => EventManager::class, 'log' => LogManager::class, 'date' => DateManager::class, 'client-request' => ClientRequest::class, 'command' => CommandManager::class, RequestContract::class => Request::class, 'request' => Request::class] as $key => $abstract) {
$this->alias($key, $abstract);
}
}
/**
* Register a service provider to the application.
*
* @param ServiceProvider|string $provider The service provider class name or instance.
*
* @return ServiceProvider
*
* @since 1.0.0
*/
public function register($provider)
{
$registered = $this->get_provider($provider);
if ($registered) {
return $registered;
}
if (\is_string($provider)) {
$provider = $this->resolve_provider($provider);
}
$provider->register();
$this->mark_as_registered($provider);
if ($this->is_booted()) {
$this->boot_provider($provider);
}
return $provider;
}
/**
* Get the registered service provider.
*
* @param ServiceProvider|string $provider The service provider to get.
*
* @return ServiceProvider|null
*
* @since 1.0.0
*/
protected function get_provider($provider)
{
$name = \is_string($provider) ? $provider : \get_class($provider);
return $this->service_providers[$name] ?? null;
}
/**
* Resolve service provider from provider class name.
*
* @param string $provider The service provider class name.
*
* @return ServiceProvider
*
* @since 1.0.0
*/
protected function resolve_provider(string $provider)
{
return new $provider($this);
}
/**
* Mark the service provider as registered.
*
* @param ServiceProvider $provider The service provider to mark as registered.
*
* @return void
*
* @since 1.0.0
*/
protected function mark_as_registered(ServiceProvider $provider)
{
$class = \get_class($provider);
$this->service_providers[$class] = $provider;
}
/**
* Boot the service provider.
*
* @param ServiceProvider $provider The service provider to boot.
*
* @return void
*
* @since 1.0.0
*/
protected function boot_provider(ServiceProvider $provider)
{
if (\method_exists($provider, 'boot')) {
$provider->boot();
}
}
/**
* Check if the application is booted or not.
*
* @return bool
*
* @since 1.0.0
*/
public function is_booted()
{
return $this->booted;
}
/**
* Configure the application.
*
* @param string $base_path The base path of the application.
*
* @return static
*
* @since 1.0.0
*/
public static function configure(string $base_path)
{
$instance = static::get_instance($base_path);
$instance->register_app_defined_providers()->register_app_defined_aliases();
return $instance;
}
/**
* Register a route file.
*
* @param string $path The route file path.
*
* @return self
*
* @throws \Exception
*
* @since 1.0.0
*/
public function use_routing(string $path)
{
if (!\file_exists($path)) {
throw new Exception("Route file not found: {$path}");
}
include $path;
return $this;
}
/**
* Use a prefix for the application.
*
* @param string $prefix The prefix to use.
*
* @return self
*
* @since 1.0.0
*/
public function use_prefix(string $prefix)
{
$this->prefix = Str::snake($prefix);
return $this;
}
/**
* Get the application prefix.
*
* @return string
*
* @since 1.0.0
*/
public function prefix()
{
return $this->prefix;
}
/**
* Register a bootstrap path.
*
* @param string $path The bootstrap path.
*
* @return static
*
* @since 1.0.0
*/
public function use_bootstrap_path($path)
{
$this->bootstrap_path = $path;
$this->instance('path.bootstrap', $path);
return $this;
}
/**
* Register a config path.
*
* @param string $path The config path.
*
* @return static
*
* @since 1.0.0
*/
public function use_config_path($path)
{
$this->config_path = $path;
$this->instance('path.config', $path);
return $this;
}
/**
* Register an app path.
*
* @param string $path The app path.
*
* @return static
*
* @since 1.0.0
*/
public function use_app_path(string $path)
{
$this->app_path = $path;
$this->instance('path', $path);
return $this;
}
/**
* Register a database path.
*
* @param string $path The database path.
*
* @return static
*
* @since 1.0.0
*/
public function use_database_path($path)
{
$this->database_path = $path;
$this->instance('path.database', $path);
return $this;
}
/**
* Register a resource path.
*
* @param string $path The resource path.
*
* @return static
*
* @since 1.0.0
*/
public function use_resource_path($path)
{
$this->resource_path = $path;
$this->instance('path.resource', $path);
return $this;
}
/**
* Join paths.
*
* @param string $base_path The base path to join.
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
protected function join_paths($base_path, $path)
{
return Path::join($base_path, $path);
}
/**
* Get the path to the app directory.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function path($path = '')
{
return $this->join_paths($this->app_path ?: $this->base_path('app'), $path);
}
/**
* Get the path to the base directory.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function base_path($path = '')
{
return $this->join_paths($this->base_path, $path);
}
/**
* Get the path to the bootstrap directory.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function bootstrap_path($path = '')
{
return $this->join_paths($this->bootstrap_path ?: $this->base_path('bootstrap'), $path);
}
/**
* Get the path to the config directory.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function config_path($path = '')
{
return $this->join_paths($this->config_path ?: $this->base_path('config'), $path);
}
/**
* Get the path to the database directory.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function database_path($path = '')
{
return $this->join_paths($this->database_path ?: $this->base_path('database'), $path);
}
/**
* Get the path to the resources directory.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function resource_path($path = '')
{
return $this->join_paths($this->resource_path ?: $this->base_path('resources'), $path);
}
/**
* Get the path to the bootstrap providers file.
*
* @return string The path to the bootstrap providers file.
*
* @since 1.0.0
*/
public function bootstrap_service_provider_path()
{
return $this->bootstrap_path('providers.php');
}
/**
* Get the base URL of the application.
*
* @param string $path The path to join.
*
* @return string
*
* @since 1.0.0
*/
public function base_url($path = '')
{
$base_path = $this->base_path();
$last_segment = \basename($base_path);
$site_base_path = 'wp-content/plugins/' . $last_segment;
return site_url($site_base_path . $path);
}
/**
* Check if the CLI is available or not.
*
* @return bool
*
* @since 1.0.0
*/
public function is_cli_available()
{
return \defined('WP_CLI') && WP_CLI;
}
/**
* Register a booting callback.
*
* @param callable $callback The callback to register.
*
* @return void
*
* @since 1.0.0
*/
public function booting($callback)
{
$this->booting_callbacks[] = $callback;
}
/**
* Boot the plugin application.
*
* @return void
*
* @since 1.0.0
*/
public function boot()
{
if ($this->is_booted()) {
return;
}
$this->fire_app_callbacks($this->booting_callbacks);
\array_walk($this->service_providers, function ($provider) {
$this->boot_provider($provider);
});
$this->booted = \true;
$this->fire_app_callbacks($this->booted_callbacks);
// After booting the application, register the core CLI commands.
if ($this->is_cli_available()) {
$this->register_base_cli_commands();
}
}
/**
* Register a booted callback.
*
* @param callable $callback The callback to register.
*
* @return void
*
* @since 1.0.0
*/
public function booted($callback)
{
$this->booted_callbacks[] = $callback;
if ($this->is_booted()) {
$callback($this);
}
}
/**
* Fire the booting callbacks.
*
* @param array<callable> $callbacks The callbacks to fire.
*
* @return void
*
* @since 1.0.0
*/
protected function fire_app_callbacks(array $callbacks)
{
foreach ($callbacks as $callback) {
$callback($this);
}
}
/**
* Register other on demand provided providers.
*
* @return $this
*
* @throws \InvalidArgumentException
*
* @since 1.0.0
*/
protected function register_app_defined_providers()
{
$path = $this->bootstrap_service_provider_path();
if (!\file_exists($path)) {
return $this;
}
$providers = (require $path);
if (empty($providers)) {
return $this;
}
foreach ($providers as $provider) {
if (!\class_exists($provider) || !\is_subclass_of($provider, ServiceProvider::class)) {
throw new InvalidArgumentException(\sprintf('Class %s must be a subclass of %s.', $provider, ServiceProvider::class));
}
$this->register(new $provider($this));
}
return $this;
}
/**
* Register tha aliases defined at the application level.
* Generally it will come from the bootstrap/aliases.php file.
*
* @return $this
*
* @since 1.0.0
*/
protected function register_app_defined_aliases()
{
$aliases_path = $this->bootstrap_path('aliases.php');
if (!\file_exists($aliases_path)) {
return $this;
}
$aliases = (require $aliases_path);
if (empty($aliases)) {
return $this;
}
foreach ($aliases as $alias => $abstracts) {
foreach ($abstracts as $abstract) {
$this->alias($alias, $abstract);
}
}
return $this;
}
/**
* Get the application namespace.
*
* @return string
*
* @since 1.0.0
*/
public function get_namespace()
{
if (!empty($this->namespace)) {
return $this->namespace;
}
return $this->namespace = $this->parse_namespace_from_composer();
}
/**
* Parse the namespace from the composer.json file.
*
* @return string
*
* @since 1.0.0
*/
protected function parse_namespace_from_composer()
{
return $this->namespace = $this->get_namespace_for_path('app');
}
/**
* Qualify a namespace under the application PSR-4 root.
*
* @param string $suffix The suffix to qualify.
*
* @return string
*
* @since 1.0.0
*/
public function qualify_app_namespace($suffix = '')
{
$namespace = \rtrim($this->get_namespace(), '\\');
if ($suffix === '') {
return $namespace;
}
$suffix = \str_replace('/', '\\', $suffix);
return $namespace . '\\' . \ltrim($suffix, '\\');
}
/**
* Get the migrations namespace from the host composer.json PSR-4 map.
*
* @return string
*
* @since 1.0.0
*/
public function get_migrations_namespace()
{
return \rtrim($this->get_namespace_for_path('database/migrations'), '\\');
}
/**
* Get the seeders namespace from composer or derive it from migrations.
*
* @return string
*
* @since 1.0.0
*/
public function get_seeders_namespace()
{
try {
return \rtrim($this->get_namespace_for_path('database/seeders'), '\\');
} catch (RuntimeException $exception) {
return \preg_replace('/\\Migrations\\?$/', '\\Seeders', \rtrim($this->get_migrations_namespace(), '\\'));
}
}
/**
* Resolve a PSR-4 namespace for a path relative to the application base.
*
* @param string $relative_path The relative path to the namespace.
*
* @return string
*
* @throws \RuntimeException
*
* @since 1.0.0
*/
public function get_namespace_for_path($relative_path)
{
if (isset($this->namespace_paths[$relative_path])) {
return $this->namespace_paths[$relative_path];
}
$composer = File::json($this->base_path('composer.json'));
if (empty($composer['autoload']['psr-4'])) {
throw new RuntimeException('The composer must have a PSR-4 autoload configuration.');
}
$resolved_path = $this->base_path($relative_path);
$target = \realpath($resolved_path);
if ($target === \false) {
File::make_dir($this->base_path($relative_path));
$target = \realpath($resolved_path);
}
foreach ($composer['autoload']['psr-4'] as $namespace => $paths) {
$paths = Arr::wrap($paths);
foreach ($paths as $path) {
$resolved = \realpath($this->base_path($path));
if ($resolved !== \false && $resolved === $target) {
return $this->namespace_paths[$relative_path] = $namespace;
}
}
}
throw new RuntimeException(\sprintf('Unable to detect namespace for path [%s].', $relative_path));
}
/**
* Set the application mode.
*
* @param string $mode The mode to set.
*
* @return static
*
* @since 1.0.0
*/
public function use_app_mode($mode = 'production')
{
$this->mode = \in_array(\strtolower($mode), ['dev', 'development'], \true) ? 'development' : 'production';
return $this;
}
/**
* Check if the application is in development mode.
*
* @return bool
*
* @since 1.0.0
*/
public function is_dev_mode()
{
return $this->mode === 'development';
}
}