Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ThemeGenerator
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 3
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 generate
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 configure
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
156
1<?php
2
3/**
4 * Class to generate a new theme from a template and reconfigure VuFind to use it.
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2017.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Theme
25 * @author   Chris Hallberg <challber@villanova.edu>
26 * @author   Demian Katz <demian.katz@villanova.edu>
27 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
28 * @link     https://vufind.org Main Site
29 */
30
31namespace VuFindTheme;
32
33use Laminas\Config\Config;
34use VuFind\Config\Locator as ConfigLocator;
35use VuFind\Config\PathResolver;
36use VuFind\Config\Writer as ConfigWriter;
37
38/**
39 * Class to generate a new theme from a template and reconfigure VuFind to use it.
40 *
41 * @category VuFind
42 * @package  Theme
43 * @author   Chris Hallberg <challber@villanova.edu>
44 * @author   Demian Katz <demian.katz@villanova.edu>
45 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
46 * @link     https://vufind.org Main Site
47 */
48class ThemeGenerator extends AbstractThemeUtility implements GeneratorInterface
49{
50    use \VuFindConsole\ConsoleOutputTrait;
51
52    /**
53     * Config file path resolver
54     *
55     * @var PathResolver
56     */
57    protected $pathResolver;
58
59    /**
60     * Constructor
61     *
62     * @param ThemeInfo    $info         Theme info object
63     * @param PathResolver $pathResolver Config file path resolver
64     */
65    public function __construct(ThemeInfo $info, PathResolver $pathResolver = null)
66    {
67        parent::__construct($info);
68        $this->pathResolver = $pathResolver;
69    }
70
71    /**
72     * Generate a new theme from a template.
73     *
74     * @param string $name          Name of theme to generate.
75     * @param string $themeTemplate Name of template theme
76     *
77     * @return bool
78     */
79    public function generate($name, $themeTemplate = 'local_theme_example')
80    {
81        // Check for existing theme
82        $baseDir = $this->info->getBaseDir() . '/';
83        if (realpath($baseDir . $name)) {
84            return $this->setLastError('Theme "' . $name . '" already exists');
85        }
86        $this->writeln('Creating new theme: "' . $name . '"');
87        $source = $baseDir . $themeTemplate;
88        $dest = $baseDir . $name;
89        $this->writeln("\tCopying $themeTemplate");
90        $this->writeln("\t\tFrom: " . $source);
91        $this->writeln("\t\tTo: " . $dest);
92        return $this->copyDir($source, $dest);
93    }
94
95    /**
96     * Configure the specified theme as VuFind's new default theme (and one of
97     * the alternatives).
98     *
99     * @param Config $config Existing VuFind configuration
100     * @param string $name   Theme name to add to configuration.
101     *
102     * @return bool
103     */
104    public function configure(Config $config, $name)
105    {
106        // Enable theme
107        $configPath = $this->pathResolver
108            ? $this->pathResolver->getLocalConfigPath('config.ini', null, true)
109            : ConfigLocator::getLocalConfigPath('config.ini', null, true);
110        if (!file_exists($configPath)) {
111            return $this
112                ->setLastError("Expected configuration file missing: $configPath");
113        }
114        $this->writeln("\tUpdating $configPath...");
115        $this->writeln("\t\t[Site] > theme = $name");
116        $writer = new ConfigWriter($configPath);
117        $writer->set('Site', 'theme', $name);
118        // Enable dropdown
119        $settingPrefixes = [
120            'bootstrap' => 'bs3',
121            'custom' => strtolower(str_replace(' ', '', $name)),
122        ];
123        // - Set alternate_themes
124        $this->writeln("\t\t[Site] > alternate_themes");
125        $altSetting = [];
126        if (isset($config->Site->alternate_themes)) {
127            $alts = explode(',', $config->Site->alternate_themes);
128            foreach ($alts as $a) {
129                $parts = explode(':', $a);
130                if ($parts[1] === 'bootstrap3') {
131                    $settingPrefixes['bootstrap'] = $parts[0];
132                } elseif ($parts[1] === $name) {
133                    $settingPrefixes['custom'] = $parts[0];
134                } else {
135                    $altSetting[] = $a;
136                }
137            }
138        }
139        $altSetting[] = $settingPrefixes['bootstrap'] . ':bootstrap3';
140        $altSetting[] = $settingPrefixes['custom'] . ':' . $name;
141        $writer->set('Site', 'alternate_themes', implode(',', $altSetting));
142        // - Set selectable_themes
143        $this->writeln("\t\t[Site] > selectable_themes");
144        $dropSetting = [
145            $settingPrefixes['bootstrap'] . ':Bootstrap',
146            $settingPrefixes['custom'] . ':' . ucwords($name),
147        ];
148        if (isset($config->Site->selectable_themes)) {
149            $themes = explode(',', $config->Site->selectable_themes);
150            foreach ($themes as $t) {
151                $parts = explode(':', $t);
152                if (
153                    $parts[0] !== $settingPrefixes['bootstrap']
154                    && $parts[0] !== $settingPrefixes['custom']
155                ) {
156                    $dropSetting[] = $t;
157                }
158            }
159        }
160        $writer->set('Site', 'selectable_themes', implode(',', $dropSetting));
161        // Save
162        if (!$writer->save()) {
163            return $this->setLastError("\tConfiguration saving failed!");
164        }
165        return true;
166    }
167}