1: <?php
2: 3: 4: 5: 6: 7: 8:
9:
10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
41: class Horde_Argv_OptionContainer
42: {
43: public $description = '';
44: public $optionList = array();
45: public $optionClass = 'Horde_Argv_Option';
46: public $defaults = array();
47: public $shortOpt = array();
48: public $longOpt = array();
49: public $conflictHandler;
50:
51: 52: 53: 54: 55: 56:
57: public function __construct($optionClass, $conflictHandler, $description)
58: {
59: $this->_createOptionList();
60:
61: $this->optionClass = $optionClass;
62: $this->setConflictHandler($conflictHandler);
63: $this->setDescription($description);
64: }
65:
66: 67: 68: 69: 70:
71: protected function _createOptionMappings()
72: {
73: $this->shortOpt = array();
74: $this->longOpt = array();
75: $this->defaults = array();
76: }
77:
78: 79: 80: 81:
82: protected function _shareOptionMappings($parser)
83: {
84: $this->shortOpt =& $parser->shortOpt;
85: $this->longOpt =& $parser->longOpt;
86: $this->defaults = $parser->defaults;
87: }
88:
89: public function setConflictHandler($handler)
90: {
91: if (!in_array($handler, array('error', 'resolve'))) {
92: throw new InvalidArgumentException('invalid conflictHandler ' . var_export($handler, true));
93: }
94: $this->conflictHandler = $handler;
95: }
96:
97: public function setDescription($description)
98: {
99: $this->description = $description;
100: }
101:
102: public function getDescription()
103: {
104: return $this->description;
105: }
106:
107:
108:
109: protected function _checkConflict($option)
110: {
111: $conflictOpts = array();
112: foreach ($option->shortOpts as $opt) {
113: if (isset($this->shortOpt[$opt])) {
114: $conflictOpts[$opt] = $this->shortOpt[$opt];
115: }
116: }
117: foreach ($option->longOpts as $opt) {
118: if (isset($this->longOpt[$opt])) {
119: $conflictOpts[$opt] = $this->longOpt[$opt];
120: }
121: }
122:
123: if ($conflictOpts) {
124: $handler = $this->conflictHandler;
125: if ($handler == 'error') {
126: throw new Horde_Argv_OptionConflictException(sprintf(
127: 'conflicting option string(s): %s',
128: implode(', ', array_keys($conflictOpts))), $option);
129: } elseif ($handler == 'resolve') {
130: foreach ($conflictOpts as $opt => $c_option) {
131: if (strncmp($opt, '--', 2) === 0) {
132: $key = array_search($opt, $c_option->longOpts);
133: if ($key !== false) {
134: unset($c_option->longOpts[$key]);
135: }
136: unset($this->longOpt[$opt]);
137: } else {
138: $key = array_search($opt, $c_option->shortOpts);
139: if ($key !== false) {
140: unset($c_option->shortOpts[$key]);
141: }
142: unset($this->shortOpt[$opt]);
143: }
144:
145: if (! ($c_option->shortOpts || $c_option->longOpts)) {
146: $key = array_search($c_option, $c_option->container->optionList);
147: unset($c_option->container->optionList[$key]);
148: }
149: }
150: }
151: }
152: }
153:
154: public function addOption()
155: {
156: $opts = func_get_args();
157:
158: if (count($opts) && is_string($opts[0])) {
159: $optionFactory = new ReflectionClass($this->optionClass);
160: $option = $optionFactory->newInstanceArgs($opts);
161: } elseif (count($opts) == 1) {
162: $option = $opts[0];
163: if (!$option instanceof Horde_Argv_Option)
164: throw new InvalidArgumentException('not an Option instance: ' . var_export($option, true));
165: } else {
166: throw new InvalidArgumentException('invalid arguments');
167: }
168:
169: $this->_checkConflict($option);
170:
171: $this->optionList[] = $option;
172: $option->container = $this;
173: foreach ($option->shortOpts as $opt) {
174: $this->shortOpt[$opt] = $option;
175: }
176: foreach ($option->longOpts as $opt) {
177: $this->longOpt[$opt] = $option;
178: }
179:
180: if (!is_null($option->dest)) {
181:
182: if ($option->default !== Horde_Argv_Option::$NO_DEFAULT) {
183: $this->defaults[$option->dest] = $option->default;
184: } elseif (!isset($this->defaults[$option->dest])) {
185: $this->defaults[$option->dest] = null;
186: }
187: }
188:
189: return $option;
190: }
191:
192: public function addOptions($optionList)
193: {
194: foreach ($optionList as $option) {
195: $this->addOption($option);
196: }
197: }
198:
199:
200:
201: public function getOption($opt_str)
202: {
203: if (isset($this->shortOpt[$opt_str])) {
204: return $this->shortOpt[$opt_str];
205: } elseif (isset($this->longOpt[$opt_str])) {
206: return $this->longOpt[$opt_str];
207: } else {
208: return null;
209: }
210: }
211:
212: public function hasOption($opt_str)
213: {
214: return isset($this->shortOpt[$opt_str])
215: || isset($this->longOpt[$opt_str]);
216: }
217:
218: public function removeOption($opt_str)
219: {
220: $option = $this->getOption($opt_str);
221: if (is_null($option)) {
222: throw new InvalidArgumentException("no such option '$opt_str'");
223: }
224:
225: foreach ($option->shortOpts as $opt) {
226: unset($this->shortOpt[$opt]);
227: }
228: foreach ($option->longOpts as $opt) {
229: unset($this->longOpt[$opt]);
230: }
231: $key = array_search($option, $option->container->optionList);
232: unset($option->container->optionList[$key]);
233: }
234:
235:
236:
237:
238: public function formatOptionHelp($formatter = null)
239: {
240: if (!$this->optionList)
241: return '';
242: $result = array();
243: foreach ($this->optionList as $option) {
244: if ($option->help != Horde_Argv_Option::SUPPRESS_HELP)
245: $result[] = $formatter->formatOption($option);
246: }
247: return implode('', $result);
248: }
249:
250: public function formatDescription($formatter = null)
251: {
252: return $formatter->formatDescription($this->getDescription());
253: }
254:
255: public function formatHelp($formatter = null)
256: {
257: $result = array();
258: if ($this->description)
259: $result[] = $this->formatDescription($formatter);
260: if ($this->optionList)
261: $result[] = $this->formatOptionHelp($formatter);
262: return implode("\n", $result);
263: }
264:
265: }
266: