source: trunk/library/PEAR/PEAR/Task/Postinstallscript.php @ 5146

Revision 5146, 14.1 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2305 - Enviando alteracoes, desenvolvidas internamente na Prognus. Library: adicionando arquivos.

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