Browse Source

plugin search course: #4597

Laurent Opprecht 13 years ago
parent
commit
061d27b8c4

+ 5 - 0
plugin/search_course/index.php

@@ -0,0 +1,5 @@
+<?php
+
+require_once dirname(__FILE__) . '/lib/search_course_widget.class.php';
+$widget = new SearchCourseWidget();
+$widget->run();

+ 10 - 0
plugin/search_course/lang/english.php

@@ -0,0 +1,10 @@
+<?php
+/**
+ *
+ * @copyright (c) 2012 University of Geneva
+ * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
+ * @author Laurent Opprecht <laurent@opprecht.info>
+ */
+
+$strings['plugin_title'] = "Search Course";
+$strings['plugin_comment'] = "Allow to search the course catalog and register to courses.";

+ 10 - 0
plugin/search_course/lang/french.php

@@ -0,0 +1,10 @@
+<?php
+/**
+ *
+ * @copyright (c) 2012 University of Geneva
+ * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
+ * @author Laurent Opprecht <laurent@opprecht.info>
+ */
+
+$strings['plugin_title'] = "Rechercher un cours";
+$strings['plugin_comment'] = "Permets de rechercher un cours dans le catalogue et de s'inscrire.";

+ 163 - 0
plugin/search_course/lib/register_course_widget.class.php

@@ -0,0 +1,163 @@
+<?php
+
+/**
+ * Register course widget. 
+ * Handles user's registration action.
+ * Display a register to course form if required.
+ * 
+ * @copyright (c) 2011 University of Geneva
+ * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
+ * @author Laurent Opprecht
+ */
+class RegisterCourseWidget
+{
+    const ACTION_SUBSCRIBE = 'subscribe';
+
+    const PARAM_SUBSCRIBE = 'subscribe';
+    const PARAM_PASSCODE = 'course_registration_code';
+
+    /**
+     * Returns $_POST data for $key is it exists or $default otherwise.
+     * 
+     * @param string $key
+     * @param object $default
+     * @return string 
+     */
+    public static function post($key, $default = '')
+    {
+        return isset($_POST[$key]) ? $_POST[$key] : $default;
+    }
+
+    /**
+     * Returns $_GET data for $key is it exists or $default otherwise.
+     * 
+     * @param string $key
+     * @param object $default
+     * @return string 
+     */
+    public static function get($key, $default = '')
+    {
+        return isset($_GET[$key]) ? $_GET[$key] : $default;
+    }
+
+    /**
+     *
+     * @return RegisterCourseWidget
+     */
+    public static function factory()
+    {
+        return new self();
+    }
+
+    function run()
+    {
+        return $this->action_subscribe_user();
+    }
+
+    /**
+     * Handle the subscribe action.
+     * 
+     * @return bool
+     */
+    function action_subscribe_user()
+    {
+        $action = self::get('action');
+        if ($action != self::ACTION_SUBSCRIBE)
+        {
+            return false;
+        }
+
+        $course_code = self::post(self::PARAM_SUBSCRIBE);
+        if (empty($course_code))
+        {
+            return false;
+        }
+        
+        $registration_code = self::post(self::PARAM_PASSCODE);
+
+        if ($this->subscribe_user($course_code, $registration_code))
+        {
+            Display::display_confirmation_message(get_lang('EnrollToCourseSuccessful'));
+            return;
+        }
+        if (!empty($registration_code))
+        {
+            Display::display_error_message(get_lang('CourseRegistrationCodeIncorrect'));
+        }
+        $this->display_form($course_code);
+        return true;
+    }
+
+    /**
+     * Regiser a user to a course.
+     * Returns true on success, false otherwise.
+     * 
+     * @param string $course_code
+     * @param string $registration_code
+     * @param int $user_id
+     * @return bool 
+     */
+    function subscribe_user($course_code, $registration_code = '', $user_id = null)
+    {
+        $course = $this->retrieve_course($course_code);
+        $course_regisration_code = $course['registration_code'];
+        if (!empty($course_regisration_code) && $registration_code != $course_regisration_code)
+        {
+            return false;
+        }
+
+        if (empty($user_id))
+        {
+            global $_user;
+            $user_id = $_user['user_id'];
+        }
+
+        return (bool) CourseManager::add_user_to_course($user_id, $course_code);
+    }
+
+    /**
+     * Display the course registration form.
+     * Asks for registration code/password.
+     * 
+     * @param string $course_code
+     */
+    function display_form($course_code)
+    {
+        global $stok;
+
+        $course = $this->retrieve_course($course_code);
+        $self = $_SERVER['REQUEST_URI'];
+        $course_code = $course['code'];
+        $course_visual_code = $course['visual_code'];
+        $course_title = $course['title'];
+        $submit_registration_code_label = get_lang("SubmitRegistrationCode");
+        $course_requires_password_label = get_lang('CourseRequiresPassword');
+
+        $result = <<<EOT
+            $course_requires_password_label<br/>
+            $course_visual_code - $course_title
+            <form action="$self" method="post">
+            <input type="hidden" name="sec_token" value="$stok" />
+            <input type="hidden" name="subscribe" value="$course_code" />
+            <input type="text" name="course_registration_code" value="$registration_code" />
+            <input type="Submit" name="submit_course_registration_code" value="OK" alt="$submit_registration_code_label" /></form>
+EOT;
+        echo $result;
+    }
+
+    /**
+     * DB functions - DB functions - DB functions
+     */
+
+    /**
+     *
+     * @param type $course_code
+     * @return type 
+     */
+    function retrieve_course($course_code)
+    {
+        require_once api_get_path(SYS_PATH) . '/main/inc/lib/course.lib.php';
+        return CourseManager::get_course_information($course_code);
+    }
+
+}

