Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
common_ext_ExtensionInstaller
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 11
1056
0.00% covered (danger)
0.00%
0 / 1
 install
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
20
 installLoadDefaultConfig
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
72
 installOntology
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 installRegisterExt
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 installCustomScript
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
90
 installLocalData
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setLocalData
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getLocalData
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExtensionModel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 extendedInstall
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2008-2010 (original work) Deutsche Institut für Internationale Pädagogische Forschung
19 *                         (under the project TAO-TRANSFER);
20 *             2009-2012 (update and modification) Public Research Centre Henri Tudor
21 *                         (under the project TAO-SUSTAIN & TAO-DEV);
22 *
23 */
24
25use oat\generis\model\data\ModelManager;
26use oat\oatbox\service\ServiceFactoryInterface;
27use oat\oatbox\service\ServiceManager;
28use oat\oatbox\event\EventManager;
29use oat\oatbox\service\ConfigurableService;
30use oat\generis\model\data\import\RdfImporter;
31use oat\oatbox\cache\SimpleCache;
32use oat\oatbox\extension\exception\ManifestNotFoundException;
33
34/**
35 * Generis installer of extensions
36 * Can be extended to add advanced features
37 *
38 * @access public
39 * @author lionel.lecaque@tudor.lu
40 * @package generis
41 * @see @license  GNU General Public (GPL) Version 2 http://www.opensource.org/licenses/gpl-2.0.php
42
43 */
44class common_ext_ExtensionInstaller extends common_ext_ExtensionHandler
45{
46    // --- ASSOCIATIONS ---
47
48
49    // --- ATTRIBUTES ---
50
51    /**
52     * States if local data must be installed or not.
53     *
54     * @access private
55     * @var boolean
56     */
57    private $localData = false;
58
59    // --- OPERATIONS ---
60
61    /**
62     * install an extension
63     *
64     * @access public
65     * @author Jerome Bogaerts, <jerome@taotesting.com>
66     *
67     * @throws common_ext_ForbiddenActionException When the installable extension is generis.
68     * @throws common_ext_AlreadyInstalledException When the extension is already installed.
69     *
70     * @return void
71     */
72    public function install()
73    {
74        $this->log('i', 'Installing extension ' . $this->extension->getId());
75
76        if ($this->extension->getId() == 'generis') {
77            throw new common_ext_ForbiddenActionException(
78                'Tried to install generis using the ExtensionInstaller',
79                $this->extension->getId()
80            );
81        }
82        if (common_ext_ExtensionsManager::singleton()->isInstalled($this->extension->getId())) {
83            throw new common_ext_AlreadyInstalledException(
84                'Problem installing extension ' . $this->extension->getId() . ' : Already installed',
85                $this->extension->getId()
86            );
87        }
88
89        // we purge the whole cache.
90        $this->log('d', 'Purging cache...');
91        $cache = $this->getServiceManager()->get(SimpleCache::SERVICE_ID);
92        $cache->clear();
93
94
95        // check required extensions, throws exception if failed
96        helpers_ExtensionHelper::checkRequiredExtensions($this->getExtension());
97
98        $this->installLoadDefaultConfig();
99        $this->installOntology();
100        $this->installRegisterExt();
101
102        $this->log('d', 'Installing custom script for extension ' . $this->extension->getId());
103        $this->installCustomScript();
104        $this->log('d', 'Done installing custom script for extension ' . $this->extension->getId());
105
106        if ($this->getLocalData() == true) {
107            $this->log('d', 'Installing local data for extension ' . $this->extension->getId());
108            $this->installLocalData();
109            $this->log('d', 'Done installing local data for extension ' . $this->extension->getId());
110        }
111        $this->log('d', 'Extended install for extension ' . $this->extension->getId());
112
113        // Method to be overridden by subclasses
114        // to extend the installation mechanism.
115        $this->extendedInstall();
116        $this->log('d', 'Done extended install for extension ' . $this->extension->getId());
117        $eventManager = ServiceManager::getServiceManager()->get(EventManager::CONFIG_ID);
118        $eventManager->trigger(new common_ext_event_ExtensionInstalled($this->extension));
119    }
120
121    /**
122     * writes the config based on the config.sample
123     *
124     * @access protected
125     * @author Jerome Bogaerts, <jerome@taotesting.com>
126     * @return void
127     */
128    protected function installLoadDefaultConfig()
129    {
130        $defaultsPath = $this->extension->getDir() . 'config/default';
131        if (is_dir($defaultsPath)) {
132            $defaultIterator = new DirectoryIterator($defaultsPath);
133            foreach ($defaultIterator as $fileinfo) {
134                if (!$fileinfo->isDot() && strpos($fileinfo->getFilename(), '.conf.php') > 0) {
135                    $confKey = substr($fileinfo->getFilename(), 0, -strlen('.conf.php'));
136                    if (! $this->extension->hasConfig($confKey)) {
137                        $config = include $fileinfo->getPathname();
138                        if ($config instanceof ServiceFactoryInterface) {
139                            $config = $config($this->getServiceManager());
140                        }
141                        if ($config instanceof ConfigurableService) {
142                            $this->getServiceManager()->register($this->extension->getId() . '/' . $confKey, $config);
143                        } else {
144                            $this->extension->setConfig($confKey, $config);
145                        }
146                        $this->extension->setConfig($confKey, $config);
147                    }
148                }
149            }
150        }
151    }
152
153    /**
154     * inserts the datamodels
155     * specified in the Manifest
156     *
157     * @access protected
158     * @author Jerome Bogaerts, <jerome@taotesting.com>
159     * @return void
160     */
161    protected function installOntology()
162    {
163        helpers_TimeOutHelper::setTimeOutLimit(helpers_TimeOutHelper::MEDIUM);
164        $rdfImporter = $this->getServiceManager()->get(RdfImporter::class);
165        $rdfImporter->importTriples($this->getExtensionModel());
166        helpers_TimeOutHelper::reset();
167    }
168
169    /**
170     * Registers the Extension with the extensionManager
171     *
172     * @access protected
173     * @author Jerome Bogaerts, <jerome@taotesting.com>
174     * @return void
175     */
176    protected function installRegisterExt()
177    {
178
179        $this->log('d', 'Registering extension ' . $this->extension->getId());
180        common_ext_ExtensionsManager::singleton()->registerExtension($this->extension);
181        common_ext_ExtensionsManager::singleton()->setEnabled($this->extension->getId());
182    }
183
184    /**
185     * Install Custom Scripts
186     *
187     * Executes custom install scripts specified in the Manifest
188     *
189     * @throws common_ext_InstallationException
190     * @throws ManifestNotFoundException
191     */
192    protected function installCustomScript()
193    {
194        //install script
195        foreach ($this->extension->getManifest()->getInstallPHPFiles() as $script) {
196            if (is_string($script)) {
197                $this->runExtensionScript($script);
198            } elseif (
199                is_array($script)
200                && isset($script[0])
201                && is_string($script[0])
202                && !empty($script[0])
203                && isset($script[1])
204                && is_array($script[1])
205            ) {
206                $this->runExtensionScript($script[0], $script[1]);
207            } else {
208                \common_Logger::w(
209                    "Ignored custom install script because it's call definition is malformed in extension manifest!"
210                );
211            }
212        }
213    }
214
215    /**
216     * Installs example files and other non essential content
217     *
218     * @access protected
219     * @author Jerome Bogaerts, <jerome@taotesting.com>
220     * @return void
221     */
222    protected function installLocalData()
223    {
224        $localData = $this->extension->getManifest()->getLocalData();
225        if (isset($localData['php'])) {
226            $scripts = $localData['php'];
227            $scripts = is_array($scripts) ? $scripts : [$scripts];
228            foreach ($scripts as $script) {
229                $this->runExtensionScript($script);
230            }
231        }
232    }
233
234    /**
235     * Instantiate a new ExtensionInstaller for a given Extension.
236     *
237     * @access public
238     * @author Jerome Bogaerts, <jerome@taotesting.com>
239     * @param  common_ext_Extension $extension The extension to install
240     * @param  boolean $localData Import local data or not.
241     * @return void
242     */
243    public function __construct(common_ext_Extension $extension, $localData = true)
244    {
245
246        parent::__construct($extension);
247        $this->setLocalData($localData);
248    }
249
250    /**
251     * Sets localData field.
252     *
253     * @access public
254     * @author Jerome Bogaerts, <jerome@taotesting.com>
255     * @param  boolean $value
256     * @return void
257     */
258    public function setLocalData($value)
259    {
260        $this->localData = $value;
261    }
262
263    /**
264     * Retrieve localData field
265     *
266     * @access public
267     * @author Jerome Bogaerts, <jerome@taotesting.com>
268     * @return boolean
269     */
270    public function getLocalData()
271    {
272        return $this->localData;
273    }
274
275    /**
276     * Returns the ontology model of the extension
277     *
278     * @return common_ext_ExtensionModel
279     */
280    public function getExtensionModel()
281    {
282        return new common_ext_ExtensionModel($this->extension);
283    }
284
285    /**
286     * Short description of method extendedInstall
287     *
288     * @access public
289     * @author Jerome Bogaerts, <jerome@taotesting.com>
290     * @return void
291     */
292    public function extendedInstall()
293    {
294        return;
295    }
296}