Subversion Repositories Applications.gtt

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
94 jpm 1
<?php
2
/**
3
 * <tasks:postinstallscript>
4
 *
5
 * PHP versions 4 and 5
6
 *
7
 * LICENSE: This source file is subject to version 3.0 of the PHP license
8
 * that is available through the world-wide-web at the following URI:
9
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
10
 * the PHP License and are unable to obtain it through the web, please
11
 * send a note to license@php.net so we can mail you a copy immediately.
12
 *
13
 * @category   pear
14
 * @package    PEAR
15
 * @author     Greg Beaver <cellog@php.net>
16
 * @copyright  1997-2006 The PHP Group
17
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
18
 * @version    CVS: $Id: Postinstallscript.php,v 1.18 2006/02/08 01:21:47 cellog Exp $
19
 * @link       http://pear.php.net/package/PEAR
20
 * @since      File available since Release 1.4.0a1
21
 */
22
/**
23
 * Base class
24
 */
25
require_once 'PEAR/Task/Common.php';
26
/**
27
 * Implements the postinstallscript file task.
28
 *
29
 * Note that post-install scripts are handled separately from installation, by the
30
 * "pear run-scripts" command
31
 * @category   pear
32
 * @package    PEAR
33
 * @author     Greg Beaver <cellog@php.net>
34
 * @copyright  1997-2006 The PHP Group
35
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
36
 * @version    Release: 1.5.1
37
 * @link       http://pear.php.net/package/PEAR
38
 * @since      Class available since Release 1.4.0a1
39
 */
40
class PEAR_Task_Postinstallscript extends PEAR_Task_Common
41
{
42
    var $type = 'script';
43
    var $_class;
44
    var $_params;
45
    var $_obj;
46
    /**
47
     *
48
     * @var PEAR_PackageFile_v2
49
     */
50
    var $_pkg;
51
    var $_contents;
52
    var $phase = PEAR_TASK_INSTALL;
53
 
54
    /**
55
     * Validate the raw xml at parsing-time.
56
     *
57
     * This also attempts to validate the script to make sure it meets the criteria
58
     * for a post-install script
59
     * @param PEAR_PackageFile_v2
60
     * @param array The XML contents of the <postinstallscript> tag
61
     * @param PEAR_Config
62
     * @param array the entire parsed <file> tag
63
     * @static
64
     */
65
    function validateXml($pkg, $xml, &$config, $fileXml)
66
    {
67
        if ($fileXml['role'] != 'php') {
68
            return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
69
            $fileXml['name'] . '" must be role="php"');
70
        }
71
        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
72
        $file = $pkg->getFileContents($fileXml['name']);
73
        if (PEAR::isError($file)) {
74
            PEAR::popErrorHandling();
75
            return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
76
                $fileXml['name'] . '" is not valid: ' .
77
                $file->getMessage());
78
        } elseif ($file === null) {
79
            return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
80
                $fileXml['name'] . '" could not be retrieved for processing!');
81
        } else {
82
            $analysis = $pkg->analyzeSourceCode($file, true);
83
            if (!$analysis) {
84
                PEAR::popErrorHandling();
85
                $warnings = '';
86
                foreach ($pkg->getValidationWarnings() as $warn) {
87
                    $warnings .= $warn['message'] . "\n";
88
                }
89
                return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "' .
90
                    $fileXml['name'] . '" failed: ' . $warnings);
91
            }
92
            if (count($analysis['declared_classes']) != 1) {
93
                PEAR::popErrorHandling();
94
                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
95
                    $fileXml['name'] . '" must declare exactly 1 class');
96
            }
97
            $class = $analysis['declared_classes'][0];
98
            if ($class != str_replace(array('/', '.php'), array('_', ''),
99
                  $fileXml['name']) . '_postinstall') {
100
                PEAR::popErrorHandling();
101
                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
102
                    $fileXml['name'] . '" class "' . $class . '" must be named "' .
103
                    str_replace(array('/', '.php'), array('_', ''),
104
                    $fileXml['name']) . '_postinstall"');
105
            }
106
            if (!isset($analysis['declared_methods'][$class])) {
107
                PEAR::popErrorHandling();
108
                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
109
                    $fileXml['name'] . '" must declare methods init() and run()');
110
            }
111
            $methods = array('init' => 0, 'run' => 1);
