Version 1
[yaffs-website] / vendor / alchemy / zippy / src / Adapter / AbstractAdapter.php
1 <?php
2
3 /*
4  * This file is part of Zippy.
5  *
6  * (c) Alchemy <info@alchemy.fr>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  *
11  */
12
13 namespace Alchemy\Zippy\Adapter;
14
15 use Alchemy\Zippy\Adapter\Resource\ResourceInterface;
16 use Alchemy\Zippy\Adapter\VersionProbe\VersionProbeInterface;
17 use Alchemy\Zippy\Archive\Archive;
18 use Alchemy\Zippy\Archive\ArchiveInterface;
19 use Alchemy\Zippy\Exception\RuntimeException;
20 use Alchemy\Zippy\Exception\InvalidArgumentException;
21 use Alchemy\Zippy\Resource\PathUtil;
22 use Alchemy\Zippy\Resource\ResourceManager;
23
24 abstract class AbstractAdapter implements AdapterInterface
25 {
26     /** @var ResourceManager */
27     protected $manager;
28
29     /**
30      * The version probe
31      *
32      * @var VersionProbeInterface
33      */
34     protected $probe;
35
36     public function __construct(ResourceManager $manager)
37     {
38         $this->manager = $manager;
39     }
40
41     /**
42      * @inheritdoc
43      */
44     public function open($path)
45     {
46         $this->requireSupport();
47
48         return new Archive($this->createResource($path), $this, $this->manager);
49     }
50
51     /**
52      * @inheritdoc
53      */
54     public function create($path, $files = null, $recursive = true)
55     {
56         $this->requireSupport();
57
58         return $this->doCreate($this->makeTargetAbsolute($path), $files, $recursive);
59     }
60
61     /**
62      * @inheritdoc
63      */
64     public function listMembers(ResourceInterface $resource)
65     {
66         $this->requireSupport();
67
68         return $this->doListMembers($resource);
69     }
70
71     /**
72      * @inheritdoc
73      */
74     public function add(ResourceInterface $resource, $files, $recursive = true)
75     {
76         $this->requireSupport();
77
78         return $this->doAdd($resource, $files, $recursive);
79     }
80
81     /**
82      * @inheritdoc
83      */
84     public function remove(ResourceInterface $resource, $files)
85     {
86         $this->requireSupport();
87
88         return $this->doRemove($resource, $files);
89     }
90
91     /**
92      * @inheritdoc
93      */
94     public function extract(ResourceInterface $resource, $to = null)
95     {
96         $this->requireSupport();
97
98         return $this->doExtract($resource, $to);
99     }
100
101     /**
102      * @inheritdoc
103      */
104     public function extractMembers(ResourceInterface $resource, $members, $to = null, $overwrite = false)
105     {
106         $this->requireSupport();
107
108         return $this->doExtractMembers($resource, $members, $to, $overwrite);
109     }
110
111     /**
112      * Returns the version probe used by this adapter
113      *
114      * @return VersionProbeInterface
115      */
116     public function getVersionProbe()
117     {
118         return $this->probe;
119     }
120
121     /**
122      * Sets the version probe used by this adapter
123      *
124      * @param VersionProbeInterface $probe
125      *
126      * @return VersionProbeInterface
127      */
128     public function setVersionProbe(VersionProbeInterface $probe)
129     {
130         $this->probe = $probe;
131
132         return $this;
133     }
134
135     /**
136      * @inheritdoc
137      */
138     public function isSupported()
139     {
140         if (!$this->probe) {
141             throw new RuntimeException(sprintf(
142                 'No version probe has been set on %s whereas it is required', get_class($this)
143             ));
144         }
145
146         return VersionProbeInterface::PROBE_OK === $this->probe->getStatus();
147     }
148
149     /**
150      * Throws an exception is the current adapter is not supported
151      *
152      * @throws RuntimeException
153      */
154     protected function requireSupport()
155     {
156         if (false === $this->isSupported()) {
157             throw new RuntimeException(sprintf('%s is not supported on your system', get_class($this)));
158         }
159     }
160
161     /**
162      * Change current working directory to another
163      *
164      * @param string $target the target directory
165      *
166      * @return AdapterInterface
167      *
168      * @throws RuntimeException In case of failure
169      */
170     protected function chdir($target)
171     {
172         if (false === @chdir($target)) {
173             throw new RuntimeException(sprintf('Unable to chdir to `%s`', $target));
174         }
175
176         return $this;
177     }
178
179     /**
180      * Creates a resource given a path
181      *
182      * @param string $path
183      *
184      * @return ResourceInterface
185      */
186     abstract protected function createResource($path);
187
188     /**
189      * Do the removal after having check that the current adapter is supported
190      *
191      * @param ResourceInterface $resource
192      * @param array             $files
193      *
194      * @return array
195      */
196     abstract protected function doRemove(ResourceInterface $resource, $files);
197
198     /**
199      * Do the add after having check that the current adapter is supported
200      *
201      * @param ResourceInterface $resource
202      * @param array             $files
203      * @param bool              $recursive
204      *
205      * @return array
206      */
207     abstract protected function doAdd(ResourceInterface $resource, $files, $recursive);
208
209     /**
210      * Do the extract after having check that the current adapter is supported
211      *
212      * @param ResourceInterface $resource
213      * @param                   $to
214      *
215      * @return \SplFileInfo The extracted archive
216      */
217     abstract protected function doExtract(ResourceInterface $resource, $to);
218
219     /**
220      * Do the extract members after having check that the current adapter is supported
221      *
222      * @param ResourceInterface $resource
223      * @param string|string[]   $members
224      * @param string            $to
225      * @param bool              $overwrite
226      *
227      * @return \SplFileInfo The extracted archive
228      */
229     abstract protected function doExtractMembers(ResourceInterface $resource, $members, $to, $overwrite = false);
230
231     /**
232      * Do the list members after having check that the current adapter is supported
233      *
234      * @param ResourceInterface $resource
235      *
236      * @return array
237      */
238     abstract protected function doListMembers(ResourceInterface $resource);
239
240     /**
241      * Do the create after having check that the current adapter is supported
242      *
243      * @param string $path
244      * @param string $file
245      * @param bool   $recursive
246      *
247      * @return ArchiveInterface
248      */
249     abstract protected function doCreate($path, $file, $recursive);
250
251     /**
252      * Makes the target path absolute as the adapters might have a different directory
253      *
254      * @param string $path The path to convert
255      *
256      * @return string The absolute path
257      *
258      * @throws InvalidArgumentException In case the path is not writable or does not exist
259      */
260     private function makeTargetAbsolute($path)
261     {
262         $directory = dirname($path);
263
264         if (!is_dir($directory)) {
265             throw new InvalidArgumentException(sprintf('Target path %s does not exist.', $directory));
266         }
267         if (!is_writable($directory)) {
268             throw new InvalidArgumentException(sprintf('Target path %s is not writeable.', $directory));
269         }
270
271         return realpath($directory) . '/' . PathUtil::basename($path);
272     }
273 }