Пример #1
0
 /**
  * Instantiates a new hasher object and set the salt to the supplied one.
  * The constructor will throw an exception if SIP 3rd party module isn't
  * installed in PHP, or if the hash is not a string or if its length is not
  * 16 exactly -- a requirement of this hashing algorithm.
  *
  * @link https://github.com/jedisct1/siphash-php SIP 3rd party module
  * @param string $salt must be a 16-byte string
  */
 public function __construct($salt)
 {
     // Check for SIP module.
     Assert::that(['condition' => function_exists('sip_hash'), 'message' => 'The SIP 3rd party module is not installed', 'type' => Error::TYPE_RUNTIME]);
     // The salt must be exactly 16-bytes long.
     Assert::that(['condition' => is_string($salt) && 16 === strlen($salt), 'message' => 'The SIP hash value must be a 16-byte string', 'type' => Error::TYPE_ARGUMENT]);
     // All good, continue execution.
     parent::__construct($salt);
 }
Пример #2
0
 /**
  * Instantiates this class with the specified service name and log file path.
  * If the file doesn't exist, and $autoCreate is TRUE, then the file will be
  * created. Note that the target directory *must* exist before the file will
  * be created, or else an exception will be thrown.
  *
  * @param string $serviceName of this log file
  * @param string $filePath to log file
  * @param boolean $autoCreate TRUE to create the file if missing
  */
 public function __construct($serviceName, $filePath, $autoCreate = true)
 {
     // Always call parent constructor.
     parent::__construct($serviceName);
     Assert::that(['condition' => !System::isDir($filePath), 'message' => 'The error log file path [%s] cannot be a directory', 'args' => [$filePath], 'type' => Error::TYPE_ARGUMENT]);
     if (!System::isFile($filePath)) {
         Assert::that(['condition' => $autoCreate, 'message' => 'The error log file [%s] is not present', 'args' => [$filePath], 'type' => Error::TYPE_ARGUMENT]);
         Assert::that(['condition' => System::touch($filePath), 'message' => 'The error log file [%s] cannot be created', 'args' => [$filePath], 'type' => Error::TYPE_RUNTIME]);
     }
     // At this point, a production environment should be already set up to
     // include this file or create it when necessary.
     $this->fileHandle = System::openFile($filePath, 'a');
     Assert::that(['condition' => $this->fileHandle, 'message' => 'Unable to open error log file [%s] for writing', 'args' => [$filePath], 'type' => Error::TYPE_RUNTIME]);
 }
Пример #3
0
 /**
  * Loads the associated PHP class script for the specified driver.
  *
  * @param string $driver to load
  * @return \Fine47\DbOne\Prototype instance of a specified driver
  * @throws \Fine47\DbOne\Error
  */
 public static function getDriver($driver)
 {
     // Normalize driver name.
     $driver = @strtolower(trim($driver));
     // The 'prototype' driver is built-in.
     Assert::that(['condition' => self::PROTOTYPE !== $driver, 'message' => 'Driver [%s] is built-in and cannot be used.', 'args' => [$driver], 'type' => Error::TYPE_DATABASE]);
     // Load the driver script once.
     if (!isset(self::$instances[$driver])) {
         // Class name has a first uppercase letter.
         $className = '\\Fine47\\DbOne\\Drivers\\' . ucfirst($driver);
         // Create a new instance of the driver.
         self::$instances[$driver] = new $className();
     }
     return self::$instances[$driver];
 }
Пример #4
0
 /**
  * @see \Fine47\MicroRouter\Responses\Http::serveImpl()
  */
 protected function serveImpl()
 {
     // Create a temporary file to hold the output buffer.
     $tempPath = System::tempFile();
     try {
         // Save output buffer as JSON.
         Assert::that(['condition' => false !== file_put_contents($tempPath, Json::encode($this->getBody())), 'message' => 'Unable to serve the response body', 'type' => Error::TYPE_RUNTIME, 'magic' => 0xeb73]);
         // Close the file handle and outputs its contents.
         Assert::that(['condition' => false !== readfile($tempPath, false), 'message' => 'Unable to serve the response body', 'type' => Error::TYPE_RUNTIME, 'magic' => 0xeb74]);
     } finally {
         // Deletes temporary file.
         @unlink($tempPath);
     }
     // Once the body is served, it cannot be re-served again.
     $this->shutdown();
 }
Пример #5
0
 /**
  * Guarantees that this image instance hasn't been destroyed yet.
  *
  * @throws \Fine47\Exceptions\ImageError
  */
 protected function assertActive()
 {
     Assert::that(['condition' => $this->resource && is_resource($this->resource), 'message' => 'This image has already been destroyed', 'type' => Error::TYPE_IMAGE, 'magic' => 0x777e]);
 }
Пример #6
0
 /**
  * Auxiliary method to ensure that the output body hasn't been served yet. If
  * it has, the method will throw an exception.
  */
 protected function ensureNotServed()
 {
     Assert::that(['condition' => !$this->served, 'message' => 'Response body already served', 'type' => Error::TYPE_RUNTIME]);
 }
