From 5bfa0706837ec3e6ea6eca81b04e39b4f9427a22 Mon Sep 17 00:00:00 2001
From: Thomas Steur <thomas.steur@gmail.com>
Date: Fri, 4 Oct 2013 23:42:25 +0000
Subject: [PATCH] refs #4121 added possibility to generate API for a specific
 plugin

---
 console                                       |   1 +
 core/Console.php                              |   2 +
 core/Console/Command.php                      |  19 +++
 plugins/CoreConsole/GenerateApi.php           | 127 ++++++++++++++++++
 plugins/CoreConsole/GeneratePlugin.php        |   5 +-
 plugins/CoreConsole/RunTests.php              |   2 +-
 .../templates/PluginApiTemplate.php           |  42 ++++++
 7 files changed, 196 insertions(+), 2 deletions(-)
 create mode 100644 plugins/CoreConsole/GenerateApi.php
 create mode 100644 plugins/CoreConsole/templates/PluginApiTemplate.php

diff --git a/console b/console
index 8c99a38d04..a1a51328b4 100755
--- a/console
+++ b/console
@@ -6,6 +6,7 @@ define('PIWIK_USER_PATH', PIWIK_DOCUMENT_ROOT);
 
 require_once PIWIK_INCLUDE_PATH . '/vendor/autoload.php';
 require_once PIWIK_INCLUDE_PATH . '/core/Loader.php';
+require_once PIWIK_INCLUDE_PATH . '/libs/upgradephp/upgrade.php';
 
 if (!Piwik\Common::isPhpCliMode()) {
     exit;
diff --git a/core/Console.php b/core/Console.php
index 9e2057582c..dc8b9732b3 100644
--- a/core/Console.php
+++ b/core/Console.php
@@ -11,6 +11,7 @@
 namespace Piwik;
 
 use Piwik\Plugins\CoreConsole\GeneratePlugin;
+use Piwik\Plugins\CoreConsole\GenerateApi;
 use Piwik\Plugins\CoreConsole\RunTests;
 use Piwik\Plugins\CoreConsole\WatchLog;
 use Symfony\Component\Console\Application;
@@ -23,6 +24,7 @@ class Console
 
         $console->add(new RunTests());
         $console->add(new GeneratePlugin());
+        $console->add(new GenerateApi());
         $console->add(new WatchLog());
 
         $console->run();
diff --git a/core/Console/Command.php b/core/Console/Command.php
index 7f49029c7e..920d69c303 100644
--- a/core/Console/Command.php
+++ b/core/Console/Command.php
@@ -12,6 +12,7 @@ namespace Piwik\Console;
 
 use Piwik\Common;
 use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Output\OutputInterface;
 
 class Command extends SymfonyCommand
 {
@@ -23,4 +24,22 @@ class Command extends SymfonyCommand
 
         parent::__construct($name);
     }
+
+    public function writeSuccessMessage(OutputInterface $output, $messages)
+    {
+        $lengths = array_map('strlen', $messages);
+        $maxLen  = max($lengths) + 4;
+
+        $separator = str_pad('', $maxLen, '*');
+
+        $output->writeln('');
+        $output->writeln('<info>' . $separator . '</info>');
+
+        foreach ($messages as $message) {
+            $output->writeln('  ' . $message . '  ');
+        }
+
+        $output->writeln('<info>' . $separator . '</info>');
+        $output->writeln('');
+    }
 }
