diff --git a/.travis.yml b/.travis.yml
index 3ff0fca..c9dc9a9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
language: php
php:
- - 5.3
+ - 5.4
services:
- mysql
env:
diff --git a/README.md b/README.md
index 58a2085..f16b2bb 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ A personal SMS check-in app - check if your friends respond.
To install the platform on your computer/server, the target system must meet the following requirements:
-* PHP version 5.3.0 or greater
+* PHP version 5.4.0 or greater
* Database Server
- MySQL version 5.5 or greater
- PostgreSQL support is coming
diff --git a/application/bootstrap.php b/application/bootstrap.php
index 312fa39..7235337 100644
--- a/application/bootstrap.php
+++ b/application/bootstrap.php
@@ -125,7 +125,7 @@
/**
* Enable plugins. Plugins are referenced by a relative or absolute path.
*/
-Kohana::modules( array_merge(Kohana::$config->load('plugins')->as_array(), Kohana::modules()) );
+//Kohana::modules( array_merge(Kohana::$config->load('plugins')->as_array(), Kohana::modules()) );
/**
* Set cookie salt
diff --git a/application/classes/PingApp.php b/application/classes/PingApp.php
index 92aa9e3..742d903 100644
--- a/application/classes/PingApp.php
+++ b/application/classes/PingApp.php
@@ -20,11 +20,7 @@ final class PingApp {
public static function init()
{
/**
- * Plugin Registration Listener
- * ++TODO's
- * - Load Modules Here Instead of Boostrap
- * - Add to a plugins table to set on/off
- * - If off, unload from modules
+ * 1. Plugin Registration Listener
*/
Event::instance()->listen(
'PingApp_Plugin',
@@ -33,24 +29,98 @@ function ($event, $params) {
}
);
+ /**
+ * 2. Load the plugins
+ */
+ self::load();
+
+
// SMS Settings
self::$sms = (PingApp_Settings::get('sms') == 'on') ? TRUE : FALSE;
self::$sms_provider = PingApp_Settings::get('sms_provider');
}
+ /**
+ * Load All Plugins Into System
+ */
+ public static function load()
+ {
+ // Load Plugins
+ $results = scandir(PLUGINPATH);
+ foreach ($results as $result) {
+ if ($result === '.' or $result === '..') continue;
+
+ if (is_dir(PLUGINPATH.$result))
+ {
+ Kohana::modules( array($result => PLUGINPATH.$result) + Kohana::modules() );
+ }
+ }
+ }
+
/**
* Register A Plugin
+ *
+ * @param array $params
*/
public static function register($params)
{
- try
+ if (self::valid_plugin($params))
{
$config = Kohana::$config->load('_plugins');
- $config->set(key($params), $params[key($params)]);
+ $config->set(key($params), $params[key($params)]);
+ }
+ }
+
+ /**
+ * Validate Plugin Parameters
+ *
+ * @param array $params
+ * @return bool valid/invalid
+ */
+ public static function valid_plugin($params)
+ {
+ $path = array_keys($params)[0];
+
+ if ( ! is_array($params) )
+ {
+ return FALSE;
}
- catch (Exception $e)
+
+ // Validate Name
+ if ( ! isset($params[$path]['name']) )
{
- // Problem Registering Config
+ Kohana::$log->add(Log::ERROR, __("':plugin' does not have 'name'", array(':plugin' => $path)));
+ return FALSE;
}
+
+ // Validate Version
+ if ( ! isset($params[$path]['version']) )
+ {
+ Kohana::$log->add(Log::ERROR, __("':plugin' does not have 'version'", array(':plugin' => $path)));
+ return FALSE;
+ }
+
+ // Validate Services
+ if ( ! isset($params[$path]['services']) OR ! is_array($params[$path]['services']) )
+ {
+ Kohana::$log->add(Log::ERROR, __("':plugin' does not have 'services' or 'services' is not an array", array(':plugin' => $path)));
+ return FALSE;
+ }
+
+ // Validate Options
+ if ( ! isset($params[$path]['options']) OR ! is_array($params[$path]['options']) )
+ {
+ Kohana::$log->add(Log::ERROR, __("':plugin' does not have 'options' or 'options' is not an array", array(':plugin' => $path)));
+ return FALSE;
+ }
+
+ // Validate Links
+ if ( ! isset($params[$path]['links']) OR ! is_array($params[$path]['links']) )
+ {
+ Kohana::$log->add(Log::ERROR, __("':plugin' does not have 'links' or 'links' is not an array", array(':plugin' => $path)));
+ return FALSE;
+ }
+
+ return TRUE;
}
}
\ No newline at end of file
diff --git a/application/tests/classes/PluginTest.php b/application/tests/classes/PluginTest.php
new file mode 100644
index 0000000..b520492
--- /dev/null
+++ b/application/tests/classes/PluginTest.php
@@ -0,0 +1,153 @@
+
+ * @package Ushahidi\Application\Tests
+ * @copyright Ushahidi - http://www.ushahidi.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License Version 3 (GPLv3)
+ */
+
+class PluginTest extends Unittest_TestCase {
+ /**
+ * Provider for test_validate_valid
+ *
+ * @access public
+ * @return array
+ */
+ public function provider_validate_valid()
+ {
+ return array(
+ array(
+ // Valid plugin init
+ array(
+ 'twilio' => array(
+ 'name' => 'Twilio Plugin',
+ 'version' => '0.1',
+ 'services' => array(
+ 'sms' => true,
+ 'ivr' => true,
+ 'email' => true
+ ),
+ 'options' => array(
+ 'phone' => 'Phone Number',
+ 'account_sid' => 'Account SID',
+ 'auth_token' => 'Auth Token'
+ ),
+ 'links' => array(
+ 'developer' => 'https://www.twilio.com',
+ 'signup' => 'https://www.twilio.com/try-twilio'
+ )
+ )
+ )
+ ),
+ array(
+ // Valid plugin init
+ array(
+ 'nexmo' => array(
+ 'name' => 'Nexmo',
+ 'version' => '0.1',
+ 'services' => array(
+ 'sms' => true,
+ 'ivr' => true,
+ 'email' => false
+ ),
+ 'options' => array(
+ 'phone' => 'Phone Number',
+ 'api_key' => 'API Key',
+ 'api_secret' => 'API Secret'
+ ),
+ 'links' => array(
+ 'developer' => 'https://www.nexmo.com/',
+ 'signup' => 'https://dashboard.nexmo.com/register'
+ )
+ )
+ )
+ ),
+ array(
+ // Valid plugin init
+ array(
+ 'testme' => array(
+ 'name' => 'A Fake Plugin',
+ 'version' => '0.1',
+ 'services' => array(),
+ 'options' => array(),
+ 'links' => array()
+ )
+ )
+ )
+ );
+ }
+
+ /**
+ * Provider for test_validate_invalid
+ *
+ * @access public
+ * @return array
+ */
+ public function provider_validate_invalid()
+ {
+ return array(
+ array(
+ // Invalid plugin init (missing version)
+ array(
+ 'microwave' => array(
+ 'name' => 'Microwave Plugin',
+ 'services' => array(
+ 'sms' => true,
+ 'ivr' => true,
+ 'email' => true
+ ),
+ 'options' => array(),
+ 'links' => array()
+ )
+ )
+ ),
+ array(
+ // Invalid plugin init (missing options and links)
+ array(
+ 'lightbulb' => array(
+ 'name' => 'Lightbulb Plugin',
+ 'version' => '1',
+ 'services' => array(
+ 'sms' => true,
+ 'ivr' => true,
+ 'email' => true
+ ),
+ )
+ )
+ ),
+ );
+ }
+
+ /**
+ * Test Validate Valid Entries
+ *
+ * @dataProvider provider_validate_valid
+ * @return void
+ */
+ public function test_validate_valid($set)
+ {
+ if ( ! PingApp::valid_plugin($set))
+ {
+ $this->fail('This entry qualifies as invalid when it should be valid: '. json_encode($set));
+ }
+ }
+
+ /**
+ * Test Validate Invalid Entries
+ *
+ * @dataProvider provider_validate_invalid
+ * @return void
+ */
+ public function test_validate_invalid($set)
+ {
+ if ( ! PingApp::valid_plugin($set))
+ {
+ return;
+ }
+
+ $this->fail('This entry qualifies as valid when it should be invalid');
+ }
+}
\ No newline at end of file
diff --git a/application/tests/phpunit.xml b/application/tests/phpunit.xml
index 259bc96..16bd0ad 100644
--- a/application/tests/phpunit.xml
+++ b/application/tests/phpunit.xml
@@ -4,4 +4,7 @@
./
+
+
+
\ No newline at end of file
diff --git a/httpdocs/index.php b/httpdocs/index.php
index b10992c..7fa8ad6 100644
--- a/httpdocs/index.php
+++ b/httpdocs/index.php
@@ -62,25 +62,25 @@
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);
// Make the application relative to the docroot
-if ( ! is_dir($application) AND is_dir(DOCROOT.$application))
+if (is_dir(DOCROOT.$application))
{
$application = DOCROOT.$application;
}
// Make the modules relative to the docroot
-if ( ! is_dir($modules) AND is_dir(DOCROOT.$modules))
+if (is_dir(DOCROOT.$modules))
{
$modules = DOCROOT.$modules;
}
// Make the plugins relative to the docroot
-if ( ! is_dir($plugins) AND is_dir(DOCROOT.$plugins))
+if (is_dir(DOCROOT.$plugins))
{
$plugins = DOCROOT.$plugins;
}
// Make the system relative to the docroot
-if ( ! is_dir($system) AND is_dir(DOCROOT.$system))
+if (is_dir(DOCROOT.$system))
{
$system = DOCROOT.$system;
}