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