+ 33 - 0
plugin/search_course/lib/search_course_plugin.class.php

@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Description of SearchCoursePlugin
+ *
+ * @copyright (c) 2012 University of Geneva
+ * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
+ * @author Laurent Opprecht <laurent@opprecht.info>
+ */
+class SearchCoursePlugin extends Plugin
+{
+
+    /**
+     *
+     * @return SearchCoursePlugin 
+     */
+    static function create()
+    {
+        static $result = null;
+        return $result ? $result : $result = new self();
+    }
+    
+    function get_name()
+    {
+        return 'search_course';
+    }
+
+    protected function __construct()
+    {
+        parent::__construct('1.1', 'Laurent Opprecht');
+    }
+
+}

+ 435 - 0
plugin/search_course/lib/search_course_widget.class.php

@@ -0,0 +1,435 @@
+<?php
+
+require_once dirname(__FILE__) . '/register_course_widget.class.php';
+
+/**
+ * Search course widget. 
+ * Display a search form and a list of courses that matches the search.
+ * 
+ * @copyright (c) 2011 University of Geneva
+ * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
+ * @author Laurent Opprecht
+ */
+class SearchCourseWidget
+{
+
+    const PARAM_ACTION = 'action';
+    const ACTION_SUBSCRIBE = 'subscribe';
+
+    /**
+     * Returns $_POST data for $key is it exists or $default otherwise.
+     * 
+     * @param string $key
+     * @param object $default
+     * @return string 
+     */
+    public static function post($key, $default = '')
+    {
+        return isset($_POST[$key]) ? $_POST[$key] : $default;
+    }
+
+    /**
+     * Returns $_GET data for $key is it exists or $default otherwise.
+     * 
+     * @param string $key
+     * @param object $default
+     * @return string 
+     */
+    public static function get($key, $default = '')
+    {
+        return isset($_GET[$key]) ? $_GET[$key] : $default;
+    }
+
+    public static function server($key, $default = '')
+    {
+        return isset($_SERVER[$key]) ? $_SERVER[$key] : $default;
+    }
+
+    public static function get_lang($name)
+    {
+        return SearchCoursePlugin::create()->get_lang($name);
+    }
+
+    /**
+     *
+     * @return bool
+     */
+    function is_homepage()
+    {
+
+        $url = self::server('REQUEST_URI');
+        $url = explode('?', $url);
+        $url = reset($url);
+        $url = self::server('SERVER_NAME') . $url;
+
+        $root = api_get_path('WEB_PATH');
+        $root = str_replace('https://', '', $root);
+        $root = str_replace('http://', '', $root);
+        $index_url = $root . 'index.php';
+
+        return $url == $index_url || $url == $root;
+    }
+    
+    /**
+     *
+     * @return bool
+     */
+    function is_user_portal()
+    {
+
+        $url = self::server('REQUEST_URI');
+        $url = explode('?', $url);
+        $url = reset($url);
+        $url = self::server('SERVER_NAME') . $url;
+
+        $root = api_get_path('WEB_PATH');
+        $root = str_replace('https://', '', $root);
+        $root = str_replace('http://', '', $root);
+        $index_url = $root . 'user_portal.php';
+
+        return $url == $index_url || $url == $root;
+    }
+
+    /**
+     * 
+     */
+    function accept()
+    {
+        return $this->is_homepage() || $this->is_user_portal();
+    }
+
+    /**
+     * Display the search course widget:
+     * 
+     * Title
+     * Search form
+     * 
+     * Search results
+     */
+    function run()
+    {
+        if (!$this->accept())
+        {
+            return;
+        }
+        $this->display_header();
+
+        $this->display_form();
+
+        $search_term = self::post('search_term');
+        $action = self::get('action');
+
+        $has_content = !empty($search_term) || !empty($action);
+        if ($has_content)
+        {
+            echo '<div class="list">';
+        }
+        else
+        {
+            echo '<div>';
+        }
+
+        if (RegisterCourseWidget::factory()->run())
+        {
+            $result = true;
+        }
+        else
+        {
+            $result = $this->action_display();
+        }
+
+        echo '</div>';
+
+        $this->display_footer();
+        return $result;
+    }
+
+    function get_url($action = '')
+    {
+        $self = $_SERVER['PHP_SELF'];
+        $parameters = array();
+        if ($action)
+        {
+            $parameters[self::PARAM_ACTION] = $action;
+        }
+        $parameters = implode('&', $parameters);
+        $parameters = $parameters ? '?' . $parameters : '';
+        return $self . $parameters;
+    }
+
+    /**
+     * Handle the display action
+     */
+    function action_display()
+    {
+        global $charset;
+
+        $search_term = self::post('search_term');
+        if ($search_term)
+        {
+            $search_result_for_label = self::get_lang('SearchResultsFor');
+            $search_term_html = htmlentities($search_term, ENT_QUOTES, $charset);
+            echo "<h5>$search_result_for_label $search_term_html</h5>";
+
+            $courses = $this->retrieve_courses($search_term);
+            $this->display_list($courses);
+        }
+        return true;
+    }
+
+    function display_header()
+    {
+        $search_course_label = self::get_lang('SearchCourse');
+        echo <<<EOT
+        <div class="well course_search">
+        <div class="menusection">
+            <h4>$search_course_label</h4>
+EOT;
+    }
+
+    function display_footer()
+    {
+        echo '</div></div>';
+    }
+
+    /**
+     * Display the search course form.
+     */
+    function display_form()
+    {
+        global $stok;
+
+        $search_label = self::get_lang('_search');
+        $self = api_get_self();
+        $search_term = self::post('search_term');
+        $form = <<<EOT
+        <form class="course_list" method="post" action="$self">
+            <input type="hidden" name="sec_token" value="$stok" />
+            <input type="hidden" name="search_course" value="1" />
+            <input type="text" name="search_term" size="55" value="$search_term" />
+            &nbsp;<input type="submit" value="$search_label" />
+        </form>
+EOT;
+        echo $form;
+    }
+
+    /**
+     *
+     * @param array $courses
+     * @return bool 
+     */
+    function display_list($courses)
+    {
+        if (empty($courses))
+        {
+            return false;
+        }
+
+        $user_courses = $this->retrieve_user_courses();
+
+        $display_coursecode = (get_setting('display_coursecode_in_courselist') == 'true');
+        $display_teacher = (get_setting('display_teacher_in_courselist') == 'true');
+
+        echo '<table cellpadding="4">';
+        foreach ($courses as $key => $course)
+        {
+            $details = array();
+            if ($display_coursecode)
+            {
+                $details[] = $course['visual_code'];
+            }
+            if ($display_teacher)
+            {
+                $details[] = $course['tutor'];
+            }
+            $details = implode(' - ', $details);
+            $title = $course['title'];
+
+            $href = api_get_path(WEB_PATH) . 'courses/' . $course['code'];
+            echo '<tr><td><b><a href="' . $href . '">' . "$title</a></b><br/>$details</td><td>";
+            if ($course['registration_code'])
+            {
+                Display::display_icon('passwordprotected.png', '', array('style' => 'float:left;'));
+            }
+            $this->display_subscribe_icon($course, $user_courses);
+            echo '</td></tr>';
+        }
+        echo '</table>';
+        return true;
+    }
+
+    /**
+     * Displays the subscribe icon if subscribing is allowed and 
+     * if the user is not yet subscribed to this course
+     * 
+     * @global type $stok
+     * @param array $current_course
+     * @param array $user_courses
+     * @return bool 
+     */
+    function display_subscribe_icon($current_course, $user_courses)
+    {
+        global $stok;
+
+        //Already subscribed
+        $code = $current_course['code'];
+        if (isset($user_courses[$code]))
+        {
+            echo self::get_lang('AlreadySubscribed');
+            return false;
+        }
+
+        //Not authorized to subscribe
+        if ($current_course['subscribe'] != SUBSCRIBE_ALLOWED)
+        {
+            echo self::get_lang('SubscribingNotAllowed');
+            return false;
+        }
+
+        //Subscribe form     
+        $self = $_SERVER['PHP_SELF'];
+        echo <<<EOT
+                <form action="$self?action=subscribe" method="post">
+                    <input type="hidden" name="sec_token" value="$stok" />
+                    <input type="hidden" name="subscribe" value="$code" />
+EOT;
+
+        $search_term = $this->post('search_term');
+        if ($search_term)
+        {
+            $search_term = Security::remove_XSS($search_term);
+            echo <<<EOT
+                    <input type="hidden" name="search_course" value="1" />
+                    <input type="hidden" name="search_term" value="$search_term" />
+EOT;
+        }
+
+        $web_path = api_get_path(WEB_PATH);
+        $subscribe_label = get_lang('Subscribe');
+        echo <<<EOT
+                    <input type="image" name="unsub" src="$web_path/main/img/enroll.gif" alt="$subscribe_label" />$subscribe_label
+                </form>
+EOT;
+        return true;
+    }
+
+    /**
+     * DB functions - DB functions - DB functions
+     */
+
+    /**
+     * Search courses that match the search term.
+     * Search is done on the code, title and tutor fields.
+     * 
+     * @param string $search_term 
+     * @return array 
+     */
+    function retrieve_courses($search_term)
+    {
+        if (empty($search_term))
+        {
+            return array();
+        }
+        $search_term = Database::escape_string($search_term);
+        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
+
+        $sql = <<<EOT
+                SELECT * FROM $course_table 
+                WHERE code LIKE '%$search_term%' OR visual_code LIKE '%$search_term%' OR title LIKE '%$search_term%' OR tutor_name LIKE '%$search_term%' 
+                ORDER BY title, visual_code ASC      
+EOT;
+
+        $result = array();
+        $resultset = api_sql_query($sql, __FILE__, __LINE__);
+        while ($row = Database::fetch_array($resultset))
+        {
+            $code = $row['code'];
+            $result[$code] = array(
+                'code' => $code,
+                'directory' => $row['directory'],
+                'db' => $row['db_name'],
+                'visual_code' => $row['visual_code'],
+                'title' => $row['title'],
+                'tutor' => $row['tutor_name'],
+                'subscribe' => $row['subscribe'],
+                'unsubscribe' => $row['unsubscribe']
+            );
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieves courses that the user is subscribed to
+     * 
+     * @param int $user_id
+     * @return array 
+     */
+    function retrieve_user_courses($user_id = null)
+    {
+        if (is_null($user_id))
+        {
+            global $_user;
+            $user_id = $_user['user_id'];
+        }
+        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
+        $user_course_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+
+        $user_id = intval($user_id);
+        $sql_select_courses = "SELECT course.code k, course.visual_code  vc, course.subscribe subscr, course.unsubscribe unsubscr,
+                                      course.title i, course.tutor_name t, course.db_name db, course.directory dir, course_rel_user.status status,
+				      course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
+		               FROM $course_table course, $user_course_table course_rel_user
+		               WHERE course.code = course_rel_user.course_code
+		                     AND course_rel_user.user_id = $user_id
+		               ORDER BY course_rel_user.sort ASC";
+        $result = array();
+        $resultset = api_sql_query($sql_select_courses, __FILE__, __LINE__);
+        while ($row = Database::fetch_array($resultset))
+        {
+            $code = $row['k'];
+            $result[$code] = array(
+                'db' => $row['db'],
+                'code' => $code,
+                'visual_code' => $row['vc'],
+                'title' => $row['i'],
+                'directory' => $row['dir'],
+                'status' => $row['status'],
+                'tutor' => $row['t'],
+                'subscribe' => $row['subscr'],
+                'unsubscribe' => $row['unsubscr'],
+                'sort' => $row['sort'],
+                'user_course_category' => $row['user_course_cat']);
+        }
+        return $result;
+    }
+
+    /*
+     * Utility functions - Utility functions - Utility functions 
+     */
+
+    /**
+     * Removes from $courses all courses the user is subscribed to.
+     * 
+     * @global array $_user
+     * @param array $courses
+     * @return array 
+     */
+    function filter_out_user_courses($courses)
+    {
+        if (empty($courses))
+        {
+            return $courses;
+        }
+
+        global $_user;
+        $user_id = $_user['user_id'];
+
+        $user_courses = $this->retrieve_user_courses($user_id);
+        foreach ($user_courses as $key => $value)
+        {
+            unset($courses[$key]);
+        }
+        return $courses;
+    }
+
+}

+ 11 - 0
plugin/search_course/plugin.php

@@ -0,0 +1,11 @@
+<?php 
+/**
+ * @copyright (c) 2011 University of Geneva
+ * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
+ * @author Laurent Opprecht
+ */
+
+require_once api_get_path(LIBRARY_PATH) . '/plugin.class.php';
+require_once dirname(__FILE__) . '/lib/search_course_plugin.class.php';
+
+$plugin_info = SearchCoursePlugin::create()->get_info();

+ 1 - 0
plugin/search_course/readme.txt

@@ -0,0 +1 @@
+Search courses in the main catalogue and register.