Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
 * This file is part of the symfony package.
5
 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * Class to manage command line arguments and options.
13
 *
14
 * @package    symfony
15
 * @subpackage command
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfCommandManager.class.php 21908 2009-09-11 12:06:21Z fabien $
18
 */
19
class sfCommandManager
20
{
21
  protected
22
    $arguments            = '',
23
    $errors               = array(),
24
    $optionSet            = null,
25
    $argumentSet          = array(),
26
    $optionValues         = array(),
27
    $argumentValues       = array(),
28
    $parsedArgumentValues = array();
29
 
30
  /**
31
   * Constructor.
32
   *
33
   * @param sfCommandArgumentSet $argumentSet A sfCommandArgumentSet object
34
   * @param sfCommandOptionSet   $optionSet   A setOptionSet object
35
   */
36
  public function __construct(sfCommandArgumentSet $argumentSet = null, sfCommandOptionSet $optionSet = null)
37
  {
38
    if (null === $argumentSet)
39
    {
40
      $argumentSet = new sfCommandArgumentSet();
41
    }
42
    $this->setArgumentSet($argumentSet);
43
 
44
    if (null === $optionSet)
45
    {
46
      $optionSet = new sfCommandOptionSet();
47
    }
48
    $this->setOptionSet($optionSet);
49
  }
50
 
51
  /**
52
   * Sets the argument set.
53
   *
54
   * @param sfCommandArgumentSet $argumentSet A sfCommandArgumentSet object
55
   */
56
  public function setArgumentSet(sfCommandArgumentSet $argumentSet)
57
  {
58
    $this->argumentSet = $argumentSet;
59
  }
60
 
61
  /**
62
   * Gets the argument set.
63
   *
64
   * @return sfCommandArgumentSet A sfCommandArgumentSet object
65
   */
66
  public function getArgumentSet()
67
  {
68
    return $this->argumentSet;
69
  }
70
 
71
  /**
72
   * Sets the option set.
73
   *
74
   * @param sfCommandOptionSet $optionSet A sfCommandOptionSet object
75
   */
76
  public function setOptionSet(sfCommandOptionSet $optionSet)
77
  {
78
    $this->optionSet = $optionSet;
79
  }
80
 
81
  /**
82
   * Gets the option set.
83
   *
84
   * @return sfCommandOptionSet A sfCommandOptionSet object
85
   */
86
  public function getOptionSet()
87
  {
88
    return $this->optionSet;
89
  }
90
 
91
  /**
92
   * Processes command line arguments.
93
   *
94
   * @param mixed $arguments A string or an array of command line parameters
95
   */
96
  public function process($arguments = null)
97
  {
98
    if (null === $arguments)
99
    {
100
      $arguments = $_SERVER['argv'];
101
 
102
      // we strip command line program
103
      if (isset($arguments[0]) && '-' != $arguments[0][0])
104
      {
105
        array_shift($arguments);
106
      }
107
    }
108
    else if (!is_array($arguments))
109
    {
110
      // hack to split arguments with spaces : --test="with some spaces"
111
      $arguments = preg_replace('/(\'|")(.+?)\\1/e', "str_replace(' ', '=PLACEHOLDER=', '\\2')", $arguments);
112
      $arguments = preg_split('/\s+/', $arguments);
113
      $arguments = str_replace('=PLACEHOLDER=', ' ', $arguments);
114
    }
115
 
116
    $this->arguments            = $arguments;
117
    $this->optionValues         = $this->optionSet->getDefaults();
118
    $this->argumentValues       = $this->argumentSet->getDefaults();
119
    $this->parsedArgumentValues = array();
120
    $this->errors               = array();
121
 
122
    while (!in_array($argument = array_shift($this->arguments), array('', null)))
123
    {
124
      if ('--' == $argument)
125
      {
126
        // stop options parsing
127
        $this->parsedArgumentValues = array_merge($this->parsedArgumentValues, $this->arguments);
128
        break;
129
      }
130
 
131
      if ('--' == substr($argument, 0, 2))
132
      {
133
        $this->parseLongOption(substr($argument, 2));
134
      }
135
      else if ('-' == $argument[0])
136
      {
137
        $this->parseShortOption(substr($argument, 1));
138
      }
139
      else
140
      {
141
        $this->parsedArgumentValues[] = $argument;
142
      }
143
    }
144
 
145
    $position = 0;
146
    foreach ($this->argumentSet->getArguments() as $argument)
147
    {
148
      if (array_key_exists($position, $this->parsedArgumentValues))
149
      {
150
        if ($argument->isArray())
151
        {
152
          $this->argumentValues[$argument->getName()] = array_slice($this->parsedArgumentValues, $position);
153
          break;
154
        }
155
        else
156
        {
157
          $this->argumentValues[$argument->getName()] = $this->parsedArgumentValues[$position];
158
        }
159
      }
160
      ++$position;
161
    }
162
 
163
    $this->arguments = $arguments;
164
 
165
    if (count($this->parsedArgumentValues) < $this->argumentSet->getArgumentRequiredCount())
166
    {
167
      $this->errors[] = 'Not enough arguments.';
168
    }
169
    else if (count($this->parsedArgumentValues) > $this->argumentSet->getArgumentCount())
170
    {
171
      $this->errors[] = sprintf('Too many arguments ("%s" given).', implode(' ', $this->parsedArgumentValues));
172
    }
173
  }
174
 
175
  /**
176
   * Returns true if the current command line options validate the argument and option sets.
177
   *
178
   * @return true if there are some validation errors, false otherwise
179
   */
180
  public function isValid()
181
  {
182
    return count($this->errors) ? false : true;
183
  }
184
 
185
  /**
186
   * Gets the current errors.
187
   *
188
   * @return array An array of errors
189
   */
190
  public function getErrors()
191
  {
192
    return $this->errors;
193
  }
194
 
195
  /**
196
   * Returns the argument values.
197
   *
198
   * @return array An array of argument values
199
   */
200
  public function getArgumentValues()
201
  {
202
    return $this->argumentValues;
203
  }
204
 
205
  /**
206
   * Returns the argument value for a given argument name.
207
   *
208
   * @param string $name The argument name
209
   *
210
   * @return mixed The argument value
211
   */
212
  public function getArgumentValue($name)
213
  {
214
    if (!$this->argumentSet->hasArgument($name))
215
    {
216
      throw new sfCommandException(sprintf('The "%s" argument does not exist.', $name));
217
    }
218
 
219
    return $this->argumentValues[$name];
220
  }
221
 
222
  /**
223
   * Returns the options values.
224
   *
225
   * @return array An array of option values
226
   */
227
  public function getOptionValues()
228
  {
229
    return $this->optionValues;
230
  }
231
 
232
  /**
233
   * Returns the option value for a given option name.
234
   *
235
   * @param string $name The option name
236
   *
237
   * @return mixed The option value
238
   */
239
  public function getOptionValue($name)
240
  {
241
    if (!$this->optionSet->hasOption($name))
242
    {
243
      throw new sfCommandException(sprintf('The "%s" option does not exist.', $name));
244
    }
245
 
246
    return $this->optionValues[$name];
247
  }
248
 
249
  /**
250
   * Parses a short option.
251
   *
252
   * @param string $argument The option argument
253
   */
254
  protected function parseShortOption($argument)
255
  {
256
    // short option can be aggregated like in -vd (== -v -d)
257
    for ($i = 0, $count = strlen($argument); $i < $count; $i++)
258
    {
259
      $shortcut = $argument[$i];
260
      $value    = true;
261
 
262
      if (!$this->optionSet->hasShortcut($shortcut))
263
      {
264
        $this->errors[] = sprintf('The option "-%s" does not exist.', $shortcut);
265
        continue;
266
      }
267
 
268
      $option = $this->optionSet->getOptionForShortcut($shortcut);
269
 
270
      // required argument?
271
      if ($option->isParameterRequired())
272
      {
273
        if ($i + 1 < strlen($argument))
274
        {
275
          $value = substr($argument, $i + 1);
276
          $this->setOption($option, $value);
277
          break;
278
        }
279
        else
280
        {
281
          // take next element as argument (if it doesn't start with a -)
282
          if (count($this->arguments) && $this->arguments[0][0] != '-')
283
          {
284
            $value = array_shift($this->arguments);
285
            $this->setOption($option, $value);
286
            break;
287
          }
288
          else
289
          {
290
            $this->errors[] = sprintf('Option "-%s" requires an argument', $shortcut);
291
            $value = null;
292
          }
293
        }
294
      }
295
      else if ($option->isParameterOptional())
296
      {
297
        if (substr($argument, $i + 1) != '')
298
        {
299
          $value = substr($argument, $i + 1);
300
        }
301
        else
302
        {
303
          // take next element as argument (if it doesn't start with a -)
304
          if (count($this->arguments) && $this->arguments[0][0] != '-')
305
          {
306
            $value = array_shift($this->arguments);
307
          }
308
          else
309
          {
310
            $value = $option->getDefault();
311
          }
312
        }
313
 
314
        $this->setOption($option, $value);
315
        break;
316
      }
317
 
318
      $this->setOption($option, $value);
319
    }
320
  }
321
 
322
  /**
323
   * Parses a long option.
324
   *
325
   * @param string $argument The option argument
326
   */
327
  protected function parseLongOption($argument)
328
  {
329
    if (false !== strpos($argument, '='))
330
    {
331
      list($name, $value) = explode('=', $argument, 2);
332
 
333
      if (!$this->optionSet->hasOption($name))
334
      {
335
        $this->errors[] = sprintf('The "--%s" option does not exist.', $name);
336
        return;
337
      }
338
 
339
      $option = $this->optionSet->getOption($name);
340
 
341
      if (!$option->acceptParameter())
342
      {
343
        $this->errors[] = sprintf('Option "--%s" does not take an argument.', $name);
344
        $value = true;
345
      }
346
    }
347
    else
348
    {
349
      $name = $argument;
350
 
351
      if (!$this->optionSet->hasOption($name))
352
      {
353
        $this->errors[] = sprintf('The "--%s" option does not exist.', $name);
354
        return;
355
      }
356
 
357
      $option = $this->optionSet->getOption($name);
358
 
359
      if ($option->isParameterRequired())
360
      {
361
        $this->errors[] = sprintf('Option "--%s" requires an argument.', $name);
362
      }
363
 
364
      $value = $option->acceptParameter() ? $option->getDefault() : true;
365
    }
366
 
367
    $this->setOption($option, $value);
368
  }
369
 
370
  public function setOption(sfCommandOption $option, $value)
371
  {
372
    if ($option->isArray())
373
    {
374
      $this->optionValues[$option->getName()][] = $value;
375
    }
376
    else
377
    {
378
      $this->optionValues[$option->getName()] = $value;
379
    }
380
  }
381
}