Skip to content

Instantly share code, notes, and snippets.

@miedzwin
Last active November 12, 2018 16:51
Show Gist options
  • Save miedzwin/49bac1cc1d5270d3ba1bfcf700abf864 to your computer and use it in GitHub Desktop.
Save miedzwin/49bac1cc1d5270d3ba1bfcf700abf864 to your computer and use it in GitHub Desktop.
Framework
imports:
- { resource: services.yml }
<?php
namespace Framework\App;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class Container extends ContainerBuilder
{
/**
* Container constructor.
* @param ParameterBagInterface|null $parameterBag
*/
public function __construct(ParameterBagInterface $parameterBag = null)
{
parent::__construct($parameterBag);
}
}
<?php
namespace APP\V2\Service\SocialNetwork\Facebook;
class FacebookService {
public function __construct(string $awsRegion){
echo 'Hello world';
}
}
<?php
namespace Framework\App;
use APIException;
use InvalidArgumentException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\HttpKernel\EventListener\ResponseListener;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
use App\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\Routing\Matcher\UrlMatcher;
class Framework extends HttpKernel
{
/**
* @var UrlMatcherInterface
*/
protected $matcher;
/**
* @var ControllerResolverInterface
*/
protected $controllerResolver;
/**
* @var ArgumentResolverInterface
*/
protected $argumentResolver;
/**
* @var string
*/
protected $environment;
/**
* @var string
*/
private $rootDir;
/**
* @var Container
*/
private $container = null;
/**
* Framework constructor.
* @param string $environment
* @throws \Exception
*/
public function __construct(string $environment)
{
$this->buildContainer($environment);
$this->matcher = $this->container->get(UrlMatcher::class);
$this->controllerResolver = $this->container->get(ControllerResolver::class);
$this->argumentResolver = $this->container->get(ArgumentResolver::class);
$this->environment = $environment;
$dispatcher = new EventDispatcher();
$requestStack = new RequestStack();
$dispatcher->addSubscriber(new RouterListener($this->matcher, $requestStack));
$dispatcher->addSubscriber(new ResponseListener('UTF-8'));
parent::__construct($dispatcher, $this->controllerResolver, $requestStack, $this->argumentResolver);
}
/**
* Handles a Request to convert it to a Response.
*
* When $catch is true, the implementation must catch all exceptions
* and do its best to convert them to a Response instance.
*
* @param Request $request A Request instance
* @param int $type The type of the request
* (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
* @param bool $catch Whether to catch exceptions or not
*
* @return Response A Response instance
*
* @throws \Exception When an Exception occurs during processing
*/
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
{
$this->matcher->getContext()->fromRequest($request);
try {
$request->attributes->add($this->matcher->match($request->getPathInfo()));
$controller = $this->controllerResolver->getController($request);
$arguments = $this->argumentResolver->getArguments($request, $controller);
return call_user_func_array($controller, $arguments);
} catch (ResourceNotFoundException $ex) {
return new Response('Not Found.', Response::HTTP_NOT_FOUND);
} catch (APIException $ex) {
return new JsonResponse([
'success' => false,
'errorHtmlCode' => $ex->getCode(),
'errorMessage' => $ex->getMessage(),
]);
} catch (\Exception $ex) {
echo $ex->getMessage();
return new Response('An error occured.', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* Initialize DI container
*/
private function buildContainer(string $environment): void
{
$container = new Container();
$container->setParameter('routes', (new Router())->getRouteCollection());
$this->container = $container;
$this->loadParameters();
$this->loadServices();
$this->container->compile();
$this->initEnvironmentVars();
}
/**
* Loading services with configuration from file
*/
private function loadServices(): void
{
$yamlLoader = new YamlFileLoader($this->container, new FileLocator(__DIR__ . '/../../config'));
try {
$yamlLoader->load('config.yml');
} catch (\Exception $e) {
echo $e->getMessage();
die('An error occurred while registering services.');
}
}
/**
* Load parameters from file
*/
private function loadParameters(): void
{
$fileLocator = new FileLocator(__DIR__ . '/../../');
$yamlFileLoader = new YamlFileLoader($this->container, $fileLocator);
try {
$yamlFileLoader->load('.env.yml');
} catch (InvalidArgumentException $e) {
die('Invalid yaml file structure.');
} catch (\Exception $e) {
die('.env.yml file not found. Application cannot start.');
}
$parameterBag = $this->container->getParameterBag();
foreach ($parameterBag->all() as $key => $value) {
$this->container->setParameter($key, $value);
}
}
}
<?php
$loader = require __DIR__ . '/../vendor/autoload.php';
// ILFW entry point
use Framework;
use Symfony\Component\HttpFoundation\Request;
session_start();
$request = Request::createFromGlobals();
$response = (new Framework('ilikefreewifi'))->handle($request);
$response->send();
<?php
namespace Framework\App;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Router as BaseRouter;
class Router extends BaseRouter
{
/**
* @var YamlFileLoader
*/
private $yamlFileLoader;
/**
* Router constructor.
*/
public function __construct()
{
$fileLocator = new FileLocator(__DIR__ . '/../../config');
$this->yamlFileLoader = new YamlFileLoader($fileLocator);
parent::__construct($this->yamlFileLoader, 'routes.yml');
}
}
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to
### BASE FRAMEWORK SERVICES REGISTRATION ###
APP\V2\:
resource: '../src/app/V2/*'
exclude: '../src/app/V2/{Script, Trait}'
APP\V2\Controller\:
resource: '../src/app/V2/Controller/*'
public: true
parameter_bag:
class: Symfony\Component\DependencyInjection\ParameterBag\ContainerBag
public: true
arguments:
- '@service_container'
context:
class: Symfony\Component\Routing\RequestContext
public: false
url_matcher:
class: Symfony\Component\Routing\Matcher\UrlMatcher
public: true
arguments: ['%routes%', '@context']
controller_resolver:
class: Symfony\Component\HttpKernel\Controller\ControllerResolver
public: true
argument_resolver:
class: Symfony\Component\HttpKernel\Controller\ArgumentResolver
public: true
### END ###
APP\V2\Service\SocialNetwork\Facebook\FacebookService:
class: APP\V2\Service\SocialNetwork\Facebook\FacebookService
autowire: true
public: true
arguments: ['%AWS_REGION%']
<?php
namespace APP\V2\Controller\API;
use APP\V2\Service\SocialNetwork\Facebook\FacebookService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ApiController extends AbstractController
{
/**
* @return JsonResponse
*/
public function initAction(FacebookService $facebookService)
{
var_dump($facebookService);
die();
}
}
<?php
namespace ILFW\V2\Service;
use ILFW\V2\Service\SocialNetwork\Facebook\FacebookService;
class TestService
{
public function __construct(FacebookService $facebookService)
{
die('Hello world!');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment