Skip to content

Commit

Permalink
Merge pull request #2 from krakphp/v0.5
Browse files Browse the repository at this point in the history
V0.5
  • Loading branch information
ragboyjr committed Mar 12, 2017
2 parents d449a72 + d184012 commit 63313d7
Show file tree
Hide file tree
Showing 19 changed files with 262 additions and 569 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [0.5.0] - 2017-03-11
### Added

- `composer` func which creates composer functions that accept an array of middleware
and compose into a handler.
- `guard` a generic middleware that will throw an exception when invoked to indicate an
error in logic.
- `guardedComposer` decorator to automatically add guards when composing a middleware stack

### Changed

- Moved `MwStack` to simply `Stack` and simplified the API
- Removed Pimple integration in favor for the PSR container.

## [0.4.2] - 2017-01-19
### Added

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"psr/container": "^1.0"
},
"require-dev": {
"krak/cargo": "^0.2.0",
"peridot-php/peridot": "^1.18",
"pimple/pimple": "^3.0"
},
Expand Down
4 changes: 2 additions & 2 deletions doc/advanced-usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ Each middleware is invoked with a ``Mw\Context`` instance. This is responsible f
use Krak\Mw;
$handle = mw\compose([
$handle = Mw\compose([
function($v, Mw\Link $next) {
$ctx = $next->getContext();
return 1;
}
], new Krak\Mw\Context\StdContext());
], new Mw\Context\StdContext());
You can configure or pass in any context as long as it implements the ``Mw\Context`` interface. Currently, the context provides an invoker via the ``getInvoke`` method. This allows custom invocation of the middleware as shown in the :doc:`cookbook`.

Expand Down
131 changes: 34 additions & 97 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The api documentation is broken up into 2 parts: Middleware documentation and Mi
Middleware Functions
~~~~~~~~~~~~~~~~~~~~

Closure compose(array $mws, Context $ctx = null, callable $last = null, $link_class = Link::class)
Closure compose(array $mws, Context $ctx = null, $link_class = Link::class)
Composes a set of middleware into a handler.

.. code-block:: php
Expand All @@ -33,8 +33,6 @@ Closure compose(array $mws, Context $ctx = null, callable $last = null, $link_cl

``$ctx`` will default to ``Context\StdContext`` if none is supplied, and it will be the context that is passed to the start link (see: :doc:`advanced-usage` for more details).

``$last`` represents the last middleware to be executed if no other middleware handle the parameters. This typically will throw an exception in that case, but it might be advantageous to set this to something else for your needs.

``$link_class`` is the class that will be constructed for the middleware link. It must be or extend ``Krak\Mw\Link`` (see: :doc:`advanced-usage` for more details).

Closure composer(Context $ctx, $link_class = Link::class)
Expand All @@ -50,6 +48,18 @@ Closure composer(Context $ctx, $link_class = Link::class)
mw2()
]);
Closure guardedComposer($composer, $msg)

Creates a composer that will automatically append a guard middleware with the given message when composing.

.. code-block:: php
$compose = mw\composer();
$compose = mw\guardedComposer($compose, 'No result was returned.');
$handler = $compose([]);
$handler();
// A NoResultException will be thrown with the `No result was returned.` message
Closure group(array $mws)
Creates a new *middleware* composed as one from a middleware stack.

Expand Down Expand Up @@ -121,12 +131,10 @@ Closure filter(callable $mw, callable $predicate)
In this example, the stack of middleware always returns 1, however, the filtered middleware gets executed if the value is 4, and in that case, it returns 2 instead.


Invoke Functions
~~~~~~~~~~~~~~~~

Closure pimpleAwareInvoke(Pimple\\Container $c, $invoke = 'call_user_func')
invokes middleware while checking if the mw is a service defined in the pimple container

Closure containerAwareInvoke(Psr\\Container\\ContainerInterface $c, $invoke = 'call_user_func')
invokes middleware while checking if the mw is a service defined in the psr container.