diff --git a/plugins/CoreConsole/GenerateApi.php b/plugins/CoreConsole/GenerateApi.php
new file mode 100644
index 0000000000..ab3c71e5a7
--- /dev/null
+++ b/plugins/CoreConsole/GenerateApi.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik_Plugins
+ * @package CoreConsole
+ */
+
+namespace Piwik\Plugins\CoreConsole;
+
+use Piwik\Common;
+use Piwik\Console\Command;
+use Piwik\Filesystem;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @package CoreConsole
+ */
+class GenerateApi extends Command
+{
+    protected function configure()
+    {
+        $this->setName('generate:api')
+             ->setDescription('Adds an API to an existing plugin')
+             ->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'Plugin name ([a-Z0-9_-])');
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $pluginName = $this->getPluginName($input, $output);
+
+        $this->generatePluginFolder($pluginName);
+        $this->generatePluginApi($pluginName);
+
+        $this->writeSuccessMessage($output, array(
+            sprintf('API.php for %s generated.', $pluginName),
+            'You can now start adding API methods',
+            'Enjoy!'
+        ));
+    }
+
+    /**
+     * @param $pluginName
+     * @return string
+     */
+    public function getPluginPath($pluginName)
+    {
+        $pluginPath = PIWIK_INCLUDE_PATH . '/plugins/' . ucfirst($pluginName);
+        return $pluginPath;
+    }
+
+    private function generatePluginFolder($pluginName)
+    {
+        $pluginPath = $this->getPluginPath($pluginName);
+        Filesystem::mkdir($pluginPath, true);
+    }
+
+    private function writePluginFile($pluginName, $fileName, $content)
+    {
+        $pluginPath = $this->getPluginPath($pluginName);
+
+        file_put_contents($pluginPath . $fileName, $content);
+    }
+
+    /**
+     * @param $pluginName
+     */
+    private function generatePluginApi($pluginName)
+    {
+        $template   = file_get_contents(__DIR__ . '/templates/PluginApiTemplate.php');
+        $pluginFile = str_replace('PLUGINNAME', $pluginName, $template);
+        $this->writePluginFile($pluginName, '/API.php', $pluginFile);
+    }
+
+    private function getPluginNamesHavingNoApi()
+    {
+        $pluginDirs = \_glob(PIWIK_INCLUDE_PATH . '/plugins/*', GLOB_ONLYDIR);
+
+        $pluginNames = array();
+        foreach ($pluginDirs as $pluginDir) {
+            if (!file_exists($pluginDir . '/API.php')) {
+                $pluginNames[] = basename($pluginDir);;
+            }
+        }
+
+        return $pluginNames;
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return array
+     * @throws \RunTimeException
+     */
+    private function getPluginName(InputInterface $input, OutputInterface $output)
+    {
+        $pluginNames = $this->getPluginNamesHavingNoApi();
+
+        $validate = function ($pluginName) use ($pluginNames) {
+            if (!in_array($pluginName, $pluginNames)) {
+                throw new \InvalidArgumentException('You have to enter the name of an existing plugin which does not already have an API');
+            }
+
+            return $pluginName;
+        };
+
+        $pluginName = $input->getOption('pluginname');
+
+        if (empty($pluginName)) {
+            $dialog     = $this->getHelperSet()->get('dialog');
+            $pluginName = $dialog->askAndValidate($output, 'Enter the name of your plugin: ', $validate, false, null, $pluginNames);
+        } else {
+            $validate($pluginName);
+        }
+
+        $pluginName = ucfirst($pluginName);
+
+        return $pluginName;
+    }
+
+
+}
\ No newline at end of file
diff --git a/plugins/CoreConsole/GeneratePlugin.php b/plugins/CoreConsole/GeneratePlugin.php
index e5b439ad7f..6c4e27a800 100644
--- a/plugins/CoreConsole/GeneratePlugin.php
+++ b/plugins/CoreConsole/GeneratePlugin.php
@@ -45,7 +45,10 @@ class GeneratePlugin extends Command
         $this->generatePluginFiles($isTheme, $pluginName);
 
         $title = $isTheme ? 'Theme' : 'Plugin';
-        $output->writeln(sprintf('%s %s %s generated. Enjoy!', $title, $pluginName, $version));
+
+        $this->writeSuccessMessage($output, array(
+            sprintf('%s %s %s generated. Enjoy!', $title, $pluginName, $version)
+        ));
     }
 
     /**
diff --git a/plugins/CoreConsole/RunTests.php b/plugins/CoreConsole/RunTests.php
index 5da4485fd2..aa23bec7ed 100644
--- a/plugins/CoreConsole/RunTests.php
+++ b/plugins/CoreConsole/RunTests.php
@@ -36,7 +36,7 @@ class RunTests extends Command
         $group = $input->getArgument('group');
 
         if (!empty($group)) {
-            $options = '--group ' . $group . ' ' . $options;
+            $options = '--group ' . ucfirst($group) . ' ' . $options;
         }
 
         $cmd = sprintf('cd %s/tests/PHPUnit && phpunit %s', PIWIK_DOCUMENT_ROOT, $options);
diff --git a/plugins/CoreConsole/templates/PluginApiTemplate.php b/plugins/CoreConsole/templates/PluginApiTemplate.php
new file mode 100644
index 0000000000..ed54ca38ff
--- /dev/null
+++ b/plugins/CoreConsole/templates/PluginApiTemplate.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik_Plugins
+ * @package Piwik_PLUGINNAME
+ */
+namespace Piwik\Plugins\PLUGINNAME;
+
+/**
+ * API for plugin PLUGINNAME
+ *
+ * @package Piwik_PLUGINNAME
+ */
+class API
+{
+    static private $instance = null;
+
+    /**
+     * @return \Piwik\Plugins\PLUGINNAME\API
+     */
+    static public function getInstance()
+    {
+        if (self::$instance == null) {
+            self::$instance = new self;
+        }
+
+        return self::$instance;
+    }
+
+    /**
+     * Get Answer to Life
+     * @return integer
+     */
+    public function getAnswerToLife()
+    {
+        return 42;
+    }
+}
\ No newline at end of file
-- 
GitLab