1<?php
2/**
3* PHP_Shell_Options Extension implementation
4*
5* PHP Version 5
6*
7* This extension is a basic extension that provide the funcionality of set
8* options to other extensions or to the whole PHP_Shell.
9*
10* @category  Extension
11* @package   PHP_Shell
12* @author    Jan Kneschke <jan@kneschke.de>
13* @copyright 2006 Jan Kneschke
14* @license   MIT <http://www.opensource.org/licenses/mit-license.php>
15* @version   SVN: $Id$
16* @link      http://pear.php.net/package/PHP_Shell
17*
18*/
19require_once "PHP/Shell/Extensions.php"; /* for the PHP_Shell_Interface */
20
21/**
22* PHP_Shell_Options Class
23*
24* This class is a basic extension that provide the funcionality of set
25* options to other extensions or to the whole PHP_Shell.
26*
27* @category  Extension
28* @package   PHP_Shell
29* @author    Jan Kneschke <jan@kneschke.de>
30* @copyright 2006 Jan Kneschke
31* @license   MIT <http://www.opensource.org/licenses/mit-license.php>
32* @version   Release: @package_version@
33* @link      http://pear.php.net/package/PHP_Shell
34*
35*/
36class PHP_Shell_Options implements PHP_Shell_Extension
37{
38    /**
39     * instance of the current class
40     *
41     * @var PHP_Shell_Options
42     */
43    static protected $instance;
44
45    /**
46     * known options and their setors
47     *
48     * @var array
49     * @see registerOption
50     */
51    protected $options = array();
52
53    /**
54     * known options and their setors
55     *
56     * @var array
57     * @see registerOptionAlias
58     */
59    protected $option_aliases = array();
60
61    /**
62     * Register
63     *
64     * @return void
65     */
66    public function register()
67    {
68        $cmd = PHP_Shell_Commands::getInstance();
69        $cmd->registerCommand(
70            '#^:set #',
71            $this,
72            'cmdSet',
73            ':set <var>',
74            'set a shell variable'
75        );
76    }
77
78    /**
79     * register a option
80     *
81     * @param string $option name of the option
82     * @param object $obj    a object handle
83     * @param string $setor  method-name of the setor in the object
84     * @param string $getor  (unused)
85     *
86     * @return void
87     */
88    public function registerOption($option, $obj, $setor, $getor = null)
89    {
90        if (!is_callable(array($obj, $setor))) {
91            $msg = sprintf(
92                "setor %s doesn't exist on class %s",
93                $setor, get_class($obj)
94            );
95
96            throw new Exception($msg);
97        }
98
99        $this->options[trim($option)] = array("obj" => $obj, "setor" => $setor);
100    }
101
102    /**
103     * set a shell-var
104     *
105     * :set al to enable autoload
106     * :set bg=dark to enable highlighting with a dark backgroud
107     *
108     * @param string $l Unknown
109     *
110     * @return void
111     */
112    public function cmdSet($l)
113    {
114        if (!preg_match('#:set\s+([a-z]+)\s*(?:=\s*([a-z0-9]+)\s*)?$#i', $l, $a)) {
115            print(':set failed: either :set <option> or :set <option> = <value>');
116            return;
117        }
118
119        $this->execute($a[1], isset($a[2]) ? $a[2] : null);
120    }
121
122    /**
123     * get all the option names
124     *
125     * @return array names of all options
126     */
127    public function getOptions()
128    {
129        return array_keys($this->options);
130    }
131
132    /**
133     * map a option to another option
134     *
135     * e.g.: bg maps to background
136     *
137     * @param string $alias  Alias (name)
138     * @param string $option Option
139     *
140     * @return void
141     */
142    public function registerOptionAlias($alias, $option)
143    {
144        if (!isset($this->options[$option])) {
145            throw new Exception(sprintf("Option %s is not known", $option));
146        }
147
148        $this->option_aliases[trim($alias)] = trim($option);
149
150    }
151
152    /**
153     * execute a :set command
154     *
155     * calls the setor for the :set <option>
156     *
157     * @param string $key   Key to set
158     * @param mixed  $value Value to write
159     *
160     * @return void
161     */
162    protected function execute($key, $value)
163    {
164        /* did we hit a alias (bg for backgroud) ? */
165        if (isset($this->option_aliases[$key])) {
166            $opt_key = $this->option_aliases[$key];
167        } else {
168            $opt_key = $key;
169        }
170
171        if (!isset($this->options[$opt_key])) {
172            print (':set '.$key.' failed: unknown key');
173            return;
174        }
175
176        if (!isset($this->options[$opt_key]["setor"])) {
177            return;
178        }
179
180        $setor = $this->options[$opt_key]["setor"];
181        $obj = $this->options[$opt_key]["obj"];
182        $obj->$setor($key, $value);
183    }
184
185    /**
186     * Return an instance of this
187     *
188     * @todo Remove this! Singletons are bad
189     *
190     * @return PHP_Shell_Options
191     */
192    static function getInstance()
193    {
194        if (is_null(self::$instance)) {
195            $class = __CLASS__;
196            self::$instance = new $class();
197        }
198        return self::$instance;
199    }
200}
201
202
203