Skip to content

Commit

Permalink
Update Leantime Core to be Laravel Compliant
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelfolaron committed Nov 10, 2024
1 parent 8300c85 commit 8e46fdd
Show file tree
Hide file tree
Showing 28 changed files with 1,458 additions and 821 deletions.
158 changes: 158 additions & 0 deletions app/Core/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

namespace Leantime\Core;

use Illuminate\Container\Container;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Http\Kernel;
use Illuminate\Foundation\Mix;
use Illuminate\Foundation\PackageManifest;
use Illuminate\Foundation\ProviderRepository;
use Illuminate\Log\LogServiceProvider;
use Illuminate\Routing\Router;
use Illuminate\Routing\RoutingServiceProvider;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Leantime\Core\Configuration\Environment;
use Leantime\Core\Console\ConsoleKernel;
use Leantime\Core\Events\DispatchesEvents;
use Leantime\Core\Http\ApiRequest;
use Leantime\Core\Http\HttpKernel;
use Leantime\Core\Http\IncomingRequest;
use Leantime\Core\Providers\Events;
use Leantime\Core\Providers\Logging;


/**
* Class Application
*
* Represents an application.
*/
class Application extends \Illuminate\Foundation\Application
{
use DispatchesEvents;

/**
* Constructor for the class.
*
* @param string $basePath The base path for the application.
* @return void
*/
public function __construct($basePath = null)
{

$this->publicPath = 'public/';
$this->namespace = 'Leantime\\';

if ($basePath) {
$this->setBasePath($basePath);
}

$this->appPath = $basePath."/app/Core";

//Larevel stores cache in bootstrap folder
//Cache files are in root in Leantime not in bootstrap
//Env vars are not available in config

//putenv('APP_EVENTS_CACHE=cache/events.php');
//putenv('APP_CONFIG_CACHE=cache/config.php');
//putenv('APP_ROUTES_CACHE=cache/routes.php');
//putenv('APP_SERVICES_CACHE=cache/services.php');
//putenv('APP_PACKAGES_CACHE=cache/packages.php');

//Our folder structure is different and we shall not bow to the bourgeoisie
$this->useAppPath($this->basePath.'/app');
$this->useConfigPath($this->basePath.'/config');
$this->useEnvironmentPath($this->basePath.'/config');
$this->useBootstrapPath($this->basePath.'/bootstrap');
$this->usePublicPath($this->basePath.'/public');
$this->useStoragePath($this->basePath.'/storage');
$this->useLangPath($this->basePath.'/app/Language');

$this->registerBaseBindings();

//Loading some config vars so we can run events
//$this->register(new \Leantime\Core\Providers\Environment($this));

$this->registerBaseServiceProviders();
//$this->registerCoreContainerAliases();

//Overriding some of the aliases
$this->registerLeantimeAliases();

}

/**
* Register the base service providers.
*
* This method is used to register the base service providers required for the application.
*
* @return void
*/
protected function registerBaseServiceProviders()
{
//Loading some config vars so we can run events
//$this->register(new \Leantime\Core\Providers\Environment($this));

$this->register(new \Leantime\Core\Providers\Events($this));
$this->register(new LogServiceProvider($this));
$this->register(new RoutingServiceProvider($this));

//Todo: Add event and see if that works here.

}

public function registerLeantimeAliases()
{

foreach ([
'app' => [self::class, \Illuminate\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class, \Psr\SimpleCache\CacheInterface::class],
'cache.psr6' => [\Symfony\Component\Cache\Adapter\Psr16Adapter::class, \Symfony\Component\Cache\Adapter\AdapterInterface::class, \Psr\Cache\CacheItemPoolInterface::class],
'config' => [Environment::class, \Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
'encrypter' => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\StringEncrypter::class],
'events' => [\Leantime\Core\Events\EventDispatcher::class, \Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
'request' => [IncomingRequest::class, ApiRequest::class, Console\CliRequest::class, \Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class],
'redis' => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class],
'redis.connection' => [\Illuminate\Redis\Connections\Connection::class, \Illuminate\Contracts\Redis\Connection::class],
'session' => [\Illuminate\Session\SessionManager::class],
'session.store' => [\Illuminate\Session\Store::class, \Illuminate\Contracts\Session\Session::class],
'router' => [Router::class, \Illuminate\Contracts\Routing\Registrar::class, \Illuminate\Contracts\Routing\BindingRegistrar::class],
'view' => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class],
] as $key => $aliases) {
foreach ($aliases as $alias) {
$this->alias($key, $alias);
}
}

$this->alias(Application::class, \Illuminate\Contracts\Foundation\Application::class);

//$this->alias(DispatchesEvents::class, 'events');
//$this->alias(Environment::class, 'config');
}

//Boot with Leantime event dispatcher


/**
* Boot the application.
*
* @return void
*/
public function boot()
{

//We need to discover events a lot earlier than Laravel wants us to.
//So we're just doing it.
\Illuminate\Support\Facades\Event::discoverListeners();

//Calling the first event
self::dispatchEvent('beforeBootingServiceProviders');

parent::boot();

self::dispatchEvent('afterBootingServiceProviders');

}
}
108 changes: 108 additions & 0 deletions app/Core/Bootloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace Leantime\Core;

use Illuminate\Contracts\Container\BindingResolutionException;
use Leantime\Core\Console\ConsoleKernel;
use Leantime\Core\Events\DispatchesEvents;
use Leantime\Core\Http\HttpKernel;
use Leantime\Core\Http\IncomingRequest;

/**
* Bootloader
*/
class Bootloader
{
use DispatchesEvents;

/**
* Bootloader instance
*
* @var static
*/
protected static ?Bootloader $instance = null;

protected Application $app;

/**
* Get the Bootloader instance
*
* @param Application $app
*/
public static function getInstance(): self
{

if (is_null(static::$instance)) {
static::$instance = new self;
}

return static::$instance;
}

/**
* Constructor
*/
private function __construct() {}

/**
* Execute the Application lifecycle.
*
* @return void
*
* @throws BindingResolutionException
*/
public function boot(Application $app)
{
if (! defined('LEANTIME_START')) {
define('LEANTIME_START', microtime(true));
}

//Start Application
//Load the bindings and service providers
$this->app = $app;

//Capture the request and instantiate the correct type
$request = IncomingRequest::capture();


//Use the right kernel for the job and handle the request.
$this->handleRequest($request);

self::dispatchEvent('end', ['bootloader' => $this]);

}

/**
* Handle the request
*
* @throws BindingResolutionException
*/
private function handleRequest($request): void
{

if (! $this->app->runningInConsole()) {

/** @var HttpKernel $kernel */
$kernel = $this->app->make(HttpKernel::class);

$kernelHandler = $kernel->handle($request);
$response = $kernelHandler->send();

$kernel->terminate($request, $response);

} else {

/** @var ConsoleKernel $kernel */
$kernel = $this->app->make(ConsoleKernel::class);

$status = $kernel->handle(
$input = new \Symfony\Component\Console\Input\ArgvInput,
new \Symfony\Component\Console\Output\ConsoleOutput
);

$kernel->terminate($input, $status);

exit($status);
}
}
}
Loading

0 comments on commit 8e46fdd

Please sign in to comment.