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
 * PEAR_Command, command pattern class
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     Stig Bakken <ssb@php.net>
16
 * @author     Greg Beaver <cellog@php.net>
17
 * @copyright  1997-2006 The PHP Group
18
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
19
 * @version    CVS: $Id: Command.php,v 1.38 2006/10/31 02:54:40 cellog Exp $
20
 * @link       http://pear.php.net/package/PEAR
21
 * @since      File available since Release 0.1
22
 */
23
 
24
/**
25
 * Needed for error handling
26
 */
27
require_once 'PEAR.php';
28
require_once 'PEAR/Frontend.php';
29
require_once 'PEAR/XMLParser.php';
30
 
31
/**
32
 * List of commands and what classes they are implemented in.
33
 * @var array command => implementing class
34
 */
35
$GLOBALS['_PEAR_Command_commandlist'] = array();
36
 
37
/**
38
 * List of commands and their descriptions
39
 * @var array command => description
40
 */
41
$GLOBALS['_PEAR_Command_commanddesc'] = array();
42
 
43
/**
44
 * List of shortcuts to common commands.
45
 * @var array shortcut => command
46
 */
47
$GLOBALS['_PEAR_Command_shortcuts'] = array();
48
 
49
/**
50
 * Array of command objects
51
 * @var array class => object
52
 */
53
$GLOBALS['_PEAR_Command_objects'] = array();
54
 
55
/**
56
 * PEAR command class, a simple factory class for administrative
57
 * commands.
58
 *
59
 * How to implement command classes:
60
 *
61
 * - The class must be called PEAR_Command_Nnn, installed in the
62
 *   "PEAR/Common" subdir, with a method called getCommands() that
63
 *   returns an array of the commands implemented by the class (see
64
 *   PEAR/Command/Install.php for an example).
65
 *
66
 * - The class must implement a run() function that is called with three
67
 *   params:
68
 *
69
 *    (string) command name
70
 *    (array)  assoc array with options, freely defined by each
71
 *             command, for example:
72
 *             array('force' => true)
73
 *    (array)  list of the other parameters
74
 *
75
 *   The run() function returns a PEAR_CommandResponse object.  Use
76
 *   these methods to get information:
77
 *
78
 *    int getStatus()   Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
79
 *                      *_PARTIAL means that you need to issue at least
80
 *                      one more command to complete the operation
81
 *                      (used for example for validation steps).
82
 *
83
 *    string getMessage()  Returns a message for the user.  Remember,
84
 *                         no HTML or other interface-specific markup.
85
 *
86
 *   If something unexpected happens, run() returns a PEAR error.
87
 *
88
 * - DON'T OUTPUT ANYTHING! Return text for output instead.
89
 *
90
 * - DON'T USE HTML! The text you return will be used from both Gtk,
91
 *   web and command-line interfaces, so for now, keep everything to
92
 *   plain text.
93
 *
94
 * - DON'T USE EXIT OR DIE! Always use pear errors.  From static
95
 *   classes do PEAR::raiseError(), from other classes do
96
 *   $this->raiseError().
97
 * @category   pear
98
 * @package    PEAR
99
 * @author     Stig Bakken <ssb@php.net>
100
 * @author     Greg Beaver <cellog@php.net>
101
 * @copyright  1997-2006 The PHP Group
102
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
103
 * @version    Release: 1.5.1
104
 * @link       http://pear.php.net/package/PEAR
105
 * @since      Class available since Release 0.1
106
 */
107
class PEAR_Command
108
{
109
    // {{{ factory()
110
 
111
    /**
112
     * Get the right object for executing a command.
113
     *
114
     * @param string $command The name of the command
115
     * @param object $config  Instance of PEAR_Config object
116
     *
117
     * @return object the command object or a PEAR error
118
     *
119
     * @access public
120
     * @static
121
     */
122
    function &factory($command, &$config)
123
    {
124
        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
125
            PEAR_Command::registerCommands();
126
        }
127
        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
128
            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
129
        }
130
        if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
