Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * PEAR_Command, command pattern class
4
 *
5
 * PHP versions 4 and 5
6
 *
7
 * @category   pear
8
 * @package    PEAR
9
 * @author     Stig Bakken <ssb@php.net>
10
 * @author     Greg Beaver <cellog@php.net>
11
 * @copyright  1997-2009 The Authors
12
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
13
 * @version    CVS: $Id: Command.php 313023 2011-07-06 19:17:11Z dufuz $
14
 * @link       http://pear.php.net/package/PEAR
15
 * @since      File available since Release 0.1
16
 */
17
 
18
/**
19
 * Needed for error handling
20
 */
21
require_once 'PEAR.php';
22
require_once 'PEAR/Frontend.php';
23
require_once 'PEAR/XMLParser.php';
24
 
25
/**
26
 * List of commands and what classes they are implemented in.
27
 * @var array command => implementing class
28
 */
29
$GLOBALS['_PEAR_Command_commandlist'] = array();
30
 
31
/**
32
 * List of commands and their descriptions
33
 * @var array command => description
34
 */
35
$GLOBALS['_PEAR_Command_commanddesc'] = array();
36
 
37
/**
38
 * List of shortcuts to common commands.
39
 * @var array shortcut => command
40
 */
41
$GLOBALS['_PEAR_Command_shortcuts'] = array();
42
 
43
/**
44
 * Array of command objects
45
 * @var array class => object
46
 */
47
$GLOBALS['_PEAR_Command_objects'] = array();
48
 
49
/**
50
 * PEAR command class, a simple factory class for administrative
51
 * commands.
52
 *
53
 * How to implement command classes:
54
 *
55
 * - The class must be called PEAR_Command_Nnn, installed in the
56
 *   "PEAR/Common" subdir, with a method called getCommands() that
57
 *   returns an array of the commands implemented by the class (see
58
 *   PEAR/Command/Install.php for an example).
59
 *
60
 * - The class must implement a run() function that is called with three
61
 *   params:
62
 *
63
 *    (string) command name
64
 *    (array)  assoc array with options, freely defined by each
65
 *             command, for example:
66
 *             array('force' => true)
67
 *    (array)  list of the other parameters
68
 *
69
 *   The run() function returns a PEAR_CommandResponse object.  Use
70
 *   these methods to get information:
71
 *
72
 *    int getStatus()   Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
73
 *                      *_PARTIAL means that you need to issue at least
74
 *                      one more command to complete the operation
75
 *                      (used for example for validation steps).
76
 *
77
 *    string getMessage()  Returns a message for the user.  Remember,
78
 *                         no HTML or other interface-specific markup.
79
 *
80
 *   If something unexpected happens, run() returns a PEAR error.
81
 *
82
 * - DON'T OUTPUT ANYTHING! Return text for output instead.
83
 *
84
 * - DON'T USE HTML! The text you return will be used from both Gtk,
85
 *   web and command-line interfaces, so for now, keep everything to
86
 *   plain text.
87
 *
88
 * - DON'T USE EXIT OR DIE! Always use pear errors.  From static
89
 *   classes do PEAR::raiseError(), from other classes do
90
 *   $this->raiseError().
91
 * @category   pear
92
 * @package    PEAR
93
 * @author     Stig Bakken <ssb@php.net>
94
 * @author     Greg Beaver <cellog@php.net>
95
 * @copyright  1997-2009 The Authors
96
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
97
 * @version    Release: 1.9.4
98
 * @link       http://pear.php.net/package/PEAR
99
 * @since      Class available since Release 0.1
100
 */
101
class PEAR_Command
102
{
103
    // {{{ factory()
104
 
105
    /**
106
     * Get the right object for executing a command.
107
     *
108
     * @param string $command The name of the command
109
     * @param object $config  Instance of PEAR_Config object
110
     *
111
     * @return object the command object or a PEAR error
112
     *
113
     * @access public
114
     * @static
115
     */
116
    function &factory($command, &$config)
117
    {
118
        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
119
            PEAR_Command::registerCommands();
120
        }
121
        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
122
            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
123
        }
124
        if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
125
            $a = PEAR::raiseError("unknown command `$command'");
126
            return $a;
127
        }
128
        $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
129
        if (!class_exists($class)) {
130
            require_once $GLOBALS['_PEAR_Command_objects'][$class];
131
        }
132
        if (!class_exists($class)) {
133
            $a = PEAR::raiseError("unknown command `$command'");
134
            return $a;
135
        }
136
        $ui =& PEAR_Command::getFrontendObject();
137
        $obj = &new $class($ui, $config);
138
        return $obj;
