Merge branch 'MDL-30431_wiki_comments' of https://github.com/andyjdavis/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 15 Jul 2014 23:16:04 +0000 (01:16 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 15 Jul 2014 23:16:04 +0000 (01:16 +0200)
406 files changed:
admin/cli/install.php
admin/roles/classes/capability_table_base.php
admin/roles/module.js
admin/roles/override.php
admin/settings/users.php
admin/tests/behat/behat_admin.php
admin/tests/behat/set_admin_settings_value.feature [new file with mode: 0644]
admin/tool/behat/tests/behat/manipulate_forms.feature
admin/tool/installaddon/lang/en/tool_installaddon.php
admin/tool/log/classes/helper/buffered_writer.php
admin/tool/log/store/database/tests/store_test.php
admin/tool/log/store/standard/tests/store_test.php
admin/tool/task/scheduledtasks.php
admin/tool/uploaduser/index.php
admin/tool/uploaduser/user_form.php
admin/user.php
auth/cas/auth.php
auth/email/auth.php
auth/ldap/auth.php
auth/ldap/tests/plugin_test.php
auth/shibboleth/index.php
backup/util/dbops/backup_controller_dbops.class.php
backup/util/helper/backup_cron_helper.class.php
badges/badge.php
badges/edit_form.php
badges/external.php
badges/renderer.php
blocks/navigation/tests/behat/expand_my_courses_setting.feature
blog/edit.php
blog/edit_form.php
blog/external_blog_edit.php
blog/external_blog_edit_form.php
blog/external_blogs.php
blog/index.php
blog/lib.php
blog/locallib.php
blog/preferences.php
blog/preferences_form.php
blog/renderer.php
blog/rsslib.php
blog/tests/bloglib_test.php
cache/classes/store.php
cache/stores/memcache/addinstanceform.php
cache/stores/memcache/lang/en/cachestore_memcache.php
cache/stores/memcache/lib.php
cache/stores/memcache/settings.php
cache/stores/memcache/tests/memcache_test.php
cache/stores/memcached/addinstanceform.php
cache/stores/memcached/lang/en/cachestore_memcached.php
cache/stores/memcached/lib.php
cache/stores/memcached/settings.php
cache/stores/memcached/tests/memcached_test.php
cache/stores/mongodb/lib.php
cache/stores/mongodb/tests/mongodb_test.php
cache/tests/fixtures/stores.php
calendar/event_form.php
calendar/lib.php
calendar/renderer.php
calendar/set.php
calendar/tests/lib_test.php
calendar/yui/build/moodle-calendar-eventmanager/moodle-calendar-eventmanager-debug.js
calendar/yui/build/moodle-calendar-eventmanager/moodle-calendar-eventmanager-min.js
calendar/yui/build/moodle-calendar-eventmanager/moodle-calendar-eventmanager.js
calendar/yui/src/eventmanager/js/eventmanager.js
course/delete_category_form.php [deleted file]
course/edit.php
course/editcategory_form.php [deleted file]
course/manage.php [deleted file]
course/management.php
course/tests/behat/behat_course.php
course/tests/behat/category_change_visibility.feature
course/tests/behat/category_management.feature
course/tests/behat/category_resort.feature
course/tests/behat/course_category_management_listing.feature
course/tests/behat/course_change_visibility.feature
course/tests/behat/course_resort.feature
course/tests/behat/create_delete_course.feature
enrol/meta/tests/plugin_test.php
files/renderer.php
filter/activitynames/filter.php
filter/emoticon/tests/filter_test.php
grade/edit/scale/edit_form.php
grade/edit/tree/category_form.php
grade/grading/form/guide/guideeditor.php
grade/grading/form/guide/js/guide.js
grade/grading/form/guide/js/guideeditor.js
grade/grading/form/guide/lib.php
grade/grading/form/guide/renderer.php
grade/grading/form/rubric/js/rubriceditor.js
grade/grading/form/rubric/renderer.php
grade/grading/form/rubric/rubriceditor.php
group/autogroup.php
group/autogroup_form.php
group/lib.php
group/tests/behat/auto_creation.feature
install.php
install/lang/eo/langconfig.php [moved from lib/editor/tinymce/plugins/dragmath/version.php with 63% similarity]
install/lang/pt/error.php
install/lang/sr_cr/install.php
install/lang/sr_lt/install.php
lang/en/admin.php
lang/en/cache.php
lang/en/calendar.php
lang/en/group.php
lang/en/message.php
lang/en/moodle.php
lang/en/plagiarism.php
lang/en/plugin.php
lang/en/repository.php
lib/accesslib.php
lib/authlib.php
lib/classes/event/recent_activity_viewed.php
lib/classes/event/user_created.php
lib/classes/event/user_login_failed.php
lib/classes/event/user_updated.php
lib/classes/plugin_manager.php
lib/classes/session/manager.php
lib/classes/task/adhoc_task.php
lib/classes/task/manager.php
lib/classes/text.php
lib/completionlib.php
lib/db/caches.php
lib/db/install.xml
lib/db/upgrade.php
lib/ddl/mssql_sql_generator.php
lib/ddl/tests/ddl_test.php
lib/dragmath/COPYRIGHT.html [deleted file]
lib/dragmath/README.html [deleted file]
lib/dragmath/Version History.html [deleted file]
lib/dragmath/applet/Config.xml [deleted file]
lib/dragmath/applet/Display/MainApplet.class [deleted file]
lib/dragmath/applet/DragMath.jar [deleted file]
lib/dragmath/applet/formats/ASCIIMathML.xml [deleted file]
lib/dragmath/applet/formats/Latex.xml [deleted file]
lib/dragmath/applet/formats/Maple.xml [deleted file]
lib/dragmath/applet/formats/MathML.xml [deleted file]
lib/dragmath/applet/formats/Maxima.xml [deleted file]
lib/dragmath/applet/formats/MoodleTex.xml [deleted file]
lib/dragmath/applet/formats/Tex.xml [deleted file]
lib/dragmath/applet/lang/ca.xml [deleted file]
lib/dragmath/applet/lang/cz.xml [deleted file]
lib/dragmath/applet/lang/de.xml [deleted file]
lib/dragmath/applet/lang/en.xml [deleted file]
lib/dragmath/applet/lang/es.xml [deleted file]
lib/dragmath/applet/lang/fa.xml [deleted file]
lib/dragmath/applet/lang/fi.xml [deleted file]
lib/dragmath/applet/lang/fr.xml [deleted file]
lib/dragmath/applet/lang/it.xml [deleted file]
lib/dragmath/applet/lang/nl.xml [deleted file]
lib/dragmath/applet/lang/no.xml [deleted file]
lib/dragmath/applet/lang/pl.xml [deleted file]
lib/dragmath/applet/lang/pt-br.xml [deleted file]
lib/dragmath/applet/lang/ru.xml [deleted file]
lib/dragmath/applet/lang/sv.xml [deleted file]
lib/dragmath/applet/lib/AbsoluteLayout.jar [deleted file]
lib/dragmath/applet/lib/jdom.jar [deleted file]
lib/dragmath/applet/lib/jep.jar [deleted file]
lib/dragmath/applet/lib/swing-layout-1.0.jar [deleted file]
lib/dragmath/doc/about.html [deleted file]
lib/dragmath/doc/acknowledgments.html [deleted file]
lib/dragmath/doc/browser.html [deleted file]
lib/dragmath/doc/complex.html [deleted file]
lib/dragmath/doc/cvs.html [deleted file]
lib/dragmath/doc/editing.html [deleted file]
lib/dragmath/doc/img/plus.jpg [deleted file]
lib/dragmath/doc/img/sin on box.jpg [deleted file]
lib/dragmath/doc/img/sin on plus.jpg [deleted file]
lib/dragmath/doc/img/sin.jpg [deleted file]
lib/dragmath/doc/index.html [deleted file]
lib/dragmath/doc/integrations.html [deleted file]
lib/dragmath/doc/language.html [deleted file]
lib/dragmath/doc/navframe.html [deleted file]
lib/dragmath/doc/newformat.html [deleted file]
lib/dragmath/doc/newobject.html [deleted file]
lib/dragmath/doc/options.html [deleted file]
lib/dragmath/doc/parameters.html [deleted file]
lib/dragmath/doc/simple.html [deleted file]
lib/dragmath/readme_moodle.txt [deleted file]
lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-debug.js
lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button-min.js
lib/editor/atto/plugins/collapse/yui/build/moodle-atto_collapse-button/moodle-atto_collapse-button.js
lib/editor/atto/plugins/collapse/yui/src/button/js/button.js
lib/editor/tinymce/db/upgrade.php
lib/editor/tinymce/plugins/dragmath/dragmath.php [deleted file]
lib/editor/tinymce/plugins/dragmath/lang/en/tinymce_dragmath.php [deleted file]
lib/editor/tinymce/plugins/dragmath/lib.php [deleted file]
lib/editor/tinymce/plugins/dragmath/pix/icon.png [deleted file]
lib/editor/tinymce/plugins/dragmath/settings.php [deleted file]
lib/editor/tinymce/plugins/dragmath/tinymce/editor_plugin.js [deleted file]
lib/editor/tinymce/plugins/dragmath/tinymce/img/dragmath.png [deleted file]
lib/editor/tinymce/plugins/dragmath/tinymce/js/dragmath.js [deleted file]
lib/editor/tinymce/upgrade.txt
lib/editor/tinymce/version.php
lib/enrollib.php
lib/form/editor.php
lib/form/filemanager.js
lib/form/filemanager.php
lib/grade/tests/grade_scale_test.php
lib/graphlib.php
lib/htmlpurifier/locallib.php
lib/modinfolib.php
lib/moodlelib.php
lib/outputcomponents.php
lib/outputfactories.php
lib/outputrenderers.php
lib/phpunit/classes/util.php
lib/phpunit/tests/advanced_test.php
lib/questionlib.php
lib/sessionlib.php
lib/setup.php
lib/testing/classes/util.php
lib/testing/generator/data_generator.php
lib/tests/behat/behat_hooks.php
lib/tests/fixtures/test_renderer_factory.php [new file with mode: 0644]
lib/tests/htmlpurifier_test.php
lib/tests/moodlelib_test.php
lib/tests/outputfactories_test.php [new file with mode: 0644]
lib/tests/session_manager_test.php
lib/tests/sessionlib_test.php [new file with mode: 0644]
lib/tests/text_test.php
lib/thirdpartylibs.xml
lib/upgrade.txt
lib/weblib.php
lib/yui/build/moodle-core-notification-ajaxexception/moodle-core-notification-ajaxexception-debug.js
lib/yui/build/moodle-core-notification-ajaxexception/moodle-core-notification-ajaxexception-min.js
lib/yui/build/moodle-core-notification-ajaxexception/moodle-core-notification-ajaxexception.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js
lib/yui/build/moodle-core-notification-exception/moodle-core-notification-exception-debug.js
lib/yui/build/moodle-core-notification-exception/moodle-core-notification-exception-min.js
lib/yui/build/moodle-core-notification-exception/moodle-core-notification-exception.js
lib/yui/src/notification/js/ajaxexception.js
lib/yui/src/notification/js/exception.js
lib/yui/src/notification/meta/notification.json
login/change_password.php
login/index.php
login/lib.php
message/lib.php
mod/assign/gradingtable.php
mod/assign/lang/en/assign.php
mod/assign/lib.php
mod/assign/locallib.php
mod/assign/renderer.php
mod/assign/tests/lib_test.php
mod/assign/tests/locallib_test.php
mod/data/lib.php
mod/data/rsslib.php
mod/feedback/item/textarea/lib.php
mod/feedback/item/textfield/lib.php
mod/forum/classes/event/subscription_created.php
mod/forum/classes/event/subscription_deleted.php
mod/forum/classes/event/user_report_viewed.php
mod/forum/classes/post_form.php
mod/forum/lib.php
mod/forum/tests/behat/separate_group_discussions.feature [new file with mode: 0644]
mod/forum/tests/behat/separate_group_single_group_discussions.feature [new file with mode: 0644]
mod/forum/tests/events_test.php
mod/glossary/deleteentry.php
mod/glossary/rsslib.php
mod/imscp/locallib.php
mod/lti/db/install.xml
mod/lti/db/upgrade.php
mod/lti/return.php
mod/lti/service.php
mod/lti/upgrade.txt
mod/lti/version.php
mod/quiz/attemptlib.php
mod/quiz/backup/moodle2/backup_quiz_stepslib.php
mod/quiz/db/install.xml
mod/quiz/db/upgrade.php
mod/quiz/editlib.php
mod/quiz/lang/en/quiz.php
mod/quiz/lib.php
mod/quiz/locallib.php
mod/quiz/mod_form.php
mod/quiz/renderer.php
mod/quiz/report/attemptsreport_form.php
mod/quiz/report/attemptsreport_options.php
mod/quiz/report/attemptsreport_table.php
mod/quiz/report/overview/lang/en/quiz_overview.php
mod/quiz/report/overview/overview_form.php
mod/quiz/report/overview/overview_options.php
mod/quiz/report/overview/report.php
mod/quiz/report/overview/tests/report_test.php [new file with mode: 0644]
mod/quiz/report/reportlib.php
mod/quiz/review.php
mod/quiz/styles.css
mod/quiz/tests/attempt_test.php [new file with mode: 0644]
mod/quiz/tests/behat/completion_condition_attempts_used.feature [new file with mode: 0644]
mod/quiz/tests/behat/completion_condition_passing_grade.feature [new file with mode: 0644]
mod/quiz/tests/reportlib_test.php
mod/quiz/version.php
mod/scorm/datamodels/aicc.js [moved from mod/scorm/datamodels/aicc.js.php with 81% similarity]
mod/scorm/datamodels/aicc.php [new file with mode: 0644]
mod/scorm/datamodels/aicclib.php
mod/scorm/datamodels/debug.js.php
mod/scorm/datamodels/scorm_12.js [moved from mod/scorm/datamodels/scorm_12.js.php with 75% similarity]
mod/scorm/datamodels/scorm_12.php [new file with mode: 0644]
mod/scorm/datamodels/scorm_12lib.php
mod/scorm/datamodels/scorm_13.js [moved from mod/scorm/datamodels/scorm_13.js.php with 87% similarity]
mod/scorm/datamodels/scorm_13.php [new file with mode: 0644]
mod/scorm/datamodels/scorm_13lib.php
mod/scorm/loaddatamodel.php [deleted file]
mod/scorm/locallib.php
mod/scorm/module.js
mod/scorm/player.php
mod/scorm/version.php
mod/survey/classes/event/report_downloaded.php
mod/survey/classes/event/report_viewed.php
mod/survey/report.php
notes/delete.php
notes/edit.php
notes/index.php
phpunit.xml.dist
question/category_class.php
question/classes/bank/action_column_base.php [new file with mode: 0644]
question/classes/bank/checkbox_column.php [new file with mode: 0644]
question/classes/bank/column_base.php [new file with mode: 0644]
question/classes/bank/copy_action_column.php [new file with mode: 0644]
question/classes/bank/creator_name_column.php [new file with mode: 0644]
question/classes/bank/delete_action_column.php [new file with mode: 0644]
question/classes/bank/edit_action_column.php [new file with mode: 0644]
question/classes/bank/modifier_name_column.php [new file with mode: 0644]
question/classes/bank/preview_action_column.php [new file with mode: 0644]
question/classes/bank/question_name_column.php [new file with mode: 0644]
question/classes/bank/question_text_row.php [new file with mode: 0644]
question/classes/bank/question_type_column.php [new file with mode: 0644]
question/classes/bank/row_base.php [new file with mode: 0644]
question/classes/bank/search/category_condition.php
question/classes/bank/view.php [new file with mode: 0644]
question/edit.php
question/editlib.php
question/engine/bank.php
question/engine/datalib.php
question/engine/lib.php
question/engine/questionattempt.php
question/engine/questionusage.php
question/engine/tests/helpers.php
question/export.php
question/export_form.php
question/format.php
question/format/blackboard_six/formatbase.php
question/format/gift/format.php
question/format/webct/format.php
question/format/xhtml/format.php
question/format/xml/format.php
question/import_form.php
question/previewlib.php
question/question.php
question/tests/behat/behat_question.php
question/tests/behat/question_categories.feature
question/type/calculated/datasetdefinitions_form.php
question/type/calculated/datasetitems_form.php
question/type/calculated/edit_calculated_form.php
question/type/calculated/question.php
question/type/calculated/questiontype.php
question/type/calculated/tests/formula_validation_test.php [new file with mode: 0644]
question/type/calculatedmulti/edit_calculatedmulti_form.php
question/type/calculatedmulti/questiontype.php
question/type/calculatedsimple/edit_calculatedsimple_form.php
question/type/calculatedsimple/questiontype.php
question/type/edit_question_form.php
question/type/essay/db/upgrade.php
question/type/match/question.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/questiontype.php
question/type/numerical/edit_numerical_form.php
question/type/numerical/questiontype.php
question/type/questiontypebase.php
question/type/random/questiontype.php
question/type/randomsamatch/questiontype.php
question/type/shortanswer/edit_shortanswer_form.php
question/upgrade.txt
report/log/classes/renderer.php
report/log/classes/table_log.php
report/loglive/classes/renderer.php
report/loglive/classes/renderer_ajax.php
report/outline/classes/event/activity_report_viewed.php
report/outline/classes/event/report_viewed.php
repository/coursefiles/lib.php
repository/equella/callback.php
repository/equella/lib.php
repository/filepicker.js
repository/filepicker.php
repository/lib.php
repository/local/lib.php
repository/recent/lib.php
repository/repository_ajax.php
repository/upgrade.txt
repository/user/lib.php
theme/base/style/core.css
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/less/moodle/filemanager.less
theme/bootstrapbase/less/moodle/modules.less
theme/bootstrapbase/renderers/core_renderer.php
theme/bootstrapbase/style/moodle.css
theme/upgrade.txt
user/edit.php
user/editadvanced.php
user/editlib.php
user/externallib.php
user/lib.php
user/profile.php
user/tests/userlib_test.php
version.php