112
            foreach ($analysis['declared_methods'][$class] as $method) {
113
                if (isset($methods[$method])) {
114
                    unset($methods[$method]);
115
                }
116
            }
117
            if (count($methods)) {
118
                PEAR::popErrorHandling();
119
                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
120
                    $fileXml['name'] . '" must declare methods init() and run()');
121
            }
122
        }
123
        PEAR::popErrorHandling();
124
        $definedparams = array();
125
        $tasksNamespace = $pkg->getTasksNs() . ':';
126
        if (!isset($xml[$tasksNamespace . 'paramgroup']) && isset($xml['paramgroup'])) {
127
            // in order to support the older betas, which did not expect internal tags
128
            // to also use the namespace
129
            $tasksNamespace = '';
130
        }
131
        if (isset($xml[$tasksNamespace . 'paramgroup'])) {
132
            $params = $xml[$tasksNamespace . 'paramgroup'];
133
            if (!is_array($params) || !isset($params[0])) {
134
                $params = array($params);
135
            }
136
            foreach ($params as $param) {
137
                if (!isset($param[$tasksNamespace . 'id'])) {
138
                    return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
139
                        $fileXml['name'] . '" <paramgroup> must have ' .
140
                        'an ' . $tasksNamespace . 'id> tag');
141
                }
142
                if (isset($param[$tasksNamespace . 'name'])) {
143
                    if (!in_array($param[$tasksNamespace . 'name'], $definedparams)) {
144
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
145
                            $fileXml['name'] . '" ' . $tasksNamespace .
146
                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
147
                            '" parameter "' . $param[$tasksNamespace . 'name'] .
148
                            '" has not been previously defined');
149
                    }
150
                    if (!isset($param[$tasksNamespace . 'conditiontype'])) {
151
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
152
                            $fileXml['name'] . '" ' . $tasksNamespace .
153
                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
154
                            '" must have a ' . $tasksNamespace .
155
                            'conditiontype> tag containing either "=", ' .
156
                            '"!=", or "preg_match"');
157
                    }
158
                    if (!in_array($param[$tasksNamespace . 'conditiontype'],
159
                          array('=', '!=', 'preg_match'))) {
160
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
161
                            $fileXml['name'] . '" ' . $tasksNamespace .
162
                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
163
                            '" must have a ' . $tasksNamespace .
164
                            'conditiontype> tag containing either "=", ' .
165
                            '"!=", or "preg_match"');
166
                    }
167
                    if (!isset($param[$tasksNamespace . 'value'])) {
168
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
169
                            $fileXml['name'] . '" ' . $tasksNamespace .
170
                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
171
                            '" must have a ' . $tasksNamespace .
172
                            'value> tag containing expected parameter value');
173
                    }
174
                }
175
                if (isset($param[$tasksNamespace . 'instructions'])) {
176
                    if (!is_string($param[$tasksNamespace . 'instructions'])) {
177
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
178
                            $fileXml['name'] . '" ' . $tasksNamespace .
179
                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
180
                            '" ' . $tasksNamespace . 'instructions> must be simple text');
181
                    }
182
                }
183
                if (!isset($param[$tasksNamespace . 'param'])) {
184
                    continue; // <param> is no longer required
185
                }
186
                $subparams = $param[$tasksNamespace . 'param'];
187
                if (!is_array($subparams) || !isset($subparams[0])) {
188
                    $subparams = array($subparams);
189
                }
190
                foreach ($subparams as $subparam) {
191
                    if (!isset($subparam[$tasksNamespace . 'name'])) {
192
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
193
                            $fileXml['name'] . '" parameter for ' .
194
                            $tasksNamespace . 'paramgroup> id "' .
195
                            $param[$tasksNamespace . 'id'] . '" must have ' .
196
                            'a ' . $tasksNamespace . 'name> tag');
197
                    }
198
                    if (!preg_match('/[a-zA-Z0-9]+/',
199
                          $subparam[$tasksNamespace . 'name'])) {
200
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
201
                            $fileXml['name'] . '" parameter "' .
202
                            $subparam[$tasksNamespace . 'name'] .
203
                            '" for ' . $tasksNamespace . 'paramgroup> id "' .
204
                            $param[$tasksNamespace . 'id'] .
205
                            '" is not a valid name.  Must contain only alphanumeric characters');
206
                    }