131
            $a = PEAR::raiseError("unknown command `$command'");
132
            return $a;
133
        }
134
        $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
135
        if (!class_exists($class)) {
136
            require_once $GLOBALS['_PEAR_Command_objects'][$class];
137
        }
138
        if (!class_exists($class)) {
139
            $a = PEAR::raiseError("unknown command `$command'");
140
            return $a;
141
        }
142
        $ui =& PEAR_Command::getFrontendObject();
143
        $obj = &new $class($ui, $config);
144
        return $obj;
145
    }
146
 
147
    // }}}
148
    // {{{ & getObject()
149
    function &getObject($command)
150
    {
151
        $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
152
        if (!class_exists($class)) {
153
            require_once $GLOBALS['_PEAR_Command_objects'][$class];
154
        }
155
        if (!class_exists($class)) {
156
            return PEAR::raiseError("unknown command `$command'");
157
        }
158
        $ui =& PEAR_Command::getFrontendObject();
159
        $config = &PEAR_Config::singleton();
160
        $obj = &new $class($ui, $config);
161
        return $obj;
162
    }
163
 
164
    // }}}
165
    // {{{ & getFrontendObject()
166
 
167
    /**
168
     * Get instance of frontend object.
169
     *
170
     * @return object|PEAR_Error
171
     * @static
172
     */
173
    function &getFrontendObject()
174
    {
175
        $a = &PEAR_Frontend::singleton();
176
        return $a;
177
    }
178
 
179
    // }}}
180
    // {{{ & setFrontendClass()
181
 
182
    /**
183
     * Load current frontend class.
184
     *
185
     * @param string $uiclass Name of class implementing the frontend
186
     *
187
     * @return object the frontend object, or a PEAR error
188
     * @static
189
     */
190
    function &setFrontendClass($uiclass)
191
    {
192
        $a = &PEAR_Frontend::setFrontendClass($uiclass);
193
        return $a;
194
    }
195
 
196
    // }}}
197
    // {{{ setFrontendType()
198
 
199
    /**
200
     * Set current frontend.
201
     *
202
     * @param string $uitype Name of the frontend type (for example "CLI")
203
     *
204
     * @return object the frontend object, or a PEAR error
205
     * @static
206
     */
207
    function setFrontendType($uitype)
208
    {
209
        $uiclass = 'PEAR_Frontend_' . $uitype;
210
        return PEAR_Command::setFrontendClass($uiclass);
211
    }
212
 
213
    // }}}
214
    // {{{ registerCommands()
215
 
216
    /**
217
     * Scan through the Command directory looking for classes
218
     * and see what commands they implement.
219
     *
220
     * @param bool   (optional) if FALSE (default), the new list of
221
     *               commands should replace the current one.  If TRUE,
222
     *               new entries will be merged with old.
223
     *
224
     * @param string (optional) where (what directory) to look for
225
     *               classes, defaults to the Command subdirectory of
226
     *               the directory from where this file (__FILE__) is
227
     *               included.
228
     *
229
     * @return bool TRUE on success, a PEAR error on failure
230
     *
231
     * @access public
232
     * @static
233
     */
234
    function registerCommands($merge = false, $dir = null)
235
    {
236
        $parser = new PEAR_XMLParser;
237
        if ($dir === null) {
238
            $dir = dirname(__FILE__) . '/Command';
239
        }
240
        if (!is_dir($dir)) {
241
            return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
242
        }
243
        $dp = @opendir($dir);
244
        if (empty($dp)) {
245
            return PEAR::raiseError("registerCommands: opendir($dir) failed");
246
        }
247
        if (!$merge) {
248
            $GLOBALS['_PEAR_Command_commandlist'] = array();
249
        }
250
        while ($entry = readdir($dp)) {
251
            if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
252
                continue;
253
            }
254
            $class = "PEAR_Command_".substr($entry, 0, -4);
255
            $file = "$dir/$entry";
256
            $parser->parse(file_get_contents($file));
257
            $implements = $parser->getData();
258
            // List of commands
259
            if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
260
                $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) .
