1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10namespace Zend\View; 11 12use Zend\I18n\Translator\TranslatorAwareInterface; 13use Zend\ServiceManager\AbstractPluginManager; 14use Zend\ServiceManager\ConfigInterface; 15 16/** 17 * Plugin manager implementation for view helpers 18 * 19 * Enforces that helpers retrieved are instances of 20 * Helper\HelperInterface. Additionally, it registers a number of default 21 * helpers. 22 */ 23class HelperPluginManager extends AbstractPluginManager 24{ 25 /** 26 * Default set of helpers factories 27 * 28 * @var array 29 */ 30 protected $factories = array( 31 'flashmessenger' => 'Zend\View\Helper\Service\FlashMessengerFactory', 32 'identity' => 'Zend\View\Helper\Service\IdentityFactory', 33 ); 34 35 /** 36 * Default set of helpers 37 * 38 * @var array 39 */ 40 protected $invokableClasses = array( 41 // basepath, doctype, and url are set up as factories in the ViewHelperManagerFactory. 42 // basepath and url are not very useful without their factories, however the doctype 43 // helper works fine as an invokable. The factory for doctype simply checks for the 44 // config value from the merged config. 45 'basepath' => 'Zend\View\Helper\BasePath', 46 'cycle' => 'Zend\View\Helper\Cycle', 47 'declarevars' => 'Zend\View\Helper\DeclareVars', 48 'doctype' => 'Zend\View\Helper\Doctype', // overridden by a factory in ViewHelperManagerFactory 49 'escapehtml' => 'Zend\View\Helper\EscapeHtml', 50 'escapehtmlattr' => 'Zend\View\Helper\EscapeHtmlAttr', 51 'escapejs' => 'Zend\View\Helper\EscapeJs', 52 'escapecss' => 'Zend\View\Helper\EscapeCss', 53 'escapeurl' => 'Zend\View\Helper\EscapeUrl', 54 'gravatar' => 'Zend\View\Helper\Gravatar', 55 'htmltag' => 'Zend\View\Helper\HtmlTag', 56 'headlink' => 'Zend\View\Helper\HeadLink', 57 'headmeta' => 'Zend\View\Helper\HeadMeta', 58 'headscript' => 'Zend\View\Helper\HeadScript', 59 'headstyle' => 'Zend\View\Helper\HeadStyle', 60 'headtitle' => 'Zend\View\Helper\HeadTitle', 61 'htmlflash' => 'Zend\View\Helper\HtmlFlash', 62 'htmllist' => 'Zend\View\Helper\HtmlList', 63 'htmlobject' => 'Zend\View\Helper\HtmlObject', 64 'htmlpage' => 'Zend\View\Helper\HtmlPage', 65 'htmlquicktime' => 'Zend\View\Helper\HtmlQuicktime', 66 'inlinescript' => 'Zend\View\Helper\InlineScript', 67 'json' => 'Zend\View\Helper\Json', 68 'layout' => 'Zend\View\Helper\Layout', 69 'paginationcontrol' => 'Zend\View\Helper\PaginationControl', 70 'partialloop' => 'Zend\View\Helper\PartialLoop', 71 'partial' => 'Zend\View\Helper\Partial', 72 'placeholder' => 'Zend\View\Helper\Placeholder', 73 'renderchildmodel' => 'Zend\View\Helper\RenderChildModel', 74 'rendertoplaceholder' => 'Zend\View\Helper\RenderToPlaceholder', 75 'serverurl' => 'Zend\View\Helper\ServerUrl', 76 'url' => 'Zend\View\Helper\Url', 77 'viewmodel' => 'Zend\View\Helper\ViewModel', 78 ); 79 80 /** 81 * @var Renderer\RendererInterface 82 */ 83 protected $renderer; 84 85 /** 86 * Constructor 87 * 88 * After invoking parent constructor, add an initializer to inject the 89 * attached renderer and translator, if any, to the currently requested helper. 90 * 91 * @param null|ConfigInterface $configuration 92 */ 93 public function __construct(ConfigInterface $configuration = null) 94 { 95 parent::__construct($configuration); 96 97 $this->addInitializer(array($this, 'injectRenderer')) 98 ->addInitializer(array($this, 'injectTranslator')); 99 } 100 101 /** 102 * Set renderer 103 * 104 * @param Renderer\RendererInterface $renderer 105 * @return HelperPluginManager 106 */ 107 public function setRenderer(Renderer\RendererInterface $renderer) 108 { 109 $this->renderer = $renderer; 110 111 return $this; 112 } 113 114 /** 115 * Retrieve renderer instance 116 * 117 * @return null|Renderer\RendererInterface 118 */ 119 public function getRenderer() 120 { 121 return $this->renderer; 122 } 123 124 /** 125 * Inject a helper instance with the registered renderer 126 * 127 * @param Helper\HelperInterface $helper 128 * @return void 129 */ 130 public function injectRenderer($helper) 131 { 132 $renderer = $this->getRenderer(); 133 if (null === $renderer) { 134 return; 135 } 136 $helper->setView($renderer); 137 } 138 139 /** 140 * Inject a helper instance with the registered translator 141 * 142 * @param Helper\HelperInterface $helper 143 * @return void 144 */ 145 public function injectTranslator($helper) 146 { 147 if (!$helper instanceof TranslatorAwareInterface) { 148 return; 149 } 150 151 $locator = $this->getServiceLocator(); 152 153 if (!$locator) { 154 return; 155 } 156 157 if ($locator->has('MvcTranslator')) { 158 $helper->setTranslator($locator->get('MvcTranslator')); 159 return; 160 } 161 162 if ($locator->has('Zend\I18n\Translator\TranslatorInterface')) { 163 $helper->setTranslator($locator->get('Zend\I18n\Translator\TranslatorInterface')); 164 return; 165 } 166 167 if ($locator->has('Translator')) { 168 $helper->setTranslator($locator->get('Translator')); 169 return; 170 } 171 } 172 173 /** 174 * Validate the plugin 175 * 176 * Checks that the helper loaded is an instance of Helper\HelperInterface. 177 * 178 * @param mixed $plugin 179 * @return void 180 * @throws Exception\InvalidHelperException if invalid 181 */ 182 public function validatePlugin($plugin) 183 { 184 if ($plugin instanceof Helper\HelperInterface) { 185 // we're okay 186 return; 187 } 188 189 throw new Exception\InvalidHelperException(sprintf( 190 'Plugin of type %s is invalid; must implement %s\Helper\HelperInterface', 191 (is_object($plugin) ? get_class($plugin) : gettype($plugin)), 192 __NAMESPACE__ 193 )); 194 } 195} 196