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\Resolver; 11 12use ArrayIterator; 13use IteratorAggregate; 14use Traversable; 15use Zend\Stdlib\ArrayUtils; 16use Zend\View\Exception; 17use Zend\View\Renderer\RendererInterface as Renderer; 18 19class TemplateMapResolver implements IteratorAggregate, ResolverInterface 20{ 21 /** 22 * @var array 23 */ 24 protected $map = array(); 25 26 /** 27 * Constructor 28 * 29 * Instantiate and optionally populate template map. 30 * 31 * @param array|Traversable $map 32 */ 33 public function __construct($map = array()) 34 { 35 $this->setMap($map); 36 } 37 38 /** 39 * IteratorAggregate: return internal iterator 40 * 41 * @return Traversable 42 */ 43 public function getIterator() 44 { 45 return new ArrayIterator($this->map); 46 } 47 48 /** 49 * Set (overwrite) template map 50 * 51 * Maps should be arrays or Traversable objects with name => path pairs 52 * 53 * @param array|Traversable $map 54 * @throws Exception\InvalidArgumentException 55 * @return TemplateMapResolver 56 */ 57 public function setMap($map) 58 { 59 if (!is_array($map) && !$map instanceof Traversable) { 60 throw new Exception\InvalidArgumentException(sprintf( 61 '%s: expects an array or Traversable, received "%s"', 62 __METHOD__, 63 (is_object($map) ? get_class($map) : gettype($map)) 64 )); 65 } 66 67 if ($map instanceof Traversable) { 68 $map = ArrayUtils::iteratorToArray($map); 69 } 70 71 $this->map = $map; 72 return $this; 73 } 74 75 /** 76 * Add an entry to the map 77 * 78 * @param string|array|Traversable $nameOrMap 79 * @param null|string $path 80 * @throws Exception\InvalidArgumentException 81 * @return TemplateMapResolver 82 */ 83 public function add($nameOrMap, $path = null) 84 { 85 if (is_array($nameOrMap) || $nameOrMap instanceof Traversable) { 86 $this->merge($nameOrMap); 87 return $this; 88 } 89 90 if (!is_string($nameOrMap)) { 91 throw new Exception\InvalidArgumentException(sprintf( 92 '%s: expects a string, array, or Traversable for the first argument; received "%s"', 93 __METHOD__, 94 (is_object($nameOrMap) ? get_class($nameOrMap) : gettype($nameOrMap)) 95 )); 96 } 97 98 if (empty($path)) { 99 if (isset($this->map[$nameOrMap])) { 100 unset($this->map[$nameOrMap]); 101 } 102 return $this; 103 } 104 105 $this->map[$nameOrMap] = $path; 106 return $this; 107 } 108 109 /** 110 * Merge internal map with provided map 111 * 112 * @param array|Traversable $map 113 * @throws Exception\InvalidArgumentException 114 * @return TemplateMapResolver 115 */ 116 public function merge($map) 117 { 118 if (!is_array($map) && !$map instanceof Traversable) { 119 throw new Exception\InvalidArgumentException(sprintf( 120 '%s: expects an array or Traversable, received "%s"', 121 __METHOD__, 122 (is_object($map) ? get_class($map) : gettype($map)) 123 )); 124 } 125 126 if ($map instanceof Traversable) { 127 $map = ArrayUtils::iteratorToArray($map); 128 } 129 130 $this->map = array_replace_recursive($this->map, $map); 131 return $this; 132 } 133 134 /** 135 * Does the resolver contain an entry for the given name? 136 * 137 * @param string $name 138 * @return bool 139 */ 140 public function has($name) 141 { 142 return array_key_exists($name, $this->map); 143 } 144 145 /** 146 * Retrieve a template path by name 147 * 148 * @param string $name 149 * @return false|string 150 * @throws Exception\DomainException if no entry exists 151 */ 152 public function get($name) 153 { 154 if (!$this->has($name)) { 155 return false; 156 } 157 return $this->map[$name]; 158 } 159 160 /** 161 * Retrieve the template map 162 * 163 * @return array 164 */ 165 public function getMap() 166 { 167 return $this->map; 168 } 169 170 /** 171 * Resolve a template/pattern name to a resource the renderer can consume 172 * 173 * @param string $name 174 * @param null|Renderer $renderer 175 * @return string 176 */ 177 public function resolve($name, Renderer $renderer = null) 178 { 179 return $this->get($name); 180 } 181} 182