de6d3bbe922d9177318721ad73cb7dfe339fd5ad
[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.1.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                     'mail',
117                 ),
118                 'default'     => 'console',
119                 'add_list_option' => true,
120             )
121         );
122         $parser->addOption(
123             'stopOnEmpty',
124             array(
125                 'short_name'  => '-e',
126                 'long_name'   => '--stoponempty',
127                 'description' => 'Output nothing when list is empty',
128                 'action'      => 'StoreTrue',
129                 'default'     => false
130             )
131         );
132         $parser->addOption(
133             'date',
134             array(
135                 'short_name'  => '-d',
136                 'long_name'   => '--date',
137                 'description' => 'Date to show events for',
138                 'action'      => 'StoreString'
139             )
140         );
141         $parser->addOption(
142             'configfile',
143             array(
144                 'short_name'  => '-c',
145                 'long_name'   => '--config',
146                 'help_name'   => 'FILE',
147                 'description' => 'Path to configuration file',
148                 'action'      => 'StoreString'
149             )
150         );
151
152         return $parser;
153     }
154
155     /**
156      * Let the CLI option parser parse the options.
157      *
158      * @param object $parser Option parser
159      *
160      * @return object Parsed command line parameters
161      */
162     protected function parseParameters(\Console_CommandLine $parser)
163     {
164         try {
165             $result = $parser->parse();
166
167             if ($result->options['configfile'] !== null) {
168                 $this->config->cfgFiles = array($result->options['configfile']);
169             }
170
171             $this->config->daysNext    = $result->options['daysNext'];
172             $this->config->daysPrev    = $result->options['daysPrev'];
173             $this->config->renderer    = $result->options['renderer'];
174             $this->config->stopOnEmpty = $result->options['stopOnEmpty'];
175             $this->config->setDate($result->options['date']);
176             return $result;
177         } catch (\Exception $exc) {
178             $this->preRenderParameterError();
179             $parser->displayError($exc->getMessage());
180         }
181     }
182
183     /**
184      * Output the events
185      *
186      * @param array $arEvents Event objects to render
187      *
188      * @return void
189      */
190     protected function render($arEvents)
191     {
192         $r = $this->getRenderer();
193         $r->config = $this->config;
194
195         if ($this->config->stopOnEmpty && count($arEvents) == 0) {
196             $r->handleStopOnEmpty();
197             return;
198         }
199         $r->renderAndOutput($arEvents);
200     }
201
202     /**
203      * Load the configured renderer
204      *
205      * @return Renderer Renderer instance
206      */
207     protected function getRenderer()
208     {
209         $renderer = ucfirst($this->config->renderer);
210         if ($renderer == 'Htmltable') {
211             $renderer = 'HtmlTable';
212         }
213         $class = '\\bdrem\\Renderer_' . $renderer;
214         return new $class();
215     }
216
217     /**
218      * Handle any commands given on the CLI
219      *
220      * @param object $res Command line parameters and options
221      *
222      * @return void
223      */
224     protected function handleCommands($res)
225     {
226     }
227
228     /**
229      * Do something before a parameter parsing error is shown
230      *
231      * @return void
232      */
233     protected function preRenderParameterError()
234     {
235     }
236 }
237 ?>