ViewRenderer.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Controller
  17. * @subpackage Zend_Controller_Action_Helper
  18. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @see Zend_Controller_Action_Helper_Abstract
  24. */
  25. require_once 'Zend/Controller/Action/Helper/Abstract.php';
  26. /**
  27. * @see Zend_View
  28. */
  29. require_once 'Zend/View.php';
  30. /**
  31. * View script integration
  32. *
  33. * Zend_Controller_Action_Helper_ViewRenderer provides transparent view
  34. * integration for action controllers. It allows you to create a view object
  35. * once, and populate it throughout all actions. Several global options may be
  36. * set:
  37. *
  38. * - noController: if set true, render() will not look for view scripts in
  39. * subdirectories named after the controller
  40. * - viewSuffix: what view script filename suffix to use
  41. *
  42. * The helper autoinitializes the action controller view preDispatch(). It
  43. * determines the path to the class file, and then determines the view base
  44. * directory from there. It also uses the module name as a class prefix for
  45. * helpers and views such that if your module name is 'Search', it will set the
  46. * helper class prefix to 'Search_View_Helper' and the filter class prefix to ;
  47. * 'Search_View_Filter'.
  48. *
  49. * Usage:
  50. * <code>
  51. * // In your bootstrap:
  52. * Zend_Controller_Action_HelperBroker::addHelper(new Zend_Controller_Action_Helper_ViewRenderer());
  53. *
  54. * // In your action controller methods:
  55. * $viewHelper = $this->_helper->getHelper('view');
  56. *
  57. * // Don't use controller subdirectories
  58. * $viewHelper->setNoController(true);
  59. *
  60. * // Specify a different script to render:
  61. * $this->_helper->viewRenderer('form');
  62. *
  63. * </code>
  64. *
  65. * @uses Zend_Controller_Action_Helper_Abstract
  66. * @package Zend_Controller
  67. * @subpackage Zend_Controller_Action_Helper
  68. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  69. * @license http://framework.zend.com/license/new-bsd New BSD License
  70. */
  71. class Zend_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Action_Helper_Abstract
  72. {
  73. /**
  74. * @var Zend_View_Interface
  75. */
  76. public $view;
  77. /**
  78. * Word delimiters
  79. * @var array
  80. */
  81. protected $_delimiters;
  82. /**
  83. * Front controller instance
  84. * @var Zend_Controller_Front
  85. */
  86. protected $_frontController;
  87. /**
  88. * @var Zend_Filter_Inflector
  89. */
  90. protected $_inflector;
  91. /**
  92. * Inflector target
  93. * @var string
  94. */
  95. protected $_inflectorTarget = '';
  96. /**
  97. * Current module directory
  98. * @var string
  99. */
  100. protected $_moduleDir = '';
  101. /**
  102. * Whether or not to autorender using controller name as subdirectory;
  103. * global setting (not reset at next invocation)
  104. * @var boolean
  105. */
  106. protected $_neverController = false;
  107. /**
  108. * Whether or not to autorender postDispatch; global setting (not reset at
  109. * next invocation)
  110. * @var boolean
  111. */
  112. protected $_neverRender = false;
  113. /**
  114. * Whether or not to use a controller name as a subdirectory when rendering
  115. * @var boolean
  116. */
  117. protected $_noController = false;
  118. /**
  119. * Whether or not to autorender postDispatch; per controller/action setting (reset
  120. * at next invocation)
  121. * @var boolean
  122. */
  123. protected $_noRender = false;
  124. /**
  125. * Characters representing path delimiters in the controller
  126. * @var string|array
  127. */
  128. protected $_pathDelimiters;
  129. /**
  130. * Which named segment of the response to utilize
  131. * @var string
  132. */
  133. protected $_responseSegment = null;
  134. /**
  135. * Which action view script to render
  136. * @var string
  137. */
  138. protected $_scriptAction = null;
  139. /**
  140. * View object basePath
  141. * @var string
  142. */
  143. protected $_viewBasePathSpec = ':moduleDir/views';
  144. /**
  145. * View script path specification string
  146. * @var string
  147. */
  148. protected $_viewScriptPathSpec = ':controller/:action.:suffix';
  149. /**
  150. * View script path specification string, minus controller segment
  151. * @var string
  152. */
  153. protected $_viewScriptPathNoControllerSpec = ':action.:suffix';
  154. /**
  155. * View script suffix
  156. * @var string
  157. */
  158. protected $_viewSuffix = 'phtml';
  159. /**
  160. * Constructor
  161. *
  162. * Optionally set view object and options.
  163. *
  164. * @param Zend_View_Interface $view
  165. * @param array $options
  166. * @return void
  167. */
  168. public function __construct(Zend_View_Interface $view = null, array $options = array())
  169. {
  170. if (null !== $view) {
  171. $this->setView($view);
  172. }
  173. if (!empty($options)) {
  174. $this->_setOptions($options);
  175. }
  176. }
  177. /**
  178. * Clone - also make sure the view is cloned.
  179. *
  180. * @return void
  181. */
  182. public function __clone()
  183. {
  184. if (isset($this->view) && $this->view instanceof Zend_View_Interface) {
  185. $this->view = clone $this->view;
  186. }
  187. }
  188. /**
  189. * Set the view object
  190. *
  191. * @param Zend_View_Interface $view
  192. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  193. */
  194. public function setView(Zend_View_Interface $view)
  195. {
  196. $this->view = $view;
  197. return $this;
  198. }
  199. /**
  200. * Get current module name
  201. *
  202. * @return string
  203. */
  204. public function getModule()
  205. {
  206. $request = $this->getRequest();
  207. $module = $request->getModuleName();
  208. if (null === $module) {
  209. $module = $this->getFrontController()->getDispatcher()->getDefaultModule();
  210. }
  211. return $module;
  212. }
  213. /**
  214. * Get module directory
  215. *
  216. * @throws Zend_Controller_Action_Exception
  217. * @return string
  218. */
  219. public function getModuleDirectory()
  220. {
  221. $module = $this->getModule();
  222. $moduleDir = $this->getFrontController()->getControllerDirectory($module);
  223. if ((null === $moduleDir) || is_array($moduleDir)) {
  224. /**
  225. * @see Zend_Controller_Action_Exception
  226. */
  227. require_once 'Zend/Controller/Action/Exception.php';
  228. throw new Zend_Controller_Action_Exception('ViewRenderer cannot locate module directory');
  229. }
  230. $this->_moduleDir = dirname($moduleDir);
  231. return $this->_moduleDir;
  232. }
  233. /**
  234. * Get inflector
  235. *
  236. * @return Zend_Filter_Inflector
  237. */
  238. public function getInflector()
  239. {
  240. if (null === $this->_inflector) {
  241. /**
  242. * @see Zend_Filter_Inflector
  243. */
  244. require_once 'Zend/Filter/Inflector.php';
  245. /**
  246. * @see Zend_Filter_PregReplace
  247. */
  248. require_once 'Zend/Filter/PregReplace.php';
  249. /**
  250. * @see Zend_Filter_Word_UnderscoreToSeparator
  251. */
  252. require_once 'Zend/Filter/Word/UnderscoreToSeparator.php';
  253. $this->_inflector = new Zend_Filter_Inflector();
  254. $this->_inflector->setStaticRuleReference('moduleDir', $this->_moduleDir) // moduleDir must be specified before the less specific 'module'
  255. ->addRules(array(
  256. ':module' => array('Word_CamelCaseToDash', 'StringToLower'),
  257. ':controller' => array('Word_CamelCaseToDash', new Zend_Filter_Word_UnderscoreToSeparator('/'), 'StringToLower', new Zend_Filter_PregReplace('/\./', '-')),
  258. ':action' => array('Word_CamelCaseToDash', new Zend_Filter_PregReplace('#[^a-z0-9' . preg_quote('/', '#') . ']+#i', '-'), 'StringToLower'),
  259. ))
  260. ->setStaticRuleReference('suffix', $this->_viewSuffix)
  261. ->setTargetReference($this->_inflectorTarget);
  262. }
  263. // Ensure that module directory is current
  264. $this->getModuleDirectory();
  265. return $this->_inflector;
  266. }
  267. /**
  268. * Set inflector
  269. *
  270. * @param Zend_Filter_Inflector $inflector
  271. * @param boolean $reference Whether the moduleDir, target, and suffix should be set as references to ViewRenderer properties
  272. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  273. */
  274. public function setInflector(Zend_Filter_Inflector $inflector, $reference = false)
  275. {
  276. $this->_inflector = $inflector;
  277. if ($reference) {
  278. $this->_inflector->setStaticRuleReference('suffix', $this->_viewSuffix)
  279. ->setStaticRuleReference('moduleDir', $this->_moduleDir)
  280. ->setTargetReference($this->_inflectorTarget);
  281. }
  282. return $this;
  283. }
  284. /**
  285. * Set inflector target
  286. *
  287. * @param string $target
  288. * @return void
  289. */
  290. protected function _setInflectorTarget($target)
  291. {
  292. $this->_inflectorTarget = (string) $target;
  293. }
  294. /**
  295. * Set internal module directory representation
  296. *
  297. * @param string $dir
  298. * @return void
  299. */
  300. protected function _setModuleDir($dir)
  301. {
  302. $this->_moduleDir = (string) $dir;
  303. }
  304. /**
  305. * Get internal module directory representation
  306. *
  307. * @return string
  308. */
  309. protected function _getModuleDir()
  310. {
  311. return $this->_moduleDir;
  312. }
  313. /**
  314. * Generate a class prefix for helper and filter classes
  315. *
  316. * @return string
  317. */
  318. protected function _generateDefaultPrefix()
  319. {
  320. $default = 'Zend_View';
  321. if (null === $this->_actionController) {
  322. return $default;
  323. }
  324. $class = get_class($this->_actionController);
  325. if (!strstr($class, '_')) {
  326. return $default;
  327. }
  328. $module = $this->getModule();
  329. if ('default' == $module) {
  330. return $default;
  331. }
  332. $prefix = substr($class, 0, strpos($class, '_')) . '_View';
  333. return $prefix;
  334. }
  335. /**
  336. * Retrieve base path based on location of current action controller
  337. *
  338. * @return string
  339. */
  340. protected function _getBasePath()
  341. {
  342. if (null === $this->_actionController) {
  343. return './views';
  344. }
  345. $inflector = $this->getInflector();
  346. $this->_setInflectorTarget($this->getViewBasePathSpec());
  347. $dispatcher = $this->_frontController->getDispatcher();
  348. $request = $this->getRequest();
  349. $parts = array(
  350. 'module' => (($moduleName = $request->getModuleName()) != '') ? $dispatcher->formatModuleName($moduleName) : $moduleName,
  351. 'controller' => $request->getControllerName(),
  352. 'action' => $dispatcher->formatActionName($request->getActionName())
  353. );
  354. $path = $inflector->filter($parts);
  355. return $path;
  356. }
  357. /**
  358. * Set options
  359. *
  360. * @param array $options
  361. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  362. */
  363. protected function _setOptions(array $options)
  364. {
  365. foreach ($options as $key => $value)
  366. {
  367. switch ($key) {
  368. case 'neverRender':
  369. case 'neverController':
  370. case 'noController':
  371. case 'noRender':
  372. $property = '_' . $key;
  373. $this->{$property} = ($value) ? true : false;
  374. break;
  375. case 'responseSegment':
  376. case 'scriptAction':
  377. case 'viewBasePathSpec':
  378. case 'viewScriptPathSpec':
  379. case 'viewScriptPathNoControllerSpec':
  380. case 'viewSuffix':
  381. $property = '_' . $key;
  382. $this->{$property} = (string) $value;
  383. break;
  384. default:
  385. break;
  386. }
  387. }
  388. return $this;
  389. }
  390. /**
  391. * Initialize the view object
  392. *
  393. * $options may contain the following keys:
  394. * - neverRender - flag dis/enabling postDispatch() autorender (affects all subsequent calls)
  395. * - noController - flag indicating whether or not to look for view scripts in subdirectories named after the controller
  396. * - noRender - flag indicating whether or not to autorender postDispatch()
  397. * - responseSegment - which named response segment to render a view script to
  398. * - scriptAction - what action script to render
  399. * - viewBasePathSpec - specification to use for determining view base path
  400. * - viewScriptPathSpec - specification to use for determining view script paths
  401. * - viewScriptPathNoControllerSpec - specification to use for determining view script paths when noController flag is set
  402. * - viewSuffix - what view script filename suffix to use
  403. *
  404. * @param string $path
  405. * @param string $prefix
  406. * @param array $options
  407. * @throws Zend_Controller_Action_Exception
  408. * @return void
  409. */
  410. public function initView($path = null, $prefix = null, array $options = array())
  411. {
  412. if (null === $this->view) {
  413. $this->setView(new Zend_View());
  414. }
  415. // Reset some flags every time
  416. $options['noController'] = (isset($options['noController'])) ? $options['noController'] : false;
  417. $options['noRender'] = (isset($options['noRender'])) ? $options['noRender'] : false;
  418. $this->_scriptAction = null;
  419. $this->_responseSegment = null;
  420. // Set options first; may be used to determine other initializations
  421. $this->_setOptions($options);
  422. // Get base view path
  423. if (empty($path)) {
  424. $path = $this->_getBasePath();
  425. if (empty($path)) {
  426. /**
  427. * @see Zend_Controller_Action_Exception
  428. */
  429. require_once 'Zend/Controller/Action/Exception.php';
  430. throw new Zend_Controller_Action_Exception('ViewRenderer initialization failed: retrieved view base path is empty');
  431. }
  432. }
  433. if (null === $prefix) {
  434. $prefix = $this->_generateDefaultPrefix();
  435. }
  436. // Determine if this path has already been registered
  437. $currentPaths = $this->view->getScriptPaths();
  438. $path = str_replace(array('/', '\\'), '/', $path);
  439. $pathExists = false;
  440. foreach ($currentPaths as $tmpPath) {
  441. $tmpPath = str_replace(array('/', '\\'), '/', $tmpPath);
  442. if (strstr($tmpPath, $path)) {
  443. $pathExists = true;
  444. break;
  445. }
  446. }
  447. if (!$pathExists) {
  448. $this->view->addBasePath($path, $prefix);
  449. }
  450. // Register view with action controller (unless already registered)
  451. if ((null !== $this->_actionController) && (null === $this->_actionController->view)) {
  452. $this->_actionController->view = $this->view;
  453. $this->_actionController->viewSuffix = $this->_viewSuffix;
  454. }
  455. }
  456. /**
  457. * init - initialize view
  458. *
  459. * @return void
  460. */
  461. public function init()
  462. {
  463. if ($this->getFrontController()->getParam('noViewRenderer')) {
  464. return;
  465. }
  466. $this->initView();
  467. }
  468. /**
  469. * Set view basePath specification
  470. *
  471. * Specification can contain one or more of the following:
  472. * - :moduleDir - current module directory
  473. * - :controller - name of current controller in the request
  474. * - :action - name of current action in the request
  475. * - :module - name of current module in the request
  476. *
  477. * @param string $path
  478. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  479. */
  480. public function setViewBasePathSpec($path)
  481. {
  482. $this->_viewBasePathSpec = (string) $path;
  483. return $this;
  484. }
  485. /**
  486. * Retrieve the current view basePath specification string
  487. *
  488. * @return string
  489. */
  490. public function getViewBasePathSpec()
  491. {
  492. return $this->_viewBasePathSpec;
  493. }
  494. /**
  495. * Set view script path specification
  496. *
  497. * Specification can contain one or more of the following:
  498. * - :moduleDir - current module directory
  499. * - :controller - name of current controller in the request
  500. * - :action - name of current action in the request
  501. * - :module - name of current module in the request
  502. *
  503. * @param string $path
  504. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  505. */
  506. public function setViewScriptPathSpec($path)
  507. {
  508. $this->_viewScriptPathSpec = (string) $path;
  509. return $this;
  510. }
  511. /**
  512. * Retrieve the current view script path specification string
  513. *
  514. * @return string
  515. */
  516. public function getViewScriptPathSpec()
  517. {
  518. return $this->_viewScriptPathSpec;
  519. }
  520. /**
  521. * Set view script path specification (no controller variant)
  522. *
  523. * Specification can contain one or more of the following:
  524. * - :moduleDir - current module directory
  525. * - :controller - name of current controller in the request
  526. * - :action - name of current action in the request
  527. * - :module - name of current module in the request
  528. *
  529. * :controller will likely be ignored in this variant.
  530. *
  531. * @param string $path
  532. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  533. */
  534. public function setViewScriptPathNoControllerSpec($path)
  535. {
  536. $this->_viewScriptPathNoControllerSpec = (string) $path;
  537. return $this;
  538. }
  539. /**
  540. * Retrieve the current view script path specification string (no controller variant)
  541. *
  542. * @return string
  543. */
  544. public function getViewScriptPathNoControllerSpec()
  545. {
  546. return $this->_viewScriptPathNoControllerSpec;
  547. }
  548. /**
  549. * Get a view script based on an action and/or other variables
  550. *
  551. * Uses values found in current request if no values passed in $vars.
  552. *
  553. * If {@link $_noController} is set, uses {@link $_viewScriptPathNoControllerSpec};
  554. * otherwise, uses {@link $_viewScriptPathSpec}.
  555. *
  556. * @param string $action
  557. * @param array $vars
  558. * @return string
  559. */
  560. public function getViewScript($action = null, array $vars = array())
  561. {
  562. $request = $this->getRequest();
  563. if ((null === $action) && (!isset($vars['action']))) {
  564. $action = $this->getScriptAction();
  565. if (null === $action) {
  566. $action = $request->getActionName();
  567. }
  568. $vars['action'] = $action;
  569. } elseif (null !== $action) {
  570. $vars['action'] = $action;
  571. }
  572. $inflector = $this->getInflector();
  573. if ($this->getNoController() || $this->getNeverController()) {
  574. $this->_setInflectorTarget($this->getViewScriptPathNoControllerSpec());
  575. } else {
  576. $this->_setInflectorTarget($this->getViewScriptPathSpec());
  577. }
  578. return $this->_translateSpec($vars);
  579. }
  580. /**
  581. * Set the neverRender flag (i.e., globally dis/enable autorendering)
  582. *
  583. * @param boolean $flag
  584. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  585. */
  586. public function setNeverRender($flag = true)
  587. {
  588. $this->_neverRender = ($flag) ? true : false;
  589. return $this;
  590. }
  591. /**
  592. * Retrieve neverRender flag value
  593. *
  594. * @return boolean
  595. */
  596. public function getNeverRender()
  597. {
  598. return $this->_neverRender;
  599. }
  600. /**
  601. * Set the noRender flag (i.e., whether or not to autorender)
  602. *
  603. * @param boolean $flag
  604. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  605. */
  606. public function setNoRender($flag = true)
  607. {
  608. $this->_noRender = ($flag) ? true : false;
  609. return $this;
  610. }
  611. /**
  612. * Retrieve noRender flag value
  613. *
  614. * @return boolean
  615. */
  616. public function getNoRender()
  617. {
  618. return $this->_noRender;
  619. }
  620. /**
  621. * Set the view script to use
  622. *
  623. * @param string $name
  624. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  625. */
  626. public function setScriptAction($name)
  627. {
  628. $this->_scriptAction = (string) $name;
  629. return $this;
  630. }
  631. /**
  632. * Retrieve view script name
  633. *
  634. * @return string
  635. */
  636. public function getScriptAction()
  637. {
  638. return $this->_scriptAction;
  639. }
  640. /**
  641. * Set the response segment name
  642. *
  643. * @param string $name
  644. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  645. */
  646. public function setResponseSegment($name)
  647. {
  648. if (null === $name) {
  649. $this->_responseSegment = null;
  650. } else {
  651. $this->_responseSegment = (string) $name;
  652. }
  653. return $this;
  654. }
  655. /**
  656. * Retrieve named response segment name
  657. *
  658. * @return string
  659. */
  660. public function getResponseSegment()
  661. {
  662. return $this->_responseSegment;
  663. }
  664. /**
  665. * Set the noController flag (i.e., whether or not to render into controller subdirectories)
  666. *
  667. * @param boolean $flag
  668. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  669. */
  670. public function setNoController($flag = true)
  671. {
  672. $this->_noController = ($flag) ? true : false;
  673. return $this;
  674. }
  675. /**
  676. * Retrieve noController flag value
  677. *
  678. * @return boolean
  679. */
  680. public function getNoController()
  681. {
  682. return $this->_noController;
  683. }
  684. /**
  685. * Set the neverController flag (i.e., whether or not to render into controller subdirectories)
  686. *
  687. * @param boolean $flag
  688. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  689. */
  690. public function setNeverController($flag = true)
  691. {
  692. $this->_neverController = ($flag) ? true : false;
  693. return $this;
  694. }
  695. /**
  696. * Retrieve neverController flag value
  697. *
  698. * @return boolean
  699. */
  700. public function getNeverController()
  701. {
  702. return $this->_neverController;
  703. }
  704. /**
  705. * Set view script suffix
  706. *
  707. * @param string $suffix
  708. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  709. */
  710. public function setViewSuffix($suffix)
  711. {
  712. $this->_viewSuffix = (string) $suffix;
  713. return $this;
  714. }
  715. /**
  716. * Get view script suffix
  717. *
  718. * @return string
  719. */
  720. public function getViewSuffix()
  721. {
  722. return $this->_viewSuffix;
  723. }
  724. /**
  725. * Set options for rendering a view script
  726. *
  727. * @param string $action View script to render
  728. * @param string $name Response named segment to render to
  729. * @param boolean $noController Whether or not to render within a subdirectory named after the controller
  730. * @return Zend_Controller_Action_Helper_ViewRenderer Provides a fluent interface
  731. */
  732. public function setRender($action = null, $name = null, $noController = null)
  733. {
  734. if (null !== $action) {
  735. $this->setScriptAction($action);
  736. }
  737. if (null !== $name) {
  738. $this->setResponseSegment($name);
  739. }
  740. if (null !== $noController) {
  741. $this->setNoController($noController);
  742. }
  743. return $this;
  744. }
  745. /**
  746. * Inflect based on provided vars
  747. *
  748. * Allowed variables are:
  749. * - :moduleDir - current module directory
  750. * - :module - current module name
  751. * - :controller - current controller name
  752. * - :action - current action name
  753. * - :suffix - view script file suffix
  754. *
  755. * @param array $vars
  756. * @return string
  757. */
  758. protected function _translateSpec(array $vars = array())
  759. {
  760. $inflector = $this->getInflector();
  761. $request = $this->getRequest();
  762. $dispatcher = $this->_frontController->getDispatcher();
  763. $module = $dispatcher->formatModuleName($request->getModuleName());
  764. $controller = $request->getControllerName();
  765. $action = $dispatcher->formatActionName($request->getActionName());
  766. $params = compact('module', 'controller', 'action');
  767. foreach ($vars as $key => $value) {
  768. switch ($key) {
  769. case 'module':
  770. case 'controller':
  771. case 'action':
  772. case 'moduleDir':
  773. case 'suffix':
  774. $params[$key] = (string) $value;
  775. break;
  776. default:
  777. break;
  778. }
  779. }
  780. if (isset($params['suffix'])) {
  781. $origSuffix = $this->getViewSuffix();
  782. $this->setViewSuffix($params['suffix']);
  783. }
  784. if (isset($params['moduleDir'])) {
  785. $origModuleDir = $this->_getModuleDir();
  786. $this->_setModuleDir($params['moduleDir']);
  787. }
  788. $filtered = $inflector->filter($params);
  789. if (isset($params['suffix'])) {
  790. $this->setViewSuffix($origSuffix);
  791. }
  792. if (isset($params['moduleDir'])) {
  793. $this->_setModuleDir($origModuleDir);
  794. }
  795. return $filtered;
  796. }
  797. /**
  798. * Render a view script (optionally to a named response segment)
  799. *
  800. * Sets the noRender flag to true when called.
  801. *
  802. * @param string $script
  803. * @param string $name
  804. * @return void
  805. */
  806. public function renderScript($script, $name = null)
  807. {
  808. if (null === $name) {
  809. $name = $this->getResponseSegment();
  810. }
  811. $this->getResponse()->appendBody(
  812. $this->view->render($script),
  813. $name
  814. );
  815. $this->setNoRender();
  816. }
  817. /**
  818. * Render a view based on path specifications
  819. *
  820. * Renders a view based on the view script path specifications.
  821. *
  822. * @param string $action
  823. * @param string $name
  824. * @param boolean $noController
  825. * @return void
  826. */
  827. public function render($action = null, $name = null, $noController = null)
  828. {
  829. $this->setRender($action, $name, $noController);
  830. $path = $this->getViewScript();
  831. $this->renderScript($path, $name);
  832. }
  833. /**
  834. * Render a script based on specification variables
  835. *
  836. * Pass an action, and one or more specification variables (view script suffix)
  837. * to determine the view script path, and render that script.
  838. *
  839. * @param string $action
  840. * @param array $vars
  841. * @param string $name
  842. * @return void
  843. */
  844. public function renderBySpec($action = null, array $vars = array(), $name = null)
  845. {
  846. if (null !== $name) {
  847. $this->setResponseSegment($name);
  848. }
  849. $path = $this->getViewScript($action, $vars);
  850. $this->renderScript($path);
  851. }
  852. /**
  853. * postDispatch - auto render a view
  854. *
  855. * Only autorenders if:
  856. * - _noRender is false
  857. * - action controller is present
  858. * - request has not been re-dispatched (i.e., _forward() has not been called)
  859. * - response is not a redirect
  860. *
  861. * @return void
  862. */
  863. public function postDispatch()
  864. {
  865. if ($this->_shouldRender()) {
  866. $this->render();
  867. }
  868. }
  869. /**
  870. * Should the ViewRenderer render a view script?
  871. *
  872. * @return boolean
  873. */
  874. protected function _shouldRender()
  875. {
  876. return (!$this->getFrontController()->getParam('noViewRenderer')
  877. && !$this->_neverRender
  878. && !$this->_noRender
  879. && (null !== $this->_actionController)
  880. && $this->getRequest()->isDispatched()
  881. && !$this->getResponse()->isRedirect()
  882. );
  883. }
  884. /**
  885. * Use this helper as a method; proxies to setRender()
  886. *
  887. * @param string $action
  888. * @param string $name
  889. * @param boolean $noController
  890. * @return void
  891. */
  892. public function direct($action = null, $name = null, $noController = null)
  893. {
  894. $this->setRender($action, $name, $noController);
  895. }
  896. }