diff --git a/Framework.php b/Framework.php index 5f2aba0..70cccb9 100644 --- a/Framework.php +++ b/Framework.php @@ -29,14 +29,19 @@ class Framework public static $instance; private $app; private $response; - private $request; + private $request = null; private $kernel; + private $get_routes; + private $registry; - private $routes_checked = []; + private $route; + private $output; public function __construct() { $this->app = require __DIR__ . '/bootstrap/app.php'; + + $this->kernel = $this->app->make(\Illuminate\Contracts\Http\Kernel::class); } /** @@ -51,6 +56,13 @@ public static function getInstance() return self::$instance; } + public function initiate($registry, $route, &$output) + { + $this->registry = $registry; + $this->route = $route; + $this->output = $output; + } + /** * Retrieve Response */ @@ -79,8 +91,6 @@ public function getRegistry($type = null) */ public function run() { - $this->kernel = $this->app->make(\Illuminate\Contracts\Http\Kernel::class); - $this->response = $this->kernel->handle( $this->request = \Illuminate\Http\Request::capture() ); @@ -93,15 +103,11 @@ public function run() /** * Handle Framework Response */ - public function handle($registry = null) + public function handle() { - $this->registry = $registry; - - $this->kernel = $this->app->make(\Illuminate\Contracts\Http\Kernel::class); - $this->response = $this->kernel->handle($this->request); - if($this->response instanceof \Symfony\Component\HttpFoundation\BinaryFileResponse){ + if ($this->response instanceof \Symfony\Component\HttpFoundation\BinaryFileResponse) { $this->response->send(); return true; @@ -113,37 +119,46 @@ public function handle($registry = null) /** * Check Route function * - * @param string $route - * @param object $registry * @return bool */ - public function checkRoute($route, &$output) + public function checkRoute() { - - // Strip query string (?foo=bar) and decode URI - if (false !== $pos = strpos($route, '?')) { - $route = substr($route, 0, $pos); - } - $route = rawurldecode($route); + Framework::getInstance()->initiateRouteRequest(); /** - * Avoid multi chekings for the same controller + * TODO: find a better way to check all available routes */ - if(isset($this->routes_checked[$route])) { - return null; - } else { - $this->routes_checked[$route] = true; + if (!isset($this->get_routes)) { + $response = $this->kernel->handle($request = \Illuminate\Http\Request::capture()); + + $this->kernel->terminate($request, $response); + + $this->get_routes = $this->app->router->getRoutes(); + }; + + try { + return (bool) $this->get_routes->match($this->request)->uri(); + } catch (\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e) { + return false; } + } + /** + * Initiate Route request function + * + * @param string $route + * @param string &$output + * @return void + */ + public function initiateRouteRequest() + { $this->request = \Illuminate\Http\Request::capture(); /** * force admin route in case the request comes from admin side */ - if(defined('HTTPS_CATALOG')) { - $appBaseName = basename(DIR_APPLICATION) . '/'; - $route = $appBaseName . $route; - + $appBaseName = basename(DIR_APPLICATION) . '/'; + if (defined('HTTPS_CATALOG')) { $serverName = $this->request->server->get('SCRIPT_NAME'); $this->request->server->set('SCRIPT_NAME', str_replace($appBaseName, '', $serverName)); } @@ -152,10 +167,8 @@ public function checkRoute($route, &$output) * Change URI for partial loaded controllers like common/header, common/footer etc... * in order to be able to override them */ - if($output !== false) { - $this->request->server->set('REQUEST_URI', $route); + if ($this->output !== false) { + $this->request->server->set('REQUEST_URI', $this->route); } - - return $this->app->router->has($route) || $this->request->is($route . '*'); } } diff --git a/README.md b/README.md index 3639209..6e9142d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ OpenCore is an application made on Laravel for OpenCart which let's you develop new features or overwrite the existing ones in Laravel instead of the old OpenCart framework. The application comes with built-in features which help the developers to create new modules or new functionalities for OpenCart ecommerce platform. Also, stand-alone features (independent of OpenCart) can be easily added. ## OpenCore - Laravel for OpenCart -by Aweb Design +Official website [OpenCore](https://opencore.me). +project made with the help of Aweb Design ## WORK IN PROGRESS @@ -24,21 +25,22 @@ Please note that this package is still under active development. We encourage ev ## System Requirements -PHP >= 7.1.3 -BCMath PHP Extension -Ctype PHP Extension -JSON PHP Extension -Mbstring PHP Extension -OpenSSL PHP Extension -PDO PHP Extension -Tokenizer PHP Extension -XML PHP Extension -* check Laravel requirements because they may differ depending on the used version +* PHP >= 7.1.3 +* BCMath PHP Extension +* Ctype PHP Extension +* JSON PHP Extension +* Mbstring PHP Extension +* OpenSSL PHP Extension +* PDO PHP Extension +* Tokenizer PHP Extension +* XML PHP Extension + +check Laravel requirements because they may differ depending on the used version ## Other Requirements -OpenCart 2.x / 3.x installed -root .htaccess.txt renamed to .htaccess -admin / setting / server / Use SEO URLs: Yes +* OpenCart 2.x / 3.x installed +* root .htaccess.txt renamed to .htaccess +* change admin settings from admin / setting / server / Use SEO URLs: Yes ## Installation diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 6c64e52..658ffd1 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -3,9 +3,10 @@ namespace App\Providers; use Illuminate\Support\Facades\Event; -use Illuminate\Auth\Events\Registered; -use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\File; +//use Illuminate\Auth\Events\Registered; +//use Illuminate\Auth\Listeners\SendEmailVerificationNotification; class EventServiceProvider extends ServiceProvider { @@ -15,9 +16,9 @@ class EventServiceProvider extends ServiceProvider * @var array */ protected $listen = [ - Registered::class => [ - SendEmailVerificationNotification::class, - ], + // Registered::class => [ + // SendEmailVerificationNotification::class, + // ], ]; /** @@ -29,6 +30,16 @@ public function boot() { parent::boot(); - // + /** + * delete OpenCore routes stored on OpenCart cache folder + */ + Event::listen('cache:cleared', function () { + if (!defined('DIR_CACHE')) { + require realpath(basename(__DIR__ . '/../../../')) . '/config.php'; + } + + $cachedRoutes = File::glob(DIR_CACHE . 'cache.opencore_routes.*.*'); + File::delete($cachedRoutes); + }); } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 2837a04..3db150c 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -52,8 +52,8 @@ public function map() protected function mapWebRoutes() { /* Route::middleware('web') - ->namespace($this->namespace) - ->group(base_path('routes/web.php')); */ + ->namespace($this->namespace) + ->group(base_path('routes/web.php')); */ } protected function mapAdminRoutes() @@ -83,8 +83,8 @@ protected function mapCatalogRoutes() protected function mapApiRoutes() { Route::prefix('api') - ->middleware('api') - ->namespace($this->namespace) - ->group(base_path('routes/api.php')); + ->middleware('api') + ->namespace($this->namespace) + ->group(base_path('routes/api.php')); } } diff --git a/config/app.php b/config/app.php index 0123e90..1fbae68 100644 --- a/config/app.php +++ b/config/app.php @@ -211,7 +211,7 @@ 'Hash' => Illuminate\Support\Facades\Hash::class, 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, - 'Mail' => Illuminate\Support\Facades\Mail::class, + 'IMail' => Illuminate\Support\Facades\Mail::class, 'Notification' => Illuminate\Support\Facades\Notification::class, 'Password' => Illuminate\Support\Facades\Password::class, 'Queue' => Illuminate\Support\Facades\Queue::class, diff --git a/support/Opencart/Startup.php b/support/Opencart/Startup.php index cf00dc3..8b37436 100644 --- a/support/Opencart/Startup.php +++ b/support/Opencart/Startup.php @@ -14,7 +14,7 @@ } if (!defined('OPENCORE_VERSION')) { - define('OPENCORE_VERSION', '1.2.0'); + define('OPENCORE_VERSION', '1.2.1'); } require_once __DIR__ . '/../../vendor/autoload.php'; @@ -24,10 +24,19 @@ class Startup extends \Controller { - private $route; private static $_registry; + private $route; private $data; + private $routes_cache_time = 3600; //1 hour expiration time + + private $default_allowed_routes = [ + 'admin/core/home', + 'admin/core/requirements', + 'admin/core/modules', + 'admin/core/clear-cache' + ]; + function __construct($registry) { parent::__construct($registry); @@ -44,17 +53,26 @@ function __construct($registry) */ public function executeIfRouteExists($route, &$data, &$output = false) { + $this->route = $route; + $this->data = $data; + /** * we are using $this->request->get['route'] instead of $route because on $route some characters like dash ("-") are removed */ - if (!empty($this->request->get['route']) && preg_replace('/[^a-zA-Z0-9_\/]/', '', (string) $this->request->get['route']) == $route) { - $route = $this->request->get['route']; + if (!empty($this->request->get['route']) && preg_replace('/[^a-zA-Z0-9_\/]/', '', (string) $this->request->get['route']) == $this->route) { + $this->route = $this->request->get['route']; + } + + // Strip query string (?foo=bar) and decode URI + if (false !== $pos = strpos($this->route, '?')) { + $this->route = substr($this->route, 0, $pos); } + $this->route = rawurldecode($this->route); - if ($this->checkOpenCoreRoute($route, $data, $output)) { + if ($this->checkOpenCoreRoute()) { $response = $this->response(); - if($output === false) { + if ($output === false) { /** * means is a controller request which means we need to use default setOutput() */ @@ -75,20 +93,60 @@ public function executeIfRouteExists($route, &$data, &$output = false) /** * Check Framewrok available routes - * - * @param string $route */ - public function checkOpenCoreRoute($route, &$data, &$output) + public function checkOpenCoreRoute() { - $this->route = $route; - $this->data = $data; - + /** + * if is an Admin request add path to route + */ + $appBaseName = basename(DIR_APPLICATION); + if (defined('HTTPS_CATALOG') && !strstr($this->route, $appBaseName . '/')) { + $this->route = $appBaseName . '/' . $this->route; + } /* - We should add a dinamyc ignore list here + TODO: We should add a dynamic ignore list here which should be configurable in admin/core/settings */ - if (Framework::getInstance()->checkRoute($route, $output)) { - return Framework::getInstance()->handle(self::$_registry); + + /** + * force admin route in case the request comes from admin side + */ + $allowed_routes = []; + + if ($this->routes_cache_time) { + $cache = self::$_registry->get('cache'); + $allowed_routes = $cache->get('opencore_routes.' . $appBaseName); //separate for admin & catalog to avoid large cache files + } + + if (in_array($this->route, $this->default_allowed_routes)) { + $allowed_routes[$this->route] = true; } + + if (isset($allowed_routes[$this->route]) && $allowed_routes[$this->route] == false) { + return false; + } else { + Framework::getInstance()->initiate(self::$_registry, $this->route, $output); + + if (!empty($allowed_routes[$this->route])) { + Framework::getInstance()->initiateRouteRequest(); + } elseif (Framework::getInstance()->checkRoute()) { + $allowed_routes[$this->route] = true; + } else { + $allowed_routes[$this->route] = false; + } + } + + /** + * Cache OpenCore allowed routes for faster rendering + */ + if ($this->routes_cache_time) { + $cache->set('opencore_routes.' . $appBaseName, $allowed_routes, time() + $this->routes_cache_time); + } + + if ($allowed_routes[$this->route]) { + return Framework::getInstance()->handle(); + } + + return false; } /** diff --git a/support/UrlGenerator.php b/support/UrlGenerator.php index b69990b..e6e17c5 100644 --- a/support/UrlGenerator.php +++ b/support/UrlGenerator.php @@ -59,4 +59,25 @@ public function formatParameters($parameters) return $parameters; } + + /** + * Get the base URL for the request. + * + * @param string $scheme + * @param string|null $root + * @return string + */ + public function formatRoot($scheme, $root = null) + { + if(defined('DIR_CATALOG')) { + /** + * because we are checking the routes in Framework::checkRoute using + * $this->kernel->handle($request = \Illuminate\Http\Request::capture()); + * the admin path is added twice in routes + */ + $root = HTTPS_CATALOG; + } + + return parent::formatRoot($scheme, $root); + } }