Merge branch 'wip-MDL-26811-master' of git://github.com/samhemelryk/moodle
authorAparup Banerjee <aparup@moodle.com>
Mon, 5 Sep 2011 05:01:23 +0000 (13:01 +0800)
committerAparup Banerjee <aparup@moodle.com>
Mon, 5 Sep 2011 05:01:23 +0000 (13:01 +0800)
49 files changed:
auth/cas/auth.php
auth/cas/lang/en/auth_cas.php
auth/ldap/auth.php
auth/mnet/auth.php
backup/util/ui/import_extensions.php
backup/util/ui/restore_ui_components.php
blocks/community/forms.php
blocks/community/lang/en/block_community.php
course/lib.php
index.php
install/lang/en_us/install.php [new file with mode: 0644]
lang/en/auth.php
lib/db/access.php
lib/dml/moodle_database.php
lib/dml/oci_native_moodle_database.php
lib/dml/simpletest/testdml.php
lib/navigationlib.php
lib/outputcomponents.php
lib/outputrenderers.php
message/renderer.php
mnet/lib.php
mnet/xmlrpc/client.php
mod/assignment/lib.php
mod/chat/gui_ajax/theme/compact/input.png [new file with mode: 0644]
mod/data/lang/en/data.php
mod/lesson/report.php
mod/quiz/attempt.php
mod/quiz/edit.php
mod/quiz/editlib.php
mod/quiz/renderer.php
mod/quiz/report/statistics/report.php
mod/quiz/review.php
question/edit.php
question/editlib.php
question/format/xml/format.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/questiontype.php
question/type/questiontypebase.php
repository/boxnet/lang/en/repository_boxnet.php
repository/boxnet/lib.php
theme/formal_white/lang/en/theme_formal_white.php
theme/formal_white/layout/frontpage.php
theme/formal_white/layout/general.php
theme/formal_white/lib.php
theme/formal_white/settings.php
theme/formal_white/style/formal_white.css
theme/formal_white/style/menu.css
user/selector/lib.php
version.php

