Example #1
0
 /**
  * @param Config $config defaults to Config::fromFile('frest-config.php')
  * @param string $resourceName The name of the resource for the request (defaults to base name of request url)
  * @param int|string $resourceID The ID of the resource for the request (defaults to base name of request url if it is an int)
  * @param array $parameters A list of key-value parameters to pass for the request (defaults to $_GET or $_POST) 
  * @param int $requestMethod The method (get, post, put, delete) (e.g. FREST\Type\Method) of the request (defaults to REQUEST_METHOD)
  * @param string $resourceFunctionName Custom Func to be invoked on resource
  */
 public function __construct($config = NULL, $resourceName = NULL, $resourceID = NULL, $parameters = NULL, $requestMethod = NULL, $resourceFunctionName = NULL)
 {
     try {
         $this->startTimingForLabel(Type\Timing::TOTAL, 'frest');
         if (!isset($config)) {
             $config = Config::fromFile();
             if (!isset($config)) {
                 throw new Exception(Exception::Config, "No config file or object supplied to Router");
             }
         }
         $this->config = $config;
         $this->suppressHTTPStatusCodes = $this->config->getSuppressHTTPStatusCodes();
         $this->startTimingForLabel(Type\Timing::SETUP, 'frest');
         // determine resource name, id, and Func (if any, taking into account if any of those were passed as parameters)
         if (!isset($resourceName) || !isset($resourceID)) {
             $url = $_SERVER['REQUEST_URI'];
             $queryPosition = strpos($url, '?');
             if ($queryPosition !== FALSE) {
                 $url = substr($url, 0, $queryPosition);
             }
             $urlInfo = pathinfo($url);
             $urlBaseName = $urlInfo['filename'];
             if (!isset($resourceName)) {
                 // check if base name is int
                 $secondBaseName = basename($urlInfo['dirname']);
                 if (is_numeric($urlBaseName) && strpos($urlBaseName, '.') == NULL) {
                     // assume this int is actually an id and resource is specified in previous path component
                     $resourceName = basename($urlInfo['dirname']);
                     $resourceID = intval($urlBaseName);
                 } else {
                     if (is_numeric($secondBaseName) && strpos($secondBaseName, '.') == NULL) {
                         // assume this int is actually an id and resource precedes it and Func follows it
                         $resourceName = basename(dirname($urlInfo['dirname']));
                         $resourceID = intval($secondBaseName);
                         $resourceFunctionName = $urlBaseName;
                     } else {
                         $resourceName = $urlBaseName;
                     }
                 }
             } else {
                 if (!isset($resourceID)) {
                     $resourceNameIfNoFunctionUsed = basename($urlInfo['dirname']);
                     $resourceNameIfFunctionUsed = basename(dirname($urlInfo['dirname']));
                     if ($resourceNameIfNoFunctionUsed == $resourceName) {
                         $resourceID = $urlBaseName;
                     } else {
                         if ($resourceNameIfFunctionUsed == $resourceName) {
                             $resourceID = basename($urlInfo['dirname']);
                             $resourceFunctionName = $urlBaseName;
                         }
                     }
                 }
             }
         }
         // cast resource ID if exists
         if (isset($resourceID)) {
             $resourceIDType = $this->resourceIDTypeFromResource($resourceName);
             $resourceID = Type\Variable::castValue($resourceID, $resourceIDType);
         }
         // determine request method
         if (!isset($requestMethod)) {
             $actualMethodString = $_SERVER['REQUEST_METHOD'];
             $actualMethod = Type\Method::fromString($actualMethodString);
         } else {
             $actualMethod = $requestMethod;
         }
         // check for forced method
         switch ($actualMethod) {
             case Type\Method::GET:
             case Type\Method::POST:
                 if ($this->config->getEnableForcedMethod() && isset($_REQUEST['method'])) {
                     $forcedMethodString = $_REQUEST['method'];
                     $forcedMethod = Type\Method::fromString($forcedMethodString);
                     // if method is valid
                     if ($forcedMethod <= 0) {
                         throw new Exception(Exception::InvalidMethod, "Method '{$forcedMethodString}");
                     }
                 }
                 break;
         }
         if (isset($forcedMethod)) {
             $this->method = $forcedMethod;
         } else {
             $this->method = $actualMethod;
         }
         // determine parameters to be used for resource
         if (!isset($parameters)) {
             switch ($actualMethod) {
                 case Type\Method::GET:
                     $parameters = $_GET;
                     break;
                 case Type\Method::POST:
                 case Type\Method::PUT:
                 case Type\Method::DELETE:
                     $parameters = $this->config->getEnableGETParametersInAllRequests() ? $_REQUEST : $_POST;
                     break;
                 default:
                     $methodString = Type\Method::getString($actualMethod);
                     throw new Exception(Exception::InvalidMethod, "Method '{$methodString}");
                     break;
             }
         }
         if (isset($parameters['suppress_http_status_codes'])) {
             $value = $parameters['suppress_http_status_codes'];
             $this->suppressHTTPStatusCodes = Type\Variable::castValue($value, Type\Variable::BOOL);
         }
         switch ($this->method) {
             case Type\Method::GET:
                 // read
                 if (isset($resourceID) && $resourceID != self::FORCED_NULL) {
                     $this->request = new Request\SingularRead($this, $resourceID, $parameters, $resourceFunctionName);
                 } else {
                     $this->request = new Request\PluralRead($this, $parameters, $resourceFunctionName);
                 }
                 break;
             case Type\Method::POST:
                 // create
                 $this->request = new Request\Create($this, $resourceID, $parameters, $resourceFunctionName);
                 break;
             case Type\Method::PUT:
                 // update / create
                 $this->request = new Request\Update($this, $resourceID, $parameters, $resourceFunctionName);
                 break;
             case Type\Method::DELETE:
                 // delete
                 $this->request = new Request\Delete($this, $resourceID, $parameters, $resourceFunctionName);
                 break;
             default:
                 break;
         }
         $this->resource = $this->loadResourceWithName($resourceName, $this->request);
         $this->stopTimingForLabel(Type\Timing::SETUP, 'frest');
         $this->startTimingForLabel(Type\Timing::PROCESSING, 'frest');
         $this->request->setupWithResource($this->resource);
         $this->stopTimingForLabel(Type\Timing::PROCESSING, 'frest');
         $this->stopTimingForLabel(Type\Timing::TOTAL, 'frest');
     } catch (Exception $exception) {
         $this->error = $exception->generateError();
     }
 }