[opw-web] Add organizations



commit d8cb220a475f0b16792c5d67a4158edbb402309d
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sat Mar 8 23:01:40 2014 -0500

    Add organizations
    
    * Add organizations to the database scheme
    * Add an administrator interface to edit them
    * Add a screen where a a user applies to be a mentor /for a particular organization/
    * Associate projects with an organization and hook that up for create/edit/view/list

 classes/class_cache.php                            |   18 ++
 classes/class_module.php                           |    1 +
 classes/class_user.php                             |   10 +-
 lang/en-gb.php                                     |   13 ++
 modules/mod_approve_mentors.php                    |    7 +-
 modules/mod_manage_organizations.php               |  183 ++++++++++++++++++++
 modules/mod_program_home.php                       |    2 +-
 modules/mod_view_projects.php                      |  168 ++++++++++++++----
 schema.sql                                         |   16 ++-
 skins/easterngreen/html/tpl_apply_mentor.html      |    9 +
 skins/easterngreen/html/tpl_approve_mentors.html   |    3 +-
 .../html/tpl_approve_mentors_item.html             |    6 +-
 skins/easterngreen/html/tpl_header.html            |    6 +
 .../html/tpl_manage_organizations.html             |   32 ++++
 .../html/tpl_manage_organizations_editor.html      |   35 ++++
 .../html/tpl_manage_organizations_item.html        |   11 ++
 skins/easterngreen/html/tpl_view_project.html      |    5 +
 skins/easterngreen/html/tpl_view_projects.html     |    6 +-
 .../html/tpl_view_projects_editor.html             |    7 +
 .../easterngreen/html/tpl_view_projects_item.html  |    6 +-
 20 files changed, 492 insertions(+), 52 deletions(-)
---
diff --git a/classes/class_cache.php b/classes/class_cache.php
index f4da515..bab61e6 100644
--- a/classes/class_cache.php
+++ b/classes/class_cache.php
@@ -120,6 +120,24 @@ class cache
         return $program_data ? $program_data : null;
     }
 
+    function get_organization_data($id)
+    {
+        global $db;
+
+        $organization_data = $this->get("organization_{$id}", 'organizations');
+
+        if (!$organization_data)
+        {
+            $sql = "SELECT * FROM {$db->prefix}organizations " .
+                       "WHERE id = ?";
+            $organization_data = $db->query($sql, $id, true);
+
+            $this->put("organization_{$id}", $organization_data, 'organizations');
+        }
+
+        return $organization_data ? $organization_data : null;
+    }
+
     function get_project_data($id)
     {
         global $db;
diff --git a/classes/class_module.php b/classes/class_module.php
index 21d0546..608e6dd 100644
--- a/classes/class_module.php
+++ b/classes/class_module.php
@@ -28,6 +28,7 @@ class module
             array('name' => 'edit_templates',    'access' => 'a'),
             array('name' => 'user_ban',          'access' => 'a'),
             array('name' => 'manage_programs',   'access' => 'a'),
+            array('name' => 'manage_organizations', 'access' => 'a'),
             array('name' => 'notifications',     'access' => 'a'),
         );
     }
diff --git a/classes/class_user.php b/classes/class_user.php
index 4d08c7b..32cff00 100644
--- a/classes/class_user.php
+++ b/classes/class_user.php
@@ -427,8 +427,8 @@ class user
         }
     }
 
