namespace BitFrame\Data;
// implements:
use \ArrayAccess;
// uses:
use \BitFrame\Data\ApplicationDataTrait;
/**
* Stores application data to share across all middleware.
*/
class ApplicationData implements ArrayAccess
{
use ApplicationDataTrait;
/** @var array */
private $data;
/**
* @param array $data (optional, default: []
)
*/
public function __construct(
// data to store
array $data = []
);
/**
* Get stored application data.
*
* @return mixed[]
*
* @see: ApplicationDataTrait::getData()
*/
public function getData(): array;
}
namespace BitFrame\Delegate;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
// implements:
use \Psr\Http\Server\RequestHandlerInterface;
/**
* Decorate callable delegates as http delegates in order to process
* incoming requests.
*/
class CallableDelegate implements RequestHandlerInterface
{
/** @var callable */
private $delegate;
/** @var ResponseInterface */
private $response;
/**
* @param callable $delegate
* @param ResponseInterface $response
*/
public function __construct(
// callback to delegate
callable $delegate,
// response to delegate
ResponseInterface $response
);
/**
* Proxies to the underlying callable delegate to process a request.
*
* @return ResponseInterface
*
* @see: RequestHandlerInterface::handle()
*/
public function handle(
// http request to handle
ServerRequestInterface $request
): ResponseInterface;
}
namespace BitFrame\Delegate;
use \BitFrame\Router\RouteCollectionInterface;
/**
* Helps define route definitions in one place and easily
* inject them into a route collection.
*/
class RoutesDelegate {
/**
* Inject routes from a configuration array.
*
* The following configuration structure can be used to define routes:
*
* [
* [
* 'method' => ['GET', 'POST', 'PATCH'],
* 'path' => '/path/to/match',
* 'controller' => 'A callable (e.g. class or function)'
* ],
* // etc.
* ];
*
* @param array $routes An array of routes that can have 'method', 'path'
* and 'controller' keys.
*
* Note:
* - Routes without a 'controller' defined are skipped/ignored.
* - When 'method' aren't defined, a default 'GET' method is used.
* - When 'path' isn't defined, a default path '/' is used.
*/
public static function fromConfig(
// class which will store/use the $routes
RouteCollectionInterface $routeCollector,
// array of routes; must have at least a 'controller' defined
array $routes
);
}
namespace BitFrame\Dispatcher;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
use \Psr\Http\Server\MiddlewareInterface;
use \BitFrame\EventManager\Event;
// implements:
use \BitFrame\Dispatcher\DispatcherInterface;
use \BitFrame\EventManager\EventManagerInterface;
// uses:
use \BitFrame\EventManager\EventManagerAwareTrait;
// exceptions:
use \InvalidArgumentException;
use \UnexpectedValueException;
use \BadFunctionCallException;
use \BitFrame\Exception\InvalidMiddlewareException;
use \BitFrame\Exception\HttpException;
use \BitFrame\Exception\BadRequestException;
use \BitFrame\Exception\UnauthorizedException;
use \BitFrame\Exception\ForbiddenException;
use \BitFrame\Exception\RouteNotFoundException;
use \BitFrame\Exception\MethodNotAllowedException;
use \BitFrame\Exception\InternalErrorException;
use \BitFrame\Exception\NotImplementedException;
use \BitFrame\Exception\NotImplementedException;
/**
* Queues and runs middleware to create an http response based
* on the http request.
*/
class MiddlewareDispatcher implements
DispatcherInterface,
EventManagerInterface
{
use EventManagerAwareTrait;
/** @var string */
public const EVENT_BEFORE_DISPATCH = 'before.dispatch';
/** @var string */
public const EVENT_AFTER_DISPATCH = 'after.dispatch';
/** @var string */
public const EVENT_DONE_DISPATCH = 'done.dispatch';
/** @var array */
private $pendingMiddleware = [];
/** @var array */
private $processedMiddleware = [];
/** @var bool */
private $running = false;
/** @var bool */
private $immediatelyInvoked = false;
/** @var null|ServerRequestInterface */
private $request = null;
/** @var null|ResponseInterface */
private $response;
/** @var null|EventManagerInterface */
private $eventManager = null;
/**
* @param ResponseInterface|null $response (optional, default: null
)
*/
public function __construct(
// can pass an existing response object, or
// a new one will be created if null
?ResponseInterface $response = null
);
/**
* Add a middleware.
*
* @param callable|MiddlewareInterface|array $middleware
* @param bool $addToFront (optional, default: false
)
*
* @return $this
*
* @see: DispatcherInterface::addMiddleware()
*/
public function addMiddleware(
// middleware to add
$middleware,
// if true, middleware is added to front of queue
$addToFront = false
): self;
/**
* Add a middleware to front of queue.
*
* @param callable|MiddlewareInterface|array $middleware
*
* @return $this
*/
public function prependMiddleware(
// middleware to add
$middleware
): self;
/**
* Reset pending and processed middleware queues.
*
* @return $this
*
* @see DispatcherInterface::clear()
*/
public function clear(): self;
/**
* Process request.
*
* @param ServerRequestInterface $request
*
* @return ResponseInterface
*
* @triggers after.dispatch After a middleware has been processed
* @triggers before.dispatch Before a middleware is processed
* @triggers done.dispatch When a middleware has been processed
*
* @see: RequestHandlerInterface::handle()
* @see: MiddlewareDispatcher::validateHttpResponse
*/
public function handle(
// http request object
ServerRequestInterface $request
): ResponseInterface;
/**
* Check if dispatcher is running (processing middleware).
*
* @return bool
*
* @see: DispatcherInterface::isRunning()
*/
public function isRunning(): bool;
/**
* Check if there are pending middleware.
*
* @return bool
*
* @see: DispatcherInterface::hasMiddleware()
*/
public function hasMiddleware(): bool;
/**
* Get all pending middleware.
*
* @param string|null $chain
*
* @return array
*
* @see: DispatcherInterface::getPendingMiddleware()
*/
public function getPendingMiddleware(): array;
/**
* Get all processed middleware.
*
* @return array
*
* @see: DispatcherInterface::getProcessedMiddleware()
*/
public function getProcessedMiddleware(): array;
/**
* Set Http Request object.
*
* @param ServerRequestInterface $request
*
* @return $this
*/
public function setRequest(
// http request object
ServerRequestInterface $request
): self;
/**
* Get Http Request object.
*
* @return ServerRequestInterface
*/
public function getRequest(): ServerRequestInterface;
/**
* Set Http Response object.
*
* @param ResponseInterface $response
*
* @return $this
*/
public function setResponse(
// http response object
ResponseInterface $response
): self;
/**
* Get Http Response object.
*
* @return ResponseInterface
*/
public function getResponse(): ResponseInterface;
/**
* Get the Event Manager object.
*
* @return EventManagerInterface
*/
public function getEventManager(): EventManagerInterface;
/**
* Trigger an event.
*
* @param string $evtName
* @param callable|MiddlewareInterface|array $middleware
*/
private function triggerEvent(
// event name
string $evtName,
// middleware that's calling the event
$middleware
);
/**
* Process response to see if an HTTP exception needs to be thrown.
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
*
* @throws \UnexpectedValueException
* @throws \BitFrame\Exception\HttpException
* @throws \BitFrame\Exception\BadRequestException
* @throws \BitFrame\Exception\UnauthorizedException
* @throws \BitFrame\Exception\ForbiddenException
* @throws \BitFrame\Exception\RouteNotFoundException
* @throws \BitFrame\Exception\MethodNotAllowedException
* @throws \BitFrame\Exception\InternalErrorException
* @throws \BitFrame\Exception\NotImplementedException
* @throws \BitFrame\Exception\NotImplementedException
*/
private function validateHttpResponse(
// http request object
ServerRequestInterface $request,
// http response object
ResponseInterface $response
);
}
namespace BitFrame\EventManager;
// implements:
use \BitFrame\EventManager\EventInterface;
// exceptions:
use \OutOfBoundsException;
/**
* An observable event that is triggered over some action,
* and accordingly can be handled by attaching event handlers.
*/
class Event implements EventInterface
{
/** @var string */
private $name;
/** @var null|string|object */
private $target;
/** @var array */
private $params;
/** @var bool */
private $propagate;
/**
* @param string $name
* @param null|string|object $target (optional, default: null
)
* @param array $params (optional, default: []
)
* @param bool $propagate (optional, default: false
)
*/
public function __construct(
// name of the event
string $name,
// target that triggered the event
$target = null,
// params to pass along with the event
array $params = [],
// if true, event is propagated
bool $propagate = false
);
/**
* Set the event name.
*
* @param string $name
*
* @return $this
*
* @see: EventInterface::setName()
*/
public function setName(
// name of the event
string $name
): self;
/**
* Get event name.
*
* @return string
*
* @see: EventInterface::getName()
*/
public function getName(): string;
/**
* Set the event target.
*
* @param null|string|object $target
*
* @return $this
*
* @see: EventInterface::setTarget()
*/
public function setTarget(
// target linked to the event
$target
): self;
/**
* Get target/context from which event was triggered.
*
* @return null|string|object
*
* @see: EventInterface::getTarget()
*/
public function getTarget();
/**
* Set event parameters.
*
* @param array $params
*
* @return $this
*
* @see: EventInterface::setParams()
*/
public function setParams(
// params to pass along with the event
array $params
): self;
/**
* Get parameters passed to the event.
*
* @return array
*
* @see: EventInterface::getParams()
*/
public function getParams(): array;
/**
* Get a single parameter by name.
*
* @param string $name
*
* @return mixed
*
* @throws OutOfBoundsException
*
* @see: EventInterface::getParam()
*/
public function getParam(
// param key/name
string $name
);
/**
* Indicate whether or not to stop propagating this event.
*
* @param bool $flag
*
* @return $this
*
* @see: EventInterface::stopPropagation()
*/
public function stopPropagation(
// if true, event is not propagated further
bool $flag
): self;
/**
* Has this event indicated event propagation should stop?
*
* @return bool
*
* @see: EventInterface::isPropagationStopped()
*/
public function isPropagationStopped(): bool;
}
namespace BitFrame\EventManager;
// implements:
use \BitFrame\EventManager\EventManagerInterface;
// uses:
use \BitFrame\EventManager\EventManagerTrait;
/**
* Holds all the listeners for a particular event and
* methods to manage an event.
*/
class EventManager implements EventManagerInterface
{
use EventManagerTrait;
}
namespace BitFrame\Renderer;
/**
* A value object describing a (optionally) namespaced path
* in which templates reside.
*/
class TemplatePath
{
/** @var string */
protected $path;
/** @var null|string */
protected $namespace;
/**
* @param string $path
* @param null|string $namespace (optional, default: null
)
*/
public function __construct(
// directory path to store
string $path,
// namespace for the directory path
$namespace = null
);
/**
* Get the namespace.
*
* @return null|string
*/
public function getNamespace(): ?string;
/**
* Get the path.
*
* @return string
*/
public function getPath(): string;
/**
* Casts to string by returning the path only.
*
* @return string
*/
public function __toString(): string;
}
namespace BitFrame\Router;
use \Psr\Http\Server\MiddlewareInterface;
use \BitFrame\Router\RouteGroup;
// uses:
use \BitFrame\Router\RouteConditionTrait;
// exceptions:
use \InvalidArgumentException;
/**
* Holds data about a route including the methods, path,
* callback and group it belongs to, if any.
*/
class Route
{
use RouteConditionTrait;
/** @var string|callable */
private $callable;
/** @var RouteGroup */
private $group;
/** @var string[] */
private $methods;
/** @var string */
private $path;
/**
* @param array|string $methods
* @param string $path
* @param callable|string|array $handler
*/
public function __construct(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$methods,
// route path
string $path,
// route handler/callback
$handler
);
/**
* Get the callable.
*
* @return callable|MiddlewareInterface
*
* @throws InvalidArgumentException
*/
public function getCallable();
/**
* Set the callable.
*
* @param string|callable $callable
*
* @return Route
*/
public function setCallable(
// set handler/callback
$callable
): Route;
/**
* Get the parent group.
*
* @return RouteGroup
*/
public function getParentGroup(): RouteGroup;
/**
* Set the parent group.
*
* @param RouteGroup $group
*
* @return Route
*/
public function setParentGroup(
// set parent group
RouteGroup $group
): Route;
/**
* Get the path.
*
* @return string
*/
public function getPath(): string;
/**
* Set the path.
*
* @param string $path
*
* @return Route
*/
public function setPath(
// set router path
$path
): Route;
/**
* Get the methods.
*
* @return string[]
*/
public function getMethods(): array;
/**
* Get the methods.
*
* @param string[] $methods
*
* @return Route
*/
public function setMethods(
// router methods to set e.g. ['GET', 'POST'] etc.
array $methods
): Route;
}
namespace BitFrame\Router;
use \BitFrame\Router\Route;
use \BitFrame\Router\RouteGroup;
// implements:
use \BitFrame\Router\RouteCollectionInterface;
// uses:
use \BitFrame\Router\RouteCollectionMapTrait;
/**
* Stores routes.
*/
class RouteCollection implements RouteCollectionInterface
{
use RouteCollectionMapTrait;
/** @var Route[] */
private $routes = [];
/**
* Add a route to the map.
*
* @param array|string $method
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see: RouteCollectionInterface::map()
*/
public function map(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$method,
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a group of routes to the collection.
*
* @param string $prefix
* @param callable $group
*
* @return RouteGroup
*/
public function group(
// group prefix
$prefix,
// group handler/callback
callable $group
): RouteGroup;
/**
* Get stored routes from the collection.
*
* @return Route[]
*/
public function getData(): array;
}
use \BitFrame\Router\Route;
use \BitFrame\Router\RouteCollectionInterface;
// implements:
use \BitFrame\Router\RouteCollectionInterface;
// uses:
use \BitFrame\Router\RouteCollectionMapTrait;
use \BitFrame\Router\RouteConditionTrait;
/**
* Group multiple routes together under the same prefix.
*/
class RouteGroup implements RouteCollectionInterface
{
use RouteCollectionMapTrait;
use RouteConditionTrait;
/** @var callable */
protected $callback;
/** @var RouteCollectionInterface */
protected $collection;
/** @var string */
protected $prefix;
/**
* @param string $prefix
* @param callable $callback
* @param RouteCollectionInterface $collection
*/
public function __construct(
// group prefix
string $prefix,
// group handler/callback
callable $callback,
// route collection object
RouteCollectionInterface $collection
);
/**
* Process the group and ensure routes are added to the collection.
*/
public function __invoke();
/**
* Route map.
*
* @param string|array $method
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see: RouteCollectionMapTrait::map()
*/
public function map(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$method,
// route path
string $path,
// route handler/callback
$handler
): Route;
}
namespace BitFrame;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Router\RouteCollection;
use \BitFrame\Data\ApplicationData;
use \BitFrame\Dispatcher\DispatcherInterface;
// implements:
use \ArrayAccess;
use \Fig\Http\Message\StatusCodeInterface;
use \BitFrame\Router\RouteCollectionInterface;
use \BitFrame\EventManager\EventManagerInterface;
// uses:
use \BitFrame\Data\ApplicationDataTrait;
use \BitFrame\Dispatcher\DispatcherAwareTrait;
use \BitFrame\Router\RouterTrait;
// exceptions:
use \InvalidArgumentException;
/**
* The central point of a BitFrame application which
* stores routes andshared data, runs middlewares, and
* helps manage events and endpoints.
*/
class Application implements
ArrayAccess,
RouteCollectionInterface,
StatusCodeInterface,
EventManagerInterface
{
use ApplicationDataTrait;
use RouterTrait;
use DispatcherAwareTrait;
/** @var ApplicationData */
private $data;
/** @var array */
private $config;
/** @var ServerRequestInterface */
private $originalRequest;
/**
* @param array $config (optional, default: []
)
*/
public function __construct(
// configuration options
array $config = []
);
/**
* Run Application.
*
* @param callable|MiddlewareInterface|array $middleware
* (optional, default: null
)
* @param ServerRequestInterface|null $request
* (optional, default: null
)
*
* @return $this
*
* @throws InvalidArgumentException
*/
public function run(
// single/multiple PSR-15/PSR-7 based middleware
$middleware = null,
// http request object
?ServerRequestInterface $request = null
): self;
/**
* Reset application to defaults.
*/
public function reset();
/**
* Store the specified data.
*
* @see: ArrayAccess::offsetSet()
* @see: ApplicationDataTrait::offsetSet()
*/
public function offsetSet(
// key to identify the $value in store
$key,
// value to store
$value
);
/**
* Remove the data by the specified key.
*
* @see: ArrayAccess::offsetUnset()
* @see: ApplicationDataTrait::offsetUnset()
*/
public function offsetUnset(
// key to unset data for
$key
);
/**
* Get stored application data.
*
* @return mixed
*
* @see: ApplicationDataTrait::getData()
*/
public function getData(): ApplicationData;
/**
* Get Application data as array.
*
* @return mixed[]
*/
public function getDataArray(): array;
/**
* Get Http request object.
*
* @return ServerRequestInterface
*/
public function getRequest(): ServerRequestInterface;
/**
* Get original Http request object as received by
* your web server.
*
* @return ServerRequestInterface
*/
public function getOriginalRequest(): ServerRequestInterface;
/**
* Checks for reserved keys.
*
* @param string $key
*
* @throws InvalidArgumentException
*/
private function validateKey(
// key to validate
$key
);
}
namespace BitFrame\Data;
// exceptions:
use \OutOfBoundsException;
// follows:
use \ArrayAccess;
/**
* Common implementation of the \ArrayAccess interface
* methods.
*/
trait ApplicationDataTrait
{
/**
* Store the specified data.
*
* @see: ArrayAccess::offsetSet()
*/
public function offsetSet(
// key to identify the $value in store
$key,
// value to store
$value
);
/**
* Remove the data by the specified key.
*
* @throws OutOfBoundsException
*
* @see: ArrayAccess::offsetUnset()
*/
public function offsetUnset(
// key to unset data for
$key
);
/**
* Check if key exists.
*
* @see: ArrayAccess::offsetExists()
*/
public function offsetExists(
// key to check
$key
): bool;
/**
* Value to retrieve by key.
*
* @throws OutOfBoundsException
*
* @see: ArrayAccess::offsetGet()
*/
public function offsetGet(
// key get value by
$key
);
/**
* Get stored application data.
*
* @return mixed
*/
abstract public function getData();
}
namespace BitFrame\Delegate;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Delegate\CallableDelegate;
/**
* Decorate PSR-7 style callable delegates as PSR-15
* compatible, processable http requests.
*/
trait CallableMiddlewareTrait
{
/**
* PSR-7 style callable.
*
* @param $request ServerRequestInterface
* @param $response ResponseInterface
* @param $next callable
*
* @return ResponseInterface
*/
public function __invoke(
// http request object
ServerRequestInterface $request,
// http response object
ResponseInterface $response,
// next callable in chain/queue
callable $next
): ResponseInterface;
/**
* PSR-15 based middleware implementation.
*
* @param $request ServerRequestInterface
* @param $handler RequestHandlerInterface
*
* @return ResponseInterface
*/
abstract public function process(
// http request to process
ServerRequestInterface $request,
// http request handler object
RequestHandlerInterface $handler
): ResponseInterface;
}
namespace BitFrame\Dispatcher;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Factory\HttpMessageFactory;
use \BitFrame\EventManager\EventManagerInterface;
// uses:
use \BitFrame\EventManager\EventManagerAwareTrait;
// follows:
use \BitFrame\Dispatcher\DispatcherInterface;
/**
* This trait exposes the Dispatcher to any 'aware' class.
*/
trait DispatcherAwareTrait
{
use EventManagerAwareTrait;
/** @var DispatcherInterface */
private $dispatcher;
/** @var ResponseInterface */
private $response;
/** @var ServerRequestInterface */
private $request;
/**
* Add a middleware.
*
* @param callable|MiddlewareInterface|array $middleware
*
* @see DispatcherInterface::addMiddleware()
*/
public function addMiddleware(
// middleware to add
$middleware
): self;
/**
* Set middleware dispatcher object.
*
* @param DispatcherInterface $dispatcher
*
* @return $this;
*/
public function setDispatcher(
// middleware dispatcher object
DispatcherInterface $dispatcher
): self;
/**
* Set Request object.
*
* @param ServerRequestInterface $request
*
* @return $this
*/
public function setRequest(
// http request object
ServerRequestInterface $request
): self;
/**
* Get Http Request object.
*
* @return ServerRequestInterface
*/
public function getRequest(): ServerRequestInterface;
/**
* Get Http Response object.
*
* @return ResponseInterface
*/
public function getResponse(): ResponseInterface;
/**
* Get middleware dispatcher object.
*
* @return DispatcherInterface
*/
public function getDispatcher(): DispatcherInterface;
/**
* Get the Event Manager object.
*
* @return EventManagerInterface
*/
public function getEventManager(): EventManagerInterface;
}
namespace BitFrame\EventManager;
// follows:
use \BitFrame\EventManager\EventManagerInterface;
/**
* This trait exposes the EventManager to any 'aware' class.
*/
trait EventManagerAwareTrait
{
/**
* Attaches a listener to an event.
*
* @param string $eventName
* @param callable $callback
* @param int $priority (optional, default: 0
)
*
* @return $this
*
* @see EventManagerInterface::attach()
*/
public function attach(
// the event name to attach to
string $eventName,
// callable function
callable $callback,
// priority at which the $callback will be executed
int $priority = 0
): self;
/**
* Detaches a listener from an event.
*
* @param string $eventName
* @param callable $callback
*
* @return bool
*
* @see EventManagerInterface::detach()
*/
public function detach(
// the event name to detach $callback from
string $eventName,
// callable function
callable $callback
): bool;
/**
* Clear all listeners (for a given event).
*
* @param string|null $eventName (optional, default: null
)
*
* @return $this
*
* @see EventManagerInterface::clearListeners()
*/
public function clearListeners(
// event name to clear listeners from
// if null, event listeners for all events will be cleared
?string $eventName = null
): self;
/**
* Trigger an event.
*
* Can accept an Event object or will create one if not passed.
*
* @param string|Event $event
* @param null|string|object $target (optional, default: null
)
* @param array|object $argv (optional, default: []
)
*
* @return $this
*
* @see EventManagerInterface::trigger()
*/
public function trigger(
// event name to create new Event object,
// or an Event object
$event,
// event target
$target = null,
// params to pass along with the event
// (these params are combined with ones in
// the Event object, if any — if same
// string keys, then the later value
// overwrites the previous one)
$argv = []
): self;
/**
* Get all event's listeners.
*
* @param string $eventName
*
* @return array
*
* @see EventManagerInterface::getListeners()
*/
public function getListeners(
// event name to get listeners for
$eventName
): array;
/**
* Set the event manager object.
*
* @param EventManagerInterface $eventManager
*
* @return $this
*/
public function setEventManager(
// event manager object
EventManagerInterface $eventManager
): self;
/**
* Get the event manager object.
*
* @return EventManagerInterface
*/
abstract public function getEventManager(): EventManagerInterface;
}
namespace BitFrame\EventManager;
// follows:
use \BitFrame\EventManager\EventManagerInterface;
/**
* Common implementation of an event manager.
*/
trait EventManagerTrait
{
/** @var array */
private $listeners = [];
/**
* Attaches a listener to an event.
*
* @param string $eventName
* @param callable $callback
* @param int $priority (optional, default: 0
)
*
* @return $this
*
* @see EventManagerInterface::attach()
*/
public function attach(
// the event name to attach to
string $eventName,
// callable function
callable $callback,
// priority at which the $callback will be executed
int $priority = 0
): self;
/**
* Detaches a listener from an event.
*
* @param string $eventName
* @param callable $callback
*
* @return bool
*
* @see EventManagerInterface::detach()
*/
public function detach(
// the event name to detach $callback from
string $eventName,
// callable function
callable $callback
): bool;
/**
* Clear all listeners (for a given event).
*
* @param string|null $eventName (optional, default: null
)
*
* @return $this
*
* @see EventManagerInterface::clearListeners()
*/
public function clearListeners(
// event name to clear listeners from
// if null, event listeners for all events will be cleared
?string $eventName = null
): self;
/**
* Trigger an event.
*
* Can accept an Event object or will create one if not passed.
*
* @param string|Event $event
* @param null|string|object $target (optional, default: null
)
* @param array|object $argv (optional, default: []
)
*
* @return $this
*
* @see EventManagerInterface::trigger()
*/
public function trigger(
// event name to create new Event object,
// or an Event object
$event,
// event target
$target = null,
// params to pass along with the event
// (these params are combined with ones in
// the Event object, if any — if same
// string keys, then the later value
// overwrites the previous one)
$argv = []
): self;
/**
* Get all event's listeners.
*
* @param string $eventName
*
* @return array
*
* @see EventManagerInterface::getListeners()
*/
public function getListeners(
// event name to get listeners for
$eventName
): array;
}
namespace BitFrame\Message;
use \Psr\Http\Message\{ResponseInterface, UriInterface};
use \BitFrame\Factory\HttpMessageFactory;
// exceptions:
use \InvalidArgumentException;
/**
* Provides extended, proprietary, functionality for
* the PSR-7 Http Request interface.
*/
trait RequestTrait
{
/**
* Get the URL endpoints.
*
* If the specified $index is not found, an error is
* not raised, instead [] is returned.
*
* Note: This method is not part of the PSR standard.
*
* @return string|array|null
*/
public function getEndpoints();
/**
* Get a URL endpoint.
*
* Note:
*
* - This method is not part of the PSR standard.
*
* - $index = 1 means the first endpoint (as opposed to 0 used
* by array indexes).
*
* @param int $index
* @param mixed $default (optional, default: null
)
*
* @return string|array|null
*/
public function getEndpoint(
// the endpoint to retrieve where first endpoint is
// represented by the index: 1
int $index,
// $default value to return if the $index does
// not exist
$default = null
);
/**
* Get a parameter value from query string.
*
* Note: This method is not part of the PSR standard.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function getQueryParam(
// the attribute name
$key,
// $default value to return if the attribute does
// not exist
$default = null
);
/**
* Get cookie value from cookies sent by the client
* to the server.
*
* Note: This method is not part of the PSR standard.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function getCookieParam(
// the attribute name
$key,
// $default value to return if the attribute does
// not exist
$default = null
);
/**
* Check if any part of specified endpoints match the
* url endpoints.
*
* Note: This method is not part of the PSR standard.
*
* @param string|string[] $urlPaths
* @param string $basePath (optional, default: ''
)
* @param string $strict (optional, default: false
)
*
* @return bool
*
* @throws InvalidArgumentException
*/
public function hasEndpoint(
// single/array of paths to match
$urlPaths,
// prepend path to specified url paths
string $basePath = '',
// if true, specified endpoints must match exactly
bool $strict = false
): bool;
/**
* Check if the specified endpoint matches exactly
* to the one in the url.
*
* Note: This method is not part of the PSR standard.
*
* @param string|string[] $urlPath
* @param string $basePath (optional)
*
* @return bool
*/
public function isEndpoint(
// single/array of paths to match
$urlPath,
// prepend path to specified url paths
string $basePath = ''
): bool;
/**
* Check if the request is an XHR request.
*
* Note: This method is not part of the PSR standard.
*
* @return bool
*/
public function isXhr();
/**
* Get normalized uri path.
*
* In case document root (such as DOCUMENT_ROOT in apache) is not
* defined for the folder root, this would attempt to normalize
* the uri such that root folders are stripped from the path.
*
* Note: This method is not part of the PSR standard.
*
* @return string
*/
public function getNormalizedUriPath(): string;
}
namespace BitFrame\Message;
use \Psr\Http\Message\ResponseInterface;
use \Psr\Http\Message\UriInterface;
// exceptions:
use \InvalidArgumentException;
use \UnexpectedValueException;
use \BitFrame\Exception\HttpException
use \BitFrame\Exception\FileNotReadableException
/**
* Provides extended, non-standard, functionality for
* the PSR-7 Http Response interface.
*/
trait ResponseTrait
{
/**
* Http Response with redirect.
*
* Note: This method is not part of the PSR standard,
* and is merely meant to be a shortcut for
* $response->withHeader('Location', ..)->withStatus(3xx);
*
* This method prepares the response object to return an HTTP Redirect
* response to the client.
*
* @param string|UriInterface $url
* @param int|null $status (optional, default: null
)
*
* @return ResponseInterface
*
* @throws InvalidArgumentException
* @throws HttpException
*/
public function withRedirect(
// the redirect destination
$url,
// the redirect http status code
// (if null and response status is 200 so far, then
// a status 302 is set by default)
?int $status = null
): ResponseInterface;
/**
* Http Response as JSON/JSONP.
*
* Note: This method is not part of the PSR standard,
* and is merely meant to serve as a shortcut for
* preparing json data with correct headers along with
* whatever response body that may exist.
*
* This method prepares the response object to return
* an HTTP Json response to the client.
*
* @param mixed $data
* @param int $status (optional, default: null
)
* @param string $bodyKeyName (optional, default: null
)
* @param string $jsonpCallback (optional, default: null
)
* @param int $encodingOptions (optional, default: 0
)
*
* @return ResponseInterface
*
* @throws UnexpectedValueException
*/
public function withJson(
// the data
$data,
// the http status code
?int $status = null,
// name of index containing response body; it's
// only included if key name is not null
?string $bodyKeyName = null,
// callback name for JSONP calls; it's only added
// if callback name is not null
?string $jsonpCallback = null,
// json encoding options
int $encodingOptions = 0
): ResponseInterface;
/**
* Http Response to force a file download.
*
* Note: This method is not part of the PSR standard,
* and is merely meant to serve as a shortcut for forcing
* a file download with correct headers.
*
* This method prepares the response object to force the
* specified file to be downloaded.
*
* @param string $file
* @param string $spoofFileName (optional, default: ''
)
*
* @return ResponseInterface
*
* @throws FileNotReadableException
*/
public function withDownload(
// file name
string $file,
// file name the client sees
string $spoofFileName = ''
): ResponseInterface;
}
namespace BitFrame\Router;
use BitFrame\Router\Route;
// follows:
use \BitFrame\Router\RouteCollectionInterface;
/**
* Common implementation of the http router methods.
*/
trait RouteCollectionMapTrait
{
/**
* Add a route to the map.
*
* @param array|string $method
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::map()
*/
abstract public function map(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$methods,
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to GET HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::get()
*/
public function get(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to POST HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::post()
*/
public function post(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to PUT HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::put()
*/
public function put(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to PATCH HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::patch()
*/
public function patch(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to DELETE HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::delete()
*/
public function delete(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to HEAD HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::head()
*/
public function head(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to OPTIONS HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouteCollectionInterface::options()
*/
public function options(
// route path
string $path,
// route handler/callback
$handler
): Route;
}
namespace BitFrame\Router;
/**
* Provides common router-related methods.
*/
trait RouteConditionTrait
{
/** @var string */
protected $host;
/** @var string */
protected $scheme;
/**
* Get the host.
*
* @return string
*/
public function getHost(): ?string;
/**
* Set the host.
*
* @param string $host
*
* @return $this
*/
public function setHost(
// host name
$host
): self;
/**
* Get the scheme.
*
* @return string
*/
public function getScheme(): ?string;
/**
* Set the scheme.
*
* @param string $scheme
*
* @return $this
*/
public function setScheme(
// url scheme
$scheme
): self;
}
namespace BitFrame\Router;
use \BitFrame\Router\Route;
use \BitFrame\Router\RouteGroup;
use \BitFrame\Router\RouteCollectionMapTrait;
use \BitFrame\Router\RouteCollectionInterface;
// follows:
use \BitFrame\Router\RouterInterface;
/**
* Common methods that all routers can implement.
*/
trait RouterTrait
{
use RouteCollectionMapTrait;
/** @var RouteCollectionInterface */
private $routeCollection = null;
/**
* Route map.
*
* @param array|string $method
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*
* @see RouterInterface::map()
*/
public function map(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$method,
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a group of routes to the collection.
*
* @param string $prefix
* @param callable $group
*
* @return RouteGroup
*
* @see RouterInterface::group()
*/
public function group(
// group prefix
string $prefix,
// callback function
callable $group
): RouteGroup;
/**
* Get stored routes.
*
* @return Route[]
*
* @see RouterInterface::getRoutes()
*/
public function getRoutes(): array;
/**
* Get the RouteCollection object.
*
* @return RouteCollectionInterface
*/
public function getRouteCollection(): RouteCollectionInterface;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Factory\EventManagerFactoryInterface;
use \BitFrame\Factory\DispatcherFactoryInterface;
use \BitFrame\Factory\RouteCollectionFactoryInterface;
use \BitFrame\EventManager\EventManagerInterface;
use \BitFrame\Dispatcher\DispatcherInterface;
use \BitFrame\Router\RouteCollectionInterface;
/**
* Factory methods for application components.
*/
class ApplicationFactory
{
/** @var EventManagerFactoryInterface */
private static $eventManagerFactory;
/** @var DispatcherFactoryInterface */
private static $dispatcherFactory;
/** @var RouteCollectionFactoryInterface */
private static $routeCollectionFactory;
/**
* Set a custom EventManager factory.
*
* @param EventManagerFactoryInterface $eventManagerFactory
*/
public static function setEventManagerFactory(
// event manager factory class to use
EventManagerFactoryInterface $eventManagerFactory
): self;
/**
* Set a custom Dispatcher factory.
*
* @param DispatcherInterface $dispatcherFactory
*/
public static function setDispatcherFactory(
// middleware dispatcher factory class to use
DispatcherFactoryInterface $dispatcherFactory
): self;
/**
* Set a custom RouterCollection factory.
*
* @param RouteCollectionFactoryInterface $routeCollectionFactory
*/
public static function setRouteCollectionFactory(
// route collection factory class to use
RouteCollectionFactoryInterface $routeCollectionFactory
): self;
/**
* Create an EventManagerInterface instance.
*
* @return EventManagerInterface
*/
public static function createEventManager(): EventManagerInterface;
/**
* Create a DispatcherInterface instance.
*
* @param ResponseInterface $response
*
* @return DispatcherInterface
*/
public static function createDispatcher(
// http response object
ResponseInterface $response
): DispatcherInterface;
/**
* Create a RouteCollectionInterface instance.
*
* @return RouteCollectionInterface
*/
public static function createRouteCollection(): RouteCollectionInterface;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Dispatcher\DispatcherInterface;
// implements:
use \BitFrame\Factory\DispatcherFactoryInterface;
/**
* Create the default middleware dispatcher.
*/
class DispatcherFactory implements DispatcherFactoryInterface
{
/**
* Create a new middleware dispatcher.
*
* @param ResponseInterface $response
*
* @return DispatcherInterface
*
* @see: DispatcherFactoryInterface::createDispatcher()
*/
public function createDispatcher(
// http response object
ResponseInterface $response
): DispatcherInterface;
}
namespace BitFrame\Factory;
use \BitFrame\EventManager\EventManagerInterface;
// implements:
use \BitFrame\Factory\EventManagerFactoryInterface;
/**
* Create the default event manager.
*/
class EventManagerFactory implements
EventManagerFactoryInterface
{
/**
* Create a new event manager.
*
* @return EventManagerInterface
*
* @see: EventManagerFactoryInterface::createEventManager()
*/
public function createEventManager(): EventManagerInterface;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\ServerRequestFactoryInterface;
use \Psr\Http\Message\ResponseFactoryInterface;
use \Psr\Http\Message\StreamFactoryInterface;
use \Psr\Http\Message\UriFactoryInterface;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
use \Psr\Http\Message\StreamInterface;
use \Psr\Http\Message\UriInterface;
/**
* Creates a new HTTP object, as defined by PSR-7.
*/
class HttpMessageFactory
{
/** @var ResponseFactoryInterface */
private static $responseFactory;
/** @var ServerRequestFactoryInterface */
private static $serverRequestFactory;
/** @var StreamFactoryInterface */
private static $streamFactory;
/** @var UriFactoryInterface */
private static $uriFactory;
/**
* Set a custom Response factory.
*
* @param ResponseFactoryInterface $responseFactory
*/
public static function setResponseFactory(
// http response factory class to use
ResponseFactoryInterface $responseFactory
): self;
/**
* Set a custom ServerRequest factory.
*
* @param ServerRequestFactoryInterface $serverRequestFactory
*/
public static function setServerRequestFactory(
// http request factory class to use
ServerRequestFactoryInterface $serverRequestFactory
): self;
/**
* Set a custom Stream factory.
*
* @param StreamFactoryInterface $streamFactory
*/
public static function setStreamFactory(
// http stream factory class to use
StreamFactoryInterface $streamFactory
): self;
/**
* Set a custom Uri factory.
*
* @param UriFactoryInterface $uriFactory
*/
public static function setUriFactory(
// http uri factory class to use
UriFactoryInterface $uriFactory
): self;
/**
* Set a custom UploadedFile factory.
*
* @param UploadedFileFactoryInterface $uploadedFileFactory
*/
public static function setUploadedFileFactory(
// http uploaded file factory class to use
UriFactoryInterface $uploadedFileFactory
): self;
/**
* Creates a Response instance.
*
* @param int $code (optional, default: 200
)
* @param string $reasonPhrase (optional, default: ''
)
*
* @return ResponseInterface
*/
public static function createResponse(
// http status code
int $code = 200
// reason phrase to associate with status $code
string $reasonPhrase = ''
): ResponseInterface;
/**
* Creates a new server request.
*
* @param string $method (optional, default: 'GET'
)
* @param string|null $uri (optional, default: null
)
* @param array $serverParams (optional, default: []
)
*
* @return ServerRequestInterface
*/
public static function createServerRequest(
// http request method
string $method = 'GET',
// http request uri
string $uri = '',
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $serverParams = []
): ServerRequestInterface;
/**
* Create a new server request from server variables.
*
* The request method and uri are marshalled from $server.
*
* @param array $server (optional, default: []
)
*
* @return ServerRequestInterface
*/
public static function createServerRequestFromArray(
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $server
): ServerRequestInterface;
/**
* Creates a Stream instance with content.
*
* @param string $content (optional, default: ''
)
*
* @return StreamInterface
*/
public static function createStream(
// stream content
string $content = ''
): StreamInterface;
/**
* Creates a Stream instance from file.
*
* @param string $filename
* @param string $mode (optional, default: 'r'
)
*
* @return StreamInterface
*/
public static function createStreamFromFile(
// name of the file to create stream from
string $filename,
// file open mode
string $mode = 'r'
): StreamInterface;
/**
* Creates a Stream instance from resource returned
* by fopen.
*
* @param resource|null $resource
*
* @return StreamInterface
*/
public static function createStreamFromResource(
// stream resource
$resource
): StreamInterface;
/**
* Creates a Uri instance.
*
* @param string $uri (optional, default: ''
)
*
* @return UriInterface
*/
public static function createUri(
// a string uri
string $uri = ''
): UriInterface;
/**
* Creates an UploadedFile instance.
*
* @param string|StreamInterface $file
* @param null|int $size (optional, default: null
)
* @param int $error (optional, default: \UPLOAD_ERR_OK
)
* @param null|string $clientFilename (optional, default: null
)
* @param null|string $clientMediaType (optional, default: null
)
*
* @return UploadedFileInterface
*/
public static function createUploadedFile(
// file name or instance of StreamInterface
$file,
// size of file; if null
it will be
// determined by checking the size of the file.
?int $size = null,
// file upload error code
int $error = \UPLOAD_ERR_OK,
// file name as provided by the client, if any.
?string $clientFilename = null,
// media type as provided by the client, if any.
?string $clientMediaType = null
): UploadedFileInterface;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Message\ResponseTrait;
// implements:
use \Psr\Http\Message\ResponseFactoryInterface;
/**
* Create the default http response object.
*/
class ResponseFactory implements ResponseFactoryInterface
{
/**
* Create a new response.
*
* @param integer $code HTTP status code
* @param string $reasonPhrase (optional, default: ''
)
*
* @return ResponseInterface
*
* @see: ResponseFactoryInterface::createResponse()
*/
public function createResponse(
// http status code
int $code = 200,
// reason phrase to associate with status $code
string $reasonPhrase = ''
): ResponseInterface;
}
namespace BitFrame\Factory;
use \BitFrame\Router\RouteCollectionInterface;
// implements:
use \BitFrame\Factory\RouteCollectionFactoryInterface;
/**
* Create the default route collection class.
*/
class RouteCollectionFactory implements
RouteCollectionFactoryInterface
{
/**
* Create a new router collection.
*
* @return RouteCollectionInterface
*
* @see: RouteCollectionFactoryInterface::createRouteCollection()
*/
public function createRouteCollection(): RouteCollectionInterface;
}
namespace BitFrame\Factory;
use \stdClass;
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\UriInterface;
use \BitFrame\Message\RequestTrait;
use \BitFrame\Factory\HttpMessageFactory;
// implements:
use \Psr\Http\Message\ServerRequestFactoryInterface;
/**
* Creates instances of PSR-7 http server request.
*/
class ServerRequestFactory implements
ServerRequestFactoryInterface
{
/**
* Create a new server request
*
* @param string $method
* @param UriInterface|string $uri
* @param array $serverParams (optional, default: []
)
*
* @return ServerRequestInterface
*
* @see: ServerRequestFactoryInterface::createServerRequest()
*/
private static function createServerRequest(
// http request method
string $method,
// http request uri
$uri,
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $serverParams = []
): ServerRequestInterface;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\StreamInterface;
// implements:
use \Psr\Http\Message\StreamFactoryInterface;
// exceptions:
use \InvalidArgumentException;
use \BitFrame\Exception\FileNotReadableException;
/**
* Class to create instances of PSR-7 streams.
*/
class StreamFactory implements StreamFactoryInterface
{
/**
* Create a new stream from a string.
*
* The stream SHOULD be created with a temporary
* resource.
*
* @param string $content (optional, default: ''
)
*
* @return StreamInterface
*
* @see: StreamFactoryInterface::createStream()
*/
public function createStream(
// stream content
string $content = ''
): StreamInterface;
/**
* Create a stream from an existing file.
*
* The file MUST be opened using the given mode, which may
* be any mode supported by the `fopen` function.
*
* The `$filename` MAY be any string supported by `fopen()`.
*
* @param string $filename
* @param string $mode (optional, default: 'r'
)
*
* @throws InvalidArgumentException
* If the file cannot be opened using the mode requested.
*
* @return StreamInterface
*
* @throws FileNotReadableException
*
* @see: StreamFactoryInterface::createStreamFromFile()
*/
public function createStreamFromFile(
// name of the file to create stream from
string $filename,
// file open mode
string $mode = 'r'
): StreamInterface;
/**
* Create a new stream from an existing resource.
*
* The stream MUST be readable and may be writable.
*
* @param resource $resource
*
* @return StreamInterface
*
* @see: StreamFactoryInterface::createStreamFromResource()
*/
public function createStreamFromResource(
// stream resource
$resource
): StreamInterface;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\UriInterface;
// implements:
use \Psr\Http\Message\UriFactoryInterface;
// exceptions:
use \InvalidArgumentException;
/**
* Class to create instances of PSR-7 uri.
*/
class UriFactory implements UriFactoryInterface
{
/**
* Create a new URI.
*
* @param string $uri (optional, default: ''
)
*
* @return UriInterface
*
* @throws InvalidArgumentException
* If the given URI cannot be parsed.
*
* @see: UriFactoryInterface::createUri()
*/
public function createUri(
// a string uri
string $uri = ''
): UriInterface;
}
namespace BitFrame\Dispatcher;
// implements:
use \Psr\Http\Server\RequestHandlerInterface;
/**
* Representation of a middleware dispatcher.
*/
interface DispatcherInterface extends
RequestHandlerInterface
{
/**
* Add a middleware.
*
* @param callable|MiddlewareInterface|array $middleware
*/
public function addMiddleware(
// middleware to add
$middleware
);
/**
* Reset pending and processed middleware queues.
*/
public function clear();
/**
* Get all pending middleware.
*
* @param string|null $chain
*
* @return array
*/
public function getPendingMiddleware(): array;
/**
* Get all processed middleware.
*
* @return array
*/
public function getProcessedMiddleware(): array;
/**
* Check if dispatcher is running (processing middleware).
*
* @return bool
*/
public function isRunning(): bool;
/**
* Check if there are pending middleware.
*
* @return bool
*/
public function hasMiddleware(): bool;
}
namespace BitFrame\EventManager;
/**
* Representation of an event.
*/
interface EventInterface
{
/**
* Get event name.
*
* @return string
*/
public function getName(): string;
/**
* Get target/context from which event was triggered.
*
* @return null|string|object
*/
public function getTarget();
/**
* Get parameters passed to the event.
*
* @return array
*/
public function getParams(): array;
/**
* Get a single parameter by name.
*
* @param string $name
*
* @return mixed
*/
public function getParam(
// param key/name
string $name
);
/**
* Set the event name.
*
* @param string $name
*/
public function setName(
// name of the event
string $name
);
/**
* Set the event target.
*
* @param null|string|object $target
*/
public function setTarget(
// target linked to the event
$target
);
/**
* Set event parameters.
*
* @param array $params
*/
public function setParams(
// params to pass along with the event
array $params
);
/**
* Indicate whether or not to stop propagating this event.
*
* @param bool $flag
*/
public function stopPropagation(
// if true, event is not propagated further
bool $flag
);
/**
* Has this event indicated event propagation should stop?
*
* @return bool
*/
public function isPropagationStopped(): bool;
}
namespace BitFrame\EventManager;
/**
* Representation of an event manager.
*/
interface EventManagerInterface
{
/**
* Attaches a listener to an event.
*
* @param string $eventName
* @param callable $callback
* @param int $priority (optional, default: 0
)
*/
public function attach(
// the event name to attach to
string $eventName,
// callable function
callable $callback,
// priority at which the $callback will be executed
int $priority = 0
);
/**
* Detaches a listener from an event.
*
* @param string $eventName
* @param callable $callback
*
* @return bool
*/
public function detach(
// the event name to detach $callback from
string $eventName,
// callable function
callable $callback
): bool;
/**
* Clear all listeners (for a given event).
*
* @param string|null $eventName (optional, default: null
)
*/
public function clearListeners(
// event name to clear listeners from
// if null, event listeners for all events will be cleared
?string $eventName = null
);
/**
* Trigger an event.
*
* Can accept an Event object or will create one if not passed.
*
* @param string|Event $event
* @param null|string|object $target (optional, default: null
)
* @param array|object $argv (optional, default: []
)
*/
public function trigger(
// event name to create new Event object,
// or an Event object
$event,
// event target
$target = null,
// params to pass along with the event
// (these params are combined with ones in
// the Event object, if any — if same
// string keys, then the later value
// overwrites the previous one)
$argv = []
);
/**
* Get all event's listeners.
*
* @param string $eventName
*
* @return array
*/
public function getListeners(
// event name to get listeners for
$eventName
): array;
}
namespace BitFrame\Factory;
use \Psr\Http\Message\ResponseInterface;
use \BitFrame\Dispatcher\DispatcherInterface;
/**
* Representation of an dispatcher factory.
*/
interface DispatcherFactoryInterface
{
/**
* Create a new middleware dispatcher.
*
* @param ResponseInterface $response
*
* @return DispatcherInterface
*/
public function createDispatcher(
// http response object
ResponseInterface $response
): DispatcherInterface;
}
namespace BitFrame\Factory;
use \BitFrame\EventManager\EventManagerInterface;
/**
* Representation of an event manager factory.
*/
interface EventManagerFactoryInterface
{
/**
* Create a new event manager.
*
* @return EventManagerInterface
*/
public function createEventManager(): EventManagerInterface;
}
namespace BitFrame\Factory;
use \BitFrame\Router\RouteCollectionInterface;
/**
* Representation of route collection factory.
*/
interface RouteCollectionFactoryInterface
{
/**
* Create a new router collection.
*
* @return RouteCollectionInterface
*/
public function createRouteCollection(): RouteCollectionInterface;
}
namespace BitFrame\Renderer;
/**
* Interface defining required template capabilities.
*/
interface TemplateInterface
{
/** @var string Value indicating all templates;
* used with `addDefaultParam()`.
*/
public const TEMPLATE_ALL = '*';
/**
* Render a template, optionally with parameters.
*
* Implementations MUST support the `namespace::template`
* naming convention, and allow omitting the filename
* extension.
*
* @param string $templateName
* @param array $data (optional, default: []
)
*
* @return string
*/
public function render(
// name of the template to render
string $templateName,
// data to pass along to the template
array $data = []
): string;
/**
* Add a default parameter to use with a template.
*
* Use this method to provide a default parameter to use
* when a template is rendered. The parameter may be overridden
* by providing it when calling `render()`, or by calling this
* method again with a null value.
*
* The parameter will be specific to the template name provided.
* To make the parameter available to any template, pass the
* TEMPLATE_ALL constant for the template name.
*
* If the default parameter existed previously, subsequent
* invocations with the same template name and parameter name
* will overwrite.
*
* @param string $templateName
* @param array $params
*/
public function addDefaultParam(
// name of template to which the param applies;
// use TEMPLATE_ALL to apply to all templates
string $templateName,
// key/value data pair
$params
);
/**
* Add a template path to the engine.
*
* Adds a template path, with optional namespace the templates
* in that path provide.
*
* @param string $path
* @param string|null $namespace (optional, default: null
)
*/
public function addPath(
// path to add
string $path,
// namespace for the $path
?string $namespace = null
);
/**
* Retrieve configured paths from the engine.
*
* @return TemplatePath[]
*/
public function getPaths(): array;
}
namespace BitFrame\Router;
use BitFrame\Router\Route;
/**
* Representation of a route collection.
*/
interface RouteCollectionInterface
{
/**
* Add a route to the map.
*
* @param array|string $method
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function map(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$method,
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to GET HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function get(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to POST HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function post(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to PUT HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function put(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to PATCH HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function patch(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to DELETE HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function delete(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to HEAD HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function head(
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a route that responds to OPTIONS HTTP method.
*
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function options(
// route path
string $path,
// route handler/callback
$handler
): Route;
}
namespace BitFrame\Router;
use \BitFrame\Router\Route;
use \BitFrame\Router\RouteGroup;
// extends:
use \Psr\Http\Server\MiddlewareInterface;
use \BitFrame\Router\RouteCollectionInterface;
/**
* Interface defining required router capabilities.
*/
interface RouterInterface extends
MiddlewareInterface,
RouteCollectionInterface
{
/**
* Route map.
*
* @param array|string $method
* @param string $path
* @param callable|string|array $handler
*
* @return Route
*/
public function map(
// single/multiple http methods (uppercase only)
// e.g. 'GET' or ['GET', 'POST'] etc.
$method,
// route path
string $path,
// route handler/callback
$handler
): Route;
/**
* Add a group of routes to the collection.
*
* @param string $prefix
* @param callable $group
*
* @return RouteGroup
*/
public function group(
// group prefix
$prefix,
// group handler/callback
callable $group
): RouteGroup;
/**
* Get stored routes.
*
* @return Route[]
*/
public function getRoutes(): array;
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException
/**
* Represents an HTTP 400 error.
*/
class BadRequestException extends HttpException
{
/**
* @param string $message (optional, default: null
)
*/
public function __construct(
// if no message is given, defaults to 'Bad Request'
string $message = null
);
}
namespace BitFrame\Exception;
// extends:
use \Exception;
/**
* Represents application/PHP errors.
*/
class ErrorException extends Exception
{
}
namespace BitFrame\Exception;
// extends:
use \RuntimeException
/**
* Represents a 404 file not found/readable error.
*/
class FileNotReadableException extends RuntimeException
{
/**
* @param string $path
*/
public function __construct(
// file path
string $path
);
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException
/**
* Represents an HTTP 403 error.
*/
class ForbiddenException extends HttpException
{
/**
* @param string $message (optional, default: null
)
*/
public function __construct(
// if no message is given, defaults to 'Forbidden'
string $message = null
);
}
namespace BitFrame\Exception;
// extends:
use \RuntimeException
/**
* Represents an HTTP error.
*/
class HttpException extends RuntimeException
{
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException;
/**
* Represents an HTTP 500 error.
*/
class InternalErrorException extends HttpException
{
/**
* @param string $message (optional, default: null
)
*/
public function __construct(
// if no message is given, defaults to 'Internal Server Error'
$message = null
);
}
namespace BitFrame\Exception;
// extends:
use \RuntimeException
/**
* Represents an invalid middleware error.
*/
class InvalidMiddlewareException extends
RuntimeException
{
/**
* @param string $message
* @param int $code (optional, default: 500
)
*/
public function __construct(
// message to display
$message,
// http status code
$code = 500
);
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException;
/**
* Represents an HTTP 405 error.
*/
class MethodNotAllowedException extends HttpException
{
/**
* @param string $method
*/
public function __construct(
// name of the method
$method
);
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException;
/**
* Not Implemented Exception - used when an API
* method is not implemented.
*/
class NotImplementedException extends HttpException
{
/**
* @param string $method
*/
public function __construct(
// name of the method
$method
);
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException;
/**
* Represents a route not found error.
*/
class RouteNotFoundException extends HttpException
{
/**
* @param string $route
*/
public function __construct(
// route path
$route
);
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException;
/**
* Represents an HTTP 503 error.
*/
class ServiceUnavailableException extends HttpException
{
/**
* @param string $message (optional, default: null
)
*/
public function __construct(
// if no message is given, defaults
// to 'Service Unavailable'
$message = null
);
}
namespace BitFrame\Exception;
// extends:
use \BitFrame\Exception\HttpException;
/**
* Represents an HTTP 401 error.
*/
class UnauthorizedException extends HttpException
{
/**
* @param string $message (optional, default: null
)
*/
public function __construct(
// if no message is given, defaults
// to 'Unauthorized'
$message = null
);
}
namespace BitFrame\Factory;
use InvalidArgumentException;
/**
* Create an uploaded file instance from an array of values.
*
* @param array $spec
*
* @return UploadedFile
*
* @throws InvalidArgumentException if one or more of the tmp_name, size,
* or error keys are missing from $spec.
*/
function createUploadedFile(
// a single $_FILES
entry.
array $spec
);
namespace BitFrame\Factory;
use function array_key_exists;
use function strpos;
use function strtolower;
use function strtr;
use function substr;
/**
* @param array $server Values obtained from the SAPI (e.g. $_SERVER
).
*
* @return array Header/value pairs
*/
function marshalHeadersFromSapi(
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $server
);
namespace BitFrame\Factory;
/**
* Retrieve the request method from the SAPI parameters.
*
* @param array $server
*
* @return string
*/
function marshalMethodFromSapi(
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $server
);
namespace BitFrame\Factory;
use function preg_match;
// exceptions:
use \UnexpectedValueException;
/**
* Return HTTP protocol version (X.Y) as discovered
* within a $_SERVER
array.
*
* @param array $server
* @return string
* @throws UnexpectedValueException if the $server['SERVER_PROTOCOL']
* value is malformed.
*/
function marshalProtocolVersionFromSapi(
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $server
);
namespace BitFrame\Factory;
use function array_change_key_case;
use function array_key_exists;
use function explode;
use function implode;
use function is_array;
use function ltrim;
use function preg_match;
use function preg_replace;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
/**
* Marshal a Uri instance based on the values present
* in the $_SERVER
array and headers.
*
* @param array $server SAPI parameters
* @param array $headers HTTP request headers
* @return Uri
*/
function marshalUriFromSapi(
// array containing web server information such as;
// headers, paths, script locations, etc., e.g. `$_SERVER`
array $server,
// HTTP request headers
array $headers
);
namespace BitFrame\Factory;
use InvalidArgumentException;
use Psr\Http\Message\UploadedFileInterface;
use function is_array;
/**
* Normalize uploaded files.
*
* Transforms each value into an UploadedFile instance,
* and ensures that nested arrays are normalized.
*
* @param array $files
* @return UploadedFileInterface[]
* @throws InvalidArgumentException for unrecognized values
*/
function normalizeUploadedFiles(
// array of uploaded files to normalize as per PSR-7 spec
array $files
);
namespace BitFrame\Factory;
use function preg_match_all;
use function urldecode;
/**
* Parse a cookie header according to RFC 6265.
*
* PHP will replace special characters in cookie names,
* which results in other cookies not being available due
* to overwriting. Thus, the server request should take the
* cookies from the request header instead.
*
* @param string $cookieHeader
*
* @return array key/value cookie pairs.
*/
function parseCookieHeader(
// a string cookie header value.
$cookieHeader
);