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\Factory\Resource;
13
14/**
15 * Coalesces multiple directories together into one merged resource.
16 *
17 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
18 */
19class CoalescingDirectoryResource implements IteratorResourceInterface
20{
21    private $directories;
22
23    public function __construct($directories)
24    {
25        $this->directories = array();
26
27        foreach ($directories as $directory) {
28            $this->addDirectory($directory);
29        }
30    }
31
32    public function addDirectory(IteratorResourceInterface $directory)
33    {
34        $this->directories[] = $directory;
35    }
36
37    public function isFresh($timestamp)
38    {
39        foreach ($this->getFileResources() as $file) {
40            if (!$file->isFresh($timestamp)) {
41                return false;
42            }
43        }
44
45        return true;
46    }
47
48    public function getContent()
49    {
50        $parts = array();
51        foreach ($this->getFileResources() as $file) {
52            $parts[] = $file->getContent();
53        }
54
55        return implode("\n", $parts);
56    }
57
58    /**
59     * Returns a string to uniquely identify the current resource.
60     *
61     * @return string An identifying string
62     */
63    public function __toString()
64    {
65        $parts = array();
66        foreach ($this->directories as $directory) {
67            $parts[] = (string) $directory;
68        }
69
70        return implode(',', $parts);
71    }
72
73    public function getIterator()
74    {
75        return new \ArrayIterator($this->getFileResources());
76    }
77
78    /**
79     * Returns the relative version of a filename.
80     *
81     * @param ResourceInterface $file      The file
82     * @param ResourceInterface $directory The directory
83     *
84     * @return string The name to compare with files from other directories
85     */
86    protected function getRelativeName(ResourceInterface $file, ResourceInterface $directory)
87    {
88        return substr((string) $file, strlen((string) $directory));
89    }
90
91    /**
92     * Performs the coalesce.
93     *
94     * @return array An array of file resources
95     */
96    private function getFileResources()
97    {
98        $paths = array();
99
100        foreach ($this->directories as $directory) {
101            foreach ($directory as $file) {
102                $relative = $this->getRelativeName($file, $directory);
103
104                if (!isset($paths[$relative])) {
105                    $paths[$relative] = $file;
106                }
107            }
108        }
109
110        return array_values($paths);
111    }
112}
113