Expand All @@ -136,64 +144,17 @@ Closure methodInvoke(string $method_name, $allow_callable = true, $invoke = 'cal
Stack Functions
~~~~~~~~~~~~~~~

MwStack stack($name, array $entries = [], Context $ctx = null, $link_class = Link::class)
Creates a MwStack instance. Every stack must have a name which is just a personal identifier for the stack. It's primary use is for errors/exceptions that help the user track down which stack has an issue. ``$ctx`` and ``$link_class`` are forwarded to the MwStack constructor.
Stack stack(array $entries = [])
Creates a Stack instance. This is an alias of the ``Stack::__construct``

.. code-block:: php
<?php
$stack = mw\stack('demo stack');
$stack->push($mw)
->unshift($mw1);
// compose into handler
$handler = $stack->compose();
// or, use as a grouped middleware
$handler = mw\compose([
$mw2,
$stack
]);
array stackEntry(callable $mw, $sort = 0, $name = null)
Creates an entry for the MwStack. This is only used if you want to initialize a stack with entries, else, you'll just be using the stack methods to create stack entries.

.. code-block:: php
<?php
$stack = mw\stack('demo stack', [
stackEntry($mw1, 0, 'mw1'),
stackEntry($mw2),
stackEntry($mw3, 5, 'mw3'),
]);
// equivalent to
$stack = mw\stack('demo stack')
->push($mw1, 0, 'mw1')
->push($mw2)
->push($mw3, 5, 'mw3');
MwStack stackMerge(...$stacks)
Merges stacks into one another. The resulting stack has the same name as the first stack in the set. The values from the later stacks will override the values from the earlier stacks.

.. code-block:: php
<?php
$a = mw\stack('stack', [
mw\stackEntry($mw1),
mw\stackEntry($mw2),
mw\stackEntry($mw3, 0, 'mw')
]);
$b = mw\stack('stack', [
mw\stackEntry($mw4, 0, 'mw'),
]);
$c = mw\stackMerge($a, $b);
// stack $c is equivalent to
$c = mw\stack('stack')
->push($mw1)
->push($mw2)
->push($mw4, 0, 'mw')
$stack = mw\stack([
$mw1,
$mw2
])->unshift($mw0);
Utility Functions
~~~~~~~~~~~~~~~~~
Expand All @@ -215,49 +176,35 @@ array splitArgs(array $args)
}
class MwStack implements Countable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Stack
~~~~~~~~~~~

The stack presents a mutable interface into a stack of middleware. Middleware can be added with a name and priority. Only one middleware with a given name may exist. Middleware that are last in the stack will be executed first once the stack is composed.

__construct($name, Context $ctx = null, $link_class = Link::class)
Creates the mw stack with a name. The ``$ctx`` and ``$link_class`` are forwarded to ``mw\compose`` once the stack is composed.
string getName()
returns the name of the middleware
MwStack push($mw, $sort = 0, $name = null)
__construct(array $entries = [])
Creates the stack and will ``fill`` it with the given entries.
Stack fill($entries)
Pushes each entry onto the stack in the order defined.
Stack push($mw, $sort = 0, $name = null)
Pushes a new middleware on the stack. The sort determines the priority of the middleware. Middleware pushed at the same priority will be pushed on like a stack.
MwStack unshift($mw, $sort = 0, $name = null)
Stack unshift($mw, $sort = 0, $name = null)
Similar to push except it prepends the stack at the beginning.
MwStack on($name, $mw, $sort = 0)
Stack on($name, $mw, $sort = 0)
Simply an alias of ``push``; however, the argument order lends it nicer for adding/replacing named middleware.
MwStack before($name, $mw, $mw_name = null)
Stack before($name, $mw, $mw_name = null)
Inserts a middleware right before the given middleware.
MwStack after($name, $mw, $mw_name = null)
Stack after($name, $mw, $mw_name = null)
Inserts a middleware right after the given middleware.
array shift($sort = 0)
Shifts the stack at the priority given by taking an element from the front/bottom of the stack. The shifted stack entry is returned as a tuple.
array pop($sort = 0)
Pops the stack at the priority given be taking an element from the back/top of the stack. The popped stack entry is returned as a tuple.
array remove($name)
Removes a named middleware. The removed middleware is returned as a tuple.
array normalize()
array toArray()
Normalizes the stack into an array of middleware that can be used with ``mw\compose``
mixed __invoke(...$params)
Allows the middleware stack to be used as middleware itself.
Closure compose(callable $last = null)
Composes the stack into a handler.
Generator getEntries()
Yields the raw stack entries in the order they were added.
MwStack withName($name)
Creates a clone of the current stack with an updated name.
MwStack withContext(Context $ctx)
Creates a clone of the current stack with an updated context
MwStack withLinkClass($class)
Creates a clone of the current stack with an updated link class
MwStack withEntries($entries)
Creates a clone of the current stack with updated entries.
MwStack static createFromEntries($name, $entries)
Creates a stack with a set of entries. ``mw\stack`` internally calls this.

class Link
~~~~~~~~~~
Expand All @@ -274,7 +221,7 @@ getContext()
returns the context instance apart of the link.

class Link\\ContainerLink
~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~

Extends the Link class and implements the Psr\\Container\\ContainerInterface and ArrayAccess. Keep in mind that it offers read-only access, so setting and deleting offsets will cause an exception to be thrown.

