Skip to content
This repository was archived by the owner on Jan 31, 2020. It is now read-only.

Commit 182271e

Browse files
committed
Merge branch 'hotfix/84'
Close #84
2 parents 3e6b907 + 20f588c commit 182271e

File tree

3 files changed

+84
-129
lines changed

3 files changed

+84
-129
lines changed

doc/book/quick-start.md

Lines changed: 82 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -534,24 +534,26 @@ priority. Typically, you will register this during the bootstrap event.
534534
```php
535535
namespace Content;
536536

537+
use Zend\Mvc\MvcEvent;
538+
537539
class Module
538540
{
539541
/**
540-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
542+
* @param MvcEvent $e The MvcEvent instance
541543
* @return void
542544
*/
543-
public function onBootstrap($e)
545+
public function onBootstrap(MvcEvent $e)
544546
{
545547
// Register a dispatch event
546548
$app = $e->getParam('application');
547549
$app->getEventManager()->attach('dispatch', [$this, 'setLayout']);
548550
}
549551

550552
/**
551-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
553+
* @param MvcEvent $e The MvcEvent instance
552554
* @return void
553555
*/
554-
public function setLayout($e)
556+
public function setLayout(MvcEvent $e)
555557
{
556558
$matches = $e->getRouteMatch();
557559
$controller = $matches->getParam('controller');
@@ -583,16 +585,12 @@ within your application.
583585
- `Zend\View\Strategy\PhpRendererStrategy`. This strategy is a "catch-all" in
584586
that it will always return the `Zend\View\Renderer\PhpRenderer` and populate
585587
the Response body with the results of rendering.
586-
- `Zend\View\Strategy\JsonStrategy`. This strategy inspects the `Accept` HTTP
587-
request header, if present, and determines if the client has indicated it
588-
accepts an `application/json` response. If so, it will return the
588+
- `Zend\View\Strategy\JsonStrategy`. This strategy will return the
589589
`Zend\View\Renderer\JsonRenderer`, and populate the Response body with the
590590
JSON value returned, as well as set a `Content-Type` header with a value of
591591
`application/json`.
592-
- `Zend\View\Strategy\FeedStrategy`. This strategy inspects the `Accept` HTTP
593-
header, if present, and determines if the client has indicated it accepts
594-
either an `application/rss+xml` or `application/atom+xml` response. If so, it
595-
will return the `Zend\View\Renderer\FeedRenderer`, setting the feed type to
592+
- `Zend\View\Strategy\FeedStrategy`. This strategy will return the
593+
`Zend\View\Renderer\FeedRenderer`, setting the feed type to
596594
either "rss" or "atom", based on what was matched. Its Response strategy will
597595
populate the Response body with the generated feed, as well as set a
598596
`Content-Type` header with the appropriate value based on feed type.
@@ -606,13 +604,15 @@ register the `JsonStrategy`:
606604
```php
607605
namespace Application;
608606

