44/**
55 * The main class that works wonders.
66 */
7- final class Make {
7+ final class AppBuilder {
8+
9+ private static $ config = array ();
10+
11+ /**
12+ * Sets the application namespace.
13+ *
14+ * @param string $appNamespace The root namespace of the application.
15+ *
16+ * @return void
17+ */
18+ public static function useNamespace ($ appNamespace ) {
19+ self ::$ config ['appNamespace ' ] = $ appNamespace ;
20+ }
21+
22+ /**
23+ * Sets base path.
24+ *
25+ * @param string $basePath The root path of the application.
26+ *
27+ * @return void
28+ */
29+ public static function useBasePath ($ basePath ) {
30+ self ::$ config ['basePath ' ] = $ basePath ;
31+ }
32+
33+ /**
34+ * Sets context of the HTTP request.
35+ *
36+ * @param HttpContextBase $httpContext The context to set.
37+ *
38+ * @return void
39+ */
40+ public static function useHttpContext ($ httpContext ) {
41+ self ::$ config ['httpContext ' ] = $ httpContext ;
42+ }
843
944 /**
10- * Magic!
45+ * Sets cache provider.
1146 *
12- * @param string $appNamespace Root namespace of the application.
13- * @param HttpContextBase $httpContext The context of HTTP request.
14- * @param string $basePath The base path of application.
47+ * @param CacheProvider $cacheProvider The cache provider to set.
1548 *
1649 * @return void
1750 */
18- public static function magic ($ appNamespace , $ httpContext = null , $ basePath = null ) {
19- self ::init ($ appNamespace , $ basePath );
51+ public static function useCache ($ cacheProvider ) {
52+ self ::$ config ['cacheProvider ' ] = $ cacheProvider ;
53+ }
54+
55+ /**
56+ * Sets routе provider.
57+ *
58+ * @param RouteProvider $routeProvider The route provider to set.
59+ *
60+ * @return void
61+ */
62+ public static function useRouter ($ routeProvider ) {
63+ self ::$ config ['routeProvider ' ] = $ routeProvider ;
64+ }
65+
66+ /**
67+ * Registers routes.
68+ *
69+ * @param callback $routes A function in which an instance of the route provider will be passed, through which routing rules are created.
70+ * For example:
71+ * AppBuilder::routes(function($routes) {
72+ * $routes->ignore('content/{*file}');
73+ * $routes->add('default', '{controller=Home}/{action=index}/{id?}');
74+ * });
75+ *
76+ * @returnv void
77+ */
78+ public static function routes ($ routes ) {
79+ self ::$ config ['routes ' ] = $ routes ;
80+ }
81+
82+ /**
83+ * Processes the current HTTP request.
84+ *
85+ * @return void
86+ */
87+ public static function build () {
88+ self ::init ();
2089 self ::include ();
2190
22- $ httpContext = self ::httpContext ($ httpContext );
23- $ route = self ::canRoute ($ httpContext );
91+ $ route = self ::canRoute ();
2492
2593 if ($ route !== false ) {
26- $ actionContext = self ::actionContext ($ httpContext , $ route );
94+ $ actionContext = self ::actionContext ($ route );
2795
2896 if (!self ::cached ($ actionContext )) {
2997 self ::filters ($ actionContext );
30- self ::headers ($ httpContext );
31- self ::validation ($ httpContext );
98+ self ::headers ();
99+ self ::validation ();
32100 self ::render ($ actionContext );
33101 }
34102 }
@@ -37,30 +105,82 @@ public static function magic($appNamespace, $httpContext = null, $basePath = nul
37105 /**
38106 * Adds headers.
39107 *
40- * @param HttpContextBase $httpContext The context of the request.
41- *
42108 * @return void
43109 */
44- private static function headers ($ httpContext ) {
45- $ response = $ httpContext ->getResponse ();
110+ private static function headers () {
111+ $ response = self :: $ config [ ' httpContext ' ] ->getResponse ();
46112 $ response ->addHeader ('X-Powered-By ' , Info::XPOWEREDBY );
47113 }
48114
49115 /**
50- * Performs the initialization of the engine.
51- *
52- * @param string $appNamespace Root namespace of the application.
53- * @param string $basePath Base path.
116+ * Performs the initialization of the builder.
54117 *
55118 * @return void
56119 */
57- private static function init ($ appNamespace , $ basePath = null ) {
58- if (empty ($ basePath )) {
59- $ basePath = getcwd ();
120+ private static function init () {
121+ if (empty (self ::$ config ['appNamespace ' ])) {
122+ throw new \Exception ('The root namespace for the application is required. To specify the namespace of your application, use the useNamespace method. The value must not be null or empty. ' );
123+ }
124+
125+ if (empty (self ::$ config ['basePath ' ])) {
126+ self ::$ config ['basePath ' ] = getcwd ();
127+ }
128+
129+ if (empty (self ::$ config ['routeProvider ' ])) {
130+ self ::$ config ['routeProvider ' ] = new DefaultRouteProvider ();
131+ }
132+ elseif (!self ::$ config ['routeProvider ' ] instanceof RouteProvider) {
133+ throw new \Exception ('The routeProvider type must be the base of "\PhpMvc\RouteProvider". ' );
134+ }
135+
136+ if (isset (self ::$ config ['routes ' ])) {
137+ if (is_callable (self ::$ config ['routes ' ])) {
138+ self ::$ config ['routes ' ](self ::$ config ['routeProvider ' ]);
139+ }
140+ elseif (is_array (self ::$ config ['routes ' ])) {
141+ $ provider = self ::$ config ['routeProvider ' ];
142+
143+ foreach (self ::$ config ['routes ' ][0 ] as $ route ) {
144+ $ provider ->add ($ route ->name , $ route ->template , $ route ->defaults , $ route ->constraints );
145+ }
146+
147+ if (count (self ::$ config ['routes ' ]) > 1 ) {
148+ foreach (self ::$ config ['routes ' ][1 ] as $ route ) {
149+ $ provider ->ingnore ($ route ->template , $ route ->constraints );
150+ }
151+ }
152+ }
153+ elseif (self ::$ config ['routes ' ] instanceof RouteCollection) {
154+ $ provider = self ::$ config ['routeProvider ' ];
155+
156+ foreach (self ::$ config ['routes ' ] as $ route ) {
157+ $ provider ->add ($ route ->name , $ route ->template , $ route ->defaults , $ route ->constraints );
158+ }
159+ }
160+ }
161+
162+ if (empty (self ::$ config ['cacheProvider ' ])) {
163+ self ::$ config ['cacheProvider ' ] = new CacheIdleProvider ();
164+ }
165+ elseif (!self ::$ config ['cacheProvider ' ] instanceof CacheProvider) {
166+ throw new \Exception ('The $cacheProvider type must be the base of "\PhpMvc\CacheProvider". ' );
167+ }
168+
169+ if (empty (self ::$ config ['httpContext ' ])) {
170+ $ info = new HttpContextInfo ();
171+ $ info ->routeProvider = self ::$ config ['routeProvider ' ];
172+ $ info ->cacheProvider = self ::$ config ['cacheProvider ' ];
173+ $ info ->request = new HttpRequest ();
174+ $ info ->response = new HttpResponse ();
175+
176+ self ::$ config ['httpContext ' ] = new HttpContext ($ info );
177+ }
178+ elseif (!self ::$ config ['httpContext ' ] instanceof HttpContextBase) {
179+ throw new \Exception ('The httpContext type must be the base of "\PhpMvc\HttpContextBase". ' );
60180 }
61181
62182 if (!defined ('PHPMVC_DS ' )) { define ('PHPMVC_DS ' , DIRECTORY_SEPARATOR ); }
63- if (!defined ('PHPMVC_ROOT_PATH ' )) { define ('PHPMVC_ROOT_PATH ' , $ basePath . PHPMVC_DS ); }
183+ if (!defined ('PHPMVC_ROOT_PATH ' )) { define ('PHPMVC_ROOT_PATH ' , self :: $ config [ ' basePath ' ] . PHPMVC_DS ); }
64184 if (!defined ('PHPMVC_CORE_PATH ' )) { define ('PHPMVC_CORE_PATH ' , __DIR__ .PHPMVC_DS ); }
65185 if (!defined ('PHPMVC_CONFIG_PATH ' )) { define ('PHPMVC_CONFIG_PATH ' , PHPMVC_ROOT_PATH . 'config ' . PHPMVC_DS ); }
66186 if (!defined ('PHPMVC_FILTER_PATH ' )) { define ('PHPMVC_FILTER_PATH ' , PHPMVC_ROOT_PATH . 'filters ' . PHPMVC_DS ); }
@@ -70,47 +190,24 @@ private static function init($appNamespace, $basePath = null) {
70190 if (!defined ('PHPMVC_SHARED_PATH ' )) { define ('PHPMVC_SHARED_PATH ' , PHPMVC_VIEW_PATH . 'shared ' . PHPMVC_DS ); }
71191 if (!defined ('PHPMVC_UPLOAD_PATH ' )) { define ('PHPMVC_UPLOAD_PATH ' , PHPMVC_ROOT_PATH . 'upload ' . PHPMVC_DS ); }
72192
73- // define('PHPMVC_APP_NAMESPACE', $appNamespace);
74-
75193 if (!defined ('PHPMVC_APP_NAMESPACE ' )) {
76- define ('PHPMVC_APP_NAMESPACE ' , $ appNamespace );
194+ define ('PHPMVC_APP_NAMESPACE ' , self :: $ config [ ' appNamespace ' ] );
77195 }
78- elseif (PHPMVC_APP_NAMESPACE !== $ appNamespace ) {
196+ elseif (PHPMVC_APP_NAMESPACE !== self :: $ config [ ' appNamespace ' ] ) {
79197 throw new \Exception ('Constant PHPMVC_CONTROLLER already defined. Re-define with other value is not possible. ' );
80198 }
81- }
82199
83- /**
84- * Initializes the HttpContext associated with the current request.
85- *
86- * @param HttpContextBase $httpContext The context of the request.
87- *
88- * @return HttpContextBase
89- */
90- private static function httpContext ($ httpContext = null ) {
91- // check request context
92- if (isset ($ httpContext )) {
93- if (!$ httpContext instanceof HttpContextBase) {
94- throw new \Exception ('The $httpContext type must be derived from "\PhpMvc\HttpContextBase". ' );
95- }
96- }
97- else {
98- $ httpContext = new HttpContext ();
99- }
100-
101- InternalHelper::setStaticPropertyValue ('\\PhpMvc \\HttpContext ' , 'current ' , $ httpContext );
102-
103- return $ httpContext ;
200+ InternalHelper::setStaticPropertyValue ('\\PhpMvc \\HttpContext ' , 'current ' , self ::$ config ['httpContext ' ]);
104201 }
105202
106203 /**
107204 * Looks for a suitable route and checks whether the request can be executed.
108205 *
109- * @param HttpContextBase $httpContext The context of the request.
110- *
111206 * @return Route|bool
112207 */
113- private static function canRoute ($ httpContext ) {
208+ private static function canRoute () {
209+ $ httpContext = self ::$ config ['httpContext ' ];
210+
114211 if ($ httpContext ->isIgnoredRoute ()) {
115212 $ request = $ httpContext ->getRequest ();
116213 $ response = $ httpContext ->getResponse ();
@@ -142,12 +239,13 @@ private static function canRoute($httpContext) {
142239 /**
143240 * Initializes the ActionContext associated with the current request and route.
144241 *
145- * @param HttpContextBase $httpContext The context of the request.
146242 * @param Route $route The route of the request.
147243 *
148244 * @return ActionContext
149245 */
150- private static function actionContext ($ httpContext , $ route ) {
246+ private static function actionContext ($ route ) {
247+ $ httpContext = self ::$ config ['httpContext ' ];
248+
151249 // TODO: kill constants
152250 if (!defined ('PHPMVC_CONTROLLER ' )) { define ('PHPMVC_CONTROLLER ' , ucfirst ($ route ->getValueOrDefault ('controller ' , 'Home ' ))); }
153251 if (!defined ('PHPMVC_ACTION ' )) { define ('PHPMVC_ACTION ' , $ route ->getValueOrDefault ('action ' , 'index ' )); }
@@ -163,7 +261,7 @@ private static function actionContext($httpContext, $route) {
163261 $ controllerClass = new \ReflectionClass ('\\' . PHPMVC_APP_NAMESPACE . '\\Controllers \\' . PHPMVC_CONTROLLER . 'Controller ' );
164262
165263 if (!$ controllerClass ->isSubclassOf ('\\PhpMvc \\Controller ' )) {
166- throw new \Exception ('The controller type must be derived from " \\PhpMvc \\Controller". ' );
264+ throw new \Exception ('The controller type must be the base of " \\PhpMvc \\Controller". ' );
167265 }
168266
169267 $ actionContextProperty = $ controllerClass ->getParentClass ()->getProperty ('actionContext ' );
@@ -540,7 +638,7 @@ private static function filters($actionContext) {
540638 $ filterClass = new \ReflectionClass ($ className );
541639
542640 if (!$ filterClass ->isSubclassOf ('\\PhpMvc \\ActionFilter ' )) {
543- throw new \Exception ('The filter type must be derived from "\PhpMvc\ActionFilter". ' );
641+ throw new \Exception ('The filter type must be the base of "\PhpMvc\ActionFilter". ' );
544642 }
545643
546644 if ($ filterClass ->getConstructor () != null ) {
@@ -560,11 +658,9 @@ private static function filters($actionContext) {
560658 /**
561659 * Checks the request and throws an exception if the request contains dangerous data.
562660 *
563- * @param HttpContextBase $httpContext The context of the request.
564- *
565661 * @return void
566662 */
567- private static function validation ($ httpContext ) {
663+ private static function validation () {
568664 if (substr (PHPMVC_ACTION , 0 , 2 ) == '__ ' ) {
569665 throw new \Exception ('Action names can not begin with a "_". ' );
570666 }
0 commit comments