index df61269..9bb207a 100644 (file)
@@ -201,17 +201,9 @@ if (defined('COMPONENT_CLASSLOADER')) {
 require($CFG->dirroot.'/version.php');
 $CFG->target_release = $release;
 
-$_SESSION = array();
-$_SESSION['SESSION'] = new stdClass();
-$_SESSION['SESSION']->lang = $CFG->lang;
-$_SESSION['USER'] = new stdClass();
-$_SESSION['USER']->id = 0;
-$_SESSION['USER']->mnethostid = 1;
-
+\core\session\manager::init_empty_session();
 global $SESSION;
 global $USER;
-$SESSION = &$_SESSION['SESSION'];
-$USER    = &$_SESSION['USER'];
 
 global $COURSE;
 $COURSE = new stdClass();
index 11cadee..b46c137 100644 (file)
@@ -74,8 +74,16 @@ abstract class core_role_capability_table_base {
     public function display() {
         if (count($this->capabilities) > self::NUM_CAPS_FOR_SEARCH) {
             global $PAGE;
-            $PAGE->requires->strings_for_js(array('filter', 'clear'), 'moodle');
-            $PAGE->requires->js_init_call('M.core_role.init_cap_table_filter', array($this->id, $this->context->id));
+            $jsmodule = array(
+                'name' => 'rolescapfilter',
+                'fullpath' => '/admin/roles/module.js',
+                'strings' => array(
+                    array('filter', 'moodle'),
+                    array('clear', 'moodle'),                ),
+                'requires' => array('node', 'cookie', 'escape')
+            );
+            $PAGE->requires->js_init_call('M.core_role.init_cap_table_filter', array($this->id, $this->context->id), false,
+                $jsmodule);
         }
         echo '<table class="' . implode(' ', $this->classes) . '" id="' . $this->id . '">' . "\n<thead>\n";
         echo '<tr><th class="name" align="left" scope="col">' . get_string('capability', 'core_role') . '</th>';
index 7326cf3..0cac01a 100644 (file)
@@ -51,7 +51,7 @@ M.core_role.init_cap_table_filter = function(Y, tableid, contextid) {
                 marginRight : 'auto'
             });
             // Create the capability search input.
-            this.input = Y.Node.create('<input type="text" id="'+this.table.get('id')+'capabilitysearch" value="'+filtervalue+'" />');
+            this.input = Y.Node.create('<input type="text" id="'+this.table.get('id')+'capabilitysearch" value="'+Y.Escape.html(filtervalue)+'" />');
             // Create a label for the search input.
             this.label = Y.Node.create('<label for="'+this.input.get('id')+'">'+M.str.moodle.filter+' </label>');
             // Create a clear button to clear the input.
index ab80e69..1583fab 100644 (file)
@@ -139,7 +139,6 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) {
         array(
             'context' => $context,
             'objectid' => $roleid,
-            'courseid' => $courseid
         )
     );
 
index 2231bab..5a7e75a 100644 (file)
@@ -24,6 +24,46 @@ if ($hassiteconfig
     $ADMIN->add('accounts', new admin_externalpage('editusers', new lang_string('userlist','admin'), "$CFG->wwwroot/$CFG->admin/user.php", array('moodle/user:update', 'moodle/user:delete')));
     $ADMIN->add('accounts', new admin_externalpage('userbulk', new lang_string('userbulk','admin'), "$CFG->wwwroot/$CFG->admin/user/user_bulk.php", array('moodle/user:update', 'moodle/user:delete')));
     $ADMIN->add('accounts', new admin_externalpage('addnewuser', new lang_string('addnewuser'), "$securewwwroot/user/editadvanced.php?id=-1", 'moodle/user:create'));
+
+    // "User default preferences" settingpage.
+    $temp = new admin_settingpage('userdefaultpreferences', new lang_string('userdefaultpreferences', 'admin'));
+    if ($ADMIN->fulltree) {
+        $choices = array();
+        $choices['0'] = new lang_string('emaildisplayno');
+        $choices['1'] = new lang_string('emaildisplayyes');
+        $choices['2'] = new lang_string('emaildisplaycourse');
+        $temp->add(new admin_setting_configselect('defaultpreference_maildisplay', new lang_string('emaildisplay'),
+            '', 2, $choices));
+
+        $choices = array();
+        $choices['0'] = new lang_string('textformat');
+        $choices['1'] = new lang_string('htmlformat');
+        $temp->add(new admin_setting_configselect('defaultpreference_mailformat', new lang_string('emailformat'), '', 1, $choices));
+
+        $choices = array();
+        $choices['0'] = new lang_string('emaildigestoff');
+        $choices['1'] = new lang_string('emaildigestcomplete');
+        $choices['2'] = new lang_string('emaildigestsubjects');
+        $temp->add(new admin_setting_configselect('defaultpreference_maildigest', new lang_string('emaildigest'),
+            new lang_string('emaildigest_help'), 0, $choices));
+
+
+        $choices = array();
+        $choices['1'] = new lang_string('autosubscribeyes');
+        $choices['0'] = new lang_string('autosubscribeno');
+        $temp->add(new admin_setting_configselect('defaultpreference_autosubscribe', new lang_string('autosubscribe'),
+            '', 1, $choices));
+
+        if (!empty($CFG->forum_trackreadposts)) {
+            $choices = array();
+            $choices['0'] = new lang_string('trackforumsno');
+            $choices['1'] = new lang_string('trackforumsyes');
+            $temp->add(new admin_setting_configselect('defaultpreference_trackforums', new lang_string('trackforums'),
+                '', 0, $choices));
+        }
+    }
+    $ADMIN->add('accounts', $temp);
+
     $ADMIN->add('accounts', new admin_externalpage('profilefields', new lang_string('profilefields','admin'), "$CFG->wwwroot/user/profile/index.php", 'moodle/site:config'));
     $ADMIN->add('accounts', new admin_externalpage('cohorts', new lang_string('cohorts', 'cohort'), $CFG->wwwroot . '/cohort/index.php', array('moodle/cohort:manage', 'moodle/cohort:view')));
 
index 2a02183..91433c8 100644 (file)
@@ -80,7 +80,8 @@ class behat_admin extends behat_base {
             // Single element settings.
             try {
                 $fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]" .
-                    "[@id=//label[contains(normalize-space(.), $label)]/@for]";
+                    "[@id=//label[contains(normalize-space(.), $label)]/@for or " .
+                    "@id=//span[contains(normalize-space(.), $label)]/preceding-sibling::label[1]/@for]";
                 $fieldnode = $this->find('xpath', $fieldxpath, $exception);
 
                 $formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']" .
@@ -89,7 +90,7 @@ class behat_admin extends behat_base {
             } catch (ElementNotFoundException $e) {
 
                 // Multi element settings, interacting only the first one.
-                $fieldxpath = "//descendant::label[.= $label]/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
+                $fieldxpath = "//*[label[.= $label]|span[.= $label]]/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-item ')]" .
                     "/descendant::div[@class='form-group']/descendant::*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]";
                 $fieldnode = $this->find('xpath', $fieldxpath);
 
diff --git a/admin/tests/behat/set_admin_settings_value.feature b/admin/tests/behat/set_admin_settings_value.feature
new file mode 100644 (file)
index 0000000..4edbb5c
--- /dev/null
@@ -0,0 +1,27 @@
+@core @core_admin
+Feature: Set admin settings value
+  In order to set admin settings value
+  As an admin
+  I need to set admin setting value and verify it is applied
+
+  Background:
+    Given the following "courses" exist:
+      | fullname | shortname | category |
+      | Course fullname | C_shortname | 0 |
+    And I log in as "admin"
+    And I should see "Course fullname"
+    And I should not see "C_shortname Course fullname"
+
+  Scenario: set admin value with full name
+    Given I set the following administration settings values:
+      | Display extended course names | 1 |
+    When I press "Save changes"
+    And I am on homepage
+    Then I should see "C_shortname Course fullname"
+
+  Scenario: set admin value with short name
+    Given I set the following administration settings values:
+      | courselistshortnames | 1 |
+    When I press "Save changes"
+    And I am on homepage
+    Then I should see "C_shortname Course fullname"
\ No newline at end of file
index 3696b81..952b65a 100644 (file)
@@ -11,6 +11,7 @@ Feature: Forms manipulation
     When I set the field "First name" to "Field value"
     And I set the field "Text editor" to "Plain text area"
     And I set the field "Unmask" to "1"
+    And I expand all fieldsets
     Then the field "First name" matches value "Field value"
     And the "Text editor" select box should contain "Plain text area"
     And the field "Unmask" matches value "1"
index a55199a..f162e05 100644 (file)
@@ -28,20 +28,20 @@ defined('MOODLE_INTERNAL') || die();
 
 $string['acknowledgement'] = 'Acknowledgement';
 $string['acknowledgementmust'] = 'You must acknowledge this';
-$string['acknowledgementtext'] = 'I understand that it is my responsibility to have full backups of this site prior to installing add-ons. I accept and understand that add-ons (especially but not only those originating in unofficial sources) may contain security holes, can make the site unavailable, or cause private data leaks or loss.';
-$string['featuredisabled'] = 'The add-on installer is disabled on this site.';
-$string['installaddon'] = 'Install add-on!';
-$string['installaddons'] = 'Install add-ons';
-$string['installexception'] = 'Oops... An error occurred while trying to install the add-on. Turn debugging mode on to see details of the error.';
-$string['installfromrepo'] = 'Install add-ons from the Moodle plugins directory';
-$string['installfromrepo_help'] = 'You will be redirected to the Moodle plugins directory to search for and install an add-on. Note that your site full name, URL and Moodle version will be sent as well, to make the installation process easier for you.';
-$string['installfromzip'] = 'Install add-on from ZIP file';
-$string['installfromzip_help'] = 'An alternative to installing an add-on directly from the Moodle plugins directory is to upload a ZIP package of the add-on. The ZIP package should have the same structure as a package downloaded from the Moodle plugins directory.';
+$string['acknowledgementtext'] = 'I understand that it is my responsibility to have full backups of this site prior to installing additional plugins. I accept and understand that plugins (especially but not only those originating in unofficial sources) may contain security holes, can make the site unavailable, or cause private data leaks or loss.';
+$string['featuredisabled'] = 'The plugin installer is disabled on this site.';
+$string['installaddon'] = 'Install plugin!';
+$string['installaddons'] = 'Install plugins';
+$string['installexception'] = 'Oops... An error occurred while trying to install the plugin. Turn debugging mode on to see details of the error.';
+$string['installfromrepo'] = 'Install plugins from the Moodle plugins directory';
+$string['installfromrepo_help'] = 'You will be redirected to the Moodle plugins directory to search for and install a plugin. Note that your site full name, URL and Moodle version will be sent as well, to make the installation process easier for you.';
+$string['installfromzip'] = 'Install plugin from ZIP file';
+$string['installfromzip_help'] = 'An alternative to installing a plugin directly from the Moodle plugins directory is to upload a ZIP package of the plugin. The ZIP package should have the same structure as a package downloaded from the Moodle plugins directory.';
 $string['installfromzipfile'] = 'ZIP package';
 $string['installfromzipfile_help'] = 'The plugin ZIP package must contain just one directory, named to match the plugin. The ZIP will be extracted into an appropriate location for the plugin type. If the package has been downloaded from the Moodle plugins directory then it will have this structure.';
 $string['installfromziprootdir'] = 'Rename the root directory';
 $string['installfromziprootdir_help'] = 'Some ZIP packages, such as those generated by Github, may contain an incorrect root directory name. If so, the correct name may be entered here.';
-$string['installfromzipsubmit'] = 'Install add-on from the ZIP file';
+$string['installfromzipsubmit'] = 'Install plugin from the ZIP file';
 $string['installfromziptype'] = 'Plugin type';
 $string['installfromziptype_help'] = 'Choose the correct type of plugin you are about to install. Warning: The installation procedure can fail badly if an incorrect plugin type is specified.';
 $string['permcheck'] = 'Make sure the plugin type root location is writable by the web server process.';
@@ -49,54 +49,54 @@ $string['permcheckerror'] = 'Error while checking for write permission';
 $string['permcheckprogress'] = 'Checking for write permission ...';
 $string['permcheckresultno'] = 'Plugin type location <em>{$a->path}</em> is not writable';
 $string['permcheckresultyes'] = 'Plugin type location <em>{$a->path}</em> is writable';
-$string['pluginname'] = 'Add-on installer';
-$string['remoterequestalreadyinstalled'] = 'There is a request to install add-on {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, this plugin is <strong>already installed</strong> on the site.';
-$string['remoterequestconfirm'] = 'There is a request to install add-on <strong>{$a->name}</strong> ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. If you continue, the add-on ZIP package will be downloaded for validation. Nothing will be installed yet.';
-$string['remoterequestinvalid'] = 'There is a request to install an add-on from the Moodle plugins directory on this site. Unfortunately the request is not valid and so the add-on cannot be installed.';
-$string['remoterequestpermcheck'] = 'There is a request to install add-on {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, the plugin type location <strong>{$a->typepath}</strong> is <strong>not writable</strong>. You need to give write access for the web server user to the plugin type location, then press the continue button to repeat the check.';
-$string['remoterequestpluginfoexception'] = 'Oops... An error occurred while trying to obtain information about the add-on {$a->name} ({$a->component}) version {$a->version}. The add-on cannot be installed. Turn debugging mode on to see details of the error.';
-$string['validation'] = 'Add-on package validation';
+$string['pluginname'] = 'Plugin installer';
+$string['remoterequestalreadyinstalled'] = 'There is a request to install plugin {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, this plugin is <strong>already installed</strong> on the site.';
+$string['remoterequestconfirm'] = 'There is a request to install plugin <strong>{$a->name}</strong> ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. If you continue, the plugin ZIP package will be downloaded for validation. Nothing will be installed yet.';
+$string['remoterequestinvalid'] = 'There is a request to install a plugin from the Moodle plugins directory on this site. Unfortunately the request is not valid and so the plugin cannot be installed.';
+$string['remoterequestpermcheck'] = 'There is a request to install plugin {$a->name} ({$a->component}) version {$a->version} from the Moodle plugins directory on this site. However, the location <strong>{$a->typepath}</strong> is <strong>not writable</strong>. You need to give write access for the web server user to the location, then press the continue button to repeat the check.';
+$string['remoterequestpluginfoexception'] = 'Oops... An error occurred while trying to obtain information about the plugin {$a->name} ({$a->component}) version {$a->version}. The plugin cannot be installed. Turn debugging mode on to see details of the error.';
+$string['validation'] = 'Plugin package validation';
 $string['validationmsg_componentmatch'] = 'Full component name';
-$string['validationmsg_componentmismatchname'] = 'Add-on name mismatch';
-$string['validationmsg_componentmismatchname_help'] = 'Some ZIP packages, such as those generated by Github, may contain an incorrect root directory name. You need to fix the name of the root directory to match the declared add-on name.';
-$string['validationmsg_componentmismatchname_info'] = 'The add-on declares its name is \'{$a}\' but that does not match the name of the root directory.';
-$string['validationmsg_componentmismatchtype'] = 'Add-on type mismatch';
-$string['validationmsg_componentmismatchtype_info'] = 'You have selected the type \'{$a->expected}\' but the add-on declares its type is \'{$a->found}\'.';
+$string['validationmsg_componentmismatchname'] = 'Plugin name mismatch';
+$string['validationmsg_componentmismatchname_help'] = 'Some ZIP packages, such as those generated by Github, may contain an incorrect root directory name. You need to fix the name of the root directory to match the declared plugin name.';
+$string['validationmsg_componentmismatchname_info'] = 'The plugin declares its name is \'{$a}\' but that does not match the name of the root directory.';
+$string['validationmsg_componentmismatchtype'] = 'Plugin type mismatch';
+$string['validationmsg_componentmismatchtype_info'] = 'You have selected the type \'{$a->expected}\' but the plugin declares its type is \'{$a->found}\'.';
 $string['validationmsg_filenotexists'] = 'Extracted file not found';
 $string['validationmsg_filesnumber'] = 'Not enough files found in the package';
 $string['validationmsg_filestatus'] = 'Unable to extract all files';
 $string['validationmsg_filestatus_info'] = 'Attempting to extract file {$a->file} resulted in error \'{$a->status}\'.';
 $string['validationmsg_maturity'] = 'Declared maturity level';
-$string['validationmsg_maturity_help'] = 'The add-on can declare its maturity level. If the maintainer considers the add-on stable, the declared maturity level will read MATURITY_STABLE. All other maturity levels (such as alpha or beta) should be considered unstable and a warning is raised.';
+$string['validationmsg_maturity_help'] = 'The plugin can declare its maturity level. If the maintainer considers the plugin stable, the declared maturity level will read MATURITY_STABLE. All other maturity levels (such as alpha or beta) should be considered unstable and a warning is raised.';
 $string['validationmsg_missingexpectedlangenfile'] = 'English language file name mismatch';
-$string['validationmsg_missingexpectedlangenfile_info'] = 'The given add-on type is missing the expected English language file {$a}.';
+$string['validationmsg_missingexpectedlangenfile_info'] = 'The given plugin type is missing the expected English language file {$a}.';
 $string['validationmsg_missinglangenfile'] = 'No English language file found';
 $string['validationmsg_missinglangenfolder'] = 'Missing English language folder';
-$string['validationmsg_missingversion'] = 'Add-on does not declare its version';
+$string['validationmsg_missingversion'] = 'Plugin does not declare its version';
 $string['validationmsg_missingversionphp'] = 'File version.php not found';
 $string['validationmsg_multiplelangenfiles'] = 'Multiple English language files found';
 $string['validationmsg_onedir'] = 'Invalid structure of the ZIP package.';
-$string['validationmsg_onedir_help'] = 'The ZIP package must contain just one root directory that holds the add-on code. The name of that root directory must match the name of the plugin.';
+$string['validationmsg_onedir_help'] = 'The ZIP package must contain just one root directory that holds the plugin code. The name of that root directory must match the name of the plugin.';
 $string['validationmsg_pathwritable'] = 'Write access check';
-$string['validationmsg_pluginversion'] = 'Add-on version';
-$string['validationmsg_release'] = 'Add-on release';
+$string['validationmsg_pluginversion'] = 'Plugin version';
+$string['validationmsg_release'] = 'Plugin release';
 $string['validationmsg_requiresmoodle'] = 'Required Moodle version';
-$string['validationmsg_rootdir'] = 'Name of the add-on to be installed';
-$string['validationmsg_rootdir_help'] = 'The name of the root directory in the ZIP package forms the name of the add-on to be installed. If the name is not correct, you may wish to rename the root directory in the ZIP prior to installing the add-on.';
-$string['validationmsg_rootdirinvalid'] = 'Invalid add-on name';
-$string['validationmsg_rootdirinvalid_help'] = 'The name of the root directory in the ZIP package violates formal syntax requirements. Some ZIP packages, such as those generated by Github, may contain an incorrect root directory name. You need to fix the name of the root directory to match the add-on name.';
+$string['validationmsg_rootdir'] = 'Name of the plugin to be installed';
+$string['validationmsg_rootdir_help'] = 'The name of the root directory in the ZIP package forms the name of the plugin to be installed. If the name is not correct, you may wish to rename the root directory in the ZIP prior to installing the plugin.';
+$string['validationmsg_rootdirinvalid'] = 'Invalid plugin name';
+$string['validationmsg_rootdirinvalid_help'] = 'The name of the root directory in the ZIP package violates formal syntax requirements. Some ZIP packages, such as those generated by Github, may contain an incorrect root directory name. You need to fix the name of the root directory to match the plugin name.';
 $string['validationmsg_targetexists'] = 'Target location already exists';
-$string['validationmsg_targetexists_help'] = 'The directory that the add-on is to be installed to, must not exist yet.';
+$string['validationmsg_targetexists_help'] = 'The directory that the plugin is to be installed to must not yet exist.';
 $string['validationmsg_unknowntype'] = 'Unknown plugin type';
 $string['validationmsglevel_debug'] = 'Debug';
 $string['validationmsglevel_error'] = 'Error';
 $string['validationmsglevel_info'] = 'OK';
 $string['validationmsglevel_warning'] = 'Warning';
 $string['validationresult0'] = 'Validation failed!';
-$string['validationresult0_help'] = 'A serious problem was detected and so it is not safe to install the add-on. See the validation log messages for details.';
+$string['validationresult0_help'] = 'A serious problem was detected and so it is not safe to install the plugin. See the validation log messages for details.';
 $string['validationresult1'] = 'Validation passed!';
-$string['validationresult1_help'] = 'No serious problems were detected. You can continue with the add-on installation. See the validation log messages for more details and eventual warnings.';
-$string['validationresult1_help'] = 'The add-on package has been validated and no serious problems were detected.';
+$string['validationresult2_help'] = 'No serious problems were detected. You can continue with the plugin installation. See the validation log messages for more details and eventual warnings.';
+$string['validationresult1_help'] = 'The plugin package has been validated and no serious problems were detected.';
 $string['validationresultinfo'] = 'Info';
 $string['validationresultmsg'] = 'Message';
 $string['validationresultstatus'] = 'Status';
index be588be..96cfd0c 100644 (file)
@@ -72,7 +72,7 @@ trait buffered_writer {
         $entry['other'] = serialize($entry['other']);
         $entry['origin'] = $PAGE->requestorigin;
         $entry['ip'] = $PAGE->requestip;
-        $entry['realuserid'] = \core\session\manager::is_loggedinas() ? $_SESSION['USER']->realuser : null;
+        $entry['realuserid'] = \core\session\manager::is_loggedinas() ? $GLOBALS['USER']->realuser : null;
 
         $this->buffer[] = $entry;
         $this->count++;
index 48e1b39..6157cac 100644 (file)
@@ -130,8 +130,7 @@ class logstore_database_store_testcase extends advanced_testcase {
             array('context' => context_module::instance($module2->cmid), 'other' => array('sample' => 6, 'xx' => 9)));
         $event2->trigger();
 
-        $_SESSION['SESSION'] = new \stdClass();
-        $this->setUser(0);
+        \core\session\manager::init_empty_session();
         $this->assertFalse(\core\session\manager::is_loggedinas());
 
         $logs = $DB->get_records('logstore_standard_log', array(), 'id ASC');
index 5d25a2e..08d70d4 100644 (file)
@@ -95,8 +95,7 @@ class logstore_standard_store_testcase extends advanced_testcase {
         $event2->trigger();
         logstore_standard_restore::hack_executing(0);
 
-        $_SESSION['SESSION'] = new \stdClass();
-        $this->setUser(0);
+        \core\session\manager::init_empty_session();
         $this->assertFalse(\core\session\manager::is_loggedinas());
 
         $logs = $DB->get_records('logstore_standard_log', array(), 'id ASC');
index 768d4bc..4b6f344 100644 (file)
@@ -104,11 +104,11 @@ if ($mform && ($mform->is_cancelled() || !empty($CFG->preventscheduledtaskchange
 
 } else {
     echo $OUTPUT->header();
-    $error = optional_param('error', '', PARAM_RAW);
+    $error = optional_param('error', '', PARAM_NOTAGS);
     if ($error) {
         echo $OUTPUT->notification($error, 'notifyerror');
     }
-    $success = optional_param('success', '', PARAM_RAW);
+    $success = optional_param('success', '', PARAM_NOTAGS);
     if ($success) {
         echo $OUTPUT->notification($success, 'notifysuccess');
     }
index a45cb47..b50156f 100644 (file)
@@ -669,7 +669,7 @@ if ($formdata = $mform2->is_cancelled()) {
 
             if ($doupdate or $existinguser->password !== $oldpw) {
                 // We want only users that were really updated.
-                user_update_user($existinguser, false);
+                user_update_user($existinguser, false, false);
 
                 $upt->track('status', $struserupdated);
                 $usersupdated++;
@@ -687,6 +687,9 @@ if ($formdata = $mform2->is_cancelled()) {
                     }
                 }
 
+                // Trigger event.
+                \core\event\user_updated::create_from_userid($existinguser->id)->trigger();
+
             } else {
                 // no user information changed
                 $upt->track('status', $struseruptodate);
@@ -800,7 +803,7 @@ if ($formdata = $mform2->is_cancelled()) {
                 $upt->track('password', '-', 'normal', false);
             }
 
-            $user->id = user_create_user($user, false);
+            $user->id = user_create_user($user, false, false);
             $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false);
 
             // pre-process custom profile menu fields data from csv file
@@ -815,6 +818,9 @@ if ($formdata = $mform2->is_cancelled()) {
                 set_user_preference('create_password', 1, $user);
             }
 
+            // Trigger event.
+            \core\event\user_created::create_from_userid($user->id)->trigger();
+
             $upt->track('status', $struseradded);
             $upt->track('id', $user->id, 'normal', false);
             $usersnew++;
index f922995..1ec16e0 100644 (file)
@@ -221,21 +221,21 @@ class admin_uploaduser_form2 extends moodleform {
 
         $choices = array(0 => get_string('emaildisplayno'), 1 => get_string('emaildisplayyes'), 2 => get_string('emaildisplaycourse'));
         $mform->addElement('select', 'maildisplay', get_string('emaildisplay'), $choices);
-        $mform->setDefault('maildisplay', 2);
+        $mform->setDefault('maildisplay', $CFG->defaultpreference_maildisplay);
 
         $choices = array(0 => get_string('textformat'), 1 => get_string('htmlformat'));
         $mform->addElement('select', 'mailformat', get_string('emailformat'), $choices);
-        $mform->setDefault('mailformat', 1);
+        $mform->setDefault('mailformat', $CFG->defaultpreference_mailformat);
         $mform->setAdvanced('mailformat');
 
         $choices = array(0 => get_string('emaildigestoff'), 1 => get_string('emaildigestcomplete'), 2 => get_string('emaildigestsubjects'));
         $mform->addElement('select', 'maildigest', get_string('emaildigest'), $choices);
-        $mform->setDefault('maildigest', 0);
+        $mform->setDefault('maildigest', $CFG->defaultpreference_maildigest);
         $mform->setAdvanced('maildigest');
 
         $choices = array(1 => get_string('autosubscribeyes'), 0 => get_string('autosubscribeno'));
         $mform->addElement('select', 'autosubscribe', get_string('autosubscribe'), $choices);
-        $mform->setDefault('autosubscribe', 1);
+        $mform->setDefault('autosubscribe', $CFG->defaultpreference_autosubscribe);
 
         $mform->addElement('text', 'city', get_string('city'), 'maxlength="120" size="25"');
         $mform->setType('city', PARAM_TEXT);
index cfbbe22..a7e1e64 100644 (file)
     $ufiltering->display_add();
     $ufiltering->display_active();
 
-    if (has_capability('moodle/user:create', $sitecontext)) {
-        echo $OUTPUT->heading('<a href="'.$securewwwroot.'/user/editadvanced.php?id=-1">'.get_string('addnewuser').'</a>');
-    }
     if (!empty($table)) {
         echo html_writer::start_tag('div', array('class'=>'no-overflow'));
         echo html_writer::table($table);
         echo html_writer::end_tag('div');
         echo $OUTPUT->paging_bar($usercount, $page, $perpage, $baseurl);
-        if (has_capability('moodle/user:create', $sitecontext)) {
-            echo $OUTPUT->heading('<a href="'.$securewwwroot.'/user/editadvanced.php?id=-1">'.get_string('addnewuser').'</a>');
-        }
+    }
+    if (has_capability('moodle/user:create', $sitecontext)) {
+        $url = new moodle_url($securewwwroot . '/user/editadvanced.php', array('id' => -1));
+        echo $OUTPUT->single_button($url, get_string('addnewuser'), 'get');
     }
 
     echo $OUTPUT->footer();
-
-
-
index ff06a3a..9d83dd1 100644 (file)
@@ -111,6 +111,26 @@ class auth_plugin_cas extends auth_plugin_ldap {
             return;
         }
 
+        // If the multi-authentication setting is used, check for the param before connecting to CAS.
+        if ($this->config->multiauth) {
+            $authCAS = optional_param('authCAS', '', PARAM_RAW);
+            if ($authCAS == 'NOCAS') {
+                return;
+            }
+            // Show authentication form for multi-authentication.
+            // Test pgtIou parameter for proxy mode (https connection in background from CAS server to the php server).
+            if ($authCAS != 'CAS' && !isset($_GET['pgtIou'])) {
+                $PAGE->set_url('/login/index.php');
+                $PAGE->navbar->add($CASform);
+                $PAGE->set_title("$site->fullname: $CASform");
+                $PAGE->set_heading($site->fullname);
+                echo $OUTPUT->header();
+                include($CFG->dirroot.'/auth/cas/cas_form.html');
+                echo $OUTPUT->footer();
+                exit();
+            }
+        }
+
         // Connection to CAS server
         $this->connectCAS();
 
@@ -134,27 +154,6 @@ class auth_plugin_cas extends auth_plugin_ldap {
             return;
         }
 
-        if ($this->config->multiauth) {
-            $authCAS = optional_param('authCAS', '', PARAM_RAW);
-            if ($authCAS == 'NOCAS') {
-                return;
-            }
-
-            // Show authentication form for multi-authentication
-            // test pgtIou parameter for proxy mode (https connection
-            // in background from CAS server to the php server)
-            if ($authCAS != 'CAS' && !isset($_GET['pgtIou'])) {
-                $PAGE->set_url('/login/index.php');
-                $PAGE->navbar->add($CASform);
-                $PAGE->set_title("$site->fullname: $CASform");
-                $PAGE->set_heading($site->fullname);
-                echo $OUTPUT->header();
-                include($CFG->dirroot.'/auth/cas/cas_form.html');
-                echo $OUTPUT->footer();
-                exit();
-            }
-        }
-
         // Force CAS authentication (if needed).
         if (!phpCAS::isAuthenticated()) {
             phpCAS::setLang($this->config->language);
@@ -162,19 +161,6 @@ class auth_plugin_cas extends auth_plugin_ldap {
         }
     }
 
-    /**
-     * Logout from the CAS
-     *
-     */
-    function prelogout_hook() {
-        global $CFG;
-
-        if (!empty($this->config->logoutcas)) {
-            $backurl = $CFG->wwwroot;
-            $this->connectCAS();
-            phpCAS::logoutWithURL($backurl);
-        }
-    }
 
     /**
      * Connect to the CAS (clientcas connection or proxycas connection)
@@ -510,4 +496,22 @@ class auth_plugin_cas extends auth_plugin_ldap {
             }
         }
     }
+
+    /**
+     * Post logout hook.
+     *
+     * Note: this method replace the prelogout_hook method to avoid redirect to CAS logout
+     * before the event userlogout being triggered.
+     *
+     * @param stdClass $user clone of USER object object before the user session was terminated
+     */
+    public function postlogout_hook($user) {
+        global $CFG;
+        // Only redirect to CAS logout if the user is logged as a CAS user.
+        if (!empty($this->config->logoutcas) && $user->auth == $this->authtype) {
+            $backurl = $CFG->wwwroot;
+            $this->connectCAS();
+            phpCAS::logoutWithRedirectService($backurl);
+        }
+    }
 }
index b071e32..2c36eab 100644 (file)
@@ -94,11 +94,14 @@ class auth_plugin_email extends auth_plugin_base {
             $user->calendartype = $CFG->calendartype;
         }
 
-        $user->id = user_create_user($user, false);
+        $user->id = user_create_user($user, false, false);
 
         // Save any custom profile field information.
         profile_save_data($user);
 
+        // Trigger event.
+        \core\event\user_created::create_from_userid($user->id)->trigger();
+
         if (! send_confirmation_email($user)) {
             print_error('auth_emailnoemail','auth_email');
         }
index 9004e26..cc1374e 100644 (file)
@@ -551,7 +551,7 @@ class auth_plugin_ldap extends auth_plugin_base {
             print_error('auth_ldap_create_error', 'auth_ldap');
         }
 
-        $user->id = user_create_user($user, false);
+        $user->id = user_create_user($user, false, false);
 
         // Save any custom profile field information
         profile_save_data($user);
@@ -564,6 +564,8 @@ class auth_plugin_ldap extends auth_plugin_base {
 
         $user = $DB->get_record('user', array('id'=>$user->id));
 
+        \core\event\user_created::create_from_userid($user->id)->trigger();
+
         if (! send_confirmation_email($user)) {
             print_error('noemail', 'auth_ldap');
         }
@@ -1027,7 +1029,7 @@ class auth_plugin_ldap extends auth_plugin_base {
                         }
                     }
                 }
-                user_update_user($newuser, false);
+                user_update_user($newuser, false, false);
             }
         } else {
             return false;
index 13cdcc0..7f0855e 100644 (file)
@@ -279,6 +279,143 @@ class auth_ldap_plugin_testcase extends advanced_testcase {
         $this->assertEventLegacyLogData($expectedlog, $event);
     }
 
+    /**
+     * Test logging in via LDAP calls a user_loggedin event.
+     */
+    public function test_ldap_user_signup() {
+        global $CFG, $DB;
+
+        // User to create.
+        $user = array(
+            'username' => 'usersignuptest1',
+            'password' => 'Moodle2014!',
+            'idnumber' => 'idsignuptest1',
+            'firstname' => 'First Name User Test 1',
+            'lastname' => 'Last Name User Test 1',
+            'middlename' => 'Middle Name User Test 1',
+            'lastnamephonetic' => '最後のお名前のテスト一号',
+            'firstnamephonetic' => 'お名前のテスト一号',
+            'alternatename' => 'Alternate Name User Test 1',
+            'email' => 'usersignuptest1@email.com',
+            'description' => 'This is a description for user 1',
+            'city' => 'Perth',
+            'country' => 'au',
+            'mnethostid' => $CFG->mnet_localhost_id,
+            'auth' => 'ldap'
+            );
+
+        if (!extension_loaded('ldap')) {
+            $this->markTestSkipped('LDAP extension is not loaded.');
+        }
+
+        $this->resetAfterTest();
+
+        require_once($CFG->dirroot.'/auth/ldap/auth.php');
+        require_once($CFG->libdir.'/ldaplib.php');
+
+        if (!defined('TEST_AUTH_LDAP_HOST_URL') or !defined('TEST_AUTH_LDAP_BIND_DN') or !defined('TEST_AUTH_LDAP_BIND_PW') or !defined('TEST_AUTH_LDAP_DOMAIN')) {
+            $this->markTestSkipped('External LDAP test server not configured.');
+        }
+
+        // Make sure we can connect the server.
+        $debuginfo = '';
+        if (!$connection = ldap_connect_moodle(TEST_AUTH_LDAP_HOST_URL, 3, 'rfc2307', TEST_AUTH_LDAP_BIND_DN, TEST_AUTH_LDAP_BIND_PW, LDAP_DEREF_NEVER, $debuginfo, false)) {
+            $this->markTestSkipped('Can not connect to LDAP test server: '.$debuginfo);
+        }
+
+        $this->enable_plugin();
+
+        // Create new empty test container.
+        $topdn = 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN;
+
+        $this->recursive_delete($connection, TEST_AUTH_LDAP_DOMAIN, 'dc=moodletest');
+
+        $o = array();
+        $o['objectClass'] = array('dcObject', 'organizationalUnit');
+        $o['dc']         = 'moodletest';
+        $o['ou']         = 'MOODLETEST';
+        if (!ldap_add($connection, 'dc=moodletest,'.TEST_AUTH_LDAP_DOMAIN, $o)) {
+            $this->markTestSkipped('Can not create test LDAP container.');
+        }
+
+        // Create a few users.
+        $o = array();
+        $o['objectClass'] = array('organizationalUnit');
+        $o['ou']          = 'users';
+        ldap_add($connection, 'ou='.$o['ou'].','.$topdn, $o);
+
+        // Configure the plugin a bit.
+        set_config('host_url', TEST_AUTH_LDAP_HOST_URL, 'auth/ldap');
+        set_config('start_tls', 0, 'auth/ldap');
+        set_config('ldap_version', 3, 'auth/ldap');
+        set_config('ldapencoding', 'utf-8', 'auth/ldap');
+        set_config('pagesize', '2', 'auth/ldap');
+        set_config('bind_dn', TEST_AUTH_LDAP_BIND_DN, 'auth/ldap');
+        set_config('bind_pw', TEST_AUTH_LDAP_BIND_PW, 'auth/ldap');
+        set_config('user_type', 'rfc2307', 'auth/ldap');
+        set_config('contexts', 'ou=users,'.$topdn, 'auth/ldap');
+        set_config('search_sub', 0, 'auth/ldap');
+        set_config('opt_deref', LDAP_DEREF_NEVER, 'auth/ldap');
+        set_config('user_attribute', 'cn', 'auth/ldap');
+        set_config('memberattribute', 'memberuid', 'auth/ldap');
+        set_config('memberattribute_isdn', 0, 'auth/ldap');
+        set_config('creators', 'cn=creators,'.$topdn, 'auth/ldap');
+        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/ldap');
+
+        set_config('field_map_email', 'mail', 'auth/ldap');
+        set_config('field_updatelocal_email', 'oncreate', 'auth/ldap');
+        set_config('field_updateremote_email', '0', 'auth/ldap');
+        set_config('field_lock_email', 'unlocked', 'auth/ldap');
+
+        set_config('field_map_firstname', 'givenName', 'auth/ldap');
+        set_config('field_updatelocal_firstname', 'oncreate', 'auth/ldap');
+        set_config('field_updateremote_firstname', '0', 'auth/ldap');
+        set_config('field_lock_firstname', 'unlocked', 'auth/ldap');
+
+        set_config('field_map_lastname', 'sn', 'auth/ldap');
+        set_config('field_updatelocal_lastname', 'oncreate', 'auth/ldap');
+        set_config('field_updateremote_lastname', '0', 'auth/ldap');
+        set_config('field_lock_lastname', 'unlocked', 'auth/ldap');
+        set_config('passtype', 'md5', 'auth/ldap');
+        set_config('create_context', 'ou=users,'.$topdn, 'auth/ldap');
+
+        $this->assertEquals(2, $DB->count_records('user'));
+        $this->assertEquals(0, $DB->count_records('role_assignments'));
+
+        /** @var auth_plugin_ldap $auth */
+        $auth = get_auth_plugin('ldap');
+
+        $sink = $this->redirectEvents();
+        $auth->user_signup((object)$user, false);
+        $this->assertDebuggingCalled('Not sending email due to $CFG->noemailever config setting');
+        $events = $sink->get_events();
+        $sink->close();
+
+        // Verify 2 events get generated.
+        $this->assertCount(2, $events);
+
+        // Get record from db.
+        $dbuser = $DB->get_record('user', array('username' => $user['username']));
+        $user['id'] = $dbuser->id;
+
+        // Last event is user_created.
+        $event = array_pop($events);
+        $this->assertInstanceOf('\core\event\user_created', $event);
+        $this->assertEquals($user['id'], $event->objectid);
+        $this->assertEquals('user_created', $event->get_legacy_eventname());
+        $this->assertEquals(context_user::instance($user['id']), $event->get_context());
+        $expectedlogdata = array(SITEID, 'user', 'add', '/view.php?id='.$event->objectid, fullname($dbuser));
+        $this->assertEventLegacyLogData($expectedlogdata, $event);
+
+        // First event is user_password_updated.
+        $event = array_pop($events);
+        $this->assertInstanceOf('\core\event\user_password_updated', $event);
+        $this->assertEventContextNotUsed($event);
+
+        // Delete user which we just created.
+        ldap_delete($connection, 'cn='.$user['username'].',ou=users,'.$topdn);
+    }
+
     protected function create_ldap_user($connection, $topdn, $i) {
         $o = array();
         $o['objectClass']   = array('inetOrgPerson', 'organizationalPerson', 'person', 'posixAccount');
index f521442..ef38337 100644 (file)
     if (!empty($_SERVER[$pluginconfig->user_attribute])) {    // Shibboleth auto-login
         $frm = new stdClass();
         $frm->username = strtolower($_SERVER[$pluginconfig->user_attribute]);
-        $frm->password = substr(base64_encode($_SERVER[$pluginconfig->user_attribute]),0,8);
-        // The random password consists of the first 8 letters of the base 64 encoded user ID
-        // This password is never used unless the user account is converted to manual
+        // The password is never actually used, but needs to be passed to the functions 'user_login' and
+        // 'authenticate_user_login'. Shibboleth returns true for the function 'prevent_local_password', which is
+        // used when setting the password in 'update_internal_user_password'. When 'prevent_local_password'
+        // returns true, the password is set to 'not cached' (AUTH_PASSWORD_NOT_CACHED) in the Moodle DB. However,
+        // rather than setting the password to a hard-coded value, we will generate one each time, in case there are
+        // changes to the Shibboleth plugin and it is actually used.
+        $frm->password = generate_password(8);
 
     /// Check if the user has actually submitted login data to us
 
index a6cfb55..41ff9d3 100644 (file)
@@ -547,7 +547,8 @@ abstract class backup_controller_dbops extends backup_dbops {
                 self::apply_general_config_defaults($controller);
                 break;
             case backup::MODE_AUTOMATED:
-                // TODO: Move the loading from automatic stuff to here
+                // Load the automated defaults.
+                self::apply_auto_config_defaults($controller);
                 break;
             default:
                 // Nothing to do for other modes (IMPORT/HUB...). Some day we
@@ -555,6 +556,43 @@ abstract class backup_controller_dbops extends backup_dbops {
         }
     }
 
+    /**
+     * Sets the controller settings default values from the automated backup config.
+     *
+     * @param backup_controller $controller
+     */
+    private static function apply_auto_config_defaults(backup_controller $controller) {
+        $settings = array(
+            // Config name                   => Setting name.
+            'backup_auto_users'              => 'users',
+            'backup_auto_role_assignments'   => 'role_assignments',
+            'backup_auto_activities'         => 'activities',
+            'backup_auto_blocks'             => 'blocks',
+            'backup_auto_filters'            => 'filters',
+            'backup_auto_comments'           => 'comments',
+            'backup_auto_badges'             => 'badges',
+            'backup_auto_userscompletion'    => 'userscompletion',
+            'backup_auto_logs'               => 'logs',
+            'backup_auto_histories'          => 'grade_histories',
+            'backup_auto_questionbank'       => 'questionbank'
+        );
+        $plan = $controller->get_plan();
+        foreach ($settings as $config => $settingname) {
+            $value = get_config('backup', $config);
+            if ($value === false) {
+                // The setting is not set.
+                $controller->log('Could not find a value for the config ' . $config, BACKUP::LOG_DEBUG);
+                continue;
+            }
+            if ($plan->setting_exists($settingname)) {
+                $setting = $plan->get_setting($settingname);
+                $setting->set_value($value);
+            } else {
+                $controller->log('Unknown setting: ' . $settingname, BACKUP::LOG_DEBUG);
+            }
+        }
+    }
+
     /**
      * Sets the controller settings default values from the backup config.
      *
@@ -583,6 +621,7 @@ abstract class backup_controller_dbops extends backup_dbops {
                 // Ignore this because the config has not been set. get_config
                 // returns false if a setting doesn't exist, '0' is returned when
                 // the configuration is set to false.
+                $controller->log('Could not find a value for the config ' . $config, BACKUP::LOG_DEBUG);
                 continue;
             }
             $locked = (get_config('backup', $config.'_locked') == true);
@@ -594,6 +633,8 @@ abstract class backup_controller_dbops extends backup_dbops {
                         $setting->set_status(base_setting::LOCKED_BY_CONFIG);
                     }
                 }
+            } else {
+                $controller->log('Unknown setting: ' . $setting, BACKUP::LOG_DEBUG);
             }
         }
     }
index b964b67..434059b 100644 (file)
@@ -381,27 +381,6 @@ abstract class backup_cron_automated_helper {
 
         try {
 
-            $settings = array(
-                'users' => 'backup_auto_users',
-                'role_assignments' => 'backup_auto_role_assignments',
-                'activities' => 'backup_auto_activities',
-                'blocks' => 'backup_auto_blocks',
-                'filters' => 'backup_auto_filters',
-                'comments' => 'backup_auto_comments',
-                'badges' => 'backup_auto_badges',
-                'completion_information' => 'backup_auto_userscompletion',
-                'logs' => 'backup_auto_logs',
-                'histories' => 'backup_auto_histories',
-                'questionbank' => 'backup_auto_questionbank'
-            );
-            foreach ($settings as $setting => $configsetting) {
-                if ($bc->get_plan()->setting_exists($setting)) {
-                    if (isset($config->{$configsetting})) {
-                        $bc->get_plan()->get_setting($setting)->set_value($config->{$configsetting});
-                    }
-                }
-            }
-
             // Set the default filename.
             $format = $bc->get_format();
             $type = $bc->get_type();
index c2f7a63..29f8cb4 100644 (file)
@@ -52,7 +52,16 @@ $PAGE->set_title(get_string('issuedbadge', 'badges'));
 if (isloggedin()) {
     $PAGE->set_heading($badge->badgeclass['name']);
     $PAGE->navbar->add($badge->badgeclass['name']);
-    $url = new moodle_url('/badges/mybadges.php');
+    if ($badge->recipient->id == $USER->id) {
+        $url = new moodle_url('/badges/mybadges.php');
+    } else {
+        $url = new moodle_url($CFG->wwwroot);
+    }
+    navigation_node::override_active_url($url);
+} else {
+    $PAGE->set_heading($badge->badgeclass['name']);
+    $PAGE->navbar->add($badge->badgeclass['name']);
+    $url = new moodle_url($CFG->wwwroot);
     navigation_node::override_active_url($url);
 }
 
index 24e52d7..cebc483 100644 (file)
@@ -54,7 +54,7 @@ class edit_details_form extends moodleform {
         $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
 
         $mform->addElement('textarea', 'description', get_string('description', 'badges'), 'wrap="virtual" rows="8" cols="70"');
-        $mform->setType('description', PARAM_CLEANHTML);
+        $mform->setType('description', PARAM_NOTAGS);
         $mform->addRule('description', null, 'required');
 
         $str = $action == 'new' ? get_string('badgeimage', 'badges') : get_string('newimage', 'badges');
index f18883b..1a9cee8 100644 (file)
@@ -82,6 +82,14 @@ $badge = new external_badge($badge, $userid);
 
 $PAGE->set_pagelayout('base');
 $PAGE->set_title(get_string('issuedbadge', 'badges'));
+$PAGE->set_heading(s($badge->issued->assertion->badge->name));
+$PAGE->navbar->add(s($badge->issued->assertion->badge->name));
+if (isloggedin() && $USER->id == $userid) {
+    $url = new moodle_url('/badges/mybadges.php');
+} else {
+    $url = new moodle_url($CFG->wwwroot);
+}
+navigation_node::override_active_url($url);
 
 echo $OUTPUT->header();
 
index 17103de..52f7205 100644 (file)
@@ -41,7 +41,7 @@ class core_badges_renderer extends plugin_renderer_base {
                 $bname = $badge->name;
                 $imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false);
             } else {
-                $bname = $badge->assertion->badge->name;
+                $bname = s($badge->assertion->badge->name);
                 $imageurl = $badge->imageUrl;
             }
 
@@ -135,34 +135,24 @@ class core_badges_renderer extends plugin_renderer_base {
         $display = "";
 
         // Badge details.
-        $display .= html_writer::start_tag('fieldset', array('class' => 'generalbox'));
-        $display .= html_writer::tag('legend', get_string('badgedetails', 'badges'), array('class' => 'bold'));
-
-        $detailstable = new html_table();
-        $detailstable->attributes = array('class' => 'clearfix', 'id' => 'badgedetails');
-        $detailstable->data[] = array(get_string('name') . ":", $badge->name);
-        $detailstable->data[] = array(get_string('description', 'badges') . ":", $badge->description);
-        $detailstable->data[] = array(get_string('createdon', 'search') . ":", userdate($badge->timecreated));
-        $detailstable->data[] = array(get_string('badgeimage', 'badges') . ":",
-                print_badge_image($badge, $context, 'large'));
-        $display .= html_writer::table($detailstable);
-        $display .= html_writer::end_tag('fieldset');
 
-        // Issuer details.
-        $display .= html_writer::start_tag('fieldset', array('class' => 'generalbox'));
-        $display .= html_writer::tag('legend', get_string('issuerdetails', 'badges'), array('class' => 'bold'));
+        $display .= $this->heading(get_string('badgedetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('name')] = $badge->name;
+        $dl[get_string('description', 'badges')] = $badge->description;
+        $dl[get_string('createdon', 'search')] = $badge->timecreated;
+        $dl[get_string('badgeimage', 'badges')] = print_badge_image($badge, $context, 'large');
+        $display .= $this->definition_list($dl);
 
-        $issuertable = new html_table();
-        $issuertable->attributes = array('class' => 'clearfix', 'id' => 'badgeissuer');
-        $issuertable->data[] = array(get_string('issuername', 'badges') . ":", $badge->issuername);
-        $issuertable->data[] = array(get_string('contact', 'badges') . ":",
-                html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact)));
-        $display .= html_writer::table($issuertable);
-        $display .= html_writer::end_tag('fieldset');
+        // Issuer details.
+        $display .= $this->heading(get_string('issuerdetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('issuername', 'badges')] = $badge->issuername;
+        $dl[get_string('contact', 'badges')] = html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact));
+        $display .= $this->definition_list($dl);
 
         // Issuance details if any.
-        $display .= html_writer::start_tag('fieldset', array('class' => 'generalbox'));
-        $display .= html_writer::tag('legend', get_string('issuancedetails', 'badges'), array('class' => 'bold'));
+        $display .= $this->heading(get_string('issuancedetails', 'badges'), 3);
         if ($badge->can_expire()) {
             if ($badge->expiredate) {
                 $display .= get_string('expiredate', 'badges', userdate($badge->expiredate));
@@ -180,11 +170,9 @@ class core_badges_renderer extends plugin_renderer_base {
         } else {
             $display .= get_string('noexpiry', 'badges');
         }
-        $display .= html_writer::end_tag('fieldset');
 
         // Criteria details if any.
-        $display .= html_writer::start_tag('fieldset', array('class' => 'generalbox'));
-        $display .= html_writer::tag('legend', get_string('bcriteria', 'badges'), array('class' => 'bold'));
+        $display .= $this->heading(get_string('bcriteria', 'badges'), 3);
         if ($badge->has_criteria()) {
             $display .= self::print_badge_criteria($badge);
         } else {
@@ -195,12 +183,10 @@ class core_badges_renderer extends plugin_renderer_base {
                     get_string('addcriteria', 'badges'), 'POST', array('class' => 'activatebadge'));
             }
         }
-        $display .= html_writer::end_tag('fieldset');
 
         // Awards details if any.
         if (has_capability('moodle/badges:viewawarded', $context)) {
-            $display .= html_writer::start_tag('fieldset', array('class' => 'generalbox'));
-            $display .= html_writer::tag('legend', get_string('awards', 'badges'), array('class' => 'bold'));
+            $display .= $this->heading(get_string('awards', 'badges'), 3);
             if ($badge->has_awards()) {
                 $url = new moodle_url('/badges/recipients.php', array('id' => $badge->id));
                 $a = new stdClass();
@@ -218,10 +204,9 @@ class core_badges_renderer extends plugin_renderer_base {
                         new moodle_url('/badges/award.php', array('id' => $badge->id)),
                         get_string('award', 'badges'), 'POST', array('class' => 'activatebadge'));
             }
-            $display .= html_writer::end_tag('fieldset');
         }
 
-        return $display;
+        return html_writer::div($display, null, array('id' => 'badge-overview'));
     }
 
     // Prints action icons for the badge.
@@ -285,19 +270,24 @@ class core_badges_renderer extends plugin_renderer_base {
         $badgeclass = $ibadge->badgeclass;
         $badge = new badge($ibadge->badgeid);
         $now = time();
+        $expiration = isset($issued['expires']) ? $issued['expires'] : $now + 86400;
 
-        $table = new html_table();
-        $table->id = 'issued-badge-table';
+        $output = '';
+        $output .= html_writer::start_tag('div', array('id' => 'badge'));
+        $output .= html_writer::start_tag('div', array('id' => 'badge-image'));
+        $output .= html_writer::empty_tag('img', array('src' => $badgeclass['image'], 'alt' => $badge->name));
+        if ($expiration < $now) {
+            $output .= $this->output->pix_icon('i/expired',
+            get_string('expireddate', 'badges', userdate($issued['expires'])),
+                'moodle',
+                array('class' => 'expireimage'));
+        }
 
-        $imagetable = new html_table();
-        $imagetable->attributes = array('class' => 'clearfix badgeissuedimage');
-        $imagetable->data[] = array(html_writer::empty_tag('img', array('src' => $badgeclass['image'])));
         if ($USER->id == $userinfo->id && !empty($CFG->enablebadges)) {
-            $imagetable->data[] = array($this->output->single_button(
+            $output .= $this->output->single_button(
                         new moodle_url('/badges/badge.php', array('hash' => $issued['uid'], 'bake' => true)),
                         get_string('download'),
-                        'POST'));
-            $expiration = isset($issued['expires']) ? $issued['expires'] : $now + 86400;
+                        'POST');
             if (!empty($CFG->badges_allowexternalbackpack) && ($expiration > $now) && badges_user_has_backpack($USER->id)) {
                 $assertion = new moodle_url('/badges/assertion.php', array('b' => $issued['uid']));
                 $action = new component_action('click', 'addtobackpack', array('assertion' => $assertion->out(false)));
@@ -307,57 +297,55 @@ class core_badges_renderer extends plugin_renderer_base {
                         'value' => get_string('addtobackpack', 'badges'));
                 $tobackpack = html_writer::tag('input', '', $attributes);
                 $this->output->add_action_handler($action, 'addbutton');
-                $imagetable->data[] = array($tobackpack);
+                $output .= $tobackpack;
             }
         }
-        $datatable = new html_table();
-        $datatable->attributes = array('class' => 'badgeissuedinfo');
-        $datatable->colclasses = array('bfield', 'bvalue');
+        $output .= html_writer::end_tag('div');
 
+        $output .= html_writer::start_tag('div', array('id' => 'badge-details'));
         // Recipient information.
-        $datatable->data[] = array($this->output->heading(get_string('recipientdetails', 'badges'), 3), '');
+        $output .= $this->output->heading(get_string('recipientdetails', 'badges'), 3);
+        $dl = array();
         if ($userinfo->deleted) {
             $strdata = new stdClass();
             $strdata->user = fullname($userinfo);
             $strdata->site = format_string($SITE->fullname, true, array('context' => context_system::instance()));
-            $datatable->data[] = array(get_string('name'), get_string('error:userdeleted', 'badges', $strdata));
+
+            $dl[get_string('name')] = get_string('error:userdeleted', 'badges', $strdata);
         } else {
-            $datatable->data[] = array(get_string('name'), fullname($userinfo));
+            $dl[get_string('name')] = fullname($userinfo);
         }
+        $output .= $this->definition_list($dl);
 
-        $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
-        $datatable->data[] = array(get_string('issuername', 'badges'), $badge->issuername);
+        $output .= $this->output->heading(get_string('issuerdetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('issuername', 'badges')] = $badge->issuername;
         if (isset($badge->issuercontact) && !empty($badge->issuercontact)) {
-            $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($badge->issuercontact));
+            $dl[get_string('contact', 'badges')] = obfuscate_mailto($badge->issuercontact);
         }
-        $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
-        $datatable->data[] = array(get_string('name'), $badge->name);
-        $datatable->data[] = array(get_string('description', 'badges'), $badge->description);
+        $output .= $this->definition_list($dl);
+
+        $output .= $this->output->heading(get_string('badgedetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('name')] = $badge->name;
+        $dl[get_string('description', 'badges')] = $badge->description;
 
         if ($badge->type == BADGE_TYPE_COURSE && isset($badge->courseid)) {
             $coursename = $DB->get_field('course', 'fullname', array('id' => $badge->courseid));
-            $datatable->data[] = array(get_string('course'), $coursename);
+            $dl[get_string('course')] = $coursename;
         }
+        $dl[get_string('bcriteria', 'badges')] = self::print_badge_criteria($badge);
+        $output .= $this->definition_list($dl);
 
-        $datatable->data[] = array(get_string('bcriteria', 'badges'), self::print_badge_criteria($badge));
-        $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), '');
-        $datatable->data[] = array(get_string('dateawarded', 'badges'), userdate($issued['issuedOn']));
+        $output .= $this->output->heading(get_string('issuancedetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('dateawarded', 'badges')] = userdate($issued['issuedOn']);
         if (isset($issued['expires'])) {
             if ($issued['expires'] < $now) {
-                $cell = new html_table_cell(userdate($issued['expires']) . get_string('warnexpired', 'badges'));
-                $cell->attributes = array('class' => 'notifyproblem warning');
-                $datatable->data[] = array(get_string('expirydate', 'badges'), $cell);
+                $dl[get_string('expirydate', 'badges')] = userdate($issued['expires']) . get_string('warnexpired', 'badges');
 
-                $image = html_writer::start_tag('div', array('class' => 'badge'));
-                $image .= html_writer::empty_tag('img', array('src' => $badgeclass['image']));
-                $image .= $this->output->pix_icon('i/expired',
-                                get_string('expireddate', 'badges', userdate($issued['expires'])),
-                                'moodle',
-                                array('class' => 'expireimage'));
-                $image .= html_writer::end_tag('div');
-                $imagetable->data[0] = array($image);
             } else {
-                $datatable->data[] = array(get_string('expirydate', 'badges'), userdate($issued['expires']));
+                $dl[get_string('expirydate', 'badges')] = userdate($issued['expires']);
             }
         }
 
@@ -379,14 +367,11 @@ class core_badges_renderer extends plugin_renderer_base {
             }
         }
 
-        $datatable->data[] = array(get_string('evidence', 'badges'),
-                get_string('completioninfo', 'badges') .
-                html_writer::alist($items, array(), 'ul'));
-        $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox');
-        $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable));
-        $htmlbadge = html_writer::table($table);
+        $dl[get_string('evidence', 'badges')] = get_string('completioninfo', 'badges') . html_writer::alist($items, array(), 'ul');
+        $output .= $this->definition_list($dl);
+        $output .= html_writer::end_tag('div');
 
-        return $htmlbadge;
+        return $output;
     }
 
     // Outputs external badge.
@@ -396,80 +381,82 @@ class core_badges_renderer extends plugin_renderer_base {
         $issuer = $assertion->badge->issuer;
         $userinfo = $ibadge->recipient;
         $table = new html_table();
+        $today = strtotime(date('Y-m-d'));
 
-        $imagetable = new html_table();
-        $imagetable->attributes = array('class' => 'clearfix badgeissuedimage');
-        $imagetable->data[] = array(html_writer::empty_tag('img', array('src' => $issued->imageUrl, 'width' => '100px')));
+        $output = '';
+        $output .= html_writer::start_tag('div', array('id' => 'badge'));
+        $output .= html_writer::start_tag('div', array('id' => 'badge-image'));
+        $output .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
+        if (isset($assertion->expires)) {
+            $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires);
+            if ($expiration < $today) {
+                $output .= $this->output->pix_icon('i/expired',
+                        get_string('expireddate', 'badges', userdate($expiration)),
+                        'moodle',
+                        array('class' => 'expireimage'));
+            }
+        }
+        $output .= html_writer::end_tag('div');
 
-        $datatable = new html_table();
-        $datatable->attributes = array('class' => 'badgeissuedinfo');
-        $datatable->colclasses = array('bfield', 'bvalue');
+        $output .= html_writer::start_tag('div', array('id' => 'badge-details'));
 
         // Recipient information.
-        $datatable->data[] = array($this->output->heading(get_string('recipientdetails', 'badges'), 3), '');
+        $output .= $this->output->heading(get_string('recipientdetails', 'badges'), 3);
+        $dl = array();
         // Technically, we should alway have a user at this point, but added an extra check just in case.
         if ($userinfo) {
-            $notify = '';
             if (!$ibadge->valid) {
                 $notify = $this->output->notification(get_string('recipientvalidationproblem', 'badges'), 'notifynotice');
+                $dl[get_string('name')] = fullname($userinfo) . $notify;
+            } else {
+                $dl[get_string('name')] = fullname($userinfo);
             }
-            $datatable->data[] = array(get_string('name'), fullname($userinfo). $notify);
         } else {
             $notify = $this->output->notification(get_string('recipientidentificationproblem', 'badges'), 'notifynotice');
-            $datatable->data[] = array(get_string('name'), $notify);
+            $dl[get_string('name')] = $notify;
         }
+        $output .= $this->definition_list($dl);
+
+        $output .= $this->output->heading(get_string('issuerdetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('issuername', 'badges')] = s($issuer->name);
+        $dl[get_string('issuerurl', 'badges')] = html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin));
 
-        $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
-        $datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
-        $datatable->data[] = array(get_string('issuerurl', 'badges'),
-                html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
         if (isset($issuer->contact)) {
-            $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
+            $dl[get_string('contact', 'badges')] = obfuscate_mailto($issuer->contact);
         }
-        $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
-        $datatable->data[] = array(get_string('name'), $assertion->badge->name);
-        $datatable->data[] = array(get_string('description', 'badges'), $assertion->badge->description);
-        $datatable->data[] = array(get_string('bcriteria', 'badges'),
-                html_writer::tag('a', $assertion->badge->criteria, array('href' => $assertion->badge->criteria)));
-        $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), '');
+        $output .= $this->definition_list($dl);
+
+        $output .= $this->output->heading(get_string('badgedetails', 'badges'), 3);
+        $dl = array();
+        $dl[get_string('name')] = s($assertion->badge->name);
+        $dl[get_string('description', 'badges')] = s($assertion->badge->description);
+        $dl[get_string('bcriteria', 'badges')] = html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria));
+        $output .= $this->definition_list($dl);
+
+        $output .= $this->output->heading(get_string('issuancedetails', 'badges'), 3);
+        $dl = array();
         if (isset($assertion->issued_on)) {
-            $datatable->data[] = array(get_string('dateawarded', 'badges'), $assertion->issued_on);
+            $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on);
+            $dl[get_string('dateawarded', 'badges')] = userdate($issuedate);
         }
-        if (isset($assertion->badge->expire)) {
-            $today_date = date('Y-m-d');
-            $today = strtotime($today_date);
-            $expiration = strtotime($assertion->badge->expire);
+        if (isset($assertion->expires)) {
             if ($expiration < $today) {
-                $cell = new html_table_cell($assertion->badge->expire . get_string('warnexpired', 'badges'));
-                $cell->attributes = array('class' => 'notifyproblem warning');
-                $datatable->data[] = array(get_string('expirydate', 'badges'), $cell);
-
-                $image = html_writer::start_tag('div', array('class' => 'badge'));
-                $image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image']));
-                $image .= html_writer::start_tag('span', array('class' => 'expired'))
-                            . $this->output->pix_icon('i/expired',
-                                get_string('expireddate', 'badges', $assertion->badge->expire),
-                                'moodle',
-                                array('class' => 'expireimage'))
-                            . html_writer::end_tag('span');
-                $image .= html_writer::end_tag('div');
-                $imagetable->data[0] = array($image);
+                $dl[get_string('expirydate', 'badges')] = userdate($expiration) . get_string('warnexpired', 'badges');
             } else {
-                $datatable->data[] = array(get_string('expirydate', 'badges'), $assertion->badge->expire);
+                $dl[get_string('expirydate', 'badges')] = userdate($expiration);
             }
         }
         if (isset($assertion->evidence)) {
-            $datatable->data[] = array(get_string('evidence', 'badges'),
-                html_writer::tag('a', $assertion->evidence, array('href' => $assertion->evidence)));
+            $dl[get_string('evidence', 'badges')] = html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence));
         }
-        $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox');
-        $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable));
-        $htmlbadge = html_writer::table($table);
+        $output .= $this->definition_list($dl);
+        $output .= html_writer::end_tag('div');
 
-        return $htmlbadge;
+        return $output;
     }
 
-    // Outputs table of user badges.
+    // Displays the user badges.
     protected function render_badge_user_collection(badge_user_collection $badges) {
         global $CFG, $USER, $SITE;
         $backpack = $badges->backpack;
@@ -496,10 +483,8 @@ class core_badges_renderer extends plugin_renderer_base {
         $heading = get_string('localbadges', 'badges', format_string($SITE->fullname, true, array('context' => context_system::instance())));
         $localhtml .= html_writer::tag('legend', $this->output->heading_with_help($heading, 'localbadgesh', 'badges'));
         if ($badges->badges) {
-            $table = new html_table();
-            $table->attributes['class'] = 'statustable';
-            $table->data[] = array($this->output->heading(get_string('badgesearned', 'badges', $badges->totalcount), 4, 'activatebadge'), $downloadall);
-            $downloadbutton = html_writer::table($table);
+            $downloadbutton = $this->output->heading(get_string('badgesearned', 'badges', $badges->totalcount), 4, 'activatebadge');
+            $downloadbutton .= $downloadall;
 
             $htmllist = $this->print_badges_list($badges->badges, $USER->id);
             $localhtml .= $backpackconnect . $downloadbutton . $searchform . $htmlpagingbar . $htmllist . $htmlpagingbar;
@@ -534,7 +519,7 @@ class core_badges_renderer extends plugin_renderer_base {
         return $localhtml . $externalhtml;
     }
 
-    // Outputs table of available badges.
+    // Displays the available badges.
     protected function render_badge_collection(badge_collection $badges) {
         $paging = new paging_bar($badges->totalcount, $badges->page, $badges->perpage, $this->page->url, 'page');
         $htmlpagingbar = $this->render($paging);
@@ -681,8 +666,6 @@ class core_badges_renderer extends plugin_renderer_base {
      */
     public function print_badge_status_box(badge $badge) {
         if (has_capability('moodle/badges:configurecriteria', $badge->get_context())) {
-            $table = new html_table();
-            $table->attributes['class'] = 'boxaligncenter statustable';
 
             if (!$badge->has_criteria()) {
                 $criteriaurl = new moodle_url('/badges/criteria.php', array('id' => $badge->id));
@@ -694,7 +677,8 @@ class core_badges_renderer extends plugin_renderer_base {
                 } else {
                     $action = '';
                 }
-                $row = array($status, $action);
+
+                $message = $status . $action;
             } else {
                 $status = get_string('statusmessage_' . $badge->status, 'badges');
                 if ($badge->is_active()) {
@@ -708,12 +692,13 @@ class core_badges_renderer extends plugin_renderer_base {
                                       'return' => $this->page->url->out_as_local_url(false))),
                             get_string('activate', 'badges'), 'POST', array('class' => 'activatebadge'));
                 }
-                $row = array($status . $this->output->help_icon('status', 'badges'), $action);
+
+                $message = $status . $this->output->help_icon('status', 'badges') . $action;
+
             }
-            $table->data[] = $row;
 
             $style = $badge->is_active() ? 'generalbox statusbox active' : 'generalbox statusbox inactive';
-            return $this->output->box(html_writer::table($table), $style);
+            return $this->output->box($message, $style);
         }
 
         return null;
@@ -898,6 +883,22 @@ class core_badges_renderer extends plugin_renderer_base {
 
         return $out;
     }
+
+    /**
+     * Renders a definition list
+     *
+     * @param array $items the list of items to define
+     * @param array
+     */
+    protected function definition_list(array $items, array $attributes = array()) {
+        $output = html_writer::start_tag('dl', $attributes);
+        foreach ($items as $label => $value) {
+            $output .= html_writer::tag('dt', $label);
+            $output .= html_writer::tag('dd', $value);
+        }
+        $output .= html_writer::end_tag('dl');
+        return $output;
+    }
 }
 
 /**
@@ -970,9 +971,10 @@ class external_badge implements renderable {
         global $DB;
         // At this point a user has connected a backpack. So, we are going to get
         // their backpack email rather than their account email.
-        $user = $DB->get_record_sql('SELECT u.lastname, u.firstname, b.email
+        $namefields = get_all_user_name_fields(true, 'u');
+        $user = $DB->get_record_sql("SELECT {$namefields}, b.email
                     FROM {user} u INNER JOIN {badge_backpack} b ON u.id = b.userid
-                    WHERE userid = :userid', array('userid' => $recipient), IGNORE_MISSING);
+                    WHERE userid = :userid", array('userid' => $recipient), IGNORE_MISSING);
 
         $this->issued = $badge;
         $this->recipient = $user;
index 79eeb0e..b1a0b7b 100644 (file)
@@ -31,7 +31,7 @@ Feature: Test expand my courses navigation setting
   Scenario: The My Courses branch is collapsed when expand my courses is off
     Given I log in as "admin"
     And I set the following administration settings values:
-      | Expand My Courses initially on My Moodle page | 0 |
+      | Show My courses expanded on My home | 0 |
     And I log out
     Given I log in as "student1"
     And I follow "My home"
@@ -43,7 +43,7 @@ Feature: Test expand my courses navigation setting
   Scenario: My Courses can be expanded on the My Moodle page when expand my courses is off
     Given I log in as "admin"
     And I set the following administration settings values:
-      | Expand My Courses initially on My Moodle page | 0 |
+      | Show My courses expanded on My home | 0 |
     And I log out
     Given I log in as "student1"
     And I follow "My home"
@@ -53,4 +53,4 @@ Feature: Test expand my courses navigation setting
     And I expand "My courses" node
     Then I should see "c1" in the "Navigation" "block"
     And I should see "c2" in the "Navigation" "block"
-    And I should not see "c3" in the "Navigation" "block"
\ No newline at end of file
+    And I should not see "c3" in the "Navigation" "block"
index fadc8ad..c3052f7 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 require_once(dirname(dirname(__FILE__)).'/config.php');
-include_once('lib.php');
-include_once('locallib.php');
+require_once('lib.php');
+require_once('locallib.php');
 
 $action   = required_param('action', PARAM_ALPHA);
 $id       = optional_param('entryid', 0, PARAM_INT);
 $confirm  = optional_param('confirm', 0, PARAM_BOOL);
-$modid    = optional_param('modid', 0, PARAM_INT); // To associate the entry with a module instance
-$courseid = optional_param('courseid', 0, PARAM_INT); // To associate the entry with a course
-
-$PAGE->set_url('/blog/edit.php', array('action' => $action, 'entryid' => $id, 'confirm' => $confirm, 'modid' => $modid, 'courseid' => $courseid));
+$modid = optional_param('modid', 0, PARAM_INT); // To associate the entry with a module instance.
+$courseid = optional_param('courseid', 0, PARAM_INT); // To associate the entry with a course.
 
-// If action is add, we ignore $id to avoid any further problems
-if (!empty($id) && $action == 'add') {
-    $id = null;
+if ($action == 'edit') {
+    $id = required_param('entryid', PARAM_INT);
 }
 
-$returnurl = new moodle_url('/blog/index.php');
+$PAGE->set_url('/blog/edit.php', array('action' => $action,
+                                       'entryid' => $id,
+                                       'confirm' => $confirm,
+                                       'modid' => $modid,
+                                       'courseid' => $courseid));
 
-if (!empty($courseid) && empty($modid)) {
-    $returnurl->param('courseid', $courseid);
-}
-
-// If a modid is given, guess courseid
-if (!empty($modid)) {
-    $returnurl->param('modid', $modid);
-    $courseid = $DB->get_field('course_modules', 'course', array('id' => $modid));
-    $returnurl->param('courseid', $courseid);
+// If action is add, we ignore $id to avoid any further problems.
+if (!empty($id) && $action == 'add') {
+    $id = null;
 }
 
 // Blogs are always in system context.
 $sitecontext = context_system::instance();
 $PAGE->set_context($sitecontext);
 
-
-$blogheaders = blog_get_headers();
-
 require_login($courseid);
 
-if ($action == 'edit') {
-    $id = required_param('entryid', PARAM_INT);
-}
-
 if (empty($CFG->enableblogs)) {
     print_error('blogdisable', 'blog');
 }
@@ -75,11 +62,26 @@ if (isguestuser()) {
     print_error('noguestentry', 'blog');
 }
 
+$returnurl = new moodle_url('/blog/index.php');
+
+if (!empty($courseid) && empty($modid)) {
+    $returnurl->param('courseid', $courseid);
+}
+
+// If a modid is given, guess courseid.
+if (!empty($modid)) {
+    $returnurl->param('modid', $modid);
+    $courseid = $DB->get_field('course_modules', 'course', array('id' => $modid));
+    $returnurl->param('courseid', $courseid);
+}
+
+$blogheaders = blog_get_headers();
+
 if (!has_capability('moodle/blog:create', $sitecontext) && !has_capability('moodle/blog:manageentries', $sitecontext)) {
     print_error('cannoteditentryorblog');
 }
 
-// Make sure that the person trying to edit has access right
+// Make sure that the person trying to edit has access right.
 if ($id) {
     if (!$entry = new blog_entry($id)) {
         print_error('wrongentryid', 'blog');
@@ -94,7 +96,7 @@ if ($id) {
 
 } else {
     if (!has_capability('moodle/blog:create', $sitecontext)) {
-        print_error('noentry', 'blog'); // manageentries is not enough for adding
+        print_error('noentry', 'blog'); // The capability "manageentries" is not enough for adding.
     }
     $entry  = new stdClass();
     $entry->id = null;
@@ -105,14 +107,14 @@ $returnurl->param('userid', $userid);
 // Blog renderer.
 $output = $PAGE->get_renderer('blog');
 
-$strblogs = get_string('blogs','blog');
+$strblogs = get_string('blogs', 'blog');
 
-if ($action === 'delete'){
+if ($action === 'delete') {
     if (empty($entry->id)) {
         print_error('wrongentryid', 'blog');
     }
     if (data_submitted() && $confirm && confirm_sesskey()) {
-        // Make sure the current user is the author of the blog entry, or has some deleteanyentry capability
+        // Make sure the current user is the author of the blog entry, or has some deleteanyentry capability.
         if (!blog_user_can_edit_entry($entry)) {
             print_error('nopermissionstodeleteentry', 'blog');
         } else {
@@ -132,7 +134,9 @@ if ($action === 'delete'){
         echo $output->render($entry);
 
         echo '<br />';
-        echo $OUTPUT->confirm(get_string('blogdeleteconfirm', 'blog'), new moodle_url('edit.php', $optionsyes),new moodle_url( 'index.php', $optionsno));
+        echo $OUTPUT->confirm(get_string('blogdeleteconfirm', 'blog'),
+                              new moodle_url('edit.php', $optionsyes),
+                              new moodle_url('index.php', $optionsno));
         echo $OUTPUT->footer();
         die;
     }
@@ -167,10 +171,21 @@ $summaryoptions = array('maxfiles'=> 99, 'maxbytes'=>$CFG->maxbytes, 'trusttext'
     'subdirs'=>file_area_contains_subdirs($sitecontext, 'blog', 'post', $entry->id));
 $attachmentoptions = array('subdirs'=>false, 'maxfiles'=> 99, 'maxbytes'=>$CFG->maxbytes);
 
-$blogeditform = new blog_edit_form(null, compact('entry', 'summaryoptions', 'attachmentoptions', 'sitecontext', 'courseid', 'modid'));
+$blogeditform = new blog_edit_form(null, compact('entry',
+                                                 'summaryoptions',
+                                                 'attachmentoptions',
+                                                 'sitecontext',
+                                                 'courseid',
+                                                 'modid'));
 
 $entry = file_prepare_standard_editor($entry, 'summary', $summaryoptions, $sitecontext, 'blog', 'post', $entry->id);
-$entry = file_prepare_standard_filemanager($entry, 'attachment', $attachmentoptions, $sitecontext, 'blog', 'attachment', $entry->id);
+$entry = file_prepare_standard_filemanager($entry,
+                                           'attachment',
+                                           $attachmentoptions,
+                                           $sitecontext,
+                                           'blog',
+                                           'attachment',
+                                           $entry->id);
 
 if (!empty($CFG->usetags) && !empty($entry->id)) {
     include_once($CFG->dirroot.'/tag/lib.php');
@@ -178,13 +193,13 @@ if (!empty($CFG->usetags) && !empty($entry->id)) {
 }
 
 $entry->action = $action;
-// set defaults
+// Set defaults.
 $blogeditform->set_data($entry);
 
 if ($blogeditform->is_cancelled()) {
     redirect($returnurl);
 
-} else if ($data = $blogeditform->get_data()){
+} else if ($data = $blogeditform->get_data()) {
 
     switch ($action) {
         case 'add':
@@ -209,23 +224,23 @@ if ($blogeditform->is_cancelled()) {
 }
 
 
-// gui setup
+// GUI setup.
 switch ($action) {
     case 'add':
-        // prepare new empty form
+        // Prepare new empty form.
         $entry->publishstate = 'site';
         $strformheading = get_string('addnewentry', 'blog');
         $entry->action       = $action;
 
         if ($CFG->useblogassociations) {
 
-            //pre-select the course for associations
+            // Pre-select the course for associations.
             if ($courseid) {
                 $context = context_course::instance($courseid);
                 $entry->courseassoc = $context->id;
             }
 
-            //pre-select the mod for associations
+            // Pre-select the mod for associations.
             if ($modid) {
                 $context = context_module::instance($modid);
                 $entry->modassoc = $context->id;
index 2b28a73..805bf79 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -16,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 if (!defined('MOODLE_INTERNAL')) {
-    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+    die('Direct access to this script is forbidden.');    //  It must be included from a Moodle page.
 }
 
 require_once($CFG->libdir.'/formslib.php');
@@ -24,7 +23,10 @@ require_once($CFG->libdir.'/formslib.php');
 class blog_edit_form extends moodleform {
     public $modnames = array();
 
-    function definition() {
+    /**
+     * Blog form definition.
+     */
+    public function definition() {
         global $CFG, $DB;
 
         $mform =& $this->_form;
@@ -50,12 +52,12 @@ class blog_edit_form extends moodleform {
 
         $mform->addElement('filemanager', 'attachment_filemanager', get_string('attachment', 'forum'), null, $attachmentoptions);
 
-        //disable publishstate options that are not allowed
+        // Disable publishstate options that are not allowed.
         $publishstates = array();
         $i = 0;
 
         foreach (blog_entry::get_applicable_publish_states() as $state => $desc) {
-            $publishstates[$state] = $desc;   //no maximum was set
+            $publishstates[$state] = $desc;   // No maximum was set.
             $i++;
         }
 
@@ -87,7 +89,12 @@ class blog_edit_form extends moodleform {
                 }
 
                 $mform->addElement('header', 'assochdr', get_string('associations', 'blog'));
-                $mform->addElement('advcheckbox', 'courseassoc', get_string('associatewithcourse', 'blog', $a), null, null, array(0, $contextid));
+                $mform->addElement('advcheckbox',
+                                   'courseassoc',
+                                   get_string('associatewithcourse', 'blog', $a),
+                                   null,
+                                   null,
+                                   array(0, $contextid));
                 $mform->setDefault('courseassoc', $contextid);
 
             } else if ((!empty($entry->modassoc) || !empty($modid))) {
@@ -107,7 +114,12 @@ class blog_edit_form extends moodleform {
                 }
 
                 $mform->addElement('header', 'assochdr', get_string('associations', 'blog'));
-                $mform->addElement('advcheckbox', 'modassoc', get_string('associatewithmodule', 'blog', $a), null, null, array(0, $context->id));
+                $mform->addElement('advcheckbox',
+                                   'modassoc',
+                                   get_string('associatewithmodule', 'blog', $a),
+                                   null,
+                                   null,
+                                   array(0, $context->id));
                 $mform->setDefault('modassoc', $context->id);
             }
         }
@@ -130,12 +142,18 @@ class blog_edit_form extends moodleform {
         $mform->setDefault('courseid', $courseid);
     }
 
-    function validation($data, $files) {
+    /**
+     * Validate the blog form data.
+     * @param array $data Data to be validated
+     * @param array $files unused
+     * @return array|bool
+     */
+    public function validation($data, $files) {
         global $CFG, $DB, $USER;
 
         $errors = array();
 
-        // validate course association
+        // Validate course association.
         if (!empty($data['courseassoc'])) {
             $coursecontext = context::instance_by_id($data['courseassoc']);
 
@@ -144,16 +162,16 @@ class blog_edit_form extends moodleform {
             }
         }
 
-        // validate mod association
+        // Validate mod association.
         if (!empty($data['modassoc'])) {
             $modcontextid = $data['modassoc'];
             $modcontext = context::instance_by_id($modcontextid);
 
             if ($modcontext->contextlevel == CONTEXT_MODULE) {
-                // get context of the mod's course
+                // Get context of the mod's course.
                 $coursecontext = $modcontext->get_course_context(true);
 
-                // ensure only one course is associated
+                // Ensure only one course is associated.
                 if (!empty($data['courseassoc'])) {
                     if ($data['courseassoc'] != $coursecontext->id) {
                         $errors['modassoc'] = get_string('onlyassociateonecourse', 'blog');
index b28860a..0aa122b 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -35,7 +34,9 @@ require_login();
 $context = context_system::instance();
 require_capability('moodle/blog:manageexternal', $context);
 
-// TODO redirect if $CFG->useexternalblogs is off, $CFG->maxexternalblogsperuser == 0, or if user doesn't have caps to manage external blogs
+// TODO redirect if $CFG->useexternalblogs is off,
+//                  $CFG->maxexternalblogsperuser == 0,
+//                  or if user doesn't have caps to manage external blogs.
 
 $id = optional_param('id', null, PARAM_INT);
 $url = new moodle_url('/blog/external_blog_edit.php');
@@ -52,24 +53,24 @@ $action = (empty($id)) ? 'add' : 'edit';
 
 $external = new stdClass();
 
-// Check that this id exists
+// Check that this id exists.
 if (!empty($id) && !$DB->record_exists('blog_external', array('id' => $id))) {
     print_error('wrongexternalid', 'blog');
-} elseif (!empty($id)) {
+} else if (!empty($id)) {
     $external = $DB->get_record('blog_external', array('id' => $id));
 }
 
 $strformheading = ($action == 'edit') ? get_string('editexternalblog', 'blog') : get_string('addnewexternalblog', 'blog');
-$strexternalblogs = get_string('externalblogs','blog');
-$strblogs = get_string('blogs','blog');
+$strexternalblogs = get_string('externalblogs', 'blog');
+$strblogs = get_string('blogs', 'blog');
 
 $externalblogform = new blog_edit_external_form();
 
-if ($externalblogform->is_cancelled()){
+if ($externalblogform->is_cancelled()) {
     redirect($returnurl);
 
 } else if ($data = $externalblogform->get_data()) {
-    //save stuff in db
+    // Save stuff in db.
     switch ($action) {
         case 'add':
             $rss = new moodle_simplepie($data->url);
@@ -79,13 +80,16 @@ if ($externalblogform->is_cancelled()){
             $newexternal->description = (empty($data->description)) ? $rss->get_description() : $data->description;
             $newexternal->userid = $USER->id;
             $newexternal->url = $data->url;
-            $newexternal->filtertags = $data->filtertags;
+            $newexternal->filtertags = (!empty($data->filtertags)) ? $data->filtertags : null;
             $newexternal->timemodified = time();
 
             $newexternal->id = $DB->insert_record('blog_external', $newexternal);
             blog_sync_external_entries($newexternal);
-            tag_set('blog_external', $newexternal->id, explode(',', $data->autotags), 'core',
-                context_user::instance($newexternal->userid)->id);
+            if ($CFG->usetags) {
+                $autotags = (!empty($data->autotags)) ? $data->autotags : null;
+                tag_set('blog_external', $newexternal->id, explode(',', $autotags), 'core',
+                    context_user::instance($newexternal->userid)->id);
+            }
 
             break;
 
@@ -99,13 +103,15 @@ if ($externalblogform->is_cancelled()){
                 $external->description = (empty($data->description)) ? $rss->get_description() : $data->description;
                 $external->userid = $USER->id;
                 $external->url = $data->url;
-                $external->filtertags = $data->filtertags;
+                $external->filtertags = (!empty($data->filtertags)) ? $data->filtertags : null;
                 $external->timemodified = time();
 
                 $DB->update_record('blog_external', $external);
-                tag_set('blog_external', $external->id, explode(',', $data->autotags), 'core',
-                    context_user::instance($newexternal->userid)->id);
-
+                if ($CFG->usetags) {
+                    $autotags = (!empty($data->autotags)) ? $data->autotags : null;
+                    tag_set('blog_external', $external->id, explode(',', $autotags), 'core',
+                        context_user::instance($external->userid)->id);
+                }
             } else {
                 print_error('wrongexternalid', 'blog');
             }
index 696e79a..fc28e9a 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -26,7 +25,7 @@
  */
 
 if (!defined('MOODLE_INTERNAL')) {
-    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+    die('Direct access to this script is forbidden.');    // It must be included from a Moodle page.
 }
 
 require_once($CFG->libdir.'/formslib.php');
@@ -118,9 +117,11 @@ class blog_edit_external_form extends moodleform {
         if ($id = $mform->getElementValue('id')) {
             $mform->setDefault('autotags', implode(',', tag_get_tags_array('blog_external', $id)));
             $mform->freeze('url');
-            $mform->freeze('filtertags');
+            if ($mform->elementExists('filtertags')) {
+                $mform->freeze('filtertags');
+            }
             // TODO change the filtertags element to a multiple select, using the tags of the external blog
-            // Use $rss->get_channel_tags()
+            // Use $rss->get_channel_tags().
         }
     }
 }
index 57af11a..800c85c 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -36,23 +35,25 @@ require_capability('moodle/blog:manageexternal', $context);
 
 $delete = optional_param('delete', null, PARAM_INT);
 
-$strexternalblogs = get_string('externalblogs','blog');
-$straddnewexternalblog = get_string('addnewexternalblog','blog');
-$strblogs = get_string('blogs','blog');
+$strexternalblogs = get_string('externalblogs', 'blog');
+$straddnewexternalblog = get_string('addnewexternalblog', 'blog');
+$strblogs = get_string('blogs', 'blog');
 $message = null;
 
 if ($delete && confirm_sesskey()) {
     $externalbloguserid = $DB->get_field('blog_external', 'userid', array('id' => $delete));
     if ($externalbloguserid == $USER->id) {
-        // Delete the external blog
+        // Delete the external blog.
         $DB->delete_records('blog_external', array('id' => $delete));
 
-        // Delete the external blog's posts
+        // Delete the external blog's posts.
         $deletewhere = 'module = :module
                             AND userid = :userid
                             AND ' . $DB->sql_isnotempty('post', 'uniquehash', false, false) . '
                             AND ' . $DB->sql_compare_text('content') . ' = ' . $DB->sql_compare_text(':delete');
-        $DB->delete_records_select('post', $deletewhere, array('module' => 'blog_external', 'userid' => $USER->id, 'delete' => $delete));
+        $DB->delete_records_select('post', $deletewhere, array('module' => 'blog_external',
+                                                               'userid' => $USER->id,
+                                                               'delete' => $delete));
 
         $message = get_string('externalblogdeleted', 'blog');
     }
@@ -77,7 +78,11 @@ if (!empty($blogs)) {
     $table = new html_table();
     $table->cellpadding = 4;
     $table->attributes['class'] = 'generaltable boxaligncenter';
-    $table->head = array(get_string('name'), get_string('url', 'blog'), get_string('timefetched', 'blog'), get_string('valid', 'blog'), get_string('actions'));
+    $table->head = array(get_string('name'),
+                         get_string('url', 'blog'),
+                         get_string('timefetched', 'blog'),
+                         get_string('valid', 'blog'),
+                         get_string('actions'));
 
     foreach ($blogs as $blog) {
         if ($blog->failedlastsync) {
@@ -92,7 +97,11 @@ if (!empty($blogs)) {
         $deletelink = new moodle_url('/blog/external_blogs.php', array('delete' => $blog->id, 'sesskey'=>sesskey()));
         $deleteicon = $OUTPUT->action_icon($deletelink, new pix_icon('t/delete', get_string('deleteexternalblog', 'blog')));
 
-        $table->data[] = new html_table_row(array($blog->name, $blog->url, userdate($blog->timefetched), $validicon, $editicon . '&nbsp'. $deleteicon));
+        $table->data[] = new html_table_row(array($blog->name,
+                                                  $blog->url,
+                                                  userdate($blog->timefetched),
+                                                  $validicon,
+                                                  $editicon . '&nbsp'. $deleteicon));
     }
     echo html_writer::table($table);
 }
index efa99ea..4c58f34 100644 (file)
@@ -1,4 +1,18 @@
 <?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/>.
 
 /**
  * file index.php
@@ -34,11 +48,7 @@ foreach ($url_params as $var => $val) {
 }
 $PAGE->set_url('/blog/index.php', $url_params);
 
-if (empty($CFG->enableblogs)) {
-    print_error('blogdisable', 'blog');
-}
-
-//correct tagid if a text tag is provided as a param
+// Correct tagid if a text tag is provided as a param.
 if (!empty($tag)) {
     if ($tagrec = $DB->get_record('tag', array('name' => $tag))) {
         $tagid = $tagrec->id;
@@ -47,43 +57,47 @@ if (!empty($tag)) {
     }
 }
 
-// add courseid if modid or groupid is specified: This is used for navigation and title
-if (!empty($modid) && empty($courseid)) {
-    $courseid = $DB->get_field('course_modules', 'course', array('id'=>$modid));
-}
-
-if (!empty($groupid) && empty($courseid)) {
-    $courseid = $DB->get_field('groups', 'courseid', array('id'=>$groupid));
-}
-
 $sitecontext = context_system::instance();
 // Blogs are always in system context.
 $PAGE->set_context($sitecontext);
 
-// check basic permissions
+// Check basic permissions.
 if ($CFG->bloglevel == BLOG_GLOBAL_LEVEL) {
-    // everybody can see anything - no login required unless site is locked down using forcelogin
+    // Everybody can see anything - no login required unless site is locked down using forcelogin.
     if ($CFG->forcelogin) {
         require_login();
     }
 
 } else if ($CFG->bloglevel == BLOG_SITE_LEVEL) {
-    // users must log in and can not be guests
+    // Users must log in and can not be guests.
     require_login();
     if (isguestuser()) {
-        // they must have entered the url manually...
+        // They must have entered the url manually.
         print_error('blogdisable', 'blog');
     }
 
 } else if ($CFG->bloglevel == BLOG_USER_LEVEL) {
-    // users can see own blogs only! with the exception of ppl with special cap
+    // Users can see own blogs only! with the exception of people with special cap.
     require_login();
 
 } else {
-    // weird!
+    // Weird!
     print_error('blogdisable', 'blog');
 }
 
+if (empty($CFG->enableblogs)) {
+    print_error('blogdisable', 'blog');
+}
+
+// Add courseid if modid or groupid is specified: This is used for navigation and title.
+if (!empty($modid) && empty($courseid)) {
+    $courseid = $DB->get_field('course_modules', 'course', array('id' => $modid));
+}
+
+if (!empty($groupid) && empty($courseid)) {
+    $courseid = $DB->get_field('groups', 'courseid', array('id' => $groupid));
+}
+
 
 if (!$userid && has_capability('moodle/blog:view', $sitecontext) && $CFG->bloglevel > BLOG_USER_LEVEL) {
     if ($entryid) {
@@ -206,13 +220,10 @@ if ($CFG->enablerssfeeds) {
     }
     $rsstitle = $blogheaders['heading'];
 
-    //check we haven't started output by outputting an error message
+    // Check we haven't started output by outputting an error message.
     if ($PAGE->state == moodle_page::STATE_BEFORE_HEADER) {
         blog_rss_add_http_header($rsscontext, $rsstitle, $filtertype, $thingid, $tagid);
     }
-
-    //this works but there isn't a great place to put the link
-    //blog_rss_print_link($rsscontext, $filtertype, $thingid, $tagid);
 }
 
 echo $OUTPUT->header();
index 9190e46..5b26916 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -26,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-/**
+/*
  * Library of functions and constants for blog
  */
 require_once($CFG->dirroot .'/blog/rsslib.php');
@@ -45,11 +44,11 @@ function blog_user_can_edit_entry($blogentry) {
     $sitecontext = context_system::instance();
 
     if (has_capability('moodle/blog:manageentries', $sitecontext)) {
-        return true; // can edit any blog entry
+        return true; // Can edit any blog entry.
     }
 
     if ($blogentry->userid == $USER->id && has_capability('moodle/blog:create', $sitecontext)) {
-        return true; // can edit own when having blog:create capability
+        return true; // Can edit own when having blog:create capability.
     }
 
     return false;
@@ -168,12 +167,12 @@ function blog_sync_external_entries($externalblog) {
     if (empty($rss->data)) {
         return null;
     }
-    //used to identify blog posts that have been deleted from the source feed
+    // Used to identify blog posts that have been deleted from the source feed.
     $oldesttimestamp = null;
     $uniquehashes = array();
 
     foreach ($rss->get_items() as $entry) {
-        // If filtertags are defined, use them to filter the entries by RSS category
+        // If filtertags are defined, use them to filter the entries by RSS category.
         if (!empty($externalblog->filtertags)) {
             $containsfiltertag = false;
             $categories = $entry->get_categories();
@@ -201,26 +200,26 @@ function blog_sync_external_entries($externalblog) {
         $newentry->uniquehash = $entry->get_permalink();
         $newentry->publishstate = 'site';
         $newentry->format = FORMAT_HTML;
-        // Clean subject of html, just in case
+        // Clean subject of html, just in case.
         $newentry->subject = clean_param($entry->get_title(), PARAM_TEXT);
-        // Observe 128 max chars in DB
-        // TODO: +1 to raise this to 255
+        // Observe 128 max chars in DB.
+        // TODO: +1 to raise this to 255.
         if (core_text::strlen($newentry->subject) > 128) {
             $newentry->subject = core_text::substr($newentry->subject, 0, 125) . '...';
         }
         $newentry->summary = $entry->get_description();
 
-        //used to decide whether to insert or update
-        //uses enty permalink plus creation date if available
+        // Used to decide whether to insert or update.
+        // Uses enty permalink plus creation date if available.
         $existingpostconditions = array('uniquehash' => $entry->get_permalink());
 
-        //our DB doesnt allow null creation or modified timestamps so check the external blog supplied one
+        // Our DB doesnt allow null creation or modified timestamps so check the external blog supplied one.
         $entrydate = $entry->get_date('U');
         if (!empty($entrydate)) {
             $existingpostconditions['created'] = $entrydate;
         }
 
-        //the post ID or false if post not found in DB
+        // The post ID or false if post not found in DB.
         $postid = $DB->get_field('post', 'id', $existingpostconditions);
 
         $timestamp = null;
@@ -230,14 +229,14 @@ function blog_sync_external_entries($externalblog) {
             $timestamp = $entrydate;
         }
 
-        //only set created if its a new post so we retain the original creation timestamp if the post is edited
+        // Only set created if its a new post so we retain the original creation timestamp if the post is edited.
         if ($postid === false) {
             $newentry->created = $timestamp;
         }
         $newentry->lastmodified = $timestamp;
 
         if (empty($oldesttimestamp) || $timestamp < $oldesttimestamp) {
-            //found an older post
+            // Found an older post.
             $oldesttimestamp = $timestamp;
         }
 
@@ -252,7 +251,7 @@ function blog_sync_external_entries($externalblog) {
         if ($postid === false) {
             $id = $DB->insert_record('post', $newentry);
 
-            // Set tags
+            // Set tags.
             if ($tags = tag_get_tags_array('blog_external', $externalblog->id)) {
                 tag_set('post', $id, $tags, 'core', context_user::instance($externalblog->userid)->id);
             }
@@ -273,7 +272,7 @@ function blog_sync_external_entries($externalblog) {
     $dbposts = $DB->get_records_sql($sql, array('blogid' => $externalblog->id, 'ts' => $oldesttimestamp));
 
     $todelete = array();
-    foreach($dbposts as $dbpost) {
+    foreach ($dbposts as $dbpost) {
         if ( !in_array($dbpost->uniquehash, $uniquehashes) ) {
             $todelete[] = $dbpost->id;
         }
@@ -324,13 +323,13 @@ function blog_get_all_options(moodle_page $page, stdClass $userid = null) {
 
     $options = array();
 
-    // If blogs are enabled and the user is logged in and not a guest
+    // If blogs are enabled and the user is logged in and not a guest.
     if (blog_is_enabled_for_user()) {
-        // If the context is the user then assume we want to load for the users context
+        // If the context is the user then assume we want to load for the users context.
         if (is_null($userid) && $page->context->contextlevel == CONTEXT_USER) {
             $userid = $page->context->instanceid;
         }
-        // Check the userid var
+        // Check the userid var.
         if (!is_null($userid) && $userid!==$USER->id) {
             // Load the user from the userid... it MUST EXIST throw a wobbly if it doesn't!
             $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
@@ -339,33 +338,36 @@ function blog_get_all_options(moodle_page $page, stdClass $userid = null) {
         }
 
         if ($CFG->useblogassociations && $page->cm !== null) {
-            // Load for the module associated with the page
+            // Load for the module associated with the page.
             $options[CONTEXT_MODULE] = blog_get_options_for_module($page->cm, $user);
         } else if ($CFG->useblogassociations && $page->course->id != SITEID) {
-            // Load the options for the course associated with the page
+            // Load the options for the course associated with the page.
             $options[CONTEXT_COURSE] = blog_get_options_for_course($page->course, $user);
         }
 
-        // Get the options for the user
+        // Get the options for the user.
         if ($user !== null and !isguestuser($user)) {
-            // Load for the requested user
+            // Load for the requested user.
             $options[CONTEXT_USER+1] = blog_get_options_for_user($user);
         }
-        // Load for the current user
+        // Load for the current user.
         if (isloggedin() and !isguestuser()) {
             $options[CONTEXT_USER] = blog_get_options_for_user();
         }
     }
 
-    // If blog level is global then display a link to view all site entries
-    if (!empty($CFG->enableblogs) && $CFG->bloglevel >= BLOG_GLOBAL_LEVEL && has_capability('moodle/blog:view', context_system::instance())) {
+    // If blog level is global then display a link to view all site entries.
+    if (!empty($CFG->enableblogs)
+        && $CFG->bloglevel >= BLOG_GLOBAL_LEVEL
+        && has_capability('moodle/blog:view', context_system::instance())) {
+
         $options[CONTEXT_SYSTEM] = array('viewsite' => array(
             'string' => get_string('viewsiteentries', 'blog'),
             'link' => new moodle_url('/blog/index.php')
         ));
     }
 
-    // Return the options
+    // Return the options.
     return $options;
 }
 
@@ -380,16 +382,16 @@ function blog_get_all_options(moodle_page $page, stdClass $userid = null) {
  */
 function blog_get_options_for_user(stdClass $user=null) {
     global $CFG, $USER;
-    // Cache
+    // Cache.
     static $useroptions = array();
 
     $options = array();
-    // Blogs must be enabled and the user must be logged in
+    // Blogs must be enabled and the user must be logged in.
     if (!blog_is_enabled_for_user()) {
         return $options;
     }
 
-    // Sort out the user var
+    // Sort out the user var.
     if ($user === null || $user->id == $USER->id) {
         $user = $USER;
         $iscurrentuser = true;
@@ -397,7 +399,7 @@ function blog_get_options_for_user(stdClass $user=null) {
         $iscurrentuser = false;
     }
 
-    // If we've already generated serve from the cache
+    // If we've already generated serve from the cache.
     if (array_key_exists($user->id, $useroptions)) {
         return $useroptions[$user->id];
     }
@@ -406,22 +408,22 @@ function blog_get_options_for_user(stdClass $user=null) {
     $canview = has_capability('moodle/blog:view', $sitecontext);
 
     if (!$iscurrentuser && $canview && ($CFG->bloglevel >= BLOG_SITE_LEVEL)) {
-        // Not the current user, but we can view and its blogs are enabled for SITE or GLOBAL
+        // Not the current user, but we can view and its blogs are enabled for SITE or GLOBAL.
         $options['userentries'] = array(
             'string' => get_string('viewuserentries', 'blog', fullname($user)),
             'link' => new moodle_url('/blog/index.php', array('userid'=>$user->id))
         );
     } else {
-        // It's the current user
+        // It's the current user.
         if ($canview) {
-            // We can view our own blogs .... BIG surprise
+            // We can view our own blogs .... BIG surprise.
             $options['view'] = array(
                 'string' => get_string('viewallmyentries', 'blog'),
                 'link' => new moodle_url('/blog/index.php', array('userid'=>$USER->id))
             );
         }
         if (has_capability('moodle/blog:create', $sitecontext)) {
-            // We can add to our own blog
+            // We can add to our own blog.
             $options['add'] = array(
                 'string' => get_string('addnewentry', 'blog'),
                 'link' => new moodle_url('/blog/edit.php', array('action'=>'add'))
@@ -432,12 +434,12 @@ function blog_get_options_for_user(stdClass $user=null) {
         $options['rss'] = array(
             'string' => get_string('rssfeed', 'blog'),
             'link' => new moodle_url(rss_get_url($sitecontext->id, $USER->id, 'blog', 'user/'.$user->id))
-       );
+        );
     }
 
-    // Cache the options
+    // Cache the options.
     $useroptions[$user->id] = $options;
-    // Return the options
+    // Return the options.
     return $options;
 }
 
@@ -451,47 +453,46 @@ function blog_get_options_for_user(stdClass $user=null) {
  */
 function blog_get_options_for_course(stdClass $course, stdClass $user=null) {
     global $CFG, $USER;
-    // Cache
+    // Cache.
     static $courseoptions = array();
 
     $options = array();
 
-    // User must be logged in and blogs must be enabled
+    // User must be logged in and blogs must be enabled.
     if (!blog_is_enabled_for_user()) {
         return $options;
     }
 
-    // Check that the user can associate with the course
+    // Check that the user can associate with the course.
     $sitecontext = context_system::instance();
-    // Generate the cache key
+    // Generate the cache key.
     $key = $course->id.':';
     if (!empty($user)) {
         $key .= $user->id;
     } else {
         $key .= $USER->id;
     }
-    // Serve from the cache if we've already generated for this course
+    // Serve from the cache if we've already generated for this course.
     if (array_key_exists($key, $courseoptions)) {
         return $courseoptions[$key];
     }
 
-
     if (has_capability('moodle/blog:view', $sitecontext)) {
         // We can view!
         if ($CFG->bloglevel >= BLOG_SITE_LEVEL) {
-            // View entries about this course
+            // View entries about this course.
             $options['courseview'] = array(
                 'string' => get_string('viewcourseblogs', 'blog'),
                 'link' => new moodle_url('/blog/index.php', array('courseid' => $course->id))
             );
         }
-        // View MY entries about this course
+        // View MY entries about this course.
         $options['courseviewmine'] = array(
             'string' => get_string('viewmyentriesaboutcourse', 'blog'),
             'link' => new moodle_url('/blog/index.php', array('courseid' => $course->id, 'userid' => $USER->id))
         );
         if (!empty($user) && ($CFG->bloglevel >= BLOG_SITE_LEVEL)) {
-            // View the provided users entries about this course
+            // View the provided users entries about this course.
             $options['courseviewuser'] = array(
                 'string' => get_string('viewentriesbyuseraboutcourse', 'blog', fullname($user)),
                 'link' => new moodle_url('/blog/index.php', array('courseid' => $course->id, 'userid' => $user->id))
@@ -500,17 +501,16 @@ function blog_get_options_for_course(stdClass $course, stdClass $user=null) {
     }
 
     if (has_capability('moodle/blog:create', $sitecontext)) {
-        // We can blog about this course
+        // We can blog about this course.
         $options['courseadd'] = array(
             'string' => get_string('blogaboutthiscourse', 'blog'),
             'link' => new moodle_url('/blog/edit.php', array('action' => 'add', 'courseid' => $course->id))
         );
     }
 
-
-    // Cache the options for this course
+    // Cache the options for this course.
     $courseoptions[$key] = $options;
-    // Return the options
+    // Return the options.
     return $options;
 }
 
@@ -524,18 +524,18 @@ function blog_get_options_for_course(stdClass $course, stdClass $user=null) {
  */
 function blog_get_options_for_module($module, $user=null) {
     global $CFG, $USER;
-    // Cache
+    // Cache.
     static $moduleoptions = array();
 
     $options = array();
-    // User must be logged in, blogs must be enabled
+    // User must be logged in, blogs must be enabled.
     if (!blog_is_enabled_for_user()) {
         return $options;
     }
 
     $sitecontext = context_system::instance();
 
-    // Generate the cache key
+    // Generate the cache key.
     $key = $module->id.':';
     if (!empty($user)) {
         $key .= $user->id;
@@ -543,18 +543,17 @@ function blog_get_options_for_module($module, $user=null) {
         $key .= $USER->id;
     }
     if (array_key_exists($key, $moduleoptions)) {
-        // Serve from the cache so we don't have to regenerate
+        // Serve from the cache so we don't have to regenerate.
         return $moduleoptions[$key];
     }
 
-
     if (has_capability('moodle/blog:view', $sitecontext)) {
         // Save correct module name for later usage.
         $modulename = get_string('modulename', $module->modname);
 
         // We can view!
         if ($CFG->bloglevel >= BLOG_SITE_LEVEL) {
-            // View all entries about this module
+            // View all entries about this module.
             $a = new stdClass;
             $a->type = $modulename;
             $options['moduleview'] = array(
@@ -562,13 +561,13 @@ function blog_get_options_for_module($module, $user=null) {
                 'link' => new moodle_url('/blog/index.php', array('modid'=>$module->id))
             );
         }
-        // View MY entries about this module
+        // View MY entries about this module.
         $options['moduleviewmine'] = array(
             'string' => get_string('viewmyentriesaboutmodule', 'blog', $modulename),
             'link' => new moodle_url('/blog/index.php', array('modid'=>$module->id, 'userid'=>$USER->id))
         );
         if (!empty($user) && ($CFG->bloglevel >= BLOG_SITE_LEVEL)) {
-            // View the given users entries about this module
+            // View the given users entries about this module.
             $a = new stdClass;
             $a->mod = $modulename;
             $a->user = fullname($user);
@@ -580,15 +579,15 @@ function blog_get_options_for_module($module, $user=null) {
     }
 
     if (has_capability('moodle/blog:create', $sitecontext)) {
-        // The user can blog about this module
+        // The user can blog about this module.
         $options['moduleadd'] = array(
             'string' => get_string('blogaboutthismodule', 'blog', $modulename),
             'link' => new moodle_url('/blog/edit.php', array('action'=>'add', 'modid'=>$module->id))
         );
     }
-    // Cache the options
+    // Cache the options.
     $moduleoptions[$key] = $options;
-    // Return the options
+    // Return the options.
     return $options;
 }
 
@@ -626,7 +625,7 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
     $action   = optional_param('action', null, PARAM_ALPHA);
     $confirm  = optional_param('confirm', false, PARAM_BOOL);
 
-    // Ignore userid when action == add
+    // Ignore userid when action == add.
     if ($action == 'add' && $userid) {
         unset($userid);
         $PAGE->url->remove_params(array('userid'));
@@ -644,11 +643,11 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
 
     $site = $DB->get_record('course', array('id' => SITEID));
     $sitecontext = context_system::instance();
-    // Common Lang strings
+    // Common Lang strings.
     $strparticipants = get_string("participants");
     $strblogentries  = get_string("blogentries", 'blog');
 
-    // Prepare record objects as needed
+    // Prepare record objects as needed.
     if (!empty($courseid)) {
         $headers['filters']['course'] = $courseid;
         $course = $DB->get_record('course', array('id' => $courseid));
@@ -659,7 +658,7 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $user = $DB->get_record('user', array('id' => $userid));
     }
 
-    if (!empty($groupid)) { // groupid always overrides courseid
+    if (!empty($groupid)) { // The groupid always overrides courseid.
         $headers['filters']['group'] = $groupid;
         $group = $DB->get_record('groups', array('id' => $groupid));
         $course = $DB->get_record('course', array('id' => $group->courseid));
@@ -667,11 +666,11 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
 
     $PAGE->set_pagelayout('standard');
 
-    // modid always overrides courseid, so the $course object may be reset here
+    // The modid always overrides courseid, so the $course object may be reset here.
     if (!empty($modid) && $CFG->useblogassociations) {
 
         $headers['filters']['module'] = $modid;
-        // A groupid param may conflict with this coursemod's courseid. Ignore groupid in that case
+        // A groupid param may conflict with this coursemod's courseid. Ignore groupid in that case.
         $courseid = $DB->get_field('course_modules', 'course', array('id'=>$modid));
         $course = $DB->get_record('course', array('id' => $courseid));
         $cm = $DB->get_record('course_modules', array('id' => $modid));
@@ -685,17 +684,16 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
     }
 
     // Case 1: No entry, mod, course or user params: all site entries to be shown (filtered by search and tag/tagid)
-    // Note: if action is set to 'add' or 'edit', we do this at the end
+    // Note: if action is set to 'add' or 'edit', we do this at the end.
     if (empty($entryid) && empty($modid) && empty($courseid) && empty($userid) && !in_array($action, array('edit', 'add'))) {
         $shortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $PAGE->navbar->add($strblogentries, $blogurl);
         $PAGE->set_title("$shortname: " . get_string('blog', 'blog'));
         $PAGE->set_heading("$shortname: " . get_string('blog', 'blog'));
         $headers['heading'] = get_string('siteblog', 'blog', $shortname);
-        // $headers['strview'] = get_string('viewsiteentries', 'blog');
     }
 
-    // Case 2: only entryid is requested, ignore all other filters. courseid is used to give more contextual information
+    // Case 2: only entryid is requested, ignore all other filters. courseid is used to give more contextual information.
     if (!empty($entryid)) {
         $headers['filters']['entry'] = $entryid;
         $sql = 'SELECT u.* FROM {user} u, {post} p WHERE p.id = ? AND p.userid = u.id';
@@ -720,15 +718,16 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $PAGE->set_heading("$shortname: " . fullname($user) . ": $entry->subject");
         $headers['heading'] = get_string('blogentrybyuser', 'blog', fullname($user));
 
-        // We ignore tag and search params
+        // We ignore tag and search params.
         if (empty($action) || !$CFG->useblogassociations) {
             $headers['url'] = $blogurl;
             return $headers;
         }
     }
 
-    // Case 3: A user's blog entries
     if (!empty($userid) && empty($entryid) && ((empty($courseid) && empty($modid)) || !$CFG->useblogassociations)) {
+        // Case 3: A user's blog entries.
+
         $shortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $blogurl->param('userid', $userid);
         $PAGE->set_title("$shortname: " . fullname($user) . ": " . get_string('blog', 'blog'));
@@ -736,23 +735,21 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $headers['heading'] = get_string('userblog', 'blog', fullname($user));
         $headers['strview'] = get_string('viewuserentries', 'blog', fullname($user));
 
-    } else
+    } else if (!$CFG->useblogassociations && empty($userid) && !in_array($action, array('edit', 'add'))) {
+        // Case 4: No blog associations, no userid.
 
-    // Case 4: No blog associations, no userid
-    if (!$CFG->useblogassociations && empty($userid) && !in_array($action, array('edit', 'add'))) {
         $shortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $PAGE->set_title("$shortname: " . get_string('blog', 'blog'));
         $PAGE->set_heading("$shortname: " . get_string('blog', 'blog'));
         $headers['heading'] = get_string('siteblog', 'blog', $shortname);
-    } else
+    } else if (!empty($userid) && !empty($modid) && empty($entryid)) {
+        // Case 5: Blog entries associated with an activity by a specific user (courseid ignored).
 
-    // Case 5: Blog entries associated with an activity by a specific user (courseid ignored)
-    if (!empty($userid) && !empty($modid) && empty($entryid)) {
         $shortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $blogurl->param('userid', $userid);
         $blogurl->param('modid', $modid);
 
-        // Course module navigation is handled by build_navigation as the second param
+        // Course module navigation is handled by build_navigation as the second param.
         $headers['cm'] = $cm;
         $PAGE->navbar->add(fullname($user), "$CFG->wwwroot/user/view.php?id=$user->id");
         $PAGE->navbar->add($strblogentries, $blogurl);
@@ -767,10 +764,9 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $headers['heading'] = get_string('blogentriesbyuseraboutmodule', 'blog', $a);
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
         $headers['strview'] = get_string('viewallmodentries', 'blog', $a);
-    } else
+    } else if (!empty($userid) && !empty($courseid) && empty($modid) && empty($entryid)) {
+        // Case 6: Blog entries associated with a course by a specific user.
 
-    // Case 6: Blog entries associated with a course by a specific user
-    if (!empty($userid) && !empty($courseid) && empty($modid) && empty($entryid)) {
         $siteshortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
         $blogurl->param('userid', $userid);
@@ -789,12 +785,11 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
         $headers['strview'] = get_string('viewblogentries', 'blog', $a);
 
-        // Remove the userid from the URL to inform the blog_menu block correctly
+        // Remove the userid from the URL to inform the blog_menu block correctly.
         $blogurl->remove_params(array('userid'));
-    } else
+    } else if (!empty($groupid) && empty($modid) && empty($entryid)) {
+        // Case 7: Blog entries by members of a group, associated with that group's course.
 
-    // Case 7: Blog entries by members of a group, associated with that group's course
-    if (!empty($groupid) && empty($modid) && empty($entryid)) {
         $siteshortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
         $blogurl->param('courseid', $course->id);
@@ -814,10 +809,9 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $headers['heading'] = get_string('blogentriesbygroupaboutcourse', 'blog', $a);
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
         $headers['strview'] = get_string('viewblogentries', 'blog', $a);
-    } else
+    } else if (!empty($groupid) && !empty($modid) && empty($entryid)) {
+        // Case 8: Blog entries by members of a group, associated with an activity in that course.
 
-    // Case 8: Blog entries by members of a group, associated with an activity in that course
-    if (!empty($groupid) && !empty($modid) && empty($entryid)) {
         $siteshortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
         $headers['cm'] = $cm;
@@ -838,10 +832,9 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
         $headers['strview'] = get_string('viewallmodentries', 'blog', $a);
 
-    } else
+    } else if (!empty($modid) && empty($userid) && empty($groupid) && empty($entryid)) {
+        // Case 9: All blog entries associated with an activity.
 
-    // Case 9: All blog entries associated with an activity
-    if (!empty($modid) && empty($userid) && empty($groupid) && empty($entryid)) {
         $siteshortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
         $PAGE->set_cm($cm, $course);
@@ -854,10 +847,9 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $a->type = get_string('modulename', $cm->modname);
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
         $headers['strview'] = get_string('viewallmodentries', 'blog', $a);
-    } else
+    } else if (!empty($courseid) && empty($userid) && empty($groupid) && empty($modid) && empty($entryid)) {
+        // Case 10: All blog entries associated with a course.
 
-    // Case 10: All blog entries associated with a course
-    if (!empty($courseid) && empty($userid) && empty($groupid) && empty($modid) && empty($entryid)) {
         $siteshortname = format_string($site->shortname, true, array('context' => context_course::instance(SITEID)));
         $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
         $blogurl->param('courseid', $courseid);
@@ -866,20 +858,24 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         $PAGE->set_heading("$siteshortname: $courseshortname: " . get_string('blogentries', 'blog'));
         $a = new stdClass();
         $a->type = get_string('course');
-        $headers['heading'] = get_string('blogentriesabout', 'blog', format_string($course->fullname, true, array('context' => context_course::instance($course->id))));
+        $headers['heading'] = get_string('blogentriesabout',
+                                         'blog',
+                                         format_string($course->fullname,
+                                                       true,
+                                                       array('context' => context_course::instance($course->id))));
         $headers['stradd'] = get_string('blogaboutthis', 'blog', $a);
         $headers['strview'] = get_string('viewblogentries', 'blog', $a);
         $blogurl->remove_params(array('userid'));
     }
 
     if (!in_array($action, array('edit', 'add'))) {
-        // Append Tag info
+        // Append Tag info.
         if (!empty($tagid)) {
             $headers['filters']['tag'] = $tagid;
             $blogurl->param('tagid', $tagid);
             $tagrec = $DB->get_record('tag', array('id'=>$tagid));
             $PAGE->navbar->add($tagrec->name, $blogurl);
-        } elseif (!empty($tag)) {
+        } else if (!empty($tag)) {
             if ($tagrec = $DB->get_record('tag', array('name' => $tag))) {
                 $tagid = $tagrec->id;
                 $headers['filters']['tag'] = $tagid;
@@ -888,7 +884,7 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
             }
         }
 
-        // Append Search info
+        // Append Search info.
         if (!empty($search)) {
             $headers['filters']['search'] = $search;
             $blogurl->param('search', $search);
@@ -896,7 +892,7 @@ function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=nu
         }
     }
 
-    // Append edit mode info
+    // Append edit mode info.
     if (!empty($action) && $action == 'add') {
 
     } else if (!empty($action) && $action == 'edit') {
index 5561050..5df39ad 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -40,7 +39,7 @@ require_once($CFG->libdir . '/filelib.php');
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class blog_entry implements renderable {
-    // Public Database fields
+    // Public Database fields.
     public $id;
     public $userid;
     public $subject;
@@ -49,7 +48,7 @@ class blog_entry implements renderable {
     public $attachment;
     public $publishstate;
 
-    // Locked Database fields (Don't touch these)
+    // Locked Database fields (Don't touch these).
     public $courseid = 0;
     public $groupid = 0;
     public $module = 'blog';
@@ -62,14 +61,13 @@ class blog_entry implements renderable {
     public $created;
     public $usermodified;
 
-    // Other class variables
+    // Other class variables.
     public $form;
     public $tags = array();
 
     /** @var StdClass Data needed to render the entry */
     public $renderable;
 
-    // Methods
     /**
      * Constructor. If given an id, will fetch the corresponding record from the DB.
      *
@@ -137,11 +135,12 @@ class blog_entry implements renderable {
             if ($externalblog = $DB->get_record('blog_external', array('id' => $this->content))) {
                 $urlparts = parse_url($externalblog->url);
                 $this->renderable->externalblogtext = get_string('retrievedfrom', 'blog') . get_string('labelsep', 'langconfig');
-                $this->renderable->externalblogtext .= html_writer::link($urlparts['scheme'] . '://'.$urlparts['host'], $externalblog->name);
+                $this->renderable->externalblogtext .= html_writer::link($urlparts['scheme'] . '://' . $urlparts['host'],
+                                                                         $externalblog->name);
             }
         }
 
-        // Retrieve associations
+        // Retrieve associations.
         $this->renderable->unassociatedentry = false;
         if (!empty($CFG->useblogassociations)) {
 
@@ -165,9 +164,11 @@ class blog_entry implements renderable {
 
                     // Course associations.
                     if ($context->contextlevel ==  CONTEXT_COURSE) {
-                        $instancename = $DB->get_field('course', 'shortname', array('id' => $context->instanceid)); //TODO: performance!!!!
+                        // TODO: performance!!!!
+                        $instancename = $DB->get_field('course', 'shortname', array('id' => $context->instanceid));
 
-                        $associations[$key]->url = $assocurl = new moodle_url('/course/view.php', array('id' => $context->instanceid));
+                        $associations[$key]->url = $assocurl = new moodle_url('/course/view.php',
+                                                                              array('id' => $context->instanceid));
                         $associations[$key]->text = $instancename;
                         $associations[$key]->icon = new pix_icon('i/course', $associations[$key]->text);
                     }
@@ -175,15 +176,17 @@ class blog_entry implements renderable {
                     // Mod associations.
                     if ($context->contextlevel ==  CONTEXT_MODULE) {
 
-                        // Getting the activity type and the activity instance id
+                        // Getting the activity type and the activity instance id.
                         $sql = 'SELECT cm.instance, m.name FROM {course_modules} cm
                                   JOIN {modules} m ON m.id = cm.module
                                  WHERE cm.id = :cmid';
                         $modinfo = $DB->get_record_sql($sql, array('cmid' => $context->instanceid));
-                        $instancename = $DB->get_field($modinfo->name, 'name', array('id' => $modinfo->instance)); //TODO: performance!!!!
+                        // TODO: performance!!!!
+                        $instancename = $DB->get_field($modinfo->name, 'name', array('id' => $modinfo->instance));
 
                         $associations[$key]->type = get_string('modulename', $modinfo->name);
-                        $associations[$key]->url = new moodle_url('/mod/' . $modinfo->name . '/view.php', array('id' => $context->instanceid));
+                        $associations[$key]->url = new moodle_url('/mod/' . $modinfo->name . '/view.php',
+                                                                  array('id' => $context->instanceid));
                         $associations[$key]->text = $instancename;
                         $associations[$key]->icon = new pix_icon('icon', $associations[$key]->text, $modinfo->name);
                     }
@@ -203,7 +206,7 @@ class blog_entry implements renderable {
      * Gets the entry attachments list
      * @return array List of blog_entry_attachment instances
      */
-    function get_attachments() {
+    public function get_attachments() {
 
         global $CFG;
 
@@ -293,7 +296,13 @@ class blog_entry implements renderable {
         }
 
         $entry = file_postupdate_standard_editor($entry, 'summary', $summaryoptions, $sitecontext, 'blog', 'post', $entry->id);
-        $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $sitecontext, 'blog', 'attachment', $entry->id);
+        $entry = file_postupdate_standard_filemanager($entry,
+                                                      'attachment',
+                                                      $attachmentoptions,
+                                                      $sitecontext,
+                                                      'blog',
+                                                      'attachment',
+                                                      $entry->id);
 
         if (!empty($CFG->useblogassociations)) {
             $entry->add_associations();
@@ -427,7 +436,7 @@ class blog_entry implements renderable {
 
         if ($otags = optional_param('otags', '', PARAM_INT)) {
             foreach ($otags as $tagid) {
-                // TODO : make this use the tag name in the form
+                // TODO : make this use the tag name in the form.
                 if ($tag = tag_get('id', $tagid)) {
                     $tags[] = $tag->name;
                 }
@@ -456,11 +465,11 @@ class blog_entry implements renderable {
         $sitecontext = context_system::instance();
 
         if (has_capability('moodle/blog:manageentries', $sitecontext)) {
-            return true; // can edit any blog entry
+            return true; // Can edit any blog entry.
         }
 
         if ($this->userid == $userid && has_capability('moodle/blog:create', $sitecontext)) {
-            return true; // can edit own when having blog:create capability
+            return true; // Can edit own when having blog:create capability.
         }
 
         return false;
@@ -480,23 +489,23 @@ class blog_entry implements renderable {
         $sitecontext = context_system::instance();
 
         if (empty($CFG->enableblogs) || !has_capability('moodle/blog:view', $sitecontext)) {
-            return false; // blog system disabled or user has no blog view capability
+            return false; // Blog system disabled or user has no blog view capability.
         }
 
         if (isloggedin() && $USER->id == $targetuserid) {
-            return true; // can view own entries in any case
+            return true; // Can view own entries in any case.
         }
 
         if (has_capability('moodle/blog:manageentries', $sitecontext)) {
-            return true; // can manage all entries
+            return true; // Can manage all entries.
         }
 
-        // coming for 1 entry, make sure it's not a draft
+        // Coming for 1 entry, make sure it's not a draft.
         if ($this->publishstate == 'draft' && !has_capability('moodle/blog:viewdrafts', $sitecontext)) {
-            return false;  // can not view draft of others
+            return false;  // Can not view draft of others.
         }
 
-        // coming for 1 entry, make sure user is logged in, if not a public blog
+        // Coming for 1 entry, make sure user is logged in, if not a public blog.
         if ($this->publishstate != 'public' && !isloggedin()) {
             return false;
         }
@@ -507,7 +516,7 @@ class blog_entry implements renderable {
                 break;
 
             case BLOG_SITE_LEVEL:
-                if (isloggedin()) { // not logged in viewers forbidden
+                if (isloggedin()) { // Not logged in viewers forbidden.
                     return true;
                 }
                 return false;
@@ -533,7 +542,7 @@ class blog_entry implements renderable {
         global $CFG;
         $options = array();
 
-        // everyone gets draft access
+        // Everyone gets draft access.
         if ($CFG->bloglevel >= BLOG_USER_LEVEL) {
             $options['draft'] = get_string('publishtonoone', 'blog');
         }
@@ -577,7 +586,7 @@ class blog_listing {
      * @param array $filters An associative array of filtername => filterid
      */
     public function __construct($filters=array()) {
-        // Unset filters overridden by more specific filters
+        // Unset filters overridden by more specific filters.
         foreach ($filters as $type => $id) {
             if (!empty($type) && !empty($id)) {
                 $this->filters[$type] = blog_filter::get_instance($id, $type);
@@ -615,50 +624,53 @@ class blog_listing {
     public function get_entry_fetch_sql($count=false, $sort='lastmodified DESC', $userid = false) {
         global $DB, $USER, $CFG;
 
-        if(!$userid) {
+        if (!$userid) {
             $userid = $USER->id;
         }
 
         $allnamefields = get_all_user_name_fields(true, 'u');
         // The query used to locate blog entries is complicated.  It will be built from the following components:
-        $requiredfields = "p.*, $allnamefields, u.email";  // the SELECT clause
-        $tables = array('p' => 'post', 'u' => 'user');   // components of the FROM clause (table_id => table_name)
-        $conditions = array('u.deleted = 0', 'p.userid = u.id', '(p.module = \'blog\' OR p.module = \'blog_external\')');  // components of the WHERE clause (conjunction)
+        $requiredfields = "p.*, $allnamefields, u.email";  // The SELECT clause.
+        $tables = array('p' => 'post', 'u' => 'user');   // Components of the FROM clause (table_id => table_name).
+        // Components of the WHERE clause (conjunction).
+        $conditions = array('u.deleted = 0', 'p.userid = u.id', '(p.module = \'blog\' OR p.module = \'blog_external\')');
 
-        // build up a clause for permission constraints
+        // Build up a clause for permission constraints.
 
         $params = array();
 
-        // fix for MDL-9165, use with readuserblogs capability in a user context can read that user's private blogs
-        // admins can see all blogs regardless of publish states, as described on the help page
+        // Fix for MDL-9165, use with readuserblogs capability in a user context can read that user's private blogs.
+        // Admins can see all blogs regardless of publish states, as described on the help page.
         if (has_capability('moodle/user:readuserblogs', context_system::instance())) {
-            // don't add permission constraints
+            // Don't add permission constraints.
 
-        } else if(!empty($this->filters['user']) && has_capability('moodle/user:readuserblogs',
-                context_user::instance((empty($this->filters['user']->id) ? 0 : $this->filters['user']->id)))) {
-            // don't add permission constraints
+        } else if (!empty($this->filters['user'])
+                   && has_capability('moodle/user:readuserblogs',
+                                     context_user::instance((empty($this->filters['user']->id) ? 0 : $this->filters['user']->id)))) {
+            // Don't add permission constraints.
 
         } else {
             if (isloggedin() and !isguestuser()) {
-                $assocexists = $DB->record_exists('blog_association', array());  //dont check association records if there aren't any
+                // Dont check association records if there aren't any.
+                $assocexists = $DB->record_exists('blog_association', array());
 
-                //begin permission sql clause
+                // Begin permission sql clause.
                 $permissionsql =  '(p.userid = ? ';
                 $params[] = $userid;
 
-                if ($CFG->bloglevel >= BLOG_SITE_LEVEL) { // add permission to view site-level entries
+                if ($CFG->bloglevel >= BLOG_SITE_LEVEL) { // Add permission to view site-level entries.
                     $permissionsql .= " OR p.publishstate = 'site' ";
                 }
 
-                if ($CFG->bloglevel >= BLOG_GLOBAL_LEVEL) { // add permission to view global entries
+                if ($CFG->bloglevel >= BLOG_GLOBAL_LEVEL) { // Add permission to view global entries.
                     $permissionsql .= " OR p.publishstate = 'public' ";
                 }
 
-                $permissionsql .= ') ';   //close permissions sql clause
-            } else {  // default is access to public entries
+                $permissionsql .= ') ';   // Close permissions sql clause.
+            } else {  // Default is access to public entries.
                 $permissionsql = "p.publishstate = 'public'";
             }
-            $conditions[] = $permissionsql;  //add permission constraints
+            $conditions[] = $permissionsql;  // Add permission constraints.
         }
 
         foreach ($this->filters as $type => $blogfilter) {
@@ -667,7 +679,7 @@ class blog_listing {
             $tables = array_merge($tables, $blogfilter->tables);
         }
 
-        $tablessql = '';  // build up the FROM clause
+        $tablessql = '';  // Build up the FROM clause.
         foreach ($tables as $tablename => $table) {
             $tablessql .= ($tablessql ? ', ' : '').'{'.$table.'} '.$tablename;
         }
@@ -688,7 +700,7 @@ class blog_listing {
         global $CFG, $USER, $DB, $OUTPUT, $PAGE;
         $sitecontext = context_system::instance();
 
-        // Blog renderer
+        // Blog renderer.
         $output = $PAGE->get_renderer('blog');
 
         $page  = optional_param('blogpage', 0, PARAM_INT);
@@ -711,7 +723,7 @@ class blog_listing {
         echo $OUTPUT->render($pagingbar);
 
         if (has_capability('moodle/blog:create', $sitecontext)) {
-            //the user's blog is enabled and they are viewing their own blog
+            // The user's blog is enabled and they are viewing their own blog.
             $userid = optional_param('userid', null, PARAM_INT);
 
             if (empty($userid) || (!empty($userid) && $userid == $USER->id)) {
@@ -744,7 +756,7 @@ class blog_listing {
             foreach ($entries as $entry) {
                 $blogentry = new blog_entry(null, $entry);
 
-                // Get the required blog entry data to render it
+                // Get the required blog entry data to render it.
                 $blogentry->prepare_render();
                 echo $output->render($blogentry);
 
@@ -762,7 +774,7 @@ class blog_listing {
         }
     }
 
-    /// Find the base url from $_GET variables, for print_paging_bar
+    // Find the base url from $_GET variables, for print_paging_bar.
     public function get_baseurl() {
         $getcopy  = $_GET;
 
@@ -897,11 +909,13 @@ class blog_filter_context extends blog_filter {
             $this->type = $type;
         }
 
-        $this->availabletypes = array('site' => get_string('site'), 'course' => get_string('course'), 'module' => get_string('activity'));
+        $this->availabletypes = array('site' => get_string('site'),
+                                      'course' => get_string('course'),
+                                      'module' => get_string('activity'));
 
         switch ($this->type) {
             case 'course': // Careful of site course!
-                // Ignore course filter if blog associations are not enabled
+                // Ignore course filter if blog associations are not enabled.
                 if ($this->id != $SITE->id && !empty($CFG->useblogassociations)) {
                     $this->overrides = array('site');
                     $context = context_course::instance($this->id);
@@ -910,11 +924,11 @@ class blog_filter_context extends blog_filter {
                     $this->conditions[] = 'ba.contextid = '.$context->id;
                     break;
                 } else {
-                    // We are dealing with the site course, do not break from the current case
+                    // We are dealing with the site course, do not break from the current case.
                 }
 
             case 'site':
-                // No special constraints
+                // No special constraints.
                 break;
             case 'module':
                 if (!empty($CFG->useblogassociations)) {
@@ -961,7 +975,7 @@ class blog_filter_user extends blog_filter {
             $this->params = array($this->id);
             $this->overrides = array('group');
 
-        } elseif ($this->type == 'group') {
+        } else if ($this->type == 'group') {
             $this->overrides = array('course', 'site');
 
             $this->tables['gm'] = 'groups_members';
@@ -969,7 +983,7 @@ class blog_filter_user extends blog_filter {
             $this->conditions[] = 'gm.groupid = ?';
             $this->params[]     = $this->id;
 
-            if (!empty($CFG->useblogassociations)) {  // only show blog entries associated with this course
+            if (!empty($CFG->useblogassociations)) {  // Only show blog entries associated with this course.
                 $coursecontext     = context_course::instance($DB->get_field('groups', 'courseid', array('id' => $this->id)));
                 $this->tables['ba'] = 'blog_association';
                 $this->conditions[] = 'gm.groupid = ?';
@@ -1068,7 +1082,8 @@ class blog_entry_attachment implements renderable {
 
         $this->file = $file;
         $this->filename = $file->get_filename();
-        $this->url = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.SYSCONTEXTID.'/blog/attachment/'.$entryid.'/'.$this->filename);
+        $this->url = file_encode_url($CFG->wwwroot . '/pluginfile.php',
+                                     '/' . SYSCONTEXTID . '/blog/attachment/' . $entryid . '/' . $this->filename);
     }
 
 }
index e3d82fc..59aea44 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -66,7 +65,7 @@ if (empty($CFG->enableblogs)) {
 // The preference is site wide not blog specific. Hence user should have permissions in site level.
 require_capability('moodle/blog:view', $sitecontext);
 
-/// If data submitted, then process and store.
+// If data submitted, then process and store.
 
 $mform = new blog_preferences_form('preferences.php');
 $mform->set_data(array('pagesize' => get_user_preferences('blogpagesize')));
@@ -80,7 +79,7 @@ if (!$mform->is_cancelled() && $data = $mform->get_data()) {
     set_user_preference('blogpagesize', $pagesize);
 }
 
-if ($mform->is_cancelled()){
+if ($mform->is_cancelled()) {
     redirect($CFG->wwwroot . '/blog/index.php');
 }
 
index d5c5005..12edfed 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -26,7 +25,7 @@
  */
 
 if (!defined('MOODLE_INTERNAL')) {
-    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+    die('Direct access to this script is forbidden.');    //  It must be included from a Moodle page.
 }
 
 require_once($CFG->libdir.'/formslib.php');
index af1724d..832d4b1 100644 (file)
@@ -63,7 +63,9 @@ class core_blog_renderer extends plugin_renderer_base {
         $o .= $this->output->container_start('topic starter header clearfix');
 
         // Title.
-        $titlelink =  html_writer::link(new moodle_url('/blog/index.php', array('entryid' => $entry->id)), format_string($entry->subject));
+        $titlelink = html_writer::link(new moodle_url('/blog/index.php',
+                                                       array('entryid' => $entry->id)),
+                                                       format_string($entry->subject));
         $o .= $this->output->container($titlelink, 'subject');
 
         // Post by.
@@ -244,9 +246,14 @@ class core_blog_renderer extends plugin_renderer_base {
             $o = html_writer::empty_tag('img', $attrs);
             $class = 'attachedimages';
         } else {
-            $image = $this->output->pix_icon(file_file_icon($attachment->file), $attachment->filename, 'moodle', array('class'=>'icon'));
+            $image = $this->output->pix_icon(file_file_icon($attachment->file),
+                                             $attachment->filename,
+                                             'moodle',
+                                             array('class' => 'icon'));
             $o = html_writer::link($attachment->url, $image);
-            $o .= format_text(html_writer::link($attachment->url, $attachment->filename), FORMAT_HTML, array('context' => $syscontext));
+            $o .= format_text(html_writer::link($attachment->url, $attachment->filename),
+                              FORMAT_HTML,
+                              array('context' => $syscontext));
             $class = 'attachments';
         }
 
index 12854d6..3f26eb0 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -97,9 +96,6 @@ function blog_rss_print_link($context, $filtertype, $filterselect=0, $tagid=0, $
 function blog_rss_add_http_header($context, $title, $filtertype, $filterselect=0, $tagid=0) {
     global $PAGE, $USER, $CFG;
 
-    //$componentname = 'blog';
-    //rss_add_http_header($context, $componentname, $filterselect, $title);
-
     if (!isloggedin()) {
         $userid = $CFG->siteguest;
     } else {
@@ -159,7 +155,7 @@ function blog_rss_get_feed($context, $args) {
 
     if ($CFG->bloglevel == BLOG_SITE_LEVEL) {
         if (isguestuser()) {
-            debugging(get_string('nopermissiontoshow','error'));
+            debugging(get_string('nopermissiontoshow', 'error'));
             return '';
         }
     }
@@ -170,7 +166,7 @@ function blog_rss_get_feed($context, $args) {
     }
 
     $type  = clean_param($args[3], PARAM_ALPHA);
-    $id = clean_param($args[4], PARAM_INT);  // could be groupid / courseid  / userid  depending on $type
+    $id = clean_param($args[4], PARAM_INT);  // Could be groupid / courseid  / userid  depending on $type.
 
     $tagid=0;
     if ($args[5] != 'rss.xml') {
@@ -183,14 +179,13 @@ function blog_rss_get_feed($context, $args) {
 
     if (file_exists($filename)) {
         if (filemtime($filename) + 3600 > time()) {
-            return $filename;   // It's already done so we return cached version
+            return $filename;   // It's already done so we return cached version.
         }
     }
 
     $courseid = $groupid = $userid = null;
     switch ($type) {
         case 'site':
-            //$siteid = $id;
             break;
         case 'course':
             $courseid = $id;
@@ -203,26 +198,26 @@ function blog_rss_get_feed($context, $args) {
             break;
     }
 
-    // Get all the entries from the database
+    // Get all the entries from the database.
     require_once($CFG->dirroot .'/blog/locallib.php');
     $blogheaders = blog_get_headers($courseid, $groupid, $userid, $tagid);
 
     $bloglisting = new blog_listing($blogheaders['filters']);
     $blogentries = $bloglisting->get_entries();
 
-    // Now generate an array of RSS items
+    // Now generate an array of RSS items.
     if ($blogentries) {
         $items = array();
-        foreach ($blogentries as $blog_entry) {
-            $item = NULL;
-            $item->author = fullname($DB->get_record('user', array('id'=>$blog_entry->userid))); // TODO: this is slow
-            $item->title = $blog_entry->subject;
-            $item->pubdate = $blog_entry->lastmodified;
-            $item->link = $CFG->wwwroot.'/blog/index.php?entryid='.$blog_entry->id;
-            $summary = file_rewrite_pluginfile_urls($blog_entry->summary, 'pluginfile.php',
-                $sitecontext->id, 'blog', 'post', $blog_entry->id);
-            $item->description = format_text($summary, $blog_entry->format);
-            if ( !empty($CFG->usetags) && ($blogtags = tag_get_tags_array('post', $blog_entry->id)) ) {
+        foreach ($blogentries as $blogentry) {
+            $item = null;
+            $item->author = fullname($DB->get_record('user', array('id' => $blogentry->userid))); // TODO: this is slow.
+            $item->title = $blogentry->subject;
+            $item->pubdate = $blogentry->lastmodified;
+            $item->link = $CFG->wwwroot.'/blog/index.php?entryid='.$blogentry->id;
+            $summary = file_rewrite_pluginfile_urls($blogentry->summary, 'pluginfile.php',
+                $sitecontext->id, 'blog', 'post', $blogentry->id);
+            $item->description = format_text($summary, $blogentry->format);
+            if ( !empty($CFG->usetags) && ($blogtags = tag_get_tags_array('post', $blogentry->id)) ) {
                 if ($blogtags) {
                     $item->tags = $blogtags;
                 }
@@ -230,12 +225,12 @@ function blog_rss_get_feed($context, $args) {
             }
             $items[] = $item;
         }
-        $articles = rss_add_items($items);   /// Change structure to XML
+        $articles = rss_add_items($items);   // Change structure to XML.
     } else {
         $articles = '';
     }
 
-/// Get header and footer information
+    // Get header and footer information.
 
     switch ($type) {
         case 'user':
@@ -250,7 +245,7 @@ function blog_rss_get_feed($context, $args) {
             break;
         case 'group':
             $group = groups_get_group($id);
-            $info = $group->name; //TODO: $DB->get_field('groups', 'name', array('id'=>$id))
+            $info = $group->name; // TODO: $DB->get_field('groups', 'name', array('id'=>$id)).
             break;
         default:
             $info = '';
@@ -261,18 +256,18 @@ function blog_rss_get_feed($context, $args) {
         $info .= ': '.$DB->get_field('tags', 'text', array('id'=>$tagid));
     }
 
-    $header = rss_standard_header(get_string($type.'blog','blog', $info),
+    $header = rss_standard_header(get_string($type.'blog', 'blog', $info),
                                   $CFG->wwwroot.'/blog/index.php',
-                                  get_string('intro','blog'));
+                                  get_string('intro', 'blog'));
 
     $footer = rss_standard_footer();
 
     // Save the XML contents to file.
     $rssdata = $header.$articles.$footer;
-    if (blog_rss_save_file($type,$id,$tagid,$rssdata)) {
+    if (blog_rss_save_file($type, $id, $tagid, $rssdata)) {
         return $filename;
     } else {
-        return false;   // Couldn't find it or make it
+        return false;   // Couldn't find it or make it.
     }
 }
 
@@ -308,12 +303,12 @@ function blog_rss_save_file($type, $id, $tagid=0, $contents='') {
 
     $status = true;
 
-    //blog creates some additional dirs within the rss cache so make sure they all exist
+    // Blog creates some additional dirs within the rss cache so make sure they all exist.
     make_cache_directory('rss/blog');
     make_cache_directory('rss/blog/'.$type);
 
     $filename = blog_rss_file_name($type, $id, $tagid);
-    $expandfilename = false; //we're supplying a full file path
+    $expandfilename = false; // We are supplying a full file path.
     $status = rss_save_file('blog', $filename, $contents, $expandfilename);
 
     return $status;
index 2db2265..06b1f07 100644 (file)
@@ -32,7 +32,7 @@ require_once($CFG->dirroot . '/blog/lib.php');
  */
 class core_bloglib_testcase extends advanced_testcase {
 
-    private $courseid; // To store important ids to be used in tests
+    private $courseid;
     private $cmid;
     private $groupid;
     private $userid;
@@ -45,22 +45,22 @@ class core_bloglib_testcase extends advanced_testcase {
 
         $this->resetAfterTest();
 
-        // Create default course
+        // Create default course.
         $course = $this->getDataGenerator()->create_course(array('category'=>1, 'shortname'=>'ANON'));
         $this->assertNotEmpty($course);
         $page = $this->getDataGenerator()->create_module('page', array('course'=>$course->id));
         $this->assertNotEmpty($page);
 
-        // Create default group
+        // Create default group.
         $group = new stdClass();
         $group->courseid = $course->id;
         $group->name = 'ANON';
         $group->id = $DB->insert_record('groups', $group);
 
-        // Create default user
+        // Create default user.
         $user = $this->getDataGenerator()->create_user(array('username'=>'testuser', 'firstname'=>'Jimmy', 'lastname'=>'Kinnon'));
 
-        // Create default tag
+        // Create default tag.
         $tag = new stdClass();
         $tag->userid = $user->id;
         $tag->name = 'testtagname';
@@ -68,14 +68,14 @@ class core_bloglib_testcase extends advanced_testcase {
         $tag->tagtype = 'official';
         $tag->id = $DB->insert_record('tag', $tag);
 
-        // Create default post
+        // Create default post.
         $post = new stdClass();
         $post->userid = $user->id;
         $post->groupid = $group->id;
         $post->content = 'test post content text';
         $post->id = $DB->insert_record('post', $post);
 
-        // Grab important ids
+        // Grab important ids.
         $this->courseid = $course->id;
         $this->cmid = $page->cmid;
         $this->groupid  = $group->id;
@@ -88,7 +88,7 @@ class core_bloglib_testcase extends advanced_testcase {
     public function test_overrides() {
         global $SITE;
 
-        // Try all the filters at once: Only the entry filter is active
+        // Try all the filters at once: Only the entry filter is active.
         $filters = array('site' => $SITE->id, 'course' => $this->courseid, 'module' => $this->cmid,
             'group' => $this->groupid, 'user' => $this->userid, 'tag' => $this->tagid, 'entry' => $this->postid);
         $blog_listing = new blog_listing($filters);
@@ -100,7 +100,7 @@ class core_bloglib_testcase extends advanced_testcase {
         $this->assertFalse(array_key_exists('tag', $blog_listing->filters));
         $this->assertTrue(array_key_exists('entry', $blog_listing->filters));
 
-        // Again, but without the entry filter: This time, the tag, user and module filters are active
+        // Again, but without the entry filter: This time, the tag, user and module filters are active.
         $filters = array('site' => $SITE->id, 'course' => $this->courseid, 'module' => $this->cmid,
             'group' => $this->groupid, 'user' => $this->userid, 'tag' => $this->postid);
         $blog_listing = new blog_listing($filters);
@@ -111,7 +111,7 @@ class core_bloglib_testcase extends advanced_testcase {
         $this->assertTrue(array_key_exists('user', $blog_listing->filters));
         $this->assertTrue(array_key_exists('tag', $blog_listing->filters));
 
-        // We should get the same result by removing the 3 inactive filters: site, course and group:
+        // We should get the same result by removing the 3 inactive filters: site, course and group.
         $filters = array('module' => $this->cmid, 'user' => $this->userid, 'tag' => $this->tagid);
         $blog_listing = new blog_listing($filters);
         $this->assertFalse(array_key_exists('site', $blog_listing->filters));
@@ -128,26 +128,26 @@ class core_bloglib_testcase extends advanced_testcase {
 
     public function test_blog_get_headers_case_1() {
         global $CFG, $PAGE, $OUTPUT;
-        $blog_headers = blog_get_headers();
-        $this->assertEquals($blog_headers['heading'], get_string('siteblog', 'blog', 'phpunit'));
+        $blogheaders = blog_get_headers();
+        $this->assertEquals($blogheaders['heading'], get_string('siteblog', 'blog', 'phpunit'));
     }
 
     public function test_blog_get_headers_case_6() {
         global $CFG, $PAGE, $OUTPUT;
-        $blog_headers = blog_get_headers($this->courseid, NULL, $this->userid);
-        $this->assertNotEquals($blog_headers['heading'], '');
+        $blogheaders = blog_get_headers($this->courseid, null, $this->userid);
+        $this->assertNotEquals($blogheaders['heading'], '');
     }
 
     public function test_blog_get_headers_case_7() {
         global $CFG, $PAGE, $OUTPUT;
-        $blog_headers = blog_get_headers(NULL, $this->groupid);
-        $this->assertNotEquals($blog_headers['heading'], '');
+        $blogheaders = blog_get_headers(null, $this->groupid);
+        $this->assertNotEquals($blogheaders['heading'], '');
     }
 
     public function test_blog_get_headers_case_10() {
         global $CFG, $PAGE, $OUTPUT;
-        $blog_headers = blog_get_headers($this->courseid);
-        $this->assertNotEquals($blog_headers['heading'], '');
+        $blogheaders = blog_get_headers($this->courseid);
+        $this->assertNotEquals($blogheaders['heading'], '');
     }
 
     /**
index 22c20db..b5cfcc1 100644 (file)
@@ -356,13 +356,13 @@ abstract class cache_store implements cache_store_interface {
      * Initialises a test instance for unit tests.
      *
      * This differs from initialise_test_instance in that it doesn't rely on interacting with the config table.
-     * By default however it calls initialise_test_instance to support backwards compatability.
+     * By default however it calls initialise_test_instance to support backwards compatibility.
      *
      * @since 2.8
      * @param cache_definition $definition
      * @return cache_store|false
      */
     public static function initialise_unit_test_instance(cache_definition $definition) {
-        return self::initialise_test_instance($definition);
+        return static::initialise_test_instance($definition);
     }
 }
index eb7c999..5a90f39 100644 (file)
@@ -52,5 +52,54 @@ class cachestore_memcache_addinstance_form extends cachestore_addinstance_form {
         $form->setType('prefix', PARAM_TEXT); // We set to text but we have a rule to limit to alphanumext.
         $form->setDefault('prefix', 'mdl_');
         $form->addRule('prefix', get_string('prefixinvalid', 'cachestore_memcache'), 'regex', '#^[a-zA-Z0-9\-_]+$#');
+
+        $form->addElement('header', 'clusteredheader', get_string('clustered', 'cachestore_memcache'));
+
+        $form->addElement('checkbox', 'clustered', get_string('clustered', 'cachestore_memcache'));
+        $form->setDefault('checkbox', false);
+        $form->addHelpButton('clustered', 'clustered', 'cachestore_memcache');
+
+        $form->addElement('textarea', 'setservers', get_string('setservers', 'cachestore_memcache'),
+                array('cols' => 75, 'rows' => 5));
+        $form->addHelpButton('setservers', 'setservers', 'cachestore_memcache');
+        $form->disabledIf('setservers', 'clustered');
+        $form->setType('setservers', PARAM_RAW);
+    }
+
+    /**
+     * Perform minimal validation on the settings form.
+     *
+     * @param array $data
+     * @param array $files
+     */
+    public function validation($data, $files) {
+        $errors = parent::validation($data, $files);
+
+        if (isset($data['clustered']) && ($data['clustered'] == 1)) {
+            // Set servers is required with in cluster mode.
+            if (!isset($data['setservers'])) {
+                $errors['setservers'] = get_string('required');
+            } else {
+                $trimmed = trim($data['setservers']);
+                if (empty($trimmed)) {
+                    $errors['setservers'] = get_string('required');
+                }
+            }
+
+            $validservers = false;
+            if (isset($data['servers'])) {
+                $servers = trim($data['servers']);
+                $servers = explode("\n", $servers);
+                if (count($servers) === 1) {
+                    $validservers = true;
+                }
+            }
+
+            if (!$validservers) {
+                $errors['servers'] = get_string('serversclusterinvalid', 'cachestore_memcache');
+            }
+        }
+
+        return $errors;
     }
 }
\ No newline at end of file
index fb87d28..78d3947 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
+$string['clustered'] = 'Enable clustered servers';
+$string['clustered_help'] = 'This is used to allow read-one, set-multi functionality.
+
+The intended use case is to create an improved store for load-balanced configurations. The store will fetch from one server (usually localhost), but set to many (all the servers in the load-balance pool). For caches with very high read to set ratios, this saves a significant amount of network overhead.
+
+When this setting is enabled, the server listed above will be used for fetching.';
+$string['clusteredheader'] = 'Split servers';
 $string['pluginname'] = 'Memcache';
 $string['prefix'] = 'Key prefix';
 $string['prefix_help'] = 'This prefix is used for all key names on the memcache server.
@@ -42,6 +49,20 @@ For example:
 server.url.com
 ipaddress:port
 servername:port:weight
+</pre>
+
+If *Enable clustered servers* is enabled below, there must be only one server listed here. This would usually be a name that always resolves to the local manchine, like 127.0.0.1 or localhost.';
+$string['serversclusterinvalid'] = 'Exactly one server is required when clustering is enabled.';
+$string['setservers'] = 'Set Servers';
+$string['setservers_help'] = 'This is the list of servers that will updated when data is modified in the cache. Generally the fully qualified name of each server in the pool.
+It **must** include the server listed in *Servers* above, even if by a different hostname.
+Servers should be defined one per line and consist of a server address and optionally a port.
+If no port is provided then the default port (11211) is used.
+
+For example:
+<pre>
+server.url.com
+ipaddress:port
 </pre>';
 $string['testservers'] = 'Test servers';
 $string['testservers_desc'] = 'The test servers get used for unit tests and for performance tests. It is entirely optional to set up test servers. Servers should be defined one per line and consist of a server address and optionally a port and weight.
index 42db75b..3a7da5f 100644 (file)
@@ -87,6 +87,24 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
      */
     protected $definition;
 
+    /**
+     * Set to true when this store is clustered.
+     * @var bool
+     */
+    protected $clustered = false;
+
+    /**
+     * Array of servers to set when in clustered mode.
+     * @var array
+     */
+    protected $setservers = array();
+
+    /**
+     * The an array of memcache connections for the set servers, once established.
+     * @var array
+     */
+    protected $setconnections = array();
+
     /**
      * Default prefix for key names.
      * @var string
@@ -123,6 +141,30 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
             }
             $this->servers[] = $server;
         }
+
+        $this->clustered = array_key_exists('clustered', $configuration) ? (bool)$configuration['clustered'] : false;
+
+        if ($this->clustered) {
+            if (!array_key_exists('setservers', $configuration) || (count($configuration['setservers']) < 1)) {
+                // Can't setup clustering without set servers.
+                return;
+            }
+            if (count($this->servers) !== 1) {
+                // Can only setup cluster with exactly 1 get server.
+                return;
+            }
+            foreach ($configuration['setservers'] as $server) {
+                // We do not use weights (3rd part) on these servers.
+                if (!is_array($server)) {
+                    $server = explode(':', $server, 3);
+                }
+                if (!array_key_exists(1, $server)) {
+                    $server[1] = 11211;
+                }
+                $this->setservers[] = $server;
+            }
+        }
+
         if (empty($configuration['prefix'])) {
             $this->prefix = self::DEFAULT_PREFIX;
         } else {
@@ -133,6 +175,16 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
         foreach ($this->servers as $server) {
             $this->connection->addServer($server[0], (int) $server[1], true, (int) $server[2]);
         }
+
+        if ($this->clustered) {
+            foreach ($this->setservers as $setserver) {
+                // Since we will have a number of them with the same name, append server and port.
+                $connection = new Memcache;
+                $connection->addServer($setserver[0], $setserver[1]);
+                $this->setconnections[] = $connection;
+            }
+        }
+
         // Test the connection to the pool of servers.
         $this->isready = @$this->connection->set($this->parse_key('ping'), 'ping', MEMCACHE_COMPRESSED, 1);
     }
@@ -280,6 +332,15 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
      * @return bool True if the operation was a success false otherwise.
      */
     public function set($key, $data) {
+        if ($this->clustered) {
+            $status = true;
+            foreach ($this->setconnections as $connection) {
+                $status = $connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl())
+                        && $status;
+            }
+            return $status;
+        }
+
         return $this->connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl());
     }
 
@@ -294,7 +355,7 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
     public function set_many(array $keyvaluearray) {
         $count = 0;
         foreach ($keyvaluearray as $pair) {
-            if ($this->connection->set($this->parse_key($pair['key']), $pair['value'], MEMCACHE_COMPRESSED, $this->definition->get_ttl())) {
+            if ($this->set($pair['key'], $pair['value'])) {
                 $count++;
             }
         }
@@ -308,6 +369,14 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
      * @return bool Returns true if the operation was a success, false otherwise.
      */
     public function delete($key) {
+        if ($this->clustered) {
+            $status = true;
+            foreach ($this->setconnections as $connection) {
+                $status = $connection->delete($this->parse_key($key)) && $status;
+            }
+            return $status;
+        }
+
         return $this->connection->delete($this->parse_key($key));
     }
 
@@ -334,7 +403,13 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
      */
     public function purge() {
         if ($this->isready) {
-            $this->connection->flush();
+            if ($this->clustered) {
+                foreach ($this->setconnections as $connection) {
+                    $connection->flush();
+                }
+            } else {
+                $this->connection->flush();
+            }
         }
 
         return true;
@@ -358,9 +433,33 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
             }
             $servers[] = explode(':', $line, 3);
         }
+
+        $clustered = false;
+        if (isset($data->clustered)) {
+            $clustered = true;
+        }
+
+        $lines = explode("\n", $data->setservers);
+        $setservers = array();
+        foreach ($lines as $line) {
+            // Trim surrounding colons and default whitespace.
+            $line = trim(trim($line), ":");
+            if ($line === '') {
+                continue;
+            }
+            $setserver = explode(':', $line, 3);
+            // We don't use weights, so display a debug message.
+            if (count($setserver) > 2) {
+                debugging('Memcache Set Server '.$setserver[0].' has too many parameters.');
+            }
+            $setservers[] = $setserver;
+        }
+
         return array(
             'servers' => $servers,
             'prefix' => $data->prefix,
+            'clustered' => $clustered,
+            'setservers' => $setservers
         );
     }
 
@@ -384,6 +483,16 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
         } else {
             $data['prefix'] = self::DEFAULT_PREFIX;
         }
+        if (isset($config['clustered'])) {
+            $data['clustered'] = (bool)$config['clustered'];
+        }
+        if (!empty($config['setservers'])) {
+            $servers = array();
+            foreach ($config['setservers'] as $server) {
+                $servers[] = join(":", $server);
+            }
+            $data['setservers'] = join("\n", $servers);
+        }
 
         $editform->set_data($data);
     }
@@ -423,6 +532,12 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
 
         $configuration = array();
         $configuration['servers'] = explode("\n", $config->testservers);
+        if (!empty($config->testclustered)) {
+            $configuration['clustered'] = $config->testclustered;
+        }
+        if (!empty($config->testsetservers)) {
+            $configuration['setservers'] = explode("\n", $config->testsetservers);
+        }
 
         $store = new cachestore_memcache('Test memcache', $configuration);
         $store->initialise($definition);
index f8229c5..26d8984 100644 (file)
@@ -30,4 +30,4 @@ $settings->add(new admin_setting_configtextarea(
         'cachestore_memcache/testservers',
         new lang_string('testservers', 'cachestore_memcache'),
         new lang_string('testservers_desc', 'cachestore_memcache'),
-        '', PARAM_RAW, 60, 3));
\ No newline at end of file
+        '', PARAM_RAW, 60, 3));
index 62b52f4..63d366c 100644 (file)
@@ -54,6 +54,8 @@ class cachestore_memcache_test extends cachestore_tests {
      * Tests the valid keys to ensure they work.
      */
     public function test_valid_keys() {
+        $this->resetAfterTest(true);
+
         $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcache', 'phpunit_test');
         $instance = cachestore_memcache::initialise_unit_test_instance($definition);
 
@@ -69,15 +71,197 @@ class cachestore_memcache_test extends cachestore_tests {
             // Underscores.
             'a_1', '1_a', '_a1', 'a1_'
         );
+
+        // Set some keys.
         foreach ($keys as $key) {
             $this->assertTrue($instance->set($key, $key), "Failed to set key `$key`");
         }
+
+        // Get some keys.
         foreach ($keys as $key) {
             $this->assertEquals($key, $instance->get($key), "Failed to get key `$key`");
         }
+
+        // Try get many.
         $values = $instance->get_many($keys);
         foreach ($values as $key => $value) {
             $this->assertEquals($key, $value);
         }
+
+        // Reset a key.
+        $this->assertTrue($instance->set($keys[0], 'New'), "Failed to reset key `$key`");
+        $this->assertEquals('New', $instance->get($keys[0]), "Failed to get reset key `$key`");
+
+        // Delete and check that we can't retrieve.
+        foreach ($keys as $key) {
+            $this->assertTrue($instance->delete($key), "Failed to delete key `$key`");
+            $this->assertFalse($instance->get($key), "Retrieved deleted key `$key`");
+        }
+
+        // Try set many, and check that count is correct.
+        $many = array();
+        foreach ($keys as $key) {
+            $many[] = array('key' => $key, 'value' => $key);
+        }
+        $returncount = $instance->set_many($many);
+        $this->assertEquals(count($many), $returncount, 'Set many count didn\'t match');
+
+        // Check keys retrieved with get_many.
+        $values = $instance->get_many($keys);
+        foreach ($keys as $key) {
+            $this->assertTrue(isset($values[$key]), "Failed to get_many key `$key`");
+            $this->assertEquals($key, $values[$key], "Failed to match get_many key `$key`");
+        }
+
+        // Delete many, make sure count matches.
+        $returncount = $instance->delete_many($keys);
+        $this->assertEquals(count($many), $returncount, 'Delete many count didn\'t match');
+
+        // Check that each key was deleted.
+        foreach ($keys as $key) {
+            $this->assertFalse($instance->get($key), "Retrieved many deleted key `$key`");
+        }
+
+        // Set the keys again.
+        $returncount = $instance->set_many($many);
+        $this->assertEquals(count($many), $returncount, 'Set many count didn\'t match');
+
+        // Purge.
+        $this->assertTrue($instance->purge(), 'Failure to purge');
+
+        // Delete and check that we can't retrieve.
+        foreach ($keys as $key) {
+            $this->assertFalse($instance->get($key), "Retrieved purged key `$key`");
+        }
+    }
+
+    /**
+     * Tests the clustering feature.
+     */
+    public function test_clustered() {
+        $this->resetAfterTest(true);
+
+        if (!defined('TEST_CACHESTORE_MEMCACHE_TESTSERVERS')) {
+            $this->markTestSkipped();
+        }
+
+        $testservers = explode("\n", trim(TEST_CACHESTORE_MEMCACHE_TESTSERVERS));
+
+        if (count($testservers) < 2) {
+            $this->markTestSkipped();
+        }
+
+        // User the first server as our primary.
+        set_config('testservers', $testservers[0], 'cachestore_memcache');
+        set_config('testsetservers', TEST_CACHESTORE_MEMCACHE_TESTSERVERS, 'cachestore_memcache');
+        set_config('testclustered', true, 'cachestore_memcache');
+
+        // First and instance that we can use to test the second server.
+        $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcache', 'phpunit_test');
+        $instance = cachestore_memcache::initialise_test_instance($definition);
+
+        if (!$instance) {
+            $this->markTestSkipped();
+        }
+
+        // Now we are going to setup a connection to each independent server.
+        set_config('testclustered', false, 'cachestore_memcache');
+        set_config('testsetservers', '', 'cachestore_memcache');
+        $checkinstances = array();
+        foreach ($testservers as $testserver) {
+            set_config('testservers', $testserver, 'cachestore_memcache');
+            $checkinstance = cachestore_memcache::initialise_test_instance($definition);
+            if (!$checkinstance) {
+                $this->markTestSkipped();
+            }
+            $checkinstances[] = $checkinstance;
+        }
+
+        $keys = array(
+            // Alphanumeric.
+            'abc', 'ABC', '123', 'aB1', '1aB',
+            // Hyphens.
+            'a-1', '1-a', '-a1', 'a1-',
+            // Underscores.
+            'a_1', '1_a', '_a1', 'a1_'
+        );
+
+        // Set each key.
+        foreach ($keys as $key) {
+            $this->assertTrue($instance->set($key, $key), "Failed to set key `$key`");
+        }
+
+        // Check each key.
+        foreach ($keys as $key) {
+            $this->assertEquals($key, $instance->get($key), "Failed to get key `$key`");
+            foreach ($checkinstances as $id => $checkinstance) {
+                $this->assertEquals($key, $checkinstance->get($key), "Failed to get key `$key` from server $id");
+            }
+        }
+
+        // Reset a key.
+        $this->assertTrue($instance->set($keys[0], 'New'), "Failed to reset key `$key`");
+        $this->assertEquals('New', $instance->get($keys[0]), "Failed to get reset key `$key`");
+        foreach ($checkinstances as $id => $checkinstance) {
+            $this->assertEquals('New', $checkinstance->get($keys[0]), "Failed to get reset key `$key` from server $id");
+        }
+
+        // Delete and check that we can't retrieve.
+        foreach ($keys as $key) {
+            $this->assertTrue($instance->delete($key), "Failed to delete key `$key`");
+            $this->assertFalse($instance->get($key), "Retrieved deleted key `$key`");
+            foreach ($checkinstances as $id => $checkinstance) {
+                $this->assertFalse($checkinstance->get($key), "Retrieved deleted key `$key` from server $id");
+            }
+        }
+
+        // Try set many, and check that count is correct.
+        $many = array();
+        foreach ($keys as $key) {
+            $many[] = array('key' => $key, 'value' => $key);
+        }
+        $returncount = $instance->set_many($many);
+        $this->assertEquals(count($many), $returncount, 'Set many count didn\'t match');
+
+        // Check keys retrieved with get_many.
+        $values = $instance->get_many($keys);
+        foreach ($keys as $key) {
+            $this->assertTrue(isset($values[$key]), "Failed to get_many key `$key`");
+            $this->assertEquals($key, $values[$key], "Failed to match get_many key `$key`");
+        }
+        foreach ($checkinstances as $id => $checkinstance) {
+            $values = $checkinstance->get_many($keys);
+            foreach ($keys as $key) {
+                $this->assertTrue(isset($values[$key]), "Failed to get_many key `$key` from server $id");
+                $this->assertEquals($key, $values[$key], "Failed to get_many key `$key` from server $id");
+            }
+        }
+
+        // Delete many, make sure count matches.
+        $returncount = $instance->delete_many($keys);
+        $this->assertEquals(count($many), $returncount, 'Delete many count didn\'t match');
+
+        // Check that each key was deleted.
+        foreach ($keys as $key) {
+            $this->assertFalse($instance->get($key), "Retrieved many deleted key `$key`");
+            foreach ($checkinstances as $id => $checkinstance) {
+                $this->assertFalse($checkinstance->get($key), "Retrieved many deleted key `$key` from server $id");
+            }
+        }
+
+        // Set the keys again.
+        $returncount = $instance->set_many($many);
+        $this->assertEquals(count($many), $returncount, 'Set many count didn\'t match');
+
+        // Purge.
+        $this->assertTrue($instance->purge(), 'Failure to purge');
+
+        // Delete and check that we can't retrieve.
+        foreach ($keys as $key) {
+            $this->assertFalse($instance->get($key), "Retrieved purged key `$key`");
+            foreach ($checkinstances as $id => $checkinstance) {
+                $this->assertFalse($checkinstance->get($key), "Retrieved purged key `$key` from server 2");
+            }
+        }
     }
 }
index c833a18..12bfbbc 100644 (file)
@@ -74,5 +74,54 @@ class cachestore_memcached_addinstance_form extends cachestore_addinstance_form
         $form->addHelpButton('bufferwrites', 'bufferwrites', 'cachestore_memcached');
         $form->setDefault('bufferwrites', 0);
         $form->setType('bufferwrites', PARAM_BOOL);
+
+        $form->addElement('header', 'clusteredheader', get_string('clustered', 'cachestore_memcached'));
+
+        $form->addElement('checkbox', 'clustered', get_string('clustered', 'cachestore_memcached'));
+        $form->setDefault('checkbox', false);
+        $form->addHelpButton('clustered', 'clustered', 'cachestore_memcached');
+
+        $form->addElement('textarea', 'setservers', get_string('setservers', 'cachestore_memcached'),
+                array('cols' => 75, 'rows' => 5));
+        $form->addHelpButton('setservers', 'setservers', 'cachestore_memcached');
+        $form->disabledIf('setservers', 'clustered');
+        $form->setType('setservers', PARAM_RAW);
+    }
+
+    /**
+     * Perform minimal validation on the settings form.
+     *
+     * @param array $data
+     * @param array $files
+     */
+    public function validation($data, $files) {
+        $errors = parent::validation($data, $files);
+
+        if (isset($data['clustered']) && ($data['clustered'] == 1)) {
+            // Set servers is required with in cluster mode.
+            if (!isset($data['setservers'])) {
+                $errors['setservers'] = get_string('required');
+            } else {
+                $trimmed = trim($data['setservers']);
+                if (empty($trimmed)) {
+                    $errors['setservers'] = get_string('required');
+                }
+            }
+
+            $validservers = false;
+            if (isset($data['servers'])) {
+                $servers = trim($data['servers']);
+                $servers = explode("\n", $servers);
+                if (count($servers) === 1) {
+                    $validservers = true;
+                }
+            }
+
+            if (!$validservers) {
+                $errors['servers'] = get_string('serversclusterinvalid', 'cachestore_memcached');
+            }
+        }
+
+        return $errors;
     }
 }
index 87713f6..5d35c1c 100644 (file)
@@ -28,6 +28,13 @@ defined('MOODLE_INTERNAL') || die();
 
 $string['bufferwrites'] = 'Buffer writes';
 $string['bufferwrites_help'] = 'Enables or disables buffered I/O. Enabling buffered I/O causes storage commands to "buffer" instead of being sent. Any action that retrieves data causes this buffer to be sent to the remote connection. Quitting the connection or closing down the connection will also cause the buffered data to be pushed to the remote connection.';
+$string['clustered'] = 'Enable clustered servers';
+$string['clustered_help'] = 'This is used to allow read-one, set-multi functionality.
+
+The intended use case is to create an improved store for load-balanced configurations. The store will fetch from one server (usually localhost), but set to many (all the servers in the load-balance pool). For caches with very high read to set ratios, this saves a significant amount of network overhead.
+
+When this setting is enabled, the server listed above will be used for fetching