Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
50.00% covered (danger)
50.00%
3 / 6
CRAP
68.66% covered (warning)
68.66%
46 / 67
ResourceDispatcher
0.00% covered (danger)
0.00%
0 / 1
50.00% covered (danger)
50.00%
3 / 6
49.45
68.66% covered (warning)
68.66%
46 / 67
 __construct
0.00% covered (danger)
0.00%
0 / 1
8.30
60.00% covered (warning)
60.00%
12 / 20
 getResource
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 createFlags
100.00% covered (success)
100.00%
1 / 1
11
100.00% covered (success)
100.00%
18 / 18
 buildPath
0.00% covered (danger)
0.00%
0 / 1
6.75
58.82% covered (warning)
58.82%
10 / 17
 view
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 6
 getContent
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
<?php
    namespace manager;
    use \manager\Repo;
    use \manager\sessionManager;
    class ResourceDispatcher{
        // Constantes
        public static $extension_config_path       = '/config/dispatcher-extensions.json';
        public static $parents_config_path         = '/config/dispatcher-tree.json';
        public static $supported_extensions;
        public static $supported_parents;
        // Attributs prives utiles (initialisation)
        private $header;
        private $path;
        private $flags;
        private $stylesheet;
        public $error;
        /* CONSTRUCTEUR & AMORCAGE DU DISPATCHER
        *
        * @url<String>                L'url courante
        * @view<Boolean>            Si VRAI, retourne header+contenu, sinon cree juste l'objet
        *
        * @return status<Boolean>    Retourne si oui ou non tout s'est bien passe
        *
        */
        public function __construct($url, $view=false){
            $this->error = ManagerError::Success;
            /* [0] On met a jour la configuration
            =====================================================*/
            // Extensions supportees
            $extensions_conf = json_decode( file_get_contents(__ROOT__.self::$extension_config_path), true );
            // Gestion de l'erreur de parsage
            if( $extensions_conf == null ){
                $this->error = ManagerError::ParsingFailed;
                return false;
            }
            self::$supported_extensions = $extensions_conf;
            // Dossiers supportes
            $parents_conf = json_decode( file_get_contents(__ROOT__.self::$parents_config_path), true );
            // Gestion de l'erreur de parsage
            if( $parents_conf == null ){
                $this->error = ManagerError::ParsingFailed;
                return false;
            }
            self::$supported_parents = $parents_conf;
            /* [1] On recupere les donnees de l'URL
            ==================================================*/
            $serialFlags = array_slice( explode('/',$url), 1 );
            /* [2] On check/cree les drapeaux avec ces donnees
            ==================================================*/
            if( !$this->createFlags($serialFlags) ){ // Creation des drapeaux
                $this->error = ManagerError::InvalidFlags;
                return false;
            }
            /* [3] On construit le chemin a partir des tags
            ==================================================*/
            if( !$this->buildPath() ){ // Construction du chemin
                $this->error = ManagerError::UnreachableResource;
                return false;
            }
            /* [4] On gere l'affichage pour l'appel externe/interne
            ==================================================*/
            if( $view ) // Appel externe
                $this->view();
            return true;
        }
        /* INCLUSION PHP D'UNE RESSOURCE UTILISANT LE DISPATCHER
        *
        * @route<String>                                     Route associee a une ressource
        *
        * @return content<*>                                 Retourne le contenu de la ressource
        *
        */
        public static function getResource($route){
            $instance = new ResourceDispatcher($route);
            return $instance->getContent();
        }
        /* FONCTION QUI VERIFIE LES DRAPEAUX
        *
        * @serialFlags<Array>                    Tableau a indice numerique
        *
        * @return correct<Boolean>                Retourne si oui ou non les drapeaux sont corrects
        *
        */
        private function createFlags($serialFlags){
            /* [1] Verification des flags (version serialisee)
            ======================================================*/
            $correct = true;
            // Verification du nombre de drapeaux () au moins 3
            $correct = $correct && count($serialFlags) >= 3;
            // Verification que l'extension est correcte
            $correct = $correct && array_key_exists($serialFlags[0], self::$supported_extensions);
            // Verification du filename
            $correct = $correct && preg_match('/^[\w_\.-]+$/i', $serialFlags[1]);
            // Verification du parent
            $correct = $correct && array_key_exists($serialFlags[2], self::$supported_parents);
            // Verification du sous-parent (optionnel)
            $opt_subParent = count($serialFlags) >= 4;
            if( $opt_subParent )
                $correct = $correct && preg_match('/^[\w_-]+$/i', $serialFlags[3]);
            // Verification de la couleur (optionnel)
            $opt_color = count($serialFlags) >= 5 && preg_match('/^[\da-f]{6,8}+$/i', $serialFlags[4]);
            if( !$correct )
                return false;
            /* [2] Creation (non serialisee) des flags
            ======================================================*/
            // Si tout se deroule bien, on cree les flags
            $this->flags = array(
                'extension' => $serialFlags[0],
                'filename'  => $serialFlags[1],
                'parent'    => $serialFlags[2]
            );
            // Ajout du sous-parent optionnel
            if( $opt_subParent )
                $this->flags['subparent'] = $serialFlags[3];
            // Ajout du color optionnel
            if( $opt_color )
                $this->flags['color'] = '#'.$serialFlags[4];
            return true;
        }
        /* FONCTION QUI CONSTRUIT LE CHEMIN A PARTIR DU PATH
        *
        * @return fileExists<Boolean>                        Retourne si oui ou non le fichier cible existe
        *
        * @format
        *
        *  f/extension/filename/parent/:subparent:/            (:OPT:)
        *
        */
        private function buildPath(){
            /* [1] On recupere le HEADER associe a l'extension
            ==========================================================*/
            // Si aucun header pour cet cle, on retourne une erreur
            if( !isset(self::$supported_extensions[$this->flags['extension']]) ) return false;
            // On recupere le header associe
            $header = self::$supported_extensions[$this->flags['extension']];
            /* [2] On recupere le chemin associe au parent
            ==========================================================*/
            // Si aucun dossier pour cet indice, on retourne une erreur
            if( !isset(self::$supported_parents[$this->flags['parent']]) ) return false;
            // On recupere le dossier associe
            $parent = self::$supported_parents[$this->flags['parent']];
            /* [3] Gestion du sous-parent optionnel
            ==========================================================*/
            $opt_subParent = (isset($this->flags['subparent'])) ? $this->flags['subparent'].'/' : '';
            /* [4] Gestion du color optionnel
            =========================================================*/
            $this->stylesheet = "";
            // si le color est defini
            if( isset($this->flags['color']) ){
                $this->stylesheet = "\n<style type='text/css'>\n";
                    $this->stylesheet .= "\t#stylisable{\n";
                        $this->stylesheet .= "\t\tfill: ".$this->flags['color']." !important;\n";
                        $this->stylesheet .= "\t\tfill-opacity: 1 !important;\n";
                    $this->stylesheet .= "\t}\n";
                $this->stylesheet .= "</style>";
            }
            /* [5] On definit le header
            ==========================================================*/
            $this->header = $header;
            /* [6] On construit le chemin
            ==========================================================*/
            $this->path = __ROOT__.$parent.'/'.$opt_subParent.$this->flags['filename'].'.'.$this->flags['extension'];
            /* [7] On retourne si le fichier existe ou non
            ==========================================================*/
            return @file_get_contents( $this->path ) != false;
        }
        /* FUNCTION QUI AFFICHE LA RESSOURCE EN QUESTION
        *
        */
        public function view(){
            // S'il y a eu une erreur en amont
            if( $this->error != ManagerError::Success )
                return false; // on retourne faux
            // On definit le header
            header('Content-Type: '.$this->header);
            // On recupere le contenu
            $content = file_get_contents($this->path);
            // On affiche tout
            echo str_replace( '</svg>', $this->stylesheet.'</svg>', $content );
        }
        /* FUNCTION QUI RETOURNE LE CONTENU DE LA RESSOURCE EN QUESTION
        *
        */
        public function getContent(){
            // S'il y a eu une erreur en amont
            if( $this->error != ManagerError::Success )
                return false; // on retourne faux
            // On inclut le contenu
            $content = file_get_contents($this->path);
            // On retourne tout
            return str_replace( '</svg>', $this->stylesheet.'</svg>', $content );
        }
    }
?>