Пример #7
0
 /**
  * Instantiates a new action corresponding to the supplied handler script.
  *
  * @param string $routePath digging starts from this top-level directory
  * @param string $matchUri farthest path to traverse
  * @param string $scriptPath where handler resides
  * @param array $params for the action
  * @param \Fine47\MicroRouter\Interfaces\Query $query for the action
  * @return \Fine47\MicroRouter\Interfaces\Action
  */
 protected function getHandlerAction($routePath, $matchUri, $scriptPath, array $params, Interfaces\Query $query)
 {
     // Load this action's class. The returned value is the class's name.
     $actionClass = (require_once $scriptPath);
     // Trim any spaces.
     $actionClass = @trim($actionClass);
     // Because a back-slash is used to escape characters, we also accept forward
     // slashes to set the namespace.
     $actionClass = @str_replace('/', '\\', $actionClass);
     // Make the namespace absolute by adding a starting back slash.
     if ('' !== $actionClass && '\\' !== $actionClass[0]) {
         $actionClass = '\\' . $actionClass;
     }
     // Test if the action class is valid.
     Assert::that(['condition' => $actionClass && class_exists($actionClass), 'message' => 'The handler class [%s] cannot be found' . ' (did you include a namespace?)', 'args' => [$actionClass], 'type' => Error::TYPE_PARSE, 'magic' => 0xf776]);
     // TODO: Find the filters for this action.
     $filters = $this->getActionFilters($routePath, $matchUri, $query);
     // Instantiate this class.
     $action = new $actionClass($query, $params, $filters);
     // Test if the action class is valid.
     Assert::that(['condition' => $action instanceof Actions\Files, 'message' => 'The handler script [%s] must inherit from ' . 'Actions\\Files class', 'args' => [$scriptPath], 'type' => Error::TYPE_PARSE, 'magic' => 0x3ba7]);
     return $action;
 }
Пример #8
0
 /**
  * Instantiates a new request identified by the specified URI. A base URI must
  * be provided also to govern the base URI to anchor to (ex.: '/', '/api').
  *
  * Note that getUri() will return the evaluated request URI after cropping the
  * leading base URI.
  *
  * @param string $baseUri for this request
  * @param string $uri of this request (including leading base URI)
  * @see \Fine47\MicroRouter\Interfaces\Request::getUri()
  */
 public function __construct($baseUri, $uri = null)
 {
     // Normalize the base URI to be a string.
     $baseUri = @trim($baseUri);
     // A base URI must start with a '/'
     Assert::that(['condition' => $baseUri && '/' === $baseUri[0], 'message' => 'Base URI path must start with a / character', 'type' => Error::TYPE_ARGUMENT]);
     // Normalize it by adding a trailing slash character.
     $baseUri = @rtrim($baseUri, '/') . '/';
     // Use default request URI if it's not provided.
     if (null === $uri) {
         $uri = @trim($_SERVER['REQUEST_URI']);
     }
     // A request URI must start with a '/'
     Assert::that(['condition' => $uri && '/' === $uri[0], 'message' => 'Request URI must start with a / character', 'type' => Error::TYPE_ARGUMENT]);
     // Get base URI's length.
     $baseUriLen = strlen($baseUri);
     // Strip base URI from request URI.
     if (!strcmp(substr($uri, 0, $baseUriLen), $baseUri)) {
         $uri = substr($uri, $baseUriLen);
     }
     // Ensure that the resulting request URI (without base URI) is valid.
     Assert::that(['condition' => $this->isValidUri($uri), 'message' => 'Request URI is invalid', 'type' => Error::TYPE_ARGUMENT, 'magic' => 0x8245]);
     // Normalize request URI by removing leading and trailing slash characters.
     $uri = @trim($uri, '/');
     // Keep details.
     $this->baseUri = $baseUri;
     $this->uri = $uri;
 }
Пример #9
0
 /**
  * Logger constructor accepts a service name to associate with the logger. In
  * logging messages the service name will be shown for verbosity's sake.
  *
  * @param string $serviceName to associate with the logger
  */
 public function __construct($serviceName)
 {
     $serviceName = @trim($serviceName);
     Assert::that(['condition' => $serviceName, 'message' => 'The service name cannot be empty', 'type' => Error::TYPE_ARGUMENT]);
     $this->serviceName = $serviceName;
 }