607+
use Zend\Mvc\MvcEvent;
608+
609609
class Module
610610
{
611611
/**
612-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
612+
* @param MvcEvent $e The MvcEvent instance
613613
* @return void
614614
*/
615-
public function onBootstrap($e)
615+
public function onBootstrap(MvcEvent $e)
616616
{
617617
// Register a "render" event, at high priority (so it executes prior
618618
// to the view attempting to render)
@@ -621,10 +621,10 @@ class Module
621621
}
622622

623623
/**
624-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
624+
* @param MvcEvent $e The MvcEvent instance
625625
* @return void
626626
*/
627-
public function registerJsonStrategy($e)
627+
public function registerJsonStrategy(MvcEvent $e)
628628
{
629629
$app = $e->getTarget();
630630
$locator = $app->getServiceManager();
@@ -639,34 +639,64 @@ class Module
639639

640640
The above will register the `JsonStrategy` with the "render" event, such that it
641641
executes prior to the `PhpRendererStrategy`, and thus ensure that a JSON payload
642-
is created when requested.
642+
is created when the controller returns a `JsonModel`.
643+
644+
You could also use the module configuration to add the strategies:
645+
```php
646+
namespace Application;
647+
648+
use Zend\ModuleManager\Feature\ConfigProviderInterface;
649+
650+
class Module implements ConfigProviderInterface
651+
{
652+
/**
653+
* Returns configuration to merge with application configuration
654+
*
655+
* @return array
656+
*/
657+
public function getConfig()
658+
{
659+
return [
660+
/* ... */
661+
'view_manager' => [
662+
/* ... */
663+
'strategies' => [
664+
'ViewJsonStrategy',
665+
],
666+
],
667+
];
668+
}
669+
}
670+
```
643671

644672
What if you want this to happen only in specific modules, or specific
645673
controllers? One way is similar to the last example in the
646674
[previous section on layouts](#dealing-with-layouts), where we detailed changing
647675
the layout for a specific module:
648676

649677
```php
650-
namespace Content;
678+
namespace Application;
679+
680+
use Zend\Mvc\MvcEvent;
651681

652682
class Module
653683
{
654684
/**
655-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
685+
* @param MvcEvent $e The MvcEvent instance
656686
* @return void
657687
*/
658-
public function onBootstrap($e)
688+
public function onBootstrap(MvcEvent $e)
659689
{
660690
// Register a render event
661691
$app = $e->getParam('application');
662692
$app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100);
663693
}
664694

665695
/**
666-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
696+
* @param MvcEvent $e The MvcEvent instance
667697
* @return void
668698
*/
669-
public function registerJsonStrategy($e)
699+
public function registerJsonStrategy(MvcEvent $e)
670700
{
671701
$matches = $e->getRouteMatch();
672702
$controller = $matches->getParam('controller');
@@ -694,124 +724,51 @@ class Module
694724
While the above examples detail using the `JsonStrategy`, the same could be done
695725
for the `FeedStrategy`.
696726

697-
What if you want to use a custom renderer? Or if your app might allow a
698-
combination of JSON, Atom feeds, and HTML? At this point, you'll need to create
699-
your own custom strategies. Below is an example that appropriately loops through
700-
the HTTP `Accept` header, and selects the appropriate Renderer based on what is
701-
matched first.
702-
727+
If you successfully registered the Strategy you need to use the appropriate `ViewModel`:
703728
```php
704-
namespace Content\View;
729+
namespace Application;
705730

706-
use Zend\EventManager\EventManagerInterface;
707-
use Zend\EventManager\ListenerAggregateInterface;
708-
use Zend\EventManager\ListenerAggregateTrait;
709-
use Zend\Feed\Writer\Feed;
710-
use Zend\View\Renderer\FeedRenderer;
711-
use Zend\View\Renderer\JsonRenderer;
712-
use Zend\View\Renderer\PhpRenderer;
731+
use Zend\Mvc\Controller\AbstractActionController;
732+
use Zend\View\Model\ViewModel;
733+
use Zend\View\Model\JsonModel;
734+
use Zend\View\Model\FeedModel;
713735

714-
class AcceptStrategy implements ListenerAggregateInterface
736+
class MyController extends AbstractActionController
715737
{
716-
use ListenerAggregateTrait;
717-
718-
protected $feedRenderer;
719-
protected $jsonRenderer;
720-
protected $phpRenderer;
721-
722-
public function __construct(
723-
PhpRenderer $phpRenderer,
724-
JsonRenderer $jsonRenderer,
725-
FeedRenderer $feedRenderer
726-
) {
727-
$this->phpRenderer = $phpRenderer;
728-
$this->jsonRenderer = $jsonRenderer;
729-
$this->feedRenderer = $feedRenderer;
730-
}
731-
732-
public function attach(EventManagerInterface $events, $priority = 1)
738+
/**
739+
* Lists the items as HTML
740+
*/
741+
public function listAction()
733742
{
734-
$this->listeners[] = $events->attach('renderer', [$this, 'selectRenderer'], $priority);
735-
$this->listeners[] = $events->attach('response', [$this, 'injectResponse'], $priority);
743+
$items = /* ... get items ... */;
744+
$viewModel = new ViewModel();
745+
$viewModel->setVariable('items', $items);
746+
return $viewModel;
736747
}
737-
748+
738749
/**
739-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
740-
* @return \Zend\View\Renderer\RendererInterface
750+
* Lists the items as JSON
741751
*/
742-
public function selectRenderer($e)
752+
public function listJsonAction()
743753
{
744-
$request = $e->getRequest();
745-
$headers = $request->getHeaders();
746-
747-
// No Accept header? return PhpRenderer
748-
if (!$headers->has('accept')) {
749-
return $this->phpRenderer;
750-
}
751-
752-
$accept = $headers->get('accept');
753-
foreach ($accept->getPrioritized() as $mediaType) {
754-
if (0 === strpos($mediaType, 'application/json')) {
755-
return $this->jsonRenderer;
756-
}
757-
758-
if (0 === strpos($mediaType, 'application/rss+xml')) {
759-
$this->feedRenderer->setFeedType('rss');
760-
return $this->feedRenderer;
761-
}
762-
763-
if (0 === strpos($mediaType, 'application/atom+xml')) {
764-
$this->feedRenderer->setFeedType('atom');
765-
return $this->feedRenderer;
766-
}
767-
}
768-
769-
// Nothing matched; return PhpRenderer. Technically, we should probably
770-
// return an HTTP 415 Unsupported response.
771-
return $this->phpRenderer;
754+
$items = /* ... get items ... */;
755+
$viewModel = new JsonModel();
756+
$viewModel->setVariable('items', $items);
757+
return $viewModel;
772758
}
773-
759+
774760
/**
775-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
776-
* @return void
761+
* Lists the items as a Feed
777762
*/
778-
public function injectResponse($e)
763+
public function listFeedAction()
779764
{
780-
$renderer = $e->getRenderer();
781-
$response = $e->getResponse();
782-
$result = $e->getResult();
783-
784-
if ($renderer === $this->jsonRenderer) {
785-
// JSON Renderer; set content-type header
786-
$headers = $response->getHeaders();
787-
$headers->addHeaderLine('content-type', 'application/json');
788-
$response->setContent($result);
789-
return
790-
}
791-
792-
if ($renderer === $this->feedRenderer) {
793-
// Feed Renderer; set content-type header, and export the feed if
794-
// necessary
795-
$feedType = $this->feedRenderer->getFeedType();
796-
$headers = $response->getHeaders();
797-
$mediatype = 'application/'
798-
. (('rss' == $feedType) ? 'rss' : 'atom')
799-
. '+xml';
800-
$headers->addHeaderLine('content-type', $mediatype);
801-
802-
// If the $result is a feed, export it
803-
if ($result instanceof Feed) {
804-
$result = $result->export($feedType);
805-
}
806-
807-
$response->setContent($result);
808-
return;
809-
}
765+
$items = /* ... get items ... */;
766+
$viewModel = new FeedModel();
767+
$viewModel->setVariable('items', $items);
768+
return $viewModel;
810769
}
811770
}
812771
```
813772

814-
This strategy would be registered just as we demonstrated registering the
815-
`JsonStrategy` earlier. You would also need to define service manager
816-
configuration to ensure the various renderers are injected when you retrieve the
817-
strategy from the application's locator instance.
773+
Or you could switch the `ViewModel` dynamically based on the "Accept" HTTP Header with the
774+
[Zend-Mvc-Plugin AcceptableViewModelSelector](http://zendframework.github.io/zend-mvc/plugins/#acceptableviewmodelselector-plugin).

src/Strategy/FeedStrategy.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ public function attach(EventManagerInterface $events, $priority = 1)
4343
}
4444

4545
/**
46-
* Detect if we should use the FeedRenderer based on model type and/or
47-
* Accept header
46+
* Detect if we should use the FeedRenderer based on model type
4847
*
4948
* @param ViewEvent $e
5049
* @return null|FeedRenderer

src/Strategy/JsonStrategy.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ public function getCharset()
8181
}
8282

8383
/**
84-
* Detect if we should use the JsonRenderer based on model type and/or
85-
* Accept header
84+
* Detect if we should use the JsonRenderer based on model type
8685
*
8786
* @param ViewEvent $e
8887
* @return null|JsonRenderer

0 commit comments

Comments
 (0)