Expand All @@ -293,18 +240,8 @@ The default context for the mw system. It simply holds the a value to the invoke

__construct($invoke = 'call_user_func')

class Context\\PimpleContext implements Context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Provides nice pimple integeration by allowing the context to act like a pimple container and it provides pimple invocation by default.

View the :doc:`cookbook/pimple-middleware` for example on this.

__construct(Container $container, $invoke = null)
The pimple container and an optional invoker if you don't want to use the ``pimpleAwareInvoke``

class Context\\ContainerContext implements Context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Provides psr container integeration by allowing the context to act like a psr container and it provides container invocation by default.

Expand Down
1 change: 0 additions & 1 deletion doc/cookbook.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ The cookbook provides documentation on how to extend or utilize the mw system in

- :doc:`cookbook/custom-link-class`
- :doc:`cookbook/custom-method-middleware`
- :doc:`cookbook/pimple-middleware`
- :doc:`cookbook/container-middleware`
2 changes: 1 addition & 1 deletion doc/cookbook/container-middleware.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Container Middleware
====================

You can easily integrate your middleware stacks with any PSR container using the ``Mw\Context\Container`` which will allow any middleware to be a container identifier and give you access to your container via the mw context.
You can easily integrate your middleware stacks with any PSR container using the ``Mw\Context\ContainerContext`` which will allow any middleware to be a container identifier and give you access to your container via the mw context.

.. code-block:: php
Expand Down
30 changes: 0 additions & 30 deletions doc/cookbook/pimple-middleware.rst

This file was deleted.

8 changes: 4 additions & 4 deletions doc/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Troubleshooting

Here are few common errors and how to resolve them

"No middleware returned a response" Error
=========================================
"Cannot invoke last middleware in chain. No middleware returned a result." NoResultException
============================================================================================

When you get this error or something similar, this means that no middleware in the set of middleware returned a response.

Expand All @@ -14,11 +14,11 @@ You can get this error if you:
- Forget to put a return statement in your middleware so the chain breaks and no response is returned.
- Have a logic error where no middleware actually accepts the response

If you are having trouble finding which handler is causing the issue, you can use a MwStack instead. These provide better error messages because each middleware stack has a name which can help track down which middlware stack is causing the problem.
If you are having trouble finding which handler is causing the issue, you can use add a `guard` middleware when you compose your middleware set to provide custom error messages.

"Middleware cannot be invoked because it does not contain the '' method"
========================================================================

This exception is thrown when using the ``methodInvoke`` for composing your middleware. This means that one of the middleware on your stack doesn't have the proper method to be called.

To fix this, you should check your middleware stack and verify that every middleware has the proper method. The stack trace should also show you which class instance caused the problem to help you track down the problem.
To fix this, you should check your middleware stack and verify that every middleware has the proper method. The stack trace should also show you which class instance caused the problem to help you track down the problem.
13 changes: 7 additions & 6 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,19 @@ After Style
Stack
=====

The library also comes with a MwStack that allows you to easily build a set of middleware.
The library also comes with a Stack that allows you to easily build a set of middleware.

.. code-block:: php
<?php
use Krak\Mw;
$stack = mw\stack('Stack Name');
$stack->push(function($a, $next) {
return $next($a . 'b');
})
$stack = mw\stack([
function($a, $next) {
return $next($a . 'b');
},
]);
->push(function($a, $next) {
return $next($a) . 'z';
}, 0, 'c')
Expand All @@ -117,6 +118,6 @@ The library also comes with a MwStack that allows you to easily build a set of m
return $a;
});
$handler = $stack->compose();
$handler = mw\compose([$stack]);
$res = $handler('a');
assert($res == 'abxcy');
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php

use Krak\Mw;
use Krak\Cargo;

require_once __DIR__ . '/../vendor/autoload.php';

$container = new Pimple\Container();
$container = Cargo\container();
$container['i'] = 5;
$container['inc_mw'] = function() {
return function($i, $next) {
Expand All @@ -15,10 +16,10 @@
$handler = mw\compose([
function($i) { return $i; },
function($i, $next) {
$ctx = $next->getContext();
return $next($i + $ctx['i']);
$c = $next->getContext()->getContainer();
return $next($i + $c->get('i'));
},
'inc_mw'
], new Mw\Context\PimpleContext($container));
], new Mw\Context\ContainerContext($container->toInterop()));

assert($handler(4) == 10);
2 changes: 1 addition & 1 deletion example/custom-link-class.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ function($i, $next) {
$next->log('hi');
return 1;
}
], null, null, LoggingLink::class);
], null, LoggingLink::class);

assert($handler(0) == 1);

0 comments on commit 63313d7

Please sign in to comment.