fix version in user interface
[bdrem.git] / src / bdrem / UserInterface.php
index cd9f7024650c9707678d135c4de08f491b1fc154..ef18493d99e6c3fa8894a454763419eddc1aec92 100644 (file)
 <?php
+/**
+ * Part of bdrem
+ *
+ * PHP version 5
+ *
+ * @category  Tools
+ * @package   Bdrem
+ * @author    Christian Weiske <cweiske@cweiske.de>
+ * @copyright 2014 Christian Weiske
+ * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
+ * @link      http://cweiske.de/bdrem.htm
+ */
 namespace bdrem;
 
+/**
+ * Generic user interface class
+ *
+ * @category  Tools
+ * @package   Bdrem
+ * @author    Christian Weiske <cweiske@cweiske.de>
+ * @copyright 2014 Christian Weiske
+ * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
+ * @version   Release: @package_version@
+ * @link      http://cweiske.de/bdrem.htm
+ */
 abstract class UserInterface
 {
+    /**
+     * Configuration
+     * @var Config
+     */
     protected $config;
 
+    /**
+     * Start the user interface, load config, parse and render events.
+     *
+     * @return void
+     */
     public function run()
     {
-        $this->config = new Config();
-        $this->config->load();
-        $this->config->date = date('Y-m-d');
-        setlocale(LC_TIME, $this->config->locale);
-        $source = $this->config->loadSource();
-
-        $parser = $this->loadParameters();
-        $this->parseParameters($parser);
-
-        $arEvents = $source->getEvents(
-            $this->config->date,
-            $this->config->daysBefore, $this->config->daysAfter
-        );
-        usort($arEvents, '\\bdrem\\Event::compare');
-        $this->render($arEvents);
+        try {
+            $this->config = new Config();
+            $parser = $this->loadParameters();
+            $res = $this->parseParameters($parser);
+
+            $this->config->load();
+            if (!$this->config->cfgFileExists) {
+                throw new \Exception(
+                    "No config file found. Looked at the following places:\n"
+                    . '- ' . implode("\n- ", $this->config->cfgFiles)
+                );
+            }
+
+            setlocale(LC_TIME, $this->config->locale);
+            $this->handleCommands($res);
+
+            $source = $this->config->loadSource();
+            $arEvents = $source->getEvents(
+                $this->config->date,
+                $this->config->daysPrev, $this->config->daysNext
+            );
+            usort($arEvents, '\\bdrem\\Event::compare');
+            $this->render($arEvents);
+        } catch (\Exception $e) {
+            $this->preRenderParameterError();
+            echo 'Error: ' . $e->getMessage() . "\n";
+            exit(1);
+        }
     }
 
+    /**
+     * Load parameters for the CLI option parser.
+     *
+     * @return \Console_CommandLine CLI option parser
+     */
     protected function loadParameters()
     {
         $parser = new \Console_CommandLine();
         $parser->description = 'Birthday reminder';
-        $parser->version = '0.1.0';
+        $parser->version = '0.6.0';
 
         $parser->addOption(
-            'daysAfter',
+            'daysNext',
             array(
-                'short_name'  => '-a',
-                'long_name'   => '--days-after',
+                'short_name'  => '-n',
+                'long_name'   => '--next',
                 'description' => 'Show NUM days after date',
                 'help_name'   => 'NUM',
                 'action'      => 'StoreInt',
-                'default'     => $this->config->daysAfter,
+                'default'     => null,
             )
         );
         $parser->addOption(
-            'daysBefore',
+            'daysPrev',
             array(
-                'short_name'  => '-b',
-                'long_name'   => '--days-before',
+                'short_name'  => '-p',
+                'long_name'   => '--prev',
                 'description' => 'Show NUM days before date',
                 'help_name'   => 'NUM',
                 'action'      => 'StoreInt',
-                'default'     => $this->config->daysBefore,
+                'default'     => null,
             )
         );
         $parser->addOption(
@@ -63,6 +113,7 @@ abstract class UserInterface
                     'console',
                     'html',
                     'htmltable',
+                    'ical',
                     'mail',
                 ),
                 'default'     => 'console',
@@ -70,39 +121,93 @@ abstract class UserInterface
             )
         );
         $parser->addOption(
-            'quiet',
+            'stopOnEmpty',
+            array(
+                'short_name'  => '-e',
+                'long_name'   => '--stoponempty',
+                'description' => 'Output nothing when list is empty',
+                'action'      => 'StoreTrue',
+                'default'     => false
+            )
+        );
+        $parser->addOption(
+            'date',
             array(
-                'short_name'  => '-q',
-                'long_name'   => '--quiet',
-                'description' => "Don't print status messages to stdout",
-                'action'      => 'StoreTrue'
+                'short_name'  => '-d',
+                'long_name'   => '--date',
+                'description' => 'Date to show events for',
+                'action'      => 'StoreString'
             )
         );
+        $parser->addOption(
+            'configfile',
+            array(
+                'short_name'  => '-c',
+                'long_name'   => '--config',
+                'help_name'   => 'FILE',
+                'description' => 'Path to configuration file',
+                'action'      => 'StoreString'
+            )
+        );
+
         return $parser;
     }
 
-    protected function parseParameters($parser)
+    /**
+     * Let the CLI option parser parse the options.
+     *
+     * @param object $parser Option parser
+     *
+     * @return object Parsed command line parameters
+     */
+    protected function parseParameters(\Console_CommandLine $parser)
     {
         try {
             $result = $parser->parse();
-            // do something with the result object
-            $this->config->daysAfter  = $result->options['daysAfter'];
-            $this->config->daysBefore = $result->options['daysBefore'];
-            $this->config->renderer   = $result->options['renderer'];
-            $this->config->quiet      = $result->options['quiet'];
+
+            if ($result->options['configfile'] !== null) {
+                $this->config->cfgFiles = array($result->options['configfile']);
+            }
+
+            $this->config->daysNext    = $result->options['daysNext'];
+            $this->config->daysPrev    = $result->options['daysPrev'];
+            $this->config->renderer    = $result->options['renderer'];
+            $this->config->stopOnEmpty = $result->options['stopOnEmpty'];
+            $this->config->setDate($result->options['date']);
+            if (isset($result->options['ansi'])) {
+                $this->config->ansi = $result->options['ansi'];
+            }
+            return $result;
         } catch (\Exception $exc) {
             $this->preRenderParameterError();
             $parser->displayError($exc->getMessage());
         }
     }
 
+    /**
+     * Output the events
+     *
+     * @param array $arEvents Event objects to render
+     *
+     * @return void
+     */
     protected function render($arEvents)
     {
         $r = $this->getRenderer();
         $r->config = $this->config;
+
+        if ($this->config->stopOnEmpty && count($arEvents) == 0) {
+            $r->handleStopOnEmpty();
+            return;
+        }
         $r->renderAndOutput($arEvents);
     }
 
+    /**
+     * Load the configured renderer
+     *
+     * @return Renderer Renderer instance
+     */
     protected function getRenderer()
     {
         $renderer = ucfirst($this->config->renderer);
@@ -113,6 +218,22 @@ abstract class UserInterface
         return new $class();
     }
 
+    /**
+     * Handle any commands given on the CLI
+     *
+     * @param object $res Command line parameters and options
+     *
+     * @return void
+     */
+    protected function handleCommands($res)
+    {
+    }
+
+    /**
+     * Do something before a parameter parsing error is shown
+     *
+     * @return void
+     */
     protected function preRenderParameterError()
     {
     }