fix version in user interface
[bdrem.git] / src / bdrem / UserInterface.php
1 <?php
2 /**
3  * Part of bdrem
4  *
5  * PHP version 5
6  *
7  * @category  Tools
8  * @package   Bdrem
9  * @author    Christian Weiske <cweiske@cweiske.de>
10  * @copyright 2014 Christian Weiske
11  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12  * @link      http://cweiske.de/bdrem.htm
13  */
14 namespace bdrem;
15
16 /**
17  * Generic user interface class
18  *
19  * @category  Tools
20  * @package   Bdrem
21  * @author    Christian Weiske <cweiske@cweiske.de>
22  * @copyright 2014 Christian Weiske
23  * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
24  * @version   Release: @package_version@
25  * @link      http://cweiske.de/bdrem.htm
26  */
27 abstract class UserInterface
28 {
29     /**
30      * Configuration
31      * @var Config
32      */
33     protected $config;
34
35     /**
36      * Start the user interface, load config, parse and render events.
37      *
38      * @return void
39      */
40     public function run()
41     {
42         try {
43             $this->config = new Config();
44             $parser = $this->loadParameters();
45             $res = $this->parseParameters($parser);
46
47             $this->config->load();
48             if (!$this->config->cfgFileExists) {
49                 throw new \Exception(
50                     "No config file found. Looked at the following places:\n"
51                     . '- ' . implode("\n- ", $this->config->cfgFiles)
52                 );
53             }
54
55             setlocale(LC_TIME, $this->config->locale);
56             $this->handleCommands($res);
57
58             $source = $this->config->loadSource();
59             $arEvents = $source->getEvents(
60                 $this->config->date,
61                 $this->config->daysPrev, $this->config->daysNext
62             );
63             usort($arEvents, '\\bdrem\\Event::compare');
64             $this->render($arEvents);
65         } catch (\Exception $e) {
66             $this->preRenderParameterError();
67             echo 'Error: ' . $e->getMessage() . "\n";
68             exit(1);
69         }
70     }
71
72     /**
73      * Load parameters for the CLI option parser.
74      *
75      * @return \Console_CommandLine CLI option parser
76      */
77     protected function loadParameters()
78     {
79         $parser = new \Console_CommandLine();
80         $parser->description = 'Birthday reminder';
81         $parser->version = '0.6.0';
82
83         $parser->addOption(
84             'daysNext',
85             array(
86                 'short_name'  => '-n',
87                 'long_name'   => '--next',
88                 'description' => 'Show NUM days after date',
89                 'help_name'   => 'NUM',
90                 'action'      => 'StoreInt',
91                 'default'     => null,
92             )
93         );
94         $parser->addOption(
95             'daysPrev',
96             array(
97                 'short_name'  => '-p',
98                 'long_name'   => '--prev',
99                 'description' => 'Show NUM days before date',
100                 'help_name'   => 'NUM',
101                 'action'      => 'StoreInt',
102                 'default'     => null,
103             )
104         );
105         $parser->addOption(
106             'renderer',
107             array(
108                 'short_name'  => '-r',
109                 'long_name'   => '--renderer',
110                 'description' => 'Output mode',
111                 'action'      => 'StoreString',
112                 'choices'     => array(
113                     'console',
114                     'html',
115                     'htmltable',
116                     'ical',
117                     'mail',
118                 ),
119                 'default'     => 'console',
120                 'add_list_option' => true,
121             )
122         );
123         $parser->addOption(
124             'stopOnEmpty',
125             array(
126                 'short_name'  => '-e',
127                 'long_name'   => '--stoponempty',
128                 'description' => 'Output nothing when list is empty',
129                 'action'      => 'StoreTrue',
130                 'default'     => false
131             )
132         );
133         $parser->addOption(
134             'date',
135             array(
136                 'short_name'  => '-d',
137                 'long_name'   => '--date',
138                 'description' => 'Date to show events for',
139                 'action'      => 'StoreString'
140             )
141         );
142         $parser->addOption(
143             'configfile',
144             array(
145                 'short_name'  => '-c',
146                 'long_name'   => '--config',
147                 'help_name'   => 'FILE',
148                 'description' => 'Path to configuration file',
149                 'action'      => 'StoreString'
150             )
151         );
152
153         return $parser;
154     }
155
156     /**
157      * Let the CLI option parser parse the options.
158      *
159      * @param object $parser Option parser
160      *
161      * @return object Parsed command line parameters
162      */
163     protected function parseParameters(\Console_CommandLine $parser)
164     {
165         try {
166             $result = $parser->parse();
167
168             if ($result->options['configfile'] !== null) {
169                 $this->config->cfgFiles = array($result->options['configfile']);
170             }
171
172             $this->config->daysNext    = $result->options['daysNext'];
173             $this->config->daysPrev    = $result->options['daysPrev'];
174             $this->config->renderer    = $result->options['renderer'];
175             $this->config->stopOnEmpty = $result->options['stopOnEmpty'];
176             $this->config->setDate($result->options['date']);
177             if (isset($result->options['ansi'])) {
178                 $this->config->ansi = $result->options['ansi'];
179             }
180             return $result;
181         } catch (\Exception $exc) {
182             $this->preRenderParameterError();
183             $parser->displayError($exc->getMessage());
184         }
185     }
186
187     /**
188      * Output the events
189      *
190      * @param array $arEvents Event objects to render
191      *
192      * @return void
193      */
194     protected function render($arEvents)
195     {
196         $r = $this->getRenderer();
197         $r->config = $this->config;
198
199         if ($this->config->stopOnEmpty && count($arEvents) == 0) {
200             $r->handleStopOnEmpty();
201             return;
202         }
203         $r->renderAndOutput($arEvents);
204     }
205
206     /**
207      * Load the configured renderer
208      *
209      * @return Renderer Renderer instance
210      */
211     protected function getRenderer()
212     {
213         $renderer = ucfirst($this->config->renderer);
214         if ($renderer == 'Htmltable') {
215             $renderer = 'HtmlTable';
216         }
217         $class = '\\bdrem\\Renderer_' . $renderer;
218         return new $class();
219     }
220
221     /**
222      * Handle any commands given on the CLI
223      *
224      * @param object $res Command line parameters and options
225      *
226      * @return void
227      */
228     protected function handleCommands($res)
229     {
230     }
231
232     /**
233      * Do something before a parameter parsing error is shown
234      *
235      * @return void
236      */
237     protected function preRenderParameterError()
238     {
239     }
240 }
241 ?>