-    // Check the role of the current user
-    function get_role($program_id) {
+    // Get the role and organization of the current user
+    function get_role($program_id, &$role, &$organization) {
         global $cache, $db;
 
         $key = "role_{$this->username}_{$program_id}";
@@ -436,7 +436,7 @@ class user
 
         if (!$role_data)
         {
-            $sql = "SELECT role FROM {$db->prefix}roles " .
+            $sql = "SELECT role, organization_id FROM {$db->prefix}roles " .
                        "WHERE username = :username " .
                        "AND program_id = :id";
 
@@ -451,13 +451,13 @@ class user
         if ($role_data !== false)
         {
             $role = $role_data['role'];
+            $organization = $role_data['organization_id'];
         }
         else
         {
             $role = 'g';
+            $organization = null;
         }
-
-        return $role;
     }
 
     // Restricts a screen to a specific condition only
diff --git a/lang/en-gb.php b/lang/en-gb.php
index ea5ce70..79730da 100644
--- a/lang/en-gb.php
+++ b/lang/en-gb.php
@@ -23,6 +23,7 @@ $lang_data = array(
     'log_out'               => 'Log out',
     'administration'        => 'Administration',
     'manage_programs'       => 'Manage programs',
+    'manage_organizations'  => 'Manage organizations',
     'manage_bans'           => 'Manage user bans',
     'navigation'            => 'Navigation',
     'view_active_progms'    => 'View active programs',
@@ -41,8 +42,10 @@ $lang_data = array(
     'no'                    => 'No',
     'program_title'         => 'Program title',
     'project_title'         => 'Project title',
+    'organization'          => 'Organization',
     'description'           => 'Description',
     'no_programs'           => 'There are no programs to display',
+    'no_organizations'      => 'There are no organizations to display',
     'error_occurred'        => 'An error occurred while processing your request',
     'confirm_deletion'      => 'Confirm deletion',
     'edit'                  => 'Edit',
@@ -103,6 +106,12 @@ $lang_data = array(
     'confirm_program_del'   => 'If you delete this program, all projects associated with it will also get 
deleted. ' .
                                'Do you want to continue?',
 
+    /* Module: manage_organizations */
+    'add_organization'      => 'Add new organization',
+    'edit_organization'     => 'Edit organization',
+    'confirm_organization_del' => 'If you delete this organization, all projects associated with it will 
also get deleted. ' .
+                                  'Do you want to continue?',
+
     /* Module: programs_home */
     'login_to_participate'  => 'Log in or sign-up to participate',
     'program_started'       => 'This program isn\'t accepting new participants',
@@ -146,6 +155,10 @@ $lang_data = array(
     'rejected_projects'     => 'Rejected projects',
     'student'               => 'Student',
 
+    'select_organization'   => '- select organization -',
+    'other'                 => 'Other',
+    'apply'                 => 'Apply',
+
     'mentor'                => 'Mentor',
     'no_projects'           => 'No projects were found in this category',
     'new_mentor'            => 'New mentor',
diff --git a/modules/mod_approve_mentors.php b/modules/mod_approve_mentors.php
index b8b0eb3..8769634 100644
--- a/modules/mod_approve_mentors.php
+++ b/modules/mod_approve_mentors.php
@@ -42,7 +42,11 @@ if (!empty($action) && !empty($username))
 }
 
 // Get the proposed mentors list
-$sql = "SELECT * FROM {$db->prefix}roles " .
+$sql = "SELECT ".
+            "r.username as username, " .
+            "o.title as organization_title " .
+       "FROM {$db->prefix}roles r " .
+            "LEFT JOIN {$db->prefix}organizations o on o.id = r.organization_id " .
        "WHERE role = 'i'";
 $list_data = $db->query($sql);
 
@@ -56,6 +60,7 @@ foreach ($list_data as $row)
     // Assign data for each mentor
     $skin->assign(array(
         'mentor_name'           => $user->profile(htmlspecialchars($row['username']), true),
+        'organization'          => htmlspecialchars($row['organization_title']),
         'approve_url'           => "?q=approve_mentors&amp;a=approve&amp;u={$mentor_url}",
         'reject_url'            => "?q=approve_mentors&amp;a=reject&amp;u={$mentor_url}",
     ));
diff --git a/modules/mod_manage_organizations.php b/modules/mod_manage_organizations.php
new file mode 100644
index 0000000..90e7d46
--- /dev/null
+++ b/modules/mod_manage_organizations.php
@@ -0,0 +1,183 @@
+<?php
+/**
+* Pandora v1
+* @license GPLv3 - http://www.opensource.org/licenses/GPL-3.0
+* @copyright (c) 2012 KDE. All rights reserved.
+*/
+
+if (!defined('IN_PANDORA')) exit;
+
+// Collect some data
+$action = $core->variable('a', 'list');
+$id = $core->variable('o', 0);
+$program_id = 0 + $core->variable('prg', 0);
+$title = $core->variable('title', '', false, true);
+$page = $core->variable('pg', 1);
+$limit_start = ($page - 1) * $config->per_page;
+
+$organization_save = isset($_POST['organization_save']);
+$confirm = isset($_POST['yes']);
+
+$program_data = $cache->get_program_data($program_id);
+if ($program_data == null)
+    $core->redirect("?q=view_programs");
+
+// Serve the page based on the action
+if ($action == 'list')
+{
+    $organizations_list = '';
+
+    // Get all organizations
+    $sql = "SELECT * FROM {$db->prefix}organizations " .
+               " WHERE program_id = :program_id ".
+           "LIMIT :start, :count";
+    $organization_data = $db->query($sql, array('program_id' => $program_id,
+                                                'i:start' => $limit_start,
+                                                'i:count' => $config->per_page));
+
+    // Get organization count
+    $sql = "SELECT COUNT(*) AS count FROM {$db->prefix}organizations";
+    $organization_count = $db->query($sql, null, true);
+
+    // Build the list
+    foreach ($organization_data as $row)
+    {
+        // Assign data for this organization
+        $skin->assign(array(
+            'organization_id'          => $row['id'],
+            'organization_title'       => htmlspecialchars($row['title'])
+        ));
+
+        $organizations_list .= $skin->output('tpl_manage_organizations_item');
+    }
+
+    // Get the pagination
+    $pagination = $skin->pagination($organization_count['count'], $page);
+
+    // Assign final skin data
+    $skin->assign(array(
+        'program_id'         => $program_id,
+        'organizations_list' => $organizations_list,
+        'list_pages'         => $pagination,
+        'notice_visibility'  => $skin->visibility(count($organization_data) == 0),
+        'list_visibility'    => $skin->visibility(count($organization_data) > 0),
+        'pages_visibility'   => $skin->visibility($organization_count['count'] > $config->per_page),
+    ));
+
+    // Output the module
+    $module_title = $lang->get('manage_organizations');
+    $module_data = $skin->output('tpl_manage_organizations');
+}
+else if ($action == 'editor')
+{
+    $page_title = $id == 0 ? $lang->get('add_organization') : $lang->get('edit_organization');
+
+    if ($organization_save)
+    {
+        if (empty($title))
+        {
+            $error_message = $lang->get('err_mandatory_fields');
+        }
+        else
+        {
+            $params = array('id' => $id,
+                            'title' => $title,
+                            'program_id' => $program_id);
+
+            if ($id > 0)
+            {
+                // Update organization data
+                $sql = "UPDATE {$db->prefix}organizations " .
+                       "SET title = :title " .
+                       "WHERE id = :id";
+                $db->query($sql, $params);
+            }
+            else
+            {
+                // Insert organization data
+                $sql = "INSERT INTO {$db->prefix}organizations " .
+                       "(title, program_id) " .
+                       "VALUES (:title, :program_id)";
+                $db->query($sql, $params);
+
+                // Get the new organization ID
+                $params['id'] = $db->get_id();
+            }
+
+            // Purge the organizations cache
+            $cache->purge('organizations');
+
+            // Redirect to list page
+            $core->redirect("?q=manage_organizations&prg={$program_id}");
+        }
+    }
+
+    // Load data when in edit mode
+    if ($id > 0)
+    {
+        $sql = "SELECT * FROM {$db->prefix}organizations " .
+               "WHERE id = ?";
+        $row = $db->query($sql, array($id), true);
+
+        // Set loaded data
+        $title = $row['title'];
+    }
+
+    // Assign skin data
+    $skin->assign(array(
+        'editor_title'      => $page_title,
+        'title'             => htmlspecialchars($title),
+        'error_message'     => isset($error_message) ? $error_message : '',
+        'error_visibility'  => $skin->visibility(isset($error_message)),
+        'delete_visibility' => $skin->visibility($id > 0),
+        'cancel_url'        => "?q=manage_organizations&amp;prg={$program_id}",
+        'delete_url'        => "?q=manage_organizations&amp;a=delete&amp;o={$id}",
+    ));
+
+    // Output the module
+    $module_title = $page_title;
+    $module_data = $skin->output('tpl_manage_organizations_editor');
+}
+else if ($action == 'delete')
+{
+    // Deletion was confirmed
+    if ($confirm)
+    {
+        $params = array('id' => $id);
+
+//        XXX FIXME
+//        $sql = "DELETE FROM {$db->prefix}projects " .
+//               "WHERE organization_id = :id";
+//       $db->query($sql, $params);
+
+//        XXX FIXME
+//       $sql = "DELETE FROM {$db->prefix}coordinators " .
+//               "WHERE organization_id = :id";
+//        $db->query($sql, $params);
+
+
+        $sql = "DELETE FROM {$db->prefix}organizations " .
+               "WHERE id = :id";
+        $db->query($sql, $params);
+
+        // Purge the cache data
+        // XXX FIXME
+        $cache->purge(array('organizations'));
+
+        // Redirect to list page
+        $core->redirect("?q=manage_organizations&prg={$program_id}");
+    }
+
+    // Assign confirm box data
+    $skin->assign(array(
+        'message_title'     => $lang->get('confirm_deletion'),
+        'message_body'      => $lang->get('confirm_organization_del'),
+        'cancel_url'        => "?q=manage_organizations&amp;a=editor&amp;o={$id}",
+    ));
+
+    // Output the module
+    $module_title = $lang->get('confirm_deletion');
+    $module_data = $skin->output('tpl_confirm_box');
+}
+
+?>
diff --git a/modules/mod_program_home.php b/modules/mod_program_home.php
index 5204ad5..fc146e1 100644
--- a/modules/mod_program_home.php
+++ b/modules/mod_program_home.php
@@ -15,7 +15,7 @@ $program_data = $cache->get_program_data($id);
 // Was the program found?
 if ($program_data != null)
 {
-    $role = $user->get_role($id);
+    $user->get_role($id, $role, $organization);
 
     // Set object availability based on deadlines
     $show_student = true;
diff --git a/modules/mod_view_projects.php b/modules/mod_view_projects.php
index 2f69abe..f9cd22f 100644
--- a/modules/mod_view_projects.php
+++ b/modules/mod_view_projects.php
@@ -10,8 +10,9 @@ if (!defined('IN_PANDORA')) exit;
 // Collect some data
 $action = $core->variable('a', 'view');
 $category = $core->variable('c', '');
-$program_id = $core->variable('prg', 0);
-$project_id = $core->variable('p', 0);
+$program_id = 0 + $core->variable('prg', 0);
+$project_id = 0 + $core->variable('p', 0);
+$organization_id = 0 + $core->variable('o', 0);
 $title = $core->variable('title', '', false, true);
 $description = $core->variable('description', '', false, true);
 $new_student = $core->variable('new_student', '', false, true);
@@ -49,10 +50,27 @@ $row = $db->query($sql,
                   array('program_id' => $program_id,
                         'project_id' => $project_id),
                   true);
+
 $user->restrict($row['count'] > 0);
 
+// Validate organization_id
+if ($organization_id > 0) {
+    $sql = "SELECT COUNT(*) AS count " .
+           "FROM {$db->prefix}organizations prj " .
+           "LEFT JOIN {$db->prefix}programs prg " .
+           "ON prg.id = prj.program_id " .
+           "WHERE prj.id = :organization_id " .
+        "AND prg.id = :program_id ";
+
+    $row = $db->query($sql,
+                      array('program_id' => $program_id,
+                            'organization_id' => $organization_id),
+                      true);
+    $user->restrict($row['count'] > 0);
+}
+
 // Get the role of the user
-$role = $user->get_role($program_id);
+$user->get_role($program_id, $role, $organization);
 
 // Check if the user is the owner of the project
 if ($project_id > 0)
@@ -78,6 +96,38 @@ else
     $is_owner = false;
 }
 
+function build_organization_select($program_id, $current, $include_other)
+{
+    global $db, $lang;
+
+    $sql = "SELECT * FROM {$db->prefix}organizations " .
+               "WHERE program_id = ?";
+    $list_data = $db->query($sql, $program_id);
+
+    $option_name = $lang->get('select_organization');
+    $organization_select = "<select name='o'>";
+
+    $selected = $current == 0 ? " selected" : "";
+    $organization_select .= "<option value='0'$selected>{$option_name}</option>";
+
+    foreach ($list_data as $row)
+      {
+        $organization_title = htmlspecialchars($row['title']);
+        $id = $row['id'];
+        $selected = $current == $id ? " selected" : "";
+        $organization_select .= "<option value='$id'$selected>{$organization_title}</option>";
+      }
+
+    $option_name = $lang->get('other');
+    if ($include_other) {
+        $selected = $current == -1 ? " selected" : "";
+        $organization_select .= "<option value='-1'$selected>{$option_name}</option>";
+    }
+    $organization_select .= "</select>";
+
+    return $organization_select;
+}
+
 // Serve the page based on the action
 if ($action == 'editor')
 {
@@ -129,6 +179,7 @@ if ($action == 'editor')
         {
             $title = $project_data['title'];
             $description = $project_data['description'];
+            $organization_id = $project_data['organization_id'];
             $is_passed = $project_data['passed'];
             $is_complete = $project_data['is_complete'];
         }
@@ -141,7 +192,7 @@ if ($action == 'editor')
     if ($project_save)
     {
         // All fields are mandatory
-        if (empty($title) || empty($description))
+        if (empty($title) || empty($description) || $organization_id <= 0)
         {
             $error_message = $lang->get('mandatory_all');
         }
@@ -151,6 +202,7 @@ if ($action == 'editor')
                             'project_id' => $project_id,
                             'title' => $title,
                             'description' => $description,
+                            'organization_id' => $organization_id > 0 ? $organization_id : null,
                             'is_complete' => $is_complete,
                             'is_passed' => $is_passed,
                             'new_student' => $new_student,
@@ -163,6 +215,7 @@ if ($action == 'editor')
                 $sql = "UPDATE {$db->prefix}projects " .
                        "SET title = :title, " .
                        "    description = :description, " .
+                       "    organization_id = :organization_id, " .
                        "    is_complete = " . ($can_decide ? ":is_complete " : "is_complete ") .
                        "WHERE id = :project_id";
                 $db->query($sql, $params);
@@ -290,8 +343,8 @@ if ($action == 'editor')
 
                 // Insert new project
                 $sql = "INSERT INTO {$db->prefix}projects " .
-                       "(title, description, program_id, is_accepted, is_complete) " .
-                       "VALUES (:title, :description, :program_id, :is_accepted, 0)";
+                       "(title, description, program_id, organization_id, is_accepted, is_complete) " .
+                       "VALUES (:title, :description, :program_id, :organization_id, :is_accepted, 0)";
                 $db->query($sql, $params);
 
                 // Get the new project ID
@@ -308,6 +361,7 @@ if ($action == 'editor')
                 $success_message = $lang->get('proposal_submitted');
                 $title = '';
                 $description = '';
+                $organization_id = 0;
                 $show_subscribe = true;
             }
 
@@ -327,6 +381,7 @@ if ($action == 'editor')
         'project_title'         => htmlspecialchars($title),
         'project_description'   => nl2br(htmlspecialchars($description)),
         'new_mentor'            => htmlspecialchars($new_mentor),
+        'organization_select'   => build_organization_select($program_id, $organization_id, false),
         'success_message'       => isset($success_message) ? $success_message : '',
         'error_message'         => isset($error_message) ? $error_message : '',
         'success_visibility'    => $skin->visibility(empty($success_message), true),
@@ -389,6 +444,11 @@ else if ($action == 'view')
     $program_data     = $cache->get_program_data($program_id);
     $project_data     = $cache->get_project_data($project_id);
 
+    if ($project_data['organization_id'] != null)
+        $organization_data  = $cache->get_organization_data($project_data['organization_id']);
+    else
+        $organization_data = null;
+
     $participant_data = $cache->get("participant_{$project_id}", 'projects');
 
     if (!$participant_data)
@@ -508,6 +568,7 @@ else if ($action == 'view')
         'program_id'                => $program_id,
         'project_id'                => $project_id,
         'project_title'             => htmlspecialchars($project_data['title']),
+        'project_organization'      => htmlspecialchars($organization_data ? $organization_data['title'] : 
''),
         'project_description'       => nl2br(htmlspecialchars($project_data['description'])),
         'project_student'           => $user->profile(htmlspecialchars($student), true),
         'project_mentor'            => $user->profile(htmlspecialchars($mentor), true),
@@ -548,8 +609,9 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
                     'i:count' => $config->per_page);
 
     // Build the queries
-    $data_sql = "SELECT * FROM {$db->prefix}projects ";
-    $count_sql = "SELECT COUNT(*) AS count FROM {$db->prefix}projects ";
+    $data_sql = "SELECT p.*, o.title as organization_title FROM {$db->prefix}projects p " .
+                "LEFT JOIN {$db->prefix}organizations o on p.organization_id = o.id ";
+    $count_sql = "SELECT COUNT(*) AS count FROM {$db->prefix}projects p ";
     $limit = "LIMIT :start, :count";
 
     // Set action specific page title and query
@@ -560,7 +622,7 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
         $key = "projects_user_{$program_id}_{$user->username}";
 
         $title = $lang->get('your_projects');
-        $filter = "WHERE id IN (SELECT project_id " .
+        $filter = "WHERE p.id IN (SELECT project_id " .
                   "FROM {$db->prefix}participants " .
                   "WHERE username = :username " .
                   "AND program_id = :program_id) ";
@@ -579,7 +641,7 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
 
         $title = $lang->get('proposed_projects');
         $filter = "WHERE {$is_accepted} " .
-                  "AND program_id = :program_id ";
+                  "AND p.program_id = :program_id ";
     }
     else if ($action == 'accepted')
     {
@@ -597,7 +659,7 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
 
         $title = $lang->get('accepted_projects');
         $filter = "WHERE {$is_accepted} " .
-                  "AND program_id = :program_id ";
+                  "AND p.program_id = :program_id ";
     }
     else if ($action == 'rejected')
     {
@@ -605,7 +667,7 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
 
         $title = $lang->get('rejected_projects');
         $filter = "WHERE is_accepted = 0 " .
-                  "AND program_id = :program_id ";
+                  "AND p.program_id = :program_id ";
     }
 
     // Apply filters
@@ -666,6 +728,7 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
             $skin->assign(array(
                 'project_title'         => $project_title,
                 'project_description'   => nl2br($project_desc),
+                'project_organization'  => htmlspecialchars($row['organization_title']),
                 'project_url'           => "?q=view_projects&amp;prg={$program_id}&amp;p={$row['id']}",
                 'approve_url'           => "?q=view_projects&amp;a=approve&amp;prg={$program_id}" .
                                            "&amp;p={$row['id']}&amp;r={$return_url}",
@@ -732,39 +795,66 @@ else if ($action == 'apply')
     // Validate category
     $user->restrict(in_array($category, array('student', 'mentor')));
 
-    $params = array('program_id' => $program_id,
-                    'username' => $username);
+    // When applying as a mentor, an organization must be selected - otherwise
+    // we can continue
+    if ($category == 'student' || ($organization_id > 0 || $organization_id == -1)) {
+        $params = array('program_id' => $program_id,
+                        'organization_id' => $organization_id,
+                        'username' => $user->username);
 
-    // Get the program data
-    $program_data = $cache->get_program_data($program_id);
+        // Get the program data
+        $program_data = $cache->get_program_data($program_id);
 
-    // Set the new role based on action
-    $new_role = $category == 'student' ? 's' : 'i';
+        // Set the new role based on action
+        $new_role = $category == 'student' ? 's' : 'i';
 
-    // Allow setting new role based on deadlines
-    $user->restrict(($new_role == 's' && $core->timestamp < $program_data['dl_student']) ||
-                    ($new_role == 'i' && $core->timestamp < $program_data['dl_mentor']));
+        // Allow setting new role based on deadlines
+        $user->restrict(($new_role == 's' && $core->timestamp < $program_data['dl_student']) ||
+                        ($new_role == 'i' && $core->timestamp < $program_data['dl_mentor']));
 
-    $params['role'] = $new_role;
+        $params['role'] = $new_role;
 
-    // Insert the new role
-    $sql = "INSERT INTO {$db->prefix}roles " .
-           "(username, program_id, role) " .
-           "VALUES (:username, :program_id, :role)";
-    $db->query($sql, $params);
+        // Insert the new role
+        if ($organization_id > 0) {
+            $sql = "INSERT INTO {$db->prefix}roles " .
+                       "(username, program_id, organization_id, role) " .
+                       "VALUES (:username, :program_id, :organization_id, :role)";
+            $db->query($sql, $params);
+        } else {
+            $sql = "INSERT INTO {$db->prefix}roles " .
+                       "(username, program_id, role) " .
+                       "VALUES (:username, :program_id, :role)";
+            $db->query($sql, $params);
+        }
 
-    // Notify admin with email for new mentor requests
-    if ($new_role == 'i')
-    {
-        $email->assign('mentor_name', $user->username);
-        $email->send($config->webmaster, $lang->get('mentor_subject'), 'mentor');
+        // Notify admin with email for new mentor requests
+        if ($new_role == 'i')
+        {
+            $email->assign('mentor_name', $user->username);
+            $email->send($config->webmaster, $lang->get('mentor_subject'), 'mentor');
+        }
+
+        // Purge the roles cache
+        $cache->purge('roles');
+
+        // Redirect to program home
+        $core->redirect("?q=program_home&prg={$program_id}");
     }
 
-    // Purge the roles cache
-    $cache->purge('roles');
+    $organization_select = build_organization_select($program_id, 0, true);
 
-    // Redirect to program home
-    $core->redirect("?q=program_home&prg={$program_id}");
+    // Assign final skin data
+    $skin->assign(array(
+        'program_id'            => $program_id,
+        'view_title'            => $title,
+        'organization_select'   => $organization_select,
+        'submit_url'            => "?q=view_projects&amp;a=apply&ampl;prg={$program_id}",
+        'cancel_url'            => "?q=project_home&amp;prg={$program_id}"
+    ));
+
+    // Output the module
+    $module_title = $lang->get('apply_mentor');
+    $module_data = $skin->output('tpl_apply_mentor');
 }
 else if ($action == 'resign')
 {
diff --git a/schema.sql b/schema.sql
index 0bcc94f..4fccd07 100644
--- a/schema.sql
+++ b/schema.sql
@@ -18,15 +18,25 @@ CREATE TABLE `opw_programs` (
   PRIMARY KEY (`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
+CREATE TABLE `opw_organizations` (
+  `id` mediumint(6) unsigned NOT NULL AUTO_INCREMENT,
+  `program_id` mediumint(6) unsigned NOT NULL,
+  `title` varchar(255) NOT NULL DEFAULT '',
+  PRIMARY KEY (`id`),
+  FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
 CREATE TABLE `opw_projects` (
   `id` mediumint(10) unsigned NOT NULL AUTO_INCREMENT,
   `title` varchar(255) NOT NULL DEFAULT '',
   `description` mediumtext,
   `program_id` mediumint(6) unsigned NOT NULL,
+  `organization_id` mediumint(6) unsigned,
   `is_accepted` tinyint(1) NOT NULL DEFAULT -1,
   `is_complete` tinyint(1) NOT NULL DEFAULT 0,
   PRIMARY KEY (`id`),
-  FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`)
+  FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`),
+  FOREIGN KEY (`organization_id`) REFERENCES `opw_programs`(`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
 CREATE TABLE `opw_participants` (
@@ -45,9 +55,11 @@ CREATE TABLE `opw_roles` (
   `id` mediumint(10) NOT NULL AUTO_INCREMENT,
   `username` varchar(255) NOT NULL DEFAULT '',
   `program_id` mediumint(6) unsigned NOT NULL,
+  `organization_id` mediumint(6) unsigned,
   `role` char(1) NOT NULL DEFAULT 's',
   PRIMARY KEY (`id`),
-  FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`)
+  FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`),
+  FOREIGN KEY (`organization_id`) REFERENCES `opw_organizations`(`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
 CREATE TABLE `opw_session` (
diff --git a/skins/easterngreen/html/tpl_apply_mentor.html b/skins/easterngreen/html/tpl_apply_mentor.html
new file mode 100644
index 0000000..7c8d889
--- /dev/null
+++ b/skins/easterngreen/html/tpl_apply_mentor.html
@@ -0,0 +1,9 @@
+<h1>{{apply_mentor}}</h1>
+<hr class="hr-head" />
+
+<form method="post" action="[[submit_url]]">
+  [[organization_select]]
+  <button type="submit" name="apply" class="btn btn-primary">{{apply}}</button>
+  <a href="[[cancel_url]]" class="btn">{{cancel}}</a>
+</form>
+
diff --git a/skins/easterngreen/html/tpl_approve_mentors.html 
b/skins/easterngreen/html/tpl_approve_mentors.html
index 108614d..d3b58a3 100644
--- a/skins/easterngreen/html/tpl_approve_mentors.html
+++ b/skins/easterngreen/html/tpl_approve_mentors.html
@@ -14,6 +14,7 @@
                 </th>
                 
                 <th style="width:200px;"></th>
+                <th style="width:200px;"></th>
             </tr>
         </thead>
 
@@ -21,4 +22,4 @@
             [[mentors_list]]
         </tbody>
     </table>
-</div>
\ No newline at end of file
+</div>
diff --git a/skins/easterngreen/html/tpl_approve_mentors_item.html 
b/skins/easterngreen/html/tpl_approve_mentors_item.html
index 575b7d1..4c700dd 100644
--- a/skins/easterngreen/html/tpl_approve_mentors_item.html
+++ b/skins/easterngreen/html/tpl_approve_mentors_item.html
@@ -3,6 +3,10 @@
         [[mentor_name]]
     </td>
 
+    <td>
+        [[organization]]
+    </td>
+
     <td class="align-right">
         <a href="[[approve_url]]" title="{{approve}}">
             <i class="icon-ok"></i>
@@ -12,4 +16,4 @@
             <i class="icon-remove"></i>
         </a>
     </td>
-</tr>
\ No newline at end of file
+</tr>
diff --git a/skins/easterngreen/html/tpl_header.html b/skins/easterngreen/html/tpl_header.html
index 03bce69..f2c3865 100644
--- a/skins/easterngreen/html/tpl_header.html
+++ b/skins/easterngreen/html/tpl_header.html
@@ -78,6 +78,12 @@ ocalization variable
                                 </li>
 
                                 <li>
+                                    <a href="?q=manage_organizations&amp;prg=[[program_id]]">
+                                        {{manage_organizations}}
+                                    </a>
+                                </li>
+
+                                <li>
                                     <a href="?q=view_programs&amp;r=proposed">
                                         {{approve_proposal}}
                                     </a>
diff --git a/skins/easterngreen/html/tpl_manage_organizations.html 
b/skins/easterngreen/html/tpl_manage_organizations.html
new file mode 100644
index 0000000..52a020c
--- /dev/null
+++ b/skins/easterngreen/html/tpl_manage_organizations.html
@@ -0,0 +1,32 @@
+<div class="pull-right"m>
+    <a href="?q=manage_organizations&amp;a=editor&amp;prg=[[program_id]]" class="btn btn-primary">
+        <i class="icon-plus-sign icon-white"></i>
+        {{add_organization}}
+    </a>
+</div>
+
+<h1>{{manage_organizations}}</h1>
+<hr class="hr-head" />
+
+<div class="alert alert-info [[notice_visibility]]">
+    {{no_organizations}}
+</div>
+
+<div class="[[list_visibility]]">
+    <table class="table table-striped">
+        <thead>
+            <tr>
+                <th>{{organization_title}}</th>
+                <th style="width:20px">{{edit}}</th>
+            </tr>
+        </thead>
+
+        <tbody>
+            [[organizations_list]]
+        </tbody>
+    </table>
+
+    <div class="pages align-center [[pages_visibility]]">
+        [[list_pages]]
+    </div>
+</div>
diff --git a/skins/easterngreen/html/tpl_manage_organizations_editor.html 
b/skins/easterngreen/html/tpl_manage_organizations_editor.html
new file mode 100644
index 0000000..8432494
--- /dev/null
+++ b/skins/easterngreen/html/tpl_manage_organizations_editor.html
@@ -0,0 +1,35 @@
+<h1>[[editor_title]]</h1>
+<hr class="hr-head" />
+
+<div class="alert alert-error [[error_visibility]]">
+    <a class="close" data-dismiss="alert">×</a>
+    [[error_message]]
+</div>
+
+<div class="alert alert-info">
+    {{form_notice}}
+</div>
+
+<div class="control-group">
+    <label class="control-label">{{organization_title}} *</label>
+    <div class="controls">
+        <input type="text" name="title" maxlength="100" class="input-xxlarge" value="[[title]]"  />
+    </div>
+</div>
+
+<div class="form-actions">
+    <button type="submit" name="organization_save" class="btn btn-primary">
+        <i class="icon-ok-sign icon-white"></i>
+        {{save}}
+    </button>
+
+    <a href="[[cancel_url]]" class="btn">
+        <i class="icon-remove icon-black"></i>
+        {{cancel}}
+    </a>
+
+    <a href="[[delete_url]]" class="btn btn-danger delete-button [[delete_visibility]]">
+        <i class="icon-trash icon-white"></i>
+        {{delete}}
+    </a>
+</div>
diff --git a/skins/easterngreen/html/tpl_manage_organizations_item.html 
b/skins/easterngreen/html/tpl_manage_organizations_item.html
new file mode 100644
index 0000000..3a0d3e0
--- /dev/null
+++ b/skins/easterngreen/html/tpl_manage_organizations_item.html
@@ -0,0 +1,11 @@
+<tr>
+    <td>
+        [[organization_title]]
+    </td>
+
+    <td class="align-center">
+        <a href="?q=manage_organizations&amp;a=editor&amp;o=[[organization_id]]">
+            <i class="icon-pencil"></i>
+        </a>
+    </td>
+</tr>
diff --git a/skins/easterngreen/html/tpl_view_project.html b/skins/easterngreen/html/tpl_view_project.html
index 349e56c..11445a4 100644
--- a/skins/easterngreen/html/tpl_view_project.html
+++ b/skins/easterngreen/html/tpl_view_project.html
@@ -23,6 +23,11 @@
     </div>
 
     <div class="row">
+        <div class="span2">{{organization}}</div>
+        <div class="span8">[[project_organization]]</div>
+    </div>
+
+    <div class="row">
         <div class="span2">{{description}}</div>
         <div class="span8">[[project_description]]</div>
     </div>
diff --git a/skins/easterngreen/html/tpl_view_projects.html b/skins/easterngreen/html/tpl_view_projects.html
index 3c88bba..81adede 100644
--- a/skins/easterngreen/html/tpl_view_projects.html
+++ b/skins/easterngreen/html/tpl_view_projects.html
@@ -17,6 +17,10 @@
                 <th style="width:250px">
                     {{project_title}}
                 </th>
+
+                <th style="width:50px">
+                    {{organization}}
+                </th>
                 
                 <th>
                     {{description}}
@@ -34,4 +38,4 @@
     <div class="pages align-center [[pages_visibility]]">
         [[list_pages]]
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/skins/easterngreen/html/tpl_view_projects_editor.html 
b/skins/easterngreen/html/tpl_view_projects_editor.html
index 2fd7f28..b4b92d2 100644
--- a/skins/easterngreen/html/tpl_view_projects_editor.html
+++ b/skins/easterngreen/html/tpl_view_projects_editor.html
@@ -29,6 +29,13 @@
 </div>
 
 <div class="control-group">
+    <label class="control-label">{{organization}}</label>
+    <div class="controls">
+        [[organization_select]]
+    </div>
+</div>
+
+<div class="control-group">
     <label class="control-label">{{description}}</label>
     <div class="controls">
         <textarea name="description" rows="10" class="input-xxlarge">[[project_description]]</textarea>
diff --git a/skins/easterngreen/html/tpl_view_projects_item.html 
b/skins/easterngreen/html/tpl_view_projects_item.html
index 459b2fe..c9a01e6 100644
--- a/skins/easterngreen/html/tpl_view_projects_item.html
+++ b/skins/easterngreen/html/tpl_view_projects_item.html
@@ -6,6 +6,10 @@
     </td>
 
     <td>
+        [[project_organization]]
+    </td>
+
+    <td>
         [[project_description]]
     </td>
 
@@ -20,4 +24,4 @@
             </a>
         </div>
     </td>
-</tr>
\ No newline at end of file
+</tr>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]