207
                    if (!isset($subparam[$tasksNamespace . 'prompt'])) {
208
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
209
                            $fileXml['name'] . '" parameter "' .
210
                            $subparam[$tasksNamespace . 'name'] .
211
                            '" for ' . $tasksNamespace . 'paramgroup> id "' .
212
                            $param[$tasksNamespace . 'id'] .
213
                            '" must have a ' . $tasksNamespace . 'prompt> tag');
214
                    }
215
                    if (!isset($subparam[$tasksNamespace . 'type'])) {
216
                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
217
                            $fileXml['name'] . '" parameter "' .
218
                            $subparam[$tasksNamespace . 'name'] .
219
                            '" for ' . $tasksNamespace . 'paramgroup> id "' .
220
                            $param[$tasksNamespace . 'id'] .
221
                            '" must have a ' . $tasksNamespace . 'type> tag');
222
                    }
223
                    $definedparams[] = $param[$tasksNamespace . 'id'] . '::' .
224
                    $subparam[$tasksNamespace . 'name'];
225
                }
226
            }
227
        }
228
        return true;
229
    }
230
 
231
    /**
232
     * Initialize a task instance with the parameters
233
     * @param array raw, parsed xml
234
     * @param array attributes from the <file> tag containing this task
235
     * @param string|null last installed version of this package, if any (useful for upgrades)
236
     */
237
    function init($xml, $fileattribs, $lastversion)
238
    {
239
        $this->_class = str_replace('/', '_', $fileattribs['name']);
240
        $this->_filename = $fileattribs['name'];
241
        $this->_class = str_replace ('.php', '', $this->_class) . '_postinstall';
242
        $this->_params = $xml;
243
        $this->_lastversion = $lastversion;
244
    }
245
 
246
    /**
247
     * Strip the tasks: namespace from internal params
248
     *
249
     * @access private
250
     */
251
    function _stripNamespace($params = null)
252
    {
253
        if ($params === null) {
254
            $params = array();
255
            if (!is_array($this->_params)) {
256
                return;
257
            }
258
            foreach ($this->_params as $i => $param) {
259
                if (is_array($param)) {
260
                    $param = $this->_stripNamespace($param);
261
                }
262
                $params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
263
            }
264
            $this->_params = $params;
265
        } else {
266
            $newparams = array();
267
            foreach ($params as $i => $param) {
268
                if (is_array($param)) {
269
                    $param = $this->_stripNamespace($param);
270
                }
271
                $newparams[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
272
            }
273
            return $newparams;
274
        }
275
    }
276
 
277
    /**
278
     * Unlike other tasks, the installed file name is passed in instead of the file contents,
279
     * because this task is handled post-installation
280
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
281
     * @param string file name
282
     * @return bool|PEAR_Error false to skip this file, PEAR_Error to fail
283
     *         (use $this->throwError)
284
     */
285
    function startSession($pkg, $contents)
286
    {
287
        if ($this->installphase != PEAR_TASK_INSTALL) {
288
            return false;
289
        }
290
        // remove the tasks: namespace if present
291
        $this->_pkg = $pkg;
292
        $this->_stripNamespace();
293
        $this->logger->log(0, 'Including external post-installation script "' .
294
            $contents . '" - any errors are in this script');
295
        include_once $contents;
296
        if (class_exists($this->_class)) {
297
            $this->logger->log(0, 'Inclusion succeeded');
298
        } else {
299
            return $this->throwError('init of post-install script class "' . $this->_class
300
                . '" failed');
301
        }
302
        $this->_obj = new $this->_class;
303
        $this->logger->log(1, 'running post-install script "' . $this->_class . '->init()"');
304
        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
305
        $res = $this->_obj->init($this->config, $pkg, $this->_lastversion);
306
        PEAR::popErrorHandling();
307
        if ($res) {
308
            $this->logger->log(0, 'init succeeded');
309
        } else {
310
            return $this->throwError('init of post-install script "' . $this->_class .
311
                '->init()" failed');
312
        }
313
        $this->_contents = $contents;
314
        return true;
315
    }
316
 
317
    /**
318
     * No longer used
319
     * @see PEAR_PackageFile_v2::runPostinstallScripts()
320
     * @param array an array of tasks
321
     * @param string install or upgrade
322
     * @access protected
323
     * @static
324
     */
325
    function run()
326
    {
327
    }
328
}
329
?>