Browse code

More initial feed...

RafaƂ Szklarczyk authored on 16/05/2019 22:26:29
Showing 3 changed files
... ...
@@ -1,4 +1,4 @@
1
-<?
1
+<?php
2 2
 
3 3
 namespace elanpl\L3;
4 4
 
... ...
@@ -16,8 +16,8 @@ class Request{
16 16
         $this->Method = $_SERVER['REQUEST_METHOD'];
17 17
         $this->Accept = $_SERVER['HTTP_ACCEPT'];
18 18
         $this->AcceptTypes = $this->ParseAccept($this->Accept);
19
-        $this->AcceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
20
-        $this->UserAgent = $_SERVER['HTTP_USERAGENT'];
19
+        $this->AcceptLanguage = isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])?$_SERVER['HTTP_ACCEPT_LANGUAGE']:"";
20
+        $this->UserAgent = $_SERVER['HTTP_USER_AGENT'];
21 21
         if(function_exists('apache_request_headers')){
22 22
             $this->Headers = apache_request_headers();
23 23
         }
24 24
new file mode 100644
... ...
@@ -0,0 +1,148 @@
1
+<?php
2
+
3
+namespace elanpl\L3;
4
+
5
+class Router{
6
+
7
+    //protected static $_instance; // object instance (for fluent api)
8
+    protected static $routes; // The defined routes collection
9
+    protected static $parsedParameters; // Parameters parsed from Request Path
10
+    protected static $depth; // Number of nested nodes in Request Path
11
+    protected static $routeNameIndex; // An array with elements that reference to the routes ordered by a route names
12
+    public static $RouteInfo; // The RouteInfo objcet if the route was matched
13
+
14
+    public function __construct()
15
+    {
16
+        //if(!isset(self::$_instance)) self::$_instance = new self;
17
+        if(!isset(self::$routes)) self::$routes = array(); 
18
+        if(!isset(self::$routeNameIndex)) self::$routeNameIndex= array();
19
+    }
20
+
21
+    public static function add($Method, $Path, $Result, $Name = ''){
22
+        self::$routes[] = new RouteInfo($Method, $Path, $Result, $Name);
23
+        if(isset($Name)&&$Name!='') self::$routeNameIndex[$Name] = &self::$routes[count(self::$routes)-1];
24
+        return new self;
25
+    }
26
+
27
+    public static function get($Path, $Result, $Name = ''){
28
+        return self::add('GET', $Path, $Result, $Name);
29
+    }
30
+
31
+    public static function post($Path, $Result, $Name = ''){
32
+        return self::add('POST', $Path, $Result, $Name);
33
+    }
34
+
35
+    public static function put($Path, $Result, $Name = ''){
36
+        return self::add('PUT', $Path, $Result, $Name);
37
+    }
38
+
39
+    public static function patch($Path, $Result, $Name = ''){
40
+        return self::add('PATCH', $Path, $Result, $Name);
41
+    }
42
+
43
+    public static function delete($Path, $Result, $Name = ''){
44
+        return self::add('DELETE', $Path, $Result, $Name);
45
+    }
46
+
47
+    public static function any($Path, $Result, $Name = ''){
48
+        return self::add('ANY', $Path, $Result, $Name);
49
+    }
50
+
51
+    public static function AddBeforeAction($event_handler){
52
+        self::$routes[count(self::$routes)-1]->AddBeforeAction($event_handler);
53
+        return new self;
54
+    }
55
+
56
+    public static function AddAfterAction($event_handler){
57
+        self::$routes[count(self::$routes)-1]->AddAfterAction($event_handler);
58
+        return new self;
59
+    }
60
+
61
+    public static function AddAfterResult($event_handler){
62
+        self::$routes[count(self::$routes)-1]->AddAfterAction($event_handler);
63
+        return new self;
64
+    }
65
+
66
+    public static function match($Request){
67
+
68
+        $auri = explode('/', trim($Request->Path, "/ \t\n\r\0\x0B"));
69
+        $curi = count($auri);
70
+			
71
+        foreach (self::$routes as $routeInfo) {
72
+            
73
+            $route = $routeInfo->Path;
74
+            $method = $routeInfo->Method;
75
+            if($method=='ANY' || strpos($Request->Method,$method)!==false){
76
+                $aroute = explode('/', trim($route, "/ \t\n\r\0\x0B"));
77
+                //print_r($aroute);
78
+                if($curi==count($aroute)){ //compare path element count
79
+                    //optimistic assumption :)
80
+                    $matchResult = true;
81
+                    for($i = 0; $i<$curi; $i++){
82
+                        $pathPartName = trim($aroute[$i],'{}');
83
+                        if($aroute[$i]==$pathPartName){
84
+                            if($auri[$i]!=$pathPartName){
85
+                                //echo "diffrence found";
86
+                                $matchResult = false;
87
+                                break;
88
+                            }
89
+                        }
90
+                        else{ // {...} found -> catch $uri variable
91
+                            $value = $auri[$i];
92
+                            $valueKey = explode(':', $pathPartName);
93
+                            //validation
94
+                            if(isset($valueKey[1]) && $valueKey[1]=='int'){
95
+                                $value = intval($value);
96
+                            }
97
+                            //value store...
98
+                            self::$parsedParameters[$valueKey[0]] = $value;
99
+                        }
100
+                    }
101
+                    if($matchResult){ // match found
102
+                        self::$depth = $curi;
103
+                        self::$RouteInfo = $routeInfo;
104
+                        return $routeInfo->Result;
105
+                    }
106
+                }
107
+            }
108
+        }
109
+        return false;
110
+    }
111
+
112
+    public static function link($name, $parameters){
113
+        $route = self::$routeNameIndex[$name];
114
+        $fields = array_keys($parameters);
115
+        $values = array_values($parameters);
116
+        array_walk($fields, function (&$item, $key){
117
+            $item = "/\{".$item."\}/";
118
+        });
119
+        return preg_replace($fields, $values, $route->Path);
120
+    }
121
+
122
+    public function __get($name)
123
+    {
124
+        if($name=="routes") return self::$routes;
125
+        if($name=="parsedParameters") return self::$parsedParameters;
126
+        if($name=="depth") return self::$depth;
127
+        if($name=="RouteInfo") return self::$RouteInfo;
128
+    }
129
+
130
+    public function __call($name, $arguments)
131
+    {
132
+        if($name == 'GetParameter'){
133
+            return self::$parsedParameters[$arguments[0]];
134
+        }
135
+        // Note: value of $name is case sensitive.
136
+        $allowed_methods = ['add', 'post', 'any', 'get', 'match', 'AddBeforeAction', 'AddAfterAction', 'AddAfterResult'];
137
+
138
+        if(in_array($name, $allowed_methods)){
139
+            $the_method = new \ReflectionMethod($this, $name);
140
+            $the_method->invokeArgs(NULL,$arguments);
141
+        }
142
+        else{
143
+            throw new \Exception("Call undefined or inaccesible method ".get_class($this)."::$name");
144
+        }
145
+        
146
+    }
147
+
148
+}
0 149
\ No newline at end of file
1 150
new file mode 100644
... ...
@@ -0,0 +1,85 @@
1
+<?php
2
+
3
+namespace elanpl\L3;
4
+
5
+class Serialization{
6
+    protected static $serializers; //registered serializers dictionary
7
+
8
+    public function __construct()
9
+    {
10
+        if(!isset(self::$serializers)) self::$serializers = array(); 
11
+    }
12
+
13
+    public static function Register($ContentType, $Serializer, $ViewModelClass = null){
14
+        if(isset($ViewModelClass) && $ViewModelClass!=''){
15
+            $class_key = $ViewModelClass.'|';
16
+        }
17
+        else{
18
+            $class_key = '';
19
+        }
20
+        self::$serializers[$class_key.$ContentType] = $Serializer;
21
+    }
22
+
23
+    public function Match($AcceptTypes, $ViewModel=null){
24
+        if(isset($ViewModel)){
25
+            if(is_object($ViewModel)){
26
+                $ViewModelClass = get_class($ViewModel);
27
+            }
28
+            if(is_string($ViewModel)){
29
+                $ViewModelClass = $ViewModel;
30
+            }
31
+        }
32
+
33
+        if(is_array($AcceptTypes)){
34
+            $RegisteredTypes = array_keys(self::$serializers);
35
+
36
+            foreach ($AcceptTypes as $type){
37
+                //Dedicated config for ViewModel class first...
38
+                if(array_key_exists($ViewModelClass."|".$type, self::$serializers)){
39
+                    return $type;
40
+                }
41
+                foreach($RegisteredTypes as $rtype_with_class){
42
+                    $rtype_parts = explode("|", $rtype_with_class);
43
+                    if(count($rtype_parts)==2){
44
+                        $rclass = $rtype_parts[0];
45
+                        $t = explode("/", $type);
46
+                        $rt = explode("/", $rtype_parts[1]);
47
+                        if($rclass==$ViewModelClass && ($t[0]=="*" || $rt[0]=="*" || $t[0]==$rt[0]) && ($t[1]=="*" || $rt[1]=="*" || $t[1]==$rt[1])){
48
+                            return $rtype_with_class;
49
+                        }
50
+                    }
51
+                }
52
+
53
+                //Then check configs without the ViewModel class name
54
+                if(array_key_exists($type, self::$serializers)){
55
+                    return $type;
56
+                }
57
+                foreach($RegisteredTypes as $rtype){
58
+                    $t = explode("/", $type);
59
+                    $rt = explode("/", $rtype);
60
+                    if(($t[0]=="*" || $rt[0]=="*" || $t[0]==$t[0]) && ($t[1]=="*" || $rt[1]=="*" || $t[1]==$t[1])){
61
+                        return $rtype;
62
+                    }
63
+                }
64
+            }
65
+        }
66
+        return false;
67
+    }
68
+
69
+    public function Serialize($ContentType, $ViewModel){
70
+        if(isset(Serialization::$serializers[get_class($ViewModel).'|'.$ContentType])){
71
+            $serializerClass = Serialization::$serializers[get_class($ViewModel).'|'.$ContentType];
72
+        }
73
+        else if(isset(Serialization::$serializers[$ContentType])){
74
+            $serializerClass = Serialization::$serializers[$ContentType];
75
+        }
76
+
77
+        if(isset($serializerClass)){
78
+            $serializer = new $serializerClass();
79
+            return $serializer->Serialize($ViewModel);
80
+        }
81
+        else{
82
+            return null;
83
+        }
84
+    }
85
+}
0 86
\ No newline at end of file