public function validate(Request $request, array $rules)
 {
     $valid = true;
     foreach ($rules as $field => $rule) {
         if (is_null($rule) || !is_string($rule) || strlen($rule) == 0) {
             throw new ValidationException("Rule must be a string");
         }
         // get field value
         $value = $request->input($field);
         // split validation rule into required / sometimes (no validation if not set or empty)
         // contract and contract parameters
         $parts = explode("|", $rule);
         if (is_null($parts) || !is_array($parts) || count($parts) < 3) {
             throw new ValidationException("Invalid rule");
         }
         $required = strtolower($parts[0]) == "required" ? true : false;
         if ($required && is_null($value)) {
             $valid = false;
             continue;
         }
         $args = explode(":", $parts[1]);
         $clazz = Inflector::classify($args[0]) . "Contract";
         if (!class_exists($clazz)) {
             throw new ValidationException("Invalid rule: invalid validation class '{$clazz}'");
         }
         $instance = new $clazz($value, isset($args[1]) ? $args[1] : array());
         if (!$instance instanceof Contract) {
             throw new ValidationException("Invalid rule: invalid validation class '{$clazz}'. Class must extend Simplified\\Validator\\Contract");
         }
         if (!$instance->isValid()) {
             $valid = false;
         }
     }
     return $valid;
 }
 public function handleRequest()
 {
     ob_start();
     $this->startSession();
     $routes = RouteCollection::instance();
     if ($routes == null || $routes->count() == 0) {
         throw new \ErrorException('Unable to load routes from configuration directory.');
     }
     $request = Request::createFromGlobals();
     $path = $request->getUri()->getPath();
     $current_route = null;
     $matches = array();
     $urlMatcher = new UrlMatcher($routes, $request);
     switch ($urlMatcher->matches($path)) {
         case UrlMatcher::UNKNOWN_RESOURCE:
             throw new ResourceNotFoundException('Route not found: ' . $path);
             return;
         case UrlMatcher::METHOD_MISMATCH:
             throw new MethodNotAllowedException("Method not allowed");
             return;
         case UrlMatcher::MATCH_FOUND:
             $current_route = $urlMatcher->getMatchedRoute();
             $matches = $urlMatcher->getMatches();
             break;
     }
     // we use a controller, so do checks and throw if something is wrong (class or method)
     if (!$current_route->controller && !$current_route->closure) {
         throw new IllegalArgumentException('No controller or Closure was set for route ' . $current_route->path);
     }
     $params = array();
     $userObject = null;
     // if we use a closure, call them with the request object
     if ($current_route->closure) {
         $userObject = $current_route->closure;
         $ref = new \ReflectionFunction($current_route->closure);
         if ($ref->getNumberOfParameters() > 0) {
             $first = $ref->getParameters()[0];
             if ($first->getClass() != null && strstr($first->getClass()->getName(), 'Request')) {
                 $params[] = $request;
             }
             foreach ($matches as $match) {
                 $params[] = $match;
             }
         }
     } else {
         // handle controller
         $parts = explode("@", $current_route->controller);
         $controller = "App\\Controllers\\" . $parts[0];
         $method = $parts[1];
         if (!class_exists($controller)) {
             throw new ResourceNotFoundException("Unable to find controller {$controller}.");
         }
         if (!method_exists($controller, $method)) {
             throw new ResourceNotFoundException("Unable to call {$controller}::{$method}()");
         }
         $instance = new $controller();
         $userObject = array($instance, $method);
         $ref = new \ReflectionClass($controller);
         $num_params = $ref->getMethod($method)->getNumberOfParameters();
         $retval = null;
         if ($num_params > 0) {
             $ref_method = $ref->getMethod($method);
             $first = $ref_method->getParameters()[0];
             if ($first->getClass() != null && strstr($first->getClass()->getName(), 'Request')) {
                 $params[] = $request;
             }
             foreach ($matches as $match) {
                 $params[] = $match;
             }
         }
         if ($instance instanceof BaseController) {
             $instance->onBefore();
         }
     }
     $retval = call_user_func_array($userObject, $params);
     $this->handleContent($retval);
 }
 private static function output($html, $message)
 {
     $req = Request::createFromGlobals();
     if ($req->isAjax()) {
         $json = json_encode(array('error' => true, 'message' => 'Internal Server Error<br>' . $message));
         (new Response($json, 500, array('Content-Type' => 'application/json')))->send();
     } else {
         // TODO check for debug. If not, send error page
         (new Response($html, 500))->send();
     }
 }