├── README.md ├── composer.json └── src └── TinyLara ├── Contracts ├── BindingResolutionException.php ├── Kernel.php └── Pipeline.php ├── Http ├── Request.php └── Response.php ├── Log ├── LogServiceProvider.php └── LogWriter.php ├── Pipeline └── Pipeline.php ├── Routing └── Router.php ├── Stone ├── Application.php └── Bootstrap │ ├── LoadConfiguration.php │ └── RegisterProviders.php ├── Support └── Facades │ ├── Facade.php │ └── Log.php ├── Validation ├── Validator.php └── reasons.php └── View └── View.php /README.md: -------------------------------------------------------------------------------- 1 | TinyLara Framework for version 2 2 | ------- 3 | 4 | 5 | ### License 6 | 7 | MIT license. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tinylara/framework", 3 | "description": "Framework for TinyLara version 2", 4 | "license": "MIT", 5 | "require": { 6 | "php": ">=5.4.0" 7 | }, 8 | "authors": [ 9 | { 10 | "name": "John Lui", 11 | "email": "wenhanlv@gmail.com" 12 | } 13 | ], 14 | "autoload": { 15 | "psr-4": {"TinyLara\\": "src/TinyLara/"} 16 | }, 17 | "extra": { 18 | "branch-alias": { 19 | "dev-master": "2.0-dev" 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/TinyLara/Contracts/BindingResolutionException.php: -------------------------------------------------------------------------------- 1 | response = $response; 14 | } 15 | } -------------------------------------------------------------------------------- /src/TinyLara/Http/Response.php: -------------------------------------------------------------------------------- 1 | return); 18 | } 19 | } -------------------------------------------------------------------------------- /src/TinyLara/Log/LogServiceProvider.php: -------------------------------------------------------------------------------- 1 | app = $app; 13 | } 14 | 15 | public function register() 16 | { 17 | $this->app->singleton('log', function () { 18 | return $this->createLogger(); 19 | }); 20 | } 21 | 22 | public function createLogger() 23 | { 24 | $log = new \TinyLara\Log\LogWriter; 25 | return $log; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/TinyLara/Log/LogWriter.php: -------------------------------------------------------------------------------- 1 | log = new Logger('local'); 14 | $this->log->pushHandler(new StreamHandler(BASE_PATH.'/logs/app.log', Logger::DEBUG)); 15 | } 16 | private function process($level, $data) 17 | { 18 | if ( is_array($data) || is_object($data) ) { 19 | $data = json_encode($data); 20 | } else { 21 | $data = (String) $data; 22 | } 23 | $funcName = 'add'.ucfirst($level); 24 | $this->log->$funcName($data); 25 | } 26 | public function __call($method, $parameters) 27 | { 28 | if ( !in_array($method, ['debug', 'info', 'notice', 'warning', 'error', 'critical', 'alert', 'emergency']) ) { 29 | throw new \UnexpectedValueException("Log level [$method] does not exist!"); 30 | } else { 31 | $log = new self; 32 | $log->process($method, $parameters); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/TinyLara/Pipeline/Pipeline.php: -------------------------------------------------------------------------------- 1 | container = $container; 20 | } 21 | 22 | public function send($passable) 23 | { 24 | $this->passable = $passable; 25 | 26 | return $this; 27 | } 28 | 29 | public function through($pipes) 30 | { 31 | $this->pipes = is_array($pipes) ? $pipes : func_get_args(); 32 | 33 | return $this; 34 | } 35 | 36 | public function via($method) 37 | { 38 | $this->method = $method; 39 | 40 | return $this; 41 | } 42 | 43 | public function then(Closure $destination) 44 | { 45 | $pipeline = array_reduce( 46 | array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination) 47 | ); 48 | return $pipeline($this->passable); 49 | } 50 | 51 | protected function prepareDestination(Closure $destination) 52 | { 53 | return function ($passable) use ($destination) { 54 | return $destination($passable); 55 | }; 56 | } 57 | 58 | public function carry() 59 | { 60 | return function ($stack, $pipe) { 61 | return function ($passable) use ($stack, $pipe) { 62 | list($name, $parameters) = $this->parsePipeString($pipe); 63 | $pipe = $this->container->make($name); 64 | $parameters = array_merge([$passable, $stack], $parameters); 65 | return $pipe->{$this->method}(...$parameters); 66 | }; 67 | }; 68 | } 69 | protected function parsePipeString($pipe) 70 | { 71 | list($name, $parameters) = array_pad(explode(':', $pipe, 2), 2, []); 72 | 73 | if (is_string($parameters)) { 74 | $parameters = explode(',', $parameters); 75 | } 76 | 77 | return [$name, $parameters]; 78 | } 79 | } -------------------------------------------------------------------------------- /src/TinyLara/Routing/Router.php: -------------------------------------------------------------------------------- 1 | '[^/]+', 29 | ':num' => '[0-9]+', 30 | ':all' => '.*' 31 | ); 32 | 33 | public static $error_callback; 34 | 35 | /** 36 | * add filter for your routes 37 | */ 38 | public static function filter($filter, $result) { 39 | if ($filter()) { 40 | $result(); 41 | } 42 | } 43 | 44 | /** 45 | * Defines a route w/ callback and method 46 | */ 47 | public static function __callstatic($method, $params) 48 | { 49 | 50 | if ( $method == 'group' ) { 51 | if ( isset($params[0]['namespace']) ) { 52 | self::$namespace[] = $params[0]['namespace']; 53 | } 54 | if ( isset($params[0]['prefix']) ) { 55 | self::$prefix[] = $params[0]['prefix']; 56 | } 57 | $callback = $params[1]; 58 | $callback(); 59 | if ( isset($params[0]['namespace']) ) { 60 | array_pop(self::$namespace); 61 | } 62 | if ( isset($params[0]['prefix']) ) { 63 | array_pop(self::$prefix); 64 | } 65 | }else { 66 | $nowPrefix = implode('/', self::$prefix); 67 | if ( $nowPrefix ) { 68 | $nowPrefix .= '/'; 69 | } 70 | $nowNamespace = implode('\\',self::$namespace); 71 | if ( $nowNamespace ) { 72 | $nowNamespace .= '\\'; 73 | } 74 | $uri = $nowPrefix.$params[0]; 75 | 76 | 77 | if( !is_object($params[1]) ) { 78 | $callback = self::$baseNamespace.$nowNamespace.$params[1]; 79 | }else { 80 | $callback = $params[1]; 81 | } 82 | 83 | if ( $method == 'any' ) { 84 | self::pushToArray($uri, 'get', $callback); 85 | self::pushToArray($uri, 'post', $callback); 86 | } else { 87 | self::pushToArray($uri, $method, $callback); 88 | } 89 | } 90 | } 91 | 92 | /** 93 | * Push route items to class arrays 94 | * 95 | */ 96 | public static function pushToArray($uri, $method, $callback) 97 | { 98 | array_push(self::$routes, $uri); 99 | array_push(self::$methods, strtoupper($method)); 100 | array_push(self::$callbacks, $callback); 101 | } 102 | 103 | /** 104 | * Defines callback if route is not found 105 | */ 106 | public static function error($callback) 107 | { 108 | self::$error_callback = $callback; 109 | } 110 | 111 | /** 112 | * Runs the callback for the given request 113 | * 114 | * $after: Processor After. It will process the value returned by Controller. 115 | * Example: View@process 116 | * 117 | */ 118 | public static function dispatch() 119 | { 120 | $uri = self::detect_uri(); 121 | $method = $_SERVER['REQUEST_METHOD']; 122 | $searches = array_keys(static::$patterns); 123 | $replaces = array_values(static::$patterns); 124 | $routeMatch = false; 125 | // check if route is defined without regex 126 | if (in_array($uri, self::$routes)) { 127 | $route_pos = array_keys(self::$routes, $uri); 128 | $route = current($route_pos); 129 | foreach ($route_pos as $route) { 130 | 131 | if ($routeMatch) { 132 | break; 133 | } 134 | 135 | if (self::$methods[$route] == $method) { 136 | $routeMatch = true; 137 | 138 | //if route is not an object 139 | if(!is_object(self::$callbacks[$route])){ 140 | 141 | //grab all parts based on a / separator 142 | $parts = explode('/',self::$callbacks[$route]); 143 | //collect the last index of the array 144 | $last = end($parts); 145 | //grab the controller name and method call 146 | $segments = explode('@',$last); 147 | //instanitate controller 148 | $controller = new $segments[0](); 149 | 150 | //call method 151 | $methodName = $segments[1]; 152 | return $controller->$methodName(); 153 | } else { 154 | //call closure 155 | call_user_func(self::$callbacks[$route]); 156 | } 157 | } 158 | } 159 | } else { 160 | // check if defined with regex 161 | 162 | $uriForPreg = $uri; 163 | if (strpos($uri, '/') !== 0) { 164 | $uriForPreg = '/'.$uriForPreg; 165 | } 166 | 167 | foreach (self::$routes as $key => $route) { 168 | 169 | if ($routeMatch) { 170 | break; 171 | } 172 | 173 | if (strpos($route, ':') !== false) { 174 | $route = str_replace($searches, $replaces, $route); 175 | } 176 | if (preg_match('#^' . $route . '$#', $uriForPreg, $matched)) { 177 | if (self::$methods[$key] == $method) { 178 | $routeMatch = true; 179 | 180 | if(!is_object(self::$callbacks[$key])){ 181 | 182 | //grab all parts based on a / separator 183 | $parts = explode('/',self::$callbacks[$key]); 184 | 185 | //collect the last index of the array 186 | $last = end($parts); 187 | 188 | //grab the controller name and method call 189 | $segments = explode('@',$last); 190 | 191 | //instanitate controller 192 | $controller = new $segments[0](); 193 | 194 | //call method and pass any extra parameters to the method 195 | $methodName = $segments[1]; 196 | return $controller->$methodName(...$matched); 197 | } else { 198 | $realMatched = []; 199 | foreach ($matched as $m) { 200 | if (strpos($m, '/') === 0) { 201 | $m = substr($m, 1); 202 | } 203 | 204 | // just for :all with uri of 'foo/bar' 205 | // this code makes blow strange `call_user_func_array` with `...$realMatched` 206 | // please do not be confused 207 | $realMatched[] = explode('/', $m); 208 | } 209 | call_user_func_array(self::$callbacks[$key], ...$realMatched); 210 | } 211 | 212 | } 213 | } 214 | } 215 | } 216 | 217 | // run the error callback if the route was not found 218 | if ($routeMatch == false) { 219 | if (!self::$error_callback) { 220 | self::$error_callback = function() { 221 | header($_SERVER['SERVER_PROTOCOL']." 404 Not Found"); 222 | echo '404'; 223 | }; 224 | } 225 | call_user_func(self::$error_callback); 226 | } 227 | } 228 | 229 | // detect true URI, inspired by CodeIgniter 2 230 | private static function detect_uri() 231 | { 232 | $uri = $_SERVER['REQUEST_URI']; 233 | if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) { 234 | $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME'])); 235 | } elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) { 236 | $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); 237 | } 238 | if ($uri == '/' || empty($uri)) { 239 | return '/'; 240 | } 241 | $uri = parse_url($uri, PHP_URL_PATH); 242 | return str_replace(array('//', '../'), '/', trim($uri, '/')); 243 | } 244 | } -------------------------------------------------------------------------------- /src/TinyLara/Stone/Application.php: -------------------------------------------------------------------------------- 1 | path = $path; 27 | 28 | $this->registerBaseBindings(); 29 | 30 | $this->registerBaseServiceProviders(); 31 | 32 | // $this->registerCoreContainerAliases(); 33 | } 34 | 35 | protected function registerBaseBindings() 36 | { 37 | $this->instances['app'] = $this; 38 | } 39 | 40 | protected function registerBaseServiceProviders() 41 | { 42 | $provider = $this->resolveProvider(new LogServiceProvider($this)); 43 | if (method_exists($provider, 'register')) { 44 | $provider->register(); 45 | } 46 | 47 | $this->markAsRegistered($provider); 48 | 49 | return $provider; 50 | } 51 | protected function markAsRegistered($provider) 52 | { 53 | $this->serviceProviders[] = $provider; 54 | 55 | $this->loadedProviders[get_class($provider)] = true; 56 | } 57 | public function resolveProvider($provider) 58 | { 59 | return new $provider($this); 60 | } 61 | 62 | public function singleton($abstract, $concrete = null) 63 | { 64 | $this->bind($abstract, $concrete, true); 65 | } 66 | 67 | public function bind($abstract, $concrete = null, $shared = false) 68 | { 69 | if (! $concrete instanceof Closure) { 70 | $concrete = $this->getClosure($abstract, $concrete); 71 | } 72 | 73 | $this->bindings[$abstract] = compact('concrete', 'shared'); 74 | } 75 | 76 | protected function getClosure($abstract, $concrete) 77 | { 78 | return function ($container, $parameters = []) use ($abstract, $concrete) { 79 | $method = ($abstract == $concrete) ? 'build' : 'make'; 80 | 81 | return $container->$method($concrete, $parameters); 82 | }; 83 | } 84 | 85 | public function make($abstract, array $parameters = []) 86 | { 87 | if (isset($this->instances[$abstract])) { 88 | return $this->instances[$abstract]; 89 | } 90 | $concrete = $this->getConcrete($abstract); 91 | 92 | if ($this->isBuildable($concrete, $abstract)) { 93 | $object = $this->build($concrete, $parameters); 94 | } else { 95 | $object = $this->make($concrete, $parameters); 96 | } 97 | 98 | if ($this->isShared($abstract)) { 99 | $this->instances[$abstract] = $object; 100 | } 101 | 102 | $this->resolved[$abstract] = true; 103 | 104 | return $object; 105 | } 106 | 107 | public function build($concrete, array $parameters = []) 108 | { 109 | if ($concrete instanceof Closure) { 110 | return $concrete($this, $parameters); 111 | } 112 | $reflector = new ReflectionClass($concrete); 113 | 114 | $this->buildStack[] = $concrete; 115 | 116 | $constructor = $reflector->getConstructor(); 117 | 118 | // If there are no constructors, that means there are no dependencies then 119 | // we can just resolve the instances of the objects right away, without 120 | // resolving any other types or dependencies out of these containers. 121 | if (is_null($constructor)) { 122 | array_pop($this->buildStack); 123 | 124 | return new $concrete; 125 | } 126 | 127 | $dependencies = $constructor->getParameters(); 128 | 129 | // Once we have all the constructor's parameters we can create each of the 130 | // dependency instances and then use the reflection instances to make a 131 | // new instance of this class, injecting the created dependencies in. 132 | $parameters = $this->keyParametersByArgument( 133 | $dependencies, $parameters 134 | ); 135 | 136 | $instances = $this->getDependencies( 137 | $dependencies, $parameters 138 | ); 139 | 140 | array_pop($this->buildStack); 141 | 142 | return $reflector->newInstanceArgs($instances); 143 | } 144 | 145 | protected function keyParametersByArgument(array $dependencies, array $parameters) 146 | { 147 | foreach ($parameters as $key => $value) { 148 | if (is_numeric($key)) { 149 | unset($parameters[$key]); 150 | 151 | $parameters[$dependencies[$key]->name] = $value; 152 | } 153 | } 154 | 155 | return $parameters; 156 | } 157 | protected function getDependencies(array $parameters, array $primitives = []) 158 | { 159 | $dependencies = []; 160 | 161 | foreach ($parameters as $parameter) { 162 | $dependency = $parameter->getClass(); 163 | 164 | // If the class is null, it means the dependency is a string or some other 165 | // primitive type which we can not resolve since it is not a class and 166 | // we will just bomb out with an error since we have no-where to go. 167 | if (array_key_exists($parameter->name, $primitives)) { 168 | $dependencies[] = $primitives[$parameter->name]; 169 | } elseif (is_null($dependency)) { 170 | $dependencies[] = $this->resolveNonClass($parameter); 171 | } else { 172 | $dependencies[] = $this->resolveClass($parameter); 173 | } 174 | } 175 | 176 | return $dependencies; 177 | } 178 | protected function resolveNonClass(ReflectionParameter $parameter) 179 | { 180 | if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->name))) { 181 | if ($concrete instanceof Closure) { 182 | return call_user_func($concrete, $this); 183 | } else { 184 | return $concrete; 185 | } 186 | } 187 | 188 | if ($parameter->isDefaultValueAvailable()) { 189 | return $parameter->getDefaultValue(); 190 | } 191 | 192 | $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}"; 193 | 194 | throw new BindingResolutionException($message); 195 | } 196 | protected function resolveClass(ReflectionParameter $parameter) 197 | { 198 | try { 199 | return $this->make($parameter->getClass()->name); 200 | } 201 | 202 | // If we can not resolve the class instance, we will check to see if the value 203 | // is optional, and if it is we will return the optional parameter value as 204 | // the value of the dependency, similarly to how we do this with scalars. 205 | catch (BindingResolutionException $e) { 206 | if ($parameter->isOptional()) { 207 | return $parameter->getDefaultValue(); 208 | } 209 | 210 | throw $e; 211 | } 212 | } 213 | 214 | protected function getConcrete($abstract) 215 | { 216 | if (! is_null($concrete = $this->getContextualConcrete($abstract))) { 217 | return $concrete; 218 | } 219 | 220 | // If we don't have a registered resolver or concrete for the type, we'll just 221 | // assume each type is a concrete name and will attempt to resolve it as is 222 | // since the container should be able to resolve concretes automatically. 223 | if (! isset($this->bindings[$abstract])) { 224 | return $abstract; 225 | } 226 | 227 | return $this->bindings[$abstract]['concrete']; 228 | } 229 | protected function getContextualConcrete($abstract) 230 | { 231 | if (isset($this->contextual[end($this->buildStack)][$abstract])) { 232 | return $this->contextual[end($this->buildStack)][$abstract]; 233 | } 234 | } 235 | protected function isBuildable($concrete, $abstract) 236 | { 237 | return $concrete === $abstract || $concrete instanceof Closure; 238 | } 239 | public function isShared($abstract) 240 | { 241 | if (isset($this->instances[$abstract])) { 242 | return true; 243 | } 244 | 245 | if (! isset($this->bindings[$abstract]['shared'])) { 246 | return false; 247 | } 248 | 249 | return $this->bindings[$abstract]['shared'] === true; 250 | } 251 | 252 | public function bootstrapWith(array $bootstrappers) 253 | { 254 | $this->hasBeenBootstrapped = true; 255 | 256 | foreach ($bootstrappers as $bootstrapper) { 257 | // $this['events']->fire('bootstrapping: '.$bootstrapper, [$this]); 258 | 259 | $this->make($bootstrapper)->bootstrap($this); 260 | 261 | // $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]); 262 | } 263 | } 264 | public function hasBeenBootstrapped() 265 | { 266 | return $this->hasBeenBootstrapped; 267 | } 268 | 269 | public function offsetExists($key) 270 | { 271 | return $this->bound($key); 272 | } 273 | public function offsetGet($key) 274 | { 275 | return $this->make($key); 276 | } 277 | public function offsetSet($key, $value) 278 | { 279 | // If the value is not a Closure, we will make it one. This simply gives 280 | // more "drop-in" replacement functionality for the Pimple which this 281 | // container's simplest functions are base modeled and built after. 282 | if (! $value instanceof Closure) { 283 | $value = function () use ($value) { 284 | return $value; 285 | }; 286 | } 287 | 288 | $this->bind($key, $value); 289 | } 290 | public function offsetUnset($key) 291 | { 292 | $key = $this->normalize($key); 293 | 294 | unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]); 295 | } 296 | } -------------------------------------------------------------------------------- /src/TinyLara/Stone/Bootstrap/LoadConfiguration.php: -------------------------------------------------------------------------------- 1 | pushHandler(new \Monolog\Handler\StreamHandler(BASE_PATH.'/logs/app.log', \Monolog\Logger::ERROR)); 21 | // whoops: php errors for cool kids 22 | $whoops = new \Whoops\Run; 23 | $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); 24 | // $whoops->pushHandler(new \Whoops\Handler\PlainTextHandler($monolog)); 25 | $whoops->register(); 26 | 27 | // BASE_URL 28 | $config = require BASE_PATH.'/config/config.php'; 29 | define('BASE_URL', $config['base_url']); 30 | 31 | mb_internal_encoding('UTF-8'); 32 | 33 | // TIME_ZONE 34 | date_default_timezone_set($config['time_zone']); 35 | 36 | // Eloquent ORM 37 | $capsule = new Capsule; 38 | $capsule->addConnection(require BASE_PATH.'/config/database.php'); 39 | $capsule->bootEloquent(); 40 | 41 | // View Loader 42 | // 43 | class_alias('TinyLara\Routing\Router', 'Route'); 44 | class_alias('\TinyLara\View\View','View'); 45 | } 46 | } -------------------------------------------------------------------------------- /src/TinyLara/Stone/Bootstrap/RegisterProviders.php: -------------------------------------------------------------------------------- 1 | $facadeName) { 18 | class_alias($facadeName, $className); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/TinyLara/Support/Facades/Facade.php: -------------------------------------------------------------------------------- 1 | $method(...$args); 18 | } 19 | 20 | public static function setFacadeApplication($app) 21 | { 22 | static::$app = $app; 23 | } 24 | } -------------------------------------------------------------------------------- /src/TinyLara/Support/Facades/Log.php: -------------------------------------------------------------------------------- 1 | data = $data; 17 | $this->rules = $rules; 18 | $this->reasons = require __DIR__.'/reasons.php'; 19 | 20 | $this->fire(); 21 | } 22 | 23 | public function fire() 24 | { 25 | foreach ($this->rules as $attribute => $rule) { 26 | foreach (explode('|', $rule) as $item) { 27 | $detial = explode(':', $item); 28 | if ( count( $detial ) > 1 ) { 29 | $reason = call_user_func_array([$this, $detial[0]], [$this->data[$attribute], $detial[1]]); 30 | } else { 31 | $reason = $this->$item($this->data[$attribute]); 32 | } 33 | if ( $reason !== true ) { 34 | $this->errors[] = str_replace(':attribute', $attribute, $reason); 35 | } 36 | } 37 | } 38 | if ( count($this->errors) ) { 39 | $this->success = false; 40 | } 41 | } 42 | 43 | protected function required($value) 44 | { 45 | return !$value ? $this->reasons['required'] : true; 46 | } 47 | protected function email($value) 48 | { 49 | return filter_var($value, FILTER_VALIDATE_EMAIL) ? true : $this->reasons['email']; 50 | } 51 | protected function min($value, $min) 52 | { 53 | return mb_strlen($value, 'UTF-8') >= $min ? true : str_replace(':min', $min, $this->reasons['min']); 54 | } 55 | protected function max($value, $max) 56 | { 57 | return mb_strlen($value, 'UTF-8') <= $max ? true : str_replace(':max', $max, $this->reasons['max']); 58 | } 59 | protected function numeric($value) 60 | { 61 | return is_numeric($value) ? true : $this->reasons['numeric']; 62 | } 63 | protected function integer($value) 64 | { 65 | return filter_var($value, FILTER_VALIDATE_INT) !== false ? true : $this->reasons['integer']; 66 | } 67 | 68 | public function __call($method, $parameters) 69 | { 70 | throw new \UnexpectedValueException("Validate rule [$method] does not exist!"); 71 | } 72 | } -------------------------------------------------------------------------------- /src/TinyLara/Validation/reasons.php: -------------------------------------------------------------------------------- 1 | 'The :attribute format is invalid.', 5 | 'min' => 'The :attribute must be at least :min.', 6 | 'max' => 'The :attribute may not be greater than :max.', 7 | 'required' => 'The :attribute field is required.', 8 | 'numeric' => 'The :attribute field must be number.', 9 | 'integer' => 'The :attribute field must be integer.' 10 | ]; -------------------------------------------------------------------------------- /src/TinyLara/View/View.php: -------------------------------------------------------------------------------- 1 | view = $view; 14 | $this->isJson = $isJson; 15 | } 16 | 17 | public static function make($viewName = null) 18 | { 19 | if ( !defined('VIEW_BASE_PATH') ) { 20 | throw new \InvalidArgumentException("VIEW_BASE_PATH is undefined!"); 21 | } 22 | if ( ! $viewName ) { 23 | throw new \InvalidArgumentException("View name can not be empty!"); 24 | } else { 25 | 26 | $viewFilePath = self::getFilePath($viewName); 27 | if ( is_file($viewFilePath) ) { 28 | return new View($viewFilePath); 29 | } else { 30 | throw new \UnexpectedValueException("View file does not exist!"); 31 | } 32 | } 33 | } 34 | 35 | public static function json($arr) 36 | { 37 | if ( !is_array($arr) ) { 38 | throw new \UnexpectedValueException("View::json can only recieve Array!"); 39 | } else { 40 | return new View($arr, true); 41 | } 42 | } 43 | 44 | public static function process($view = null) 45 | { 46 | if ( is_string($view) ) { 47 | echo $view; 48 | return; 49 | } 50 | if ( isset($view) && $view->isJson ) { 51 | echo json_encode($view->view); 52 | } else { 53 | if ( $view instanceof View ) { 54 | if ($view->data) { 55 | extract($view->data); 56 | } 57 | require $view->view; 58 | } 59 | } 60 | } 61 | 62 | public function with($key, $value = null) 63 | { 64 | $this->data[$key] = $value; 65 | return $this; 66 | } 67 | 68 | private static function getFilePath($viewName) 69 | { 70 | $filePath = str_replace('.', '/', $viewName); 71 | return VIEW_BASE_PATH.$filePath.'.php'; 72 | } 73 | 74 | public function __call($method, $parameters) 75 | { 76 | if (starts_with($method, 'with')) 77 | { 78 | return $this->with(snake_case(substr($method, 4)), $parameters[0]); 79 | } 80 | 81 | throw new \BadMethodCallException("Function [$method] does not exist!"); 82 | } 83 | } --------------------------------------------------------------------------------