Version 1
[yaffs-website] / vendor / alchemy / zippy / src / Adapter / AbstractAdapter.php
diff --git a/vendor/alchemy/zippy/src/Adapter/AbstractAdapter.php b/vendor/alchemy/zippy/src/Adapter/AbstractAdapter.php
new file mode 100644 (file)
index 0000000..e0ad2a8
--- /dev/null
@@ -0,0 +1,273 @@
+<?php
+
+/*
+ * This file is part of Zippy.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ */
+
+namespace Alchemy\Zippy\Adapter;
+
+use Alchemy\Zippy\Adapter\Resource\ResourceInterface;
+use Alchemy\Zippy\Adapter\VersionProbe\VersionProbeInterface;
+use Alchemy\Zippy\Archive\Archive;
+use Alchemy\Zippy\Archive\ArchiveInterface;
+use Alchemy\Zippy\Exception\RuntimeException;
+use Alchemy\Zippy\Exception\InvalidArgumentException;
+use Alchemy\Zippy\Resource\PathUtil;
+use Alchemy\Zippy\Resource\ResourceManager;
+
+abstract class AbstractAdapter implements AdapterInterface
+{
+    /** @var ResourceManager */
+    protected $manager;
+
+    /**
+     * The version probe
+     *
+     * @var VersionProbeInterface
+     */
+    protected $probe;
+
+    public function __construct(ResourceManager $manager)
+    {
+        $this->manager = $manager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function open($path)
+    {
+        $this->requireSupport();
+
+        return new Archive($this->createResource($path), $this, $this->manager);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function create($path, $files = null, $recursive = true)
+    {
+        $this->requireSupport();
+
+        return $this->doCreate($this->makeTargetAbsolute($path), $files, $recursive);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function listMembers(ResourceInterface $resource)
+    {
+        $this->requireSupport();
+
+        return $this->doListMembers($resource);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function add(ResourceInterface $resource, $files, $recursive = true)
+    {
+        $this->requireSupport();
+
+        return $this->doAdd($resource, $files, $recursive);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function remove(ResourceInterface $resource, $files)
+    {
+        $this->requireSupport();
+
+        return $this->doRemove($resource, $files);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function extract(ResourceInterface $resource, $to = null)
+    {
+        $this->requireSupport();
+
+        return $this->doExtract($resource, $to);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function extractMembers(ResourceInterface $resource, $members, $to = null, $overwrite = false)
+    {
+        $this->requireSupport();
+
+        return $this->doExtractMembers($resource, $members, $to, $overwrite);
+    }
+
+    /**
+     * Returns the version probe used by this adapter
+     *
+     * @return VersionProbeInterface
+     */
+    public function getVersionProbe()
+    {
+        return $this->probe;
+    }
+
+    /**
+     * Sets the version probe used by this adapter
+     *
+     * @param VersionProbeInterface $probe
+     *
+     * @return VersionProbeInterface
+     */
+    public function setVersionProbe(VersionProbeInterface $probe)
+    {
+        $this->probe = $probe;
+
+        return $this;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function isSupported()
+    {
+        if (!$this->probe) {
+            throw new RuntimeException(sprintf(
+                'No version probe has been set on %s whereas it is required', get_class($this)
+            ));
+        }
+
+        return VersionProbeInterface::PROBE_OK === $this->probe->getStatus();
+    }
+
+    /**
+     * Throws an exception is the current adapter is not supported
+     *
+     * @throws RuntimeException
+     */
+    protected function requireSupport()
+    {
+        if (false === $this->isSupported()) {
+            throw new RuntimeException(sprintf('%s is not supported on your system', get_class($this)));
+        }
+    }
+
+    /**
+     * Change current working directory to another
+     *
+     * @param string $target the target directory
+     *
+     * @return AdapterInterface
+     *
+     * @throws RuntimeException In case of failure
+     */
+    protected function chdir($target)
+    {
+        if (false === @chdir($target)) {
+            throw new RuntimeException(sprintf('Unable to chdir to `%s`', $target));
+        }
+
+        return $this;
+    }
+
+    /**
+     * Creates a resource given a path
+     *
+     * @param string $path
+     *
+     * @return ResourceInterface
+     */
+    abstract protected function createResource($path);
+
+    /**
+     * Do the removal after having check that the current adapter is supported
+     *
+     * @param ResourceInterface $resource
+     * @param array             $files
+     *
+     * @return array
+     */
+    abstract protected function doRemove(ResourceInterface $resource, $files);
+
+    /**
+     * Do the add after having check that the current adapter is supported
+     *
+     * @param ResourceInterface $resource
+     * @param array             $files
+     * @param bool              $recursive
+     *
+     * @return array
+     */
+    abstract protected function doAdd(ResourceInterface $resource, $files, $recursive);
+
+    /**
+     * Do the extract after having check that the current adapter is supported
+     *
+     * @param ResourceInterface $resource
+     * @param                   $to
+     *
+     * @return \SplFileInfo The extracted archive
+     */
+    abstract protected function doExtract(ResourceInterface $resource, $to);
+
+    /**
+     * Do the extract members after having check that the current adapter is supported
+     *
+     * @param ResourceInterface $resource
+     * @param string|string[]   $members
+     * @param string            $to
+     * @param bool              $overwrite
+     *
+     * @return \SplFileInfo The extracted archive
+     */
+    abstract protected function doExtractMembers(ResourceInterface $resource, $members, $to, $overwrite = false);
+
+    /**
+     * Do the list members after having check that the current adapter is supported
+     *
+     * @param ResourceInterface $resource
+     *
+     * @return array
+     */
+    abstract protected function doListMembers(ResourceInterface $resource);
+
+    /**
+     * Do the create after having check that the current adapter is supported
+     *
+     * @param string $path
+     * @param string $file
+     * @param bool   $recursive
+     *
+     * @return ArchiveInterface
+     */
+    abstract protected function doCreate($path, $file, $recursive);
+
+    /**
+     * Makes the target path absolute as the adapters might have a different directory
+     *
+     * @param string $path The path to convert
+     *
+     * @return string The absolute path
+     *
+     * @throws InvalidArgumentException In case the path is not writable or does not exist
+     */
+    private function makeTargetAbsolute($path)
+    {
+        $directory = dirname($path);
+
+        if (!is_dir($directory)) {
+            throw new InvalidArgumentException(sprintf('Target path %s does not exist.', $directory));
+        }
+        if (!is_writable($directory)) {
+            throw new InvalidArgumentException(sprintf('Target path %s is not writeable.', $directory));
+        }
+
+        return realpath($directory) . '/' . PathUtil::basename($path);
+    }
+}