diff --git a/module/VuFindTheme/src/VuFindTheme/AbstractThemeUtility.php b/module/VuFindTheme/src/VuFindTheme/AbstractThemeUtility.php new file mode 100644 index 0000000000000000000000000000000000000000..d0e1e70a4ca4eea18642935f43fc6ce418fe1f14 --- /dev/null +++ b/module/VuFindTheme/src/VuFindTheme/AbstractThemeUtility.php @@ -0,0 +1,149 @@ +<?php +/** + * Abstract base class to hold shared logic for theme utilities. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2017. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Theme + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +namespace VuFindTheme; + +/** + * Abstract base class to hold shared logic for theme utilities. + * + * @category VuFind + * @package Theme + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +abstract class AbstractThemeUtility +{ + /** + * Theme info object + * + * @var ThemeInfo + */ + protected $info; + + /** + * Last error message + * + * @var string + */ + protected $lastError = null; + + /** + * Constructor + * + * @param ThemeInfo $info Theme info object + */ + public function __construct(ThemeInfo $info) + { + $this->info = $info; + } + + /** + * Get last error message. + * + * @return string + */ + public function getLastError() + { + return $this->lastError; + } + + /** + * Copy the contents of $src into $dest if no matching files already exist. + * + * @param string $src Source directory + * @param string $dest Target directory + * + * @return bool + */ + protected function copyDir($src, $dest) + { + if (!is_dir($dest)) { + if (!mkdir($dest)) { + return $this->setLastError("Cannot create $dest"); + } + } + $dir = opendir($src); + while ($current = readdir($dir)) { + if ($current === '.' || $current === '..') { + continue; + } + if (is_dir("$src/$current")) { + if (!$this->copyDir("$src/$current", "$dest/$current")) { + return false; + } + } else if (!file_exists("$dest/$current") + && !copy("$src/$current", "$dest/$current") + ) { + return $this->setLastError( + "Cannot copy $src/$current to $dest/$current." + ); + } + } + closedir($dir); + return true; + } + + /** + * Recursively delete a directory and its contents. + * + * @param string $path Directory to delete. + * + * @return bool + */ + protected function deleteDir($path) + { + $dir = opendir($path); + while ($current = readdir($dir)) { + if ($current === '.' || $current === '..') { + continue; + } + if (is_dir("$path/$current")) { + if (!$this->deleteDir("$path/$current")) { + return false; + } + } else if (!unlink("$path/$current")) { + return $this->setLastError("Cannot delete $path/$current"); + } + } + closedir($dir); + return rmdir($path); + } + + /** + * Set last error message and return a boolean false. + * + * @param string $error Error message. + * + * @return bool + */ + protected function setLastError($error) + { + $this->lastError = $error; + return false; + } +} diff --git a/module/VuFindTheme/src/VuFindTheme/ThemeCompiler.php b/module/VuFindTheme/src/VuFindTheme/ThemeCompiler.php index 55ceed5fdcb7896bf48b5543b815ee0fb8fdf74c..89d3d2b497a01f717fd31e643b7b7848aa38fef5 100644 --- a/module/VuFindTheme/src/VuFindTheme/ThemeCompiler.php +++ b/module/VuFindTheme/src/VuFindTheme/ThemeCompiler.php @@ -36,32 +36,8 @@ namespace VuFindTheme; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org Main Site */ -class ThemeCompiler +class ThemeCompiler extends AbstractThemeUtility { - /** - * Theme info object - * - * @var ThemeInfo - */ - protected $info; - - /** - * Last error message - * - * @var string - */ - protected $lastError = null; - - /** - * Constructor - * - * @param ThemeInfo $info Theme info object - */ - public function __construct(ThemeInfo $info) - { - $this->info = $info; - } - /** * Compile from $source theme into $target theme. * @@ -114,16 +90,6 @@ class ThemeCompiler return true; } - /** - * Get last error message. - * - * @return string - */ - public function getLastError() - { - return $this->lastError; - } - /** * Remove a theme directory (used for cleanup in testing). * @@ -136,68 +102,6 @@ class ThemeCompiler return $this->deleteDir($this->info->getBaseDir() . '/' . $theme); } - /** - * Copy the contents of $src into $dest if no matching files already exist. - * - * @param string $src Source directory - * @param string $dest Target directory - * - * @return bool - */ - protected function copyDir($src, $dest) - { - if (!is_dir($dest)) { - if (!mkdir($dest)) { - return $this->setLastError("Cannot create $dest"); - } - } - $dir = opendir($src); - while ($current = readdir($dir)) { - if ($current === '.' || $current === '..') { - continue; - } - if (is_dir("$src/$current")) { - if (!$this->copyDir("$src/$current", "$dest/$current")) { - return false; - } - } else if (!file_exists("$dest/$current") - && !copy("$src/$current", "$dest/$current") - ) { - return $this->setLastError( - "Cannot copy $src/$current to $dest/$current." - ); - } - } - closedir($dir); - return true; - } - - /** - * Recursively delete a directory and its contents. - * - * @param string $path Directory to delete. - * - * @return bool - */ - protected function deleteDir($path) - { - $dir = opendir($path); - while ($current = readdir($dir)) { - if ($current === '.' || $current === '..') { - continue; - } - if (is_dir("$path/$current")) { - if (!$this->deleteDir("$path/$current")) { - return false; - } - } else if (!unlink("$path/$current")) { - return $this->setLastError("Cannot delete $path/$current"); - } - } - closedir($dir); - return rmdir($path); - } - /** * Merge configurations from $src into $dest; return the result. * @@ -233,17 +137,4 @@ class ThemeCompiler } return $dest; } - - /** - * Set last error message and return a boolean false. - * - * @param string $error Error message. - * - * @return bool - */ - protected function setLastError($error) - { - $this->lastError = $error; - return false; - } } diff --git a/module/VuFindTheme/src/VuFindTheme/ThemeGenerator.php b/module/VuFindTheme/src/VuFindTheme/ThemeGenerator.php index 78d40101e261fe7320d6e071453db886eb376959..32d01e35004f806ee3db3551e8120819cc6811ea 100644 --- a/module/VuFindTheme/src/VuFindTheme/ThemeGenerator.php +++ b/module/VuFindTheme/src/VuFindTheme/ThemeGenerator.php @@ -42,32 +42,8 @@ use Zend\Console\Console; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org Main Site */ -class ThemeGenerator +class ThemeGenerator extends AbstractThemeUtility { - /** - * Theme info object - * - * @var ThemeInfo - */ - protected $info; - - /** - * Last error message - * - * @var string - */ - protected $lastError = null; - - /** - * Constructor - * - * @param ThemeInfo $info Theme info object - */ - public function __construct(ThemeInfo $info) - { - $this->info = $info; - } - /** * Generate a new theme from a template. * @@ -84,15 +60,12 @@ class ThemeGenerator return $this->setLastError('Theme "' . $name . '" already exists'); } Console::writeLine('Creating new theme: "' . $name . '"'); - $source = $this->getAbsolutePath($baseDir . $themeTemplate); - $dest = $this->getAbsolutePath($baseDir . $name); + $source = $baseDir . $themeTemplate; + $dest = $baseDir . $name; Console::writeLine("\tCopying $themeTemplate"); Console::writeLine("\t\tFrom: " . $source); Console::writeLine("\t\tTo: " . $dest); - if (!$this->copyDirectory($source, $dest)) { - return $this->setLastError("Copy failed."); - } - return true; + return $this->copyDir($source, $dest); } /** @@ -108,6 +81,10 @@ class ThemeGenerator { // Enable theme $configPath = ConfigLocator::getLocalConfigPath('config.ini', null, true); + if (!file_exists($configPath)) { + return $this + ->setLastError("Expected configuration file missing: $configPath"); + } Console::writeLine("\tUpdating $configPath..."); Console::writeLine("\t\t[Site] > theme = $name"); $writer = new ConfigWriter($configPath); @@ -160,98 +137,4 @@ class ThemeGenerator } return true; } - - /** - * Get last error message. - * - * @return string - */ - public function getLastError() - { - return $this->lastError; - } - - /** - * Copies contents from $source to $dest - * - * @param string $source full path to source directory - * @param string $dest full path to copy destination - * - * @return boolean true on success false otherwise - */ - protected function copyDirectory($source, $dest) - { - $sourceHandle = opendir($source); - if (!file_exists($dest)) { - mkdir($dest, 0755); - } - - if (!$sourceHandle) { - return false; - } - - $success = true; - while ($file = readdir($sourceHandle)) { - if ($file == '.' || $file == '..') { - continue; - } - - if (is_dir($source . '/' . $file)) { - if (!file_exists($dest . '/' . $file)) { - mkdir($dest . '/' . $file, 0755); - } - if (!$this->copyDirectory("$source/$file", "$dest/$file")) { - $success = false; - break; - } - } else { - copy($source . '/' . $file, $dest . '/' . $file); - } - } - closedir($sourceHandle); - - return $success; - } - - /** - * Removes // and /./ in paths and collapses /../ - * Same as realpath, but doesn't check for file existence - * - * @param string $path full path to condense - * - * @return string - */ - protected function getAbsolutePath($path) - { - $path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path); - $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); - $absolutes = []; - foreach ($parts as $part) { - if ('.' == $part) { - continue; - } - if ('..' == $part) { - array_pop($absolutes); - } else { - $absolutes[] = $part; - } - } - if (substr($path, 0, 1) === DIRECTORY_SEPARATOR) { - return DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $absolutes); - } - return implode(DIRECTORY_SEPARATOR, $absolutes); - } - - /** - * Set last error message and return a boolean false. - * - * @param string $error Error message. - * - * @return bool - */ - protected function setLastError($error) - { - $this->lastError = $error; - return false; - } }