1<?php 2 3/* 4 * This file is part of the Assetic package, an OpenSky project. 5 * 6 * (c) 2010-2014 OpenSky Project Inc 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Assetic\Asset\Iterator; 13 14use Assetic\Asset\AssetCollectionInterface; 15 16/** 17 * Iterates over an asset collection. 18 * 19 * The iterator is responsible for cascading filters and target URL patterns 20 * from parent to child assets. 21 * 22 * @author Kris Wallsmith <kris.wallsmith@gmail.com> 23 */ 24class AssetCollectionIterator implements \RecursiveIterator 25{ 26 private $assets; 27 private $filters; 28 private $vars; 29 private $output; 30 private $clones; 31 32 public function __construct(AssetCollectionInterface $coll, \SplObjectStorage $clones) 33 { 34 $this->assets = $coll->all(); 35 $this->filters = $coll->getFilters(); 36 $this->vars = $coll->getVars(); 37 $this->output = $coll->getTargetPath(); 38 $this->clones = $clones; 39 40 if (false === $pos = strrpos($this->output, '.')) { 41 $this->output .= '_*'; 42 } else { 43 $this->output = substr($this->output, 0, $pos).'_*'.substr($this->output, $pos); 44 } 45 } 46 47 /** 48 * Returns a copy of the current asset with filters and a target URL applied. 49 * 50 * @param Boolean $raw Returns the unmodified asset if true 51 * 52 * @return \Assetic\Asset\AssetInterface 53 */ 54 public function current($raw = false) 55 { 56 $asset = current($this->assets); 57 58 if ($raw) { 59 return $asset; 60 } 61 62 // clone once 63 if (!isset($this->clones[$asset])) { 64 $clone = $this->clones[$asset] = clone $asset; 65 66 // generate a target path based on asset name 67 $name = sprintf('%s_%d', pathinfo($asset->getSourcePath(), PATHINFO_FILENAME) ?: 'part', $this->key() + 1); 68 69 $name = $this->removeDuplicateVar($name); 70 71 $clone->setTargetPath(str_replace('*', $name, $this->output)); 72 } else { 73 $clone = $this->clones[$asset]; 74 } 75 76 // cascade filters 77 foreach ($this->filters as $filter) { 78 $clone->ensureFilter($filter); 79 } 80 81 return $clone; 82 } 83 84 public function key() 85 { 86 return key($this->assets); 87 } 88 89 public function next() 90 { 91 return next($this->assets); 92 } 93 94 public function rewind() 95 { 96 return reset($this->assets); 97 } 98 99 public function valid() 100 { 101 return false !== current($this->assets); 102 } 103 104 public function hasChildren() 105 { 106 return current($this->assets) instanceof AssetCollectionInterface; 107 } 108 109 /** 110 * @uses current() 111 */ 112 public function getChildren() 113 { 114 return new self($this->current(), $this->clones); 115 } 116 117 private function removeDuplicateVar($name) 118 { 119 foreach ($this->vars as $var) { 120 $var = '{'.$var.'}'; 121 if (false !== strpos($name, $var) && false !== strpos($this->output, $var)) { 122 $name = str_replace($var, '', $name); 123 } 124 } 125 126 return $name; 127 } 128} 129