From 464f4d3497617fadb9d7752868f1175849cfa6d2 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 7 Jan 2012 08:21:00 -0800 Subject: Refactor to separate the framework from the app; drop message stuff, this app is just user management. Add a json view for individual users --- apps/um/controllers/Authenticator.class.php | 57 ++ apps/um/controllers/Config.class.php | 30 ++ apps/um/controllers/Groups.class.php | 11 + apps/um/controllers/Http404.class.php | 7 + apps/um/controllers/Main.class.php | 9 + apps/um/controllers/Plugins.class.php | 75 +++ apps/um/controllers/Users.class.php | 371 +++++++++++++ apps/um/ext/PasswordHash.class.php | 253 +++++++++ apps/um/ext/README.txt | 12 + apps/um/ext/recaptchalib.php | 277 ++++++++++ apps/um/lib/DB.class.php | 164 ++++++ apps/um/lib/Database.class.php | 403 ++++++++++++++ apps/um/lib/Hasher.class.php | 18 + apps/um/lib/Login.class.php | 41 ++ apps/um/lib/Plugin.class.php | 25 + apps/um/lib/PluginManager.class.php | 99 ++++ apps/um/lib/Singleton.class.php | 12 + apps/um/lib/Site.class.php | 32 ++ apps/um/models/Auth.class.php | 157 ++++++ apps/um/models/ContactMethod.class.php | 29 + apps/um/models/Group.class.php | 23 + apps/um/models/User.class.php | 25 + apps/um/plugins/InformationPlugin.class.php | 62 +++ apps/um/plugins/ReCaptcha.class.php | 47 ++ apps/um/views/Template.class.php | 316 +++++++++++ apps/um/views/includes/header-include.php | 51 ++ apps/um/views/includes/header.php | 84 +++ apps/um/views/pages/auth/badrequest.html.php | 11 + apps/um/views/pages/auth/index.html.php | 12 + apps/um/views/pages/auth/login.html.php | 54 ++ apps/um/views/pages/auth/logout.html.php | 6 + apps/um/views/pages/groups/401.html.php | 15 + apps/um/views/pages/http404.html.php | 16 + apps/um/views/pages/index.html.php | 8 + apps/um/views/pages/plugins/401.html.php | 9 + apps/um/views/pages/plugins/index.html.php | 42 ++ apps/um/views/pages/users/401.html.php | 15 + apps/um/views/pages/users/404.html.php | 10 + apps/um/views/pages/users/500.html.php | 15 + apps/um/views/pages/users/created.html.php | 18 + apps/um/views/pages/users/index.csv.php | 27 + apps/um/views/pages/users/index.html.php | 104 ++++ apps/um/views/pages/users/individual.html.php | 147 +++++ apps/um/views/pages/users/individual.json.php | 27 + apps/um/views/pages/users/new-locked.html.php | 9 + apps/um/views/pages/users/new-logged-in.html.php | 8 + apps/um/views/pages/users/new.html.php | 57 ++ index.php | 35 +- lpf/ext/HTTP_Accept.class.php | 659 +++++++++++++++++++++++ lpf/ext/README.txt | 11 + lpf/lib/Controller.class.php | 30 ++ lpf/lib/Mime.class.php | 45 ++ lpf/lib/Model.class.php | 9 + lpf/lib/Router.class.php | 110 ++++ lpf/lib/View.class.php | 135 +++++ lpf/views/pages/no-conf.html.php | 8 + src/controllers/AuthPage.class.php | 57 -- src/controllers/Config.class.php | 30 -- src/controllers/Groups.class.php | 11 - src/controllers/Http404.class.php | 7 - src/controllers/Main.class.php | 9 - src/controllers/Messages.class.php | 100 ---- src/controllers/NewMessage.class.php | 37 -- src/controllers/Plugins.class.php | 75 --- src/controllers/Users.class.php | 371 ------------- src/ext/GoogleVoice.class.php | 84 --- src/ext/HTTP_Accept.class.php | 659 ----------------------- src/ext/Identica.class.php | 491 ----------------- src/ext/MimeMailParser.class.php | 447 --------------- src/ext/MimeMailParser_attachment.class.php | 136 ----- src/ext/PasswordHash.class.php | 253 --------- src/ext/README.txt | 17 - src/ext/recaptchalib.php | 277 ---------- src/lib/Controller.class.php | 30 -- src/lib/DB.class.php | 164 ------ src/lib/Database.class.php | 403 -------------- src/lib/Hasher.class.php | 18 - src/lib/Login.class.php | 41 -- src/lib/Mime.class.php | 45 -- src/lib/Model.class.php | 9 - src/lib/Plugin.class.php | 25 - src/lib/PluginManager.class.php | 99 ---- src/lib/Router.class.php | 110 ---- src/lib/Singleton.class.php | 12 - src/lib/Site.class.php | 32 -- src/lib/View.class.php | 135 ----- src/models/Auth.class.php | 157 ------ src/models/ContactMethod.class.php | 29 - src/models/Group.class.php | 23 - src/models/User.class.php | 25 - src/plugins/InformationPlugin.class.php | 62 --- src/plugins/ReCaptcha.class.php | 47 -- src/plugins/SenderGVSMS.class.php | 34 -- src/plugins/SenderIdentica.class.php | 35 -- src/plugins/maildir.php | 58 -- src/views/Template.class.php | 316 ----------- src/views/includes/header-include.php | 51 -- src/views/includes/header.php | 84 --- src/views/pages/auth/badrequest.html.php | 11 - src/views/pages/auth/index.html.php | 12 - src/views/pages/auth/login.html.php | 49 -- src/views/pages/auth/logout.html.php | 6 - src/views/pages/groups/401.html.php | 15 - src/views/pages/http404.html.php | 16 - src/views/pages/index.html.php | 8 - src/views/pages/messages/401.html.php | 15 - src/views/pages/messages/frame.html.php | 57 -- src/views/pages/messages/index.html.php | 25 - src/views/pages/no-conf.html.php | 8 - src/views/pages/plugins/401.html.php | 9 - src/views/pages/plugins/index.html.php | 42 -- src/views/pages/users/401.html.php | 15 - src/views/pages/users/404.html.php | 10 - src/views/pages/users/500.html.php | 15 - src/views/pages/users/created.html.php | 18 - src/views/pages/users/index.csv.php | 27 - src/views/pages/users/index.html.php | 104 ---- src/views/pages/users/individual.html.php | 147 ----- src/views/pages/users/new-locked.html.php | 9 - src/views/pages/users/new-logged-in.html.php | 8 - src/views/pages/users/new.html.php | 57 -- 121 files changed, 4336 insertions(+), 5794 deletions(-) create mode 100644 apps/um/controllers/Authenticator.class.php create mode 100644 apps/um/controllers/Config.class.php create mode 100644 apps/um/controllers/Groups.class.php create mode 100644 apps/um/controllers/Http404.class.php create mode 100644 apps/um/controllers/Main.class.php create mode 100644 apps/um/controllers/Plugins.class.php create mode 100644 apps/um/controllers/Users.class.php create mode 100644 apps/um/ext/PasswordHash.class.php create mode 100644 apps/um/ext/README.txt create mode 100644 apps/um/ext/recaptchalib.php create mode 100644 apps/um/lib/DB.class.php create mode 100644 apps/um/lib/Database.class.php create mode 100644 apps/um/lib/Hasher.class.php create mode 100644 apps/um/lib/Login.class.php create mode 100644 apps/um/lib/Plugin.class.php create mode 100644 apps/um/lib/PluginManager.class.php create mode 100644 apps/um/lib/Singleton.class.php create mode 100644 apps/um/lib/Site.class.php create mode 100644 apps/um/models/Auth.class.php create mode 100644 apps/um/models/ContactMethod.class.php create mode 100644 apps/um/models/Group.class.php create mode 100644 apps/um/models/User.class.php create mode 100644 apps/um/plugins/InformationPlugin.class.php create mode 100644 apps/um/plugins/ReCaptcha.class.php create mode 100644 apps/um/views/Template.class.php create mode 100644 apps/um/views/includes/header-include.php create mode 100644 apps/um/views/includes/header.php create mode 100644 apps/um/views/pages/auth/badrequest.html.php create mode 100644 apps/um/views/pages/auth/index.html.php create mode 100644 apps/um/views/pages/auth/login.html.php create mode 100644 apps/um/views/pages/auth/logout.html.php create mode 100644 apps/um/views/pages/groups/401.html.php create mode 100644 apps/um/views/pages/http404.html.php create mode 100644 apps/um/views/pages/index.html.php create mode 100644 apps/um/views/pages/plugins/401.html.php create mode 100644 apps/um/views/pages/plugins/index.html.php create mode 100644 apps/um/views/pages/users/401.html.php create mode 100644 apps/um/views/pages/users/404.html.php create mode 100644 apps/um/views/pages/users/500.html.php create mode 100644 apps/um/views/pages/users/created.html.php create mode 100644 apps/um/views/pages/users/index.csv.php create mode 100644 apps/um/views/pages/users/index.html.php create mode 100644 apps/um/views/pages/users/individual.html.php create mode 100644 apps/um/views/pages/users/individual.json.php create mode 100644 apps/um/views/pages/users/new-locked.html.php create mode 100644 apps/um/views/pages/users/new-logged-in.html.php create mode 100644 apps/um/views/pages/users/new.html.php create mode 100644 lpf/ext/HTTP_Accept.class.php create mode 100644 lpf/ext/README.txt create mode 100644 lpf/lib/Controller.class.php create mode 100644 lpf/lib/Mime.class.php create mode 100644 lpf/lib/Model.class.php create mode 100644 lpf/lib/Router.class.php create mode 100644 lpf/lib/View.class.php create mode 100644 lpf/views/pages/no-conf.html.php delete mode 100644 src/controllers/AuthPage.class.php delete mode 100644 src/controllers/Config.class.php delete mode 100644 src/controllers/Groups.class.php delete mode 100644 src/controllers/Http404.class.php delete mode 100644 src/controllers/Main.class.php delete mode 100644 src/controllers/Messages.class.php delete mode 100644 src/controllers/NewMessage.class.php delete mode 100644 src/controllers/Plugins.class.php delete mode 100644 src/controllers/Users.class.php delete mode 100644 src/ext/GoogleVoice.class.php delete mode 100644 src/ext/HTTP_Accept.class.php delete mode 100644 src/ext/Identica.class.php delete mode 100644 src/ext/MimeMailParser.class.php delete mode 100644 src/ext/MimeMailParser_attachment.class.php delete mode 100644 src/ext/PasswordHash.class.php delete mode 100644 src/ext/README.txt delete mode 100644 src/ext/recaptchalib.php delete mode 100644 src/lib/Controller.class.php delete mode 100644 src/lib/DB.class.php delete mode 100644 src/lib/Database.class.php delete mode 100644 src/lib/Hasher.class.php delete mode 100644 src/lib/Login.class.php delete mode 100644 src/lib/Mime.class.php delete mode 100644 src/lib/Model.class.php delete mode 100644 src/lib/Plugin.class.php delete mode 100644 src/lib/PluginManager.class.php delete mode 100644 src/lib/Router.class.php delete mode 100644 src/lib/Singleton.class.php delete mode 100644 src/lib/Site.class.php delete mode 100644 src/lib/View.class.php delete mode 100644 src/models/Auth.class.php delete mode 100644 src/models/ContactMethod.class.php delete mode 100644 src/models/Group.class.php delete mode 100644 src/models/User.class.php delete mode 100644 src/plugins/InformationPlugin.class.php delete mode 100644 src/plugins/ReCaptcha.class.php delete mode 100644 src/plugins/SenderGVSMS.class.php delete mode 100644 src/plugins/SenderIdentica.class.php delete mode 100644 src/plugins/maildir.php delete mode 100644 src/views/Template.class.php delete mode 100644 src/views/includes/header-include.php delete mode 100644 src/views/includes/header.php delete mode 100644 src/views/pages/auth/badrequest.html.php delete mode 100644 src/views/pages/auth/index.html.php delete mode 100644 src/views/pages/auth/login.html.php delete mode 100644 src/views/pages/auth/logout.html.php delete mode 100644 src/views/pages/groups/401.html.php delete mode 100644 src/views/pages/http404.html.php delete mode 100644 src/views/pages/index.html.php delete mode 100644 src/views/pages/messages/401.html.php delete mode 100644 src/views/pages/messages/frame.html.php delete mode 100644 src/views/pages/messages/index.html.php delete mode 100644 src/views/pages/no-conf.html.php delete mode 100644 src/views/pages/plugins/401.html.php delete mode 100644 src/views/pages/plugins/index.html.php delete mode 100644 src/views/pages/users/401.html.php delete mode 100644 src/views/pages/users/404.html.php delete mode 100644 src/views/pages/users/500.html.php delete mode 100644 src/views/pages/users/created.html.php delete mode 100644 src/views/pages/users/index.csv.php delete mode 100644 src/views/pages/users/index.html.php delete mode 100644 src/views/pages/users/individual.html.php delete mode 100644 src/views/pages/users/new-locked.html.php delete mode 100644 src/views/pages/users/new-logged-in.html.php delete mode 100644 src/views/pages/users/new.html.php diff --git a/apps/um/controllers/Authenticator.class.php b/apps/um/controllers/Authenticator.class.php new file mode 100644 index 0000000..0c1bf0c --- /dev/null +++ b/apps/um/controllers/Authenticator.class.php @@ -0,0 +1,57 @@ +login(); break; + case 'logout': $this->logout(); break; + case '' : $this->maybe_login(); break; + default : $this->badrequest(); break; + } + } + private function login() { + $username = ''; + $password = ''; + + $login = -1; + if ( isset($_POST['username']) && isset($_POST['password'])) { + $username = $_POST['username']; + $password = $_POST['password']; + $login = Login::login($username, $password); + } + + $vars = array(); + $vars['login_code'] = $login; + $vars['username'] = $username; + $vars['password'] = $password; + if (isset($_POST['url'])) { + $vars['url'] = $_POST['url']; + } + + $this->showView('auth/login', $vars); + } + private function logout() { + Login::logout(); + $this->showView('auth/logout'); + } + private function maybe_login() { + $uid = Login::isLoggedIn(); + if ($uid===false) { + $this->login(); + } else { + $username = Auth::getInstance($uid)->getName(); + $this->showView('auth/index', + array('username'=>$username)); + } + } + private function badrequest() { + $this->showView('auth/badrequest'); + } +} diff --git a/apps/um/controllers/Config.class.php b/apps/um/controllers/Config.class.php new file mode 100644 index 0000000..dc6a884 --- /dev/null +++ b/apps/um/controllers/Config.class.php @@ -0,0 +1,30 @@ +isAdmin()) { + $this->http401($routed, $remainder); + return; + } + + $method = $_SERVER['REQUEST_METHOD']; + switch ($method) { + case 'PUT': $_POST = $_PUT; + case 'POST': + // We're PUTing an updated configuration. + $this->update(); + break; + } + $this->show_index(); + } + private function show_index() { + + } + private function update() { + + } +} diff --git a/apps/um/controllers/Groups.class.php b/apps/um/controllers/Groups.class.php new file mode 100644 index 0000000..9d99d99 --- /dev/null +++ b/apps/um/controllers/Groups.class.php @@ -0,0 +1,11 @@ +http404($routed, $remainder); + } +} diff --git a/apps/um/controllers/Main.class.php b/apps/um/controllers/Main.class.php new file mode 100644 index 0000000..7651b62 --- /dev/null +++ b/apps/um/controllers/Main.class.php @@ -0,0 +1,9 @@ +showView('index'); + } +} diff --git a/apps/um/controllers/Plugins.class.php b/apps/um/controllers/Plugins.class.php new file mode 100644 index 0000000..2ed6e7a --- /dev/null +++ b/apps/um/controllers/Plugins.class.php @@ -0,0 +1,75 @@ +isAdmin()) { + $this->http401($routed, $remainder); + return; + } + + $method = $_SERVER['REQUEST_METHOD']; + switch ($method) { + case 'PUT': $_POST = $_PUT; + case 'POST': + // We're PUTing an updated user index. + $this->update(); + break; + } + $this->show_index(); + } + + private function update() { + $db = Database::getInstance(); + + if (isset($_POST['plugins'])) { + $string = $db->arrayToValue($_POST['plugins']); + $db->setSysConf('plugins', $string); + } + + if (isset($_POST['config'])) { + foreach ($_POST['config'] as $plugin_name => $plugin) { + foreach ($plugin as $param => $value) { + $db->setPluginConf($plugin_name, + $param, + $value); + } + } + } + } + + private function show_index() { + $pm = PluginManager::getInstance(); + $all_plugins = $pm->listPlugins(); + $enabled_plugins = $pm->getActivePlugins(); + + $plugin_data = array(); + foreach ($all_plugins as $plugin_name) { + $plugin = array(); + $plugin['name'] = $plugin_name; + $plugin['key'] = 'config['.$plugin_name.']'; + $plugin['active'] = + in_array($plugin_name, $enabled_plugins); + $plugin['description'] = + $pm->staticHook($plugin_name, 'description'); + $plugin['config'] = + $pm->staticHook($plugin_name, 'configList'); + $plugin_data[] = $plugin; + } + + $vars = array(); + $vars['plugins'] = $plugin_data; + $this->showView('plugins/index', $vars); + } + + public function http401($routed, $remainder) { + $this->showView('plugins/401'); + } +} diff --git a/apps/um/controllers/Users.class.php b/apps/um/controllers/Users.class.php new file mode 100644 index 0000000..9978ef8 --- /dev/null +++ b/apps/um/controllers/Users.class.php @@ -0,0 +1,371 @@ +index_dir($routed, $remainder); + } + + /** + * Handle POSTing a new user, or GETing the index. + */ + public function index_dir($routed, $remainder) { + $method = $_SERVER['REQUEST_METHOD']; + switch ($method) { + case 'POST': + // We're POSTing a new user. + if ($this->registrationOpen()) { + $this->create_user(); + } else { + $this->showView('users/new-locked', array()); + exit(); + } + break; + case 'HEAD': // fall-through to GET + case 'GET': + // We're GETing the index. + $this->show_index($routed, $remainder); + break; + } + } + + /** + * Handle PUTing an updated user index, or GETing the index. + */ + public function index_file($routed, $remainder) { + $method = $_SERVER['REQUEST_METHOD']; + switch ($method) { + case 'PUT': $_POST = $_PUT; + case 'POST': + // We're PUTing an updated user index. + $this->update_users(); + break; + } + $this->show_index($routed, $remainder); + } + + // Other Views /////////////////////////////////////////////// + + /** + * Handle GETing the new user form. + * + * I would have named this `new', but that's a keyword. + */ + public function new_user($routed, $vars) { + // since there will never be a remainder to `users/new', we can + // use that parameter to pass in some data. + if (Login::isLoggedIn()) { + $this->showView('users/new-logged-in', array()); + exit(); + } + if (!$this->registrationOpen()) { + $this->showView('users/new-locked', array()); + exit(); + } + if (!isset($vars['errors'])) $vars['errors'] = array(); + + $db = Database::getInstance(); + $pm = PluginManager::getInstance(); + + $vars['antispam_html'] = $pm->callHook('antispam_html'); + $vars['userlist'] = $db->getSysConf('anon_userlist'); + $this->showView('users/new', $vars); + } + + public function individual($routed, $remainder) { + $db = Database::getInstance(); + $pm = PluginManager::getInstance(); + + $username = implode('/', $remainder); + if ($username == 'all') { + $uids = $db->listUsers(); + } else { + $uids = array($db->getUID($username)); + } + + $vars = array(); + + if (count($uids)<2) { + $user = Auth::getInstance($uid); + + if ($user->isGroup()) $uid = false; // ignore groups. + + if ($uid===false) { + $this->http404($routed, $remainder); + exit(); + } + if (!$user->canRead()) { + $this->http401($routed, $remainder); + exit(); + } + + $method = $_SERVER['REQUEST_METHOD']; + switch ($method) { + case 'PUT': $_POST = $_PUT; + case 'POST': + // We're PUTing updated user info. + if ($user->canEdit()) { + $vars = $this->update_user($user); + } + break; + } + } + + $config_options = array(); + $pm->callHook('userConfig', &$config_options); + + $vars['users'] = array(); + foreach ($uids as $uid) { + $vars['users'][] = Auth::getInstance($uid); + } + $vars['username'] = $username; + $vars['config_options'] = $config_options; + $vars['groups'] = $db->listGroupNames(); + require_once('ContactMethod.class.php'); + $this->showView('users/individual', $vars); + } + + public function http404($routed, $remainder) { + $username = implode('/', $remainder); + $this->showView('users/404', + array('username'=>$username)); + } + + public function http401($routed, $remainder) { + $this->showView('users/401', array('uid'=>Login::isLoggedIn())); + } + + // Other Functions /////////////////////////////////////////// + + /** + * This will parse POST data to create a new user. + * If successfull it will show a message saying so. + * If not successfull, it will re-show the new-user form with errors + * explained. + */ + private function create_user() { + $db = Database::getInstance(); + $pm = PluginManager::getInstance(); + + $vars = array(); + @$vars['username' ] = $_POST['auth_name']; + @$vars['password1'] = $_POST['auth_password' ]; + @$vars['password2'] = $_POST['auth_password_verify']; + @$vars['email'] = $_POST['user_email']; + + $vars['errors'] = array(); + if ($db->getUID($vars['username'])!==false) + $vars['errors'][] = 'user exists'; + if (!Auth::isNameLegal($vars['username'])) + $vars['errors'][] = 'illegal name'; + $matches = ($vars['password1'] == $vars['password2']); + if (!$matches) { + $vars['errors'][] = 'pw mixmatch'; + } + if ($matches && $vars['password2'] == '') { + $vars['errors'][] = 'no pw'; + } + if ($vars['email'] == '') { + $vars['errors'][] = 'no email'; + } + foreach ($pm->callHook('antispam_verify') as $plugin=>$valid) { + if (!$valid) $vars['errors'][] = 'plugin_'.$plugin; + } + + if (count($vars['errors']) > 0) { + $this->new_user($routed, $vars); + } else { + $username = $vars['username']; + $password = $vars['password1']; + $uid = $db->addUser($username, $password); + if ($uid===false) { + $this->showView('users/500'); + } else { + Login::login($username, $password); + DB::set('users', $uid, 'email', $vars['email']); + $this->showView('users/created', + array('username'=>$username)); + } + } + } + + /** + * This will parse POST (really, PUT) data to update a single user + */ + private function update_user($user) { + $vars = array(); + + $username = $user->getName(); + // Change the username ///////////////////////////////////////// + if (isset($_POST['auth_name'])) { + $new_name = $_POST['auth_name']; + if ($new_name != $username) { + $changed_name = $user->setName($new_name); + $username = $user->getName(); + $vars['changed name'] = $changed_name; + } + } + + // Change the password ///////////////////////////////////////// + @$password1 = $_POST['auth_password' ]; + @$password2 = $_POST['auth_password'.'_verify']; + + // Check the verify box, not main box, so that we don't get + // tripped by browsers annoyingly autocompleting the password. + $is_set = ($password2 != ''); + + if ($is_set) { + $matches = ( $password1 == $password2 ); + if ($matches) { + $user->setPassword($password1); + $vars['pw updated'] = true; + } else { + $vars['pw mixmatch'] = true; + } + } + + // Change information ////////////////////////////////////////// + $config_options = array(); + $pm = PluginManager::getInstance(); + $pm->callHook('userConfig', &$config_options); + + foreach ($config_options as $group=>$options) { + foreach ($options as $option) { + $this->confText($user, $option[0]); + } + } + + // Change contact info ///////////////////////////////////////// + global $CONTACT_METHODS; + foreach ($CONTACT_METHODS as $method) { + $this->confText($user, $method->addr_slug); + } + $this->confArray($user, 'use'); + + // Change groups /////////////////////////////////////////////// + $this->confArray($user, 'groups'); + + return $vars; + } + + private function confArray($user, $key) { + if (isset($_POST[$key]) && is_array($_POST[$key])) { + $user->setConfArray($key, $_POST[$key]); + } + } + + private function confText($user, $name) { + if (isset($_POST["user_$name"])) { + $user->setConf($name, $_POST["user_$name"]); + } + } + + + /** + * This will parse POST (really, PUT) data to update multiple users. + */ + private function update_users() { + $attribs = $this->getIndexAttribs(); + $form = new Form(null, null); + foreach ($attribs as $attrib) { + $key = $attrib['key']; + if (isset($_POST[$key]) && is_array($_POST[$key])) { + $old = $_POST['_old'][$key]; + foreach ($_POST[$key] as $uid => $value) { + @$value_base = $old[$uid]; + $set = DB::set('users', $uid, $key, $value, $value_base); + if (is_string($set)) { + echo "
\n";
+						echo "Error: Value changed elsewhere, ".
+							"and I don't have real handling ".
+							"for this yet.\n";
+						echo "UID: $uid\n";
+						echo "Name: ".$user->getName()."\n";
+						echo "Key: $key\n";
+						echo "Value: Original  : ";
+						var_dump($value_base);
+						echo "Value: Other edit: ";
+						var_dump($value_fork);
+						echo "Value: This edit : ";
+						var_dump($value);
+						echo "
"; + } + } + } + } + } + + /** + * This will show the user index. + */ + private function show_index($routed, $remainder) { + $db = Database::getInstance(); + + $logged_in_user = Auth::getInstance(Login::isLoggedIn()); + $anon_userlist = $db->getSysConf('anon_userlist')=='true'; + if (!$anon_userlist && !$logged_in_user->isUser()) { + $this->http401($routed, $remainder); + exit(); + } + + $vars = array(); + $vars['attribs'] = $this->getIndexAttribs(); + $vars['users'] = array(); + $uids = $db->listUsers(); + foreach ($uids as $uid) { + $vars['users'][$uid] = array(); + foreach ($vars['attribs'] as $attrib) { + $key = $attrib['key']; + $props = DB::get('users', $uid, $key); + $vars['users'][$uid][$key] = $props; + } + } + $this->showView('users/index', $vars); + } + + function attrib($key, $name, $type='string') { + return array('key'=>$key, 'name'=>$name, 'type'=>$type); + } + private function getIndexAttribs() { + $user = Auth::getInstance(Login::isLoggedIn()); + + $attribs = array(); + $attribs[] = $this->attrib('auth_uid', 'UID'); + if ($user->isUser()) { + $attribs[] = $this->attrib('auth_user', 'Active', 'bool'); + if ($user->isAdmin()) { + $attribs[] = $this->attrib('auth_admin', 'Admin', 'bool'); + $attribs[] = $this->attrib('auth_delete', 'Delete', 'bool'); + } + $attribs[] = $this->attrib('lastname','Last'); + $attribs[] = $this->attrib('firstname','First'); + $attribs[] = $this->attrib('hsclass','Class of'); + $attribs[] = $this->attrib('phone','Phone number'); + $attribs[] = $this->attrib('email','Email'); + } + $attribs[] = $this->attrib('auth_name', 'Username'); + + return $attribs; + } + + private function registrationOpen() { + $db = Database::getInstance(); + $val = $db->getSysConf('registration_open'); + switch ($val) { + case 'true': return true; + case 'false': return false; + default: return true; + } + } +} diff --git a/apps/um/ext/PasswordHash.class.php b/apps/um/ext/PasswordHash.class.php new file mode 100644 index 0000000..12958c7 --- /dev/null +++ b/apps/um/ext/PasswordHash.class.php @@ -0,0 +1,253 @@ + in 2004-2006 and placed in +# the public domain. Revised in subsequent years, still public domain. +# +# There's absolutely no warranty. +# +# The homepage URL for this framework is: +# +# http://www.openwall.com/phpass/ +# +# Please be sure to update the Version line if you edit this file in any way. +# It is suggested that you leave the main version number intact, but indicate +# your project name (after the slash) and add your own revision information. +# +# Please do not change the "private" password hashing method implemented in +# here, thereby making your hashes incompatible. However, if you must, please +# change the hash type identifier (the "$P$") to something different. +# +# Obviously, since this code is in the public domain, the above are not +# requirements (there can be none), but merely suggestions. +# +class PasswordHash { + var $itoa64; + var $iteration_count_log2; + var $portable_hashes; + var $random_state; + + function PasswordHash($iteration_count_log2, $portable_hashes) + { + $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + + if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) + $iteration_count_log2 = 8; + $this->iteration_count_log2 = $iteration_count_log2; + + $this->portable_hashes = $portable_hashes; + + $this->random_state = microtime(); + if (function_exists('getmypid')) + $this->random_state .= getmypid(); + } + + function get_random_bytes($count) + { + $output = ''; + if (is_readable('/dev/urandom') && + ($fh = @fopen('/dev/urandom', 'rb'))) { + $output = fread($fh, $count); + fclose($fh); + } + + if (strlen($output) < $count) { + $output = ''; + for ($i = 0; $i < $count; $i += 16) { + $this->random_state = + md5(microtime() . $this->random_state); + $output .= + pack('H*', md5($this->random_state)); + } + $output = substr($output, 0, $count); + } + + return $output; + } + + function encode64($input, $count) + { + $output = ''; + $i = 0; + do { + $value = ord($input[$i++]); + $output .= $this->itoa64[$value & 0x3f]; + if ($i < $count) + $value |= ord($input[$i]) << 8; + $output .= $this->itoa64[($value >> 6) & 0x3f]; + if ($i++ >= $count) + break; + if ($i < $count) + $value |= ord($input[$i]) << 16; + $output .= $this->itoa64[($value >> 12) & 0x3f]; + if ($i++ >= $count) + break; + $output .= $this->itoa64[($value >> 18) & 0x3f]; + } while ($i < $count); + + return $output; + } + + function gensalt_private($input) + { + $output = '$P$'; + $output .= $this->itoa64[min($this->iteration_count_log2 + + ((PHP_VERSION >= '5') ? 5 : 3), 30)]; + $output .= $this->encode64($input, 6); + + return $output; + } + + function crypt_private($password, $setting) + { + $output = '*0'; + if (substr($setting, 0, 2) == $output) + $output = '*1'; + + $id = substr($setting, 0, 3); + # We use "$P$", phpBB3 uses "$H$" for the same thing + if ($id != '$P$' && $id != '$H$') + return $output; + + $count_log2 = strpos($this->itoa64, $setting[3]); + if ($count_log2 < 7 || $count_log2 > 30) + return $output; + + $count = 1 << $count_log2; + + $salt = substr($setting, 4, 8); + if (strlen($salt) != 8) + return $output; + + # We're kind of forced to use MD5 here since it's the only + # cryptographic primitive available in all versions of PHP + # currently in use. To implement our own low-level crypto + # in PHP would result in much worse performance and + # consequently in lower iteration counts and hashes that are + # quicker to crack (by non-PHP code). + if (PHP_VERSION >= '5') { + $hash = md5($salt . $password, TRUE); + do { + $hash = md5($hash . $password, TRUE); + } while (--$count); + } else { + $hash = pack('H*', md5($salt . $password)); + do { + $hash = pack('H*', md5($hash . $password)); + } while (--$count); + } + + $output = substr($setting, 0, 12); + $output .= $this->encode64($hash, 16); + + return $output; + } + + function gensalt_extended($input) + { + $count_log2 = min($this->iteration_count_log2 + 8, 24); + # This should be odd to not reveal weak DES keys, and the + # maximum valid value is (2**24 - 1) which is odd anyway. + $count = (1 << $count_log2) - 1; + + $output = '_'; + $output .= $this->itoa64[$count & 0x3f]; + $output .= $this->itoa64[($count >> 6) & 0x3f]; + $output .= $this->itoa64[($count >> 12) & 0x3f]; + $output .= $this->itoa64[($count >> 18) & 0x3f]; + + $output .= $this->encode64($input, 3); + + return $output; + } + + function gensalt_blowfish($input) + { + # This one needs to use a different order of characters and a + # different encoding scheme from the one in encode64() above. + # We care because the last character in our encoded string will + # only represent 2 bits. While two known implementations of + # bcrypt will happily accept and correct a salt string which + # has the 4 unused bits set to non-zero, we do not want to take + # chances and we also do not want to waste an additional byte + # of entropy. + $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + $output = '$2a$'; + $output .= chr(ord('0') + $this->iteration_count_log2 / 10); + $output .= chr(ord('0') + $this->iteration_count_log2 % 10); + $output .= '$'; + + $i = 0; + do { + $c1 = ord($input[$i++]); + $output .= $itoa64[$c1 >> 2]; + $c1 = ($c1 & 0x03) << 4; + if ($i >= 16) { + $output .= $itoa64[$c1]; + break; + } + + $c2 = ord($input[$i++]); + $c1 |= $c2 >> 4; + $output .= $itoa64[$c1]; + $c1 = ($c2 & 0x0f) << 2; + + $c2 = ord($input[$i++]); + $c1 |= $c2 >> 6; + $output .= $itoa64[$c1]; + $output .= $itoa64[$c2 & 0x3f]; + } while (1); + + return $output; + } + + function HashPassword($password) + { + $random = ''; + + if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) { + $random = $this->get_random_bytes(16); + $hash = + crypt($password, $this->gensalt_blowfish($random)); + if (strlen($hash) == 60) + return $hash; + } + + if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) { + if (strlen($random) < 3) + $random = $this->get_random_bytes(3); + $hash = + crypt($password, $this->gensalt_extended($random)); + if (strlen($hash) == 20) + return $hash; + } + + if (strlen($random) < 6) + $random = $this->get_random_bytes(6); + $hash = + $this->crypt_private($password, + $this->gensalt_private($random)); + if (strlen($hash) == 34) + return $hash; + + # Returning '*' on error is safe here, but would _not_ be safe + # in a crypt(3)-like function used _both_ for generating new + # hashes and for validating passwords against existing hashes. + return '*'; + } + + function CheckPassword($password, $stored_hash) + { + $hash = $this->crypt_private($password, $stored_hash); + if ($hash[0] == '*') + $hash = crypt($password, $stored_hash); + + return $hash == $stored_hash; + } +} + +?> diff --git a/apps/um/ext/README.txt b/apps/um/ext/README.txt new file mode 100644 index 0000000..78c4f70 --- /dev/null +++ b/apps/um/ext/README.txt @@ -0,0 +1,12 @@ +These are class files that I've gathered from around the internet. + +I've renamed the files to follow a standard scheme. + +This is where each file came from: + +My Name : Original Name : From +PasswordHash.class.php : PasswordHash.php : http://www.openwall.com/phpass/ +recaptchalib.php : recaptchalib.php : https://code.google.com/p/recaptcha/ + +~ Luke Shumaker +Happy Hacking! diff --git a/apps/um/ext/recaptchalib.php b/apps/um/ext/recaptchalib.php new file mode 100644 index 0000000..32c4f4d --- /dev/null +++ b/apps/um/ext/recaptchalib.php @@ -0,0 +1,277 @@ + $value ) + $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; + + // Cut the last '&' + $req=substr($req,0,strlen($req)-1); + return $req; +} + + + +/** + * Submits an HTTP POST to a reCAPTCHA server + * @param string $host + * @param string $path + * @param array $data + * @param int port + * @return array response + */ +function _recaptcha_http_post($host, $path, $data, $port = 80) { + + $req = _recaptcha_qsencode ($data); + + $http_request = "POST $path HTTP/1.0\r\n"; + $http_request .= "Host: $host\r\n"; + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; + $http_request .= "Content-Length: " . strlen($req) . "\r\n"; + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; + $http_request .= "\r\n"; + $http_request .= $req; + + $response = ''; + if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { + die ('Could not open socket'); + } + + fwrite($fs, $http_request); + + while ( !feof($fs) ) + $response .= fgets($fs, 1160); // One TCP-IP packet + fclose($fs); + $response = explode("\r\n\r\n", $response, 2); + + return $response; +} + + + +/** + * Gets the challenge HTML (javascript and non-javascript version). + * This is called from the browser, and the resulting reCAPTCHA HTML widget + * is embedded within the HTML form it was called from. + * @param string $pubkey A public key for reCAPTCHA + * @param string $error The error given by reCAPTCHA (optional, default is null) + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) + + * @return string - The HTML to be embedded in the user's form. + */ +function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) +{ + if ($pubkey == null || $pubkey == '') { + die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } + + if ($use_ssl) { + $server = RECAPTCHA_API_SECURE_SERVER; + } else { + $server = RECAPTCHA_API_SERVER; + } + + $errorpart = ""; + if ($error) { + $errorpart = "&error=" . $error; + } + return ' + + '; +} + + + + +/** + * A ReCaptchaResponse is returned from recaptcha_check_answer() + */ +class ReCaptchaResponse { + var $is_valid; + var $error; +} + + +/** + * Calls an HTTP POST function to verify if the user's guess was correct + * @param string $privkey + * @param string $remoteip + * @param string $challenge + * @param string $response + * @param array $extra_params an array of extra variables to post to the server + * @return ReCaptchaResponse + */ +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) +{ + if ($privkey == null || $privkey == '') { + die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); + } + + if ($remoteip == null || $remoteip == '') { + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); + } + + + + //discard spam submissions + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { + $recaptcha_response = new ReCaptchaResponse(); + $recaptcha_response->is_valid = false; + $recaptcha_response->error = 'incorrect-captcha-sol'; + return $recaptcha_response; + } + + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", + array ( + 'privatekey' => $privkey, + 'remoteip' => $remoteip, + 'challenge' => $challenge, + 'response' => $response + ) + $extra_params + ); + + $answers = explode ("\n", $response [1]); + $recaptcha_response = new ReCaptchaResponse(); + + if (trim ($answers [0]) == 'true') { + $recaptcha_response->is_valid = true; + } + else { + $recaptcha_response->is_valid = false; + $recaptcha_response->error = $answers [1]; + } + return $recaptcha_response; + +} + +/** + * gets a URL where the user can sign up for reCAPTCHA. If your application + * has a configuration page where you enter a key, you should provide a link + * using this function. + * @param string $domain The domain where the page is hosted + * @param string $appname The name of your application + */ +function recaptcha_get_signup_url ($domain = null, $appname = null) { + return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); +} + +function _recaptcha_aes_pad($val) { + $block_size = 16; + $numpad = $block_size - (strlen ($val) % $block_size); + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); +} + +/* Mailhide related code */ + +function _recaptcha_aes_encrypt($val,$ky) { + if (! function_exists ("mcrypt_encrypt")) { + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); + } + $mode=MCRYPT_MODE_CBC; + $enc=MCRYPT_RIJNDAEL_128; + $val=_recaptcha_aes_pad($val); + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); +} + + +function _recaptcha_mailhide_urlbase64 ($x) { + return strtr(base64_encode ($x), '+/', '-_'); +} + +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ +function recaptcha_mailhide_url($pubkey, $privkey, $email) { + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . + "you can do so at http://www.google.com/recaptcha/mailhide/apikey"); + } + + + $ky = pack('H*', $privkey); + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); + + return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); +} + +/** + * gets the parts of the email to expose to the user. + * eg, given johndoe@example,com return ["john", "example.com"]. + * the email is then displayed as john...@example.com + */ +function _recaptcha_mailhide_email_parts ($email) { + $arr = preg_split("/@/", $email ); + + if (strlen ($arr[0]) <= 4) { + $arr[0] = substr ($arr[0], 0, 1); + } else if (strlen ($arr[0]) <= 6) { + $arr[0] = substr ($arr[0], 0, 3); + } else { + $arr[0] = substr ($arr[0], 0, 4); + } + return $arr; +} + +/** + * Gets html to display an email address given a public an private key. + * to get a key, go to: + * + * http://www.google.com/recaptcha/mailhide/apikey + */ +function recaptcha_mailhide_html($pubkey, $privkey, $email) { + $emailparts = _recaptcha_mailhide_email_parts ($email); + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); + + return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); + +} + + +?> diff --git a/apps/um/lib/DB.class.php b/apps/um/lib/DB.class.php new file mode 100644 index 0000000..ac8dafe --- /dev/null +++ b/apps/um/lib/DB.class.php @@ -0,0 +1,164 @@ +getConfString($key); + $someone_else_changed_it = + $value_fork != $value_base; + if ($someone_else_changed_it) { + if ($value == $value_fork) { + // we might as well not have + $we_changed_it = false; + } else { + $forked = true; + } + } + } + if (!$we_changed_it) { + $doit = false;// nothing to do + } + } + if ($doit) { + return $this->setConf($key, $value); + } + if ($forked) { + return $value_fork; + } + } + + public static function get($table, $unit, $key) { + switch ($table) { + case 'conf': + case 'plugins': + return self::admin_get($unit, $key); + break; + case 'users': + return self::user_get($unit, $key); + break; + default: + return false; + } + } + public static function raw_set($table, $unit, $key, $value) { + switch ($table) { + case 'conf': + case 'plugins': + return self::admin_get($unit, $key, $value); + break; + case 'users': + return self::user_set($unit, $key, $value); + break; + default: + return false; + } + } + + private static function user_get($uid, $key) { + $user = Auth::getInstance($uid); + $logged_in_user = Auth::getInstance(Login::isLoggedIn()); + + $post_key = $key."[$uid]"; + @$value = $_POST[$post_key]; + $editable = $user->canEdit(); + + switch ($key) { + case 'auth_uid': + $value = $user->getUID(); + $editable = false; + break; + case 'auth_name': + $value = $user->getName(); + break; + case 'auth_user': + $editable = $editable && $logged_in_user->isAdmin(); + $value = $user->isUser()?'true':'false'; + break; + case 'auth_admin': + $editable = $editable && $logged_in_user->isAdmin(); + $value = $user->isAdmin()?'true':'false'; + break; + case 'auth_delete': + $editable = $editable && $logged_in_user->isAdmin(); + $value = 'false'; + break; + default: + $value = $user->getConf($key); + if ($value===false) $value=''; + break; + } + + return array('value'=>$value, + 'post_key'=>$post_key, + 'editable'=>$editable); + } + private static function user_set($uid, $key, $value) { + $user = Auth::getInstance($uid); + + switch ($key) { + case 'auth_uid': + return false; + break; + case 'auth_name': + return $user->setName($value); + break; + case 'auth_user': + return $user->setUser($value=='true'); + break; + case 'auth_admin': + return $user->setAdmin($value=='true'); + break; + case 'auth_delete': + if ($value=='true') return $user->delete(); + default: + return $user->setConf($key, $value); + break; + } + } + + private static function admin_get($plugin, $key) { + $db = Database::getInstance(); + $user = Auth::getInstance(Login::isLoggedIn()); + if ($user->isAdmin()) { + $editable = true; + switch ($plugin) { + case 'system': + $value = $db->getSysConf($key); + break; + default: + $value = $db->getPluginConf($plugin, $key); + break; + } + } else { + $editable = false; + $value = false; + } + + return array('value'=>$value, + 'post_key'=>'to be implemented',// FIXME + 'editable'=>$editable); + } + private static function admin_set($plugin, $key, $value) { + $db = Database::getInstance(); + $user = Auth::getInstance(Login::isLoggedIn()); + if (!$user->isAdmin()) { + return false; + } + switch ($plugin) { + case 'system': + return $db->setSysConf($key, $value); + default: + return $db->setPluginConf($plugin, $key, $value); + } + } +} diff --git a/apps/um/lib/Database.class.php b/apps/um/lib/Database.class.php new file mode 100644 index 0000000..a76d891 --- /dev/null +++ b/apps/um/lib/Database.class.php @@ -0,0 +1,403 @@ +conf = $conf_file; + self::$me = $this; + } + public static function getInstance() { + return self::$me; + } + + // Low-Level SQL functions ///////////////////////////////////////////// + + private function mysql() { + if (!isset($this->mysql)) { + $this->mysql_init(); + } + return $this->mysql; + } + private function mysql_init() { + global $db_config; + require($this->conf); + $this->mysql = mysql_connect($db_config['host'], + $db_config['user'], + $db_config['password']); + mysql_set_charset($db_config['charset'], $this->mysql); + mysql_select_db($db_config['name'], $this->mysql); + $this->db_prefix = $db_config['prefix']; + unset($db_config); + } + private function mysql_table($table_name) { + $mysql = $this->mysql(); + $prefix = $this->db_prefix; + return $prefix.mysql_real_escape_string($table_name, $mysql); + } + private function mysql_escape($string) { + $mysql = $this->mysql(); + return mysql_real_escape_string($string, $mysql); + } + private function mysql_query($query) { + $mysql = $this->mysql(); + return mysql_query($query, $mysql); + } + public function mysql_error() { + $mysql = $this->mysql(); + return mysql_error($mysql); + } + + // High-Level SQL functions //////////////////////////////////////////// + + // The 'auth' table + + public function getUID($username) { + $t = $this->mysql_table('auth'); + $v = $this->mysql_escape($username); + $query = + "SELECT * \n". + "FROM $t \n". + "WHERE name='$v' ;"; + $q = $this->mysql_query($query); + $user = mysql_fetch_array($q); + if (isset($user['uid'])) { + return (int)$user['uid']; + } else { + return false; + } + } + public function getUsername($uid) { + if (!is_int($uid)) return false; + $t = $this->mysql_table('auth'); + $query = + "SELECT * \n". + "FROM $t \n". + "WHERE uid=$uid ;"; + $q = $this->mysql_query($query); + $user = mysql_fetch_array($q); + if (isset($user['name'])) { + return $user['name']; + } else { + return false; + } + } + public function setUsername($uid, $username) { + if (!is_int($uid)) return false; + if ($this->getUID($username) !== false) { + return false; + } + $table = $this->mysql_table('auth'); + $name = $this->mysql_escape($username); + $query = + "UPDATE $table \n". + "SET name='$name' \n". + "WHERE uid=$uid ;"; + $q = $this->mysql_query($query); + return ($q?true:false); + } + public function getPasswordHash($uid) { + if (!is_int($uid)) return false; + + $table = $this->mysql_table('auth'); + $query = + "SELECT * \n". + "FROM $table \n". + "WHERE uid=$uid ;"; + $q = $this->mysql_query($query); + $user = mysql_fetch_array($q); + if (isset($user['hash'])) { + return $user['hash']; + } else { + return false; + } + } + public function setPassword($uid, $password) { + if (!is_int($uid)) return false; + $table = $this->mysql_table('auth'); + + $hasher = Hasher::getInstance(); + @$hash = $hasher->hash($password); + $query = + "UPDATE $table \n". + "SET hash='$hash' \n". + "WHERE uid=$uid ;"; + $q = $this->mysql_query($query); + return ($q?true:false); + } + public function addUser($username, $password) { + $user_exits = $this->getUID($username); + if ($user_exists) { + return false; + } + + $table = $this->mysql_table('auth'); + $user = $this->mysql_escape($username); + $hasher = Hasher::getInstance(); + @$hash = $hasher->hash($password); + $status = 0; + $query = + "INSERT INTO $table ( name, hash , status) \n". + "VALUES ('$user', '$hash', $status) ;"; + $this->mysql_query($query); + $uid = $this->getUID($username); + return $uid; + } + public function getStatus($uid) { + if (!is_int($uid)) return false; + $table = $this->mysql_table('auth'); + $query = + "SELECT * \n". + "FROM $table \n". + "WHERE uid=$uid ;"; + $q = $this->mysql_query($query); + $user = mysql_fetch_array($q); + if (isset($user['status'])) { + return (int)$user['status']; + } else { + return false; + } + } + public function setStatus($uid, $status) { + if (!is_int($uid)) return false; + $table = $this->mysql_table('auth'); + $s = $this->mysql_escape($status); + $query = + "UPDATE $table \n". + "SET status=$s \n". + "WHERE uid=$uid ;"; + $q = $this->mysql_query($query); + return ($q?true:false); + } + public function countUsers() { + $table = $this->mysql_table('auth'); + $query = "SELECT COUNT(*) FROM $table;"; + $q = $this->mysql_query($query); + $row = mysql_fetch_array($q); + $count = $row[0]; + return $count; + } + public function listGroups() { + $table = $this->mysql_table('auth'); + $query = + "SELECT uid \n". + "FROM $table \n". + "WHERE status=3 ;"; + $q = $this->mysql_query($query); + $groups = array(); + while (($row = mysql_fetch_array($q)) !==false) { + $groups[] = (int)$row[0]; + } + return $groups; + } + public function listGroupNames() { + $table = $this->mysql_table('auth'); + $query = + "SELECT name \n". + "FROM $table \n". + "WHERE status=3 ;"; + $q = $this->mysql_query($query); + $groups = array(); + while (($row = mysql_fetch_array($q)) !==false) { + $groups[] = $row[0].''; + } + return $groups; + } + public function listUsers() { + $table = $this->mysql_table('auth'); + $query = + "SELECT uid \n". + "FROM $table \n". + "WHERE status < 3 ;"; + $q = $this->mysql_query($query); + $users = array(); + while (($row = mysql_fetch_array($q)) !==false) { + $users[] = (int)$row[0]; + } + return $users; + } + + // The 'users' table + + public function findUser($setting, $value) { + $t = $this->mysql_table('users'); + $k = $this->mysql_escape($setting); + $v = $this->mysql_escape($value); + $query = + "SELECT * \n". + "FROM $t \n". + "WHERE k = '$k' \n". + "AND UPPER(v)=UPPER('$v') ;"; + $q = $this->mysql_query($query); + $user = mysql_fetch_array($q); + if (isset($user['uid'])) { + return $user['uid']; + } else { + return false; + } + } + public function getUserConf($uid, $setting) { + if (!is_int($uid)) return false; + $t = $this->mysql_table('users'); + $k = $this->mysql_escape($setting); + $query = + "SELECT * \n". + "FROM $t \n". + "WHERE k='$k' \n". + "AND uid=$uid ;"; + $q = $this->mysql_query($query); + $row = mysql_fetch_array($q); + if (isset($row['v'])) { + return $row['v']; + } else { + return false; + } + } + public function setUserConf($uid, $setting, $value) { + if (!is_int($uid)) return false; + $isset = ($this->getUserConf($uid, $setting) !== false); + $t = $this->mysql_table('users'); + $k = $this->mysql_escape($setting); + $v = $this->mysql_escape($value); + if ($isset) { + $query = + "UPDATE $t \n". + "SET v = '$v' \n". + "WHERE k = '$k' \n". + "AND uid = $uid ;"; + } else { + $query = + "INSERT INTO $t ( uid, k , v ) \n". + "VALUES ($uid, '$k', '$v') ;"; + } + $q = $this->mysql_query($query); + return ($q?true:false); + } + public function getUsersInGroup($groupname) { + $table = $this->mysql_table('users'); + $group = $this->mysql_escape($groupname); + $query = + "SELECT uid \n". + "FROM $table \n". + "WHERE k='groups' \n". + "AND v LIKE '%,$group,%' ;"; + $q = $this->mysql_query($query); + $users = array(); + while (($row = mysql_fetch_array($q)) !==false) { + $users[] = $row[0]; + } + return $users; + } + + // The 'plugins' table + + public function getPluginConf($plugin, $key) { + $t = $this->mysql_table('plugins'); + $p = $this->mysql_escape($plugin); + $k = $this->mysql_escape($key); + $query = + "SELECT * \n". + "FROM $t \n". + "WHERE k='$k' \n". + "AND plugin='$p' ;"; + $q = $this->mysql_query($query); + $row = mysql_fetch_array($q); + if (isset($row['v'])) { + return $row['v']; + } else { + return false; + } + } + public function setPluginConf($plugin, $key, $value) { + $isset = ($this->getPluginConf($plugin, $key) !== false); + $t = $this->mysql_table('plugins'); + $p = $this->mysql_escape($plugin); + $k = $this->mysql_escape($key); + $v = $this->mysql_escape($value); + if ($isset) { + $query = + "UPDATE $t \n". + "SET v = '$v' \n". + "WHERE k = '$k' \n". + "AND plugin = '$p' ;"; + } else { + $query = + "INSERT INTO $t (plugin, k , v ) \n". + "VALUES ('$p' , '$k', '$v') ;"; + } + $q = $this->mysql_query($query); + return ($q?true:false); + } + + // The 'conf' table + + public function getSysConf($key) { + $t = $this->mysql_table('conf'); + $k = $this->mysql_escape($key); + $query = + "SELECT * \n". + "FROM $t \n". + "WHERE k='$k' ;"; + $q = $this->mysql_query($query); + $row = mysql_fetch_array($q); + if (isset($row['v'])) { + return $row['v']; + } else { + return false; + } + } + public function setSysConf($key, $value) { + $isset = ($this->getSysConf($key) !== false); + $t = $this->mysql_table('conf'); + $k = $this->mysql_escape($key); + $v = $this->mysql_escape($value); + if ($isset) { + $query = + "UPDATE $t \n". + "SET v = '$v' \n". + "WHERE k = '$k' ;"; + } else { + $query = + "INSERT INTO $t ( k , v ) \n". + "VALUES ('$k', '$v') ;"; + } + $q = $this->mysql_query($query); + return ($q?true:false); + } + + /** + * Strip out empty group names and duplicates, sort. + */ + private static function sanitizeArray($in) { + $out = array(); + foreach ($in as $item) { + if (($item !== '')&&(!in_array($item, $out))) { + $out[] = $item; + } + } + natsort($out); + return $out; + } + /** + * Translate an array into a value suitable to be stored into a + * key-value store in the database. + */ + public static function arrayToValue($list) { + $out_list = self::sanitizeArray($list); + return ','.implode(',', $out_list).','; + } + /** + * Translate a value from arrayToValue() back into an array. + */ + public static function valueToArray($value) { + $raw_list = explode(',', $value); + $out_list = self::sanitizeArray($raw_list); + return $out_list; + } + +} diff --git a/apps/um/lib/Hasher.class.php b/apps/um/lib/Hasher.class.php new file mode 100644 index 0000000..dc16d68 --- /dev/null +++ b/apps/um/lib/Hasher.class.php @@ -0,0 +1,18 @@ +pw_hash = new PasswordHash(8, false); + } + + public function hash($password) { + return $this->pw_hash->HashPassword($password); + } + public function check($password, $hash) { + return $this->pw_hash->CheckPassword($password, $hash); + } +} diff --git a/apps/um/lib/Login.class.php b/apps/um/lib/Login.class.php new file mode 100644 index 0000000..bb21928 --- /dev/null +++ b/apps/um/lib/Login.class.php @@ -0,0 +1,41 @@ +getUID($username); + if ($uid!==false && $db->getStatus($uid)>=3) + $uid=false; + if ($uid===false) { + // user does not exist + return 2; + } + $hash = $db->getPasswordHash($uid); + if ($hasher->check($password, $hash)) { + // success + $_SESSION['uid'] = $uid; + return 0; + } else { + // wrong password + return 1; + } + } + public static function isLoggedIn() { + if ( isset($_SESSION['uid']) && ($_SESSION['uid']!='') ) { + return $_SESSION['uid']; + } else { + return false; + } + } + public static function logout() { + $_SESSION['uid'] = ''; + } +} diff --git a/apps/um/lib/Plugin.class.php b/apps/um/lib/Plugin.class.php new file mode 100644 index 0000000..9d2fc2e --- /dev/null +++ b/apps/um/lib/Plugin.class.php @@ -0,0 +1,25 @@ +config[$param])) { + $this->config[$param]=$value; + } + } + + public function userConfig() { return array(); } + protected function addConfigGroup($arr, $group) { + if (!isset($arr[$group])) + $arr[$group] = array(); + } + + public abstract function init(); + + public function antispam_html() { return ''; } + public function antispam_verify() { return true; } +} diff --git a/apps/um/lib/PluginManager.class.php b/apps/um/lib/PluginManager.class.php new file mode 100644 index 0000000..ce5a3ef --- /dev/null +++ b/apps/um/lib/PluginManager.class.php @@ -0,0 +1,99 @@ + $type) { + $value = $db->getPluginConf($plugin_name, $param); + if ($value!==false) { + switch ($type) { + case 'text': + case 'password': + $value = "$value"; + break; + case 'int': + $value = (int)$value; + break; + } + $obj->configSet($param, $value); + } + } + return $obj; + } + + /** + * Return an array of available plugin names. + */ + public function listPlugins() { + $plugins = array(); + + $dirs = explode(PATH_SEPARATOR, PLUGINPATH); + foreach ($dirs as $dir) { + // Find all files in $dir with the ext `.class.php' + $files = glob($dir.'/*.class.php'); + foreach ($files as $file) { + $plugins[] = preg_replace('@\.class\.php$@', '$1', basename($file)); + } + } + + return $plugins; + } + + /** + * Return an array of enabled plugin names. + */ + public function getActivePlugins() { + $db = Database::getInstance(); + $string = $db->getSysConf('plugins'); + return $db->valueToArray($string); + } + + /** + * Set the enabled plugins. + */ + public function setActivePlugins($plugins) { + $db = Database::getInstance(); + $string = $db->arrayToValue($plugins); + return $db->setSysConf('plugins', $string); + } + + /** + * Load the enabled plugins. + */ + public function loadPlugins() { + if ($this->loaded) return; + $plugin_names = $this->getActivePlugins(); + foreach ($plugin_names as $name) { + $this->plugins[$name] = $this->loadPlugin($name); + } + $this->loaded = true; + } + + public function callHook($hook, $arg=null) { + $this->loadPlugins(); + $ret = array(); + foreach ($this->plugins as $name => $plugin) { + $ret[$name] = call_user_func(array($plugin, $hook), + &$arg); + } + return $ret; + } + + public function staticHook($plugin_name, $hook) { + require_once("$plugin_name.class.php"); + return call_user_func("$plugin_name::$hook"); + } + +} diff --git a/apps/um/lib/Singleton.class.php b/apps/um/lib/Singleton.class.php new file mode 100644 index 0000000..2f8c74f --- /dev/null +++ b/apps/um/lib/Singleton.class.php @@ -0,0 +1,12 @@ +/',$html,$matches); + $shortUrl = $matches[1]; + curl_close($ch); + return $shortUrl; + } + + public function baseUrl() { + $base = $_SERVER['REQUEST_URI']; + + $db = Database::getInstance(); + if ($db !== null) { + $b = $db->getSysConf('baseurl'); + if ($b != false) { + $base = $b; + } + } + + return $base; + } +} diff --git a/apps/um/models/Auth.class.php b/apps/um/models/Auth.class.php new file mode 100644 index 0000000..39f627e --- /dev/null +++ b/apps/um/models/Auth.class.php @@ -0,0 +1,157 @@ +getStatus($uid); + switch ($type) { + case 0: // unactivated user + case 1: // user + case 2: $obj = new User($uid); // admin + case 3: $obj = new Group($uid); + case 4: $obj = new Auth($uid); // deleted + } + self::$users[$uid] = $obj; + } + return self::$users[$uid]; + } + + /**********************************************************************\ + * Static stuff * + \**********************************************************************/ + public static function isNameLegal($name) { + // Current rules: + // * Not in "$illegal_names" + // * Does not contain '.' + // * Fewer than 256 characters + $illegal_names = array('', 'new', 'index', 'all'); + return true + && (!in_array($name, $illegal_names)) + && (strpos($name,'.')===false) + && (strpos($name,'!')===false) + && (strlen($name)<256); + } + + /**********************************************************************\ + * Class stuff * + \**********************************************************************/ + protected $uid = false; + public function __construct($uid) { + parent::__construct(); + $this->uid = $uid; + } + public function getUID() { + return $this->uid; + } + + /**********************************************************************\ + * The 'auth' table. * + \**********************************************************************/ + + // Row Type //////////////////////////////////////////////////////////// + /** + * @return 0=unverified 1=user 2=admin 3=group 4=deleted + */ + protected function getType() { + $type = $this->db->getStatus($this->uid); + return $type; + } + protected function setType($type) { + $logged_in_uid = Login::isLoggedIn(); + $logged_in_obj = Auth::getInstance($logged_in_uid); + $is_admin = $logged_in_obj->isAdmin(); + if (!$is_admin) return false; + return $this->db->setStatus($this->uid, $type); + } + public function isUser() { + $type = $this->getType(); + return ($type===1) || ($type===2); + } + public function isAdmin() { + $type = $this->getType(); + return ($type===2); + } + public function isGroup() { + $type = $this->getType(); + return ($type===3); + } + public function setUser($is_user) { + $is_user = ($is_user?true:false); + if ($this->isUser() != $is_user) { + $this->setType($is_user?1:0); + } + } + public function setAdmin($is_admin) { + $is_admin = ($is_admin?true:false); + $is_user = $this->isUser(); + $this->setType($is_admin?2:($is_user?1:0)); + } + public function delete() { + $this->setType(4); + } + + // Permissions ///////////////////////////////////////////////////////// + public function canRead() { + $logged_in_uid = Login::isLoggedIn(); + $is_me = ($logged_in_uid === $this->uid); + + $logged_in_obj = Auth::getInstance($logged_in_uid); + $is_user = $logged_in_obj->isUser(); + + return ($is_me || $is_user); + } + public function canEdit() { + $logged_in_uid = Login::isLoggedIn(); + $is_me = ($logged_in_uid === $this->uid); + + $logged_in_obj = Auth::getInstance($logged_in_uid); + $is_admin = $logged_in_obj->isAdmin(); + + return ($is_me || $is_admin); + } + + // [user|group]name //////////////////////////////////////////////////// + public function getName() { + if ($this->db===null) { + return false; + } else { + return $this->db->getUsername($this->uid); + } + } + public function setName($new_name) { + if (!$this->canEdit()) return false; + if (!self::isNameLegal($new_name)) return false; + return $this->db->setUsername($this->uid, $new_name); + } + + /**********************************************************************\ + * The 'users' table. * + \**********************************************************************/ + + public function getConf($setting) { + if (!$this->canRead()) return false; + return $this->db->getUserConf($this->uid, $setting); + } + public function setConf($setting, $value) { + if (!$this->canEdit()) return false; + return $this->db->setUserConf($this->uid, $setting, $value); + } + public function getConfArray($setting) { + $string = $this->getConf($setting); + return $this->db->valueToArray($string); + } + public function setConfArray($setting, $list) { + $string = $this->db->arrayToValue($list); + return $this->setConf($setting, $string); + } +} diff --git a/apps/um/models/ContactMethod.class.php b/apps/um/models/ContactMethod.class.php new file mode 100644 index 0000000..1dd40ee --- /dev/null +++ b/apps/um/models/ContactMethod.class.php @@ -0,0 +1,29 @@ +verb_slug = $verb_slug; + $this->addr_slug = $addr_slug; + $this->verb_text = $verb_text; + $this->addr_text = $addr_text; + + global $CONTACT_METHODS; + $CONTACT_METHODS[$verb_slug] = $this; + } + public function setHandler($handler) { + $this->handler = $handler; + } +} diff --git a/apps/um/models/Group.class.php b/apps/um/models/Group.class.php new file mode 100644 index 0000000..f981a4f --- /dev/null +++ b/apps/um/models/Group.class.php @@ -0,0 +1,23 @@ +uid; + } + + /**********************************************************************\ + * The 'auth' table. * + \**********************************************************************/ + + /**********************************************************************\ + * The 'users' table. * + \**********************************************************************/ + + public function getMembers() { + return $this->db->getUsersInGroup($this->getName()); + } +} diff --git a/apps/um/models/User.class.php b/apps/um/models/User.class.php new file mode 100644 index 0000000..b6dbede --- /dev/null +++ b/apps/um/models/User.class.php @@ -0,0 +1,25 @@ +uid; + } + + /**********************************************************************\ + * The 'auth' table. * + \**********************************************************************/ + + public function setPassword($password) { + if (!$this->canEdit()) return false; + return $this->db->setPassword($this->uid, $password); + } + + /**********************************************************************\ + * The 'users' table. * + \**********************************************************************/ + +} diff --git a/apps/um/plugins/InformationPlugin.class.php b/apps/um/plugins/InformationPlugin.class.php new file mode 100644 index 0000000..70ec8ac --- /dev/null +++ b/apps/um/plugins/InformationPlugin.class.php @@ -0,0 +1,62 @@ +addConfigGroup($arr, $group); + $arr[$group][] = array('firstname','First Name','text'); + $arr[$group][] = array('lastname','Last Name','text'); + $arr[$group][] = array('school','Home School','text'); + $arr[$group][] = array('hsclass','Highschool Class of','text'); + + $group = 'New Member Questions'; + $this->addConfigGroup($arr, $group); + $arr[$group][] = array('q_why_team', + 'Why do you want to be a part of the robotics team?', + 'textarea'); + $arr[$group][] = array('q_strengths', + 'What strengths do you have that can contribute to the robotics team?', + 'textarea'); + $arr[$group][] = array('q_other_activities', + 'Other after school activities--sports, performing arts, extracurricular activities. (January through March)', + 'textarea'); + $arr[$group][] = array('q_other_commitments', + 'After school/weekend work commitments. (January through March)', + 'textarea'); + // TODO: Top 3 subteams + $arr[$group][] = array('q_who_you_know', + 'Who do you know that could possibly help our team this year? '. + 'This includes material resources, supplying or preparing food '. + 'for work nights/competitions, corporate sponsorship, travel, '. + 'engineers, computer programmers, web developers, and fundraisers.', + 'textarea'); + $arr[$group][] = array('x_bogus_recommend', + "List two teachers who we could contact for your recommendation to be a member of this year's team.", + 'paragraph'); + $arr[$group][] = array('q_teacher_recommend1', 'Teacher 1', 'text'); + $arr[$group][] = array('q_teacher_recommend2', 'Teacher 2', 'text'); + $arr[$group][] = array('x_bogus_agreement', + "I understand that if I am chosen to participate ". + "in the robotics project, I will represent my ". + "school in a positive manner. If I fail to do so, ". + "I may be removed from the team at any time. In ". + "addition, if I do not have good attendance ". + "during this project, I will not be allowed to ". + "travel with the team to the competitions. I also ". + "understand that all of the school rules will be ". + "in effect at all times.", + 'paragraph'); + $arr[$group][] = array('q_i_agree', + "I agree", + 'checkbox'); + } + public function sendPrivate($to, $id, $subject, $body) {} + public function sendBroadcast($id, $subject, $body) {} +} diff --git a/apps/um/plugins/ReCaptcha.class.php b/apps/um/plugins/ReCaptcha.class.php new file mode 100644 index 0000000..165493b --- /dev/null +++ b/apps/um/plugins/ReCaptcha.class.php @@ -0,0 +1,47 @@ +'', + 'private_key'=>''); + public static function description() { + return 'Add a reCaptcha to keep out spam users.'; + } + public static function configList() { + return array('public_key'=>'text', + 'private_key'=>'text'); + } + public function init() {} + + private $resp = null; + private function getResp() { + if ($this->resp===null) { + require_once('recaptchalib.php'); + @$response = $_POST['recaptcha_response_field']; + @$challenge = $_POST['recaptcha_challenge_field']; + $this->resp = recaptcha_check_answer($this->config['private_key'], + $_SERVER['REMOTE_ADDR'], + $challenge, + $response); + } + return $this->resp; + } + + private function getError() { + if ($_POST["recaptcha_response_field"] && !$this->antispam_verify()) { + return $this->getResp()->error; + } else { + return false; + } + } + + public function antispam_verify() { + return $this->getResp()->is_valid; + } + + public function antispam_html() { + require_once('recaptchalib.php'); + return recaptcha_get_html($this->config['public_key'], $this->getError()); + } +} diff --git a/apps/um/views/Template.class.php b/apps/um/views/Template.class.php new file mode 100644 index 0000000..9d55b75 --- /dev/null +++ b/apps/um/views/Template.class.php @@ -0,0 +1,316 @@ +ret = $ret; + } + + private function tabs() { + $str = ''; + for ($i=0;$i<$this->indent;$i++) { $str .= "\t"; } + return $str; + } + + private function attr($attr='') { + $tags=''; + if (is_array($attr)) { + foreach($attr as $key=>$value) { + $tags .= " $key=\"$value\""; + } + } + return $tags; + } + + public function tag($tag, $attr='', $content=false) { + $tags = $this->attr($attr); + $str = $this->tabs()."<$tag$tags"; + if ($content===false) { + $str.= " />"; + } else { + $str.= ">$content"; + } + $str.= "\n"; + if ($this->ret) return $str; + echo $str; + } + + public function openTag($tag, $attr='') { + $tags = $this->attr($attr); + $str = $this->tabs()."<$tag$tags>\n"; + $this->indent++; + if ($this->ret) return $str; + echo $str; + } + + public function closeTag($tag) { + $this->indent--; + $str = $this->tabs()."\n"; + if ($this->ret) return $str; + echo $str; + } + + public function text($text) { + $str = $this->tabs().$text."\n"; + if ($this->ret) return $str; + echo $str; + } + + public function paragraph($text, $attr='', $return=false) { + $tabs = $this->tabs(); + $tags = $this->attr($attr); + $str = $tabs.""; + $str.= wordwrap($text, 78-($this->indent*8), "\n$tabs "); + $str.= "

\n"; + if ($this->ret||$return) return $str; + echo $str; + } + + public function link($target, $text, $return=false) { + $ret = $this->ret; + $this->ret |= $return; + $str = $this->tag('a', array('href'=>$target), $text); + $this->ret = $ret; + if ($this->ret||$return) return $str; + echo $str; + } + public function url($page) { + return Site::getInstance()->baseUrl().$page; + } + + public function row($cells) { + $str = $this->openTag('tr'); + foreach ($cells as $cell) + $str.= $this->tag('td', array(), $cell); + $str.= $this->closeTag('tr'); + if ($this->ret) return $str; + echo $str; + } + private function css($file, $media) { + $str.= $this->tag('link', array('rel'=>"stylesheet", + 'type'=>"text/css", + 'href'=>$this->url($file), + 'media'=>$media)); + if ($this->ret) return $str; + echo $str; + } + public function header($title) { + // username=false if not logged in or not connected to DB + $username = Auth::getInstance(Login::isLoggedIn())->getName(); + + $ret = $this->ret; + $this->ret = true; + + $logged_in = ($username!==false); + + $str = ''."\n"; + $str.= ''."\n"; + + $xmlns = "http://www.w3.org/1999/xhtml"; + $str.= $this->openTag('html', array('xmlns'=>$xmlns, + 'lang'=>"en-us", + 'dir'=>"ltr")); + $this->indent = 0; // don't indent for the tag + + $str.= $this->openTag('head'); + $str.= $this->tag('title', array(), htmlspecialchars($title)); + $str.= $this->css('style.css', 'all'); + $str.= $this->css('screen.css', 'screen'); + $str.= $this->css('print.css', 'print'); + $str.= $this->closeTag('head'); + + $body_class = 'logged'.($logged_in?'in':'out'); + $str.= $this->openTag('body', array('class'=>$body_class)); + + $str.= $this->openTag('div', array('class'=>'infobar')); + if ($logged_in) { + $user = htmlentities($username); + + $str.= $this->link($this->url(''), "Home"); + $str.= $this->link($this->url("users/$user"),"@$user"); + $str.= $this->logout_button('Logout'); + } else { + $url=$_SERVER['REQUEST_URI']; + $str.= $this->openTag('form', + array('action'=>$this->url('auth'), + 'method'=>'post')); + $str.= $this->tag('input', array('type'=>'hidden', + 'name'=>'action', + 'value'=>'login')); + $str.= $this->tag('input', array('type'=>'hidden', + 'name'=>'url', + 'value'=>$url)); + $str.= $this->tag('label', + array('for'=>'username'),'Username:'); + $str.= $this->tag('input', array('type'=>'text', + 'name'=>'username', + 'id'=>'username')); + $str.= $this->tag('label', + array('for'=>'password'),'Password:'); + $str.= $this->tag('input', array('type'=>'password', + 'name'=>'password', + 'id'=>'password')); + $str.= $this->tag('input', array('type'=>'submit', + 'value'=>'Login')); + $str.= $this->link($this->url("users/new"),'New Account'); + $str.= $this->closeTag('form'); + } + $str.= $this->closeTag('div'); + + $str.= $this->openTag('div',array('class'=>'main')); + $str.= $this->openTag('div',array('class'=>'main_sub')); + + $this->ret = $ret; + if ($this->ret) return $str; + echo $str; + } + + public function footer() { + $str = $this->closeTag('div'); + $str.= $this->closeTag('div'); + $str.= $this->closeTag('body'); + $str.= $this->closeTag('html'); + + if ($this->ret) return $str; + echo $str; + } + + public function openFieldset($name, $lock=false) { + $class = ($lock?' class="readonly"':''); + $str = $this->text("$name
    "); + $this->indent++; + if ($this->ret) return $str; + echo $str; + } + + public function closeFieldset() { + $this->indent--; + $str = $this->text("
"); + if ($this->ret) return $str; + echo $str; + } + + public function input($id, $label, $hint, $html, $tags=null) { + if ($tags===null) { $tags=array(); } + $str = $this->openTag('li', $tags); + $str.= $this->tag('label', array('for'=>$id), $label); + $str.= $this->text($html); + if (strlen($hint)>0) { + $str.=$this->paragraph($hint, + Array('class'=>'form_data')); + } + $str.= $this->closeTag('li'); + if ($this->ret) return $str; + echo $str; + } + + private function inputStr($type, $id, $default, $lock) { + $value = htmlentities($default); + $tag = ($lock?"readonly='readonly' ":''); + return ""; + } + public function inputTextArea($id, $label, $hint='', $default='', $lock=FALSE) { + $value = htmlentities($default); + $tag = ($lock?"readonly='readonly' ":''); + return $this->input($id, $label, $hint, + "", + array('class'=>'wide')); + } + + public function inputText($id, $label, $hint='', $default='', $lock=FALSE) { + return $this->input($id, $label, $hint, + $this->inputStr('text', $id, $default, $lock)); + } + + public function inputPassword($id, $label, $hint='', $default='', $lock=FALSE) { + return $this->input($id, $label, $hint, + $this->inputStr('password', $id, $default, $lock)); + } + + public function inputNewPassword($id, $label, $default='', $lock=FALSE) { + return $this->input($id, $label, + "Type the same password twice, to make sure you don't mistype.", + $this->inputStr('password', $id, $default, $lock). + "\n".$this->tabs()."\t". + $this->inputStr('password', $id.'_verify', $default,$lock)); + } + public function inputBool($id, $label, $hint='', $default=FALSE, $lock=FALSE) { + $tag = ''; + if ($lock) $tag.= "readonly='readonly' "; + if ($default) $tag.= "checked='checked' "; + return $this->input($id, $label, $hint, + "". + ""); + + $attrib = array('type'=>'checkbox', + 'id'=>$id, + 'name'=>$name.'[]', + 'value'=>$value); + if ($default) $attrib['checked']='checked'; + if ($lock ) $attrib['readonly']='readonly'; + + $str = $this->openTag('li'); + $str.= $this->tag('input', $attrib); + $str.= $this->tag('label', array('for'=>$id), $label); + $str.= $this->closeTag('li'); + + if ($this->ret) return $str; + echo $str; + + } + + public function inputBoolArray($name, $value, $label, $default=FALSE, $lock=FALSE) { + $id = $name.'_'.$value; + $attrib = array('type'=>'checkbox', + 'id'=>$id, + 'name'=>$name.'[]', + 'value'=>$value); + if ($default) $attrib['checked']='checked'; + if ($lock ) $attrib['readonly']='readonly'; + + $str = $this->openTag('li'); + $str.= $this->tag('input', $attrib); + $str.= $this->tag('label', array('for'=>$id), $label); + $str.= $this->closeTag('li'); + + if ($this->ret) return $str; + echo $str; + + } + + public function inputP($text, $error=false) { + $str = $this->openTag('li'); + $str.=$this->paragraph($text, + array('class'=>($error?' error':''))); + $str.= $this->closeTag('li'); + if ($this->ret) return $str; + echo $str; + } + + public function logout_button($text) { + $str = $this->openTag('form',array('action'=>$this->url('auth'), + 'method'=>"post", + 'style'=>'display:inline')); + $str.= $this->tag('input', array('type'=>'hidden', + 'name'=>'action', + 'value'=>'logout')); + $str.= $this->tag('input', array('type'=>'submit', + 'value'=>$text)); + $str.= $this->closeTag('form'); + if ($this->ret) return $str; + echo $str; + } +} diff --git a/apps/um/views/includes/header-include.php b/apps/um/views/includes/header-include.php new file mode 100644 index 0000000..3826b3a --- /dev/null +++ b/apps/um/views/includes/header-include.php @@ -0,0 +1,51 @@ +getName(); +$logged_in = ($username!==false); + +$ret = $this->ret; +$this->ret = true; + +function body_class() { + $body_class = 'logged'.($logged_in?'in':'out'); + echo 'class="'+$body_class+'"'; +} + +require(dirname(__FILE__)+"/header.php"); \ No newline at end of file diff --git a/apps/um/views/includes/header.php b/apps/um/views/includes/header.php new file mode 100644 index 0000000..0a3e161 --- /dev/null +++ b/apps/um/views/includes/header.php @@ -0,0 +1,84 @@ + section and everything up till
+ * + * @package WordPress + * @subpackage Twenty_Eleven + * @since Twenty Eleven 1.0 + */ +?> + + + + +> + + + + +<?php + /* + * Print the <title> tag based on what is being viewed. + */ + global $_title_; + echo $_title_; + ?> + + + + + + * tag of your theme, or you will break many plugins, which + * generally use this hook to add elements to such + * as styles, scripts, and meta tags. + */ + wp_head(); +?> + + +> +
+ + + +
\ No newline at end of file diff --git a/apps/um/views/pages/auth/badrequest.html.php b/apps/um/views/pages/auth/badrequest.html.php new file mode 100644 index 0000000..c1fe726 --- /dev/null +++ b/apps/um/views/pages/auth/badrequest.html.php @@ -0,0 +1,11 @@ +status('400 Bad Request'); +$t->header('Authentication'); +$t->paragraph('The recieved POST request was malformed/invalid. '. + 'If you got here from a link, this is a bug; '. + 'Let the admin know.'. + 'If you got here from outside, then the API is being '. + 'used incorrectly.'); +$t->footer(); diff --git a/apps/um/views/pages/auth/index.html.php b/apps/um/views/pages/auth/index.html.php new file mode 100644 index 0000000..ac80140 --- /dev/null +++ b/apps/um/views/pages/auth/index.html.php @@ -0,0 +1,12 @@ +header('Authentication'); + +$t->openTag('div',array('class'=>'login')); +$t->text("Logged in as ".htmlentities($username).'.'); +$t->logout_button('Logout'); +$t->closeTag('div'); + +$t->footer(); \ No newline at end of file diff --git a/apps/um/views/pages/auth/login.html.php b/apps/um/views/pages/auth/login.html.php new file mode 100644 index 0000000..4e3e0e6 --- /dev/null +++ b/apps/um/views/pages/auth/login.html.php @@ -0,0 +1,54 @@ +status('401 Unauthorized'); break; +case 2: $t->status('404 Not Found'); break; +} + +$t->header('Authentication'); + +$t->openTag('form',array('action'=>$t->url('auth'), 'method'=>"post")); +$t->openFieldset('Login'); +switch ($VARS['login_code']) { +case -1: break; +case 0: + $t->inputP('Successfully logged in as '. + htmlentities($username).'.'); + if (isset($VARS['url'])) { + $url = htmlentities($VARS['url']); + $t->inputP($t->link($url, + 'Return to the page you were on.', + true)); + } + $t->closeFieldset(); + $t->closeTag('form'); + return; + break; +case 1: + $t->inputP("Password does not match username.", + array('class'=>'error')); + break; +case 2: + $t->inputP("Username $username does not exist."); + $username = ''; + break; +} +$t->inputText( 'username', 'Username:', '', $username); +$t->inputPassword('password', 'Password:', '', $password); +$t->openTag('li'); +$t->tag('input', array('type'=>'submit', 'value'=>'Login')); +$t->closeTag('li'); +$t->closeFieldset(); +$t->tag('input', array('type'=>'hidden', + 'name'=>'action', + 'value'=>'login')); +if (isset($VARS['url'])) { + $url = htmlentities($VARS['url']); + $t->tag('input', array('type'=>'hidden', + 'name'=>'url', + 'value'=>$url)); +} +$t->closeTag('form'); diff --git a/apps/um/views/pages/auth/logout.html.php b/apps/um/views/pages/auth/logout.html.php new file mode 100644 index 0000000..2d00998 --- /dev/null +++ b/apps/um/views/pages/auth/logout.html.php @@ -0,0 +1,6 @@ +header('Authentication'); +$t->paragraph('Logged out'); +$t->footer(); diff --git a/apps/um/views/pages/groups/401.html.php b/apps/um/views/pages/groups/401.html.php new file mode 100644 index 0000000..23e3778 --- /dev/null +++ b/apps/um/views/pages/groups/401.html.php @@ -0,0 +1,15 @@ +status('401 Unauthorized'); +$t->header('Unauthorized'); +$t->tag('h1', array(), "401: Unauthorized"); +if ($VARS['uid']===false) { + // Not logged in + $t->paragraph('You need to be logged in to view group-data.'); +} else { + // Logged in, so the account must not activated + $t->paragraph('Your account needs to be activated by an administrator '. + 'to group-data.'); +} +$t->footer(); diff --git a/apps/um/views/pages/http404.html.php b/apps/um/views/pages/http404.html.php new file mode 100644 index 0000000..730b0ee --- /dev/null +++ b/apps/um/views/pages/http404.html.php @@ -0,0 +1,16 @@ +status('404 Not Found'); +$t->header('Page Not Found'); +$t->tag('h1',array(),"404: Not Found"); +$t->paragraph("Awe man, the page you requested wasn't found."); +$t->paragraph('This folder was found: '. + ''.$t->link($t->url($routed), $routed.'/', true).''); +$t->paragraph("But this file in it wasn't: ". + ''.$full.''); +$t->footer(); diff --git a/apps/um/views/pages/index.html.php b/apps/um/views/pages/index.html.php new file mode 100644 index 0000000..71b0091 --- /dev/null +++ b/apps/um/views/pages/index.html.php @@ -0,0 +1,8 @@ +header('Main Page'); +$t->tag('h1', array(), "Message Manager"); +$t->paragraph($t->link($t->url('users/new'),'Register to be on the team', true), array('style'=>'font-size:5em')); +$t->link($t->url('users'), 'List of all users'); +$t->footer(); diff --git a/apps/um/views/pages/plugins/401.html.php b/apps/um/views/pages/plugins/401.html.php new file mode 100644 index 0000000..5b1b222 --- /dev/null +++ b/apps/um/views/pages/plugins/401.html.php @@ -0,0 +1,9 @@ +status('401 Unauthorized'); +$t->header('Unauthorized'); +$t->tag('h1',array(),"401: Unauthorized"); +$t->paragraph('You need to be logged in as an admin to edit global plugin '. + 'settings.'); +$t->footer(); diff --git a/apps/um/views/pages/plugins/index.html.php b/apps/um/views/pages/plugins/index.html.php new file mode 100644 index 0000000..b182288 --- /dev/null +++ b/apps/um/views/pages/plugins/index.html.php @@ -0,0 +1,42 @@ +header('Administrator Plugin Management'); +$t->openTag('form',array('method'=>'post','action'=>$t->url('plugins'))); + +foreach ($plugins as $plugin) { + $t->setRet(true); + $props = array('type'=>'checkbox', + 'name'=>'plugins[]', + 'id'=>'plugins_'.$plugin['name'], + 'value'=>$plugin['name']); + if ($plugin['active']==true) { + $props['checked'] = 'checked'; + } + $box = $t->tag('input', $props); + $t->setRet(false); + $t->openFieldset($plugin['name'].$box); + + $t->inputP($plugin['description']); + foreach ($plugin['config'] as $param => $type) { + $name = $plugin['key'].'['.$param.']'; + $value = $db->getPluginConf($plugin['name'], $param); + $hint = "Type: $type"; + switch ($type) { + case 'text': + case 'int': + $t->inputText( $name, $param, $hint, $value); break; + case 'password': + $t->inputPassword($name, $param, $hint, $value); break; + } + } + $t->closeFieldset(); +} + +$t->tag('input', array('type'=>'submit', + 'value'=>'Save/Update')); +$t->closeTag('form'); +$t->footer(); diff --git a/apps/um/views/pages/users/401.html.php b/apps/um/views/pages/users/401.html.php new file mode 100644 index 0000000..0a5a1ce --- /dev/null +++ b/apps/um/views/pages/users/401.html.php @@ -0,0 +1,15 @@ +status('401 Unauthorized'); +$t->header('Unauthorized'); +$t->tag('h1', array(), "401: Unauthorized"); +if ($VARS['uid']===false) { + // Not logged in + $t->paragraph('You need to be logged in to view user-data.'); +} else { + // Logged in, so the account must not activated + $t->paragraph('Your account needs to be activated by an administrator '. + 'to view user-data.'); +} +$t->footer(); diff --git a/apps/um/views/pages/users/404.html.php b/apps/um/views/pages/users/404.html.php new file mode 100644 index 0000000..00f9dca --- /dev/null +++ b/apps/um/views/pages/users/404.html.php @@ -0,0 +1,10 @@ +status('404 Not Found'); +$t->header('User Not Found'); +$t->tag('h1',array(),"404: Not Found"); +$t->paragraph('No user with the name '. + htmlentities($username).' exists.'); +$t->footer(); diff --git a/apps/um/views/pages/users/500.html.php b/apps/um/views/pages/users/500.html.php new file mode 100644 index 0000000..339fe63 --- /dev/null +++ b/apps/um/views/pages/users/500.html.php @@ -0,0 +1,15 @@ +status('500 Internal Server Error'); +$t->header('Unknown error'); +$t->paragraph("An unknown error was encountered when creating ". + "the user. The username appears to be free, and ". + "the passwords match, so I'm assuming that the ". + "error is on our end. Sorry."); +$t->paragraph("Here's a dump of the SQL error stack, it may ". + "help us find the issue:"); +$t->tag('pre', array(), htmlentities($db->mysql_error())); +$t->footer(); diff --git a/apps/um/views/pages/users/created.html.php b/apps/um/views/pages/users/created.html.php new file mode 100644 index 0000000..d3027cc --- /dev/null +++ b/apps/um/views/pages/users/created.html.php @@ -0,0 +1,18 @@ +status('201 Created'); +header('Location: '.$t->url("users/$username")); +$t->header('User created'); +/*$t->paragraph("You can go ahead and fill out more of your ". + "user information, (click the @username link at ". + "the top) but will need to wait for an ". + "administrator to approve your account before ". + "you can really use the site. Actually, ". + "filling your info out might help approval, so ". + "that the administrator can more easily see who ". + "you are."); +*/ +$t->tag('h2',array(), $t->link($t->url("users/$username"), 'Go on to step 2')); +$t->footer(); diff --git a/apps/um/views/pages/users/index.csv.php b/apps/um/views/pages/users/index.csv.php new file mode 100644 index 0000000..0a69cee --- /dev/null +++ b/apps/um/views/pages/users/index.csv.php @@ -0,0 +1,27 @@ +header('Users'); + +$t->paragraph($t->link($t->url('users.csv'), "Download this as a spreadsheet.", true)); + +$t->openTag('form', array('action'=>$t->url('users/index'), + 'method'=>'post')); + +if (Login::isLoggedIn()) { + $t->tag('input', array('type'=>'submit', + 'value'=>'Save/Update')); +} + +$t->openTag('table', array('class'=>'sortable', 'id'=>'bar')); + +function table_head($attribs, $t) { + $t->openTag('tr'); + foreach ($attribs as $attrib) { + switch ($attrib['type']) { + case 'bool': $class = 'small'; break; + default: $class = ''; break; + } + $t->tag('th', array('class'=>$class), $attrib['name']); + } + if (Login::isLoggedIn()) { + $t->tag('th', array(), '-'); + } + $t->closeTag('tr'); +} + +$t->openTag('thead'); +table_head($attribs, $t); +$t->closeTag('thead'); + +$t->openTag('tfoot'); +table_head($attribs, $t); +$t->closeTag('tfoot'); + +$t->openTag('tbody'); + +foreach ($users as $user) { + $t->openTag('tr'); + + foreach ($attribs as $attrib) { + $t->openTag('td'); + + $props = $user[$attrib['key']]; + + $bool = $attrib['type']=='bool'; + if ($bool) { + $value = $props['value']=='true'; + } else { + $value = $props['value']; + } + $editable = $props['editable']; + $post_key = $props['post_key']; + + $arr = array('name'=>$post_key); + if (!$editable) { + $arr['readonly'] = 'readonly'; + if ($bool) $arr['disabled'] = $disabled; + } + if ($bool) { + $t->tag('input', array('type'=>'hidden', 'name'=>$post_key, 'value'=>'false')); + if ($value==true) { + $arr['checked'] = 'checked'; + } + $arr['value'] = 'true'; + $arr['type'] = 'checkbox'; + } else { + $t->tag('span', array('class'=>'cell_width'), $value); + $arr['value'] = $value; + $arr['type'] = 'text'; + } + + $t->tag('input', array('name'=>'_old['.$arr['name'].']', + 'value'=>$arr['value'], + 'type'=>'hidden')); + $t->tag('input', $arr); + $t->closeTag('td'); + } + + if (Login::isLoggedIn()) { + $t->openTag('td'); + $t->link($t->url('users/'.$user['auth_name']['value']), 'More'); + $t->closeTag('td'); + } + $t->closeTag('tr'); +} + +$t->closeTag('tbody'); +$t->closeTag('table'); + +if (Login::isLoggedIn()) { + $t->tag('input', array('type'=>'submit', + 'value'=>'Save/Update')); +} + +$t->footer(); diff --git a/apps/um/views/pages/users/individual.html.php b/apps/um/views/pages/users/individual.html.php new file mode 100644 index 0000000..39360b7 --- /dev/null +++ b/apps/um/views/pages/users/individual.html.php @@ -0,0 +1,147 @@ +getConf($key); + $t->inputText("user_$key", $label, $hint, $current_setting, + !$user->canEdit()); +} +function inputTextarea($user, $key, $label, $hint='') { + global $VARS; $t = $VARS['template']; + $current_setting = $user->getConf($key); + $t->inputTextarea("user_$key", $label, $hint, $current_setting, + !$user->canEdit()); +} + +function inputBool($user, $key, $label, $hint='') { + global $VARS; $t = $VARS['template']; + $current_setting = $user->getConf($key)=='true'; + $t->inputBool("user_$key", $label, $hint, $current_setting, + !$user->canEdit()); +} + +function inputArray($user, $key, $arr) { + global $VARS; $t = $VARS['template']; + $defaults = $user->getConfArray($key); + + foreach ($arr as $value => $label) { + $t->inputBoolArray($key, $value, $label, + in_array($value, $defaults), !$user->canEdit()); + } +} + +function inputField($user, $arr) { + $fieldname = $arr[0]; + $fieldlabel = $arr[1]; + $fieldtype = $arr[2]; + + switch ($fieldtype) { + case 'text': + inputText($user, $fieldname, $fieldlabel, ''); + break; + case 'textarea': + inputTextarea($user, $fieldname, $fieldlabel, ''); + break; + case 'paragraph': + global $VARS; $t = $VARS['template']; + $t->inputP($fieldlabel); + break; + case 'checkbox': + inputBool($user, $fieldname, $fieldlabel, ''); + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// + +if (count($users)>1) { + $t->header("Users: $username"); +} else { + $t->header("User: $username"); +} + +foreach($users as $user) { +$username = $user->getName(); + +$t->tag('h1', array(), ($user->canEdit()?'Edit':'View')." User $username (UID: ".$user->getUID().")"); + +if ($user->canEdit()) { + $t->openTag('form', array('method'=>'post', + 'action'=>$t->url("users/$username"))); +} else { + $t->openTag('form'); +} + +$t->openFieldset("Login / Authentication"); +// Username //////////////////////////////////////////////////////////////////// +if (isset($VARS['changed name']) && !$VARS['changed name']) { + $t->inputP("Error setting username to ". + "$new_name. This is probably because". + " a user with that name already exists.", + true); +} +$t->inputText('auth_name','Username', + "This is the name you use to log in, but it is also a ". + "short name that is used in various places, think of it ". + "as a sort of Twitter name.", + $user->getName(), !$user->canEdit()); +// Password //////////////////////////////////////////////////////////////////// +if (@$VARS['pw_updated']===true) { + $t->inputP('Password successfully updated.'); +} +if (@$VARS['pw mixmatch']===true) { + $t->inputP("Passwords don't match.", true); +} +if ($user->canEdit()) $t->inputNewPassword('auth_password','Reset Password'); +//////////////////////////////////////////////////////////////////////////////// +$t->closeFieldset(); + +$t->openFieldset("Contact"); +// TODO: I should make this a setting for admins to set. +$hints = array('email'=> + "Right now you can only have one email address, ". + "but I'm working on making it so you can have ". + "multiple.", + 'phone'=> + "A home phone number isn't much use here because it is ". + "used to text-message you (if you enable it), and ". + "contact you at competition." + ); +$use_arr = array(); +foreach ($CONTACT_METHODS as $method) { + inputText($user, + $method->addr_slug, + ucwords($method->addr_text), + $hints[$method->addr_slug]); + $use_arr[$method->verb_slug] = ucwords($method->verb_text); +} + +$t->inputP("When I recieve a message, notify me using the following methods:"); +inputArray($user, 'use', $use_arr); +$t->closeFieldSet(); + +foreach ($VARS['config_options'] as $groupname=>$options) { + $t->openFieldset($groupname); + foreach ($options as $option) { + inputField($user, $option); + } + $t->closeFieldset(); +} + +$t->openFieldSet('Groups'); +$group_arr = array(); +foreach ($VARS['groups'] as $group_name) { + $group_arr[$group_name] = ucwords($group_name); +} +inputArray($user, 'groups', $group_arr); +$t->closeFieldset(); + +if ($user->canEdit()) { + $t->tag('input', array('type'=>'submit', 'value'=>'Save')); +} +$t->closeTag('form'); +} +$t->footer(); diff --git a/apps/um/views/pages/users/individual.json.php b/apps/um/views/pages/users/individual.json.php new file mode 100644 index 0000000..c3dee50 --- /dev/null +++ b/apps/um/views/pages/users/individual.json.php @@ -0,0 +1,27 @@ +getName(); + $user_json['uid'] = $user_obj->getUID(); + foreach ($CONTACT_METHODS as $method) { + $field = $method->addr_slug; + $user_json[$field] = $user_obj->getConf($field); + } + foreach ($VARS['config_options'] as $groupname=>$options) { + foreach ($options as $option) { + $fieldname = $option[0]; + $fieldlabel = $option[1]; + $fieldtype = $option[2]; + $user_json[$fieldname] = $user_obj->getConf($fieldname); + } + } + $json[] = $user_json; +} + +echo json_encode($json); \ No newline at end of file diff --git a/apps/um/views/pages/users/new-locked.html.php b/apps/um/views/pages/users/new-locked.html.php new file mode 100644 index 0000000..dc7ad0d --- /dev/null +++ b/apps/um/views/pages/users/new-locked.html.php @@ -0,0 +1,9 @@ +status('403 Forbidden'); +$t->header('Create new user'); + +$t->paragraph("Sorry, new user registration is disabled."); + +$t->footer(); diff --git a/apps/um/views/pages/users/new-logged-in.html.php b/apps/um/views/pages/users/new-logged-in.html.php new file mode 100644 index 0000000..51823fe --- /dev/null +++ b/apps/um/views/pages/users/new-logged-in.html.php @@ -0,0 +1,8 @@ +header('Create new user'); + +$t->paragraph("Dude, you're logged in, what are you doing creating an account?"); + +$t->footer(); diff --git a/apps/um/views/pages/users/new.html.php b/apps/um/views/pages/users/new.html.php new file mode 100644 index 0000000..9df376f --- /dev/null +++ b/apps/um/views/pages/users/new.html.php @@ -0,0 +1,57 @@ +header('Create new user'); + +$t->openTag('form', array('method'=>'post', + 'action'=>$t->url('users'))); + +$t->openFieldset("New User: Step 1"); + +if ($VARS['userlist']) { + $t->inputP("If you may have already created a username, please, ". + "please check the ". + $t->link($t->url('users/'), 'user-list', true). + " to find your old username, instead of creating a new ". + "user. If you don't like the name, you can log in and ". + "change it."); +} + +if (in_array('illegal name', $VARS['errors'])) { + $t->inputP("That is a forbidden username.", true); +} +if (in_array('user exists', $VARS['errors'])) { + $t->inputP("A user with that name already exists."); +} +$t->inputText('auth_name','Username', + "This is the name you use to log in, but it is also a ". + "short name that is used in various places, think of it ". + "as a sort of Twitter name.",$VARS['username']); + +@$password = $VARS['password1']; +if (in_array('pw mixmatch', $VARS['errors'])) { + $t->inputP("The passwords didn't match.", true); + $password = ''; +} +if (in_array('no pw', $VARS['errors'])) { + $t->inputP("You must set a password.", true); + $password = ''; +} +$t->inputNewPassword('auth_password','Password', $password); + +if (in_array('no email', $VARS['errors'])) { + $t->inputP("You must provide an email address.", true); +} +$t->inputText('user_email', 'Email Address', + 'This is so that we can contact you. (duh).', $VARS['email']); +$t->closeFieldset(); + +foreach ($VARS['antispam_html'] as $html) { + echo $html; +} + +$t->tag('input', array('type'=>'submit', 'value'=>'Go on to Step 2')); + +$t->closeTag('form'); + +$t->footer(); diff --git a/index.php b/index.php index 6c17d47..4880d5c 100644 --- a/index.php +++ b/index.php @@ -11,13 +11,34 @@ if (file_exists($xss_file)) { exit(); } } +unset($xss_file); // Decide where to look for things. //////////////////////////////////////////// -define('LIBPATH', BASEPATH.'/src/lib'.PATH_SEPARATOR.BASEPATH.'/src/ext'); -define('MODELPATH', BASEPATH.'/src/models'); -define('VIEWPATH', BASEPATH.'/src/views');// views are not objects -define('CONTROLLERPATH',BASEPATH.'/src/controllers'); -define('PLUGINPATH', BASEPATH.'/src/plugins'); +$app_path = glob(BASEPATH.'/apps/*'); +array_unshift($app_path, BASEPATH.'/lpf'); + +$libpath = array(); +$modelpath = array(); +$viewpath = array(); +$controllerpath = array(); +$pluginpath = array(); + +foreach ($app_path as $dir) { + if (is_dir($dir.'/lib' )) { $libpath[] = $dir.'/lib'; } + if (is_dir($dir.'/ext' )) { $libpath[] = $dir.'/ext'; } + if (is_dir($dir.'/models' )) { $modelpath[] = $dir.'/models'; } + if (is_dir($dir.'/views' )) { $viewpath[] = $dir.'/views'; } + if (is_dir($dir.'/controllers')) { $controllerpath[] = $dir.'/controllers'; } + if (is_dir($dir.'/plugins' )) { $controllerpath[] = $dir.'/plugins'; } +} +unset($app_path); + +define('LIBPATH', implode(PATH_SEPARATOR, $libpath )); unset($libpath); +define('MODELPATH', implode(PATH_SEPARATOR, $modelpath )); unset($modelpath); +/*define('VIEWPATH', implode(PATH_SEPARATOR, $viewpath ));*/ unset($viewpath); +define('VIEWPATH', BASEPATH.'/apps/um/views'); +define('CONTROLLERPATH',implode(PATH_SEPARATOR, $controllerpath)); unset($controllerpath); +define('PLUGINPATH', implode(PATH_SEPARATOR, $pluginpath )); unset($pluginpath); set_include_path(get_include_path() .PATH_SEPARATOR.LIBPATH @@ -29,7 +50,6 @@ set_include_path(get_include_path() // Figure what page is trying to be loaded. //////////////////////////////////// // We don't have to do any check if it's a real file being looked for, if the // requested page exists as a real file, .htaccess won't even let us load -// thisfile. @$PAGE_RAW = $_GET['p']; $PAGE_PARTS = explode('/', $PAGE_RAW); $FILE = array_pop($PAGE_PARTS); @@ -42,6 +62,8 @@ if (preg_match($regex, $FILE, $matches)) { } else { $PAGE = $PAGE_RAW; } +unset($PAGE_RAW); unset($PAGE_PARTS); unset($FILE); unset($regex); + if ($PAGE=='') $PAGE = 'index'; define('PAGE', $PAGE); unset($PAGE); define('PAGE_EXT', $EXT); unset($EXT); @@ -62,6 +84,7 @@ if (file_exists($conf_file)) { $view->show(array()); exit(); } +unset($conf_file); // Kludgy ugly hacky hack ////////////////////////////////////////////////////// require_once('ContactMethod.class.php'); diff --git a/lpf/ext/HTTP_Accept.class.php b/lpf/ext/HTTP_Accept.class.php new file mode 100644 index 0000000..5efaa5d --- /dev/null +++ b/lpf/ext/HTTP_Accept.class.php @@ -0,0 +1,659 @@ + + * @copyright 2007 Kevin Locke + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @version SVN: $Id: HTTP_Accept.php 22 2007-10-06 18:46:45Z kevin $ + * @link http://pear.php.net/package/HTTP_Accept + */ + +/** + * HTTP_Accept class for dealing with the HTTP 'Accept' header + * + * This class is intended to be used to parse the HTTP Accept header into + * usable information and provide a simple API for dealing with that + * information. + * + * The parsing of this class is designed to follow RFC 2616 to the letter, + * any deviations from that standard are bugs and should be reported to the + * maintainer. + * + * Often the class will be used very simply as + * + * getQuality("image/png") > $accept->getQuality("image/jpeg")) + * // Send PNG image + * else + * // Send JPEG image + * ?> + * + * + * However, for browsers which do not accurately describe their preferences, + * it may be necessary to check if a MIME Type is explicitly listed in their + * Accept header, in addition to being preferred to another type + * + * + * isMatchExact("application/xhtml+xml")) + * // Client specifically asked for this type at some quality level + * ?> + * + * + * + * @category HTTP + * @package HTTP_Accept + * @access public + * @link http://pear.php.net/package/HTTP_Accept + */ +class HTTP_Accept +{ + /** + * Array of types and their associated parameters, extensions, and quality + * factors, as represented in the Accept: header. + * Indexed by [type][subtype][index], + * and contains 'PARAMS', 'QUALITY', and 'EXTENSIONS' keys for the + * parameter set, quality factor, and extensions set respectively. + * Note: Since type, subtype, and parameters are case-insensitive + * (RFC 2045 5.1) they are stored as lower-case. + * + * @var array + * @access private + */ + var $acceptedtypes = array(); + + /** + * Regular expression to match a token, as defined in RFC 2045 + * + * @var string + * @access private + */ + var $_matchtoken = '(?:[^[:cntrl:]()<>@,;:\\\\"\/\[\]?={} \t]+)'; + + /** + * Regular expression to match a quoted string, as defined in RFC 2045 + * + * @var string + * @access private + */ + var $_matchqstring = '(?:"[^\\\\"]*(?:\\\\.[^\\\\"]*)*")'; + + /** + * Constructs a new HTTP_Accept object + * + * Initializes the HTTP_Accept class with a given accept string + * or creates a new (empty) HTTP_Accept object if no string is given + * + * Note: The behavior is a little strange here to accomodate + * missing headers (to be interpreted as accept all) as well as + * new empty objects which should accept nothing. This means that + * HTTP_Accept("") will be different than HTTP_Accept() + * + * @access public + * @return object HTTP_Accept + * @param string $acceptstring The value of an Accept: header + * Will often be $_SERVER['HTTP_ACCEPT'] + * Note: If get_magic_quotes_gpc is on, + * run stripslashes() on the string first + */ + function HTTP_Accept() + { + if (func_num_args() == 0) { + // User wishes to create empty HTTP_Accept object + $this->acceptedtypes = array( + '*' => array( + '*' => array ( + 0 => array( + 'PARAMS' => array(), + 'QUALITY' => 0, + 'EXTENSIONS' => array() + ) + ) + ) + ); + return; + } + + $acceptstring = trim(func_get_arg(0)); + if (empty($acceptstring)) { + // Accept header empty or not sent, interpret as "*/*" + $this->acceptedtypes = array( + '*' => array( + '*' => array ( + 0 => array( + 'PARAMS' => array(), + 'QUALITY' => 1, + 'EXTENSIONS' => array() + ) + ) + ) + ); + return; + } + + $matches = preg_match_all( + '/\s*('.$this->_matchtoken.')\/' . // typegroup/ + '('.$this->_matchtoken.')' . // subtype + '((?:\s*;\s*'.$this->_matchtoken.'\s*' . // parameter + '(?:=\s*' . // optional =value + '(?:'.$this->_matchqstring.'|'.$this->_matchtoken.'))?)*)/', // value + $acceptstring, $acceptedtypes, + PREG_SET_ORDER); + + if ($matches == 0) { + // Malformed Accept header + $this->acceptedtypes = array( + '*' => array( + '*' => array ( + 0 => array( + 'PARAMS' => array(), + 'QUALITY' => 1, + 'EXTENSIONS' => array() + ) + ) + ) + ); + return; + } + + foreach ($acceptedtypes as $accepted) { + $typefamily = strtolower($accepted[1]); + $subtype = strtolower($accepted[2]); + + // */subtype is invalid according to grammar in section 14.1 + // so we ignore it + if ($typefamily == '*' && $subtype != '*') + continue; + + // Parse all arguments of the form "key=value" + $matches = preg_match_all('/;\s*('.$this->_matchtoken.')\s*' . + '(?:=\s*' . + '('.$this->_matchqstring.'|'. + $this->_matchtoken.'))?/', + $accepted[3], $args, + PREG_SET_ORDER); + + $params = array(); + $quality = -1; + $extensions = array(); + foreach ($args as $arg) { + array_shift($arg); + if (!empty($arg[1])) { + // Strip quotes (Note: Can't use trim() in case "text\"") + $len = strlen($arg[1]); + if ($arg[1][0] == '"' && $arg[1][$len-1] == '"' + && $len > 1) { + $arg[1] = substr($arg[1], 1, $len-2); + $arg[1] = stripslashes($arg[1]); + } + } else if (!isset($arg[1])) { + $arg[1] = null; + } + + // Everything before q=# is a parameter, after is an extension + if ($quality >= 0) { + $extensions[$arg[0]] = $arg[1]; + } else if ($arg[0] == 'q') { + $quality = (float)$arg[1]; + + if ($quality < 0) + $quality = 0; + else if ($quality > 1) + $quality = 1; + } else { + $arg[0] = strtolower($arg[0]); + // Values required for parameters, + // assume empty-string for missing values + if (isset($arg[1])) + $params[$arg[0]] = $arg[1]; + else + $params[$arg[0]] = ""; + } + } + + if ($quality < 0) + $quality = 1; + else if ($quality == 0) + continue; + + if (!isset($this->acceptedtypes[$typefamily])) + $this->acceptedtypes[$typefamily] = array(); + if (!isset($this->acceptedtypes[$typefamily][$subtype])) + $this->acceptedtypes[$typefamily][$subtype] = array(); + + $this->acceptedtypes[$typefamily][$subtype][] = + array('PARAMS' => $params, + 'QUALITY' => $quality, + 'EXTENSIONS' => $extensions); + } + + if (!isset($this->acceptedtypes['*'])) + $this->acceptedtypes['*'] = array(); + if (!isset($this->acceptedtypes['*']['*'])) + $this->acceptedtypes['*']['*'] = array( + 0 => array( + 'PARAMS' => array(), + 'QUALITY' => 0, + 'EXTENSIONS' => array() + ) + ); + } + + /** + * Gets the accepted quality factor for a given MIME Type + * + * Note: If there are multiple best matches + * (e.g. "text/html;level=4;charset=utf-8" matching both "text/html;level=4" + * and "text/html;charset=utf-8"), it returns the lowest quality factor as + * a conservative estimate. Further, if the ambiguity is between parameters + * and extensions (e.g. "text/html;level=4;q=1;ext=foo" matching both + * "text/html;level=4" and "text/html;q=1;ext=foo") the parameters take + * precidence. + * + * Usage Note: If the quality factor for all supported media types is 0, + * RFC 2616 specifies that applications SHOULD send an HTTP 406 (not + * acceptable) response. + * + * @access public + * @return double the quality value for the given MIME Type + * Quality values are in the range [0,1] where 0 means + * "not accepted" and 1 is "perfect quality". + * @param string $mimetype The MIME Type to query ("text/html") + * @param array $params Parameters of Type to query ([level => 4]) + * @param array $extensions Extension parameters to query + */ + function getQuality($mimetype, $params = array(), $extensions = array()) + { + $type = explode("/", $mimetype); + $supertype = strtolower($type[0]); + $subtype = strtolower($type[1]); + + if ($params == null) + $params = array(); + if ($extensions == null) + $extensions = array(); + + if (empty($this->acceptedtypes[$supertype])) { + if ($supertype == '*') + return 0; + else + return $this->getQuality("*/*", $params, $extensions); + } + + if (empty($this->acceptedtypes[$supertype][$subtype])) { + if ($subtype == '*') + return $this->getQuality("*/*", $params, $extensions); + else + return $this->getQuality("$supertype/*", $params, $extensions); + } + + $params = array_change_key_case($params, CASE_LOWER); + + $matches = $this->_findBestMatchIndices($supertype, $subtype, + $params, $extensions); + + if (count($matches) == 0) { + if ($subtype != '*') + return $this->getQuality("$supertype/*", $params, $extensions); + else if ($supertype != '*') + return $this->getQuality("*/*", $params, $extensions); + else + return 0; + } + + $minquality = 1; + foreach ($matches as $match) + if ($this->acceptedtypes[$supertype][$subtype][$match]['QUALITY'] < $minquality) + $minquality = $this->acceptedtypes[$supertype][$subtype][$match]['QUALITY']; + + return $minquality; + } + + /** + * Determines if there is an exact match for the specified MIME Type + * + * @access public + * @return boolean true if there is an exact match to the given + * values, false otherwise. + * @param string $mimetype The MIME Type to query (e.g. "text/html") + * @param array $params Parameters of Type to query (e.g. [level => 4]) + * @param array $extensions Extension parameters to query + */ + function isMatchExact($mimetype, $params = array(), $extensions = array()) + { + $type = explode("/", $mimetype); + $supertype = strtolower($type[0]); + $subtype = strtolower($type[1]); + + if ($params == null) + $params = array(); + if ($extensions == null) + $extensions = array(); + + return $this->_findExactMatchIndex($supertype, $subtype, + $params, $extensions) >= 0; + } + + /** + * Gets a list of all MIME Types explicitly accepted, sorted by quality + * + * @access public + * @return array list of MIME Types explicitly accepted, sorted + * in decreasing order of quality factor + */ + function getTypes() + { + $qvalues = array(); + $types = array(); + foreach ($this->acceptedtypes as $typefamily => $subtypes) { + if ($typefamily == '*') + continue; + + foreach ($subtypes as $subtype => $variants) { + if ($subtype == '*') + continue; + + $maxquality = 0; + foreach ($variants as $variant) + if ($variant['QUALITY'] > $maxquality) + $maxquality = $variant['QUALITY']; + + if ($maxquality > 0) { + $qvalues[] = $maxquality; + $types[] = $typefamily.'/'.$subtype; + } + } + } + + array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, + $types, SORT_DESC, SORT_STRING); + + return $types; + } + + /** + * Gets the parameter sets for a given mime type, sorted by quality. + * Only parameter sets where the extensions set is empty will be returned. + * + * @access public + * @return array list of sets of name=>value parameter pairs + * in decreasing order of quality factor + * @param string $mimetype The MIME Type to query ("text/html") + */ + function getParameterSets($mimetype) + { + $type = explode("/", $mimetype); + $supertype = strtolower($type[0]); + $subtype = strtolower($type[1]); + + if (!isset($this->acceptedtypes[$supertype]) + || !isset($this->acceptedtypes[$supertype][$subtype])) + return array(); + + $qvalues = array(); + $paramsets = array(); + foreach ($this->acceptedtypes[$supertype][$subtype] as $acceptedtype) { + if (count($acceptedtype['EXTENSIONS']) == 0) { + $qvalues[] = $acceptedtype['QUALITY']; + $paramsets[] = $acceptedtype['PARAMS']; + } + } + + array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, + $paramsets, SORT_DESC, SORT_STRING); + + return $paramsets; + } + + /** + * Gets the extension sets for a given mime type, sorted by quality. + * Only extension sets where the parameter set is empty will be returned. + * + * @access public + * @return array list of sets of name=>value extension pairs + * in decreasing order of quality factor + * @param string $mimetype The MIME Type to query ("text/html") + */ + function getExtensionSets($mimetype) + { + $type = explode("/", $mimetype); + $supertype = strtolower($type[0]); + $subtype = strtolower($type[1]); + + if (!isset($this->acceptedtypes[$supertype]) + || !isset($this->acceptedtypes[$supertype][$subtype])) + return array(); + + $qvalues = array(); + $extensionsets = array(); + foreach ($this->acceptedtypes[$supertype][$subtype] as $acceptedtype) { + if (count($acceptedtype['PARAMS']) == 0) { + $qvalues[] = $acceptedtype['QUALITY']; + $extensionsets[] = $acceptedtype['EXTENSIONS']; + } + } + + array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, + $extensionsets, SORT_DESC, SORT_STRING); + + return $extensionsets; + } + + /** + * Adds a type to the set of accepted types + * + * @access public + * @param string $mimetype The MIME Type to add (e.g. "text/html") + * @param double $quality The quality value for the given MIME Type + * Quality values are in the range [0,1] where + * 0 means "not accepted" and 1 is + * "perfect quality". + * @param array $params Parameters of the type to add (e.g. [level => 4]) + * @param array $extensions Extension parameters of the type to add + */ + function addType($mimetype, $quality = 1, + $params = array(), $extensions = array()) + { + $type = explode("/", $mimetype); + $supertype = strtolower($type[0]); + $subtype = strtolower($type[1]); + + if ($params == null) + $params = array(); + if ($extensions == null) + $extensions = array(); + + $index = $this->_findExactMatchIndex($supertype, $subtype, $params, $extensions); + + if ($index >= 0) { + $this->acceptedtypes[$supertype][$subtype][$index]['QUALITY'] = $quality; + } else { + if (!isset($this->acceptedtypes[$supertype])) + $this->acceptedtypes[$supertype] = array(); + if (!isset($this->acceptedtypes[$supertype][$subtype])) + $this->acceptedtypes[$supertype][$subtype] = array(); + + $this->acceptedtypes[$supertype][$subtype][] = + array('PARAMS' => $params, + 'QUALITY' => $quality, + 'EXTENSIONS' => $extensions); + } + } + + /** + * Removes a type from the set of accepted types + * + * @access public + * @param string $mimetype The MIME Type to remove (e.g. "text/html") + * @param array $params Parameters of the type to remove (e.g. [level => 4]) + * @param array $extensions Extension parameters of the type to remove + */ + function removeType($mimetype, $params = array(), $extensions = array()) + { + $type = explode("/", $mimetype); + $supertype = strtolower($type[0]); + $subtype = strtolower($type[1]); + + if ($params == null) + $params = array(); + if ($extensions == null) + $extensions = array(); + + $index = $this->_findExactMatchIndex($supertype, $subtype, $params, $extensions); + + if ($index >= 0) { + $this->acceptedtypes[$supertype][$subtype] = + array_merge(array_slice($this->acceptedtypes[$supertype][$subtype], + 0, $index), + array_slice($this->acceptedtypes[$supertype][$subtype], + $index+1)); + } + } + + /** + * Gets a string representation suitable for use in an HTTP Accept header + * + * @access public + * @return string a string representation of this object + */ + function __toString() + { + $accepted = array(); + $qvalues = array(); + foreach ($this->acceptedtypes as $supertype => $subtypes) { + foreach ($subtypes as $subtype => $entries) { + foreach ($entries as $entry) { + $accepted[] = array('TYPE' => "$supertype/$subtype", + 'QUALITY' => $entry['QUALITY'], + 'PARAMS' => $entry['PARAMS'], + 'EXTENSIONS' => $entry['EXTENSIONS']); + $qvalues[] = $entry['QUALITY']; + } + } + } + + array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, + $accepted); + + $str = ""; + foreach ($accepted as $accept) { + // Skip the catchall value if it is 0, since this is implied + if ($accept['TYPE'] == '*/*' && + $accept['QUALITY'] == 0 && + count($accept['PARAMS']) == 0 && + count($accept['EXTENSIONS'] == 0)) + continue; + + $str = $str.$accept['TYPE'].';'; + + foreach ($accept['PARAMS'] as $param => $value) { + if (preg_match('/^'.$this->_matchtoken.'$/', $value)) + $str = $str.$param.'='.$value.';'; + else + $str = $str.$param.'="'.addcslashes($value,'"\\').'";'; + } + + if ($accept['QUALITY'] < 1 || !empty($accept['EXTENSIONS'])) + $str = $str.'q='.$accept['QUALITY'].';'; + + foreach ($accept['EXTENSIONS'] as $extension => $value) { + if (preg_match('/^'.$this->_matchtoken.'$/', $value)) + $str = $str.$extension.'='.$value.';'; + else + $str = $str.$extension.'="'.addcslashes($value,'"\\').'";'; + } + + $str[strlen($str)-1] = ','; + } + + return rtrim($str, ','); + } + + /** + * Finds the index of an exact match for the specified MIME Type + * + * @access private + * @return int the index of an exact match if found, + * -1 otherwise + * @param string $supertype The general MIME Type to find (e.g. "text") + * @param string $subtype The MIME subtype to find (e.g. "html") + * @param array $params Parameters of Type to find ([level => 4]) + * @param array $extensions Extension parameters to find + */ + function _findExactMatchIndex($supertype, $subtype, $params, $extensions) + { + if (empty($this->acceptedtypes[$supertype]) + || empty($this->acceptedtypes[$supertype][$subtype])) + return -1; + + $params = array_change_key_case($params, CASE_LOWER); + + $parammatches = array(); + foreach ($this->acceptedtypes[$supertype][$subtype] as $index => $typematch) + if ($typematch['PARAMS'] == $params + && $typematch['EXTENSIONS'] == $extensions) + return $index; + + return -1; + } + + /** + * Finds the indices of the best matches for the specified MIME Type + * + * A "match" in this context is an exact type match and no extraneous + * matches for parameters or extensions (so the best match for + * "text/html;level=4" may be "text/html" but not the other way around). + * + * "Best" is interpreted as the entries that match the most + * parameters and extensions (the sum of the number of matches) + * + * @access private + * @return array an array of the indices of the best matches + * (empty if no matches) + * @param string $supertype The general MIME Type to find (e.g. "text") + * @param string $subtype The MIME subtype to find (e.g. "html") + * @param array $params Parameters of Type to find ([level => 4]) + * @param array $extensions Extension parameters to find + */ + function _findBestMatchIndices($supertype, $subtype, $params, $extensions) + { + $bestmatches = array(); + $bestlength = 0; + + if (empty($this->acceptedtypes[$supertype]) + || empty($this->acceptedtypes[$supertype][$subtype])) + return $bestmatches; + + foreach ($this->acceptedtypes[$supertype][$subtype] as $index => $typematch) { + if (count(array_diff_assoc($typematch['PARAMS'], $params)) == 0 + && count(array_diff_assoc($typematch['EXTENSIONS'], + $extensions)) == 0) { + $length = count($typematch['PARAMS']) + + count($typematch['EXTENSIONS']); + + if ($length > $bestlength) { + $bestmatches = array($index); + $bestlength = $length; + } else if ($length == $bestlength) { + $bestmatches[] = $index; + } + } + } + + return $bestmatches; + } +} + +// vim: set ts=4 sts=4 sw=4 et: +?> diff --git a/lpf/ext/README.txt b/lpf/ext/README.txt new file mode 100644 index 0000000..c8eddb6 --- /dev/null +++ b/lpf/ext/README.txt @@ -0,0 +1,11 @@ +These are class files that I've gathered from around the internet. + +I've renamed the files to follow a standard scheme. + +This is where each file came from: + +My Name : Original Name : From +HTTP_Accept.class.php : HTTP_Accept.php : http://kevinlocke.name/programs/http_accept.php + +~ Luke Shumaker +Happy Hacking! diff --git a/lpf/lib/Controller.class.php b/lpf/lib/Controller.class.php new file mode 100644 index 0000000..05736ee --- /dev/null +++ b/lpf/lib/Controller.class.php @@ -0,0 +1,30 @@ +show($vars); + } + + // Here be default handlers //////////////////////////////////////////// + + public function index($routed, $remainder) { + header('Content-type: text/plain'); + echo " == Generic Controller Index == \n\n"; + $routed_str = implode('/', $routed); + $remainder_str = implode('/', $remainder); + echo "Full path: $routed_str/$remainder_str\n"; + echo "Controller path: $routed_str\n"; + echo "Remainder path: $remainder_str\n"; + } + public function http404($routed, $remainder) { + $this->showView('http404', array('routed'=>$routed, + 'remainder'=>$remainder)); + } +} diff --git a/lpf/lib/Mime.class.php b/lpf/lib/Mime.class.php new file mode 100644 index 0000000..f37c1eb --- /dev/null +++ b/lpf/lib/Mime.class.php @@ -0,0 +1,45 @@ + array( + 'text/csv', 'text/x-csv', + 'text/x-comma-separated-values', + 'text/comma-separated-values', + 'application/csv', + 'application/excel', 'application/vnd.msexcel'), + 'xhtml' => array('text/html', 'application/xhtml+xml'), + 'html' => array('text/html', 'application/xhtml+xml'), + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'png' => array('image/png', 'image/x-png'), + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'htm' => 'text/html', + 'txt' => 'text/plain', + 'json' => array('application/json', 'text/json') + ); + + public static function ext2mime($ext) { + $mimes = self::$mimes; + $mime = $mimes[$ext]; + if (!is_array($mime)) $mime = array($mime); + return $mime; + } + public static function mime2ext($my_mime) { + $ret = array(); + foreach (self::mimes as $ext => $mime) { + if (is_array($mime)) { + $match = in_array($my_mime, $mime); + } else { + $match = $my_mime==$mime; + } + if ($match) $ret[] = $ext; + } + return $ret; + } +} \ No newline at end of file diff --git a/lpf/lib/Model.class.php b/lpf/lib/Model.class.php new file mode 100644 index 0000000..0cce525 --- /dev/null +++ b/lpf/lib/Model.class.php @@ -0,0 +1,9 @@ +db = Database::getInstance(); + } +} diff --git a/lpf/lib/Router.class.php b/lpf/lib/Router.class.php new file mode 100644 index 0000000..238e3f8 --- /dev/null +++ b/lpf/lib/Router.class.php @@ -0,0 +1,110 @@ + 'Http404'); + + /** + * Instantiate a router that looks for controllers in $controllerpath. + */ + public function Router($controllerpath) { + // create a $ROUTES global that can be used to set up our + // $this->routes. + global $ROUTES; + $ROUTES = $this->routes; + + // Split $controllerpath into directories, and load the + // controllers in each. + $dirs = explode(PATH_SEPARATOR, $controllerpath); + foreach ($dirs as $dir) { + // Find all files in $dir with the ext `.class.php' + $files = glob($dir.'/*.class.php'); + foreach ($files as $file) { + // and include them + require_once($file); + } + } + + $this->routes = $ROUTES; + unset($ROUTES); + } + + /** + * Route the page at the relative URL $page to the appropriate + * controller, and call the appropriate function. + */ + public function route($page) { + $parts = explode('/', $page); + $length = count($parts); // the # of segments in $controllerpart + + // if $page ends in "/", strip that off + if ($parts[$length-1]=='') { + array_pop($parts); + $length--; + } + + $controllerpart = implode('/', $parts); + + // Keep shortening $controllerpart until it matches something in + // $this->routes. The shortest it will ever become is '/*'. + // If no key exists for '/*', that's an infinite loop. + // Fortunately, the default value of $this->routes directs '/*' + // to the Http404 controller. + while(!isset($this->routes[$controllerpart])) { + $some_parts = array_slice($parts, 0, $length); + $controllerpart = implode('/', $some_parts).'/*'; + $length--; + } + $length++; + + // Figure what function to call on what controller + // Grammar Nazi Warning: `what' or `which'? + $controller = $this->routes[$controllerpart]; + if (strpos($controller, '->')===false) { + // imply function + $function = $parts[$length]; + } else { + preg_match('/(.*)->(.*)/', $controller, $matches); + $controller = $matches[1]; + $function = $matches[2]; + } + + // Default to the `index' function, provided by all controllers + if ($function=='') { + $function = 'index'; + } + + // We will pass these arrays to the function. + $routed = array_slice($parts, 0, $length); + $remainder = array_slice($parts, $length); + + // Finally, run the controller + $obj = new $controller(); + if (in_array($function, get_class_methods($obj))) { + call_user_func(array($obj, $function), + $routed, $remainder); + } else { + $obj->http404($routed, $remainder); + } + } + + /** + * This is to allow controllers to register themselves to the router. + * If $function=='', then the function will be determined by the segment + * to the right of the last segment in $path + */ + public static function register($path, $controller, $function='') { + $str = $controller.(($function=='')?'':'->'.$function); + global $ROUTES; + $ROUTES[$path] = $str; + } +} \ No newline at end of file diff --git a/lpf/lib/View.class.php b/lpf/lib/View.class.php new file mode 100644 index 0000000..d7a21d3 --- /dev/null +++ b/lpf/lib/View.class.php @@ -0,0 +1,135 @@ +extensions = array(); + $regex = '@'.preg_quote(VIEWPATH,'@').'[^.]*\.(.*)\.php$@'; + foreach ($files as $file) { + $ext = preg_replace($regex, '$1', $file); + $this->extensions[] = $ext; + } + if (count($this->extensions)<1) return false; + + if (PAGE_EXT != '') { + // First, do a check if we can just return requested + // file extension: + if (in_array(PAGE_EXT, $this->extensions)) { + return PAGE_EXT; + } + + // Check for other extensions with the same mime type as + // the requested: + $accept_str = implode(', ', Mime::ext2mime(PAGE_EXT)); + $extensions = $this->parseAccept($view, $accept_str); + if ($ext = $this->chooseBetweenEquals($extensions)) return $ext; + } + + // Check for other extensions based on HTTP 'Accept' headers: + $accept_str = $_SERVER['HTTP_ACCEPT']; + $extensions = $this->parseAccept($view, $accept_str); + if ($ext = $this->chooseBetweenEquals($extensions)) return $ext; + + // Well, all the good options failed, so let's see what we've + // got left: + $extensions = $this->extensions; + return $this->chooseBetweenEquals($extensions); + + } + + private function parseAccept($view, $accept_str) { + // $prefs is a associative array where the key is the file + // extension, and the value is how much we like that extension. + // Higher numbers are better. + $prefs = array(); + + $accept = new HTTP_Accept($accept_str); + + // Loop through the candidate views, and record how much we + // like each. + foreach ($this->extensions as $ext) { + $mimes = Mime::ext2mime($ext); + foreach ($mimes as $mime) { + $quality = $accept->getQuality($mime); + if (isset($prefs[$ext])) { + $quality = max($prefs[$ext], $quality); + } + $prefs[$ext] = $quality; + } + } + + // Create an array of all extensions tied for the top quality. + $ret = array(); + $top_quality = 0.001;// minimum acceptable according to RFC 2616 + foreach ($prefs as $ext => $quality) { + if ($quality > $top_quality) { + $top_quality = $quality; + $ret = array(); + } + if ($quality == $top_quality) { + $ret[] = $ext; + } + } + return $ret; + } + + public function __construct($view) { + $this->ext = $this->chooseExtension($view); + $this->view = $view; + } + + public function show($vars) { + $file = self::filename($this->view, $this->ext); + $mimes = Mime::ext2mime($this->ext); + + header('Content-type: '.$mimes[0]); + + require_once(VIEWPATH.'/Template.class.php'); + $vars['template'] = new Template(); + + global $VARS; + $VARS = $vars; + include($file); + unset($VARS); + } +} diff --git a/lpf/views/pages/no-conf.html.php b/lpf/views/pages/no-conf.html.php new file mode 100644 index 0000000..1f4e3d3 --- /dev/null +++ b/lpf/views/pages/no-conf.html.php @@ -0,0 +1,8 @@ +header('Message Manager'); +$t->paragraph('Awe shiz, dude, conf.php doesn\'t exist, you '. + 'need to go through the '. + 'installer.'); +$t->footer(); diff --git a/src/controllers/AuthPage.class.php b/src/controllers/AuthPage.class.php deleted file mode 100644 index 1f46f72..0000000 --- a/src/controllers/AuthPage.class.php +++ /dev/null @@ -1,57 +0,0 @@ -login(); break; - case 'logout': $this->logout(); break; - case '' : $this->maybe_login(); break; - default : $this->badrequest(); break; - } - } - private function login() { - $username = ''; - $password = ''; - - $login = -1; - if ( isset($_POST['username']) && isset($_POST['password'])) { - $username = $_POST['username']; - $password = $_POST['password']; - $login = Login::login($username, $password); - } - - $vars = array(); - $vars['login_code'] = $login; - $vars['username'] = $username; - $vars['password'] = $password; - if (isset($_POST['url'])) { - $vars['url'] = $_POST['url']; - } - - $this->showView('auth/login', $vars); - } - private function logout() { - Login::logout(); - $this->showView('auth/logout'); - } - private function maybe_login() { - $uid = Login::isLoggedIn(); - if ($uid===false) { - $this->login(); - } else { - $username = Auth::getInstance($uid)->getName(); - $this->showView('auth/index', - array('username'=>$username)); - } - } - private function badrequest() { - $this->showView('auth/badrequest'); - } -} diff --git a/src/controllers/Config.class.php b/src/controllers/Config.class.php deleted file mode 100644 index dc6a884..0000000 --- a/src/controllers/Config.class.php +++ /dev/null @@ -1,30 +0,0 @@ -isAdmin()) { - $this->http401($routed, $remainder); - return; - } - - $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { - case 'PUT': $_POST = $_PUT; - case 'POST': - // We're PUTing an updated configuration. - $this->update(); - break; - } - $this->show_index(); - } - private function show_index() { - - } - private function update() { - - } -} diff --git a/src/controllers/Groups.class.php b/src/controllers/Groups.class.php deleted file mode 100644 index 9d99d99..0000000 --- a/src/controllers/Groups.class.php +++ /dev/null @@ -1,11 +0,0 @@ -http404($routed, $remainder); - } -} diff --git a/src/controllers/Main.class.php b/src/controllers/Main.class.php deleted file mode 100644 index 7651b62..0000000 --- a/src/controllers/Main.class.php +++ /dev/null @@ -1,9 +0,0 @@ -showView('index'); - } -} diff --git a/src/controllers/Messages.class.php b/src/controllers/Messages.class.php deleted file mode 100644 index 717e18e..0000000 --- a/src/controllers/Messages.class.php +++ /dev/null @@ -1,100 +0,0 @@ -msgdir = BASEPATH.'/msg'; - } - - public function index($routed, $remainder) { - $parser = new MimeMailParser(); - $messages = array(); - $dh = opendir($this->msgdir); - while (($file = readdir($dh)) !== false) { - $path = $this->msgdir."/$file"; - if (is_file($path)) { - $parser->setPath($path); - - $date_string = $parser->getHeader('date'); - $date = strtotime($date_string); - if (!isset($messages[$date])) { - $messages[$date] = array(); - } - $messages[$date][] = - array('id'=>$file, - 'subject'=>$parser->getHeader('subject'), - 'from'=>$parser->getHeader('from')); - } - } - closedir($dh); - - $this->showView('messages/index', array('messages' => $messages)); - exit(); - } - - public function message($routed, $remainder) { - $uid = Login::isLoggedIn(); - if ($uid===false || !Auth::getInstance($uid)->isUser()) { - $this->http401($routed, $remainder); - return; - } - - $msg_id = $remainder[0];// We can trust the router that this is set - $msg_file = $this->msgdir."/$msg_id"; - if (!is_file($msg_file)) { - $this->http404($routed, $remainder); - return; - } - - @$part = $remainder[1]; - @$subpart = $remainder[2]; - $parser = new MimeMailParser(); - $parser->setPath($msg_file); - - switch ($part) { - case '': - $this->showView('messages/frame', - array('msg_id'=>$msg_id, - 'parser'=>$parser, - 'msgdir'=>$this->msgdir, - )); - break; - case 'body': - require_once('Mime.class.php'); - header('Content-type: '.Mime::ext2mime(PAGE_EXT)); - $map = array('html'=>'html', - 'txt' =>'text'); - echo $parser->getMessageBody($map[PAGE_EXT]); - break; - case 'attachment': - $attachment_id = $subpart; - $attachments = $parser->getAttachments(); - $attachment = $attachments[$attachment_id]; - - $type = $attachment->getContentType(); - $filename = $attachment->getFilename(); - - header('Content-Type: '.$type); - header('Content-Disposition: attachment; filename='.$filename ); - while($bytes = $attachment->read()) { - echo $bytes; - } - break; - default: - array_push($routed, array_shift($remainder)); - $this->http404($routed, $remainder); - } - } - - public function http401($routed, $remainder) { - $this->showView('messages/401', array('uid'=>Login::isLoggedIn())); - } -} \ No newline at end of file diff --git a/src/controllers/NewMessage.class.php b/src/controllers/NewMessage.class.php deleted file mode 100644 index e778385..0000000 --- a/src/controllers/NewMessage.class.php +++ /dev/null @@ -1,37 +0,0 @@ -setPath($tmpfile); - $id = preg_replace('/<(.*)>/', '$1', - $parser->getHeader('message-id')); - $id = str_replace('/', '', $id); // for security reasons - $msg_file = "$BASE/msg/$id"; - rename($tmpfile, $msg_file); - - if (!$cmdline) { - $m->status('201 Created'); - header("Location: ".$m->baseUrl().'messages/'.$id); - } - exit(); -} - -} - */ \ No newline at end of file diff --git a/src/controllers/Plugins.class.php b/src/controllers/Plugins.class.php deleted file mode 100644 index 2ed6e7a..0000000 --- a/src/controllers/Plugins.class.php +++ /dev/null @@ -1,75 +0,0 @@ -isAdmin()) { - $this->http401($routed, $remainder); - return; - } - - $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { - case 'PUT': $_POST = $_PUT; - case 'POST': - // We're PUTing an updated user index. - $this->update(); - break; - } - $this->show_index(); - } - - private function update() { - $db = Database::getInstance(); - - if (isset($_POST['plugins'])) { - $string = $db->arrayToValue($_POST['plugins']); - $db->setSysConf('plugins', $string); - } - - if (isset($_POST['config'])) { - foreach ($_POST['config'] as $plugin_name => $plugin) { - foreach ($plugin as $param => $value) { - $db->setPluginConf($plugin_name, - $param, - $value); - } - } - } - } - - private function show_index() { - $pm = PluginManager::getInstance(); - $all_plugins = $pm->listPlugins(); - $enabled_plugins = $pm->getActivePlugins(); - - $plugin_data = array(); - foreach ($all_plugins as $plugin_name) { - $plugin = array(); - $plugin['name'] = $plugin_name; - $plugin['key'] = 'config['.$plugin_name.']'; - $plugin['active'] = - in_array($plugin_name, $enabled_plugins); - $plugin['description'] = - $pm->staticHook($plugin_name, 'description'); - $plugin['config'] = - $pm->staticHook($plugin_name, 'configList'); - $plugin_data[] = $plugin; - } - - $vars = array(); - $vars['plugins'] = $plugin_data; - $this->showView('plugins/index', $vars); - } - - public function http401($routed, $remainder) { - $this->showView('plugins/401'); - } -} diff --git a/src/controllers/Users.class.php b/src/controllers/Users.class.php deleted file mode 100644 index 9978ef8..0000000 --- a/src/controllers/Users.class.php +++ /dev/null @@ -1,371 +0,0 @@ -index_dir($routed, $remainder); - } - - /** - * Handle POSTing a new user, or GETing the index. - */ - public function index_dir($routed, $remainder) { - $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { - case 'POST': - // We're POSTing a new user. - if ($this->registrationOpen()) { - $this->create_user(); - } else { - $this->showView('users/new-locked', array()); - exit(); - } - break; - case 'HEAD': // fall-through to GET - case 'GET': - // We're GETing the index. - $this->show_index($routed, $remainder); - break; - } - } - - /** - * Handle PUTing an updated user index, or GETing the index. - */ - public function index_file($routed, $remainder) { - $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { - case 'PUT': $_POST = $_PUT; - case 'POST': - // We're PUTing an updated user index. - $this->update_users(); - break; - } - $this->show_index($routed, $remainder); - } - - // Other Views /////////////////////////////////////////////// - - /** - * Handle GETing the new user form. - * - * I would have named this `new', but that's a keyword. - */ - public function new_user($routed, $vars) { - // since there will never be a remainder to `users/new', we can - // use that parameter to pass in some data. - if (Login::isLoggedIn()) { - $this->showView('users/new-logged-in', array()); - exit(); - } - if (!$this->registrationOpen()) { - $this->showView('users/new-locked', array()); - exit(); - } - if (!isset($vars['errors'])) $vars['errors'] = array(); - - $db = Database::getInstance(); - $pm = PluginManager::getInstance(); - - $vars['antispam_html'] = $pm->callHook('antispam_html'); - $vars['userlist'] = $db->getSysConf('anon_userlist'); - $this->showView('users/new', $vars); - } - - public function individual($routed, $remainder) { - $db = Database::getInstance(); - $pm = PluginManager::getInstance(); - - $username = implode('/', $remainder); - if ($username == 'all') { - $uids = $db->listUsers(); - } else { - $uids = array($db->getUID($username)); - } - - $vars = array(); - - if (count($uids)<2) { - $user = Auth::getInstance($uid); - - if ($user->isGroup()) $uid = false; // ignore groups. - - if ($uid===false) { - $this->http404($routed, $remainder); - exit(); - } - if (!$user->canRead()) { - $this->http401($routed, $remainder); - exit(); - } - - $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { - case 'PUT': $_POST = $_PUT; - case 'POST': - // We're PUTing updated user info. - if ($user->canEdit()) { - $vars = $this->update_user($user); - } - break; - } - } - - $config_options = array(); - $pm->callHook('userConfig', &$config_options); - - $vars['users'] = array(); - foreach ($uids as $uid) { - $vars['users'][] = Auth::getInstance($uid); - } - $vars['username'] = $username; - $vars['config_options'] = $config_options; - $vars['groups'] = $db->listGroupNames(); - require_once('ContactMethod.class.php'); - $this->showView('users/individual', $vars); - } - - public function http404($routed, $remainder) { - $username = implode('/', $remainder); - $this->showView('users/404', - array('username'=>$username)); - } - - public function http401($routed, $remainder) { - $this->showView('users/401', array('uid'=>Login::isLoggedIn())); - } - - // Other Functions /////////////////////////////////////////// - - /** - * This will parse POST data to create a new user. - * If successfull it will show a message saying so. - * If not successfull, it will re-show the new-user form with errors - * explained. - */ - private function create_user() { - $db = Database::getInstance(); - $pm = PluginManager::getInstance(); - - $vars = array(); - @$vars['username' ] = $_POST['auth_name']; - @$vars['password1'] = $_POST['auth_password' ]; - @$vars['password2'] = $_POST['auth_password_verify']; - @$vars['email'] = $_POST['user_email']; - - $vars['errors'] = array(); - if ($db->getUID($vars['username'])!==false) - $vars['errors'][] = 'user exists'; - if (!Auth::isNameLegal($vars['username'])) - $vars['errors'][] = 'illegal name'; - $matches = ($vars['password1'] == $vars['password2']); - if (!$matches) { - $vars['errors'][] = 'pw mixmatch'; - } - if ($matches && $vars['password2'] == '') { - $vars['errors'][] = 'no pw'; - } - if ($vars['email'] == '') { - $vars['errors'][] = 'no email'; - } - foreach ($pm->callHook('antispam_verify') as $plugin=>$valid) { - if (!$valid) $vars['errors'][] = 'plugin_'.$plugin; - } - - if (count($vars['errors']) > 0) { - $this->new_user($routed, $vars); - } else { - $username = $vars['username']; - $password = $vars['password1']; - $uid = $db->addUser($username, $password); - if ($uid===false) { - $this->showView('users/500'); - } else { - Login::login($username, $password); - DB::set('users', $uid, 'email', $vars['email']); - $this->showView('users/created', - array('username'=>$username)); - } - } - } - - /** - * This will parse POST (really, PUT) data to update a single user - */ - private function update_user($user) { - $vars = array(); - - $username = $user->getName(); - // Change the username ///////////////////////////////////////// - if (isset($_POST['auth_name'])) { - $new_name = $_POST['auth_name']; - if ($new_name != $username) { - $changed_name = $user->setName($new_name); - $username = $user->getName(); - $vars['changed name'] = $changed_name; - } - } - - // Change the password ///////////////////////////////////////// - @$password1 = $_POST['auth_password' ]; - @$password2 = $_POST['auth_password'.'_verify']; - - // Check the verify box, not main box, so that we don't get - // tripped by browsers annoyingly autocompleting the password. - $is_set = ($password2 != ''); - - if ($is_set) { - $matches = ( $password1 == $password2 ); - if ($matches) { - $user->setPassword($password1); - $vars['pw updated'] = true; - } else { - $vars['pw mixmatch'] = true; - } - } - - // Change information ////////////////////////////////////////// - $config_options = array(); - $pm = PluginManager::getInstance(); - $pm->callHook('userConfig', &$config_options); - - foreach ($config_options as $group=>$options) { - foreach ($options as $option) { - $this->confText($user, $option[0]); - } - } - - // Change contact info ///////////////////////////////////////// - global $CONTACT_METHODS; - foreach ($CONTACT_METHODS as $method) { - $this->confText($user, $method->addr_slug); - } - $this->confArray($user, 'use'); - - // Change groups /////////////////////////////////////////////// - $this->confArray($user, 'groups'); - - return $vars; - } - - private function confArray($user, $key) { - if (isset($_POST[$key]) && is_array($_POST[$key])) { - $user->setConfArray($key, $_POST[$key]); - } - } - - private function confText($user, $name) { - if (isset($_POST["user_$name"])) { - $user->setConf($name, $_POST["user_$name"]); - } - } - - - /** - * This will parse POST (really, PUT) data to update multiple users. - */ - private function update_users() { - $attribs = $this->getIndexAttribs(); - $form = new Form(null, null); - foreach ($attribs as $attrib) { - $key = $attrib['key']; - if (isset($_POST[$key]) && is_array($_POST[$key])) { - $old = $_POST['_old'][$key]; - foreach ($_POST[$key] as $uid => $value) { - @$value_base = $old[$uid]; - $set = DB::set('users', $uid, $key, $value, $value_base); - if (is_string($set)) { - echo "
\n";
-						echo "Error: Value changed elsewhere, ".
-							"and I don't have real handling ".
-							"for this yet.\n";
-						echo "UID: $uid\n";
-						echo "Name: ".$user->getName()."\n";
-						echo "Key: $key\n";
-						echo "Value: Original  : ";
-						var_dump($value_base);
-						echo "Value: Other edit: ";
-						var_dump($value_fork);
-						echo "Value: This edit : ";
-						var_dump($value);
-						echo "
"; - } - } - } - } - } - - /** - * This will show the user index. - */ - private function show_index($routed, $remainder) { - $db = Database::getInstance(); - - $logged_in_user = Auth::getInstance(Login::isLoggedIn()); - $anon_userlist = $db->getSysConf('anon_userlist')=='true'; - if (!$anon_userlist && !$logged_in_user->isUser()) { - $this->http401($routed, $remainder); - exit(); - } - - $vars = array(); - $vars['attribs'] = $this->getIndexAttribs(); - $vars['users'] = array(); - $uids = $db->listUsers(); - foreach ($uids as $uid) { - $vars['users'][$uid] = array(); - foreach ($vars['attribs'] as $attrib) { - $key = $attrib['key']; - $props = DB::get('users', $uid, $key); - $vars['users'][$uid][$key] = $props; - } - } - $this->showView('users/index', $vars); - } - - function attrib($key, $name, $type='string') { - return array('key'=>$key, 'name'=>$name, 'type'=>$type); - } - private function getIndexAttribs() { - $user = Auth::getInstance(Login::isLoggedIn()); - - $attribs = array(); - $attribs[] = $this->attrib('auth_uid', 'UID'); - if ($user->isUser()) { - $attribs[] = $this->attrib('auth_user', 'Active', 'bool'); - if ($user->isAdmin()) { - $attribs[] = $this->attrib('auth_admin', 'Admin', 'bool'); - $attribs[] = $this->attrib('auth_delete', 'Delete', 'bool'); - } - $attribs[] = $this->attrib('lastname','Last'); - $attribs[] = $this->attrib('firstname','First'); - $attribs[] = $this->attrib('hsclass','Class of'); - $attribs[] = $this->attrib('phone','Phone number'); - $attribs[] = $this->attrib('email','Email'); - } - $attribs[] = $this->attrib('auth_name', 'Username'); - - return $attribs; - } - - private function registrationOpen() { - $db = Database::getInstance(); - $val = $db->getSysConf('registration_open'); - switch ($val) { - case 'true': return true; - case 'false': return false; - default: return true; - } - } -} diff --git a/src/ext/GoogleVoice.class.php b/src/ext/GoogleVoice.class.php deleted file mode 100644 index 9638416..0000000 --- a/src/ext/GoogleVoice.class.php +++ /dev/null @@ -1,84 +0,0 @@ -username = $username; - $this->password = $password; - } - - public function getLoginAuth() - { - $login_param = "accountType=GOOGLE&Email={$this->username}&Passwd={$this->password}&service=grandcentral&source=com.lostleon.GoogleVoiceTool"; - $ch = curl_init($this->loginURL); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11 Safari/525.20"); - curl_setopt($ch, CURLOPT_REFERER, $this->lastURL); - curl_setopt($ch, CURLOPT_POST, "application/x-www-form-urlencoded"); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $login_param); - $html = curl_exec($ch); - $this->lastURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - curl_close($ch); - $this->login_auth = $this->match('/Auth=([A-z0-9_-]+)/', $html, 1); - return $this->login_auth; - } - - public function get_rnr_se() - { - $this->getLoginAuth(); - $ch = curl_init($this->inboxURL); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - $headers = array("Authorization: GoogleLogin auth=".$this->login_auth, 'User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11 Safari/525.20'); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - $html = curl_exec($ch); - $this->lastURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - curl_close($ch); - $_rnr_se = $this->match('!get_rnr_se(); - $sms_param = "id=&c=&number=".urlencode($to_phonenumber)."&smstext=".urlencode($smstxt)."&_rnr_se=".urlencode($_rnr_se); - $ch = curl_init($this->smsURL); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - $headers = array("Authorization: GoogleLogin auth=".$this->login_auth, 'User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5H11 Safari/525.20'); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_REFERER, $this->lastURL); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $sms_param); - $this->status = curl_exec($ch); - $this->lastURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); - curl_close($ch); - return $this->status; - } - - private function match($regex, $str, $out_ary = 0) - { - return preg_match($regex, $str, $match) == 1 ? $match[$out_ary] : false; - } -} -?> diff --git a/src/ext/HTTP_Accept.class.php b/src/ext/HTTP_Accept.class.php deleted file mode 100644 index 5efaa5d..0000000 --- a/src/ext/HTTP_Accept.class.php +++ /dev/null @@ -1,659 +0,0 @@ - - * @copyright 2007 Kevin Locke - * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @version SVN: $Id: HTTP_Accept.php 22 2007-10-06 18:46:45Z kevin $ - * @link http://pear.php.net/package/HTTP_Accept - */ - -/** - * HTTP_Accept class for dealing with the HTTP 'Accept' header - * - * This class is intended to be used to parse the HTTP Accept header into - * usable information and provide a simple API for dealing with that - * information. - * - * The parsing of this class is designed to follow RFC 2616 to the letter, - * any deviations from that standard are bugs and should be reported to the - * maintainer. - * - * Often the class will be used very simply as - * - * getQuality("image/png") > $accept->getQuality("image/jpeg")) - * // Send PNG image - * else - * // Send JPEG image - * ?> - * - * - * However, for browsers which do not accurately describe their preferences, - * it may be necessary to check if a MIME Type is explicitly listed in their - * Accept header, in addition to being preferred to another type - * - * - * isMatchExact("application/xhtml+xml")) - * // Client specifically asked for this type at some quality level - * ?> - * - * - * - * @category HTTP - * @package HTTP_Accept - * @access public - * @link http://pear.php.net/package/HTTP_Accept - */ -class HTTP_Accept -{ - /** - * Array of types and their associated parameters, extensions, and quality - * factors, as represented in the Accept: header. - * Indexed by [type][subtype][index], - * and contains 'PARAMS', 'QUALITY', and 'EXTENSIONS' keys for the - * parameter set, quality factor, and extensions set respectively. - * Note: Since type, subtype, and parameters are case-insensitive - * (RFC 2045 5.1) they are stored as lower-case. - * - * @var array - * @access private - */ - var $acceptedtypes = array(); - - /** - * Regular expression to match a token, as defined in RFC 2045 - * - * @var string - * @access private - */ - var $_matchtoken = '(?:[^[:cntrl:]()<>@,;:\\\\"\/\[\]?={} \t]+)'; - - /** - * Regular expression to match a quoted string, as defined in RFC 2045 - * - * @var string - * @access private - */ - var $_matchqstring = '(?:"[^\\\\"]*(?:\\\\.[^\\\\"]*)*")'; - - /** - * Constructs a new HTTP_Accept object - * - * Initializes the HTTP_Accept class with a given accept string - * or creates a new (empty) HTTP_Accept object if no string is given - * - * Note: The behavior is a little strange here to accomodate - * missing headers (to be interpreted as accept all) as well as - * new empty objects which should accept nothing. This means that - * HTTP_Accept("") will be different than HTTP_Accept() - * - * @access public - * @return object HTTP_Accept - * @param string $acceptstring The value of an Accept: header - * Will often be $_SERVER['HTTP_ACCEPT'] - * Note: If get_magic_quotes_gpc is on, - * run stripslashes() on the string first - */ - function HTTP_Accept() - { - if (func_num_args() == 0) { - // User wishes to create empty HTTP_Accept object - $this->acceptedtypes = array( - '*' => array( - '*' => array ( - 0 => array( - 'PARAMS' => array(), - 'QUALITY' => 0, - 'EXTENSIONS' => array() - ) - ) - ) - ); - return; - } - - $acceptstring = trim(func_get_arg(0)); - if (empty($acceptstring)) { - // Accept header empty or not sent, interpret as "*/*" - $this->acceptedtypes = array( - '*' => array( - '*' => array ( - 0 => array( - 'PARAMS' => array(), - 'QUALITY' => 1, - 'EXTENSIONS' => array() - ) - ) - ) - ); - return; - } - - $matches = preg_match_all( - '/\s*('.$this->_matchtoken.')\/' . // typegroup/ - '('.$this->_matchtoken.')' . // subtype - '((?:\s*;\s*'.$this->_matchtoken.'\s*' . // parameter - '(?:=\s*' . // optional =value - '(?:'.$this->_matchqstring.'|'.$this->_matchtoken.'))?)*)/', // value - $acceptstring, $acceptedtypes, - PREG_SET_ORDER); - - if ($matches == 0) { - // Malformed Accept header - $this->acceptedtypes = array( - '*' => array( - '*' => array ( - 0 => array( - 'PARAMS' => array(), - 'QUALITY' => 1, - 'EXTENSIONS' => array() - ) - ) - ) - ); - return; - } - - foreach ($acceptedtypes as $accepted) { - $typefamily = strtolower($accepted[1]); - $subtype = strtolower($accepted[2]); - - // */subtype is invalid according to grammar in section 14.1 - // so we ignore it - if ($typefamily == '*' && $subtype != '*') - continue; - - // Parse all arguments of the form "key=value" - $matches = preg_match_all('/;\s*('.$this->_matchtoken.')\s*' . - '(?:=\s*' . - '('.$this->_matchqstring.'|'. - $this->_matchtoken.'))?/', - $accepted[3], $args, - PREG_SET_ORDER); - - $params = array(); - $quality = -1; - $extensions = array(); - foreach ($args as $arg) { - array_shift($arg); - if (!empty($arg[1])) { - // Strip quotes (Note: Can't use trim() in case "text\"") - $len = strlen($arg[1]); - if ($arg[1][0] == '"' && $arg[1][$len-1] == '"' - && $len > 1) { - $arg[1] = substr($arg[1], 1, $len-2); - $arg[1] = stripslashes($arg[1]); - } - } else if (!isset($arg[1])) { - $arg[1] = null; - } - - // Everything before q=# is a parameter, after is an extension - if ($quality >= 0) { - $extensions[$arg[0]] = $arg[1]; - } else if ($arg[0] == 'q') { - $quality = (float)$arg[1]; - - if ($quality < 0) - $quality = 0; - else if ($quality > 1) - $quality = 1; - } else { - $arg[0] = strtolower($arg[0]); - // Values required for parameters, - // assume empty-string for missing values - if (isset($arg[1])) - $params[$arg[0]] = $arg[1]; - else - $params[$arg[0]] = ""; - } - } - - if ($quality < 0) - $quality = 1; - else if ($quality == 0) - continue; - - if (!isset($this->acceptedtypes[$typefamily])) - $this->acceptedtypes[$typefamily] = array(); - if (!isset($this->acceptedtypes[$typefamily][$subtype])) - $this->acceptedtypes[$typefamily][$subtype] = array(); - - $this->acceptedtypes[$typefamily][$subtype][] = - array('PARAMS' => $params, - 'QUALITY' => $quality, - 'EXTENSIONS' => $extensions); - } - - if (!isset($this->acceptedtypes['*'])) - $this->acceptedtypes['*'] = array(); - if (!isset($this->acceptedtypes['*']['*'])) - $this->acceptedtypes['*']['*'] = array( - 0 => array( - 'PARAMS' => array(), - 'QUALITY' => 0, - 'EXTENSIONS' => array() - ) - ); - } - - /** - * Gets the accepted quality factor for a given MIME Type - * - * Note: If there are multiple best matches - * (e.g. "text/html;level=4;charset=utf-8" matching both "text/html;level=4" - * and "text/html;charset=utf-8"), it returns the lowest quality factor as - * a conservative estimate. Further, if the ambiguity is between parameters - * and extensions (e.g. "text/html;level=4;q=1;ext=foo" matching both - * "text/html;level=4" and "text/html;q=1;ext=foo") the parameters take - * precidence. - * - * Usage Note: If the quality factor for all supported media types is 0, - * RFC 2616 specifies that applications SHOULD send an HTTP 406 (not - * acceptable) response. - * - * @access public - * @return double the quality value for the given MIME Type - * Quality values are in the range [0,1] where 0 means - * "not accepted" and 1 is "perfect quality". - * @param string $mimetype The MIME Type to query ("text/html") - * @param array $params Parameters of Type to query ([level => 4]) - * @param array $extensions Extension parameters to query - */ - function getQuality($mimetype, $params = array(), $extensions = array()) - { - $type = explode("/", $mimetype); - $supertype = strtolower($type[0]); - $subtype = strtolower($type[1]); - - if ($params == null) - $params = array(); - if ($extensions == null) - $extensions = array(); - - if (empty($this->acceptedtypes[$supertype])) { - if ($supertype == '*') - return 0; - else - return $this->getQuality("*/*", $params, $extensions); - } - - if (empty($this->acceptedtypes[$supertype][$subtype])) { - if ($subtype == '*') - return $this->getQuality("*/*", $params, $extensions); - else - return $this->getQuality("$supertype/*", $params, $extensions); - } - - $params = array_change_key_case($params, CASE_LOWER); - - $matches = $this->_findBestMatchIndices($supertype, $subtype, - $params, $extensions); - - if (count($matches) == 0) { - if ($subtype != '*') - return $this->getQuality("$supertype/*", $params, $extensions); - else if ($supertype != '*') - return $this->getQuality("*/*", $params, $extensions); - else - return 0; - } - - $minquality = 1; - foreach ($matches as $match) - if ($this->acceptedtypes[$supertype][$subtype][$match]['QUALITY'] < $minquality) - $minquality = $this->acceptedtypes[$supertype][$subtype][$match]['QUALITY']; - - return $minquality; - } - - /** - * Determines if there is an exact match for the specified MIME Type - * - * @access public - * @return boolean true if there is an exact match to the given - * values, false otherwise. - * @param string $mimetype The MIME Type to query (e.g. "text/html") - * @param array $params Parameters of Type to query (e.g. [level => 4]) - * @param array $extensions Extension parameters to query - */ - function isMatchExact($mimetype, $params = array(), $extensions = array()) - { - $type = explode("/", $mimetype); - $supertype = strtolower($type[0]); - $subtype = strtolower($type[1]); - - if ($params == null) - $params = array(); - if ($extensions == null) - $extensions = array(); - - return $this->_findExactMatchIndex($supertype, $subtype, - $params, $extensions) >= 0; - } - - /** - * Gets a list of all MIME Types explicitly accepted, sorted by quality - * - * @access public - * @return array list of MIME Types explicitly accepted, sorted - * in decreasing order of quality factor - */ - function getTypes() - { - $qvalues = array(); - $types = array(); - foreach ($this->acceptedtypes as $typefamily => $subtypes) { - if ($typefamily == '*') - continue; - - foreach ($subtypes as $subtype => $variants) { - if ($subtype == '*') - continue; - - $maxquality = 0; - foreach ($variants as $variant) - if ($variant['QUALITY'] > $maxquality) - $maxquality = $variant['QUALITY']; - - if ($maxquality > 0) { - $qvalues[] = $maxquality; - $types[] = $typefamily.'/'.$subtype; - } - } - } - - array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, - $types, SORT_DESC, SORT_STRING); - - return $types; - } - - /** - * Gets the parameter sets for a given mime type, sorted by quality. - * Only parameter sets where the extensions set is empty will be returned. - * - * @access public - * @return array list of sets of name=>value parameter pairs - * in decreasing order of quality factor - * @param string $mimetype The MIME Type to query ("text/html") - */ - function getParameterSets($mimetype) - { - $type = explode("/", $mimetype); - $supertype = strtolower($type[0]); - $subtype = strtolower($type[1]); - - if (!isset($this->acceptedtypes[$supertype]) - || !isset($this->acceptedtypes[$supertype][$subtype])) - return array(); - - $qvalues = array(); - $paramsets = array(); - foreach ($this->acceptedtypes[$supertype][$subtype] as $acceptedtype) { - if (count($acceptedtype['EXTENSIONS']) == 0) { - $qvalues[] = $acceptedtype['QUALITY']; - $paramsets[] = $acceptedtype['PARAMS']; - } - } - - array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, - $paramsets, SORT_DESC, SORT_STRING); - - return $paramsets; - } - - /** - * Gets the extension sets for a given mime type, sorted by quality. - * Only extension sets where the parameter set is empty will be returned. - * - * @access public - * @return array list of sets of name=>value extension pairs - * in decreasing order of quality factor - * @param string $mimetype The MIME Type to query ("text/html") - */ - function getExtensionSets($mimetype) - { - $type = explode("/", $mimetype); - $supertype = strtolower($type[0]); - $subtype = strtolower($type[1]); - - if (!isset($this->acceptedtypes[$supertype]) - || !isset($this->acceptedtypes[$supertype][$subtype])) - return array(); - - $qvalues = array(); - $extensionsets = array(); - foreach ($this->acceptedtypes[$supertype][$subtype] as $acceptedtype) { - if (count($acceptedtype['PARAMS']) == 0) { - $qvalues[] = $acceptedtype['QUALITY']; - $extensionsets[] = $acceptedtype['EXTENSIONS']; - } - } - - array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, - $extensionsets, SORT_DESC, SORT_STRING); - - return $extensionsets; - } - - /** - * Adds a type to the set of accepted types - * - * @access public - * @param string $mimetype The MIME Type to add (e.g. "text/html") - * @param double $quality The quality value for the given MIME Type - * Quality values are in the range [0,1] where - * 0 means "not accepted" and 1 is - * "perfect quality". - * @param array $params Parameters of the type to add (e.g. [level => 4]) - * @param array $extensions Extension parameters of the type to add - */ - function addType($mimetype, $quality = 1, - $params = array(), $extensions = array()) - { - $type = explode("/", $mimetype); - $supertype = strtolower($type[0]); - $subtype = strtolower($type[1]); - - if ($params == null) - $params = array(); - if ($extensions == null) - $extensions = array(); - - $index = $this->_findExactMatchIndex($supertype, $subtype, $params, $extensions); - - if ($index >= 0) { - $this->acceptedtypes[$supertype][$subtype][$index]['QUALITY'] = $quality; - } else { - if (!isset($this->acceptedtypes[$supertype])) - $this->acceptedtypes[$supertype] = array(); - if (!isset($this->acceptedtypes[$supertype][$subtype])) - $this->acceptedtypes[$supertype][$subtype] = array(); - - $this->acceptedtypes[$supertype][$subtype][] = - array('PARAMS' => $params, - 'QUALITY' => $quality, - 'EXTENSIONS' => $extensions); - } - } - - /** - * Removes a type from the set of accepted types - * - * @access public - * @param string $mimetype The MIME Type to remove (e.g. "text/html") - * @param array $params Parameters of the type to remove (e.g. [level => 4]) - * @param array $extensions Extension parameters of the type to remove - */ - function removeType($mimetype, $params = array(), $extensions = array()) - { - $type = explode("/", $mimetype); - $supertype = strtolower($type[0]); - $subtype = strtolower($type[1]); - - if ($params == null) - $params = array(); - if ($extensions == null) - $extensions = array(); - - $index = $this->_findExactMatchIndex($supertype, $subtype, $params, $extensions); - - if ($index >= 0) { - $this->acceptedtypes[$supertype][$subtype] = - array_merge(array_slice($this->acceptedtypes[$supertype][$subtype], - 0, $index), - array_slice($this->acceptedtypes[$supertype][$subtype], - $index+1)); - } - } - - /** - * Gets a string representation suitable for use in an HTTP Accept header - * - * @access public - * @return string a string representation of this object - */ - function __toString() - { - $accepted = array(); - $qvalues = array(); - foreach ($this->acceptedtypes as $supertype => $subtypes) { - foreach ($subtypes as $subtype => $entries) { - foreach ($entries as $entry) { - $accepted[] = array('TYPE' => "$supertype/$subtype", - 'QUALITY' => $entry['QUALITY'], - 'PARAMS' => $entry['PARAMS'], - 'EXTENSIONS' => $entry['EXTENSIONS']); - $qvalues[] = $entry['QUALITY']; - } - } - } - - array_multisort($qvalues, SORT_DESC, SORT_NUMERIC, - $accepted); - - $str = ""; - foreach ($accepted as $accept) { - // Skip the catchall value if it is 0, since this is implied - if ($accept['TYPE'] == '*/*' && - $accept['QUALITY'] == 0 && - count($accept['PARAMS']) == 0 && - count($accept['EXTENSIONS'] == 0)) - continue; - - $str = $str.$accept['TYPE'].';'; - - foreach ($accept['PARAMS'] as $param => $value) { - if (preg_match('/^'.$this->_matchtoken.'$/', $value)) - $str = $str.$param.'='.$value.';'; - else - $str = $str.$param.'="'.addcslashes($value,'"\\').'";'; - } - - if ($accept['QUALITY'] < 1 || !empty($accept['EXTENSIONS'])) - $str = $str.'q='.$accept['QUALITY'].';'; - - foreach ($accept['EXTENSIONS'] as $extension => $value) { - if (preg_match('/^'.$this->_matchtoken.'$/', $value)) - $str = $str.$extension.'='.$value.';'; - else - $str = $str.$extension.'="'.addcslashes($value,'"\\').'";'; - } - - $str[strlen($str)-1] = ','; - } - - return rtrim($str, ','); - } - - /** - * Finds the index of an exact match for the specified MIME Type - * - * @access private - * @return int the index of an exact match if found, - * -1 otherwise - * @param string $supertype The general MIME Type to find (e.g. "text") - * @param string $subtype The MIME subtype to find (e.g. "html") - * @param array $params Parameters of Type to find ([level => 4]) - * @param array $extensions Extension parameters to find - */ - function _findExactMatchIndex($supertype, $subtype, $params, $extensions) - { - if (empty($this->acceptedtypes[$supertype]) - || empty($this->acceptedtypes[$supertype][$subtype])) - return -1; - - $params = array_change_key_case($params, CASE_LOWER); - - $parammatches = array(); - foreach ($this->acceptedtypes[$supertype][$subtype] as $index => $typematch) - if ($typematch['PARAMS'] == $params - && $typematch['EXTENSIONS'] == $extensions) - return $index; - - return -1; - } - - /** - * Finds the indices of the best matches for the specified MIME Type - * - * A "match" in this context is an exact type match and no extraneous - * matches for parameters or extensions (so the best match for - * "text/html;level=4" may be "text/html" but not the other way around). - * - * "Best" is interpreted as the entries that match the most - * parameters and extensions (the sum of the number of matches) - * - * @access private - * @return array an array of the indices of the best matches - * (empty if no matches) - * @param string $supertype The general MIME Type to find (e.g. "text") - * @param string $subtype The MIME subtype to find (e.g. "html") - * @param array $params Parameters of Type to find ([level => 4]) - * @param array $extensions Extension parameters to find - */ - function _findBestMatchIndices($supertype, $subtype, $params, $extensions) - { - $bestmatches = array(); - $bestlength = 0; - - if (empty($this->acceptedtypes[$supertype]) - || empty($this->acceptedtypes[$supertype][$subtype])) - return $bestmatches; - - foreach ($this->acceptedtypes[$supertype][$subtype] as $index => $typematch) { - if (count(array_diff_assoc($typematch['PARAMS'], $params)) == 0 - && count(array_diff_assoc($typematch['EXTENSIONS'], - $extensions)) == 0) { - $length = count($typematch['PARAMS']) - + count($typematch['EXTENSIONS']); - - if ($length > $bestlength) { - $bestmatches = array($index); - $bestlength = $length; - } else if ($length == $bestlength) { - $bestmatches[] = $index; - } - } - } - - return $bestmatches; - } -} - -// vim: set ts=4 sts=4 sw=4 et: -?> diff --git a/src/ext/Identica.class.php b/src/ext/Identica.class.php deleted file mode 100644 index a3e62a9..0000000 --- a/src/ext/Identica.class.php +++ /dev/null @@ -1,491 +0,0 @@ - Gianluca Urgese - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** -* The main identica-php class. Create an object to use your Identi.ca account from php. -*/ -class Identica { - /** Username:password format string */ - private $credentials; - - /** Contains the last HTTP status code returned */ - private $http_status; - - /** Contains the last API call */ - private $last_api_call; - - /** Contains the application calling the API */ - private $application_source; - - /** - * Identi.ca class constructor. - * @param username is a alphanumeric string to perform login on Identi.ca. - * @param password is a alphanumeric string to perform login on Identi.ca. - * @param source is the name of your application. - * @return An Identica object to use to perform all the operation. - */ - function Identica($username, $password, $source=false) { - $this->credentials = sprintf("%s:%s", $username, $password); - $this->application_source = $source; - } - - /** - * Returns the 20 most recent statuses from non-protected users who have set a custom user icon. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param since_id returns only statuses with an ID greater than (that is, more recent than) the specified ID. - * @return the public timeline in the specified format. - */ - function getPublicTimeline($format, $since_id = 0) { - $api_call = sprintf("http://identi.ca/api/statuses/public_timeline.%s", $format); - if ($since_id > 0) { - $api_call .= sprintf("?since_id=%d", $since_id); - } - return $this->APICall($api_call); - } - - /** - * Returns the 20 most recent statuses posted by the authenticating user and that user's friends. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param id returns only statuses from specified ID. - * @param since returns only statuses with an ID greater than (that is, more recent than) the specified ID. - * @return the friends timeline in the specified format. - */ - function getFriendsTimeline($format, $id = NULL, $since = NULL) { - if ($id != NULL) { - $api_call = sprintf("http://identi.ca/api/statuses/friends_timeline/%s.%s", $id, $format); - } - else { - $api_call = sprintf("http://identi.ca/api/statuses/friends_timeline.%s", $format); - } - if ($since != NULL) { - $api_call .= sprintf("?since=%s", urlencode($since)); - } - return $this->APICall($api_call, true); - } - - /** - * Returns the 20 most recent statuses posted from the authenticating user. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param id get only statuses from specified ID. - * @param count specifies the number of statuses to retrieve. May not be greater than 200. - * @param since get only statuses with an ID greater than (that is, more recent than) the specified ID. - * @return the 20 most recent statuses posted from the authenticating user. - */ - function getUserTimeline($format, $id = NULL, $count = 20, $since = NULL) { - if ($id != NULL) { - $api_call = sprintf("http://identi.ca/api/statuses/user_timeline/%s.%s", $id, $format); - } - else { - $api_call = sprintf("http://identi.ca/api/statuses/user_timeline.%s", $format); - } - if ($count != 20) { - $api_call .= sprintf("?count=%d", $count); - } - if ($since != NULL) { - $api_call .= sprintf("%ssince=%s", (strpos($api_call, "?count=") === false) ? "?" : "&", urlencode($since)); - } - return $this->APICall($api_call, true); - } - - /** - * Returns a single status, specified by the id parameter below. The status's author will be returned inline. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param id get only statuses from specified ID. - * @return a single status, specified by the id parameter. - */ - function showStatus($format, $id) { - $api_call = sprintf("http://identi.ca/api/statuses/show/%d.%s", $id, $format); - return $this->APICall($api_call); - } - - /** - * Updates the authenticating user's status. Request must be a POST. Statuses over 140 characters will be forceably truncated. - * @param status is the text of your status update. - * @return the current update from authenticating user. - */ - function updateStatus($status) { - $status = urlencode(stripslashes(urldecode($status))); - $api_call = sprintf("http://identi.ca/api/statuses/update.xml?status=%s", $status); - return $this->APICall($api_call, true, true); - } - - /** - * Returns a list of replies from authenticating user. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param page specifies the page of results to retrieve. - * @return list of replies from authenticating user. - */ - function getReplies($format, $page = 0) { - $api_call = sprintf("http://identi.ca/api/statuses/replies.%s", $format); - if ($page) { - $api_call .= sprintf("?page=%d", $page); - } - return $this->APICall($api_call, true); - } - - /** - * Destroys the status specified by the required ID parameter. The authenticating user must be the author of the specified status. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param id the ID of the status to destroy. - * @return a destroyed status specified by the id parameter. - */ - function destroyStatus($format, $id) { - $api_call = sprintf("http://identi.ca/api/statuses/destroy/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Returns a user's friends, each with current status inline. They are ordered by the order in which - * they were added as friends, 100 at a time. Use the page option to access older friends. With no - * user specified, request defaults to the authenticated user's friends. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param id is the ID of the user for whom to request a list of friends. - * @return a user's friends. - */ - function getFriends($format, $id = NULL) { - if ($id != NULL) { - $api_call = sprintf("http://identi.ca/api/statuses/friends/%s.%s", $id, $format); - } - else { - $api_call = sprintf("http://identi.ca/api/statuses/friends.%s", $format); - } - return $this->APICall($api_call, true); - } - - /** - * Returns a user's followers. They are ordered by the order in which they joined Identi.ca, 100 at a time. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param lite specified if status must be show. - * @return a user's followers. - */ - function getFollowers($format, $lite = NULL) { - $api_call = sprintf("http://identi.ca/api/statuses/followers.%s%s", $format, ($lite) ? "?lite=true" : NULL); - return $this->APICall($api_call, true); - } - - /** - * Returns extended information of a given user, specified by ID or email as per the required id parameter. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @param email is the email of specified user. - * @return extended information of a given user. - */ - function showUser($format, $id, $email = NULL) { - if ($email == NULL) { - $api_call = sprintf("http://identi.ca/api/users/show/%s.%s", $id, $format); - } - else { - $api_call = sprintf("http://identi.ca/api/users/show.xml?email=%s", $email); - } - return $this->APICall($api_call, true); - } - - /** - * Returns a list of the 20 most recent direct messages sent to the authenticating user. The XML - * and JSON versions include detailed information about the sending and recipient users. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param since get only messages from an ID greater than (that is, more recent than) the specified ID. - * @param since_id returns only statuses from the specified ID. - * @param page Specifies the page of direct messages to retrieve. - * @return a list of the 20 most recent direct messages. - */ - function getMessages($format, $since = NULL, $since_id = 0, $page = 1) { - $api_call = sprintf("http://identi.ca/api/direct_messages.%s", $format); - if ($since != NULL) { - $api_call .= sprintf("?since=%s", urlencode($since)); - } - if ($since_id > 0) { - $api_call .= sprintf("%ssince_id=%d", (strpos($api_call, "?since") === false) ? "?" : "&", $since_id); - } - if ($page > 1) { - $api_call .= sprintf("%spage=%d", (strpos($api_call, "?since") === false) ? "?" : "&", $page); - } - return $this->APICall($api_call, true); - } - - /** - * Returns a list of the 20 most recent direct messages sent by the authenticating user. The XML - * and JSON versions include detailed information about the sending and recipient users. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param since get only messages from an ID greater than (that is, more recent than) the specified ID. - * @param since_id returns only statuses from the specified ID. - * @param page specifies the page of direct messages to retrieve. - * @return a list of the 20 most recent sent direct messages. - */ - function getSentMessages($format, $since = NULL, $since_id = 0, $page = 1) { - $api_call = sprintf("http://identi.ca/api/direct_messages/sent.%s", $format); - if ($since != NULL) { - $api_call .= sprintf("?since=%s", urlencode($since)); - } - if ($since_id > 0) { - $api_call .= sprintf("%ssince_id=%d", (strpos($api_call, "?since") === false) ? "?" : "&", $since_id); - } - if ($page > 1) { - $api_call .= sprintf("%spage=%d", (strpos($api_call, "?since") === false) ? "?" : "&", $page); - } - return $this->APICall($api_call, true); - } - - /** - * Sends a new direct message to the specified user from the authenticating user. Request must be a POST. - * @param format is the extension for the result file (xml, json). - * @param user is the ID of specified user to send the message. - * @param text is the text of your direct message. - * @return the sent message in the requested format when successful. - */ - function newMessage($format, $user, $text) { - $text = urlencode(stripslashes(urldecode($text))); - $api_call = sprintf("http://identi.ca/api/direct_messages/new.%s?user=%s&text=%s", $format, $user, $text); - return $this->APICall($api_call, true, true); - } - - /** - * Destroys the direct message specified in the required ID parameter. The authenticating user - * must be the recipient of the specified direct message. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified direct message. - * @return the message destroyed. - */ - function destroyMessage($format, $id) { - $api_call = sprintf("http://identi.ca/api/direct_messages/destroy/%s.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Allows the authenticating users to follow the user specified in the ID parameter. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the befriended user in the requested format when successful. Returns a string describing the - * failure condition when unsuccessful. If you are already friends with the user an HTTP 403 will be returned. - */ - function createFriendship($format, $id) { - $api_call = sprintf("http://identi.ca/api/friendships/create/%s.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Allows the authenticating users to unfollow the user specified in the ID parameter. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the unfollowed user in the requested format when successful. Returns a string - * describing the failure condition when unsuccessful. - */ - function destroyFriendship($format, $id) { - $api_call = sprintf("http://identi.ca/api/friendships/destroy/%s.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Tests for the existence of friendship between two users. - * @param format is the extension for the result file (xml, json). - * @param user_a is the ID of the first specified user. - * @param user_b is the ID of the second specified user. - * @return true if user_a follows user_b, otherwise will return false. - */ - function friendshipExists($format, $user_a, $user_b) { - $api_call = sprintf("http://identi.ca/api/friendships/exists.%s?user_a=%s&user_b=%s", $format, $user_a, $user_b); - return $this->APICall($api_call, true); - } - - /** - * Tests if supplied user credentials are valid. - * @param format is the extension for the result file (xml, json). - * @return an HTTP 200 OK response code and a representation of the requesting user if authentication - * was successful; returns a 401 status code and an error message if not. - */ - function verifyCredentials($format = NULL) { - $api_call = sprintf("http://identi.ca/api/account/verify_credentials%s", ($format != NULL) ? sprintf(".%s", $format) : NULL); - return $this->APICall($api_call, true); - } - - /** - * Ends the session of the authenticating user, returning a null cookie. - * @return NULL - */ - function endSession() { - $api_call = "http://identi.ca/api/account/end_session"; - return $this->APICall($api_call, true); - } - - /** - * Update user's location in the profile. - * @param location is the user's location . - * @return NULL. - */ - function updateLocation($format, $location) { - $api_call = sprintf("http://identi.ca/api/account/update_location.%s?location=%s", $format, $location); - return $this->APICall($api_call, true, true); - } - - /** - * Sets which device Identi.ca delivers updates to for the authenticating user. - * @param format is the extension for the result file (xml, json). - * @param device must be one of: sms, im, none. - * @return user's profile details in a selected format. - */ - function updateDeliveryDevice($format, $device) { - $api_call = sprintf("http://identi.ca/api/account/update_delivery_device.%s?device=%s", $format, $device); - return $this->APICall($api_call, true, true); - } - - /** - * Returns the remaining number of API requests available to the requesting user before the API - * limit is reached for the current hour. Calls to rateLimitStatus() do not count against the rate limit. - * @param format is the extension for the result file (xml, json). - * @return remaining number of API requests. - */ - function rateLimitStatus($format) { - $api_call = sprintf("http://identi.ca/api/account/rate_limit_status.%s", $format); - return $this->APICall($api_call, true); - } - - /** - * Returns the 20 most recent favorite statuses for the authenticating user or user - * specified by the ID parameter in the requested format. - * @param format is the extension for the result file (xml, json, rss, atom). - * @param id is the ID of specified user. - * @param page specifies the page of favorites to retrieve. - * @return a list of the 20 most recent favorite statuses. - */ - function getFavorites($format, $id = NULL, $page = 1) { - if ($id == NULL) { - $api_call = sprintf("http://identi.ca/api/favorites.%s", $format); - } - else { - $api_call = sprintf("http://identi.ca/api/favorites/%s.%s", $id, $format); - } - if ($page > 1) { - $api_call .= sprintf("?page=%d", $page); - } - return $this->APICall($api_call, true); - } - - /** - * Favorites the status specified in the ID parameter as the authenticating user. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the favorite status when successful. - */ - function createFavorite($format, $id) { - $api_call = sprintf("http://identi.ca/api/favorites/create/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Un-favorites the status specified in the ID parameter as the authenticating user. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the un-favorited status in the requested format when successful. - */ - function destroyFavorite($format, $id) { - $api_call = sprintf("http://identi.ca/api/favorites/destroy/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Enables device notifications for updates from the specified user. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the specified user when successful. - */ - function follow($format, $id) { - $api_call = sprintf("http://identi.ca/api/notifications/follow/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Disables notifications for updates from the specified user to the authenticating user. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the specified user when successful. - */ - function leave($format, $id) { - $api_call = sprintf("http://identi.ca/api/notifications/leave/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Blocks the user specified in the ID parameter as the authenticating user. Destroys a friendship to the blocked user if it exists. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the blocked user in the requested format when successful. - */ - function createBlock($format, $id) { - $api_call = sprintf("http://identi.ca/api/blocks/create/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Un-blocks the user specified in the ID parameter for the authenticating user. - * @param format is the extension for the result file (xml, json). - * @param id is the ID of specified user. - * @return the un-blocked user in the requested format when successful. - */ - function destroyBlock($format, $id) { - $api_call = sprintf("http://identi.ca/api/blocks/destroy/%d.%s", $id, $format); - return $this->APICall($api_call, true, true); - } - - /** - * Returns true or false in the requested format with a 200 OK HTTP status code. - * @param format is the extension for the result file (xml, json). - * @return test results. - */ - function test($format) { - $api_call = sprintf("http://identi.ca/api/help/test.%s", $format); - return $this->APICall($api_call, true); - } - - private function APICall($api_url, $require_credentials = false, $http_post = false) { - $curl_handle = curl_init(); - if($this->application_source){ - $api_url .= "&source=" . $this->application_source; - } - curl_setopt($curl_handle, CURLOPT_URL, $api_url); - if ($require_credentials) { - curl_setopt($curl_handle, CURLOPT_USERPWD, $this->credentials); - } - if ($http_post) { - curl_setopt($curl_handle, CURLOPT_POST, true); - } - curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE); - $identica_data = curl_exec($curl_handle); - $this->http_status = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); - $this->last_api_call = $api_url; - curl_close($curl_handle); - return $identica_data; - } - - function lastStatusCode() { - return $this->http_status; - } - - function lastAPICall() { - return $this->last_api_call; - } -} -?> diff --git a/src/ext/MimeMailParser.class.php b/src/ext/MimeMailParser.class.php deleted file mode 100644 index 0080199..0000000 --- a/src/ext/MimeMailParser.class.php +++ /dev/null @@ -1,447 +0,0 @@ -attachment_streams = array(); - } - - /** - * Free the held resouces - * @return void - */ - public function __destruct() { - // clear the email file resource - if (is_resource($this->stream)) { - fclose($this->stream); - } - // clear the MailParse resource - if (is_resource($this->resource)) { - mailparse_msg_free($this->resource); - } - // remove attachment resources - foreach($this->attachment_streams as $stream) { - fclose($stream); - } - } - - /** - * Set the file path we use to get the email text - * @return Object MimeMailParser Instance - * @param $mail_path Object - */ - public function setPath($path) { - // should parse message incrementally from file - $this->resource = mailparse_msg_parse_file($path); - $this->stream = fopen($path, 'r'); - $this->parse(); - return $this; - } - - /** - * Set the Stream resource we use to get the email text - * @return Object MimeMailParser Instance - * @param $stream Resource - */ - public function setStream($stream) { - - // streams have to be cached to file first - if (get_resource_type($stream) == 'stream') { - $tmp_fp = tmpfile(); - if ($tmp_fp) { - while(!feof($stream)) { - fwrite($tmp_fp, fread($stream, 2028)); - } - fseek($tmp_fp, 0); - $this->stream =& $tmp_fp; - } else { - throw new Exception('Could not create temporary files for attachments. Your tmp directory may be unwritable by PHP.'); - return false; - } - fclose($stream); - } else { - $this->stream = $stream; - } - - $this->resource = mailparse_msg_create(); - // parses the message incrementally low memory usage but slower - while(!feof($this->stream)) { - mailparse_msg_parse($this->resource, fread($this->stream, 2082)); - } - $this->parse(); - return $this; - } - - /** - * Set the email text - * @return Object MimeMailParser Instance - * @param $data String - */ - public function setText($data) { - $this->resource = mailparse_msg_create(); - // does not parse incrementally, fast memory hog might explode - mailparse_msg_parse($this->resource, $data); - $this->data = $data; - $this->parse(); - return $this; - } - - /** - * Parse the Message into parts - * @return void - * @private - */ - private function parse() { - $structure = mailparse_msg_get_structure($this->resource); - $this->parts = array(); - foreach($structure as $part_id) { - $part = mailparse_msg_get_part($this->resource, $part_id); - $this->parts[$part_id] = mailparse_msg_get_part_data($part); - } - } - - /** - * Retrieve the Email Headers - * @return Array - */ - public function getHeaders() { - if (isset($this->parts[1])) { - return $this->getPartHeaders($this->parts[1]); - } else { - throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email headers.'); - } - return false; - } - /** - * Retrieve the raw Email Headers - * @return string - */ - public function getHeadersRaw() { - if (isset($this->parts[1])) { - return $this->getPartHeaderRaw($this->parts[1]); - } else { - throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email headers.'); - } - return false; - } - - /** - * Retrieve a specific Email Header - * @return String - * @param $name String Header name - */ - public function getHeader($name) { - if (isset($this->parts[1])) { - $headers = $this->getPartHeaders($this->parts[1]); - if (isset($headers[$name])) { - return $headers[$name]; - } - } else { - throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email headers.'); - } - return false; - } - - /** - * Returns the part for the message body in the specified format - * @return Part or False if not found - * @param $type String[optional] - */ - public function getMessageBodyPart($type = 'text') { - $mime_types = array( - 'text'=> 'text/plain', - 'html'=> 'text/html' - ); - $attachment_dispositions = array("attachment","inline"); - if (in_array($type, array_keys($mime_types))) { - foreach($this->parts as $part) { - $disposition = $this->getPartContentDisposition($part); - $mime_type = $this->getPartContentType($part); - if ( (!in_array($disposition, $attachment_dispositions)) && - ($mime_type == $mime_types[$type]) ) { - return $part; - } - } - } else { - throw new Exception('Invalid type specified for MimeMailParser::getMessageBodyPart. "type" can either be text or html.'); - } - return false; - } - - /** - * Returns the email message body in the specified format - * @return Mixed String Body or False if not found - * @param $type Object[optional] - */ - public function getMessageBody($type = 'text') { - $body = false; - $part = $this->getMessageBodyPart($type); - if ($part!==false) { - $headers = $this->getPartHeaders($part); - $body = $this->decode($this->getPartBody($part), array_key_exists('content-transfer-encoding', $headers) ? $headers['content-transfer-encoding'] : ''); - } - return $body; - } - - /** - * get the headers for the message body part. - * @return Array - * @param $type Object[optional] - */ - public function getMessageBodyHeaders($type = 'text') { - $headers = false; - $part = $this->getMessageBodyPart($type); - if ($part!==false) { - $headers = $this->getPartHeaders($part); - } - return $headers; - } - - - /** - * Returns the attachments contents in order of appearance - * @return Array - * @param $type Object[optional] - */ - public function getAttachments() { - $attachments = array(); - $dispositions = array("attachment","inline"); - foreach($this->parts as $part) { - $disposition = $this->getPartContentDisposition($part); - if (in_array($disposition, $dispositions)) { - $headers = $this->getPartHeaders($part); - $attachments[] = new MimeMailParser_attachment( - $part['disposition-filename'], - $this->getPartContentType($part), - $this->getAttachmentStream($part), - $disposition, - $headers - ); - } - } - return $attachments; - } - - /** - * Return the Headers for a MIME part - * @return Array - * @param $part Array - */ - private function getPartHeaders($part) { - if (isset($part['headers'])) { - return $part['headers']; - } - return false; - } - - /** - * Return a Specific Header for a MIME part - * @return Array - * @param $part Array - * @param $header String Header Name - */ - private function getPartHeader($part, $header) { - if (isset($part['headers'][$header])) { - return $part['headers'][$header]; - } - return false; - } - - /** - * Return the ContentType of the MIME part - * @return String - * @param $part Array - */ - private function getPartContentType($part) { - if (isset($part['content-type'])) { - return $part['content-type']; - } - return false; - } - - /** - * Return the Content Disposition - * @return String - * @param $part Array - */ - private function getPartContentDisposition($part) { - if (isset($part['content-disposition'])) { - return $part['content-disposition']; - } - return false; - } - - /** - * Retrieve the raw Header of a MIME part - * @return String - * @param $part Object - */ - private function getPartHeaderRaw(&$part) { - $header = ''; - if ($this->stream) { - $header = $this->getPartHeaderFromFile($part); - } else if ($this->data) { - $header = $this->getPartHeaderFromText($part); - } else { - throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email parts.'); - } - return $header; - } - /** - * Retrieve the Body of a MIME part - * @return String - * @param $part Object - */ - private function getPartBody(&$part) { - $body = ''; - if ($this->stream) { - $body = $this->getPartBodyFromFile($part); - } else if ($this->data) { - $body = $this->getPartBodyFromText($part); - } else { - throw new Exception('MimeMailParser::setPath() or MimeMailParser::setText() must be called before retrieving email parts.'); - } - return $body; - } - - /** - * Retrieve the Header from a MIME part from file - * @return String Mime Header Part - * @param $part Array - */ - private function getPartHeaderFromFile(&$part) { - $start = $part['starting-pos']; - $end = $part['starting-pos-body']; - fseek($this->stream, $start, SEEK_SET); - $header = fread($this->stream, $end-$start); - return $header; - } - /** - * Retrieve the Body from a MIME part from file - * @return String Mime Body Part - * @param $part Array - */ - private function getPartBodyFromFile(&$part) { - $start = $part['starting-pos-body']; - $end = $part['ending-pos-body']; - fseek($this->stream, $start, SEEK_SET); - $body = fread($this->stream, $end-$start); - return $body; - } - - /** - * Retrieve the Header from a MIME part from text - * @return String Mime Header Part - * @param $part Array - */ - private function getPartHeaderFromText(&$part) { - $start = $part['starting-pos']; - $end = $part['starting-pos-body']; - $header = substr($this->data, $start, $end-$start); - return $header; - } - /** - * Retrieve the Body from a MIME part from text - * @return String Mime Body Part - * @param $part Array - */ - private function getPartBodyFromText(&$part) { - $start = $part['starting-pos-body']; - $end = $part['ending-pos-body']; - $body = substr($this->data, $start, $end-$start); - return $body; - } - - /** - * Read the attachment Body and save temporary file resource - * @return String Mime Body Part - * @param $part Array - */ - private function getAttachmentStream(&$part) { - $temp_fp = tmpfile(); - - array_key_exists('content-transfer-encoding', $part['headers']) ? $encoding = $part['headers']['content-transfer-encoding'] : $encoding = ''; - - if ($temp_fp) { - if ($this->stream) { - $start = $part['starting-pos-body']; - $end = $part['ending-pos-body']; - fseek($this->stream, $start, SEEK_SET); - $len = $end-$start; - $written = 0; - $write = 2028; - $body = ''; - while($written < $len) { - if (($written+$write < $len )) { - $write = $len - $written; - } - $part = fread($this->stream, $write); - fwrite($temp_fp, $this->decode($part, $encoding)); - $written += $write; - } - } else if ($this->data) { - $attachment = $this->decode($this->getPartBodyFromText($part), $encoding); - fwrite($temp_fp, $attachment, strlen($attachment)); - } - fseek($temp_fp, 0, SEEK_SET); - } else { - throw new Exception('Could not create temporary files for attachments. Your tmp directory may be unwritable by PHP.'); - return false; - } - return $temp_fp; - } - - - /** - * Decode the string depending on encoding type. - * @return String the decoded string. - * @param $encodedString The string in its original encoded state. - * @param $encodingType The encoding type from the Content-Transfer-Encoding header of the part. - */ - private function decode($encodedString, $encodingType) { - if (strtolower($encodingType) == 'base64') { - return base64_decode($encodedString); - } else if (strtolower($encodingType) == 'quoted-printable') { - return quoted_printable_decode($encodedString); - } else { - return $encodedString; - } - } - -} - - -?> diff --git a/src/ext/MimeMailParser_attachment.class.php b/src/ext/MimeMailParser_attachment.class.php deleted file mode 100644 index 6bd327c..0000000 --- a/src/ext/MimeMailParser_attachment.class.php +++ /dev/null @@ -1,136 +0,0 @@ -filename = $filename; - $this->content_type = $content_type; - $this->stream = $stream; - $this->content = null; - $this->content_disposition = $content_disposition; - $this->headers = $headers; - } - - /** - * retrieve the attachment filename - * @return String - */ - public function getFilename() { - return $this->filename; - } - - /** - * Retrieve the Attachment Content-Type - * @return String - */ - public function getContentType() { - return $this->content_type; - } - - /** - * Retrieve the Attachment Content-Disposition - * @return String - */ - public function getContentDisposition() { - return $this->content_disposition; - } - - /** - * Retrieve the Attachment Headers - * @return String - */ - public function getHeaders() { - return $this->headers; - } - - /** - * Retrieve the file extension - * @return String - */ - public function getFileExtension() { - if (!$this->extension) { - $ext = substr(strrchr($this->filename, '.'), 1); - if ($ext == 'gz') { - // special case, tar.gz - // todo: other special cases? - $ext = preg_match("/\.tar\.gz$/i", $ext) ? 'tar.gz' : 'gz'; - } - $this->extension = $ext; - } - return $this->extension; - } - - /** - * Read the contents a few bytes at a time until completed - * Once read to completion, it always returns false - * @return String - * @param $bytes Int[optional] - */ - public function read($bytes = 2082) { - return feof($this->stream) ? false : fread($this->stream, $bytes); - } - - /** - * Retrieve the file content in one go - * Once you retreive the content you cannot use MimeMailParser_attachment::read() - * @return String - */ - public function getContent() { - if ($this->content === null) { - fseek($this->stream, 0); - while(($buf = $this->read()) !== false) { - $this->content .= $buf; - } - } - return $this->content; - } - - /** - * Allow the properties - * MimeMailParser_attachment::$name, - * MimeMailParser_attachment::$extension - * to be retrieved as public properties - * @param $name Object - */ - public function __get($name) { - if ($name == 'content') { - return $this->getContent(); - } else if ($name == 'extension') { - return $this->getFileExtension(); - } - return null; - } - -} - -?> \ No newline at end of file diff --git a/src/ext/PasswordHash.class.php b/src/ext/PasswordHash.class.php deleted file mode 100644 index 12958c7..0000000 --- a/src/ext/PasswordHash.class.php +++ /dev/null @@ -1,253 +0,0 @@ - in 2004-2006 and placed in -# the public domain. Revised in subsequent years, still public domain. -# -# There's absolutely no warranty. -# -# The homepage URL for this framework is: -# -# http://www.openwall.com/phpass/ -# -# Please be sure to update the Version line if you edit this file in any way. -# It is suggested that you leave the main version number intact, but indicate -# your project name (after the slash) and add your own revision information. -# -# Please do not change the "private" password hashing method implemented in -# here, thereby making your hashes incompatible. However, if you must, please -# change the hash type identifier (the "$P$") to something different. -# -# Obviously, since this code is in the public domain, the above are not -# requirements (there can be none), but merely suggestions. -# -class PasswordHash { - var $itoa64; - var $iteration_count_log2; - var $portable_hashes; - var $random_state; - - function PasswordHash($iteration_count_log2, $portable_hashes) - { - $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - - if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) - $iteration_count_log2 = 8; - $this->iteration_count_log2 = $iteration_count_log2; - - $this->portable_hashes = $portable_hashes; - - $this->random_state = microtime(); - if (function_exists('getmypid')) - $this->random_state .= getmypid(); - } - - function get_random_bytes($count) - { - $output = ''; - if (is_readable('/dev/urandom') && - ($fh = @fopen('/dev/urandom', 'rb'))) { - $output = fread($fh, $count); - fclose($fh); - } - - if (strlen($output) < $count) { - $output = ''; - for ($i = 0; $i < $count; $i += 16) { - $this->random_state = - md5(microtime() . $this->random_state); - $output .= - pack('H*', md5($this->random_state)); - } - $output = substr($output, 0, $count); - } - - return $output; - } - - function encode64($input, $count) - { - $output = ''; - $i = 0; - do { - $value = ord($input[$i++]); - $output .= $this->itoa64[$value & 0x3f]; - if ($i < $count) - $value |= ord($input[$i]) << 8; - $output .= $this->itoa64[($value >> 6) & 0x3f]; - if ($i++ >= $count) - break; - if ($i < $count) - $value |= ord($input[$i]) << 16; - $output .= $this->itoa64[($value >> 12) & 0x3f]; - if ($i++ >= $count) - break; - $output .= $this->itoa64[($value >> 18) & 0x3f]; - } while ($i < $count); - - return $output; - } - - function gensalt_private($input) - { - $output = '$P$'; - $output .= $this->itoa64[min($this->iteration_count_log2 + - ((PHP_VERSION >= '5') ? 5 : 3), 30)]; - $output .= $this->encode64($input, 6); - - return $output; - } - - function crypt_private($password, $setting) - { - $output = '*0'; - if (substr($setting, 0, 2) == $output) - $output = '*1'; - - $id = substr($setting, 0, 3); - # We use "$P$", phpBB3 uses "$H$" for the same thing - if ($id != '$P$' && $id != '$H$') - return $output; - - $count_log2 = strpos($this->itoa64, $setting[3]); - if ($count_log2 < 7 || $count_log2 > 30) - return $output; - - $count = 1 << $count_log2; - - $salt = substr($setting, 4, 8); - if (strlen($salt) != 8) - return $output; - - # We're kind of forced to use MD5 here since it's the only - # cryptographic primitive available in all versions of PHP - # currently in use. To implement our own low-level crypto - # in PHP would result in much worse performance and - # consequently in lower iteration counts and hashes that are - # quicker to crack (by non-PHP code). - if (PHP_VERSION >= '5') { - $hash = md5($salt . $password, TRUE); - do { - $hash = md5($hash . $password, TRUE); - } while (--$count); - } else { - $hash = pack('H*', md5($salt . $password)); - do { - $hash = pack('H*', md5($hash . $password)); - } while (--$count); - } - - $output = substr($setting, 0, 12); - $output .= $this->encode64($hash, 16); - - return $output; - } - - function gensalt_extended($input) - { - $count_log2 = min($this->iteration_count_log2 + 8, 24); - # This should be odd to not reveal weak DES keys, and the - # maximum valid value is (2**24 - 1) which is odd anyway. - $count = (1 << $count_log2) - 1; - - $output = '_'; - $output .= $this->itoa64[$count & 0x3f]; - $output .= $this->itoa64[($count >> 6) & 0x3f]; - $output .= $this->itoa64[($count >> 12) & 0x3f]; - $output .= $this->itoa64[($count >> 18) & 0x3f]; - - $output .= $this->encode64($input, 3); - - return $output; - } - - function gensalt_blowfish($input) - { - # This one needs to use a different order of characters and a - # different encoding scheme from the one in encode64() above. - # We care because the last character in our encoded string will - # only represent 2 bits. While two known implementations of - # bcrypt will happily accept and correct a salt string which - # has the 4 unused bits set to non-zero, we do not want to take - # chances and we also do not want to waste an additional byte - # of entropy. - $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - $output = '$2a$'; - $output .= chr(ord('0') + $this->iteration_count_log2 / 10); - $output .= chr(ord('0') + $this->iteration_count_log2 % 10); - $output .= '$'; - - $i = 0; - do { - $c1 = ord($input[$i++]); - $output .= $itoa64[$c1 >> 2]; - $c1 = ($c1 & 0x03) << 4; - if ($i >= 16) { - $output .= $itoa64[$c1]; - break; - } - - $c2 = ord($input[$i++]); - $c1 |= $c2 >> 4; - $output .= $itoa64[$c1]; - $c1 = ($c2 & 0x0f) << 2; - - $c2 = ord($input[$i++]); - $c1 |= $c2 >> 6; - $output .= $itoa64[$c1]; - $output .= $itoa64[$c2 & 0x3f]; - } while (1); - - return $output; - } - - function HashPassword($password) - { - $random = ''; - - if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) { - $random = $this->get_random_bytes(16); - $hash = - crypt($password, $this->gensalt_blowfish($random)); - if (strlen($hash) == 60) - return $hash; - } - - if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) { - if (strlen($random) < 3) - $random = $this->get_random_bytes(3); - $hash = - crypt($password, $this->gensalt_extended($random)); - if (strlen($hash) == 20) - return $hash; - } - - if (strlen($random) < 6) - $random = $this->get_random_bytes(6); - $hash = - $this->crypt_private($password, - $this->gensalt_private($random)); - if (strlen($hash) == 34) - return $hash; - - # Returning '*' on error is safe here, but would _not_ be safe - # in a crypt(3)-like function used _both_ for generating new - # hashes and for validating passwords against existing hashes. - return '*'; - } - - function CheckPassword($password, $stored_hash) - { - $hash = $this->crypt_private($password, $stored_hash); - if ($hash[0] == '*') - $hash = crypt($password, $stored_hash); - - return $hash == $stored_hash; - } -} - -?> diff --git a/src/ext/README.txt b/src/ext/README.txt deleted file mode 100644 index e5cb94a..0000000 --- a/src/ext/README.txt +++ /dev/null @@ -1,17 +0,0 @@ -These are class files that I've gathered from around the internet. - -I've renamed the files to follow a standard scheme. -(Could we get a standard scheme, please?) - -This is where each file came from: - -My Name : Original Name : From -GoogleVoice.class.php : class.googlevoice.php : https://code.google.com/p/phpgooglevoice/ -Identica.class.php : identica.lib.php : https://code.google.com/p/identica-php/ -MimeMailParser.class.php : MimeMailParser.class.php : https://code.google.com/p/php-mime-mail-parser/ -MimeMailParser_attachment.class.php : attachment.php : https://code.google.com/p/php-mime-mail-parser/ -PasswordHash.class.php : PasswordHash.php : http://www.openwall.com/phpass/ -recaptchalib.php : recaptchalib.php : https://code.google.com/p/recaptcha/ - -~ Luke Shumaker -Happy Hacking! diff --git a/src/ext/recaptchalib.php b/src/ext/recaptchalib.php deleted file mode 100644 index 32c4f4d..0000000 --- a/src/ext/recaptchalib.php +++ /dev/null @@ -1,277 +0,0 @@ - $value ) - $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; - - // Cut the last '&' - $req=substr($req,0,strlen($req)-1); - return $req; -} - - - -/** - * Submits an HTTP POST to a reCAPTCHA server - * @param string $host - * @param string $path - * @param array $data - * @param int port - * @return array response - */ -function _recaptcha_http_post($host, $path, $data, $port = 80) { - - $req = _recaptcha_qsencode ($data); - - $http_request = "POST $path HTTP/1.0\r\n"; - $http_request .= "Host: $host\r\n"; - $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; - $http_request .= "Content-Length: " . strlen($req) . "\r\n"; - $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; - $http_request .= "\r\n"; - $http_request .= $req; - - $response = ''; - if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { - die ('Could not open socket'); - } - - fwrite($fs, $http_request); - - while ( !feof($fs) ) - $response .= fgets($fs, 1160); // One TCP-IP packet - fclose($fs); - $response = explode("\r\n\r\n", $response, 2); - - return $response; -} - - - -/** - * Gets the challenge HTML (javascript and non-javascript version). - * This is called from the browser, and the resulting reCAPTCHA HTML widget - * is embedded within the HTML form it was called from. - * @param string $pubkey A public key for reCAPTCHA - * @param string $error The error given by reCAPTCHA (optional, default is null) - * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) - - * @return string - The HTML to be embedded in the user's form. - */ -function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) -{ - if ($pubkey == null || $pubkey == '') { - die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); - } - - if ($use_ssl) { - $server = RECAPTCHA_API_SECURE_SERVER; - } else { - $server = RECAPTCHA_API_SERVER; - } - - $errorpart = ""; - if ($error) { - $errorpart = "&error=" . $error; - } - return ' - - '; -} - - - - -/** - * A ReCaptchaResponse is returned from recaptcha_check_answer() - */ -class ReCaptchaResponse { - var $is_valid; - var $error; -} - - -/** - * Calls an HTTP POST function to verify if the user's guess was correct - * @param string $privkey - * @param string $remoteip - * @param string $challenge - * @param string $response - * @param array $extra_params an array of extra variables to post to the server - * @return ReCaptchaResponse - */ -function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) -{ - if ($privkey == null || $privkey == '') { - die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create"); - } - - if ($remoteip == null || $remoteip == '') { - die ("For security reasons, you must pass the remote ip to reCAPTCHA"); - } - - - - //discard spam submissions - if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { - $recaptcha_response = new ReCaptchaResponse(); - $recaptcha_response->is_valid = false; - $recaptcha_response->error = 'incorrect-captcha-sol'; - return $recaptcha_response; - } - - $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", - array ( - 'privatekey' => $privkey, - 'remoteip' => $remoteip, - 'challenge' => $challenge, - 'response' => $response - ) + $extra_params - ); - - $answers = explode ("\n", $response [1]); - $recaptcha_response = new ReCaptchaResponse(); - - if (trim ($answers [0]) == 'true') { - $recaptcha_response->is_valid = true; - } - else { - $recaptcha_response->is_valid = false; - $recaptcha_response->error = $answers [1]; - } - return $recaptcha_response; - -} - -/** - * gets a URL where the user can sign up for reCAPTCHA. If your application - * has a configuration page where you enter a key, you should provide a link - * using this function. - * @param string $domain The domain where the page is hosted - * @param string $appname The name of your application - */ -function recaptcha_get_signup_url ($domain = null, $appname = null) { - return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); -} - -function _recaptcha_aes_pad($val) { - $block_size = 16; - $numpad = $block_size - (strlen ($val) % $block_size); - return str_pad($val, strlen ($val) + $numpad, chr($numpad)); -} - -/* Mailhide related code */ - -function _recaptcha_aes_encrypt($val,$ky) { - if (! function_exists ("mcrypt_encrypt")) { - die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); - } - $mode=MCRYPT_MODE_CBC; - $enc=MCRYPT_RIJNDAEL_128; - $val=_recaptcha_aes_pad($val); - return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); -} - - -function _recaptcha_mailhide_urlbase64 ($x) { - return strtr(base64_encode ($x), '+/', '-_'); -} - -/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ -function recaptcha_mailhide_url($pubkey, $privkey, $email) { - if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { - die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . - "you can do so at http://www.google.com/recaptcha/mailhide/apikey"); - } - - - $ky = pack('H*', $privkey); - $cryptmail = _recaptcha_aes_encrypt ($email, $ky); - - return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); -} - -/** - * gets the parts of the email to expose to the user. - * eg, given johndoe@example,com return ["john", "example.com"]. - * the email is then displayed as john...@example.com - */ -function _recaptcha_mailhide_email_parts ($email) { - $arr = preg_split("/@/", $email ); - - if (strlen ($arr[0]) <= 4) { - $arr[0] = substr ($arr[0], 0, 1); - } else if (strlen ($arr[0]) <= 6) { - $arr[0] = substr ($arr[0], 0, 3); - } else { - $arr[0] = substr ($arr[0], 0, 4); - } - return $arr; -} - -/** - * Gets html to display an email address given a public an private key. - * to get a key, go to: - * - * http://www.google.com/recaptcha/mailhide/apikey - */ -function recaptcha_mailhide_html($pubkey, $privkey, $email) { - $emailparts = _recaptcha_mailhide_email_parts ($email); - $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); - - return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]); - -} - - -?> diff --git a/src/lib/Controller.class.php b/src/lib/Controller.class.php deleted file mode 100644 index 05736ee..0000000 --- a/src/lib/Controller.class.php +++ /dev/null @@ -1,30 +0,0 @@ -show($vars); - } - - // Here be default handlers //////////////////////////////////////////// - - public function index($routed, $remainder) { - header('Content-type: text/plain'); - echo " == Generic Controller Index == \n\n"; - $routed_str = implode('/', $routed); - $remainder_str = implode('/', $remainder); - echo "Full path: $routed_str/$remainder_str\n"; - echo "Controller path: $routed_str\n"; - echo "Remainder path: $remainder_str\n"; - } - public function http404($routed, $remainder) { - $this->showView('http404', array('routed'=>$routed, - 'remainder'=>$remainder)); - } -} diff --git a/src/lib/DB.class.php b/src/lib/DB.class.php deleted file mode 100644 index ac8dafe..0000000 --- a/src/lib/DB.class.php +++ /dev/null @@ -1,164 +0,0 @@ -getConfString($key); - $someone_else_changed_it = - $value_fork != $value_base; - if ($someone_else_changed_it) { - if ($value == $value_fork) { - // we might as well not have - $we_changed_it = false; - } else { - $forked = true; - } - } - } - if (!$we_changed_it) { - $doit = false;// nothing to do - } - } - if ($doit) { - return $this->setConf($key, $value); - } - if ($forked) { - return $value_fork; - } - } - - public static function get($table, $unit, $key) { - switch ($table) { - case 'conf': - case 'plugins': - return self::admin_get($unit, $key); - break; - case 'users': - return self::user_get($unit, $key); - break; - default: - return false; - } - } - public static function raw_set($table, $unit, $key, $value) { - switch ($table) { - case 'conf': - case 'plugins': - return self::admin_get($unit, $key, $value); - break; - case 'users': - return self::user_set($unit, $key, $value); - break; - default: - return false; - } - } - - private static function user_get($uid, $key) { - $user = Auth::getInstance($uid); - $logged_in_user = Auth::getInstance(Login::isLoggedIn()); - - $post_key = $key."[$uid]"; - @$value = $_POST[$post_key]; - $editable = $user->canEdit(); - - switch ($key) { - case 'auth_uid': - $value = $user->getUID(); - $editable = false; - break; - case 'auth_name': - $value = $user->getName(); - break; - case 'auth_user': - $editable = $editable && $logged_in_user->isAdmin(); - $value = $user->isUser()?'true':'false'; - break; - case 'auth_admin': - $editable = $editable && $logged_in_user->isAdmin(); - $value = $user->isAdmin()?'true':'false'; - break; - case 'auth_delete': - $editable = $editable && $logged_in_user->isAdmin(); - $value = 'false'; - break; - default: - $value = $user->getConf($key); - if ($value===false) $value=''; - break; - } - - return array('value'=>$value, - 'post_key'=>$post_key, - 'editable'=>$editable); - } - private static function user_set($uid, $key, $value) { - $user = Auth::getInstance($uid); - - switch ($key) { - case 'auth_uid': - return false; - break; - case 'auth_name': - return $user->setName($value); - break; - case 'auth_user': - return $user->setUser($value=='true'); - break; - case 'auth_admin': - return $user->setAdmin($value=='true'); - break; - case 'auth_delete': - if ($value=='true') return $user->delete(); - default: - return $user->setConf($key, $value); - break; - } - } - - private static function admin_get($plugin, $key) { - $db = Database::getInstance(); - $user = Auth::getInstance(Login::isLoggedIn()); - if ($user->isAdmin()) { - $editable = true; - switch ($plugin) { - case 'system': - $value = $db->getSysConf($key); - break; - default: - $value = $db->getPluginConf($plugin, $key); - break; - } - } else { - $editable = false; - $value = false; - } - - return array('value'=>$value, - 'post_key'=>'to be implemented',// FIXME - 'editable'=>$editable); - } - private static function admin_set($plugin, $key, $value) { - $db = Database::getInstance(); - $user = Auth::getInstance(Login::isLoggedIn()); - if (!$user->isAdmin()) { - return false; - } - switch ($plugin) { - case 'system': - return $db->setSysConf($key, $value); - default: - return $db->setPluginConf($plugin, $key, $value); - } - } -} diff --git a/src/lib/Database.class.php b/src/lib/Database.class.php deleted file mode 100644 index a76d891..0000000 --- a/src/lib/Database.class.php +++ /dev/null @@ -1,403 +0,0 @@ -conf = $conf_file; - self::$me = $this; - } - public static function getInstance() { - return self::$me; - } - - // Low-Level SQL functions ///////////////////////////////////////////// - - private function mysql() { - if (!isset($this->mysql)) { - $this->mysql_init(); - } - return $this->mysql; - } - private function mysql_init() { - global $db_config; - require($this->conf); - $this->mysql = mysql_connect($db_config['host'], - $db_config['user'], - $db_config['password']); - mysql_set_charset($db_config['charset'], $this->mysql); - mysql_select_db($db_config['name'], $this->mysql); - $this->db_prefix = $db_config['prefix']; - unset($db_config); - } - private function mysql_table($table_name) { - $mysql = $this->mysql(); - $prefix = $this->db_prefix; - return $prefix.mysql_real_escape_string($table_name, $mysql); - } - private function mysql_escape($string) { - $mysql = $this->mysql(); - return mysql_real_escape_string($string, $mysql); - } - private function mysql_query($query) { - $mysql = $this->mysql(); - return mysql_query($query, $mysql); - } - public function mysql_error() { - $mysql = $this->mysql(); - return mysql_error($mysql); - } - - // High-Level SQL functions //////////////////////////////////////////// - - // The 'auth' table - - public function getUID($username) { - $t = $this->mysql_table('auth'); - $v = $this->mysql_escape($username); - $query = - "SELECT * \n". - "FROM $t \n". - "WHERE name='$v' ;"; - $q = $this->mysql_query($query); - $user = mysql_fetch_array($q); - if (isset($user['uid'])) { - return (int)$user['uid']; - } else { - return false; - } - } - public function getUsername($uid) { - if (!is_int($uid)) return false; - $t = $this->mysql_table('auth'); - $query = - "SELECT * \n". - "FROM $t \n". - "WHERE uid=$uid ;"; - $q = $this->mysql_query($query); - $user = mysql_fetch_array($q); - if (isset($user['name'])) { - return $user['name']; - } else { - return false; - } - } - public function setUsername($uid, $username) { - if (!is_int($uid)) return false; - if ($this->getUID($username) !== false) { - return false; - } - $table = $this->mysql_table('auth'); - $name = $this->mysql_escape($username); - $query = - "UPDATE $table \n". - "SET name='$name' \n". - "WHERE uid=$uid ;"; - $q = $this->mysql_query($query); - return ($q?true:false); - } - public function getPasswordHash($uid) { - if (!is_int($uid)) return false; - - $table = $this->mysql_table('auth'); - $query = - "SELECT * \n". - "FROM $table \n". - "WHERE uid=$uid ;"; - $q = $this->mysql_query($query); - $user = mysql_fetch_array($q); - if (isset($user['hash'])) { - return $user['hash']; - } else { - return false; - } - } - public function setPassword($uid, $password) { - if (!is_int($uid)) return false; - $table = $this->mysql_table('auth'); - - $hasher = Hasher::getInstance(); - @$hash = $hasher->hash($password); - $query = - "UPDATE $table \n". - "SET hash='$hash' \n". - "WHERE uid=$uid ;"; - $q = $this->mysql_query($query); - return ($q?true:false); - } - public function addUser($username, $password) { - $user_exits = $this->getUID($username); - if ($user_exists) { - return false; - } - - $table = $this->mysql_table('auth'); - $user = $this->mysql_escape($username); - $hasher = Hasher::getInstance(); - @$hash = $hasher->hash($password); - $status = 0; - $query = - "INSERT INTO $table ( name, hash , status) \n". - "VALUES ('$user', '$hash', $status) ;"; - $this->mysql_query($query); - $uid = $this->getUID($username); - return $uid; - } - public function getStatus($uid) { - if (!is_int($uid)) return false; - $table = $this->mysql_table('auth'); - $query = - "SELECT * \n". - "FROM $table \n". - "WHERE uid=$uid ;"; - $q = $this->mysql_query($query); - $user = mysql_fetch_array($q); - if (isset($user['status'])) { - return (int)$user['status']; - } else { - return false; - } - } - public function setStatus($uid, $status) { - if (!is_int($uid)) return false; - $table = $this->mysql_table('auth'); - $s = $this->mysql_escape($status); - $query = - "UPDATE $table \n". - "SET status=$s \n". - "WHERE uid=$uid ;"; - $q = $this->mysql_query($query); - return ($q?true:false); - } - public function countUsers() { - $table = $this->mysql_table('auth'); - $query = "SELECT COUNT(*) FROM $table;"; - $q = $this->mysql_query($query); - $row = mysql_fetch_array($q); - $count = $row[0]; - return $count; - } - public function listGroups() { - $table = $this->mysql_table('auth'); - $query = - "SELECT uid \n". - "FROM $table \n". - "WHERE status=3 ;"; - $q = $this->mysql_query($query); - $groups = array(); - while (($row = mysql_fetch_array($q)) !==false) { - $groups[] = (int)$row[0]; - } - return $groups; - } - public function listGroupNames() { - $table = $this->mysql_table('auth'); - $query = - "SELECT name \n". - "FROM $table \n". - "WHERE status=3 ;"; - $q = $this->mysql_query($query); - $groups = array(); - while (($row = mysql_fetch_array($q)) !==false) { - $groups[] = $row[0].''; - } - return $groups; - } - public function listUsers() { - $table = $this->mysql_table('auth'); - $query = - "SELECT uid \n". - "FROM $table \n". - "WHERE status < 3 ;"; - $q = $this->mysql_query($query); - $users = array(); - while (($row = mysql_fetch_array($q)) !==false) { - $users[] = (int)$row[0]; - } - return $users; - } - - // The 'users' table - - public function findUser($setting, $value) { - $t = $this->mysql_table('users'); - $k = $this->mysql_escape($setting); - $v = $this->mysql_escape($value); - $query = - "SELECT * \n". - "FROM $t \n". - "WHERE k = '$k' \n". - "AND UPPER(v)=UPPER('$v') ;"; - $q = $this->mysql_query($query); - $user = mysql_fetch_array($q); - if (isset($user['uid'])) { - return $user['uid']; - } else { - return false; - } - } - public function getUserConf($uid, $setting) { - if (!is_int($uid)) return false; - $t = $this->mysql_table('users'); - $k = $this->mysql_escape($setting); - $query = - "SELECT * \n". - "FROM $t \n". - "WHERE k='$k' \n". - "AND uid=$uid ;"; - $q = $this->mysql_query($query); - $row = mysql_fetch_array($q); - if (isset($row['v'])) { - return $row['v']; - } else { - return false; - } - } - public function setUserConf($uid, $setting, $value) { - if (!is_int($uid)) return false; - $isset = ($this->getUserConf($uid, $setting) !== false); - $t = $this->mysql_table('users'); - $k = $this->mysql_escape($setting); - $v = $this->mysql_escape($value); - if ($isset) { - $query = - "UPDATE $t \n". - "SET v = '$v' \n". - "WHERE k = '$k' \n". - "AND uid = $uid ;"; - } else { - $query = - "INSERT INTO $t ( uid, k , v ) \n". - "VALUES ($uid, '$k', '$v') ;"; - } - $q = $this->mysql_query($query); - return ($q?true:false); - } - public function getUsersInGroup($groupname) { - $table = $this->mysql_table('users'); - $group = $this->mysql_escape($groupname); - $query = - "SELECT uid \n". - "FROM $table \n". - "WHERE k='groups' \n". - "AND v LIKE '%,$group,%' ;"; - $q = $this->mysql_query($query); - $users = array(); - while (($row = mysql_fetch_array($q)) !==false) { - $users[] = $row[0]; - } - return $users; - } - - // The 'plugins' table - - public function getPluginConf($plugin, $key) { - $t = $this->mysql_table('plugins'); - $p = $this->mysql_escape($plugin); - $k = $this->mysql_escape($key); - $query = - "SELECT * \n". - "FROM $t \n". - "WHERE k='$k' \n". - "AND plugin='$p' ;"; - $q = $this->mysql_query($query); - $row = mysql_fetch_array($q); - if (isset($row['v'])) { - return $row['v']; - } else { - return false; - } - } - public function setPluginConf($plugin, $key, $value) { - $isset = ($this->getPluginConf($plugin, $key) !== false); - $t = $this->mysql_table('plugins'); - $p = $this->mysql_escape($plugin); - $k = $this->mysql_escape($key); - $v = $this->mysql_escape($value); - if ($isset) { - $query = - "UPDATE $t \n". - "SET v = '$v' \n". - "WHERE k = '$k' \n". - "AND plugin = '$p' ;"; - } else { - $query = - "INSERT INTO $t (plugin, k , v ) \n". - "VALUES ('$p' , '$k', '$v') ;"; - } - $q = $this->mysql_query($query); - return ($q?true:false); - } - - // The 'conf' table - - public function getSysConf($key) { - $t = $this->mysql_table('conf'); - $k = $this->mysql_escape($key); - $query = - "SELECT * \n". - "FROM $t \n". - "WHERE k='$k' ;"; - $q = $this->mysql_query($query); - $row = mysql_fetch_array($q); - if (isset($row['v'])) { - return $row['v']; - } else { - return false; - } - } - public function setSysConf($key, $value) { - $isset = ($this->getSysConf($key) !== false); - $t = $this->mysql_table('conf'); - $k = $this->mysql_escape($key); - $v = $this->mysql_escape($value); - if ($isset) { - $query = - "UPDATE $t \n". - "SET v = '$v' \n". - "WHERE k = '$k' ;"; - } else { - $query = - "INSERT INTO $t ( k , v ) \n". - "VALUES ('$k', '$v') ;"; - } - $q = $this->mysql_query($query); - return ($q?true:false); - } - - /** - * Strip out empty group names and duplicates, sort. - */ - private static function sanitizeArray($in) { - $out = array(); - foreach ($in as $item) { - if (($item !== '')&&(!in_array($item, $out))) { - $out[] = $item; - } - } - natsort($out); - return $out; - } - /** - * Translate an array into a value suitable to be stored into a - * key-value store in the database. - */ - public static function arrayToValue($list) { - $out_list = self::sanitizeArray($list); - return ','.implode(',', $out_list).','; - } - /** - * Translate a value from arrayToValue() back into an array. - */ - public static function valueToArray($value) { - $raw_list = explode(',', $value); - $out_list = self::sanitizeArray($raw_list); - return $out_list; - } - -} diff --git a/src/lib/Hasher.class.php b/src/lib/Hasher.class.php deleted file mode 100644 index dc16d68..0000000 --- a/src/lib/Hasher.class.php +++ /dev/null @@ -1,18 +0,0 @@ -pw_hash = new PasswordHash(8, false); - } - - public function hash($password) { - return $this->pw_hash->HashPassword($password); - } - public function check($password, $hash) { - return $this->pw_hash->CheckPassword($password, $hash); - } -} diff --git a/src/lib/Login.class.php b/src/lib/Login.class.php deleted file mode 100644 index bb21928..0000000 --- a/src/lib/Login.class.php +++ /dev/null @@ -1,41 +0,0 @@ -getUID($username); - if ($uid!==false && $db->getStatus($uid)>=3) - $uid=false; - if ($uid===false) { - // user does not exist - return 2; - } - $hash = $db->getPasswordHash($uid); - if ($hasher->check($password, $hash)) { - // success - $_SESSION['uid'] = $uid; - return 0; - } else { - // wrong password - return 1; - } - } - public static function isLoggedIn() { - if ( isset($_SESSION['uid']) && ($_SESSION['uid']!='') ) { - return $_SESSION['uid']; - } else { - return false; - } - } - public static function logout() { - $_SESSION['uid'] = ''; - } -} diff --git a/src/lib/Mime.class.php b/src/lib/Mime.class.php deleted file mode 100644 index f37c1eb..0000000 --- a/src/lib/Mime.class.php +++ /dev/null @@ -1,45 +0,0 @@ - array( - 'text/csv', 'text/x-csv', - 'text/x-comma-separated-values', - 'text/comma-separated-values', - 'application/csv', - 'application/excel', 'application/vnd.msexcel'), - 'xhtml' => array('text/html', 'application/xhtml+xml'), - 'html' => array('text/html', 'application/xhtml+xml'), - 'bmp' => 'image/bmp', - 'gif' => 'image/gif', - 'jpeg' => array('image/jpeg', 'image/pjpeg'), - 'jpg' => array('image/jpeg', 'image/pjpeg'), - 'jpe' => array('image/jpeg', 'image/pjpeg'), - 'png' => array('image/png', 'image/x-png'), - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'css' => 'text/css', - 'htm' => 'text/html', - 'txt' => 'text/plain', - 'json' => array('application/json', 'text/json') - ); - - public static function ext2mime($ext) { - $mimes = self::$mimes; - $mime = $mimes[$ext]; - if (!is_array($mime)) $mime = array($mime); - return $mime; - } - public static function mime2ext($my_mime) { - $ret = array(); - foreach (self::mimes as $ext => $mime) { - if (is_array($mime)) { - $match = in_array($my_mime, $mime); - } else { - $match = $my_mime==$mime; - } - if ($match) $ret[] = $ext; - } - return $ret; - } -} \ No newline at end of file diff --git a/src/lib/Model.class.php b/src/lib/Model.class.php deleted file mode 100644 index 0cce525..0000000 --- a/src/lib/Model.class.php +++ /dev/null @@ -1,9 +0,0 @@ -db = Database::getInstance(); - } -} diff --git a/src/lib/Plugin.class.php b/src/lib/Plugin.class.php deleted file mode 100644 index 9d2fc2e..0000000 --- a/src/lib/Plugin.class.php +++ /dev/null @@ -1,25 +0,0 @@ -config[$param])) { - $this->config[$param]=$value; - } - } - - public function userConfig() { return array(); } - protected function addConfigGroup($arr, $group) { - if (!isset($arr[$group])) - $arr[$group] = array(); - } - - public abstract function init(); - - public function antispam_html() { return ''; } - public function antispam_verify() { return true; } -} diff --git a/src/lib/PluginManager.class.php b/src/lib/PluginManager.class.php deleted file mode 100644 index ce5a3ef..0000000 --- a/src/lib/PluginManager.class.php +++ /dev/null @@ -1,99 +0,0 @@ - $type) { - $value = $db->getPluginConf($plugin_name, $param); - if ($value!==false) { - switch ($type) { - case 'text': - case 'password': - $value = "$value"; - break; - case 'int': - $value = (int)$value; - break; - } - $obj->configSet($param, $value); - } - } - return $obj; - } - - /** - * Return an array of available plugin names. - */ - public function listPlugins() { - $plugins = array(); - - $dirs = explode(PATH_SEPARATOR, PLUGINPATH); - foreach ($dirs as $dir) { - // Find all files in $dir with the ext `.class.php' - $files = glob($dir.'/*.class.php'); - foreach ($files as $file) { - $plugins[] = preg_replace('@\.class\.php$@', '$1', basename($file)); - } - } - - return $plugins; - } - - /** - * Return an array of enabled plugin names. - */ - public function getActivePlugins() { - $db = Database::getInstance(); - $string = $db->getSysConf('plugins'); - return $db->valueToArray($string); - } - - /** - * Set the enabled plugins. - */ - public function setActivePlugins($plugins) { - $db = Database::getInstance(); - $string = $db->arrayToValue($plugins); - return $db->setSysConf('plugins', $string); - } - - /** - * Load the enabled plugins. - */ - public function loadPlugins() { - if ($this->loaded) return; - $plugin_names = $this->getActivePlugins(); - foreach ($plugin_names as $name) { - $this->plugins[$name] = $this->loadPlugin($name); - } - $this->loaded = true; - } - - public function callHook($hook, $arg=null) { - $this->loadPlugins(); - $ret = array(); - foreach ($this->plugins as $name => $plugin) { - $ret[$name] = call_user_func(array($plugin, $hook), - &$arg); - } - return $ret; - } - - public function staticHook($plugin_name, $hook) { - require_once("$plugin_name.class.php"); - return call_user_func("$plugin_name::$hook"); - } - -} diff --git a/src/lib/Router.class.php b/src/lib/Router.class.php deleted file mode 100644 index 238e3f8..0000000 --- a/src/lib/Router.class.php +++ /dev/null @@ -1,110 +0,0 @@ - 'Http404'); - - /** - * Instantiate a router that looks for controllers in $controllerpath. - */ - public function Router($controllerpath) { - // create a $ROUTES global that can be used to set up our - // $this->routes. - global $ROUTES; - $ROUTES = $this->routes; - - // Split $controllerpath into directories, and load the - // controllers in each. - $dirs = explode(PATH_SEPARATOR, $controllerpath); - foreach ($dirs as $dir) { - // Find all files in $dir with the ext `.class.php' - $files = glob($dir.'/*.class.php'); - foreach ($files as $file) { - // and include them - require_once($file); - } - } - - $this->routes = $ROUTES; - unset($ROUTES); - } - - /** - * Route the page at the relative URL $page to the appropriate - * controller, and call the appropriate function. - */ - public function route($page) { - $parts = explode('/', $page); - $length = count($parts); // the # of segments in $controllerpart - - // if $page ends in "/", strip that off - if ($parts[$length-1]=='') { - array_pop($parts); - $length--; - } - - $controllerpart = implode('/', $parts); - - // Keep shortening $controllerpart until it matches something in - // $this->routes. The shortest it will ever become is '/*'. - // If no key exists for '/*', that's an infinite loop. - // Fortunately, the default value of $this->routes directs '/*' - // to the Http404 controller. - while(!isset($this->routes[$controllerpart])) { - $some_parts = array_slice($parts, 0, $length); - $controllerpart = implode('/', $some_parts).'/*'; - $length--; - } - $length++; - - // Figure what function to call on what controller - // Grammar Nazi Warning: `what' or `which'? - $controller = $this->routes[$controllerpart]; - if (strpos($controller, '->')===false) { - // imply function - $function = $parts[$length]; - } else { - preg_match('/(.*)->(.*)/', $controller, $matches); - $controller = $matches[1]; - $function = $matches[2]; - } - - // Default to the `index' function, provided by all controllers - if ($function=='') { - $function = 'index'; - } - - // We will pass these arrays to the function. - $routed = array_slice($parts, 0, $length); - $remainder = array_slice($parts, $length); - - // Finally, run the controller - $obj = new $controller(); - if (in_array($function, get_class_methods($obj))) { - call_user_func(array($obj, $function), - $routed, $remainder); - } else { - $obj->http404($routed, $remainder); - } - } - - /** - * This is to allow controllers to register themselves to the router. - * If $function=='', then the function will be determined by the segment - * to the right of the last segment in $path - */ - public static function register($path, $controller, $function='') { - $str = $controller.(($function=='')?'':'->'.$function); - global $ROUTES; - $ROUTES[$path] = $str; - } -} \ No newline at end of file diff --git a/src/lib/Singleton.class.php b/src/lib/Singleton.class.php deleted file mode 100644 index 2f8c74f..0000000 --- a/src/lib/Singleton.class.php +++ /dev/null @@ -1,12 +0,0 @@ -/',$html,$matches); - $shortUrl = $matches[1]; - curl_close($ch); - return $shortUrl; - } - - public function baseUrl() { - $base = $_SERVER['REQUEST_URI']; - - $db = Database::getInstance(); - if ($db !== null) { - $b = $db->getSysConf('baseurl'); - if ($b != false) { - $base = $b; - } - } - - return $base; - } -} diff --git a/src/lib/View.class.php b/src/lib/View.class.php deleted file mode 100644 index d7a21d3..0000000 --- a/src/lib/View.class.php +++ /dev/null @@ -1,135 +0,0 @@ -extensions = array(); - $regex = '@'.preg_quote(VIEWPATH,'@').'[^.]*\.(.*)\.php$@'; - foreach ($files as $file) { - $ext = preg_replace($regex, '$1', $file); - $this->extensions[] = $ext; - } - if (count($this->extensions)<1) return false; - - if (PAGE_EXT != '') { - // First, do a check if we can just return requested - // file extension: - if (in_array(PAGE_EXT, $this->extensions)) { - return PAGE_EXT; - } - - // Check for other extensions with the same mime type as - // the requested: - $accept_str = implode(', ', Mime::ext2mime(PAGE_EXT)); - $extensions = $this->parseAccept($view, $accept_str); - if ($ext = $this->chooseBetweenEquals($extensions)) return $ext; - } - - // Check for other extensions based on HTTP 'Accept' headers: - $accept_str = $_SERVER['HTTP_ACCEPT']; - $extensions = $this->parseAccept($view, $accept_str); - if ($ext = $this->chooseBetweenEquals($extensions)) return $ext; - - // Well, all the good options failed, so let's see what we've - // got left: - $extensions = $this->extensions; - return $this->chooseBetweenEquals($extensions); - - } - - private function parseAccept($view, $accept_str) { - // $prefs is a associative array where the key is the file - // extension, and the value is how much we like that extension. - // Higher numbers are better. - $prefs = array(); - - $accept = new HTTP_Accept($accept_str); - - // Loop through the candidate views, and record how much we - // like each. - foreach ($this->extensions as $ext) { - $mimes = Mime::ext2mime($ext); - foreach ($mimes as $mime) { - $quality = $accept->getQuality($mime); - if (isset($prefs[$ext])) { - $quality = max($prefs[$ext], $quality); - } - $prefs[$ext] = $quality; - } - } - - // Create an array of all extensions tied for the top quality. - $ret = array(); - $top_quality = 0.001;// minimum acceptable according to RFC 2616 - foreach ($prefs as $ext => $quality) { - if ($quality > $top_quality) { - $top_quality = $quality; - $ret = array(); - } - if ($quality == $top_quality) { - $ret[] = $ext; - } - } - return $ret; - } - - public function __construct($view) { - $this->ext = $this->chooseExtension($view); - $this->view = $view; - } - - public function show($vars) { - $file = self::filename($this->view, $this->ext); - $mimes = Mime::ext2mime($this->ext); - - header('Content-type: '.$mimes[0]); - - require_once(VIEWPATH.'/Template.class.php'); - $vars['template'] = new Template(); - - global $VARS; - $VARS = $vars; - include($file); - unset($VARS); - } -} diff --git a/src/models/Auth.class.php b/src/models/Auth.class.php deleted file mode 100644 index 39f627e..0000000 --- a/src/models/Auth.class.php +++ /dev/null @@ -1,157 +0,0 @@ -getStatus($uid); - switch ($type) { - case 0: // unactivated user - case 1: // user - case 2: $obj = new User($uid); // admin - case 3: $obj = new Group($uid); - case 4: $obj = new Auth($uid); // deleted - } - self::$users[$uid] = $obj; - } - return self::$users[$uid]; - } - - /**********************************************************************\ - * Static stuff * - \**********************************************************************/ - public static function isNameLegal($name) { - // Current rules: - // * Not in "$illegal_names" - // * Does not contain '.' - // * Fewer than 256 characters - $illegal_names = array('', 'new', 'index', 'all'); - return true - && (!in_array($name, $illegal_names)) - && (strpos($name,'.')===false) - && (strpos($name,'!')===false) - && (strlen($name)<256); - } - - /**********************************************************************\ - * Class stuff * - \**********************************************************************/ - protected $uid = false; - public function __construct($uid) { - parent::__construct(); - $this->uid = $uid; - } - public function getUID() { - return $this->uid; - } - - /**********************************************************************\ - * The 'auth' table. * - \**********************************************************************/ - - // Row Type //////////////////////////////////////////////////////////// - /** - * @return 0=unverified 1=user 2=admin 3=group 4=deleted - */ - protected function getType() { - $type = $this->db->getStatus($this->uid); - return $type; - } - protected function setType($type) { - $logged_in_uid = Login::isLoggedIn(); - $logged_in_obj = Auth::getInstance($logged_in_uid); - $is_admin = $logged_in_obj->isAdmin(); - if (!$is_admin) return false; - return $this->db->setStatus($this->uid, $type); - } - public function isUser() { - $type = $this->getType(); - return ($type===1) || ($type===2); - } - public function isAdmin() { - $type = $this->getType(); - return ($type===2); - } - public function isGroup() { - $type = $this->getType(); - return ($type===3); - } - public function setUser($is_user) { - $is_user = ($is_user?true:false); - if ($this->isUser() != $is_user) { - $this->setType($is_user?1:0); - } - } - public function setAdmin($is_admin) { - $is_admin = ($is_admin?true:false); - $is_user = $this->isUser(); - $this->setType($is_admin?2:($is_user?1:0)); - } - public function delete() { - $this->setType(4); - } - - // Permissions ///////////////////////////////////////////////////////// - public function canRead() { - $logged_in_uid = Login::isLoggedIn(); - $is_me = ($logged_in_uid === $this->uid); - - $logged_in_obj = Auth::getInstance($logged_in_uid); - $is_user = $logged_in_obj->isUser(); - - return ($is_me || $is_user); - } - public function canEdit() { - $logged_in_uid = Login::isLoggedIn(); - $is_me = ($logged_in_uid === $this->uid); - - $logged_in_obj = Auth::getInstance($logged_in_uid); - $is_admin = $logged_in_obj->isAdmin(); - - return ($is_me || $is_admin); - } - - // [user|group]name //////////////////////////////////////////////////// - public function getName() { - if ($this->db===null) { - return false; - } else { - return $this->db->getUsername($this->uid); - } - } - public function setName($new_name) { - if (!$this->canEdit()) return false; - if (!self::isNameLegal($new_name)) return false; - return $this->db->setUsername($this->uid, $new_name); - } - - /**********************************************************************\ - * The 'users' table. * - \**********************************************************************/ - - public function getConf($setting) { - if (!$this->canRead()) return false; - return $this->db->getUserConf($this->uid, $setting); - } - public function setConf($setting, $value) { - if (!$this->canEdit()) return false; - return $this->db->setUserConf($this->uid, $setting, $value); - } - public function getConfArray($setting) { - $string = $this->getConf($setting); - return $this->db->valueToArray($string); - } - public function setConfArray($setting, $list) { - $string = $this->db->arrayToValue($list); - return $this->setConf($setting, $string); - } -} diff --git a/src/models/ContactMethod.class.php b/src/models/ContactMethod.class.php deleted file mode 100644 index 1dd40ee..0000000 --- a/src/models/ContactMethod.class.php +++ /dev/null @@ -1,29 +0,0 @@ -verb_slug = $verb_slug; - $this->addr_slug = $addr_slug; - $this->verb_text = $verb_text; - $this->addr_text = $addr_text; - - global $CONTACT_METHODS; - $CONTACT_METHODS[$verb_slug] = $this; - } - public function setHandler($handler) { - $this->handler = $handler; - } -} diff --git a/src/models/Group.class.php b/src/models/Group.class.php deleted file mode 100644 index f981a4f..0000000 --- a/src/models/Group.class.php +++ /dev/null @@ -1,23 +0,0 @@ -uid; - } - - /**********************************************************************\ - * The 'auth' table. * - \**********************************************************************/ - - /**********************************************************************\ - * The 'users' table. * - \**********************************************************************/ - - public function getMembers() { - return $this->db->getUsersInGroup($this->getName()); - } -} diff --git a/src/models/User.class.php b/src/models/User.class.php deleted file mode 100644 index b6dbede..0000000 --- a/src/models/User.class.php +++ /dev/null @@ -1,25 +0,0 @@ -uid; - } - - /**********************************************************************\ - * The 'auth' table. * - \**********************************************************************/ - - public function setPassword($password) { - if (!$this->canEdit()) return false; - return $this->db->setPassword($this->uid, $password); - } - - /**********************************************************************\ - * The 'users' table. * - \**********************************************************************/ - -} diff --git a/src/plugins/InformationPlugin.class.php b/src/plugins/InformationPlugin.class.php deleted file mode 100644 index 70ec8ac..0000000 --- a/src/plugins/InformationPlugin.class.php +++ /dev/null @@ -1,62 +0,0 @@ -addConfigGroup($arr, $group); - $arr[$group][] = array('firstname','First Name','text'); - $arr[$group][] = array('lastname','Last Name','text'); - $arr[$group][] = array('school','Home School','text'); - $arr[$group][] = array('hsclass','Highschool Class of','text'); - - $group = 'New Member Questions'; - $this->addConfigGroup($arr, $group); - $arr[$group][] = array('q_why_team', - 'Why do you want to be a part of the robotics team?', - 'textarea'); - $arr[$group][] = array('q_strengths', - 'What strengths do you have that can contribute to the robotics team?', - 'textarea'); - $arr[$group][] = array('q_other_activities', - 'Other after school activities--sports, performing arts, extracurricular activities. (January through March)', - 'textarea'); - $arr[$group][] = array('q_other_commitments', - 'After school/weekend work commitments. (January through March)', - 'textarea'); - // TODO: Top 3 subteams - $arr[$group][] = array('q_who_you_know', - 'Who do you know that could possibly help our team this year? '. - 'This includes material resources, supplying or preparing food '. - 'for work nights/competitions, corporate sponsorship, travel, '. - 'engineers, computer programmers, web developers, and fundraisers.', - 'textarea'); - $arr[$group][] = array('x_bogus_recommend', - "List two teachers who we could contact for your recommendation to be a member of this year's team.", - 'paragraph'); - $arr[$group][] = array('q_teacher_recommend1', 'Teacher 1', 'text'); - $arr[$group][] = array('q_teacher_recommend2', 'Teacher 2', 'text'); - $arr[$group][] = array('x_bogus_agreement', - "I understand that if I am chosen to participate ". - "in the robotics project, I will represent my ". - "school in a positive manner. If I fail to do so, ". - "I may be removed from the team at any time. In ". - "addition, if I do not have good attendance ". - "during this project, I will not be allowed to ". - "travel with the team to the competitions. I also ". - "understand that all of the school rules will be ". - "in effect at all times.", - 'paragraph'); - $arr[$group][] = array('q_i_agree', - "I agree", - 'checkbox'); - } - public function sendPrivate($to, $id, $subject, $body) {} - public function sendBroadcast($id, $subject, $body) {} -} diff --git a/src/plugins/ReCaptcha.class.php b/src/plugins/ReCaptcha.class.php deleted file mode 100644 index 165493b..0000000 --- a/src/plugins/ReCaptcha.class.php +++ /dev/null @@ -1,47 +0,0 @@ -'', - 'private_key'=>''); - public static function description() { - return 'Add a reCaptcha to keep out spam users.'; - } - public static function configList() { - return array('public_key'=>'text', - 'private_key'=>'text'); - } - public function init() {} - - private $resp = null; - private function getResp() { - if ($this->resp===null) { - require_once('recaptchalib.php'); - @$response = $_POST['recaptcha_response_field']; - @$challenge = $_POST['recaptcha_challenge_field']; - $this->resp = recaptcha_check_answer($this->config['private_key'], - $_SERVER['REMOTE_ADDR'], - $challenge, - $response); - } - return $this->resp; - } - - private function getError() { - if ($_POST["recaptcha_response_field"] && !$this->antispam_verify()) { - return $this->getResp()->error; - } else { - return false; - } - } - - public function antispam_verify() { - return $this->getResp()->is_valid; - } - - public function antispam_html() { - require_once('recaptchalib.php'); - return recaptcha_get_html($this->config['public_key'], $this->getError()); - } -} diff --git a/src/plugins/SenderGVSMS.class.php b/src/plugins/SenderGVSMS.class.php deleted file mode 100644 index 7919007..0000000 --- a/src/plugins/SenderGVSMS.class.php +++ /dev/null @@ -1,34 +0,0 @@ -'', - 'password'=>'', - 'length'=>160); - private $obj; - - public static function description() { - return 'Send messages over SMS via GoogleVoice.'; - } - - public static function configList() { - return array('username'=>'text', - 'password'=>'password'); - } - - public function init() { - $this->obj = new GoogleVoice($this->config['username'], - $this->config['password']); - } - - public function sendPrivate($phoneNum, $id, $subject, $body) { - global $shorturl, $messenger; - $url = $shorturl->get($messenger->id2url($id)); - $maxlen = $this->config['length']-(strlen($url)+1); - if($maxlen < strlen($subject)) { - $subject = substr($subject,0,$maxlen-3).'...'; - } - $this->obj->sms($phoneNum, $subject.' '.$url); - } -} diff --git a/src/plugins/SenderIdentica.class.php b/src/plugins/SenderIdentica.class.php deleted file mode 100644 index ea9b343..0000000 --- a/src/plugins/SenderIdentica.class.php +++ /dev/null @@ -1,35 +0,0 @@ -'', - 'password'=>'', - 'length'=>140); - private $obj; - - public static function description() { - return 'Dent messages to Identi.ca.'; - } - - public static function configList() { - return array('username'=>'text', - 'password'=>'password', - 'length'=>'int'); - } - - public function init() { - $this->obj = new Identica($this->config['username'], - $this->config['password']); - } - - public function sendBroadcast($id, $subject, $body) { - global $shorturl, $messenger; - $url = $shorturl->get($messenger->id2url($id)); - $maxlen = $this->config['length']-(strlen($url)+1); - if($maxlen < strlen($subject)) { - $subject = substr($subject,0,$maxlen-3).'...'; - } - $this->obj->updateStatus($subject.' '.$url); - } -} diff --git a/src/plugins/maildir.php b/src/plugins/maildir.php deleted file mode 100644 index 28211b5..0000000 --- a/src/plugins/maildir.php +++ /dev/null @@ -1,58 +0,0 @@ -''); - - public function configList() { - return array('dir'=>'text'); - } - - public function init() {} - - public function get() { - $this->handle_new(); - $this->handle_cur(); - $this->handle_tmp(); - } - - private function handle_new() { - // move files in new to cur - $new = $this->config['dir'].'/new'; - $cur = $this->config['dir'].'/cur'; - $dh = opendir($new); - - while (($file = readdir($dh)) !== false) { - if (substr($file,0,1)!='.' && is_file($new.'/'.$file)) { - rename($new.'/'.$file, - $cur.'/'.$file.':'); - } - } - } - private function handle_cur() { - $cur = $this->config['dir'].'/cur'; - $dh = opendir($cur); - - while (($file = readdir($dh)) !== false) { - if (substr($file,0,1)!='.' && is_file($cur.'/'.$file)) { - - } - } - } - private function handle_tmp() { - // Clean up files that haven't been accessed for 36 hours - $tmp = $this->config['dir'].'/tmp'; - $dh = opendir($cur); - - while (($file = readdir($dh)) !== false) { - if (is_file($tmp.'/'.$file)) { - $atime = fileatime($tmp.'/'.$file); - $time = time(); - if (($time-$atime)>(36*60*60)) { - unlink($tmp.'/'.$file); - } - } - } - } - -} diff --git a/src/views/Template.class.php b/src/views/Template.class.php deleted file mode 100644 index 9d55b75..0000000 --- a/src/views/Template.class.php +++ /dev/null @@ -1,316 +0,0 @@ -ret = $ret; - } - - private function tabs() { - $str = ''; - for ($i=0;$i<$this->indent;$i++) { $str .= "\t"; } - return $str; - } - - private function attr($attr='') { - $tags=''; - if (is_array($attr)) { - foreach($attr as $key=>$value) { - $tags .= " $key=\"$value\""; - } - } - return $tags; - } - - public function tag($tag, $attr='', $content=false) { - $tags = $this->attr($attr); - $str = $this->tabs()."<$tag$tags"; - if ($content===false) { - $str.= " />"; - } else { - $str.= ">$content"; - } - $str.= "\n"; - if ($this->ret) return $str; - echo $str; - } - - public function openTag($tag, $attr='') { - $tags = $this->attr($attr); - $str = $this->tabs()."<$tag$tags>\n"; - $this->indent++; - if ($this->ret) return $str; - echo $str; - } - - public function closeTag($tag) { - $this->indent--; - $str = $this->tabs()."\n"; - if ($this->ret) return $str; - echo $str; - } - - public function text($text) { - $str = $this->tabs().$text."\n"; - if ($this->ret) return $str; - echo $str; - } - - public function paragraph($text, $attr='', $return=false) { - $tabs = $this->tabs(); - $tags = $this->attr($attr); - $str = $tabs.""; - $str.= wordwrap($text, 78-($this->indent*8), "\n$tabs "); - $str.= "

\n"; - if ($this->ret||$return) return $str; - echo $str; - } - - public function link($target, $text, $return=false) { - $ret = $this->ret; - $this->ret |= $return; - $str = $this->tag('a', array('href'=>$target), $text); - $this->ret = $ret; - if ($this->ret||$return) return $str; - echo $str; - } - public function url($page) { - return Site::getInstance()->baseUrl().$page; - } - - public function row($cells) { - $str = $this->openTag('tr'); - foreach ($cells as $cell) - $str.= $this->tag('td', array(), $cell); - $str.= $this->closeTag('tr'); - if ($this->ret) return $str; - echo $str; - } - private function css($file, $media) { - $str.= $this->tag('link', array('rel'=>"stylesheet", - 'type'=>"text/css", - 'href'=>$this->url($file), - 'media'=>$media)); - if ($this->ret) return $str; - echo $str; - } - public function header($title) { - // username=false if not logged in or not connected to DB - $username = Auth::getInstance(Login::isLoggedIn())->getName(); - - $ret = $this->ret; - $this->ret = true; - - $logged_in = ($username!==false); - - $str = ''."\n"; - $str.= ''."\n"; - - $xmlns = "http://www.w3.org/1999/xhtml"; - $str.= $this->openTag('html', array('xmlns'=>$xmlns, - 'lang'=>"en-us", - 'dir'=>"ltr")); - $this->indent = 0; // don't indent for the tag - - $str.= $this->openTag('head'); - $str.= $this->tag('title', array(), htmlspecialchars($title)); - $str.= $this->css('style.css', 'all'); - $str.= $this->css('screen.css', 'screen'); - $str.= $this->css('print.css', 'print'); - $str.= $this->closeTag('head'); - - $body_class = 'logged'.($logged_in?'in':'out'); - $str.= $this->openTag('body', array('class'=>$body_class)); - - $str.= $this->openTag('div', array('class'=>'infobar')); - if ($logged_in) { - $user = htmlentities($username); - - $str.= $this->link($this->url(''), "Home"); - $str.= $this->link($this->url("users/$user"),"@$user"); - $str.= $this->logout_button('Logout'); - } else { - $url=$_SERVER['REQUEST_URI']; - $str.= $this->openTag('form', - array('action'=>$this->url('auth'), - 'method'=>'post')); - $str.= $this->tag('input', array('type'=>'hidden', - 'name'=>'action', - 'value'=>'login')); - $str.= $this->tag('input', array('type'=>'hidden', - 'name'=>'url', - 'value'=>$url)); - $str.= $this->tag('label', - array('for'=>'username'),'Username:'); - $str.= $this->tag('input', array('type'=>'text', - 'name'=>'username', - 'id'=>'username')); - $str.= $this->tag('label', - array('for'=>'password'),'Password:'); - $str.= $this->tag('input', array('type'=>'password', - 'name'=>'password', - 'id'=>'password')); - $str.= $this->tag('input', array('type'=>'submit', - 'value'=>'Login')); - $str.= $this->link($this->url("users/new"),'New Account'); - $str.= $this->closeTag('form'); - } - $str.= $this->closeTag('div'); - - $str.= $this->openTag('div',array('class'=>'main')); - $str.= $this->openTag('div',array('class'=>'main_sub')); - - $this->ret = $ret; - if ($this->ret) return $str; - echo $str; - } - - public function footer() { - $str = $this->closeTag('div'); - $str.= $this->closeTag('div'); - $str.= $this->closeTag('body'); - $str.= $this->closeTag('html'); - - if ($this->ret) return $str; - echo $str; - } - - public function openFieldset($name, $lock=false) { - $class = ($lock?' class="readonly"':''); - $str = $this->text("$name
    "); - $this->indent++; - if ($this->ret) return $str; - echo $str; - } - - public function closeFieldset() { - $this->indent--; - $str = $this->text("
"); - if ($this->ret) return $str; - echo $str; - } - - public function input($id, $label, $hint, $html, $tags=null) { - if ($tags===null) { $tags=array(); } - $str = $this->openTag('li', $tags); - $str.= $this->tag('label', array('for'=>$id), $label); - $str.= $this->text($html); - if (strlen($hint)>0) { - $str.=$this->paragraph($hint, - Array('class'=>'form_data')); - } - $str.= $this->closeTag('li'); - if ($this->ret) return $str; - echo $str; - } - - private function inputStr($type, $id, $default, $lock) { - $value = htmlentities($default); - $tag = ($lock?"readonly='readonly' ":''); - return ""; - } - public function inputTextArea($id, $label, $hint='', $default='', $lock=FALSE) { - $value = htmlentities($default); - $tag = ($lock?"readonly='readonly' ":''); - return $this->input($id, $label, $hint, - "", - array('class'=>'wide')); - } - - public function inputText($id, $label, $hint='', $default='', $lock=FALSE) { - return $this->input($id, $label, $hint, - $this->inputStr('text', $id, $default, $lock)); - } - - public function inputPassword($id, $label, $hint='', $default='', $lock=FALSE) { - return $this->input($id, $label, $hint, - $this->inputStr('password', $id, $default, $lock)); - } - - public function inputNewPassword($id, $label, $default='', $lock=FALSE) { - return $this->input($id, $label, - "Type the same password twice, to make sure you don't mistype.", - $this->inputStr('password', $id, $default, $lock). - "\n".$this->tabs()."\t". - $this->inputStr('password', $id.'_verify', $default,$lock)); - } - public function inputBool($id, $label, $hint='', $default=FALSE, $lock=FALSE) { - $tag = ''; - if ($lock) $tag.= "readonly='readonly' "; - if ($default) $tag.= "checked='checked' "; - return $this->input($id, $label, $hint, - "". - ""); - - $attrib = array('type'=>'checkbox', - 'id'=>$id, - 'name'=>$name.'[]', - 'value'=>$value); - if ($default) $attrib['checked']='checked'; - if ($lock ) $attrib['readonly']='readonly'; - - $str = $this->openTag('li'); - $str.= $this->tag('input', $attrib); - $str.= $this->tag('label', array('for'=>$id), $label); - $str.= $this->closeTag('li'); - - if ($this->ret) return $str; - echo $str; - - } - - public function inputBoolArray($name, $value, $label, $default=FALSE, $lock=FALSE) { - $id = $name.'_'.$value; - $attrib = array('type'=>'checkbox', - 'id'=>$id, - 'name'=>$name.'[]', - 'value'=>$value); - if ($default) $attrib['checked']='checked'; - if ($lock ) $attrib['readonly']='readonly'; - - $str = $this->openTag('li'); - $str.= $this->tag('input', $attrib); - $str.= $this->tag('label', array('for'=>$id), $label); - $str.= $this->closeTag('li'); - - if ($this->ret) return $str; - echo $str; - - } - - public function inputP($text, $error=false) { - $str = $this->openTag('li'); - $str.=$this->paragraph($text, - array('class'=>($error?' error':''))); - $str.= $this->closeTag('li'); - if ($this->ret) return $str; - echo $str; - } - - public function logout_button($text) { - $str = $this->openTag('form',array('action'=>$this->url('auth'), - 'method'=>"post", - 'style'=>'display:inline')); - $str.= $this->tag('input', array('type'=>'hidden', - 'name'=>'action', - 'value'=>'logout')); - $str.= $this->tag('input', array('type'=>'submit', - 'value'=>$text)); - $str.= $this->closeTag('form'); - if ($this->ret) return $str; - echo $str; - } -} diff --git a/src/views/includes/header-include.php b/src/views/includes/header-include.php deleted file mode 100644 index 3826b3a..0000000 --- a/src/views/includes/header-include.php +++ /dev/null @@ -1,51 +0,0 @@ -getName(); -$logged_in = ($username!==false); - -$ret = $this->ret; -$this->ret = true; - -function body_class() { - $body_class = 'logged'.($logged_in?'in':'out'); - echo 'class="'+$body_class+'"'; -} - -require(dirname(__FILE__)+"/header.php"); \ No newline at end of file diff --git a/src/views/includes/header.php b/src/views/includes/header.php deleted file mode 100644 index 0a3e161..0000000 --- a/src/views/includes/header.php +++ /dev/null @@ -1,84 +0,0 @@ - section and everything up till
- * - * @package WordPress - * @subpackage Twenty_Eleven - * @since Twenty Eleven 1.0 - */ -?> - - - - -> - - - - -<?php - /* - * Print the <title> tag based on what is being viewed. - */ - global $_title_; - echo $_title_; - ?> - - - - - - * tag of your theme, or you will break many plugins, which - * generally use this hook to add elements to such - * as styles, scripts, and meta tags. - */ - wp_head(); -?> - - -> -
- - - -
\ No newline at end of file diff --git a/src/views/pages/auth/badrequest.html.php b/src/views/pages/auth/badrequest.html.php deleted file mode 100644 index c1fe726..0000000 --- a/src/views/pages/auth/badrequest.html.php +++ /dev/null @@ -1,11 +0,0 @@ -status('400 Bad Request'); -$t->header('Authentication'); -$t->paragraph('The recieved POST request was malformed/invalid. '. - 'If you got here from a link, this is a bug; '. - 'Let the admin know.'. - 'If you got here from outside, then the API is being '. - 'used incorrectly.'); -$t->footer(); diff --git a/src/views/pages/auth/index.html.php b/src/views/pages/auth/index.html.php deleted file mode 100644 index ac80140..0000000 --- a/src/views/pages/auth/index.html.php +++ /dev/null @@ -1,12 +0,0 @@ -header('Authentication'); - -$t->openTag('div',array('class'=>'login')); -$t->text("Logged in as ".htmlentities($username).'.'); -$t->logout_button('Logout'); -$t->closeTag('div'); - -$t->footer(); \ No newline at end of file diff --git a/src/views/pages/auth/login.html.php b/src/views/pages/auth/login.html.php deleted file mode 100644 index a246a9e..0000000 --- a/src/views/pages/auth/login.html.php +++ /dev/null @@ -1,49 +0,0 @@ -header('Authentication'); - -$t->openTag('form',array('action'=>$t->url('auth'), 'method'=>"post")); -$t->openFieldset('Login'); -switch ($VARS['login_code']) { -case -1: break; -case 0: - $t->inputP('Successfully logged in as '. - htmlentities($username).'.'); - if (isset($VARS['url'])) { - $url = htmlentities($VARS['url']); - $t->inputP($t->link($url, - 'Return to the page you were on.', - true)); - } - $t->closeFieldset(); - $t->closeTag('form'); - return; - break; -case 1: - $t->inputP("Password does not match username.", - array('class'=>'error')); - break; -case 2: - $t->inputP("Username $username does not exist."); - $username = ''; - break; -} -$t->inputText( 'username', 'Username:', '', $username); -$t->inputPassword('password', 'Password:', '', $password); -$t->openTag('li'); -$t->tag('input', array('type'=>'submit', 'value'=>'Login')); -$t->closeTag('li'); -$t->closeFieldset(); -$t->tag('input', array('type'=>'hidden', - 'name'=>'action', - 'value'=>'login')); -if (isset($VARS['url'])) { - $url = htmlentities($VARS['url']); - $t->tag('input', array('type'=>'hidden', - 'name'=>'url', - 'value'=>$url)); -} -$t->closeTag('form'); diff --git a/src/views/pages/auth/logout.html.php b/src/views/pages/auth/logout.html.php deleted file mode 100644 index 2d00998..0000000 --- a/src/views/pages/auth/logout.html.php +++ /dev/null @@ -1,6 +0,0 @@ -header('Authentication'); -$t->paragraph('Logged out'); -$t->footer(); diff --git a/src/views/pages/groups/401.html.php b/src/views/pages/groups/401.html.php deleted file mode 100644 index 23e3778..0000000 --- a/src/views/pages/groups/401.html.php +++ /dev/null @@ -1,15 +0,0 @@ -status('401 Unauthorized'); -$t->header('Unauthorized'); -$t->tag('h1', array(), "401: Unauthorized"); -if ($VARS['uid']===false) { - // Not logged in - $t->paragraph('You need to be logged in to view group-data.'); -} else { - // Logged in, so the account must not activated - $t->paragraph('Your account needs to be activated by an administrator '. - 'to group-data.'); -} -$t->footer(); diff --git a/src/views/pages/http404.html.php b/src/views/pages/http404.html.php deleted file mode 100644 index 730b0ee..0000000 --- a/src/views/pages/http404.html.php +++ /dev/null @@ -1,16 +0,0 @@ -status('404 Not Found'); -$t->header('Page Not Found'); -$t->tag('h1',array(),"404: Not Found"); -$t->paragraph("Awe man, the page you requested wasn't found."); -$t->paragraph('This folder was found: '. - ''.$t->link($t->url($routed), $routed.'/', true).''); -$t->paragraph("But this file in it wasn't: ". - ''.$full.''); -$t->footer(); diff --git a/src/views/pages/index.html.php b/src/views/pages/index.html.php deleted file mode 100644 index 71b0091..0000000 --- a/src/views/pages/index.html.php +++ /dev/null @@ -1,8 +0,0 @@ -header('Main Page'); -$t->tag('h1', array(), "Message Manager"); -$t->paragraph($t->link($t->url('users/new'),'Register to be on the team', true), array('style'=>'font-size:5em')); -$t->link($t->url('users'), 'List of all users'); -$t->footer(); diff --git a/src/views/pages/messages/401.html.php b/src/views/pages/messages/401.html.php deleted file mode 100644 index 0b24f80..0000000 --- a/src/views/pages/messages/401.html.php +++ /dev/null @@ -1,15 +0,0 @@ -status('401 Unauthorized'); -$t->header('Unauthorized'); -$t->tag('h1', array(), "401: Unauthorized"); -if ($VARS['uid']===false) { - // Not logged in - $t->paragraph('You need to be logged in to view messages.'); -} else { - // Logged in, so the account must not activated - $t->paragraph('Your account needs to be activated by an administrator '. - 'to view messages.'); -} -$t->footer(); diff --git a/src/views/pages/messages/frame.html.php b/src/views/pages/messages/frame.html.php deleted file mode 100644 index e64bc2f..0000000 --- a/src/views/pages/messages/frame.html.php +++ /dev/null @@ -1,57 +0,0 @@ -%3$s>', - $t->url("messages/$id/"), - ($exists?'':' class="http404"'), - $id); -} -function parseMessageIDs($string) { - $base = $_SERVER['REQUEST_URL']; - $html = preg_replace_callback( - '/<([^>]*)>/', - 'messageLink', - $string); - return $html; -} - -$t->header('View Message'); -$t->openTag('table'); -$t->row(array('To:' , htmlentities( $parser->getHeader('to' )))); -$t->row(array('From:' , htmlentities( $parser->getHeader('from' )))); -$t->row(array('Subject:' , htmlentities( $parser->getHeader('subject' )))); -$t->row(array('In-Reply-to:', parseMessageIDs($parser->getHeader('in-reply-to')))); -$t->row(array('References:' , parseMessageIDs($parser->getHeader('references' )))); -$t->closeTag('table'); - -$t->openTag('div', array('class'=>'message-body')); -if ($parser->getMessageBodyPart('html')!==false) { - $t->tag('h2', array(), 'HTML'); - $t->tag('iframe', array('src'=>$t->url("messages/$msg_id/body.html")), ''); -} -if ($parser->getMessageBodyPart('text')!==false) { - $t->tag('h2', array(), 'Plain Text'); - $t->tag('iframe', array('src'=>$t->url("messages/$msg_id/body.txt")), ''); -} -$t->closeTag('div'); -$t->tag('h2', array(), 'Attachments'); -$t->openTag('table'); -$attachments = $parser->getAttachments(); -foreach ($attachments as $id => $attachment) { - $t->row(array( - htmlentities($attachment->getContentType()), - $t->link($t->url("$msg_id/attachment/$id"), - htmlentities($attachment->getFilename())), - )); -} -$t->closeTag('table'); -$t->footer(); diff --git a/src/views/pages/messages/index.html.php b/src/views/pages/messages/index.html.php deleted file mode 100644 index 111b6c6..0000000 --- a/src/views/pages/messages/index.html.php +++ /dev/null @@ -1,25 +0,0 @@ -header('Message Index'); -$t->tag('h1', array(), "Message Index"); - -$t->openTag('table'); -$t->row(array('From','Subject', 'Date')); -foreach ($messages as $date => $message_array) { - foreach ($message_array as $message) { - $url = $t->url('messages/'.$message['id'].'/'); - $subject = htmlentities($message['subject']); - $from = htmlentities($message['from']); - $date_str = str_replace(' ', ' ', date('Y-m-d H:i:s',$date)); - $t->row(array( - $t->link($url, $from , true), - $t->link($url, $subject , true), - $t->link($url, $date_str, true), - )); - } -} -$t->closeTag('table'); - -$t->footer(); diff --git a/src/views/pages/no-conf.html.php b/src/views/pages/no-conf.html.php deleted file mode 100644 index 1f4e3d3..0000000 --- a/src/views/pages/no-conf.html.php +++ /dev/null @@ -1,8 +0,0 @@ -header('Message Manager'); -$t->paragraph('Awe shiz, dude, conf.php doesn\'t exist, you '. - 'need to go through the '. - 'installer.'); -$t->footer(); diff --git a/src/views/pages/plugins/401.html.php b/src/views/pages/plugins/401.html.php deleted file mode 100644 index 5b1b222..0000000 --- a/src/views/pages/plugins/401.html.php +++ /dev/null @@ -1,9 +0,0 @@ -status('401 Unauthorized'); -$t->header('Unauthorized'); -$t->tag('h1',array(),"401: Unauthorized"); -$t->paragraph('You need to be logged in as an admin to edit global plugin '. - 'settings.'); -$t->footer(); diff --git a/src/views/pages/plugins/index.html.php b/src/views/pages/plugins/index.html.php deleted file mode 100644 index b182288..0000000 --- a/src/views/pages/plugins/index.html.php +++ /dev/null @@ -1,42 +0,0 @@ -header('Administrator Plugin Management'); -$t->openTag('form',array('method'=>'post','action'=>$t->url('plugins'))); - -foreach ($plugins as $plugin) { - $t->setRet(true); - $props = array('type'=>'checkbox', - 'name'=>'plugins[]', - 'id'=>'plugins_'.$plugin['name'], - 'value'=>$plugin['name']); - if ($plugin['active']==true) { - $props['checked'] = 'checked'; - } - $box = $t->tag('input', $props); - $t->setRet(false); - $t->openFieldset($plugin['name'].$box); - - $t->inputP($plugin['description']); - foreach ($plugin['config'] as $param => $type) { - $name = $plugin['key'].'['.$param.']'; - $value = $db->getPluginConf($plugin['name'], $param); - $hint = "Type: $type"; - switch ($type) { - case 'text': - case 'int': - $t->inputText( $name, $param, $hint, $value); break; - case 'password': - $t->inputPassword($name, $param, $hint, $value); break; - } - } - $t->closeFieldset(); -} - -$t->tag('input', array('type'=>'submit', - 'value'=>'Save/Update')); -$t->closeTag('form'); -$t->footer(); diff --git a/src/views/pages/users/401.html.php b/src/views/pages/users/401.html.php deleted file mode 100644 index 0a5a1ce..0000000 --- a/src/views/pages/users/401.html.php +++ /dev/null @@ -1,15 +0,0 @@ -status('401 Unauthorized'); -$t->header('Unauthorized'); -$t->tag('h1', array(), "401: Unauthorized"); -if ($VARS['uid']===false) { - // Not logged in - $t->paragraph('You need to be logged in to view user-data.'); -} else { - // Logged in, so the account must not activated - $t->paragraph('Your account needs to be activated by an administrator '. - 'to view user-data.'); -} -$t->footer(); diff --git a/src/views/pages/users/404.html.php b/src/views/pages/users/404.html.php deleted file mode 100644 index 00f9dca..0000000 --- a/src/views/pages/users/404.html.php +++ /dev/null @@ -1,10 +0,0 @@ -status('404 Not Found'); -$t->header('User Not Found'); -$t->tag('h1',array(),"404: Not Found"); -$t->paragraph('No user with the name '. - htmlentities($username).' exists.'); -$t->footer(); diff --git a/src/views/pages/users/500.html.php b/src/views/pages/users/500.html.php deleted file mode 100644 index 339fe63..0000000 --- a/src/views/pages/users/500.html.php +++ /dev/null @@ -1,15 +0,0 @@ -status('500 Internal Server Error'); -$t->header('Unknown error'); -$t->paragraph("An unknown error was encountered when creating ". - "the user. The username appears to be free, and ". - "the passwords match, so I'm assuming that the ". - "error is on our end. Sorry."); -$t->paragraph("Here's a dump of the SQL error stack, it may ". - "help us find the issue:"); -$t->tag('pre', array(), htmlentities($db->mysql_error())); -$t->footer(); diff --git a/src/views/pages/users/created.html.php b/src/views/pages/users/created.html.php deleted file mode 100644 index d3027cc..0000000 --- a/src/views/pages/users/created.html.php +++ /dev/null @@ -1,18 +0,0 @@ -status('201 Created'); -header('Location: '.$t->url("users/$username")); -$t->header('User created'); -/*$t->paragraph("You can go ahead and fill out more of your ". - "user information, (click the @username link at ". - "the top) but will need to wait for an ". - "administrator to approve your account before ". - "you can really use the site. Actually, ". - "filling your info out might help approval, so ". - "that the administrator can more easily see who ". - "you are."); -*/ -$t->tag('h2',array(), $t->link($t->url("users/$username"), 'Go on to step 2')); -$t->footer(); diff --git a/src/views/pages/users/index.csv.php b/src/views/pages/users/index.csv.php deleted file mode 100644 index 0a69cee..0000000 --- a/src/views/pages/users/index.csv.php +++ /dev/null @@ -1,27 +0,0 @@ -header('Users'); - -$t->paragraph($t->link($t->url('users.csv'), "Download this as a spreadsheet.", true)); - -$t->openTag('form', array('action'=>$t->url('users/index'), - 'method'=>'post')); - -if (Login::isLoggedIn()) { - $t->tag('input', array('type'=>'submit', - 'value'=>'Save/Update')); -} - -$t->openTag('table', array('class'=>'sortable', 'id'=>'bar')); - -function table_head($attribs, $t) { - $t->openTag('tr'); - foreach ($attribs as $attrib) { - switch ($attrib['type']) { - case 'bool': $class = 'small'; break; - default: $class = ''; break; - } - $t->tag('th', array('class'=>$class), $attrib['name']); - } - if (Login::isLoggedIn()) { - $t->tag('th', array(), '-'); - } - $t->closeTag('tr'); -} - -$t->openTag('thead'); -table_head($attribs, $t); -$t->closeTag('thead'); - -$t->openTag('tfoot'); -table_head($attribs, $t); -$t->closeTag('tfoot'); - -$t->openTag('tbody'); - -foreach ($users as $user) { - $t->openTag('tr'); - - foreach ($attribs as $attrib) { - $t->openTag('td'); - - $props = $user[$attrib['key']]; - - $bool = $attrib['type']=='bool'; - if ($bool) { - $value = $props['value']=='true'; - } else { - $value = $props['value']; - } - $editable = $props['editable']; - $post_key = $props['post_key']; - - $arr = array('name'=>$post_key); - if (!$editable) { - $arr['readonly'] = 'readonly'; - if ($bool) $arr['disabled'] = $disabled; - } - if ($bool) { - $t->tag('input', array('type'=>'hidden', 'name'=>$post_key, 'value'=>'false')); - if ($value==true) { - $arr['checked'] = 'checked'; - } - $arr['value'] = 'true'; - $arr['type'] = 'checkbox'; - } else { - $t->tag('span', array('class'=>'cell_width'), $value); - $arr['value'] = $value; - $arr['type'] = 'text'; - } - - $t->tag('input', array('name'=>'_old['.$arr['name'].']', - 'value'=>$arr['value'], - 'type'=>'hidden')); - $t->tag('input', $arr); - $t->closeTag('td'); - } - - if (Login::isLoggedIn()) { - $t->openTag('td'); - $t->link($t->url('users/'.$user['auth_name']['value']), 'More'); - $t->closeTag('td'); - } - $t->closeTag('tr'); -} - -$t->closeTag('tbody'); -$t->closeTag('table'); - -if (Login::isLoggedIn()) { - $t->tag('input', array('type'=>'submit', - 'value'=>'Save/Update')); -} - -$t->footer(); diff --git a/src/views/pages/users/individual.html.php b/src/views/pages/users/individual.html.php deleted file mode 100644 index 39360b7..0000000 --- a/src/views/pages/users/individual.html.php +++ /dev/null @@ -1,147 +0,0 @@ -getConf($key); - $t->inputText("user_$key", $label, $hint, $current_setting, - !$user->canEdit()); -} -function inputTextarea($user, $key, $label, $hint='') { - global $VARS; $t = $VARS['template']; - $current_setting = $user->getConf($key); - $t->inputTextarea("user_$key", $label, $hint, $current_setting, - !$user->canEdit()); -} - -function inputBool($user, $key, $label, $hint='') { - global $VARS; $t = $VARS['template']; - $current_setting = $user->getConf($key)=='true'; - $t->inputBool("user_$key", $label, $hint, $current_setting, - !$user->canEdit()); -} - -function inputArray($user, $key, $arr) { - global $VARS; $t = $VARS['template']; - $defaults = $user->getConfArray($key); - - foreach ($arr as $value => $label) { - $t->inputBoolArray($key, $value, $label, - in_array($value, $defaults), !$user->canEdit()); - } -} - -function inputField($user, $arr) { - $fieldname = $arr[0]; - $fieldlabel = $arr[1]; - $fieldtype = $arr[2]; - - switch ($fieldtype) { - case 'text': - inputText($user, $fieldname, $fieldlabel, ''); - break; - case 'textarea': - inputTextarea($user, $fieldname, $fieldlabel, ''); - break; - case 'paragraph': - global $VARS; $t = $VARS['template']; - $t->inputP($fieldlabel); - break; - case 'checkbox': - inputBool($user, $fieldname, $fieldlabel, ''); - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// - -if (count($users)>1) { - $t->header("Users: $username"); -} else { - $t->header("User: $username"); -} - -foreach($users as $user) { -$username = $user->getName(); - -$t->tag('h1', array(), ($user->canEdit()?'Edit':'View')." User $username (UID: ".$user->getUID().")"); - -if ($user->canEdit()) { - $t->openTag('form', array('method'=>'post', - 'action'=>$t->url("users/$username"))); -} else { - $t->openTag('form'); -} - -$t->openFieldset("Login / Authentication"); -// Username //////////////////////////////////////////////////////////////////// -if (isset($VARS['changed name']) && !$VARS['changed name']) { - $t->inputP("Error setting username to ". - "$new_name. This is probably because". - " a user with that name already exists.", - true); -} -$t->inputText('auth_name','Username', - "This is the name you use to log in, but it is also a ". - "short name that is used in various places, think of it ". - "as a sort of Twitter name.", - $user->getName(), !$user->canEdit()); -// Password //////////////////////////////////////////////////////////////////// -if (@$VARS['pw_updated']===true) { - $t->inputP('Password successfully updated.'); -} -if (@$VARS['pw mixmatch']===true) { - $t->inputP("Passwords don't match.", true); -} -if ($user->canEdit()) $t->inputNewPassword('auth_password','Reset Password'); -//////////////////////////////////////////////////////////////////////////////// -$t->closeFieldset(); - -$t->openFieldset("Contact"); -// TODO: I should make this a setting for admins to set. -$hints = array('email'=> - "Right now you can only have one email address, ". - "but I'm working on making it so you can have ". - "multiple.", - 'phone'=> - "A home phone number isn't much use here because it is ". - "used to text-message you (if you enable it), and ". - "contact you at competition." - ); -$use_arr = array(); -foreach ($CONTACT_METHODS as $method) { - inputText($user, - $method->addr_slug, - ucwords($method->addr_text), - $hints[$method->addr_slug]); - $use_arr[$method->verb_slug] = ucwords($method->verb_text); -} - -$t->inputP("When I recieve a message, notify me using the following methods:"); -inputArray($user, 'use', $use_arr); -$t->closeFieldSet(); - -foreach ($VARS['config_options'] as $groupname=>$options) { - $t->openFieldset($groupname); - foreach ($options as $option) { - inputField($user, $option); - } - $t->closeFieldset(); -} - -$t->openFieldSet('Groups'); -$group_arr = array(); -foreach ($VARS['groups'] as $group_name) { - $group_arr[$group_name] = ucwords($group_name); -} -inputArray($user, 'groups', $group_arr); -$t->closeFieldset(); - -if ($user->canEdit()) { - $t->tag('input', array('type'=>'submit', 'value'=>'Save')); -} -$t->closeTag('form'); -} -$t->footer(); diff --git a/src/views/pages/users/new-locked.html.php b/src/views/pages/users/new-locked.html.php deleted file mode 100644 index dc7ad0d..0000000 --- a/src/views/pages/users/new-locked.html.php +++ /dev/null @@ -1,9 +0,0 @@ -status('403 Forbidden'); -$t->header('Create new user'); - -$t->paragraph("Sorry, new user registration is disabled."); - -$t->footer(); diff --git a/src/views/pages/users/new-logged-in.html.php b/src/views/pages/users/new-logged-in.html.php deleted file mode 100644 index 51823fe..0000000 --- a/src/views/pages/users/new-logged-in.html.php +++ /dev/null @@ -1,8 +0,0 @@ -header('Create new user'); - -$t->paragraph("Dude, you're logged in, what are you doing creating an account?"); - -$t->footer(); diff --git a/src/views/pages/users/new.html.php b/src/views/pages/users/new.html.php deleted file mode 100644 index 9df376f..0000000 --- a/src/views/pages/users/new.html.php +++ /dev/null @@ -1,57 +0,0 @@ -header('Create new user'); - -$t->openTag('form', array('method'=>'post', - 'action'=>$t->url('users'))); - -$t->openFieldset("New User: Step 1"); - -if ($VARS['userlist']) { - $t->inputP("If you may have already created a username, please, ". - "please check the ". - $t->link($t->url('users/'), 'user-list', true). - " to find your old username, instead of creating a new ". - "user. If you don't like the name, you can log in and ". - "change it."); -} - -if (in_array('illegal name', $VARS['errors'])) { - $t->inputP("That is a forbidden username.", true); -} -if (in_array('user exists', $VARS['errors'])) { - $t->inputP("A user with that name already exists."); -} -$t->inputText('auth_name','Username', - "This is the name you use to log in, but it is also a ". - "short name that is used in various places, think of it ". - "as a sort of Twitter name.",$VARS['username']); - -@$password = $VARS['password1']; -if (in_array('pw mixmatch', $VARS['errors'])) { - $t->inputP("The passwords didn't match.", true); - $password = ''; -} -if (in_array('no pw', $VARS['errors'])) { - $t->inputP("You must set a password.", true); - $password = ''; -} -$t->inputNewPassword('auth_password','Password', $password); - -if (in_array('no email', $VARS['errors'])) { - $t->inputP("You must provide an email address.", true); -} -$t->inputText('user_email', 'Email Address', - 'This is so that we can contact you. (duh).', $VARS['email']); -$t->closeFieldset(); - -foreach ($VARS['antispam_html'] as $html) { - echo $html; -} - -$t->tag('input', array('type'=>'submit', 'value'=>'Go on to Step 2')); - -$t->closeTag('form'); - -$t->footer(); -- cgit v1.2.3