index 5690c53..d66bdb8 100644 (file)
@@ -360,7 +360,7 @@ class auth_plugin_cas extends auth_plugin_ldap {
      * @return boolean result
      */
     function iscreator($username) {
-        if ((empty($this->config->attrcreators) && empty($this->config->groupecreators)) or empty($this->config->memberattribute)) {
+        if (empty($this->config->host_url) or (empty($this->config->attrcreators) && empty($this->config->groupecreators)) or empty($this->config->memberattribute)) {
             return false;
         }
 
@@ -405,4 +405,39 @@ class auth_plugin_cas extends auth_plugin_ldap {
 
         return false;
     }
+
+    /**
+     * Reads user information from LDAP and returns it as array()
+     *
+     * If no LDAP servers are configured, user information has to be
+     * provided via other methods (CSV file, manually, etc.). Return
+     * an empty array so existing user info is not lost. Otherwise,
+     * calls parent class method to get user info.
+     *
+     * @param string $username username
+     * @return mixed array with no magic quotes or false on error
+     */
+    function get_userinfo($username) {
+        if (empty($this->config->host_url)) {
+            return array();
+        }
+        return parent::get_userinfo($username);
+    }
+
+    /**
+     * Syncronizes users from LDAP server to moodle user table.
+     *
+     * If no LDAP servers are configured, simply return. Otherwise,
+     * call parent class method to do the work.
+     *
+     * @param bool $do_updates will do pull in data updates from LDAP if relevant
+     * @return nothing
+     */
+    function sync_users($do_updates=true) {
+        if (empty($this->config->host_url)) {
+            error_log('[AUTH CAS] '.get_string('noldapserver', 'auth_cas'));
+            return;
+        }
+        parent::sync_users($do_updates);
+    }
 }
index 319a505..3f5fe1e 100644 (file)
@@ -61,4 +61,5 @@ $string['auth_cas_text'] = 'Secure connection';
 $string['auth_cas_use_cas'] = 'Use CAS';
 $string['auth_cas_version'] = 'Version of CAS';
 $string['CASform'] = 'Authentication choice';
+$string['noldapserver'] = 'No LDAP server configured for CAS! Syncing disabled.';
 $string['pluginname'] = 'CAS server (SSO)';
index 9f2f03c..9f88bbd 100644 (file)
@@ -579,16 +579,17 @@ class auth_plugin_ldap extends auth_plugin_base {
         $sr = ldap_read($ldapconnection, $user_dn, '(objectClass=*)', $search_attribs);
         if ($sr)  {
             $info = ldap_get_entries_moodle($ldapconnection, $sr);
-            $info = array_change_key_case($info, CASE_LOWER);
-            if (!empty ($info) and !empty($info[0][$this->config->expireattr][0])) {
-                $expiretime = $this->ldap_expirationtime2unix($info[0][$this->config->expireattr][0], $ldapconnection, $user_dn);
-                if ($expiretime != 0) {
-                    $now = time();
-                    if ($expiretime > $now) {
-                        $result = ceil(($expiretime - $now) / DAYSECS);
-                    }
-                    else {
-                        $result = floor(($expiretime - $now) / DAYSECS);
+            if (!empty ($info)) {
+                $info = array_change_key_case($info[0], CASE_LOWER);
+                if (!empty($info[$this->config->expireattr][0])) {
+                    $expiretime = $this->ldap_expirationtime2unix($info[$this->config->expireattr][0], $ldapconnection, $user_dn);
+                    if ($expiretime != 0) {
+                        $now = time();
+                        if ($expiretime > $now) {
+                            $result = ceil(($expiretime - $now) / DAYSECS);
+                        } else {
+                            $result = floor(($expiretime - $now) / DAYSECS);
+                        }
                     }
                 }
             }
index 5858ca4..9c463d6 100644 (file)
@@ -276,6 +276,7 @@ class auth_plugin_mnet extends auth_plugin_base {
             */
             $remoteuser->mnethostid = $remotehost->id;
             $remoteuser->firstaccess = time(); // First time user in this server, grab it here
+            $remoteuser->confirmed = 1;
 
             $remoteuser->id = $DB->insert_record('user', $remoteuser);
             $firsttime = true;
index b4f9068..9fe31bb 100644 (file)
@@ -158,4 +158,13 @@ class import_ui_stage_final extends backup_ui_stage_final {}
 /**
  * Extends the restore course search to search for import courses.
  */
-class import_course_search extends restore_course_search {}
\ No newline at end of file
+class import_course_search extends restore_course_search {
+    /**
+     * Sets up any access restrictions for the courses to be displayed in the search.
+     * 
+     * This will typically call $this->require_capability().
+     */
+    protected function setup_restrictions() {
+        $this->require_capability('moodle/backup:backuptargetimport');
+    }
+}
\ No newline at end of file
index 5daf231..85c61c8 100644 (file)
@@ -226,9 +226,17 @@ class restore_course_search extends restore_search_base {
      */
     public function __construct(array $config=array(), $currentcouseid = null) {
         parent::__construct($config);
-        $this->require_capability('moodle/restore:restorecourse');
+        $this->setup_restrictions();
         $this->currentcourseid = $currentcouseid;
         $this->includecurrentcourse = false;
+    }   
+    /**
+     * Sets up any access restrictions for the courses to be displayed in the search.
+     * 
+     * This will typically call $this->require_capability().
+     */
+    protected function setup_restrictions() {
+        $this->require_capability('moodle/restore:restorecourse');
     }
     /**
      *
index c4abd1e..141bf66 100644 (file)
@@ -155,10 +155,12 @@ class community_hub_search_form extends moodleform {
                                     array('class' => 'hubscreenshot'));
                     $hubdescriptiontext = html_writer::tag('span', format_text($hub['description'], FORMAT_PLAIN),
                                     array('class' => 'hubdescription'));
-                    $additionaldesc = get_string('sites', 'block_community') . ': ' . $hub['sites'] . ' - ' .
-                            get_string('courses', 'block_community') . ': ' . $hub['courses'];
-                    $hubdescriptiontext .= html_writer::tag('span', $additionaldesc,
-                                    array('class' => 'hubadditionaldesc'));
+                    if (isset($hub['enrollablecourses'])) { //check needed to avoid warnings for Moodle version < 2011081700
+                        $additionaldesc = get_string('enrollablecourses', 'block_community') . ': ' . $hub['enrollablecourses'] . ' - ' .
+                                get_string('downloadablecourses', 'block_community') . ': ' . $hub['downloadablecourses'];
+                        $hubdescriptiontext .= html_writer::tag('span', $additionaldesc,
+                                        array('class' => 'hubadditionaldesc'));
+                    }
                     if ($hub['trusted']) {
                     $hubtrusted =  get_string('hubtrusted', 'block_community');
                     $hubdescriptiontext .= html_writer::tag('span',
index 0505aeb..ec78b5a 100644 (file)
@@ -49,6 +49,7 @@ $string['donotrestore'] = 'No';
 $string['dorestore'] = 'Yes';
 $string['download'] = 'Download';
 $string['downloadable'] = 'courses I can download';
+$string['downloadablecourses'] = 'Downloadable courses';
 $string['downloadconfirmed'] = 'The backup has been saved in your private files {$a}';
 $string['downloaded'] = '...finished.';
 $string['downloadingcourse'] = 'Downloading course';
@@ -61,8 +62,9 @@ $string['enroldownload_help'] = 'Some courses listed in the selected hub are bei
 
 Others are course templates provided for you to download and use on your own Moodle site.';
 $string['enrollable'] = 'courses I can enrol in';
-$string['errorcourselisting'] = 'An error occured when retrieving the course listing from the selected hub, please try again later. ({$a})';
-$string['errorhublisting'] = 'An error occured when retrieving the hub listing from Moodle.org, please try again later. ({$a})';
+$string['enrollablecourses'] = 'Enrollable courses';
+$string['errorcourselisting'] = 'An error occurred when retrieving the course listing from the selected hub, please try again later. ({$a})';
+$string['errorhublisting'] = 'An error occurred when retrieving the hub listing from Moodle.org, please try again later. ({$a})';
 $string['fileinfo'] = 'Language: {$a->lang} - License: {$a->license} -  Time updated: {$a->timeupdated}';
 $string['hub'] = 'hub';
 $string['hubnottrusted'] = 'Not trusted';
index 35be49b..a562887 100644 (file)
@@ -3027,19 +3027,33 @@ function moveto_module($mod, $section, $beforemod=NULL) {
     return true;
 }
 
-function make_editing_buttons($mod, $absolute=false, $moveselect=true, $indent=-1, $section=-1) {
-    global $CFG, $USER, $DB, $OUTPUT;
+/**
+ * Produces the editing buttons for a module
+ *
+ * @global core_renderer $OUTPUT
+ * @staticvar type $str
+ * @param stdClass $mod The module to produce editing buttons for
+ * @param bool $absolute If true an absolute link is produced (default true)
+ * @param bool $moveselect If true a move seleciton process is used (default true)
+ * @param int $indent The current indenting
+ * @param int $section The section to link back to
+ * @return string XHTML for the editing buttons
+ */
+function make_editing_buttons(stdClass $mod, $absolute = true, $moveselect = true, $indent=-1, $section=-1) {
+    global $CFG, $OUTPUT;
 
     static $str;
-    static $sesskey;
 
+    $coursecontext = get_context_instance(CONTEXT_COURSE, $mod->course);
     $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
+
     // no permission to edit
     if (!has_capability('moodle/course:manageactivities', $modcontext)) {
         return false;
     }
 
     if (!isset($str)) {
+        $str = new stdClass;
         $str->assign         = get_string("assignroles", 'role');
         $str->delete         = get_string("delete");
         $str->move           = get_string("move");
@@ -3056,131 +3070,165 @@ function make_editing_buttons($mod, $absolute=false, $moveselect=true, $indent=-
         $str->groupsnone     = get_string("groupsnone");
         $str->groupsseparate = get_string("groupsseparate");
         $str->groupsvisible  = get_string("groupsvisible");
-        $sesskey = sesskey();
     }
 
-    if ($section >= 0) {
-        $section = '&amp;sr='.$section;   // Section return
+    if ($absolute) {
+        $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
     } else {
-        $section = '';
+        $baseurl = new moodle_url('mod.php', array('sesskey' => sesskey()));
     }
 
-    if ($absolute) {
-        $path = $CFG->wwwroot.'/course';
-    } else {
-        $path = '.';
+    if ($section >= 0) {
+        $baseurl->param('sr', $section);
+    }
+    $actions = array();
+
+    // leftright
+    if (has_capability('moodle/course:update', $coursecontext)) {
+        if (right_to_left()) {   // Exchange arrows on RTL
+            $rightarrow = 't/left';
+            $leftarrow  = 't/right';
+        } else {
+            $rightarrow = 't/right';
+            $leftarrow  = 't/left';
+        }
+
+        if ($indent > 0) {
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')),
+                new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_moveleft', 'title' => $str->moveleft)
+            );
+        }
+        if ($indent >= 0) {
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')),
+                new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_moveright', 'title' => $str->moveright)
+            );
+        }
+    }
+
+    // move
+    if (has_capability('moodle/course:update', $coursecontext)) {
+        if ($moveselect) {
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('copy' => $mod->id)),
+                new pix_icon('t/move', $str->move, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_move', 'title' => $str->move)
+            );
+        } else {
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('id' => $mod->id, 'move' => '-1')),
+                new pix_icon('t/up', $str->moveup, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_moveup', 'title' => $str->moveup)
+            );
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('id' => $mod->id, 'move' => '1')),
+                new pix_icon('t/down', $str->movedown, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_movedown', 'title' => $str->movedown)
+            );
+        }
     }
+
+    // Update
+    $actions[] = new action_link(
+        new moodle_url($baseurl, array('update' => $mod->id)),
+        new pix_icon('t/edit', $str->update, 'moodle', array('class' => 'iconsmall')),
+        null,
+        array('class' => 'editing_update', 'title' => $str->update)
+    );
+
+    // Duplicate
+    $actions[] = new action_link(
+        new moodle_url($baseurl, array('duplicate' => $mod->id)),
+        new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall')),
+        null,
+        array('class' => 'editing_duplicate', 'title' => $str->duplicate)
+    );
+
+    // Delete
+    $actions[] = new action_link(
+        new moodle_url($baseurl, array('delete' => $mod->id)),
+        new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall')),
+        null,
+        array('class' => 'editing_delete', 'title' => $str->delete)
+    );
+
+    // hideshow
     if (has_capability('moodle/course:activityvisibility', $modcontext)) {
         if ($mod->visible) {
-            $hideshow = '<a class="editing_hide" title="'.$str->hide.'" href="'.$path.'/mod.php?hide='.$mod->id.
-                        '&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" '.
-                        ' alt="'.$str->hide.'" /></a>'."\n";
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('hide' => $mod->id)),
+                new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_hide', 'title' => $str->hide)
+            );
         } else {
-            $hideshow = '<a class="editing_show" title="'.$str->show.'" href="'.$path.'/mod.php?show='.$mod->id.
-                        '&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" '.
-                        ' alt="'.$str->show.'" /></a>'."\n";
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('show' => $mod->id)),
+                new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => 'editing_show', 'title' => $str->show)
+            );
         }
-    } else {
-        $hideshow = '';
     }
 
+    // groupmode
     if ($mod->groupmode !== false) {
         if ($mod->groupmode == SEPARATEGROUPS) {
+            $groupmode = 0;
             $grouptitle = $str->groupsseparate;
             $groupclass = 'editing_groupsseparate';
-            $groupimage = $OUTPUT->pix_url('t/groups') . '';
-            $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=0&amp;sesskey='.$sesskey;
+            $groupimage = 't/groups';
         } else if ($mod->groupmode == VISIBLEGROUPS) {
+            $groupmode = 1;
             $grouptitle = $str->groupsvisible;
             $groupclass = 'editing_groupsvisible';
-            $groupimage = $OUTPUT->pix_url('t/groupv') . '';
-            $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=1&amp;sesskey='.$sesskey;
+            $groupimage = 't/groupv';
         } else {
+            $groupmode = 2;
             $grouptitle = $str->groupsnone;
             $groupclass = 'editing_groupsnone';
-            $groupimage = $OUTPUT->pix_url('t/groupn') . '';
-            $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=2&amp;sesskey='.$sesskey;
+            $groupimage = 't/groupn';
         }
         if ($mod->groupmodelink) {
-            $groupmode = '<a class="'.$groupclass.'" title="'.$grouptitle.' ('.$str->clicktochange.')" href="'.$grouplink.'">'.
-                         '<img src="'.$groupimage.'" class="iconsmall" '.
-                         'alt="'.$grouptitle.'" /></a>';
+            $actions[] = new action_link(
+                new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $groupmode)),
+                new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall')),
+                null,
+                array('class' => $groupclass, 'title' => $grouptitle.' ('.$str->clicktochange.')')
+            );
         } else {
-            $groupmode = '<img title="'.$grouptitle.' ('.$str->forcedmode.')" '.
-                         ' src="'.$groupimage.'" class="iconsmall" '.
-                         'alt="'.$grouptitle.'" />';
+            $actions[] = new pix_icon($groupimage, $grouptitle, 'moodle', array('title' => $grouptitle.' ('.$str->forcedmode.')', 'class' => 'iconsmall'));
         }
-    } else {
-        $groupmode = "";
     }
 
-    if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
-        if ($moveselect) {
-            $move =     '<a class="editing_move" title="'.$str->move.'" href="'.$path.'/mod.php?copy='.$mod->id.
-                        '&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/move') . '" class="iconsmall" '.
-                        ' alt="'.$str->move.'" /></a>'."\n";
-        } else {
-            $move =     '<a class="editing_moveup" title="'.$str->moveup.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;move=-1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/up') . '" class="iconsmall" '.
-                        ' alt="'.$str->moveup.'" /></a>'."\n".
-                        '<a class="editing_movedown" title="'.$str->movedown.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;move=1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/down') . '" class="iconsmall" '.
-                        ' alt="'.$str->movedown.'" /></a>'."\n";
-        }
-    } else {
-        $move = '';
+    // Assign
+    if (has_capability('moodle/course:managegroups', $modcontext)){
+        $actions[] = new action_link(
+            new moodle_url('/'.$CFG->admin.'/roles/assign.php', array('contextid' => $modcontext->id)),
+            new pix_icon('i/roles', $str->assign, 'moodle', array('class' => 'iconsmall')),
+            null,
+            array('class' => 'editing_assign', 'title' => $str->assign)
+        );
     }
 
-    $leftright = '';
-    if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
-
-        if (right_to_left()) {   // Exchange arrows on RTL
-            $rightarrow = 't/left';
-            $leftarrow  = 't/right';
+    $output = html_writer::start_tag('span', array('class' => 'commands'));
+    foreach ($actions as $action) {
+        if ($action instanceof renderable) {
+            $output .= $OUTPUT->render($action);
         } else {
-            $rightarrow = 't/right';
-            $leftarrow  = 't/left';
-        }
-
-        if ($indent > 0) {
-            $leftright .= '<a class="editing_moveleft" title="'.$str->moveleft.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;indent=-1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url($leftarrow).'" class="iconsmall" '.
-                        ' alt="'.$str->moveleft.'" /></a>'."\n";
-        }
-        if ($indent >= 0) {
-            $leftright .= '<a class="editing_moveright" title="'.$str->moveright.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;indent=1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url($rightarrow).'" class="iconsmall" '.
-                        ' alt="'.$str->moveright.'" /></a>'."\n";
+            $output .= $action;
         }
     }
-    if (has_capability('moodle/course:managegroups', $modcontext)){
-        $context = get_context_instance(CONTEXT_MODULE, $mod->id);
-        $assign = '<a class="editing_assign" title="'.$str->assign.'" href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.
-            $context->id.'"><img src="'.$OUTPUT->pix_url('i/roles') . '" alt="'.$str->assign.'" class="iconsmall"/></a>';
-    } else {
-        $assign = '';
-    }
-
-    return '<span class="commands">'."\n".$leftright.$move.
-           '<a class="editing_update" title="'.$str->update.'" href="'.$path.'/mod.php?update='.$mod->id.
-           '&amp;sesskey='.$sesskey.$section.'"><img'.
-           ' src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall" '.
-           ' alt="'.$str->update.'" /></a>'."\n".
-           '<a class="editing_duplicate" title="'.$str->duplicate.'" href="'.$path.'/mod.php?duplicate='.$mod->id.
-           '&amp;sesskey='.$sesskey.$section.'"><img'.
-           ' src="'.$OUTPUT->pix_url('t/copy') . '" class="iconsmall" '.
-           ' alt="'.$str->duplicate.'" /></a>'."\n".
-           '<a class="editing_delete" title="'.$str->delete.'" href="'.$path.'/mod.php?delete='.$mod->id.
-           '&amp;sesskey='.$sesskey.$section.'"><img'.
-           ' src="'.$OUTPUT->pix_url('t/delete') . '" class="iconsmall" '.
-           ' alt="'.$str->delete.'" /></a>'."\n".$hideshow.$groupmode."\n".$assign.'</span>';
+    $output .= html_writer::end_tag('span');
+    return $output;
 }
 
 /**
index 747bb04..aff7187 100644 (file)
--- a/index.php
+++ b/index.php
                     if (! $newsforum = forum_get_course_forum($SITE->id, 'news')) {
                         print_error('cannotfindorcreateforum', 'forum');
                     }
-                    echo html_writer::tag('a', get_string('skipa', 'access', moodle_strtolower($newsforum->name)), array('href'=>'#skipsitenews', 'class'=>'skip-block'));
+
+                    // fetch news forum context for proper filtering to happen
+                    $newsforumcm = get_coursemodule_from_instance('forum', $newsforum->id, $SITE->id, false, MUST_EXIST);
+                    $newsforumcontext = get_context_instance(CONTEXT_MODULE, $newsforumcm->id, MUST_EXIST);
+
+                    $forumname = format_string($newsforum->name, true, array('context' => $newsforumcontext));
+                    echo html_writer::tag('a', get_string('skipa', 'access', moodle_strtolower(strip_tags($forumname))), array('href'=>'#skipsitenews', 'class'=>'skip-block'));
 
                     if (isloggedin()) {
                         $SESSION->fromdiscussion = $CFG->wwwroot;
                         } else {
                             $subtext = get_string('subscribe', 'forum');
                         }
-                        echo $OUTPUT->heading($newsforum->name, 2, 'headingblock header');
+                        echo $OUTPUT->heading($forumname, 2, 'headingblock header');
                         $suburl = new moodle_url('/mod/forum/subscribe.php', array('id' => $newsforum->id, 'sesskey' => sesskey()));
                         echo html_writer::tag('div', html_writer::link($suburl, $subtext), array('class' => 'subscribelink'));
                     } else {
-                        echo $OUTPUT->heading($newsforum->name, 2, 'headingblock header');
+                        echo $OUTPUT->heading($forumname, 2, 'headingblock header');
                     }
 
                     forum_print_latest_discussions($SITE, $newsforum, $SITE->newsitems, 'plain', 'p.modified DESC');
diff --git a/install/lang/en_us/install.php b/install/lang/en_us/install.php
new file mode 100644 (file)
index 0000000..4c21e28
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Automatically generated strings for Moodle 2.2dev installer
+ *
+ * Do not edit this file manually! It contains just a subset of strings
+ * needed during the very first steps of installation. This file was
+ * generated automatically by export-installer.php (which is part of AMOS
+ * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
+ * list of strings defined in /install/stringnames.txt.
+ *
+ * @package   installer
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['welcomep50'] = 'The use of all the applications in this package is governed by their respective licenses. The complete <strong>{$a->installername}</strong> package is <a href="http://www.opensource.org/docs/definition_plain.html">open source</a> and is distributed under the <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> license.';
index 5e68e8e..df576ec 100644 (file)
@@ -115,7 +115,7 @@ $string['passwordhandling'] = 'Password field handling';
 $string['plaintext'] = 'Plain text';
 $string['pluginnotenabled'] = 'Authentication plugin \'{$a}\' is not enabled.';
 $string['pluginnotinstalled'] = 'Authentication plugin \'{$a}\' is not installed.';
-$string['potentialidps'] = 'Do you usually log in somewhere else before arriving here?<br />Choose from the following list to log in at your usual place:';
+$string['potentialidps'] = 'Log in using your account on:';
 $string['recaptcha'] = 'reCAPTCHA';
 $string['recaptcha_help'] = 'The CAPTCHA is for preventing abuse from automated programs. Simply enter the words in the box, in order and separated by a space.
 
index bc42449..667e4b2 100644 (file)
@@ -1687,7 +1687,7 @@ $capabilities = array(
     ),
     'moodle/webservice:createmobiletoken' => array(
 
-        'riskbitmask' => RISK_CONFIG | RISK_DATALOSS | RISK_SPAM | RISK_PERSONAL | RISK_XSS,
+        'riskbitmask' => RISK_SPAM | RISK_PERSONAL,
         'captype' => 'write',
         'contextlevel' => CONTEXT_SYSTEM,
         'archetypes' => array(
index db88a9e..7c9384b 100644 (file)
@@ -747,6 +747,11 @@ abstract class moodle_database {
                 if (!array_key_exists($key, $params)) {
                     throw new dml_exception('missingkeyinsql', $key, '');
                 }
+                if (strlen($key) > 30) {
+                    throw new coding_exception(
+                            "Placeholder names must be 30 characters or shorter. '" .
+                            $key . "' is too long.", $sql);
+                }
                 $finalparams[$key] = $params[$key];
             }
             if ($count != count($finalparams)) {
@@ -1595,7 +1600,9 @@ abstract class moodle_database {
      * @throws dml_exception if error
      */
     public function delete_records($table, array $conditions=null) {
-        if (is_null($conditions)) {
+        // truncate is drop/create (DDL), not transactional safe,
+        // so we don't use the shortcut within them. MDL-29198
+        if (is_null($conditions) && empty($this->transactions)) {
             return $this->execute("TRUNCATE TABLE {".$table."}");
         }
         list($select, $params) = $this->where_clause($table, $conditions);
index 2197563..943dbbb 100644 (file)
@@ -364,11 +364,23 @@ class oci_native_moodle_database extends moodle_database {
         if (empty($params)) {
             return array($sql, $params);
         }
+
         $newparams = array();
-        foreach ($params as $name=>$value) {
-            $newparams['o_'.$name] = $value;
+        $searcharr = array(); // search => replace pairs
+        foreach ($params as $name => $value) {
+            // Keep the name within the 30 chars limit always (prefixing/replacing)
+            if (strlen($name) <= 28) {
+                $newname = 'o_' . $name;
+            } else {
+                $newname = 'o_' . substr($name, 2);
+            }
+            $newparams[$newname] = $value;
+            $searcharr[':' . $name] = ':' . $newname;
         }
-        $sql = preg_replace('/:([a-z0-9_-]+[$a-z0-9_-])/', ':o_$1', $sql);
+        // sort by length desc to avoid potential str_replace() overlap
+        uksort($searcharr, array('oci_native_moodle_database', 'compare_by_length_desc'));
+
+        $sql = str_replace(array_keys($searcharr), $searcharr, $sql);
         return array($sql, $newparams);
     }
 
@@ -821,6 +833,17 @@ class oci_native_moodle_database extends moodle_database {
         return $value;
     }
 
+    /**
+     * Helper function to order by string length desc
+     *
+     * @param $a string first element to compare
+     * @param $b string second element to compare
+     * @return int < 0 $a goes first (is less), 0 $b goes first, 0 doesn't matter
+     */
+    private function compare_by_length_desc($a, $b) {
+        return strlen($b) - strlen($a);
+    }
+
     /**
      * Is db in unicode mode?
      * @return bool
@@ -1164,12 +1187,13 @@ class oci_native_moodle_database extends moodle_database {
 
         $id = null;
 
-        list($sql, $params) = $this->tweak_param_names($sql, $params);
+        // note we don't need tweak_param_names() here. Placeholders are safe column names. MDL-28080
+        // list($sql, $params) = $this->tweak_param_names($sql, $params);
         $this->query_start($sql, $params, SQL_QUERY_INSERT);
         $stmt = $this->parse_query($sql);
         $descriptors = $this->bind_params($stmt, $params, $table);
         if ($returning) {
-            oci_bind_by_name($stmt, ":o_oracle_id", $id, 10, SQLT_INT); // :o_ prefix added in tweak_param_names()
+            oci_bind_by_name($stmt, ":oracle_id", $id, 10, SQLT_INT);
         }
         $result = oci_execute($stmt, $this->commit_status);
         $this->free_descriptors($descriptors);
@@ -1276,7 +1300,8 @@ class oci_native_moodle_database extends moodle_database {
         $sql = "UPDATE {" . $table . "} SET $sets WHERE id=:id";
         list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
 
-        list($sql, $params) = $this->tweak_param_names($sql, $params);
+        // note we don't need tweak_param_names() here. Placeholders are safe column names. MDL-28080
+        // list($sql, $params) = $this->tweak_param_names($sql, $params);
         $this->query_start($sql, $params, SQL_QUERY_UPDATE);
         $stmt = $this->parse_query($sql);
         $descriptors = $this->bind_params($stmt, $params, $table);
index 7bec4a9..c9114c9 100644 (file)
@@ -465,6 +465,16 @@ class dml_test extends UnitTestCase {
             $this->fail("Unexpected ".get_class($e)." exception");
         }
 
+        // Params exceeding 30 chars length
+        $sql = "SELECT * FROM {{$tablename}} WHERE name = :long_placeholder_with_more_than_30";
+        $params = array('long_placeholder_with_more_than_30' => 'record1');
+        try {
+            $DB->fix_sql_params($sql, $params);
+            $this->fail("Expecting an exception, none occurred");
+        } catch (Exception $e) {
+            $this->assertTrue($e instanceof coding_exception);
+        }
+
         // Booleans in NAMED params are casting to 1/0 int
         $sql = "SELECT * FROM {{$tablename}} WHERE course = ? OR course = ?";
         $params = array(true, false);
@@ -493,6 +503,139 @@ class dml_test extends UnitTestCase {
         $this->assertIdentical(array_values($params), array_values($inparams));
     }
 
+    public function test_tweak_param_names() {
+        // Note the tweak_param_names() method is only available in the oracle driver,
+        // hence we look for expected results indirectly, by testing various DML methods
+        // with some "extreme" conditions causing the tweak to happen.
+        $DB = $this->tdb;
+        $dbman = $this->tdb->get_manager();
+
+        $table = $this->get_test_table();
+        $tablename = $table->getName();
+
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        // Add some columns with 28 chars in the name
+        $table->add_field('long_int_columnname_with_28c', XMLDB_TYPE_INTEGER, '10');
+        $table->add_field('long_dec_columnname_with_28c', XMLDB_TYPE_NUMBER, '10,2');
+        $table->add_field('long_str_columnname_with_28c', XMLDB_TYPE_CHAR, '100');
+        // Add some columns with 30 chars in the name
+        $table->add_field('long_int_columnname_with_30cxx', XMLDB_TYPE_INTEGER, '10');
+        $table->add_field('long_dec_columnname_with_30cxx', XMLDB_TYPE_NUMBER, '10,2');
+        $table->add_field('long_str_columnname_with_30cxx', XMLDB_TYPE_CHAR, '100');
+
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+
+        $dbman->create_table($table);
+
+        $this->assertTrue($dbman->table_exists($tablename));
+
+        // Test insert record
+        $rec1 = new stdClass();
+        $rec1->long_int_columnname_with_28c = 28;
+        $rec1->long_dec_columnname_with_28c = 28.28;
+        $rec1->long_str_columnname_with_28c = '28';
+        $rec1->long_int_columnname_with_30cxx = 30;
+        $rec1->long_dec_columnname_with_30cxx = 30.30;
+        $rec1->long_str_columnname_with_30cxx = '30';
+
+        // insert_record()
+        $rec1->id = $DB->insert_record($tablename, $rec1);
+        $this->assertEqual($rec1, $DB->get_record($tablename, array('id' => $rec1->id)));
+
+        // update_record()
+        $DB->update_record($tablename, $rec1);
+        $this->assertEqual($rec1, $DB->get_record($tablename, array('id' => $rec1->id)));
+
+        // set_field()
+        $rec1->long_int_columnname_with_28c = 280;
+        $DB->set_field($tablename, 'long_int_columnname_with_28c', $rec1->long_int_columnname_with_28c,
+            array('id' => $rec1->id, 'long_int_columnname_with_28c' => 28));
+        $rec1->long_dec_columnname_with_28c = 280.28;
+        $DB->set_field($tablename, 'long_dec_columnname_with_28c', $rec1->long_dec_columnname_with_28c,
+            array('id' => $rec1->id, 'long_dec_columnname_with_28c' => 28.28));
+        $rec1->long_str_columnname_with_28c = '280';
+        $DB->set_field($tablename, 'long_str_columnname_with_28c', $rec1->long_str_columnname_with_28c,
+            array('id' => $rec1->id, 'long_str_columnname_with_28c' => '28'));
+        $rec1->long_int_columnname_with_30cxx = 300;
+        $DB->set_field($tablename, 'long_int_columnname_with_30cxx', $rec1->long_int_columnname_with_30cxx,
+            array('id' => $rec1->id, 'long_int_columnname_with_30cxx' => 30));
+        $rec1->long_dec_columnname_with_30cxx = 300.30;
+        $DB->set_field($tablename, 'long_dec_columnname_with_30cxx', $rec1->long_dec_columnname_with_30cxx,
+            array('id' => $rec1->id, 'long_dec_columnname_with_30cxx' => 30.30));
+        $rec1->long_str_columnname_with_30cxx = '300';
+        $DB->set_field($tablename, 'long_str_columnname_with_30cxx', $rec1->long_str_columnname_with_30cxx,
+            array('id' => $rec1->id, 'long_str_columnname_with_30cxx' => '30'));
+        $this->assertEqual($rec1, $DB->get_record($tablename, array('id' => $rec1->id)));
+
+        // delete_records()
+        $rec2 = $DB->get_record($tablename, array('id' => $rec1->id));
+        $rec2->id = $DB->insert_record($tablename, $rec2);
+        $this->assertEqual(2, $DB->count_records($tablename));
+        $DB->delete_records($tablename, (array) $rec2);
+        $this->assertEqual(1, $DB->count_records($tablename));
+
+        // get_recordset()
+        $rs = $DB->get_recordset($tablename, (array) $rec1);
+        $iterations = 0;
+        foreach ($rs as $rec2) {
+            $iterations++;
+        }
+        $rs->close();
+        $this->assertEqual(1, $iterations);
+        $this->assertEqual($rec1, $rec2);
+
+        // get_records()
+        $recs = $DB->get_records($tablename, (array) $rec1);
+        $this->assertEqual(1, count($recs));
+        $this->assertEqual($rec1, reset($recs));
+
+        // get_fieldset_select()
+        $select = 'id = :id AND
+                   long_int_columnname_with_28c = :long_int_columnname_with_28c AND
+                   long_dec_columnname_with_28c = :long_dec_columnname_with_28c AND
+                   long_str_columnname_with_28c = :long_str_columnname_with_28c AND
+                   long_int_columnname_with_30cxx = :long_int_columnname_with_30cxx AND
+                   long_dec_columnname_with_30cxx = :long_dec_columnname_with_30cxx AND
+                   long_str_columnname_with_30cxx = :long_str_columnname_with_30cxx';
+        $fields = $DB->get_fieldset_select($tablename, 'long_int_columnname_with_28c', $select, (array)$rec1);
+        $this->assertEqual(1, count($fields));
+        $this->assertEqual($rec1->long_int_columnname_with_28c, reset($fields));
+        $fields = $DB->get_fieldset_select($tablename, 'long_dec_columnname_with_28c', $select, (array)$rec1);
+        $this->assertEqual($rec1->long_dec_columnname_with_28c, reset($fields));
+        $fields = $DB->get_fieldset_select($tablename, 'long_str_columnname_with_28c', $select, (array)$rec1);
+        $this->assertEqual($rec1->long_str_columnname_with_28c, reset($fields));
+        $fields = $DB->get_fieldset_select($tablename, 'long_int_columnname_with_30cxx', $select, (array)$rec1);
+        $this->assertEqual($rec1->long_int_columnname_with_30cxx, reset($fields));
+        $fields = $DB->get_fieldset_select($tablename, 'long_dec_columnname_with_30cxx', $select, (array)$rec1);
+        $this->assertEqual($rec1->long_dec_columnname_with_30cxx, reset($fields));
+        $fields = $DB->get_fieldset_select($tablename, 'long_str_columnname_with_30cxx', $select, (array)$rec1);
+        $this->assertEqual($rec1->long_str_columnname_with_30cxx, reset($fields));
+
+        // overlapping placeholders (progressive str_replace)
+        $overlapselect = 'id = :p AND
+                   long_int_columnname_with_28c = :param1 AND
+                   long_dec_columnname_with_28c = :param2 AND
+                   long_str_columnname_with_28c = :param_with_29_characters_long AND
+                   long_int_columnname_with_30cxx = :param_with_30_characters_long_ AND
+                   long_dec_columnname_with_30cxx = :param_ AND
+                   long_str_columnname_with_30cxx = :param__';
+        $overlapparams = array(
+                'p' => $rec1->id,
+                'param1' => $rec1->long_int_columnname_with_28c,
+                'param2' => $rec1->long_dec_columnname_with_28c,
+                'param_with_29_characters_long' => $rec1->long_str_columnname_with_28c,
+                'param_with_30_characters_long_' => $rec1->long_int_columnname_with_30cxx,
+                'param_' => $rec1->long_dec_columnname_with_30cxx,
+                'param__' => $rec1->long_str_columnname_with_30cxx);
+        $recs = $DB->get_records_select($tablename, $overlapselect, $overlapparams);
+        $this->assertEqual(1, count($recs));
+        $this->assertEqual($rec1, reset($recs));
+
+        // execute()
+        $DB->execute("DELETE FROM {{$tablename}} WHERE $select", (array)$rec1);
+        $this->assertEqual(0, $DB->count_records($tablename));
+    }
+
     public function test_get_tables() {
         $DB = $this->tdb;
         $dbman = $this->tdb->get_manager();
@@ -3497,6 +3640,23 @@ class dml_test extends UnitTestCase {
         $DB->insert_record($tablename, array('course' => 5, 'content' => 'hello', 'name'=>'def'));
         $DB->insert_record($tablename, array('course' => 2, 'content' => 'universe', 'name'=>'abc'));
 
+        // test grouping by expressions in the query. MDL-26819. Note that there are 4 ways:
+        // - By column position (GROUP by 1) - Not supported by mssql & oracle
+        // - By column name (GROUP by course) - Supported by all, but leading to wrong results
+        // - By column alias (GROUP by casecol) - Not supported by mssql & oracle
+        // - By complete expression (GROUP BY CASE ...) - 100% cross-db, this test checks it
+        $sql = "SELECT (CASE WHEN course = 3 THEN 1 ELSE 0 END) AS casecol,
+                       COUNT(1) AS countrecs,
+                       MAX(name) AS maxname
+                  FROM {{$tablename}}
+              GROUP BY CASE WHEN course = 3 THEN 1 ELSE 0 END
+              ORDER BY casecol DESC";
+        $result = array(
+                1 => (object)array('casecol' => 1, 'countrecs' => 2, 'maxname' => 'xyz'),
+                0 => (object)array('casecol' => 0, 'countrecs' => 2, 'maxname' => 'def'));
+        $records = $DB->get_records_sql($sql, null);
+        $this->assertEqual($result, $records);
+
         // test limits in queries with DISTINCT/ALL clauses and multiple whitespace. MDL-25268
         $sql = "SELECT   DISTINCT   course
                   FROM {{$tablename}}
@@ -3834,6 +3994,25 @@ class dml_test extends UnitTestCase {
         $transaction->allow_commit();
         $this->assertEqual(2, $DB2->count_records($tablename));
 
+        // let's try delete all is also working on (this checks MDL-29198)
+        // initially both connections see all the records in the table (2)
+        $this->assertEqual(2, $DB->count_records($tablename));
+        $this->assertEqual(2, $DB2->count_records($tablename));
+        $transaction = $DB->start_delegated_transaction();
+
+        // delete all from within transaction
+        $DB->delete_records($tablename);
+
+        // transactional $DB, sees 0 records now
+        $this->assertEqual(0, $DB->count_records($tablename));
+
+        // others ($DB2) get no changes yet
+        $this->assertEqual(2, $DB2->count_records($tablename));
+
+        // now commit and we should see changes
+        $transaction->allow_commit();
+        $this->assertEqual(0, $DB2->count_records($tablename));
+
         $DB2->dispose();
     }
 
index e2aab50..b2a619a 100644 (file)
@@ -937,6 +937,8 @@ class global_navigation extends navigation_node {
     protected $rootnodes = array();
     /** @var bool */
     protected $showemptysections = false;
+    /** @var bool */
+    protected $showcategories = null;
     /** @var array */
     protected $extendforuser = array();
     /** @var navigation_cache */
@@ -1055,14 +1057,9 @@ class global_navigation extends navigation_node {
             $limit = $CFG->navcourselimit;
         }
 
-        if (!empty($CFG->navshowcategories) && $DB->count_records('course_categories') == 1) {
-            // There is only one category so we don't want to show categories
-            $CFG->navshowcategories = false;
-        }
-
         $mycourses = enrol_get_my_courses(NULL, 'visible DESC,sortorder ASC', $limit);
         $showallcourses = (count($mycourses) == 0 || !empty($CFG->navshowallcourses));
-        $showcategories = ($showallcourses && !empty($CFG->navshowcategories));
+        $showcategories = ($showallcourses && $this->show_categories());
         $issite = ($this->page->course->id != SITEID);
         $ismycourse = (array_key_exists($this->page->course->id, $mycourses));
 
@@ -1315,6 +1312,20 @@ class global_navigation extends navigation_node {
         }
         return true;
     }
+
+    /**
+     * Returns true is courses should be shown within categories on the navigation.
+     *
+     * @return bool
+     */
+    protected function show_categories() {
+        global $CFG, $DB;
+        if ($this->showcategories === null) {
+            $this->showcategories = !empty($CFG->navshowcategories) && $DB->count_records('course_categories') > 1;
+        }
+        return $this->showcategories;
+    }
+
     /**
      * Checks the course format to see whether it wants the navigation to load
      * additional information for the course.
@@ -2154,7 +2165,7 @@ class global_navigation extends navigation_node {
         }
 
         if (!$ismycourse && !$issite && !empty($course->category)) {
-            if (!empty($CFG->navshowcategories)) {
+            if ($this->show_categories()) {
                 // We need to load the category structure for this course
                 $this->load_all_categories($course->category);
             }
index c378b62..8bb6d76 100644 (file)
@@ -373,6 +373,7 @@ class pix_icon implements renderable {
     /**
      * Constructor
      * @param string $pix short icon name
+     * @param string $alt The alt text to use for the icon
      * @param string $component component name
      * @param array $attributes html attributes
      */
index b475d8c..da23b21 100644 (file)
@@ -1004,10 +1004,16 @@ class core_renderer extends renderer_base {
     protected function render_action_link(action_link $link) {
         global $CFG;
 
+        if ($link->text instanceof renderable) {
+            $text = $this->render($link->text);
+        } else {
+            $text = $link->text;
+        }
+
         // A disabled link is rendered as formatted text
         if (!empty($link->attributes['disabled'])) {
             // do not use div here due to nesting restriction in xhtml strict
-            return html_writer::tag('span', $link->text, array('class'=>'currentlink'));
+            return html_writer::tag('span', $text, array('class'=>'currentlink'));
         }
 
         $attributes = $link->attributes;
@@ -1026,7 +1032,7 @@ class core_renderer extends renderer_base {
             }
         }
 
-        return html_writer::tag('a', $link->text, $attributes);
+        return html_writer::tag('a', $text, $attributes);
     }
 
 
index bf24fa1..b3dfef9 100644 (file)
@@ -61,7 +61,7 @@ class core_message_renderer extends plugin_renderer_base {
             $row->attributes['class'] = 'messageoutputs';
 
             // Name
-            $name = new html_table_cell($processor->name);
+            $name = new html_table_cell(get_string('pluginname', 'message_'.$processor->name));
 
             // Enable
             $enable = new html_table_cell();
index 7a2f000..1e6324d 100644 (file)
@@ -586,6 +586,7 @@ function mnet_profile_field_options() {
         'timemodified',    // will be set to relative to the host anyway
         'auth',            // going to be set to 'mnet'
         'deleted',         // we should never get deleted users sent over, but don't send this anyway
+        'confirmed',       // unconfirmed users can't log in to their home site, all remote users considered confirmed
         'password',        // no password for mnet users
         'theme',           // handled separately
         'lastip',          // will be set to relative to the host anyway
@@ -610,7 +611,6 @@ function mnet_profile_field_options() {
         'username',
         'email',
         'auth',
-        'confirmed',
         'deleted',
         'firstname',
         'lastname',
index 02a7cdc..39078d2 100644 (file)
@@ -295,7 +295,8 @@ class mnet_xmlrpc_client {
 
         // ok, it's signed, but is it signed with the right certificate ?
         // do this *after* we check for an out of date key
-        if (!openssl_verify($this->xmlrpcresponse, base64_decode($sig_parser->signature), $mnet_peer->public_key)) {
+        $verified = openssl_verify($this->xmlrpcresponse, base64_decode($sig_parser->signature), $mnet_peer->public_key);
+        if ($verified != 1) {
             $this->error[] = 'Invalid signature';
         }
 
index 60917e1..889ebc6 100644 (file)
@@ -1190,7 +1190,7 @@ class assignment_base {
         }
 
         /// Get all ppl that are allowed to submit assignments
-        list($esql, $params) = get_enrolled_sql($context, 'mod/assignment:view', $currentgroup);
+        list($esql, $params) = get_enrolled_sql($context, 'mod/assignment:submit', $currentgroup);
 
         if ($filter == self::FILTER_ALL) {
             $sql = "SELECT u.id FROM {user} u ".
diff --git a/mod/chat/gui_ajax/theme/compact/input.png b/mod/chat/gui_ajax/theme/compact/input.png
new file mode 100644 (file)
index 0000000..2d7997c
Binary files /dev/null and b/mod/chat/gui_ajax/theme/compact/input.png differ
index 7c3c8cc..8abba58 100644 (file)
@@ -280,7 +280,6 @@ $string['resettemplate'] = 'Reset template';
 $string['resizingimages'] = 'Resizing image thumbnails...';
 $string['rows'] = 'rows';
 $string['rssglobaldisabled'] = 'Disabled. See site configuration variables.';
-$string['rsshowmany'] = '(number of latest entries to show, 0 to disable RSS)';
 $string['rsstemplate'] = 'RSS template';
 $string['rsstitletemplate'] = 'RSS title template';
 $string['save'] = 'Save';
index 1d670c9..9a867e1 100644 (file)
@@ -560,7 +560,7 @@ if ($action === 'delete') {
         $table->data[] = array($fontstart.get_string("question", "lesson").": <br />".$fontend.$fontstart2.$page->contents.$fontend2, " ");
         $table->data[] = array($fontstart.get_string("answer", "lesson").":".$fontend, ' ');
         // apply the font to each answer
-        if (!empty($page->answerdata) && isset($page->answerdata->response)) {
+        if (!empty($page->answerdata)) {
             foreach ($page->answerdata->answers as $answer){
                 $modified = array();
                 foreach ($answer as $single) {
@@ -569,12 +569,12 @@ if ($action === 'delete') {
                 }
                 $table->data[] = $modified;
             }
-            if ($page->answerdata->response != NULL) {
+            if (isset($page->answerdata->response)) {
                 $table->data[] = array($fontstart.get_string("response", "lesson").": <br />".$fontend.$fontstart2.format_text($page->answerdata->response,$page->answerdata->responseformat,$formattextdefoptions).$fontend2, " ");
             }
             $table->data[] = array($page->answerdata->score, " ");
         } else {
-            $table->data[] = array(0, " ");
+            $table->data[] = array(get_string('didnotanswerquestion', 'lesson'), " ");
         }
         echo html_writer::table($table);
     }
index 5cc2f89..b770258 100644 (file)
@@ -50,7 +50,7 @@ require_login($attemptobj->get_course(), false, $attemptobj->get_cm());
 // Check that this attempt belongs to this user.
 if ($attemptobj->get_userid() != $USER->id) {
     if ($attemptobj->has_capability('mod/quiz:viewreports')) {
-        redirect($attemptobj->review_url(0, $page));
+        redirect($attemptobj->review_url(null, $page));
     } else {
         throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'notyourattempt');
     }
@@ -69,7 +69,7 @@ if (!$attemptobj->is_preview_user()) {
 
 // If the attempt is already closed, send them to the review page.
 if ($attemptobj->is_finished()) {
-    redirect($attemptobj->review_url(0, $page));
+    redirect($attemptobj->review_url(null, $page));
 }
 
 // Check the access rules.
index 15a9d8f..73a7640 100644 (file)
@@ -455,7 +455,7 @@ $questionbank->display('editq',
         $pagevars['qpage'],
         $pagevars['qperpage'],
         $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'],
-        $pagevars['showquestiontext']);
+        $pagevars['qbshowtext']);
 echo '</div>';
 echo '</div>';
 echo '</div>';
index 9f653c0..4a944da 100644 (file)
@@ -405,6 +405,8 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool,
 
     $a = '<input name="moveselectedonpagetop" type="text" size="2" ' .
         $pagingdisabled . ' />';
+    $b = '<input name="moveselectedonpagebottom" type="text" size="2" ' .
+        $pagingdisabled . ' />';
 
     $reordercontrols2top = '<div class="moveselectedonpage">' .
         get_string('moveselectedonpage', 'quiz', $a) .
@@ -415,7 +417,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool,
     $reordercontrols2bottom = '<div class="moveselectedonpage">' .
         '<input type="submit" name="savechanges" value="' .
         $strreorderquestions . '" /><br />' .
-        get_string('moveselectedonpage', 'quiz', $a) .
+        get_string('moveselectedonpage', 'quiz', $b) .
         '<input type="submit" name="savechanges" value="' .
         $strmove . '"  ' . $pagingdisabled . ' /> ' . '</div>';
 
@@ -1187,7 +1189,7 @@ class quiz_question_bank_view extends question_bank_view {
         echo '<form method="get" action="edit.php" id="displayoptions">';
         echo "<fieldset class='invisiblefieldset'>";
         echo html_writer::input_hidden_params($this->baseurl,
-                array('recurse', 'showhidden', 'showquestiontext'));
+                array('recurse', 'showhidden', 'qbshowtext'));
         $this->display_category_form_checkbox('recurse', $recurse,
                 get_string('includesubcategories', 'question'));
         $this->display_category_form_checkbox('showhidden', $showhidden,
index 9709681..20ddf69 100644 (file)
@@ -203,7 +203,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
                 quiz_get_js_module());
 
         $output = '';
-        $output .= html_writer::start_tag('form', array('action' => $attemptobj->review_url(0,
+        $output .= html_writer::start_tag('form', array('action' => $attemptobj->review_url(null,
                 $page, $showall), 'method' => 'post', 'class' => 'questionflagsaveform'));
         $output .= html_writer::start_tag('div');
         $output .= $content;
@@ -249,7 +249,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
         if ($lastpage) {
             $nav = $this->finish_review_link($attemptobj->view_url());
         } else {
-            $nav = link_arrow_right(get_string('next'), $attemptobj->review_url(0, $page + 1));
+            $nav = link_arrow_right(get_string('next'), $attemptobj->review_url(null, $page + 1));
         }
         return html_writer::tag('div', $nav, array('class' => 'submitbtns'));
     }
@@ -317,8 +317,6 @@ class mod_quiz_renderer extends plugin_renderer_base {
             $attributes[] = get_string('onthispage', 'quiz');
         }
 
-        $attributes[] = $button->statestring;
-
         // Flagged?
         if ($button->flagged) {
             $classes[] = 'flagged';
index d7875e3..93192ce 100644 (file)
@@ -620,7 +620,7 @@ class quiz_statistics_report extends quiz_default_report {
                     SUM(sumgrades) AS total
                 FROM $fromqa
                 WHERE $whereqa
-                GROUP BY attempt = 1", $qaparams);
+                GROUP BY CASE WHEN attempt = 1 THEN 1 ELSE 0 END", $qaparams);
 
         if (!$attempttotals) {
             return $this->get_emtpy_stats($questions);
index b744e05..46f0470 100644 (file)
@@ -79,7 +79,7 @@ if ($options->flags == question_display_options::EDITABLE && optional_param('sav
         PARAM_BOOL)) {
     require_sesskey();
     $attemptobj->save_question_flags();
-    redirect($attemptobj->review_url(0, $page, $showall));
+    redirect($attemptobj->review_url(null, $page, $showall));
 }
 
 // Log this review.
@@ -150,7 +150,7 @@ if (!$attemptobj->get_quiz()->showuserpicture && $attemptobj->get_userid() != $U
     );
 }
 if ($attemptobj->has_capability('mod/quiz:viewreports')) {
-    $attemptlist = $attemptobj->links_to_other_attempts($attemptobj->review_url(0, $page,
+    $attemptlist = $attemptobj->links_to_other_attempts($attemptobj->review_url(null, $page,
             $showall));
     if ($attemptlist) {
         $summarydata['attemptlist'] = array(
index 5359fe7..411cb37 100644 (file)
@@ -67,7 +67,7 @@ echo $OUTPUT->header();
 echo '<div class="questionbankwindow boxwidthwide boxaligncenter">';
 $questionbank->display('questions', $pagevars['qpage'], $pagevars['qperpage'],
         $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'],
-        $pagevars['showquestiontext']);
+        $pagevars['qbshowtext']);
 echo "</div>\n";
 
 echo $OUTPUT->footer();
index 52faf97..7b3722f 100644 (file)
@@ -1249,7 +1249,7 @@ class question_bank_view {
     protected function display_options($recurse, $showhidden, $showquestiontext) {
         echo '<form method="get" action="edit.php" id="displayoptions">';
         echo "<fieldset class='invisiblefieldset'>";
-        echo html_writer::input_hidden_params($this->baseurl, array('recurse', 'showhidden', 'showquestiontext'));
+        echo html_writer::input_hidden_params($this->baseurl, array('recurse', 'showhidden', 'qbshowtext'));
         $this->display_category_form_checkbox('recurse', $recurse, get_string('includesubcategories', 'question'));
         $this->display_category_form_checkbox('showhidden', $showhidden, get_string('showhidden', 'question'));
         $this->display_category_form_checkbox('qbshowtext', $showquestiontext, get_string('showquestiontext', 'question'));
@@ -1678,11 +1678,11 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $requirec
         $pagevars['showhidden'] = 0;
     }
 
-    if(($showquestiontext = optional_param('showquestiontext', -1, PARAM_BOOL)) != -1) {
-        $pagevars['showquestiontext'] = $showquestiontext;
-        $thispageurl->param('showquestiontext', $showquestiontext);
+    if(($showquestiontext = optional_param('qbshowtext', -1, PARAM_BOOL)) != -1) {
+        $pagevars['qbshowtext'] = $showquestiontext;
+        $thispageurl->param('qbshowtext', $showquestiontext);
     } else {
-        $pagevars['showquestiontext'] = 0;
+        $pagevars['qbshowtext'] = 0;
     }
 
     //category list page
index ca1af3a..98798b7 100644 (file)
@@ -1011,6 +1011,20 @@ class qformat_xml extends qformat_default {
         }
     }
 
+    /**
+     * Take a string, and wrap it in a CDATA secion, if that is required to make
+     * the output XML valid.
+     * @param string $string a string
+     * @return string the string, wrapped in CDATA if necessary.
+     */
+    public function xml_escape($string) {
+        if (!empty($string) && htmlspecialchars($string) != $string) {
+            return "<![CDATA[{$string}]]>";
+        } else {
+            return $string;
+        }
+    }
+
     /**
      * Generates <text></text> tags, processing raw text therein
      * @param string $raw the content to output.
@@ -1020,11 +1034,7 @@ class qformat_xml extends qformat_default {
      */
     public function writetext($raw, $indent = 0, $short = true) {
         $indent = str_repeat('  ', $indent);
-
-        // if required add CDATA tags
-        if (!empty($raw) && htmlspecialchars($raw) != $raw) {
-            $raw = "<![CDATA[$raw]]>";
-        }
+        $raw = $this->xml_escape($raw);
 
         if ($short) {
             $xml = "$indent<text>$raw</text>\n";
@@ -1467,7 +1477,7 @@ class qformat_xml extends qformat_default {
             $output .= "      <clearwrong/>\n";
         }
         if (!empty($hint->options)) {
-            $output .= '      <options>' . htmlspecialchars($hint->options) . "</options>\n";
+            $output .= '      <options>' . $this->xml_escape($hint->options) . "</options>\n";
         }
         $output .= "    </hint>\n";
         return $output;
index d12c581..f6d328d 100644 (file)
@@ -87,6 +87,9 @@ class qtype_multianswer_edit_form extends question_edit_form {
         $mform->removeElement('defaultmark');
         $this->confirm = optional_param('confirm', '0', PARAM_RAW);
 
+        // Make questiontext a required field for this question type.
+        $mform->addRule('questiontext', null, 'required', null, 'client');
+
         // display the questions from questiontext;
         if ("" != optional_param('questiontext', '', PARAM_RAW)) {
             $this->questiondisplay = fullclone(qtype_multianswer_extract_question(
index 2b04b58..e2eda32 100644 (file)
@@ -141,14 +141,14 @@ class qtype_multianswer extends question_type {
             if ($previousid != 0 && $previousid != $wrapped->id) {
                 // for some reasons a new question has been created
                 // so delete the old one
-                delete_question($previousid);
+                question_delete_question($previousid);
             }
         }
 
         // Delete redundant wrapped questions
         if (is_array($oldwrappedquestions) && count($oldwrappedquestions)) {
             foreach ($oldwrappedquestions as $oldwrappedquestion) {
-                delete_question($oldwrappedquestion->id);
+                question_delete_question($oldwrappedquestion->id);
             }
         }
 
index d127c6e..4358552 100644 (file)
@@ -940,23 +940,32 @@ class question_type {
         $qo->qtype = $question_type;
 
         foreach ($extraquestionfields as $field) {
-            $qo->$field = $format->getpath($data, array('#', $field, 0, '#'), $qo->$field);
+            $qo->$field = $format->getpath($data, array('#', $field, 0, '#'), '');
         }
 
         // run through the answers
         $answers = $data['#']['answer'];
         $a_count = 0;
-        $extraasnwersfields = $this->extra_answer_fields();
-        if (is_array($extraasnwersfields)) {
-            // TODO import the answers, with any extra data.
-        } else {
-            foreach ($answers as $answer) {
-                $ans = $format->import_answer($answer);
+        $extraanswersfields = $this->extra_answer_fields();
+        if (is_array($extraanswersfields)) {
+            array_shift($extraanswersfields);
+        }
+        foreach ($answers as $answer) {
+            $ans = $format->import_answer($answer);
+            if (!$this->has_html_answers()) {
+                $qo->answer[$a_count] = $ans->answer['text'];
+            } else {
                 $qo->answer[$a_count] = $ans->answer;
-                $qo->fraction[$a_count] = $ans->fraction;
-                $qo->feedback[$a_count] = $ans->feedback;
-                ++$a_count;
             }
+            $qo->fraction[$a_count] = $ans->fraction;
+            $qo->feedback[$a_count] = $ans->feedback;
+            if (is_array($extraanswersfields)) {
+                foreach ($extraanswersfields as $field) {
+                    $qo->{$field}[$a_count] =
+                        $format->getpath($answer, array('#', $field, 0, '#'), '');
+                }
+            }
+            ++$a_count;
         }
         return $qo;
     }
@@ -977,26 +986,29 @@ class question_type {
         array_shift($extraquestionfields);
         $expout='';
         foreach ($extraquestionfields as $field) {
-            $exportedvalue = $question->options->$field;
-            if (!empty($exportedvalue) && htmlspecialchars($exportedvalue) != $exportedvalue) {
-                $exportedvalue = '<![CDATA[' . $exportedvalue . ']]>';
-            }
+            $exportedvalue = $format->xml_escape($question->options->$field);
             $expout .= "    <$field>{$exportedvalue}</$field>\n";
         }
 
-        $extraasnwersfields = $this->extra_answer_fields();
-        if (is_array($extraasnwersfields)) {
-            // TODO export answers with any extra data
-        } else {
-            foreach ($question->options->answers as $answer) {
-                $percent = 100 * $answer->fraction;
-                $expout .= "    <answer fraction=\"$percent\">\n";
-                $expout .= $format->writetext($answer->answer, 3, false);
-                $expout .= "      <feedback>\n";
-                $expout .= $format->writetext($answer->feedback, 4, false);
-                $expout .= "      </feedback>\n";
-                $expout .= "    </answer>\n";
+        $extraanswersfields = $this->extra_answer_fields();
+        if (is_array($extraanswersfields)) {
+            array_shift($extraanswersfields);
+        }
+        foreach ($question->options->answers as $answer) {
+            $percent = 100 * $answer->fraction;
+            $expout .= "    <answer fraction=\"$percent\">\n";
+            $expout .= $format->writetext($answer->answer, 3, false);
+            $expout .= "      <feedback>\n";
+            $expout .= $format->writetext($answer->feedback, 4, false);
+            $expout .= "      </feedback>\n";
+            if (is_array($extraanswersfields)) {
+                foreach ($extraanswersfields as $field) {
+                    $exportedvalue = $format->xml_escape($answer->$field);
+                    $expout .= "      <{$field}>{$exportedvalue}</{$field}>\n";
+                }
             }
+
+            $expout .= "    </answer>\n";
         }
         return $expout;
     }
index f30b2af..2ef560c 100644 (file)
 $string['apikey'] = 'API key';
 $string['boxnet:view'] = 'View box.net repository';
 $string['configplugin'] = 'Box.net configuration';
+$string['callbackurl'] = 'Callback URL';
+$string['callbackurltext'] = '<ol>
+<li>Visit <a href="http://www.box.net/developers/services">box.net developers site</a> again.</li>
+<li>Make sure you set the callback URL of this box.net service to <strong>{$a}</strong></li></ol>';
+$string['callbackwarning'] = '<ol>
+<li>Get a <a href="http://www.box.net/developers/services">box.net API</a> from box.net for this Moodle site.</li>
+<li>Enter box.net api key here, then click Save and then come back to this page.  You will see that Moodle has generated a callback URL for you.</li>
+<li>Edit your box.net details on box.net website again and set the callback URL.</li></ol>';
+
 $string['information'] = 'Get an API key from the <a href="http://www.box.net/developers/services">Box.net developer page</a> for your Moodle site.';
 $string['invalidpassword'] = 'Invalid password';
 $string['nullfilelist'] = 'There are no files in this repository';
index b1fdda3..23ed1cc 100644 (file)
@@ -29,67 +29,55 @@ require_once($CFG->libdir.'/boxlib.php');
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class repository_boxnet extends repository {
-    private $box;
+    private $boxclient;
 
     /**
      * Constructor
-     * @global object $SESSION
      * @param int $repositoryid
      * @param object $context
      * @param array $options
      */
     public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
-        global $SESSION;
-        $options['username']   = optional_param('boxusername', '', PARAM_RAW);
-        $options['password']   = optional_param('boxpassword', '', PARAM_RAW);
-        $options['ticket']     = optional_param('ticket', '', PARAM_RAW);
-        $sess_name = 'box_token'.$this->id;
-        $this->sess_name = 'box_token'.$this->id;
         parent::__construct($repositoryid, $context, $options);
         $this->api_key = $this->get_option('api_key');
-        // do login
-        if(!empty($options['username']) && !empty($options['password']) && !empty($options['ticket']) ) {
-            $this->box = new boxclient($this->api_key);
-            try {
-                $SESSION->$sess_name = $this->box->getAuthToken($options['ticket'],
-                    $options['username'], $options['password']);
-            } catch (repository_exception $e) {
-                throw $e;
-            }
+        $this->setting_prefix = 'boxnet_';
+
+        $this->auth_token = get_user_preferences($this->setting_prefix.'_auth_token', '');
+        $this->logged = false;
+        if (!empty($this->auth_token)) {
+            $this->logged = true;
         }
         // already logged
-        if(!empty($SESSION->$sess_name)) {
-            if(empty($this->box)) {
-                $this->box = new boxclient($this->api_key, $SESSION->$sess_name);
+        if(!empty($this->logged)) {
+            if(empty($this->boxclient)) {
+                $this->boxclient = new boxclient($this->api_key, $this->auth_token);
             }
-            $this->auth_token = $SESSION->$sess_name;
         } else {
-            $this->box = new boxclient($this->api_key);
+            $this->boxclient = new boxclient($this->api_key);
         }
     }
 
     /**
-     *
-     * @global object $SESSION
+     * check if user logged
      * @return boolean
      */
     public function check_login() {
-        global $SESSION;
-        return !empty($SESSION->{$this->sess_name});
+        return $this->logged;
     }
 
     /**
+     * reset auth token
      *
-     * @global object $SESSION
      * @return string
      */
     public function logout() {
-        global $SESSION;
-        unset($SESSION->{$this->sess_name});
+        // reset auth token
+        set_user_preference($this->setting_prefix . '_auth_token', '');
         return $this->print_login();
     }
 
     /**
+     * Save settings
      *
      * @param array $options
      * @return mixed
@@ -104,6 +92,7 @@ class repository_boxnet extends repository {
     }
 
     /**
+     * Get settings
      *
      * @param string $config
      * @return mixed
@@ -119,47 +108,17 @@ class repository_boxnet extends repository {
     }
 
     /**
+     * Search files from box.net
      *
-     * @global object $SESSION
-     * @return boolean
-     */
-    public function global_search() {
-        global $SESSION;
-        if (empty($SESSION->{$this->sess_name})) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     *
-     * @global object $DB
-     * @return object
-     */
-    public function get_login() {
-        global $DB;
-        if ($entry = $DB->get_record('repository_instances', array('id'=>$this->id))) {
-            $ret->username = $entry->username;
-            $ret->password = $entry->password;
-        } else {
-            $ret->username = '';
-            $ret->password = '';
-        }
-        return $ret;
-    }
-
-    /**
-     *
-     * @global object $CFG
+     * @global object $OUTPUT
      * @param string $search_text
      * @return mixed
      */
     public function search($search_text) {
-        global $CFG, $OUTPUT;
+        global $OUTPUT;
         $list = array();
         $ret  = array();
-        $tree = $this->box->getAccountTree();
+        $tree = $this->boxclient->getAccountTree();
         if (!empty($tree)) {
             $filenames = $tree['file_name'];
             $fileids   = $tree['file_id'];
@@ -182,17 +141,16 @@ class repository_boxnet extends repository {
     }
 
     /**
+     * Get file listing
      *
-     * @global object $CFG
      * @param string $path
      * @return mixed
      */
     public function get_listing($path = '/', $page = ''){
-        global $CFG;
         $list = array();
         $ret  = array();
         $ret['list'] = array();
-        $tree = $this->box->getfiletree($path);
+        $tree = $this->boxclient->getfiletree($path);
         $ret['manage'] = 'http://www.box.net/files';
         $ret['path'] = array(array('name'=>'Root', 'path'=>0));
         if(!empty($tree)) {
@@ -202,30 +160,19 @@ class repository_boxnet extends repository {
     }
 
     /**
+     * Return login form
      *
      * @return array
      */
     public function print_login(){
-        $t = $this->box->getTicket();
-        $ret = $this->get_login();
+        $t = $this->boxclient->getTicket();
         if ($this->options['ajax']) {
-            $ticket_field->type = 'hidden';
-            $ticket_field->name = 'ticket';
-            $ticket_field->value = $t['ticket'];
-
-            $user_field->label = get_string('username', 'repository_boxnet').': ';
-            $user_field->id    = 'box_username';
-            $user_field->type  = 'text';
-            $user_field->name  = 'boxusername';
-            $user_field->value = $ret->username;
-
-            $passwd_field->label = get_string('password', 'repository_boxnet').': ';
-            $passwd_field->id    = 'box_password';
-            $passwd_field->type  = 'password';
-            $passwd_field->name  = 'boxpassword';
+            $popup_btn = new stdClass();
+            $popup_btn->type = 'popup';
+            $popup_btn->url = ' https://www.box.net/api/1.0/auth/' . $t['ticket'];
 
             $ret = array();
-            $ret['login'] = array($ticket_field, $user_field, $passwd_field);
+            $ret['login'] = array($popup_btn);
             return $ret;
         } else {
             echo '<table>';
@@ -247,11 +194,20 @@ class repository_boxnet extends repository {
         return array('api_key', 'pluginname');
     }
 
+    /**
+     * Store the auth token returned by box.net
+     */
+    public function callback() {
+        $this->auth_token  = optional_param('auth_token', '', PARAM_TEXT);
+        set_user_preference($this->setting_prefix . '_auth_token',    $this->auth_token);
+    }
+
     /**
      * Add Plugin settings input to Moodle form
      * @param object $mform
      */
     public function type_config_form($mform) {
+        global $CFG;
         parent::type_config_form($mform);
         $public_account = get_config('boxnet', 'public_account');
         $api_key = get_config('boxnet', 'api_key');
@@ -262,7 +218,27 @@ class repository_boxnet extends repository {
         $mform->addElement('text', 'api_key', get_string('apikey', 'repository_boxnet'), array('value'=>$api_key,'size' => '40'));
         $mform->addRule('api_key', $strrequired, 'required', null, 'client');
         $mform->addElement('static', null, '',  get_string('information','repository_boxnet'));
+
+        //retrieve the flickr instances
+        $params = array();
+        $params['context'] = array();
+        //$params['currentcontext'] = $this->context;
+        $params['onlyvisible'] = false;
+        $params['type'] = 'boxnet';
+        $instances = repository::get_instances($params);
+        if (empty($instances)) {
+            $callbackurl = get_string('callbackwarning', 'repository_boxnet');
+            $mform->addElement('static', null, '',  $callbackurl);
+        } else {
+            $instance = array_shift($instances);
+            $callbackurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$instance->id;
+            $mform->addElement('static', 'callbackurl', '', get_string('callbackurltext', 'repository_boxnet', $callbackurl));
+        }
     }
+    /**
+     * Box.net supports file linking and copying
+     * @return string
+     */
     public function supported_returntypes() {
         return FILE_INTERNAL | FILE_EXTERNAL;
     }
index ed5de00..d243b1b 100644 (file)
@@ -56,7 +56,12 @@ $string['choosereadme'] = '
         <p>This, and all other themes included in the Moodle core, are licensed under the <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License</a>.
     </div>
 </div>';
+$string['creditstomoodleorg'] = 'Display credits to moodle.org';
+$string['creditstomoodleorgdesc'] = 'Display the usual small moodle logo at the bottom of the page';
 $string['configtitle'] = 'Formal white theme';
+$string['ctmo_no'] = 'never'; // ctmo == credits to moodle org
+$string['ctmo_onfrontpageonly'] = 'in the front page only'; // ctmo == credits to moodle org
+$string['ctmo_ineverypage'] = 'in every page'; // ctmo == credits to moodle org
 $string['customcss'] = 'Custom CSS';
 $string['customcssdesc'] = 'Any CSS you enter here will be added to every page allowing your to easily customise this theme.';
 $string['displaylogo'] = 'Pages header content';
@@ -65,13 +70,15 @@ $string['fontsizereference'] = 'Font size reference';
 $string['fontsizereferencedesc'] = 'This allows you to set the default font size for this theme. It is not recommended to set this higher than 13px as it is known to cause display problems with certain blocks.';
 $string['footnote'] = 'Footnote';
 $string['footnotedesc'] = 'The content from this textarea will be displayed in the footer of every page.';
+$string['frontpagelogo'] = 'Custom front page logo';
+$string['frontpagelogodesc'] = 'Change the logo that is displayed on the front page of your site by entering the URL to the image you wish to use (i.e. http://www.yoursite.local/myfrontpagelogo.png). This setting overrides the custom logo setting. As a reference the default logo is 300px wide, 80px high and a transparent png will work best.';
 $string['headerbgc'] = 'Header background colour';
 $string['headerbgcdesc'] = 'This sets the blocks header background colour for the theme.';
 $string['heading'] = 'Display page heading';
 $string['lblockcolumnbgc'] = 'Left column background colour';
 $string['lblockcolumnbgcdesc'] = 'This sets the left column background colour for the theme.';
-$string['logo'] = 'logo';
-$string['logodesc'] = 'Change the logo of this theme by entering the URL to a new one (i.e., http://www.somesite/animage.png). As a reference, the default logo is 300px wide by 80px high. A transparent .png will work best.<br />The chosen logo will be shown in each page of the site without any distinction between front page and other pages.';
+$string['logo'] = 'Custom logo';
+$string['logodesc'] = 'Change the logo for this theme by entering the URL to an image you wish to use (i.e. http://www.yoursite.local/mylogo.png). As a reference the default logo is 200px wide, 50px high and a transparent png will work best.';
 $string['moodlelogo'] = 'Display moodle logo';
 $string['noframe'] = 'Formal white 1.9 look';
 $string['noframedesc'] = 'Select this option to require your moodle page to look like moodle 1.*, alias, without the surrounding frame.';
index 2c0cd10..4105a29 100644 (file)
@@ -29,7 +29,9 @@ if ($hascustommenu) {
 }
 
 /************************************************************************************************/
-if (!empty($PAGE->theme->settings->logo)) {
+if (!empty($PAGE->theme->settings->frontpagelogo)) {
+    $logourl = $PAGE->theme->settings->frontpagelogo;
+} else if (!empty($PAGE->theme->settings->logo)) {
     $logourl = $PAGE->theme->settings->logo;
 } else {
     $logourl = $OUTPUT->pix_url('logo', 'theme');
@@ -200,8 +202,10 @@ if ($hasfooter) {
     } ?>
             <div class="moodledocsleft">
             <?php
-                //echo $OUTPUT->login_info();
-                //echo $OUTPUT->home_link();
+                echo $OUTPUT->login_info();
+                if ($PAGE->theme->settings->creditstomoodleorg) {
+                    echo $OUTPUT->home_link();
+                }
                 echo $OUTPUT->standard_footer_html();
             ?>
             </div>
index 6b62aee..8d0a497 100644 (file)
@@ -198,14 +198,29 @@ if ($hasfooter) {
     } ?>
             <div class="moodledocsleft">
             <?php
-                //echo $OUTPUT->login_info();
+                echo $OUTPUT->login_info();
                 //echo $OUTPUT->home_link();
+            ?>
+                <div class="moodledocs">
+                    <?php echo page_doc_link(get_string('moodledocslink')); ?>
+                </div>
+            <?php
+                if ($PAGE->theme->settings->creditstomoodleorg == 2) {
+                    // can not use $OUTPUT->home_link() here because whether $OUTPUT->page->pagetype != 'site-index'
+                    // the output of the function is not the classic nice moodle logo $this->pix_url('moodlelogo')
+            ?>
+                    <div class="sitelink">
+                        <a title="Moodle" href="http://moodle.org/">
+                            <img style="width:100px;height:30px" src="<?php echo $this->pix_url('moodlelogo') ?>" alt="moodlelogo" />
+                        </a>
+                    </div>
+            <?php
+                }
+            ?>
+            <?php                   
                 echo $OUTPUT->standard_footer_html();
             ?>
             </div>
-            <div class="moodledocs">
-                <?php echo page_doc_link(get_string('moodledocslink')); ?>
-            </div>
         </div> <!-- end of page-footer or page-footer_noframe -->
 <?php   //the waiting div has been closed
 }
index 13ad0b5..2869b80 100644 (file)
@@ -21,7 +21,7 @@ function formal_white_user_settings($css, $theme) {
 
     // Set the page header background color
     if (empty($theme->settings->headerbgc)) {
-        $headerbgc = '#E3DFD4'; // default 
+        $headerbgc = '#E3DFD4'; // default
     } else {
         $headerbgc = $theme->settings->headerbgc;
     }
@@ -124,5 +124,4 @@ function formal_white_set_customcss($css, $customcss) {
     $tag = '[[setting:customcss]]';
     $css = str_replace($tag, $customcss, $css);
     return $css;
-}
-
+}
\ No newline at end of file
index 64826cb..a12cce8 100644 (file)
@@ -29,11 +29,11 @@ if ($ADMIN->fulltree) {
     $title = get_string('displaylogo','theme_formal_white');
     $description = get_string('displaylogodesc', 'theme_formal_white');
     $default = '1';
-    $choices = array(1=>get_string('moodlelogo', 'theme_formal_white'),0=>get_string('heading', 'theme_formal_white'));
+    $choices = array(1=>get_string('moodlelogo', 'theme_formal_white'), 0=>get_string('heading', 'theme_formal_white'));
     $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);
     $settings->add($setting);
 
-    // Logo file setting
+    // Custom site logo setting
     $name = 'theme_formal_white/logo';
     $title = get_string('logo','theme_formal_white');
     $description = get_string('logodesc', 'theme_formal_white');
@@ -41,6 +41,14 @@ if ($ADMIN->fulltree) {
     $setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_URL);
     $settings->add($setting);
 
+    // Custom front page site logo setting
+    $name = 'theme_formal_white/frontpagelogo';
+    $title = get_string('frontpagelogo','theme_formal_white');
+    $description = get_string('frontpagelogodesc', 'theme_formal_white');
+    $default = '';
+    $setting = new admin_setting_configtext($name, $title, $description, $default, PARAM_URL);
+    $settings->add($setting);
+
     // page header background colour setting
     $name = 'theme_formal_white/headerbgc';
     $title = get_string('headerbgc','theme_formal_white');
@@ -50,6 +58,24 @@ if ($ADMIN->fulltree) {
     $setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);
     $settings->add($setting);
 
+    // creditstomoodleorg: ctmo
+    $name = 'theme_formal_white/creditstomoodleorg';
+    $title = get_string('creditstomoodleorg','theme_formal_white');
+    $description = get_string('creditstomoodleorgdesc', 'theme_formal_white');
+    $default = '2';
+    $choices = array(2 => get_string('ctmo_ineverypage', 'theme_formal_white'), 1 => get_string('ctmo_onfrontpageonly', 'theme_formal_white'), 0 => get_string('ctmo_no', 'theme_formal_white'));
+    $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);
+    $settings->add($setting);
+
+    // Block region width
+    $name = 'theme_formal_white/blockcolumnwidth';
+    $title = get_string('blockcolumnwidth','theme_formal_white');
+    $description = get_string('blockcolumnwidthdesc', 'theme_formal_white');
+    $default = '200';
+    $choices = array(150=>'150px', 170=>'170px', 200=>'200px', 240=>'240px', 290=>'290px', 350=>'350px', 420=>'420px');
+    $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);
+    $settings->add($setting);
+
     // Block content background colour setting
     $name = 'theme_formal_white/blockcontentbgc';
     $title = get_string('blockcontentbgc','theme_formal_white');
@@ -77,15 +103,6 @@ if ($ADMIN->fulltree) {
     $setting = new admin_setting_configcolourpicker($name, $title, $description, $default, $previewconfig);
     $settings->add($setting);
 
-    // Block region width
-    $name = 'theme_formal_white/blockcolumnwidth';
-    $title = get_string('blockcolumnwidth','theme_formal_white');
-    $description = get_string('blockcolumnwidthdesc', 'theme_formal_white');
-    $default = '200';
-    $choices = array(150=>'150px', 170=>'170px', 200=>'200px', 240=>'240px', 290=>'290px', 350=>'350px', 420=>'420px');
-    $setting = new admin_setting_configselect($name, $title, $description, $default, $choices);
-    $settings->add($setting);
-
     // Foot note setting
     $name = 'theme_formal_white/footnote';
     $title = get_string('footnote','theme_formal_white');
index b458b4e..33f2e02 100644 (file)
@@ -25,9 +25,9 @@ h2.main, h3.main, h4.main {margin:0;padding:0;text-align: center;}
 h1.headerheading {margin:14px 11px 8px 11px;float:left;font-size:200%;}
 
 /* headermenu */
-#page-header{line-height:0;}
+#page-header{line-height:0;overflow:hidden;}
 /*#headerlogo img {margin:7px;}*/
-.headermenu {position:relative;line-height:1.7em;font-size:90%;margin:0.3em 0.3em 0 0;right:0.3em;margin-bottom:0.3em;}
+.headermenu {position:relative;line-height:1.7em;font-size:90%;margin:0.3em 0.3em 0.3em 0;right:0.3em;}
 
 #dock {background-color:[[setting:blockcontentbgc]];border-right:1px #000 dashed;}
 #dock .dockeditem_container {margin-top: 10px;}
@@ -45,16 +45,16 @@ h1.headerheading {margin:14px 11px 8px 11px;float:left;font-size:200%;}
 .navbutton table td {padding:0;}
 
 /*.block_navigation .block_tree li.type_category.contains_branch>p span {
-       padding-left: 20px;
-       background-image: url([[pix:theme|folderopen]]);
-       background-repeat: no-repeat;
-       background-position: 0 -1px;
+    padding-left: 20px;
+    background-image: url([[pix:theme|folderopen]]);
+    background-repeat: no-repeat;
+    background-position: 0 -1px;
 }
 .block_navigation .block_tree li.type_category.contains_branch.collapsed>p span {
-       padding-left: 20px;
-       background-image: url([[pix:theme|folderclose]]);
-       background-repeat: no-repeat;
-       background-position: 0 -1px;
+    padding-left: 20px;
+    background-image: url([[pix:theme|folderclose]]);
+    background-repeat: no-repeat;
+    background-position: 0 -1px;
 }*/
 
 .block_settings .block_tree .tree_item a:link,
index d4da06e..db94755 100644 (file)
@@ -101,11 +101,11 @@ div.yui3-menu-content {
 
 /* cancellazione della bordatura superiore alla lista delle voci di menu */
 .yui3-skin-sam .yui3-menu .yui3-menu {
-       border-top:none;
-       padding-left:-1px;
-       border-right:1px #CCC solid;
-       border-bottom:1px #CCC solid;
-       border-left:1px #CCC solid;
+    border-top:none;
+    padding-left:-1px;
+    border-right:1px #CCC solid;
+    border-bottom:1px #CCC solid;
+    border-left:1px #CCC solid;
 }
 
 /* color of selected item in FF */
index 4ac03b0..525979b 100644 (file)
@@ -353,7 +353,12 @@ abstract class user_selector_base {
      */
     protected function load_selected_users() {
         // See if we got anything.
-        $userids = optional_param_array($this->name, array(), PARAM_INTEGER);
+        if (isset($_REQUEST[$this->name]) && is_array($_REQUEST[$this->name])) {
+            $userids = optional_param_array($this->name, array(), PARAM_INTEGER);
+        } else {
+            $userids = optional_param($this->name, 0, PARAM_INTEGER);
+        }
+
         if (empty($userids)) {
             return array();
         }
index f12914d..deb7fdf 100644 (file)
@@ -31,10 +31,10 @@ defined('MOODLE_INTERNAL') || die();
 
 
 
-$version  = 2011082600.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2011083100.01;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes
 
-$release  = '2.2dev (Build: 20110826)'; // Human-friendly version name
+$release  = '2.2dev (Build: 20110831)'; // Human-friendly version name
 
 $maturity = MATURITY_ALPHA;             // this version's maturity level