PHP code example of earc / router

1. Go to this page and download the library: Download earc/router library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

earc / router example snippets




use eArc\Core\Configuration;
use eArc\DI\DI;

DI::init();
Configuration::build();

use eArc\Router\RouterEvent;

$event = new RouterEvent();
$event->dispatch();

 #.earc-config.php

return ['earc' => [
    'is_production_environment' => false,
    'event_tree' => [
        'directories' => [
            'earc/router/earc-event-tree' => 'eArc\\RouterEventTreeRoot',
            // your configuration part:
            '../path/to/your/eventTree/root/folder' => 'NamespaceOfYour\\EventTreeRoot',
        ]   
    ]
]];


 #.earc-config.php

return Yaml::parse(file_get_contents('/path/to/your/config.yml'));


namespace NamespaceOfYour\EventTreeRoot\routing\admin\user\edit;

use eArc\Router\AbstractController;
use eArc\Router\Interfaces\RouterEventInterface;

class Controller extends AbstractController
{
    public function process(RouterEventInterface $event) : void
    {
        //... your controller code goes here

        //... a very basic example without form processing:

        // the parameters are the route arguments that does not match a directory        
        $id = $event->getRoute()->getParam(0);
        // if you use doctrine the next step could look like this
        $user = di_get(UserRepository::class)->find($id);
        // calling some third party rendering engine    
        di_get(EngineInterface::class)->render('templates/user/edit.html', ['user' => $user]);
    }
}

namespace NamespaceOfYour\EventTreeRoot\routing\admin\user\edit;

use eArc\Router\AbstractResponseController;
use eArc\Router\Interfaces\ResponseInterface;
use eArc\Router\Response;

class Controller extends AbstractResponseController
{
    public function respond(?User $userObject) : ResponseInterface
    {
        //... your controller code goes here

        //... a very basic example without form processing:

        // calling some third party rendering engine    
        return new Response(di_get(EngineInterface::class)->render('templates/user/edit.html', ['user' => $userObject]));
    }
}

    use eArc\ParameterTransformer\Interfaces\ParameterTransformerFactoryInterface;
    
    class User implements ParameterTransformerFactoryInterface
    {
        //...
    
        public static function buildFromParameter($parameter): static
        {
            return di_get(EntityManagerInterface::class)
                ->getRepository(User::class)
                ->find($parameter);
        }
    }
 

use eArc\ParameterTransformer\Interfaces\ParameterTransformerFactoryServiceInterface;

class ParameterTransformerExtension implements ParameterTransformerFactoryServiceInterface
{
    public function buildFromParameter(string $fQCN, $parameter) : object|null
    {
        return di_get(EntityManagerInterface::class)
            ->getRepository($fQCN)
            ?->find($parameter);
    }
}

// ...

di_tag(ParameterTransformerFactoryServiceInterface::class, ParameterTransformerExtension::class);

namespace NamespaceOfYour\EventTreeRoot\routing\admin\user\edit;

use eArc\Router\AbstractResponseController;
use eArc\Router\Interfaces\ResponseInterface;
use eArc\Router\Interfaces\RouterEventInterface;

class Controller extends AbstractResponseController
{
    public function respond(?User $userObject, ?string $name) : ResponseInterface
    {
        // ...
    }
    
    protected function getInputKeyMapping(RouterEventInterface $event): array
    {
        return [
            'userObject' => 0,
            'name' => 'new_name',
        ];
    }
}

namespace NamespaceOfYour\EventTreeRoot\routing\admin\user\edit;

use eArc\Router\AbstractResponseController;
use eArc\Router\Interfaces\RequestInformationInterface;
use eArc\Router\Interfaces\ResponseInterface;
use eArc\Router\Interfaces\RouteInformationInterface;
use eArc\Router\Interfaces\RouterEventInterface;

class Controller extends AbstractResponseController
{
    public function respond(MyControllerService $service, ?User $userObject, ?string $name = 'Default Name') : ResponseInterface
    {
        // ...
    }
    
    protected function getPredefinedTypeHints(RouterEventInterface $event): array
    {
        return [
            MyControllerService::class => di_get(MyControllerServiceFactory::class)->build($event),
            RouterEventInterface::class => $event,
            RouteInformationInterface::class => $event->getResponse(),
            RequestInformationInterface::class => $event->getRequest(),
        ];
    }
}

use eArc\Router\RouterEvent;

$event = new RouterEvent(
    $url,
    $requestMethod,
    $requestVariables
);

$event->dispatch();

namespace NamespaceOfYour\EventTreeRoot\routing\admin\user\edit;

use eArc\Router\Interfaces\RouterListenerInterface;
use eArc\Router\RouterEvent;
use eArc\Router\Interfaces\RouterEventInterface;

class Listener implements RouterListenerInterface
{
    public function process(RouterEventInterface $event) : void
    {
        //... your listener code goes here

        //... 
        // the user is not logged in
        $event->getHandler()->kill();
        (new RouterEvent('/login'))->dispatch();
        // ...
        // the user has no admin privileges
        $event->getHandler()->kill();
        (new RouterEvent('/error-pages/access-denied', 'GET'))->dispatch();
        //...
    }
}

namespace NamespaceOfYour\EventTreeRoot\routing\some\route;

