Commit c6fa26ec authored by Jonty Newman's avatar Jonty Newman
Browse files

Documenting methods.

parent e3c48870
Pipeline #24570486 passed with stage
in 7 minutes and 26 seconds
......@@ -2,15 +2,55 @@
namespace ShrooPHP\RESTful;
use ShrooPHP\RESTful\Resource;
/**
* A collection of resources.
*/
interface Collection
{
/**
* Gets the resource with the given ID.
*
* @param string $id The ID of the resource to retrieve.
* @return \ShrooPHP\RESTful\Resource|null The retrieved resource (or NULL
* if no resource was found).
*/
public function get(string $id): ?Resource;
/**
* Posts the given resource to the given ID.
*
* @param string $id The ID to post the resource to.
* @param \ShrooPHP\RESTful\Resource $resource The resource to post to the
* ID.
* @return string|null The new ID of the given resource (or NULL if no
* redirection is necessary).
*/
public function post(string $id, Resource $resource): ?string;
/**
* Puts the given resource to the given ID.
*
* @param string $id The ID to put the resource to.
* @param \ShrooPHP\RESTful\Resource $resource The resource to put to the
* ID.
*/
public function put(string $id, Resource $resource): void;
/**
* Patches the resource at the given ID.
*
* @param string $id The ID of the resource to patch.
* @param \ShrooPHP\RESTful\Resource $resource The resource to apply as the
* patch.
*/
public function patch(string $id, Resource $resource): void;
/**
* Deletes the resource with the given ID.
*
* @param string $id The ID of the resource to delete.
*/
public function delete(string $id): void;
}
......@@ -7,6 +7,9 @@ use ShrooPHP\RESTful\Resources\File;
use SplFileInfo;
use SplFileObject;
/**
* Functionality for collections that persist resources via the file system.
*/
trait FileSystem
{
public function get(string $id): ?Resource
......@@ -43,16 +46,33 @@ trait FileSystem
unlink($id);
}
/**
* Gets the size of the buffer.
*
* @return int The size of the buffer.
*/
protected abstract function buffer(): int;
/**
* Converts the given path to a resource.
*
* @param string $path The path to convert.
* @return \ShrooPHP\RESTful\Resource The converted path.
*/
private function toResource(string $path): Resource
{
return new File($path, $this->buffer());
}
private function write(string $id, Resource $resource): void
/**
* Writes the given resource to the given path.
*
* @param string $path The path to write the resource to.
* @param \ShrooPHP\RESTful\Resource $resource The resource to be written.
*/
private function write(string $path, Resource $resource): void
{
$file = new SplFileObject($id, 'wb');
$file = new SplFileObject($path, 'wb');
ob_start(function (string $buffer) use ($file) {
$file->fwrite($buffer);
return '';
......
......@@ -4,13 +4,21 @@ namespace ShrooPHP\RESTful\Collection\Traits;
use ShrooPHP\RESTful\Resource;
/**
* Functionality for collections that store resources in memory.
*/
trait HashTable
{
private $entities = [];
/**
* The associative array being used to represent the hash table.
*
* @var array
*/
private $resources = [];
public function get(string $id): ?Resource
{
return $this->entities[$id] ?? null;
return $this->resources[$id] ?? null;
}
public function post(string $id, Resource $resource): ?string
......@@ -32,18 +40,32 @@ trait HashTable
public function delete(string $id): void
{
unset($this->entities[$id]);
unset($this->resources[$id]);
}
/**
* Gets the current maximum length of the underlying hash table (if any).
*
* @returns int|null The current maximum length of the underlying hash table
* (if any).
*/
protected abstract function limit(): ?int;
/**
* Associates the given ID with the given resource in the underlying hash
* table.
*
* @param string $id The ID to associate with the resource.
* @param \ShrooPHP\RESTful\Resource $resource The resource to associate
* with the ID.
*/
private function set(string $id, Resource $resource): void
{
$limit = $this->limit();
$this->entities[$id] = $resource;
$this->resources[$id] = $resource;
if (!is_null($limit) && count($this->entities) > $limit) {
array_shift($this->entities);
if (!is_null($limit) && count($this->resources) > $limit) {
array_shift($this->resources);
}
}
}
......@@ -5,6 +5,9 @@ namespace ShrooPHP\RESTful\Collection\Traits;
use ShrooPHP\RESTful\Collection\UnsupportedMethodException;
use ShrooPHP\RESTful\Resource;
/**
* Functionality for collections that only support a subset of known methods.
*/
trait Unimplemented
{
public function get(string $id): ?Resource
......
......@@ -2,6 +2,9 @@
namespace ShrooPHP\RESTful\Collection;
/**
* An error that relates to an unsupported method being invoked.
*/
interface UnsupportedMethodError
{
......
......@@ -5,6 +5,9 @@ namespace ShrooPHP\RESTful\Collection;
use Exception;
use ShrooPHP\RESTful\Collection\UnsupportedMethodError as Error;
/**
* An exception indicating that an unsupported method has been invoked.
*/
class UnsupportedMethodException extends Exception implements Error
{
......
......@@ -6,14 +6,31 @@ use ShrooPHP\RESTful\Collection;
use ShrooPHP\RESTful\Collection\Traits\FileSystem as FileSystemTrait;
use ShrooPHP\RESTful\Resources\File;
/**
* A collection that persists resources via the file system.
*/
class FileSystem implements Collection
{
/**
* The default size of the buffer.
*/
const BUFFER = File::BUFFER;
use FileSystemTrait;
/**
* The current size of the buffer.
*
* @var int
*/
private $buffer;
/**
* Constructs a collection that persists resources via the file system.
*
* @param int|null $buffer The size of the buffer (or NULL to use the
* default).
*/
public function __construct(int $buffer = null)
{
$this->buffer = $buffer ?? self::BUFFER;
......
......@@ -5,12 +5,26 @@ namespace ShrooPHP\RESTful\Collections;
use ShrooPHP\RESTful\Collection;
use ShrooPHP\RESTful\Collection\Traits\HashTable as HashTableTrait;
/**
* A collection that stores resources in memory.
*/
class HashTable implements Collection
{
use HashTableTrait;
/**
* The current maximum length of the underlying hash table (if any).
*
* @var int|null
*/
private $limit;
/**
* Constructs a collection that stores resources in memory
*
* @param int|null $limit The maximum length of the underlying hash table
* (if any).
*/
public function __construct(int $limit = null)
{
$this->limit = $limit;
......
......@@ -18,15 +18,39 @@ use ShrooPHP\RESTful\Resources\Immutable;
use ShrooPHP\RESTful\Resources\Pointer;
use ShrooPHP\RESTful\Runnables\Partial;
/**
* A RESTful request handler.
*/
class Handler implements IHandler
{
/**
* The regular expression for extracting the byte range of a request.
*/
const REGEX = '/bytes=\h*(\d+)-(\d*)[\D.*]?/i';
/**
* The collection containing resources.
*
* @var \ShrooPHP\RESTful\Collection
*/
private $collection;
/**
* The presenter being used to present responses.
*
* @var \ShrooPHP\Core\Request\Response\Presenter;
*/
private $presenter;
/**
* Constructs a RESTful request handler.
*
* @param \ShrooPHP\RESTful\Collection $collection The collection containing
* resources.
* @param \ShrooPHP\Core\Request\Response\Presenter $presenter The presenter
* to use to present responses.
*/
public function __construct(
Collection $collection,
IPresenter $presenter = null
......@@ -48,6 +72,13 @@ class Handler implements IHandler
return $handled;
}
/**
* Converts the given request to a response.
*
* @param \ShrooPHP\Core\Request $request The request to convert.
* @return \ShrooPHP\Core\Request\Response|null $response The converted
* request (or NULL if the requested resource was not found).
*/
public function respond(Request $request): ?IResponse
{
$id = null;
......@@ -85,11 +116,26 @@ class Handler implements IHandler
return $response;
}
/**
* Converts the request handler to a callable that is compatible as a
* request handler callback.
*
* @return callable The converted request handler.
*/
public function toCallable(): callable
{
return [$this, 'respond'];
}
/**
* Converts the given request to a response.
*
* @param \ShrooPHP\Core\Request $request The request to convert.
* @param \ShrooPHP\RESTful\Resource $resource The resource known to be
* associated with the request.
* @param string $id The ID known to be associated with the request.
* @return \ShrooPHP\Core\Request\Response The converted request.
*/
private function toResponse(
Request $request,
Resource $resource,
......@@ -130,11 +176,27 @@ class Handler implements IHandler
return $response;
}
/**
* Converts the given string to a date and time.
*
* @param string $since The string to convert (in RFC 2822 format).
* @return \DateTime|null The converted string (or NULL if it could not be
* converted.
*/
private function toDateTime(string $since): ?DateTime
{
return DateTime::createFromFormat(DateTime::RFC2822, $since) ?: null;
}
/**
* Converts the given string to a range of bytes.
*
* @param string $range The range to convert.
* @param int $start The variable to be assigned the start byte.
* @param int $length The variable to be assigned the length.
* @return bool Whether or not a range was successfully extracted from the
* string.
*/
private function toRange(
string $range,
int &$start,
......@@ -179,6 +241,16 @@ class Handler implements IHandler
}
}
/**
* Modifies the given response with the given resource and range.
*
* @param \ShrooPHP\Framework\Request\Responses\Response $response The
* response to modify.
* @param \ShrooPHP\RESTful\Resource $resource The resource to add to the
* response.
* @param int $start The start byte to add to the response.
* @param int $length The length to add to the response.
*/
private function modified(
Response $response,
Resource $resource,
......
......@@ -4,13 +4,40 @@ namespace ShrooPHP\RESTful;
use DateTime;
/**
* A resource.
*/
interface Resource
{
/**
* Gets the type of the resource.
*
* @return string|null The type of the resource (or NULL to assume the
* default).
*/
public function type(): ?string;
/**
* Gets the time at which the resource was last modified.
*
* @return \DateTime The time at which the resource was last modified.
*/
public function modified(): DateTime;
/**
* Gets the size of the resource.
*
* @return int|null The size of the resource (or NULL if the size is
* unknown).
*/
public function size(): ?int;
/**
* Outputs the contents of the resource.
*
* @param int $start The byte at which to begin output.
* @param int $length|null The number of remaining bytes to output (or NULL
* to output all remaining bytes.
*/
public function render(int $start = 0, int $length = null): void;
}
......@@ -2,6 +2,9 @@
namespace ShrooPHP\RESTful\Resource\Traits;
/**
* Functionality for resources with contents that is represented as a string.
*/
trait Binary
{
public function render(int $start = 0, int $length = null): void
......@@ -18,5 +21,10 @@ trait Binary
return strlen($this->binary());
}
/**
* Gets the current contents of the resource.
*
* @return string The current contents of the resource.
*/
protected abstract function binary(): string;
}
......@@ -7,6 +7,9 @@ use finfo;
use ShrooPHP\RESTful\Resource\Traits\Pointer;
use SplFileInfo;
/**
* Functionality for resources that are represented as a file.
*/
trait File
{
use Pointer;
......@@ -31,6 +34,11 @@ trait File
return $this->toSplFileInfo()->getSize();
}
/**
* Gets the current path to the underlying file.
*
* @return The current path to the underlying file.
*/
protected abstract function path(): string;
protected function pointer()
......@@ -38,6 +46,11 @@ trait File
return fopen($this->path(), 'rb');
}
/**
* Converts the current path to file information.
*
* @return \SplFileInfo The converted path.
*/
private function toSplFileInfo(): SplFileInfo
{
return new SplFileInfo($this->path());
......
......@@ -4,6 +4,9 @@ namespace ShrooPHP\RESTful\Resource\Traits;
use ShrooPHP\RESTful\Resource\Traits\Pointer\Exception;
/**
* Functionality for resources that are represented as a file pointer.
*/
trait Pointer
{
public function render(int $start = 0, int $length = null): void
......@@ -23,10 +26,27 @@ trait Pointer
}
}
/**
* Opens a pointer to the underlying file.
*
* @return resource|null A pointer to the underlying file (or NULL on
* failure).
*/
protected abstract function pointer();
/**
* Gets the size of the buffer.
*
* @return int The size of the buffer.
*/
protected abstract function buffer(): int;
/**
* Outputs the given number of bytes (at most) from the given pointer.
*
* @param resource $handle The pointer to output from.
* @param int $length The number of bytes to output (at most).
*/
private function partial($handle, int $length): void
{
$rendered = 0;
......
......@@ -4,6 +4,9 @@ namespace ShrooPHP\RESTful\Resource\Traits\Pointer;
use RuntimeException;
/**
* An exception indicating a failure to open a pointer.
*/
class Exception extends RuntimeException
{
......
......@@ -4,6 +4,10 @@ namespace ShrooPHP\RESTful\Resource\Traits;
use DateTime;
/**
* Functionality for resources with modification times that can be updated at
* runtime.
*/
trait Touchable
{
private $touched = null;
......@@ -13,6 +17,9 @@ trait Touchable
return $this->touched ?? $this->now();
}
/**
* Updates the current modification time with the current time.
*/
protected function touch(): void
{
$this->touched = $this->now();
......
......@@ -5,6 +5,9 @@ namespace ShrooPHP\RESTful\Resource\Traits;
use InvalidArgumentException as Exception;
use ShrooPHP\RESTful\Resource\UnsupportedRangeException;
/**
* Functionality for resources that do not support ranges.
*/
trait Unranged
{
public function render(int $start = 0, int $length = null): void
......@@ -17,5 +20,8 @@ trait Unranged
$this->passthru();
}
protected abstract function passthru();
/**
* Outputs the current contents of the resource in its entirety.
*/
protected abstract function passthru(): void;
}
......@@ -2,6 +2,9 @@
namespace ShrooPHP\RESTful\Resource;
/**
* An error that relates to an unsupported range being specified.
*/
interface UnsupportedRangeError
{
......
......@@ -5,6 +5,9 @@ namespace ShrooPHP\RESTful\Resource;
use Exception;
use ShrooPHP\RESTful\Resource\UnsupportedRangeError as Error;
/**
* An exception indicating that an unsupported range has been specified.
*/
class UnsupportedRangeException extends Exception implements Error
{
......
......@@ -5,16 +5,38 @@ namespace ShrooPHP\RESTful\Resources;
use ShrooPHP\RESTful\Resource;
use ShrooPHP\RESTful\Resource\Traits\File as FileTrait;
/**
* A resource that is represented as a file.
*/
class File implements Resource
{
use FileTrait;
/**
* The default size of the buffer.
*/
const BUFFER = 0x1000;
/**
* The path of the file representing the resource.
*
* @var string
*/
private $path;
/**
* The size of the buffer.
*
* @var int
*/
private $buffer;
/**
* Constructs a resource that is represented as a file.
*
* @param string $path The path to the file representing the resource.
* @param int $buffer The size of the buffer (or NULL to use the default).
*/
public function __construct(string $path, int $buffer = null)
{
$this->path = $path;
......
......@@ -7,16 +7,46 @@ use ShrooPHP\RESTful\Resource\Traits\Binary;
use ShrooPHP\RESTful\Resource\Traits\Touchable;
use RuntimeException;