Browse files

Issue #90: Admins can open/close registration in a web-based Settings…

… area (not the config file)

* Click on Settings, and then the Settings tab
* Open/close registration and set ReCAPTCHA keys
* Introduced framework for any number of application settings, aliased to the Config object
* Closes #90, Closes #527
  • Loading branch information...
1 parent 951ab36 commit e28933bcda00c41c3d2385684136315b1e62dc2f @mwilkie mwilkie committed with ginatrapani Dec 13, 2010
View
234 tests/TestOfAppConfigController.php
@@ -0,0 +1,234 @@
+<?php
+/**
+ *
+ * ThinkUp/tests/TestOfAppConfigController.php
+ *
+ * Copyright (c) 2009-2010 Mark Wilkie
+ *
+ * LICENSE:
+ *
+ * This file is part of ThinkUp (http://thinkupapp.com).
+ *
+ * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Test TestAppConfigController class
+ *
+ * @license http://www.gnu.org/licenses/gpl.html
+ * @copyright 2009-2010 Mark Wilkie
+ * @author Mark Wilkie <mwilkie[at]gmail[dot]com>
+ */
+require_once dirname(__FILE__).'/init.tests.php';
+require_once THINKUP_ROOT_PATH.'webapp/_lib/extlib/simpletest/autorun.php';
+require_once THINKUP_ROOT_PATH.'webapp/config.inc.php';
+
+class TestOfAppConfigController extends ThinkUpUnitTestCase {
+
+ const TEST_TABLE = 'options';
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->UnitTestCase('AppConfigController class test');
+ }
+
+ public function setUp(){
+ parent::setUp();
+ $this->config = Config::getInstance();
+ $this->config->setValue('debug', true);
+ $this->prefix = $this->config->getValue('table_prefix');
+ $dao = DAOFactory::getDAO('OptionDAO');
+ $this->pdo = PluginOptionMySQLDAO::$PDO;
+ }
+
+ public function tearDown(){
+ parent::tearDown();
+ }
+
+ public function testConstructor() {
+ $controller = new AppConfigController(true);
+ $this->assertTrue(isset($controller), 'constructor test');
+ }
+
+ public function testNotLoggedIn() {
+ $controller = new AppConfigController(true);
+ $results = $controller->go();
+ $v_mgr = $controller->getViewManager();
+ $config = Config::getInstance();
+ $this->assertEqual('You must <a href="'.$config->getValue('site_root_path').
+ 'session/login.php">log in</a> to do this.', $v_mgr->getTemplateDataItem('errormsg'));
+ }
+
+ public function testNonAdminAccess() {
+ $this->simulateLogin('me@example.com');
+ $controller = new AppConfigController(true);
+ $this->expectException('Exception', 'You must be a ThinkUp admin to do this');
+ $results = $controller->control();
+ }
+
+ public function testLoadConfigViewData() {
+ $this->simulateLogin('me@example.com', true);
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ //var_dump($json_obj);
+ $this->assertFalse($json_obj->app_config_settings->recaptcha_enable->required);
+ $this->assertEqual(count($json_obj->values), 0, 'no app settings stored');
+
+ $bvalue = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'recaptcha_enable',
+ 'option_value' => 'true');
+ $bvalue2 = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'recaptcha_private_key',
+ 'option_value' => 'abc123');
+ $bvalue3 = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'recaptcha_public_key',
+ 'option_value' => 'abc123public');
+ $bdata2 = FixtureBuilder::build('options', $bvalue);
+ $bdata3 = FixtureBuilder::build('options', $bvalue2);
+ $bdata4 = FixtureBuilder::build('options', $bvalue3);
+
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertFalse($json_obj->app_config_settings->recaptcha_enable->required);
+ $this->assertTrue($json_obj->values->recaptcha_enable->option_value, "uses db config value");
+ $this->assertEqual($json_obj->values->recaptcha_private_key->option_value, 'abc123');
+ $this->assertEqual($json_obj->values->recaptcha_public_key->option_value, 'abc123public');
+ }
+
+ public function testSaveConfigViewData() {
+ $this->simulateLogin('me@example.com', true);
+ $_POST['save'] = true;
+
+ # no values
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'success');
+ $this->assertEqual($json_obj->saved, 0);
+ $this->assertEqual($json_obj->deleted, 0);
+
+ # bad arg for is_registration_open
+ $_POST['is_registration_open'] = 'falsey';
+ //$_POST['recaptcha_enable'] = 'false';
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'failed');
+ $this->assertNotNull($json_obj->required->is_registration_open);
+
+ # bad arg for recaptcha
+ $_POST['is_registration_open'] = 'false';
+ $_POST['recaptcha_enable'] = 'false';
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'failed');
+ $this->assertNotNull($json_obj->required->recaptcha_enable);
+
+ # bad deps for recaptcha
+ $_POST['recaptcha_enable'] = 'true';
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'failed');
+ $this->assertNotNull($json_obj->required);
+ $this->assertNotNull($json_obj->required->recaptcha_public_key);
+ $this->assertNotNull($json_obj->required->recaptcha_private_key);
+
+ # valid save for recaptcha
+ $_POST['recaptcha_enable'] = 'true';
+ $_POST['recaptcha_public_key'] = '1234';
+ $_POST['recaptcha_private_key'] = '1234abc';
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'success');
+ $this->assertEqual($json_obj->saved, 4);
+
+ $sql = "select * from " . $this->prefix . 'options where namespace = \'' . OptionDAO::APP_OPTIONS
+ . '\' order by option_id';
+ $stmt = PluginOptionMysqlDAO::$PDO->query($sql);
+ $data = array();
+ while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ array_push($data, $row);
+ }
+ $stmt->closeCursor();
+ array_shift($data); //shift off database version record
+ $this->assertEqual(count($data), 4);
+ $this->assertEqual($data[0]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[0]['option_name'], 'is_registration_open');
+ $this->assertEqual($data[0]['option_value'], 'false');
+ $this->assertEqual($data[1]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[1]['option_name'], 'recaptcha_enable');
+ $this->assertEqual($data[1]['option_value'], 'true');
+ $this->assertEqual($data[2]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[2]['option_name'], 'recaptcha_public_key');
+ $this->assertEqual($data[2]['option_value'], '1234');
+ $this->assertEqual($data[3]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[3]['option_name'], 'recaptcha_private_key');
+ $this->assertEqual($data[3]['option_value'], '1234abc');
+
+ # update records...
+ $_POST['is_registration_open'] = 'true';
+ $_POST['recaptcha_enable'] = 'true';
+ $_POST['recaptcha_public_key'] = '12345';
+ $_POST['recaptcha_private_key'] = '12345abc';
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'success');
+ $this->assertEqual($json_obj->saved, 4);
+ $this->assertEqual($json_obj->deleted, 0);
+ $sql = "select * from " . $this->prefix . 'options where namespace = \'' . OptionDAO::APP_OPTIONS
+ . '\' order by option_id';
+ $stmt = PluginOptionMysqlDAO::$PDO->query($sql);
+ $data = array();
+ while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ array_push($data, $row);
+ }
+ $stmt->closeCursor();
+ array_shift($data); //shift off database version record
+ $this->assertEqual(count($data), 4);
+ $this->assertEqual($data[0]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[0]['option_name'], 'is_registration_open');
+ $this->assertEqual($data[0]['option_value'], 'true');
+ $this->assertEqual($data[1]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[1]['option_name'], 'recaptcha_enable');
+ $this->assertEqual($data[1]['option_value'], 'true');
+ $this->assertEqual($data[2]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[2]['option_name'], 'recaptcha_public_key');
+ $this->assertEqual($data[2]['option_value'], '12345');
+ $this->assertEqual($data[3]['namespace'], OptionDAO::APP_OPTIONS);
+ $this->assertEqual($data[3]['option_name'], 'recaptcha_private_key');
+ $this->assertEqual($data[3]['option_value'], '12345abc');
+
+ # delete records...
+ $_POST['is_registration_open'] = 'true';
+ $_POST['recaptcha_enable'] = '';
+ $_POST['recaptcha_public_key'] = '';
+ $_POST['recaptcha_private_key'] = '';
+ $controller = new AppConfigController(true);
+ $results = $controller->control();
+ $json_obj = json_decode($results);
+ $this->assertEqual($json_obj->status, 'success');
+ $this->assertEqual($json_obj->saved, 1);
+ $this->assertEqual($json_obj->deleted, 3);
+ $sql = "select * from " . $this->prefix . 'options where namespace = \'' . OptionDAO::APP_OPTIONS
+ . '\' order by option_id';
+ $stmt = PluginOptionMysqlDAO::$PDO->query($sql);
+ $data = array();
+ while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ array_push($data, $row);
+ }
+ $stmt->closeCursor();
+ array_shift($data); //shift off database version record
+ $this->assertEqual(count($data), 1);
+ }
+}
View
65 tests/TestOfConfig.php
@@ -19,25 +19,40 @@
*
* You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
* <http://www.gnu.org/licenses/>.
- */
-require_once dirname(__FILE__).'/init.tests.php';
-require_once THINKUP_ROOT_PATH.'webapp/_lib/extlib/simpletest/autorun.php';
-require_once THINKUP_ROOT_PATH.'webapp/config.inc.php';
-
-/**
+ *
* Test of Config object
* @license http://www.gnu.org/licenses/gpl.html
* @copyright 2009-2010 Gina Trapani, Mark Wilkie
* @author Gina Trapani <ginatrapani[at]gmail[dot]com>
*
*/
-class TestOfConfig extends ThinkUpBasicUnitTestCase {
+
+require_once dirname(__FILE__).'/init.tests.php';
+require_once THINKUP_ROOT_PATH.'webapp/_lib/extlib/simpletest/autorun.php';
+require_once THINKUP_ROOT_PATH.'webapp/config.inc.php';
+
+class TestOfConfig extends ThinkUpUnitTestCase {
/**
* Constructor
*/
public function __construct() {
$this->UnitTestCase('Config class test');
}
+
+ public function setUp() {
+ parent::setUp();
+ $this->logger = Logger::getInstance();
+ $this->config = Config::getInstance();
+ $this->prefix = $this->config->getValue('table_prefix');
+ $optiondao = new OptionMySQLDAO();
+ $this->pdo = $optiondao->connect();
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+ $this->logger->close();
+ }
+
/**
* Test config singleton instantiation
*/
@@ -91,6 +106,42 @@ public function testNoConfigFileNoArray() {
$this->restoreConfigFile();
}
+ public function testDBConfigValues() {
+ Config::destroyInstance();
+ $config = Config::getInstance();
+ $this->assertEqual($config->getValue('is_registration_open'), '', "uses default app config value");
+ $this->assertFalse($config->getValue('recaptcha_enable'), "uses default app config value");
+ $this->assertEqual($config->getValue('recaptcha_private_key'), '', "uses default app config value");
+ $this->assertEqual($config->getValue('recaptcha_public_key'), '', "uses default app config value");
+
+ $this->unsetArray($_SESSION);
+
+ $bvalue = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'recaptcha_enable',
+ 'option_value' => 'false');
+ $bdata = FixtureBuilder::build('options', $bvalue);
+ $this->assertFalse($config->getValue('is_registration_open'), "uses default app config value");
+ $this->assertFalse($config->getValue('recaptcha_enable'), "uses db config value");
+ $this->assertEqual($config->getValue('recaptcha_private_key'), '', "uses default app config value");
+ $this->assertEqual($config->getValue('recaptcha_public_key'), '', "uses default app config value");
+
+ $this->unsetArray($_SESSION);
+ FixtureBuilder::truncateTable('options');
+ $bvalue['option_value'] = 'true';
+ $bvalue2 = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'recaptcha_private_key',
+ 'option_value' => 'abc123');
+ $bvalue3 = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'recaptcha_public_key',
+ 'option_value' => 'abc123public');
+ $bvalue4 = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'is_registration_open',
+ 'option_value' => 'true');
+ $bdata2 = FixtureBuilder::build('options', $bvalue);
+ $bdata3 = FixtureBuilder::build('options', $bvalue2);
+ $bdata4 = FixtureBuilder::build('options', $bvalue3);
+ $bdata5 = FixtureBuilder::build('options', $bvalue4);
+ $this->assertTrue($config->getValue('recaptcha_enable'), "uses db config value");
+ $this->assertEqual($config->getValue('recaptcha_private_key'), 'abc123', "uses db config value");
+ $this->assertEqual($config->getValue('is_registration_open'), true, "uses db config value");
+ }
+
public function testGetGMTOffset() {
Config::destroyInstance();
$this->removeConfigFile();
View
37 tests/TestOfRegisterController.php
@@ -19,6 +19,13 @@
*
* You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
* <http://www.gnu.org/licenses/>.
+ *
+ * Test of RegisterController
+ *
+ * @license http://www.gnu.org/licenses/gpl.html
+ * @copyright 2009-2010 Gina Trapani
+ * @author Gina Trapani <ginatrapani[at]gmail[dot]com>
+ *
*/
require_once dirname(__FILE__).'/init.tests.php';
require_once THINKUP_ROOT_PATH.'webapp/_lib/extlib/simpletest/autorun.php';
@@ -27,14 +34,6 @@
require_once THINKUP_ROOT_PATH.'webapp/plugins/twitter/model/class.TwitterOAuthThinkUp.php';
require_once THINKUP_ROOT_PATH.'webapp/plugins/twitter/model/class.TwitterPlugin.php';
-/**
- * Test of RegisterController
- *
- * @license http://www.gnu.org/licenses/gpl.html
- * @copyright 2009-2010 Gina Trapani
- * @author Gina Trapani <ginatrapani[at]gmail[dot]com>
- *
- */
class TestOfRegisterController extends ThinkUpUnitTestCase {
public function __construct() {
$this->UnitTestCase('RegisterController class test');
@@ -71,6 +70,11 @@ public function testAlreadyLoggedIn() {
}
public function testAllMissingFields() {
+ // make sure registration is on...
+ $bvalues = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'is_registration_open',
+ 'option_value' => 'true');
+ $bdata = FixtureBuilder::build('options', $bvalues);
+
$_POST['Submit'] = 'Register';
$controller = new RegisterController(true);
$results = $controller->go();
@@ -81,6 +85,11 @@ public function testAllMissingFields() {
}
public function testSomeMissingFields() {
+ // make sure registration is on...
+ $bvalues = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'is_registration_open',
+ 'option_value' => 'true');
+ $bdata = FixtureBuilder::build('options', $bvalues);
+
$_POST['Submit'] = 'Register';
$_POST['full_name'] = "Angelina Jolie";
$_POST['email'] = 'angie@example.com';
@@ -95,6 +104,11 @@ public function testSomeMissingFields() {
}
public function testMismatchedPasswords() {
+ // make sure registration is on...
+ $bvalues = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'is_registration_open',
+ 'option_value' => 'true');
+ $bdata = FixtureBuilder::build('options', $bvalues);
+
$_POST['Submit'] = 'Register';
$_POST['full_name'] = "Angelina Jolie";
$_POST['email'] = 'angie@example.com';
@@ -112,6 +126,11 @@ public function testMismatchedPasswords() {
}
public function testSuccessfulRegistration() {
+ // make sure registration is on...
+ $bvalues = array('namespace' => OptionDAO::APP_OPTIONS, 'option_name' => 'is_registration_open',
+ 'option_value' => 'true');
+ $bdata = FixtureBuilder::build('options', $bvalues);
+
$_SERVER['HTTP_HOST'] = "http://mytestthinkup/";
$_POST['Submit'] = 'Register';
$_POST['full_name'] = "Angelina Jolie";
@@ -142,4 +161,4 @@ public function generate() {
public function check() {
return true;
}
-}
+}
View
1 tests/all_controller_tests.php
@@ -34,6 +34,7 @@
$controller_test = & new GroupTest('Controller tests');
$controller_test->addTestCase(new TestOfAccountConfigurationController());
$controller_test->addTestCase(new TestOfActivateAccountController());
+$controller_test->addTestCase(new TestOfAppConfigController());
$controller_test->addTestCase(new TestOfBackupController());
$controller_test->addTestCase(new TestOfCheckCrawlerController());
$controller_test->addTestCase(new TestOfCrawlerAuthController());
View
2 tests/classes/class.ThinkUpBasicUnitTestCase.php
@@ -80,7 +80,7 @@ public function tearDown() {
* Unset all the values for every key in an array
* @param array $array
*/
- private function unsetArray(&$array) {
+ protected function unsetArray(&$array) {
$keys = array_keys($array);
foreach ($keys as $key) {
unset($array[$key]);
View
13 tests/classes/class.ThinkUpUnitTestCase.php
@@ -19,9 +19,7 @@
*
* You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
* <http://www.gnu.org/licenses/>.
- */
-
-/**
+ *
* ThinkUp Unit Test Case
*
* Adds database support to the basic unit test case, for tests that need ThinkUp's database structure.
@@ -33,7 +31,7 @@
class ThinkUpUnitTestCase extends ThinkUpBasicUnitTestCase {
const TEST_EMAIL = '/upgrade_test_email';
-
+
var $db;
var $conn;
var $testdb_helper;
@@ -55,8 +53,6 @@ public function setUp() {
$this->db = new Database($THINKUP_CFG);
$this->conn = $this->db->getConnection();
- // $loader_paths = Loader::getLookupPath();
- // var_dump($loader_paths);
$this->testdb_helper = new ThinkUpTestDatabaseHelper();
$this->testdb_helper->drop($this->db);
$this->testdb_helper->create($this->db);
@@ -74,7 +70,6 @@ public function tearDown() {
if(file_exists($test_email)) {
unlink($test_email);
}
-
}
/**
@@ -94,12 +89,12 @@ public function getElementById($doc, $id) {
*/
class Mailer {
public static function mail($to, $subject, $message) {
- $test_email = THINKUP_WEBAPP_PATH . '_lib/view/compiled_view' . TestOfUpgradeController::TEST_EMAIL;
+ $test_email = THINKUP_WEBAPP_PATH . '_lib/view/compiled_view' . ThinkUpUnitTestCase::TEST_EMAIL;
$fp = fopen($test_email, 'w');
fwrite($fp, "to: $to\n");
fwrite($fp, "subject: $subject\n");
fwrite($fp, "message: $message");
fclose($fp);
return $message;
}
-}
+}
View
124 webapp/_lib/controller/class.AppConfigController.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ *
+ * ThinkUp/webapp/_lib/controller/class.AppConfigController.php
+ *
+ * Copyright (c) 2009-2010 Mark Wilkie
+ *
+ * LICENSE:
+ *
+ * This file is part of ThinkUp (http://thinkupapp.com).
+ *
+ * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * App Config Controller
+ * Saves/Updates application-wide options/settings.
+ *
+ * @license http://www.gnu.org/licenses/gpl.html
+ * @copyright 2009-2010 Mark Wilkie
+ * @author Mark Wilkie <mwilkie[at]gmail[dot]com>
+ *
+ */
+class AppConfigController extends ThinkUpAdminController {
+
+ public function __construct($session_started=false) {
+ parent::__construct($session_started);
+ }
+
+ public function adminControl() {
+ $this->disableCaching();
+ $option_dao = DAOFactory::getDAO("OptionDAO");
+
+ if(isset($_POST['save'])) {
+ $required = array();
+ $config_values = array();
+ $parent_config_values = array();
+ $app_config = AppConfig::getConfigData();
+ $values = 0;
+
+ foreach($app_config as $key => $value) {
+ $app_config[$key]['title'] =
+ isset($app_config[$key]['title']) ? $app_config[$key]['title'] : $key;
+
+ if((isset($_POST[$key]) && $_POST[$key] != '') || $app_config[$key]['required'] &&
+ ( (! isset($app_config[$key]['value']) || $app_config[$key]['value'] == '')
+ && ! isset($required[$key]) ) ) {
+ $config_values[$key] = $app_config[$key];
+ if(isset($_POST[$key])) {
+ $config_values[$key]['value'] = $_POST[$key];
+ $values++;
+ }
+ $config_values[$key]['value'] = isset($_POST[$key]) ? $_POST[$key] : '';
+ if( isset($app_config[$key]['match'])
+ && ! preg_match($app_config[$key]['match'], $config_values[$key]['value']) ) {
+ $required[$key] = $app_config[$key]['title'] .
+ ' should ' . $app_config[$key]['match_message'];
+ }
+
+ if(isset($app_config[$key]['dependencies'])) {
+ foreach( $config_values[$key]['dependencies'] as $dep_key ) {
+ $config_values[$dep_key]['value'] = isset($_POST[$dep_key]) ? $_POST[$dep_key] : '';
+ $value = $config_values[$dep_key]['value'];
+ if( isset($app_config[$dep_key]['match'])
+ && ! preg_match($app_config[$dep_key]['match'], $value) ) {
+ $required[$dep_key] = $app_config[$dep_key]['title'] .
+ ' is required if ' . $app_config[$key]['title'] .
+ ' is set ' . $app_config[$dep_key]['match_message'];
+ }
+ }
+ }
+ }
+ }
+
+ if(count($required) > 0) {
+ $this->setJsonData( array( 'status' => 'failed', 'required' => $required));
+ } else {
+ // save our data
+ $saved = 0;
+ $deleted = 0;
+ foreach($config_values as $key => $config_value) {
+ $config = $option_dao->getOptionByName(OptionDAO::APP_OPTIONS, $key);
+ if($config_value['value'] != '') {
+ if($config) {
+ $option_dao->updateOption($config->option_id, $config_value['value']);
+ } else {
+ $option_dao->insertOption(OptionDAO::APP_OPTIONS, $key, $config_value['value']);
+ }
+ $saved++;
+ }
+ }
+ foreach($app_config as $key => $value) {
+ // delete the record if it exists and is empty in the post request
+ if(! isset($config_values[$key]['value']) || $config_values[$key]['value'] == '') {
+ $config = $option_dao->getOptionByName(OptionDAO::APP_OPTIONS, $key);
+ if($config) {
+ $option_dao->deleteOption($config->option_id);
+ $deleted++;
+ }
+ }
+ }
+ $this->setJsonData( array( 'status' => 'success', 'saved' => $saved, 'deleted' => $deleted));
+ }
+ } else {
+ $config_values = $option_dao->getOptions(OptionDAO::APP_OPTIONS);
+ $app_config = AppConfig::getConfigData();
+ $filtered_config_values = array();
+ foreach($app_config as $key => $value) {
+ if(isset($config_values[$key])) {
+ $filtered_config_values[$key] = $config_values[$key];
+ }
+ }
+ $this->setJsonData( array( 'values' => $filtered_config_values, 'app_config_settings' => $app_config ));
+ }
+ return $this->generateView();
+ }
+}
View
91 webapp/_lib/model/class.AppConfig.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *
+ * ThinkUp/webapp/_lib/model/class.AppConfig.php
+ *
+ * Copyright (c) 2009-2010 Mark Wilkie
+ *
+ * LICENSE:
+ *
+ * This file is part of ThinkUp (http://thinkupapp.com).
+ *
+ * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Application config options defaults, and validation settings.
+ * class.Config.php will use to determine what configs to pull from the database, and
+ * class.AppConfigController will use config data for input validation
+ *
+ * @license http://www.gnu.org/licenses/gpl.html
+ * @copyright 2009-2010 Mark Wilkie
+ * @author Mark Wilkie <mwilkie[at]gmail[dot]com>
+ *
+ */
+class AppConfig {
+
+ /**
+ * Data validation array
+ * @var array Collection oif validation string for data input
+ */
+ static $config_data = array(
+ 'is_registration_open' => array(
+ 'type' => 'checkbox',
+ 'title' => 'Open Registration',
+ 'required' => false,
+ 'default' => 'false',
+ 'match' => '/^(true|false)$/',
+ 'match_message' => 'Must be true or false'
+ ),
+ 'recaptcha_enable' => array(
+ 'type' => 'checkbox',
+ 'title' => 'Enable ReCAPTCHA',
+ 'required' => false,
+ 'default' => 'false',
+ 'match' => '/^true$/',
+ 'match_message' => 'Must be true',
+ 'dependencies' => array('recaptcha_public_key','recaptcha_private_key')
+ ),
+ 'recaptcha_public_key' => array(
+ 'type' => 'text',
+ 'title' => 'ReCAPTCHA Public Key',
+ 'required' => false,
+ 'match' => '/\w/',
+ 'match_message' => '',
+ 'default' => '',
+ ),
+ 'recaptcha_private_key' => array(
+ 'type' => 'text',
+ 'title' => 'ReCAPTCHA Private Key',
+ 'required' => false,
+ 'match' => '/\w/',
+ 'match_message' => '',
+ 'default' => '',
+ )
+ );
+
+ /**
+ * Getter for db config data array
+ * @return array Application settings configuration and validation data array/hash
+ */
+ public static function getConfigData() {
+ return self::$config_data;
+ }
+
+ /**
+ * Getter for db config data value
+ * @param str Key for apllication value
+ * @return array Application settings configuration and validation data array/hash
+ */
+ public static function getConfigValue($key) {
+ $value = isset(self::$config_data[$key] ) ? self::$config_data[$key] : false;
+ return $value;
+ }
+}
View
25 webapp/_lib/model/class.Config.php
@@ -65,7 +65,6 @@ public function __construct($vals = null) {
if (file_exists(THINKUP_WEBAPP_PATH . 'config.inc.php')) {
require THINKUP_WEBAPP_PATH . 'config.inc.php';
$this->config = $THINKUP_CFG;
-
//set version info...
require THINKUP_WEBAPP_PATH . 'install/version.php';
$this->config['THINKUP_VERSION'] = $THINKUP_VERSION;
@@ -77,7 +76,6 @@ public function __construct($vals = null) {
}
}
}
-
/**
* Get the singleton instance of Config
* @param array $vals Optional values to override file config
@@ -89,17 +87,31 @@ public static function getInstance($vals = null) {
}
return self::$instance;
}
-
/**
* Get the configuration value
* @param string $key key of the configuration key/value pair
* @return mixed value of the configuration key/value pair
*/
public function getValue($key) {
- $value = isset($this->config[$key]) ? $this->config[$key] : null;
+ // is this config value stored in the db?
+ $db_value_config = AppConfig::getConfigValue($key);
+ $value = null;
+ if($db_value_config) {
+ $option_dao = DAOFactory::getDAO("OptionDAO");
+ $db_value = $option_dao->getOptionValue(OptionDAO::APP_OPTIONS, $key, true);
+ $value = $db_value ? $db_value : $db_value_config['default'];
+ // convert db text booleans if needed
+ if($value == 'false') {
+ $value = false;
+ } else if ($value == 'true') {
+ $value = true;
+ }
+ } else {
+ // if not a db config value, get from config file
+ $value = isset($this->config[$key]) ? $this->config[$key] : null;
+ }
return $value;
}
-
/**
* Provided only for use when overriding config.inc.php values in tests
* @param string $key
@@ -110,7 +122,6 @@ public function setValue($key, $value) {
$value = $this->config[$key] = $value;
return $value;
}
-
/**
* Provided only for tests that want to kill Config object in tearDown()
*/
@@ -119,14 +130,12 @@ public static function destroyInstance() {
self::$instance = null;
}
}
-
/**
* Provided for tests which expect an array
*/
public function getValuesArray() {
return $this->config;
}
-
/**
* Returns the GMT offset in hours based on the application's defined timezone.
*
View
3 webapp/_lib/model/class.OptionMySQLDAO.php
@@ -98,6 +98,7 @@ public function deleteOption($option_id){
$stmt = $this->execute($q, array(':option_id' => $option_id));
$this->clearSessionData($option->namespace);
return $this->getUpdateCount($stmt);
+ $this->clearSessionData($namespace);
} else {
return 0;
}
@@ -140,7 +141,7 @@ public function getOptions($namespace, $cached = false) {
public function getOptionValue($namespace, $name, $cached = false) {
$options = $this->getOptions($namespace, $cached);
- if($options && $options[$name]) {
+ if($options && isset($options[$name])) {
return $options[$name]->option_value;
} else {
return null;
View
90 webapp/_lib/view/account.appconfig.tpl
@@ -0,0 +1,90 @@
+ <div class="prepend_20">
+ <h1>Application Settings</h1>
+ </div>
+ <div class="clearfix prepend_20">
+ <div class="grid_17 prefix_3 left">
+ {include file="_usermessage.tpl"}
+ </div>
+ </div>
+
+<div id="settings_error_message_error"
+ class="ui-state-error ui-corner-all" style="margin: 20px 0px; padding: 0.5em 0.7em; display: none;">
+ <p>
+ <span class="ui-icon ui-icon-alert" style="float: left; margin:.3em 0.3em 0 0;"></span>
+ <span id="settings_error_message"></span>
+ </p>
+</div>
+
+<p class="success" id="settings_success" style="display: none;">
+ Settings Saved!
+</p>
+
+<form id="app-settings-form" name="app_settings" method="post" action="{$site_root_path}session/app_settings.php"
+ onsubmit="return false">
+ <div class="clearfix" style="width: 640px;">
+
+ <div style="clear:both;"></div>
+ <div style="float: left;">
+ <label for="is_registration_open">
+ Open registration to new ThinkUp users:
+ <br />
+ </label>
+ </div>
+ <div style="float: left;">
+ <input type="checkbox" name="is_registration_open" id="is_registration_open" value="true">
+ </div>
+ <div style="clear:both;"></div>
+ <div style="font-size: 10px; margin: 0px 0px 10px 0px;">
+ Set whether or not your site's registration page is available and accepts new user registrations.
+ </div>
+
+ <div style="float: left;">
+ <label for="recaptcha_enable">
+ Enable reCAPTCHA:
+ </label>
+ </div>
+ <div style="float: left;">
+ <input type="checkbox" name="recaptcha_enable" id="recaptcha_enable" value="true">
+ </div>
+ <div style="clear:both;"></div>
+ <div style="font-size: 10px; margin: 0px 0px 10px 0px;">
+ Select to enable reCAPTCHA, and <a href="https://recaptcha.com">get your reCAPTCHA keys here</a>.
+ </div>
+
+ <div id="recaptcha_enable_deps" style="display: none; width: 450px; margin: 10px 0px 60px 20px;">
+ <div style="float: left;">
+ <label for="recaptcha_public_key">
+ reCAPTCHA Public Key:
+ </label>
+ </div>
+ <div style="float: right;">
+ <input type="text" name="recaptcha_public_key" id="recaptcha_public_key" value="">
+ </div>
+
+ <div style="clear:both;"></div>
+ <div style="float: left;">
+ <label for="recaptcha_private_key">
+ reCAPTCHA Private Key:
+ </label>
+ </div>
+ <div style="float: right;">
+ <input type="text" name="recaptcha_private_key" id="recaptcha_private_key" value="">
+ </div>
+ </div>
+
+ </div>
+
+ <div style="text-align: center" id="save_setting_image">
+ <img id="save_setting_image" src="{$site_root_path}assets/img/loading.gif" width="31" height="31"
+ style="display: none; margin: 10px;"/>
+ </div>
+
+ <div class="clearfix">
+ <div class="grid_10 prefix_9 left">
+ <input type="submit" id="app-settings-save" name="Submit"
+ class="tt-button ui-state-default ui-priority-secondary ui-corner-all" value="Save Settings">
+ </div>
+ </div>
+
+</form>
+
View
19 webapp/_lib/view/account.index.tpl
@@ -6,6 +6,9 @@
<ul>
<li><a href="#plugins">Plug-ins</a></li>
+ {if $user_is_admin}
+ <li><a id="app-settings-tab" href="#app_settings">Settings</a></li>
+ {/if}
<li><a href="#instances">Your ThinkUp Password</a></li>
{if $user_is_admin}<li><a href="#ttusers">All ThinkUp Accounts</a></li>{/if}
</ul>
@@ -64,7 +67,21 @@
{/if}
</div>
</div> <!-- end #plugins -->
-
+
+ {if $user_is_admin}
+ <div class="section thinkup-canvas clearfix" id="app_settings">
+ <div style="text-align: center" id="app_setting_loading_div">
+ Loading application settings...<br /><br />
+ <img src="{$site_root_path}assets/img/loading.gif" width="31" height="31" />
+ </div>
+ <div id="app_settings_div" style="display: none;">
+ {include file="account.appconfig.tpl"}
+ </div>
+ <script type="text/javascript"> var site_root_path = '{$site_root_path}';</script>
+ <script type="text/javascript" src="{$site_root_path}assets/js/appconfig.js"></script>
+ </div> <!-- end #app_setting -->
+ {/if}
+
<div class="section" id="instances">
<div class="thinkup-canvas clearfix">
<div class="alpha omega grid_22 prefix_1 clearfix prepend_20 append_20">
View
32 webapp/account/appconfig.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ *
+ * ThinkUp/webapp/account/settings.php
+ *
+ * Copyright (c) 2009-2010 Mark Wilkie
+ *
+ * LICENSE:
+ *
+ * This file is part of ThinkUp (http://thinkupapp.com).
+ *
+ * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ *
+ * @author Mark Wilkie <mark[at]bitterpill[dot]org>
+ * @license http://www.gnu.org/licenses/gpl.html
+ * @copyright 2009-2010 Mark Wilkie
+ */
+chdir("..");
+require_once 'init.php';
+
+$controller = new AppConfigController();
+echo $controller->go();
View
197 webapp/assets/js/appconfig.js
@@ -0,0 +1,197 @@
+/**
+ *
+ * ThinkUp/webapp/assets/js/application_settings.js
+ *
+ * Copyright (c) 2009-2010 Mark Wilkie
+ *
+ * LICENSE:
+ *
+ * This file is part of ThinkUp (http://thinkupapp.com).
+ *
+ * ThinkUp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * ThinkUp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with ThinkUp. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ *
+ * @author Mark Wilkie <mwilkie[at]gmail[dot]com>
+ * @license http://www.gnu.org/licenses/gpl.html
+ * @copyright 2009-2010 Mark Wilkie
+ */
+
+var TUApplicationSettings = function() {
+
+ /**
+ * @var boolean Enable for console logging
+ */
+ this.DEBUG = false;
+
+ /**
+ * @var boolean tab view for setting has been loaded
+ */
+ this.TAB_LOADED = false;
+
+ /**
+ * Init our plugin options form
+ */
+ this.init = function() {
+ // pre-load loading image...
+ var loading_image = new Image();
+ loading_image.src = site_root_path + 'assets/img/loading.gif';
+
+ // register on submit event on our form
+ $(document).ready(function() {
+ $("#app-settings-tab").click(function(event) {
+ if (tu_app_settings.DEBUG) {
+ console.debug("app settings tab selected");
+ }
+ tu_app_settings.load_settings()
+ });
+ });
+
+ $('#recaptcha_enable').click(function(event) {
+ var checked = $('#recaptcha_enable:checked').val() ? true : false;
+ if (tu_app_settings.DEBUG) {
+ console.log("recaptcha setting checkbox selected, value = %s",checked);
+ }
+ if (checked) {
+ $('#recaptcha_enable_deps').show();
+ } else {
+ $('#recaptcha_enable_deps').hide();
+ }
+ });
+
+ if (document.location.href.match(/#app_settings/)) {
+ if (tu_app_settings.DEBUG) {
+ console
+ .debug("app settings tab loaded with hash #app_settings");
+ }
+ setTimeout(function() {
+ tu_app_settings.load_settings();
+ }, 1000);
+ }
+
+ }
+
+ this.save_settings = function() {
+ $('#settings_error_message_error').hide();
+ if (this.DEBUG) {
+ console.log("saving settings...");
+ console.dir({data: this.settings_data});
+ }
+ var params = {save: true};
+ for(key in this.settings_data.app_config_settings) {
+ var setting = this.settings_data.app_config_settings[key];
+ var id = '#' + key
+ if(setting.type == 'checkbox') {
+ id += ':checked';
+ if( $(id).val() ) {
+ params[key] = $('#' + key).val();
+ }
+ } else {
+ params[key] = $(id).val();
+ }
+ }
+ if (this.DEBUG) {
+ console.debug("sabving app settings");
+ console.dir({save_settings: params});
+ }
+ $('#app-settings-save').hide();
+ $('#save_setting_image').show();
+ controller_uri = site_root_path + 'account/appconfig.php';
+ $.ajax( {
+ url : controller_uri,
+ data: params,
+ type: 'post',
+ dataType : 'json',
+ error : function(data) {
+ $('#app-settings-save').show();
+ $('#save_setting_image').hide();
+ $('#settings_error_message').html('Sorry, but we are unable to process your request at this time.');
+ $('#settings_error_message_error').show();
+ },
+ success : function(data) {
+ tu_app_settings._save_settings(data)
+ }
+ });
+
+ }
+
+ this._save_settings = function(data) {
+ $('#app-settings-save').show();
+ $('#save_setting_image').hide();
+ if(data.status == 'failed') {
+ if(data.required) {
+ var error_mess = 'Please enter values for the required fields<ul style="padding-left: 20px;">';
+ for(key in data.required) {
+ error_mess += '<li>' + data.required[key] + '</li>';
+ }
+ error_mess += '</ul>'
+ $('#settings_error_message').html(error_mess);
+ $('#settings_error_message_error').show();
+ }
+ } else {
+ $('#settings_success').show();
+ setTimeout( function() {
+ $('#settings_success').fadeOut(1500,function() {});
+ }, 500);
+ }
+ }
+ this.load_settings = function() {
+ if (!tu_app_settings.TAB_LOADED) {
+ if (this.DEBUG) { console.debug("app settings tab not yet loaded, loading..."); }
+ controller_uri = site_root_path + 'account/appconfig.php';
+ $.ajax( {
+ url : controller_uri,
+ dataType : 'json',
+ error : function(data) {
+ $('#app_setting_loading_div').hide();
+ $('#app_settings_div').show();
+ $('#settings_error_message').html('Sorry, but we are unable to process your request at this time.');
+ $('#settings_error_message_error').show();
+ },
+ success : function(data) {
+ tu_app_settings._load_settings(data)
+ }
+ });
+ } else {
+ if (this.DEBUG) {
+ console.debug("app settings already loaded, not loading...");
+ }
+ }
+ }
+
+ this._load_settings = function(data) {
+ this.settings_data = data;
+ $('#app_setting_loading_div').hide();
+ $('#app_settings_div').show();
+ this.TAB_LOADED = true;
+ $('#app-settings-form').submit(function() {
+ tu_app_settings.save_settings();
+ });
+ for(key in data.app_config_settings) {
+ var setting = data.app_config_settings[key];
+ var id = '#' + key
+ if(data.values[key]) {
+ if(setting.type == 'checkbox') {
+ $(id).attr('checked', true);
+ } else {
+ $(id).val(data.values[key]['option_value']);
+ }
+ }
+ if(setting.dependencies && data.values[key] && data.values[key] != '') {
+ var id = '#' + key + '_deps';
+ if($(id)) { $(id).show(); }
+ }
+ }
+ }
+}
+
+var tu_app_settings = new TUApplicationSettings();
+tu_app_settings.init();
View
11 webapp/config.sample.inc.php
@@ -19,17 +19,6 @@
// Toggle Smarty caching. true: Smarty caching on, false: Smarty caching off
$THINKUP_CFG['cache_pages'] = true;
-// Set whether or not your site's registration page is available.
-// @TODO Build email invitation system so this isn't simply a binary choice.
-$THINKUP_CFG['is_registration_open'] = true;
-
-// To enable reCAPTCHA on registration, set enable to true and fill in your keys and libpath;
-// Otherwise, leave these settings as-is.
-// More info at http://recaptcha.net/plugins/php/
-$THINKUP_CFG['recaptcha_enable'] = false;
-$THINKUP_CFG['recaptcha_public_key'] = '';
-$THINKUP_CFG['recaptcha_private_key'] = '';
-
// The crawler, when triggered by requests to the RSS feed, will only launch if it's been
// 20 minutes or more since the last crawl.
$THINKUP_CFG['rss_crawler_refresh_rate'] = 20;

0 comments on commit e28933b

Please sign in to comment.