Ejemplo n.º 1
0
 /**
  * Handles dependencies for ExtendedClass instances
  *
  * @final
  * @access protected
  * @param mixed $Instance
  * @param array $Options (Optional) Array with options
  * @return void
  */
 protected final function HandleDependencies(&$Instance, array $Options = [])
 {
     /* ------------------------------------------------------------------------------------------------------
           GET DEPENDENCIES
        ------------------------------------------------------------------------------------------------------ */
     $Dependencies = new Dependencies();
     // Load environment
     $Environment = $this->InjectionContainer->Retrieve('Environment');
     // Call the "Dependencies" method on the instance
     // $Dependencies which we created above, is injected as a reference, so any actions taken
     // to it, are automatically applied on this very object
     $Instance->Dependencies($Dependencies, $Environment, ['Method' => (string) $Options['Method']]);
     /* ------------------------------------------------------------------------------------------------------
           REQUIREMENTS
        ------------------------------------------------------------------------------------------------------ */
     // List the requirements defined in the Dependencies method
     $Requirements = $Dependencies->ListRequirements();
     // Work on groups
     foreach ($Requirements['Groups'] as $X => $Group) {
         foreach ($this->Implementations as $Y => $Implementation) {
             if (!is_array($Implementation['Groups'])) {
                 continue;
             }
             if (in_array($Group['Group'], $Implementation['Groups'])) {
                 $Requirements['Implementations'][] = ['Name' => basename($Implementation['Location']), 'StrictRequirement' => False, 'Extra' => ['Groups' => $Implementation['Groups']]];
             }
         }
     }
     /* --------------------------------------------------------------------------------------------------
           INSTANTIATE
        -------------------------------------------------------------------------------------------------- */
     // Iterate over the required implementations
     foreach ($Requirements['Implementations'] as $I => $ImplementationData) {
         // Set name
         $Implementation = $ImplementationData['Name'];
         // If the implementation is not registered, we cannot safely assume its location and we'll
         // fail to load it. So let's throw an Exception
         if (!array_key_exists($Implementation, $this->Implementations)) {
             if (!$ImplementationData['StrictRequirement']) {
                 continue;
             }
             // Let the developer know the implementation has not been registered
             throw new \Bytes\ComponentException(sprintf('%s has required the implementation %s. But it does not occur in the application registry.', get_class($Instance), $Implementation));
         }
         // If the implementation has been registered, we'll create it via the CreateImplementation
         // method, and then attach it to the InjectionContainer
         $this->InjectionContainer->Attach($Implementation, $this->CreateImplementation($this->Implementations[$Implementation]['Location']), isset($ImplementationData['Extra']) ? $ImplementationData['Extra'] : []);
     }
     /* ------------------------------------------------------------------------------------------------------
           ADD INJECTION CONTAINER
        ------------------------------------------------------------------------------------------------------ */
     $Instance->SetInjectionContainer($this->InjectionContainer);
 }
Ejemplo n.º 2
0
 /**
  * Starts the application
  *
  * @access public
  * @param string $URI URI for the router to compare against
  * @param callable $Callback
  * @return mixed Whatever comes out of $Callback
  */
 public function Start(string $URI, callable $Callback)
 {
     /* ------------------------------------------------------------------------------------------------------
           INITIALIZE
        ------------------------------------------------------------------------------------------------------ */
     $InjectionContainer = new InjectionContainer();
     $ObjectBuilder = new ObjectBuilder();
     $InjectionContainer->Attach('Environment', $this->Environment);
     $InjectionContainer->Attach('Header', $this->Header);
     $ObjectBuilder->SetInjectionContainer($InjectionContainer);
     $ObjectBuilder->SetHooksContainer($this->HooksContainer);
     $ObjectBuilder->SetImplementations($this->Implementations);
     // Populate triggers/hook for the application object
     $this->__Options->PopulateTriggers($this->HooksContainer, $ObjectBuilder);
     /* ------------------------------------------------------------------------------------------------------
           LOAD COMPONENTS
        ------------------------------------------------------------------------------------------------------ */
     // Iterate over all preloaded components
     foreach ($this->Components as $I => $ComponentName) {
         // Use the object builder to create the component and work with the router and environment
         $Component = $ObjectBuilder->CreateImplementation($ComponentName, 'Component');
         // Initialize the component (create its routes, etc.)
         $Component->Initialize($this->Router);
         // Store the component for later reference
         $this->Components[basename($ComponentName)] = $Component;
     }
     /* ------------------------------------------------------------------------------------------------------
           FIND ROUTE + EXECUTE CONTROLLER
        ------------------------------------------------------------------------------------------------------ */
     try {
         // Find information on controller and method, using the Router's Match method
         $Route = $this->Router->Match($URI);
         // If no route is found, we'll invoke a 404 error
         if (!$Route) {
             throw new Exception('Not Found', 404);
         }
         // Retrieve output from the controller's requested method
         $ComponentId = basename($Route['Component']);
         $Output = $this->Components[$ComponentId]->Controller((string) $Route['Controller'], (string) $Route['Method'], ['Route' => $URI]);
         // If we successfully get to this point, we store the output
         // This enables us to use it both inside the custom callback method, as well as
         // in other methods, such as Application::Render
         $this->ControllerOutput = $Output;
     } catch (\Exception $E) {
         // Load environment
         $Env = $this->Environment();
         // In case of exception, we'll look to the router, and see if it requests to use
         // a custom error handle
         if ($this->AssignedErrorHandler) {
             $Handle = 'ERROR/' . (string) $Route['ErrorHandle'];
             $ErrorHandlerComponent = basename($this->AssignedErrorHandler['Location']);
             $ErrorHandler = $this->Components[$ErrorHandlerComponent];
             $ErrorRoute = $this->Router->Match($Handle);
             $ErrorController = (string) $ErrorRoute['Controller'];
             $ErrorMethod = (string) $ErrorRoute['Method'];
             if (!$ErrorRoute) {
                 $ErrorController = 'Index';
                 $ErrorMethod = 'Default';
             }
             $Output = $ErrorHandler->Controller($ErrorController, $ErrorMethod, ['ErrorHandler' => True, 'Exception' => $E]);
             $this->ControllerOutput = $Output;
         } else {
             // If there's no custom error handle and no default, we'll do a fallback to a simple JSON message
             // (JSON applied, if Application::Render is used)
             $this->ControllerOutput = ['Error' => $E->getMessage()];
         }
     }
     /* ------------------------------------------------------------------------------------------------------
           RETURN
        ------------------------------------------------------------------------------------------------------ */
     return $Callback($this, $this->ControllerOutput);
 }