261
                    '.php';
262
            }
263
            foreach ($implements as $command => $desc) {
264
                if ($command == 'attribs') {
265
                    continue;
266
                }
267
                if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
268
                    return PEAR::raiseError('Command "' . $command . '" already registered in ' .
269
                        'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
270
                }
271
                $GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
272
                $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
273
                if (isset($desc['shortcut'])) {
274
                    $shortcut = $desc['shortcut'];
275
                    if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
276
                        return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
277
                            'registered to command "' . $command . '" in class "' .
278
                            $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
279
                    }
280
                    $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
281
                }
282
                if (isset($desc['options']) && $desc['options']) {
283
                    foreach ($desc['options'] as $oname => $option) {
284
                        if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
285
                            return PEAR::raiseError('Option "' . $oname . '" short option "' .
286
                                $option['shortopt'] . '" must be ' .
287
                                'only 1 character in Command "' . $command . '" in class "' .
288
                                $class . '"');
289
                        }
290
                    }
291
                }
292
            }
293
        }
294
        ksort($GLOBALS['_PEAR_Command_shortcuts']);
295
        ksort($GLOBALS['_PEAR_Command_commandlist']);
296
        @closedir($dp);
297
        return true;
298
    }
299
 
300
    // }}}
301
    // {{{ getCommands()
302
 
303
    /**
304
     * Get the list of currently supported commands, and what
305
     * classes implement them.
306
     *
307
     * @return array command => implementing class
308
     *
309
     * @access public
310
     * @static
311
     */
312
    function getCommands()
313
    {
314
        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
315
            PEAR_Command::registerCommands();
316
        }
317
        return $GLOBALS['_PEAR_Command_commandlist'];
318
    }
319
 
320
    // }}}
321
    // {{{ getShortcuts()
322
 
323
    /**
324
     * Get the list of command shortcuts.
325
     *
326
     * @return array shortcut => command
327
     *
328
     * @access public
329
     * @static
330
     */
331
    function getShortcuts()
332
    {
333
        if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
334
            PEAR_Command::registerCommands();
335
        }
336
        return $GLOBALS['_PEAR_Command_shortcuts'];
337
    }
338
 
339
    // }}}
340
    // {{{ getGetoptArgs()
341
 
342
    /**
343
     * Compiles arguments for getopt.
344
     *
345
     * @param string $command     command to get optstring for
346
     * @param string $short_args  (reference) short getopt format
347
     * @param array  $long_args   (reference) long getopt format
348
     *
349
     * @return void
350
     *
351
     * @access public
352
     * @static
353
     */
354
    function getGetoptArgs($command, &$short_args, &$long_args)
355
    {
356
        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
357
            PEAR_Command::registerCommands();
358
        }
359
        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
360
            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
361
        }
362
        if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
363
            return null;
364
        }
365
        $obj = &PEAR_Command::getObject($command);
366
        return $obj->getGetoptArgs($command, $short_args, $long_args);
367
    }
368
 
369
    // }}}
370
    // {{{ getDescription()
371
 
372
    /**
373
     * Get description for a command.
374
     *
375
     * @param  string $command Name of the command
376
     *
377
     * @return string command description
378
     *
379
     * @access public
380
     * @static
381
     */
382
    function getDescription($command)
383
    {
384
        if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
385
            return null;
386
        }
387
        return $GLOBALS['_PEAR_Command_commanddesc'][$command];
388
    }
389
 
390
    // }}}
391
    // {{{ getHelp()
392
 
393
    /**
394
     * Get help for command.
395
     *
396
     * @param string $command Name of the command to return help for
397
     *
398
     * @access public
399
     * @static
400
     */
401
    function getHelp($command)
402
    {
403
        $cmds = PEAR_Command::getCommands();
404
        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
405
            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
406
        }
407
        if (isset($cmds[$command])) {
408
            $obj = &PEAR_Command::getObject($command);
409
            return $obj->getHelp($command);
410
        }
411
        return false;
412
    }
413
    // }}}
414
}
415
 
416
?>