139
    }
140
 
141
    // }}}
142
    // {{{ & getObject()
143
    function &getObject($command)
144
    {
145
        $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
146
        if (!class_exists($class)) {
147
            require_once $GLOBALS['_PEAR_Command_objects'][$class];
148
        }
149
        if (!class_exists($class)) {
150
            return PEAR::raiseError("unknown command `$command'");
151
        }
152
        $ui =& PEAR_Command::getFrontendObject();
153
        $config = &PEAR_Config::singleton();
154
        $obj = &new $class($ui, $config);
155
        return $obj;
156
    }
157
 
158
    // }}}
159
    // {{{ & getFrontendObject()
160
 
161
    /**
162
     * Get instance of frontend object.
163
     *
164
     * @return object|PEAR_Error
165
     * @static
166
     */
167
    function &getFrontendObject()
168
    {
169
        $a = &PEAR_Frontend::singleton();
170
        return $a;
171
    }
172
 
173
    // }}}
174
    // {{{ & setFrontendClass()
175
 
176
    /**
177
     * Load current frontend class.
178
     *
179
     * @param string $uiclass Name of class implementing the frontend
180
     *
181
     * @return object the frontend object, or a PEAR error
182
     * @static
183
     */
184
    function &setFrontendClass($uiclass)
185
    {
186
        $a = &PEAR_Frontend::setFrontendClass($uiclass);
187
        return $a;
188
    }
189
 
190
    // }}}
191
    // {{{ setFrontendType()
192
 
193
    /**
194
     * Set current frontend.
195
     *
196
     * @param string $uitype Name of the frontend type (for example "CLI")
197
     *
198
     * @return object the frontend object, or a PEAR error
199
     * @static
200
     */
201
    function setFrontendType($uitype)
202
    {
203
        $uiclass = 'PEAR_Frontend_' . $uitype;
204
        return PEAR_Command::setFrontendClass($uiclass);
205
    }
206
 
207
    // }}}
208
    // {{{ registerCommands()
209
 
210
    /**
211
     * Scan through the Command directory looking for classes
212
     * and see what commands they implement.
213
     *
214
     * @param bool   (optional) if FALSE (default), the new list of
215
     *               commands should replace the current one.  If TRUE,
216
     *               new entries will be merged with old.
217
     *
218
     * @param string (optional) where (what directory) to look for
219
     *               classes, defaults to the Command subdirectory of
220
     *               the directory from where this file (__FILE__) is
221
     *               included.
222
     *
223
     * @return bool TRUE on success, a PEAR error on failure
224
     *
225
     * @access public
226
     * @static
227
     */
228
    function registerCommands($merge = false, $dir = null)
229
    {
230
        $parser = new PEAR_XMLParser;
231
        if ($dir === null) {
232
            $dir = dirname(__FILE__) . '/Command';
233
        }
234
        if (!is_dir($dir)) {
235
            return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
236
        }
237
        $dp = @opendir($dir);
238
        if (empty($dp)) {
239
            return PEAR::raiseError("registerCommands: opendir($dir) failed");
240
        }
241
        if (!$merge) {
242
            $GLOBALS['_PEAR_Command_commandlist'] = array();
243
        }
244
 
245
        while ($file = readdir($dp)) {
246
            if ($file{0} == '.' || substr($file, -4) != '.xml') {
247
                continue;
248
            }
249
 
250
            $f = substr($file, 0, -4);
251
            $class = "PEAR_Command_" . $f;
252
            // List of commands
253
            if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
254
                $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
255
            }
256
 
257
            $parser->parse(file_get_contents("$dir/$file"));
258
            $implements = $parser->getData();
259
            foreach ($implements as $command => $desc) {
260
                if ($command == 'attribs') {
261
                    continue;
262
                }
263
 
264
                if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
265
                    return PEAR::raiseError('Command "' . $command . '" already registered in ' .
266
                        'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
267
                }
268
 
269
                $GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
270
                $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
271
                if (isset($desc['shortcut'])) {
272
                    $shortcut = $desc['shortcut'];
273
                    if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
274
                        return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
275
                            'registered to command "' . $command . '" in class "' .
276
                            $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
277
                    }
278
                    $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
279
                }
280
 
281
                if (isset($desc['options']) && $desc['options']) {
282
                    foreach ($desc['options'] as $oname => $option) {
283
                        if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
284
                            return PEAR::raiseError('Option "' . $oname . '" short option "' .
285
                                $option['shortopt'] . '" must be ' .
286
                                'only 1 character in Command "' . $command . '" in class "' .
287
                                $class . '"');
288
                        }
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
}