use eArc\EventTree\Transformation\ObserverTree;
use eArc\EventTree\Interfaces\PhaseSpecificListenerInterface;
use eArc\Router\Interfaces\RouterListenerInterface;
use eArc\EventTree\Interfaces\SortableListenerInterface;
use eArc\Router\Interfaces\RouterEventInterface;

class Listener implements RouterListenerInterface, SortableListenerInterface, PhaseSpecificListenerInterface
{
    public function process(RouterEventInterface $event) : void
    {
        //...
    }
                          
    public static function getPatience() : float
    {
        // it has a negative patience and is hence called before the controller
        // who has a patience of 0.
        return -1;
    }

    public static function getPhase(): int
    {
        // listener with phase destination are only called if the route matches
        return ObserverTree::PHASE_DESTINATION;
    }
}

namespace NamespaceOfYour\EventTreeRoot\routing\admin\user\edit;

use eArc\Router\AbstractController;
use eArc\Router\Interfaces\RouterEventInterface;

abstract class AbstractDeprecatedSyntaxController extends AbstractController
{
    public function process(RouterEventInterface $event) : void
    {
        $this->preProcessing($event);

        try {
            $actionId = $event->getRoute()->getParam(0);
            $methodName = $actionId.'Action';
            $this->$methodName($event);
        } catch (\Exception $exception) {
            $this->logException($exception);       
        }

        $this->postProcessing($event);
    }
    
    protected function logException(\Exception $exception) {/*...*/}

    protected function preProcessing(RouterEventInterface $event) {/*...*/}

    protected function postProcessing(RouterEventInterface $event) {/*...*/}
}

namespace NamespaceOfYour\EventTreeRoot\earc\lifecycle\router;

use eArc\Observer\Interfaces\ListenerInterface;
use eArc\EventTree\Interfaces\SortableListenerInterface;
use eArc\Observer\Interfaces\EventInterface;
use eArc\Router\AbstractController;
use eArc\Router\LifeCycle\RouterLifeCycleEvent;
use eArc\Router\Interfaces\RouterEventInterface;

class PreProcessingListener implements ListenerInterface, SortableListenerInterface
{
    public function process(EventInterface $event) : void
    {
        if ($event instanceof RouterLifeCycleEvent) {
            $this->preProcessing($event->routerEvent);
        }
    }

    protected function preProcessing(RouterEventInterface $event) {/*...*/}
        
    public static function getPatience() : float
    {
        return -1;
    }
}

class PostProcessingListener implements ListenerInterface, SortableListenerInterface
{
    public function process(EventInterface $event) : void
    {
        if ($event instanceof RouterLifeCycleEvent) {
            $this->postProcessing($event->routerEvent);
        }
    }
      
    protected function postProcessing(RouterEventInterface $event) {/*...*/}

    public static function getPatience() : float
    {
      return 1;
    }
}

class ExecuteCallListener implements ListenerInterface
{
    public function process(EventInterface $event) : void
    {
        if ($event instanceof RouterLifeCycleEvent) {
            try {
                $listener = $event->listenerCallable[0];
                if (!$listener instanceof AbstractController) {
                    call_user_func($event->listenerCallable, $event->routerEvent);
                
                    return;
                }

                $actionId = $event->routerEvent->getRoute()->getParam(0);
                $methodName = $actionId.'Action';
                $listener->$methodName($event->routerEvent);
            } catch (\Exception $exception) {
                $this->logException($exception);       
            }
        }
    }
    
    protected function logException(\Exception $exception) {/*...*/}
}

use eArc\RouterEventTreeRoot\earc\lifecycle\router\ExecuteCallListener;

di_import_param(['earc' => ['event_tree' => ['blacklist' => [
    ExecuteCallListener::class => true,
]]]]);

use NamespaceOfYour\App\Somewhere\OutsideTheEventTree\ExecuteCallListener;
use eArc\RouterEventTreeRoot\earc\lifecycle\router\ExecuteCallListener as OriginECL;

di_decorate(OriginECL::class, ExecuteCallListener::class);

namespace NamespaceOfYour\App\Somewhere\OutsideTheEventTree;

use eArc\Router\RouterEvent;

interface AppRuntimeInformationInterface
{
    public function getRunnerId(): int;
    public function addWarning(Exception $exception);
    public function getWarnings(): array;
    public function getSession(): SessionInterface;
    public function getCurrentUser() : ?UserInterface;
    public function setCurrentUser(?UserInterface $user);
}

class AppRuntimeInformation implements AppRuntimeInformationInterface
{
    protected $runnerId;
    protected $warnings = [];
    protected $session;
    protected $currentUser;

    //...
}

class AppRouterEvent extends RouterEvent
{
    protected $runtimeInformation;

    public function __construct(?string $uri = null,?string $requestMethod = null,?array $argv = null)
    {
        parent::__construct($uri,$requestMethod,$argv);

        $this->runtimeInformation = di_get(AppRuntimeInformation::class);              
    }

    public function getRI(): AppRuntimeInformationInterface {/*...*/}
}

$event = new AppRouterEvent();
$event->dispatch();

use eArc\Router\Interfaces\RouterEventInterface;

di_import_param(['earc' => [
    'router' => [
        'routing_directory' => [
            RouterEventInterface::class => 'v2/routing'
        ]   
    ]
]]);