Пример #10
0
 /**
  * Resizes (down-sizing only) the specified image to the maximum boundary set
  * by the specified dimension. If either dimension is set to 0, its value will
  * be automatically calculated using the other value, thus maintaining the
  * aspect ratio.
  *
  * @param \Fine47\ImageMan\Prototype $image to resize
  * @param int $targetWidth value for resizing
  * @param int $targetHeight value for resizing
  * @return \Fine47\ImageMan\Prototype resized image
  */
 public static function resize(ImageMan\Prototype $image, $targetWidth = 0, $targetHeight = 0)
 {
     // Make sure that arguments are valid.
     $targetWidth = @intval($targetWidth);
     $targetHeight = @intval($targetHeight);
     Assert::that(['condition' => $targetWidth || $targetHeight, 'message' => 'Trying to resize an image to an invalid dimension', 'type' => Error::TYPE_ARGUMENT]);
     // Shortcut pointers.
     $imageWidth = $image->getWidth();
     $imageHeight = $image->getHeight();
     // If image is landscape, flip the target dimension.
     if ($imageHeight < $imageWidth) {
         $savedValue = $targetWidth;
         $targetWidth = $targetHeight;
         $targetHeight = $savedValue;
         unset($savedValue);
     }
     // If the target dimension is negative, return the original.
     if (0 > $targetWidth || 0 > $targetHeight) {
         // Make the target resolution exactly the same as the image's.
         // This will effectively bypass the resizing process.
         $targetWidth = $imageWidth;
         $targetHeight = $imageHeight;
     } else {
         if (1 > $targetWidth) {
             // Adjust target width since it's missing.
             $targetWidth = ceil($targetHeight * $imageWidth / $imageHeight);
         } else {
             if (1 > $targetHeight) {
                 // Adjust target height since it's missing.
                 $targetHeight = ceil($targetWidth * $imageHeight / $imageWidth);
             }
         }
     }
     // Resample to smaller size when original is larger than that.
     if ($targetWidth < $imageWidth || $targetHeight < $imageHeight) {
         // Calculate the scaling between widths and heights.
         $scale = min($targetWidth / $imageWidth, $targetHeight / $imageHeight);
         // Scale can be maximum 1.
         if (1 < $scale) {
             $scale = 1;
         }
         // Calculate maximum resize dimension.
         $resizeWidth = round($imageWidth * $scale);
         $resizeHeight = round($imageHeight * $scale);
         // Create a new empty image.
         $resized = self::newImage($image, $resizeWidth, $resizeHeight);
         // Resize the image.
         if (imagecopyresampled($resized->getResource(), $image->getResource(), 0, 0, 0, 0, $resizeWidth, $resizeHeight, $imageWidth, $imageHeight)) {
             return $resized;
         } else {
             $resized->gc();
             $resized = null;
             Assert::raise(['message' => 'Unable to resize the image to [%dx%d]', 'args' => [$resizeWidth, $resizeHeight], 'type' => Error::TYPE_IMAGE]);
         }
     }
     // In all other cases, just return the original image.
     return $image;
 }
Пример #11
0
 /**
  * Executes the specified query and returns the response.
  *
  * @param \Fine47\MicroRouter\Interfaces\Query $query to execute
  * @return \Fine47\MicroRouter\Interfaces\Response response of the query
  */
 public function execute(Interfaces\Query $query)
 {
     // Get the action of this query.
     $action = $this->getRouter()->resolve($this, $query);
     // Make sure the action is valid.
     Assert::that(['condition' => $action, 'message' => 'Query URI cannot be resolved', 'type' => Error::TYPE_PARSE, 'magic' => 0x733f]);
     // Get list of filters for this action.
     $filters = $this->getActionFilters($action);
     // Are there any filters?
     if ($filters) {
         // Start running the onQuery() callbacks for the filters.
         $this->onQueryImpl($query, $action, $filters);
         // If the action is secured, apply security filtering.
         if ($action->isSecured()) {
             $this->onSecuredImpl($query, $action, $filters);
         }
     }
     // Execute the action and get a response.
     $response = $action->execute($this, $query);
     // A response MUST be produced by the action (otherwise, the action should
     // throw an exception.)
     Assert::that(['condition' => $response, 'message' => 'Response for this action cannot be empty', 'type' => Error::TYPE_PARSE, 'magic' => 0x5f31]);
     // Run onResponse callbacks as well.
     if ($filters) {
         // Start running the onResponse() callbacks for the filters.
         $this->onResponseImpl($response, $action, $filters);
     }
     return $response;
 }
Пример #12
0
 /**
  * @internal auxiliary method to raise an error
  */
 private function raisePossibleError($magic)
 {
     if ($this->dbc->errno) {
         $errorMsg = trim($this->dbc->error);
         if (!$errorMsg) {
             $errorMsg = 'Unknown database error detected.';
         }
         Assert::that(['condition' => false, 'message' => $errorMsg, 'code' => $this->dbc->errno, 'type' => Error::TYPE_DATABASE, 'magic' => $magic]);
     }
 }
Пример #13
0
 /**
  * Checks whether the specified value is a boolean.
  *
  * @param string $name of the parameter to check
  * @param array $value to check
  */
 protected function checkIfBoolean($name, &$value)
 {
     // Make sure this is a float.
     Assert::that(['condition' => is_bool($value), 'message' => 'The mandatory field [%s] must be a boolean', 'args' => [$name], 'type' => Error::TYPE_INPUT]);
 }
Пример #14
0
 /**
  * @see \Fine47\MicroRouter\Responses\Http::appendImpl()
  */
 protected function appendImpl($body)
 {
     // Ensure that the body is an array.
     Assert::that(['condition' => is_array($body), 'message' => 'JSON response body must be an array', 'type' => Error::TYPE_ARGUMENT, 'magic' => 0x6722]);
     // Append new body recursively to the existing body.
     $this->arrayMergeImpl($this->body, $body);
 }