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; }