Merge branch 'MDL-38713-master' of git://github.com/danpoltawski/moodle
authorDamyon Wiese <damyon@moodle.com>
Tue, 2 Apr 2013 05:23:00 +0000 (13:23 +0800)
committerDamyon Wiese <damyon@moodle.com>
Tue, 2 Apr 2013 05:23:00 +0000 (13:23 +0800)
771 files changed:
admin/environment.xml
admin/settings/plugins.php
admin/settings/server.php
admin/tests/behat/behat_admin.php [new file with mode: 0644]
admin/tests/behat/display_short_names.feature [new file with mode: 0644]
admin/tests/behat/upload_users.feature [new file with mode: 0644]
admin/tool/behat/cli/init.php
admin/tool/behat/renderer.php
backup/moodle2/restore_course_task.class.php
backup/moodle2/restore_stepslib.php
backup/util/ui/tests/behat/backup_courses.feature [new file with mode: 0644]
backup/util/ui/tests/behat/behat_backup.php [new file with mode: 0644]
backup/util/ui/tests/behat/duplicate_activities.feature [new file with mode: 0644]
backup/util/ui/tests/behat/restore_moodle2_courses.feature [new file with mode: 0644]
backup/util/ui/yui/backupselectall/backupselectall.js
blocks/course_list/block_course_list.php
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-coverage.js [new file with mode: 0644]
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js [new file with mode: 0644]
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js [new file with mode: 0644]
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js [new file with mode: 0644]
blocks/navigation/yui/src/navigation/build.json [new file with mode: 0644]
blocks/navigation/yui/src/navigation/js/navigation.js [moved from blocks/navigation/yui/navigation/navigation.js with 93% similarity]
blocks/navigation/yui/src/navigation/meta/navigation.json [new file with mode: 0644]
blocks/rss_client/edit_form.php
blocks/tests/behat/add_blocks.feature
blocks/tests/behat/behat_blocks.php
cache/forms.php
cohort/edit_form.php
cohort/lib.php
completion/tests/behat/behat_completion.php [new file with mode: 0644]
completion/tests/behat/enable_manual_complete_mark.feature [new file with mode: 0644]
completion/tests/behat/restrict_section_availability.feature [new file with mode: 0644]
course/category.php
course/completion_form.php
course/delete_category_form.php
course/dnduploadlib.php
course/edit_form.php
course/editcategory.php
course/editcategory_form.php
course/externallib.php
course/format/renderer.php
course/lib.php
course/manage.php
course/moodleform_mod.php
course/pending.php
course/recent.php
course/renderer.php
course/request_form.php
course/search.php
course/tests/behat/add_activities.feature
course/tests/behat/behat_course.php
course/tests/behat/edit_settings.feature [new file with mode: 0644]
course/tests/behat/force_group_mode.feature [new file with mode: 0644]
course/tests/behat/rename_roles.feature [new file with mode: 0644]
course/tests/behat/section_highlighting.feature [new file with mode: 0644]
course/tests/behat/section_visibility.feature [new file with mode: 0644]
course/tests/courselib_test.php
course/yui/toolboxes/toolboxes.js
enrol/database/lib.php
enrol/database/settings.php
enrol/ldap/settings.php
enrol/manual/locallib.php
enrol/manual/tests/lib_test.php
enrol/meta/locallib.php
filter/glossary/yui/autolinker/autolinker.js [deleted file]
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-coverage.js [new file with mode: 0644]
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js [new file with mode: 0644]
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js [new file with mode: 0644]
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js [new file with mode: 0644]
filter/glossary/yui/src/autolinker/build.json [new file with mode: 0644]
filter/glossary/yui/src/autolinker/js/autolinker.js [new file with mode: 0644]
filter/glossary/yui/src/autolinker/meta/autolinker.json [new file with mode: 0644]
grade/externallib.php [new file with mode: 0644]
grade/grading/form/guide/lib.php
grade/grading/form/lib.php
grade/grading/form/rubric/lib.php
grade/tests/externallib_test.php [new file with mode: 0644]
group/group_form.php
group/lib.php
lang/en/admin.php
lang/en/block.php
lang/en/cache.php
lang/en/error.php
lang/en/install.php
lang/en/moodle.php
lib/accesslib.php
lib/adodb/adodb-active-record.inc.php
lib/adodb/adodb-csvlib.inc.php
lib/adodb/adodb-datadict.inc.php
lib/adodb/adodb-error.inc.php
lib/adodb/adodb-errorhandler.inc.php
lib/adodb/adodb-errorpear.inc.php
lib/adodb/adodb-exceptions.inc.php
lib/adodb/adodb-iterator.inc.php
lib/adodb/adodb-lib.inc.php
lib/adodb/adodb-memcache.lib.inc.php
lib/adodb/adodb-pager.inc.php
lib/adodb/adodb-pear.inc.php
lib/adodb/adodb-perf.inc.php
lib/adodb/adodb-php4.inc.php
lib/adodb/adodb.inc.php
lib/adodb/drivers/adodb-access.inc.php
lib/adodb/drivers/adodb-ado.inc.php
lib/adodb/drivers/adodb-ado5.inc.php
lib/adodb/drivers/adodb-ado_access.inc.php
lib/adodb/drivers/adodb-ado_mssql.inc.php
lib/adodb/drivers/adodb-borland_ibase.inc.php
lib/adodb/drivers/adodb-csv.inc.php
lib/adodb/drivers/adodb-db2.inc.php
lib/adodb/drivers/adodb-db2oci.inc.php
lib/adodb/drivers/adodb-db2ora.inc.php
lib/adodb/drivers/adodb-fbsql.inc.php
lib/adodb/drivers/adodb-firebird.inc.php
lib/adodb/drivers/adodb-ibase.inc.php
lib/adodb/drivers/adodb-informix.inc.php
lib/adodb/drivers/adodb-informix72.inc.php
lib/adodb/drivers/adodb-ldap.inc.php
lib/adodb/drivers/adodb-mssql.inc.php
lib/adodb/drivers/adodb-mssqlnative.inc.php
lib/adodb/drivers/adodb-mssqlpo.inc.php
lib/adodb/drivers/adodb-mysql.inc.php
lib/adodb/drivers/adodb-mysqli.inc.php
lib/adodb/drivers/adodb-mysqlpo.inc.php
lib/adodb/drivers/adodb-mysqlt.inc.php
lib/adodb/drivers/adodb-netezza.inc.php
lib/adodb/drivers/adodb-oci8.inc.php
lib/adodb/drivers/adodb-oci805.inc.php
lib/adodb/drivers/adodb-oci8po.inc.php
lib/adodb/drivers/adodb-odbc.inc.php
lib/adodb/drivers/adodb-odbc_db2.inc.php
lib/adodb/drivers/adodb-odbc_mssql.inc.php
lib/adodb/drivers/adodb-odbc_oracle.inc.php
lib/adodb/drivers/adodb-odbtp.inc.php
lib/adodb/drivers/adodb-odbtp_unicode.inc.php
lib/adodb/drivers/adodb-oracle.inc.php
lib/adodb/drivers/adodb-pdo.inc.php
lib/adodb/drivers/adodb-pdo_mssql.inc.php
lib/adodb/drivers/adodb-pdo_mysql.inc.php
lib/adodb/drivers/adodb-pdo_oci.inc.php
lib/adodb/drivers/adodb-pdo_pgsql.inc.php
lib/adodb/drivers/adodb-pdo_sqlite.inc.php
lib/adodb/drivers/adodb-postgres.inc.php
lib/adodb/drivers/adodb-postgres64.inc.php
lib/adodb/drivers/adodb-postgres7.inc.php
lib/adodb/drivers/adodb-postgres8.inc.php
lib/adodb/drivers/adodb-postgres9.inc.php [new file with mode: 0644]
lib/adodb/drivers/adodb-proxy.inc.php
lib/adodb/drivers/adodb-sapdb.inc.php
lib/adodb/drivers/adodb-sqlanywhere.inc.php
lib/adodb/drivers/adodb-sqlite.inc.php
lib/adodb/drivers/adodb-sqlite3.inc.php
lib/adodb/drivers/adodb-sqlitepo.inc.php
lib/adodb/drivers/adodb-sybase.inc.php
lib/adodb/drivers/adodb-sybase_ase.inc.php
lib/adodb/drivers/adodb-vfp.inc.php
lib/adodb/lang/adodb-en.inc.php
lib/adodb/perf/perf-db2.inc.php
lib/adodb/perf/perf-informix.inc.php
lib/adodb/perf/perf-mssql.inc.php
lib/adodb/perf/perf-mssqlnative.inc.php
lib/adodb/perf/perf-mysql.inc.php
lib/adodb/perf/perf-oci8.inc.php
lib/adodb/perf/perf-postgres.inc.php
lib/adodb/readme_moodle.txt
lib/behat/behat_base.php
lib/behat/behat_field_manager.php
lib/behat/form_field/behat_form_field.php
lib/behat/form_field/behat_form_modvisible.php [new file with mode: 0644]
lib/blocklib.php
lib/coursecatlib.php [new file with mode: 0644]
lib/datalib.php
lib/db/caches.php
lib/db/install.php
lib/db/services.php
lib/db/upgrade.php
lib/deprecatedlib.php
lib/dml/moodle_database.php
lib/dml/oci_native_moodle_database.php
lib/dml/oci_native_moodle_package.sql
lib/dml/tests/dml_test.php
lib/editor/tinymce/yui/build/moodle-editor_tinymce-collapse/moodle-editor_tinymce-collapse-coverage.js [new file with mode: 0644]
lib/editor/tinymce/yui/build/moodle-editor_tinymce-collapse/moodle-editor_tinymce-collapse-debug.js [new file with mode: 0644]
lib/editor/tinymce/yui/build/moodle-editor_tinymce-collapse/moodle-editor_tinymce-collapse-min.js [new file with mode: 0644]
lib/editor/tinymce/yui/build/moodle-editor_tinymce-collapse/moodle-editor_tinymce-collapse.js [new file with mode: 0644]
lib/editor/tinymce/yui/collapse/collapse.js [deleted file]
lib/editor/tinymce/yui/src/collapse/build.json [new file with mode: 0644]
lib/editor/tinymce/yui/src/collapse/js/collapse.js [new file with mode: 0644]
lib/editor/tinymce/yui/src/collapse/meta/collapse.json [new file with mode: 0644]
lib/environmentlib.php
lib/filelib.php
lib/filestorage/tests/file_storage_test.php
lib/flowplayer/README.txt
lib/flowplayer/flowplayer-3.2.11.js [deleted file]
lib/flowplayer/flowplayer-3.2.11.min.js [deleted file]
lib/flowplayer/flowplayer-3.2.12.js [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.12.min.js [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.14.swf [deleted file]
lib/flowplayer/flowplayer-3.2.16.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.controls-3.2.13.swf [deleted file]
lib/flowplayer/flowplayer.controls-3.2.15.swf [new file with mode: 0644]
lib/form/passwordunmask.php
lib/form/yui/passwordunmask/passwordunmask.js
lib/form/yui/shortforms/shortforms.js
lib/form/yui/showadvanced/showadvanced.js
lib/formslib.php
lib/gdlib.php
lib/htmlpurifier/CREDITS
lib/htmlpurifier/HTMLPurifier.php
lib/htmlpurifier/HTMLPurifier.safe-includes.php
lib/htmlpurifier/HTMLPurifier/AttrCollections.php
lib/htmlpurifier/HTMLPurifier/AttrDef.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/AlphaValue.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Background.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Border.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Color.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Composite.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Filter.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Font.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Ident.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Length.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/ListStyle.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Multiple.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Number.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/Percentage.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/TextDecoration.php
lib/htmlpurifier/HTMLPurifier/AttrDef/CSS/URI.php
lib/htmlpurifier/HTMLPurifier/AttrDef/Clone.php
lib/htmlpurifier/HTMLPurifier/AttrDef/Enum.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/Bool.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/Class.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/Color.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/FrameTarget.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/ID.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/Length.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/LinkTypes.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/MultiLength.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/Nmtokens.php
lib/htmlpurifier/HTMLPurifier/AttrDef/HTML/Pixels.php
lib/htmlpurifier/HTMLPurifier/AttrDef/Integer.php
lib/htmlpurifier/HTMLPurifier/AttrDef/Lang.php
lib/htmlpurifier/HTMLPurifier/AttrDef/Switch.php
lib/htmlpurifier/HTMLPurifier/AttrDef/Text.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI/Email.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI/Host.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI/IPv4.php
lib/htmlpurifier/HTMLPurifier/AttrDef/URI/IPv6.php
lib/htmlpurifier/HTMLPurifier/AttrTransform.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Background.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/BdoDir.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/BgColor.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/BoolToCSS.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Border.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/EnumToCSS.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/ImgRequired.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/ImgSpace.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Input.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Lang.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Length.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Name.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/NameSync.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Nofollow.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeEmbed.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeObject.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/SafeParam.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/ScriptRequired.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/TargetBlank.php
lib/htmlpurifier/HTMLPurifier/AttrTransform/Textarea.php
lib/htmlpurifier/HTMLPurifier/AttrTypes.php
lib/htmlpurifier/HTMLPurifier/AttrValidator.php
lib/htmlpurifier/HTMLPurifier/Bootstrap.php
lib/htmlpurifier/HTMLPurifier/CSSDefinition.php
lib/htmlpurifier/HTMLPurifier/ChildDef.php
lib/htmlpurifier/HTMLPurifier/ChildDef/Chameleon.php
lib/htmlpurifier/HTMLPurifier/ChildDef/Custom.php
lib/htmlpurifier/HTMLPurifier/ChildDef/Empty.php
lib/htmlpurifier/HTMLPurifier/ChildDef/List.php
lib/htmlpurifier/HTMLPurifier/ChildDef/Optional.php
lib/htmlpurifier/HTMLPurifier/ChildDef/Required.php
lib/htmlpurifier/HTMLPurifier/ChildDef/StrictBlockquote.php
lib/htmlpurifier/HTMLPurifier/ChildDef/Table.php
lib/htmlpurifier/HTMLPurifier/Config.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Builder/Xml.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Exception.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Interchange.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Interchange/Directive.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Interchange/Id.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/InterchangeBuilder.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/Validator.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/ValidatorAtom.php
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema.ser
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.Language.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.Base.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.Host.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt
lib/htmlpurifier/HTMLPurifier/ConfigSchema/schema/info.ini
lib/htmlpurifier/HTMLPurifier/ContentSets.php
lib/htmlpurifier/HTMLPurifier/Context.php
lib/htmlpurifier/HTMLPurifier/Definition.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Decorator.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Decorator/Memory.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Decorator/Template.php.in
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Null.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer.php
lib/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer/README
lib/htmlpurifier/HTMLPurifier/DefinitionCacheFactory.php
lib/htmlpurifier/HTMLPurifier/Doctype.php
lib/htmlpurifier/HTMLPurifier/DoctypeRegistry.php
lib/htmlpurifier/HTMLPurifier/ElementDef.php
lib/htmlpurifier/HTMLPurifier/Encoder.php
lib/htmlpurifier/HTMLPurifier/EntityLookup.php
lib/htmlpurifier/HTMLPurifier/EntityParser.php
lib/htmlpurifier/HTMLPurifier/ErrorCollector.php
lib/htmlpurifier/HTMLPurifier/ErrorStruct.php
lib/htmlpurifier/HTMLPurifier/Exception.php
lib/htmlpurifier/HTMLPurifier/Filter.php
lib/htmlpurifier/HTMLPurifier/Filter/ExtractStyleBlocks.php
lib/htmlpurifier/HTMLPurifier/Filter/YouTube.php
lib/htmlpurifier/HTMLPurifier/Generator.php
lib/htmlpurifier/HTMLPurifier/HTMLDefinition.php
lib/htmlpurifier/HTMLPurifier/HTMLModule.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Bdo.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/CommonAttributes.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Edit.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Forms.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Hypertext.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Iframe.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Image.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Legacy.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/List.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Name.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Nofollow.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Object.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Presentation.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Proprietary.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Ruby.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/SafeEmbed.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/SafeObject.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/SafeScripting.php [new file with mode: 0644]
lib/htmlpurifier/HTMLPurifier/HTMLModule/Scripting.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/StyleAttribute.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tables.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Target.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/TargetBlank.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Text.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy/Name.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy/Proprietary.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy/Strict.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy/Transitional.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy/XHTML.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php
lib/htmlpurifier/HTMLPurifier/HTMLModule/XMLCommonAttributes.php
lib/htmlpurifier/HTMLPurifier/HTMLModuleManager.php
lib/htmlpurifier/HTMLPurifier/IDAccumulator.php
lib/htmlpurifier/HTMLPurifier/Injector.php
lib/htmlpurifier/HTMLPurifier/Injector/AutoParagraph.php
lib/htmlpurifier/HTMLPurifier/Injector/DisplayLinkURI.php
lib/htmlpurifier/HTMLPurifier/Injector/Linkify.php
lib/htmlpurifier/HTMLPurifier/Injector/PurifierLinkify.php
lib/htmlpurifier/HTMLPurifier/Injector/RemoveEmpty.php
lib/htmlpurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php
lib/htmlpurifier/HTMLPurifier/Injector/SafeObject.php
lib/htmlpurifier/HTMLPurifier/Language.php
lib/htmlpurifier/HTMLPurifier/Language/classes/en-x-test.php
lib/htmlpurifier/HTMLPurifier/Language/messages/en-x-test.php
lib/htmlpurifier/HTMLPurifier/Language/messages/en-x-testmini.php
lib/htmlpurifier/HTMLPurifier/Language/messages/en.php
lib/htmlpurifier/HTMLPurifier/LanguageFactory.php
lib/htmlpurifier/HTMLPurifier/Length.php
lib/htmlpurifier/HTMLPurifier/Lexer.php
lib/htmlpurifier/HTMLPurifier/Lexer/DOMLex.php
lib/htmlpurifier/HTMLPurifier/Lexer/DirectLex.php
lib/htmlpurifier/HTMLPurifier/Lexer/PH5P.php
lib/htmlpurifier/HTMLPurifier/PercentEncoder.php
lib/htmlpurifier/HTMLPurifier/Printer.php
lib/htmlpurifier/HTMLPurifier/Printer/CSSDefinition.php
lib/htmlpurifier/HTMLPurifier/Printer/ConfigForm.css
lib/htmlpurifier/HTMLPurifier/Printer/ConfigForm.js
lib/htmlpurifier/HTMLPurifier/Printer/ConfigForm.php
lib/htmlpurifier/HTMLPurifier/Printer/HTMLDefinition.php
lib/htmlpurifier/HTMLPurifier/PropertyList.php
lib/htmlpurifier/HTMLPurifier/PropertyListIterator.php
lib/htmlpurifier/HTMLPurifier/Strategy.php
lib/htmlpurifier/HTMLPurifier/Strategy/Composite.php
lib/htmlpurifier/HTMLPurifier/Strategy/Core.php
lib/htmlpurifier/HTMLPurifier/Strategy/FixNesting.php
lib/htmlpurifier/HTMLPurifier/Strategy/MakeWellFormed.php
lib/htmlpurifier/HTMLPurifier/Strategy/RemoveForeignElements.php
lib/htmlpurifier/HTMLPurifier/Strategy/ValidateAttributes.php
lib/htmlpurifier/HTMLPurifier/StringHash.php
lib/htmlpurifier/HTMLPurifier/StringHashParser.php
lib/htmlpurifier/HTMLPurifier/TagTransform.php
lib/htmlpurifier/HTMLPurifier/TagTransform/Font.php
lib/htmlpurifier/HTMLPurifier/TagTransform/Simple.php
lib/htmlpurifier/HTMLPurifier/Token.php
lib/htmlpurifier/HTMLPurifier/Token/Comment.php
lib/htmlpurifier/HTMLPurifier/Token/Empty.php
lib/htmlpurifier/HTMLPurifier/Token/End.php
lib/htmlpurifier/HTMLPurifier/Token/Start.php
lib/htmlpurifier/HTMLPurifier/Token/Tag.php
lib/htmlpurifier/HTMLPurifier/Token/Text.php
lib/htmlpurifier/HTMLPurifier/TokenFactory.php
lib/htmlpurifier/HTMLPurifier/URI.php
lib/htmlpurifier/HTMLPurifier/URIDefinition.php
lib/htmlpurifier/HTMLPurifier/URIFilter.php
lib/htmlpurifier/HTMLPurifier/URIFilter/DisableExternal.php
lib/htmlpurifier/HTMLPurifier/URIFilter/DisableExternalResources.php
lib/htmlpurifier/HTMLPurifier/URIFilter/DisableResources.php
lib/htmlpurifier/HTMLPurifier/URIFilter/HostBlacklist.php
lib/htmlpurifier/HTMLPurifier/URIFilter/MakeAbsolute.php
lib/htmlpurifier/HTMLPurifier/URIFilter/Munge.php
lib/htmlpurifier/HTMLPurifier/URIFilter/SafeIframe.php
lib/htmlpurifier/HTMLPurifier/URIParser.php
lib/htmlpurifier/HTMLPurifier/URIScheme.php
lib/htmlpurifier/HTMLPurifier/URIScheme/data.php
lib/htmlpurifier/HTMLPurifier/URIScheme/file.php
lib/htmlpurifier/HTMLPurifier/URIScheme/ftp.php
lib/htmlpurifier/HTMLPurifier/URIScheme/http.php
lib/htmlpurifier/HTMLPurifier/URIScheme/https.php
lib/htmlpurifier/HTMLPurifier/URIScheme/mailto.php
lib/htmlpurifier/HTMLPurifier/URIScheme/news.php
lib/htmlpurifier/HTMLPurifier/URIScheme/nntp.php
lib/htmlpurifier/HTMLPurifier/URISchemeRegistry.php
lib/htmlpurifier/HTMLPurifier/UnitConverter.php
lib/htmlpurifier/HTMLPurifier/VarParser.php
lib/htmlpurifier/HTMLPurifier/VarParser/Flexible.php
lib/htmlpurifier/HTMLPurifier/VarParser/Native.php
lib/htmlpurifier/HTMLPurifier/VarParserException.php
lib/htmlpurifier/readme_moodle.txt
lib/javascript-static.js
lib/jquery/MIT-LICENSE.txt [new file with mode: 0644]
lib/jquery/jquery-1.9.1.js [new file with mode: 0644]
lib/jquery/jquery-1.9.1.min.js [new file with mode: 0644]
lib/jquery/jquery-migrate-1.1.1.js [new file with mode: 0644]
lib/jquery/jquery-migrate-1.1.1.min.js [new file with mode: 0644]
lib/jquery/plugins.php [new file with mode: 0644]
lib/jquery/readme_moodle.txt [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/animated-overlay.gif [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_flat_0_aaaaaa_40x100.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_flat_75_ffffff_40x100.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_glass_55_fbf9ee_1x400.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_glass_65_ffffff_1x400.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_glass_75_dadada_1x400.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_glass_75_e6e6e6_1x400.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_glass_95_fef1ec_1x400.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-icons_222222_256x240.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-icons_2e83ff_256x240.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-icons_454545_256x240.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-icons_888888_256x240.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/images/ui-icons_cd0a0a_256x240.png [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/jquery-ui.css [new file with mode: 0644]
lib/jquery/ui-1.10.2/css/base/jquery-ui.min.css [new file with mode: 0644]
lib/jquery/ui-1.10.2/jquery-ui.js [new file with mode: 0644]
lib/jquery/ui-1.10.2/jquery-ui.min.js [new file with mode: 0644]
lib/moodlelib.php
lib/outputcomponents.php
lib/outputlib.php
lib/outputrenderers.php
lib/outputrequirementslib.php
lib/phpunit/bootstrap.php
lib/phpunit/bootstraplib.php
lib/phpunit/classes/database_driver_testcase.php
lib/phpunit/classes/util.php
lib/questionlib.php
lib/tcpdf/CHANGELOG.TXT
lib/tcpdf/README.TXT
lib/tcpdf/barcodes.php
lib/tcpdf/composer.json
lib/tcpdf/config/tcpdf_config.php
lib/tcpdf/datamatrix.php
lib/tcpdf/fonts/README.TXT [deleted file]
lib/tcpdf/fonts/arialunicid0.php [deleted file]
lib/tcpdf/pdf417.php
lib/tcpdf/readme_moodle.txt
lib/tcpdf/tcpdf.php
lib/testing/generator/block_generator.php
lib/testing/generator/component_generator_base.php [new file with mode: 0644]
lib/testing/generator/data_generator.php
lib/testing/generator/lib.php
lib/testing/generator/module_generator.php
lib/testing/tests/generator_test.php
lib/tests/behat/behat_forms.php
lib/tests/behat/behat_general.php
lib/tests/blocklib_test.php
lib/tests/coursecatlib_test.php [new file with mode: 0644]
lib/tests/fixtures/upload_users.csv
lib/tests/formslib_test.php
lib/tests/pagelib_test.php
lib/thirdpartylibs.xml
lib/timezone.txt
lib/upgrade.txt
lib/yui/blocks/blocks.js [deleted file]
lib/yui/build/moodle-core-blocks/moodle-core-blocks-coverage.js [new file with mode: 0644]
lib/yui/build/moodle-core-blocks/moodle-core-blocks-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-blocks/moodle-core-blocks-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-blocks/moodle-core-blocks.js [new file with mode: 0644]
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-coverage.js [new file with mode: 0644]
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js [new file with mode: 0644]
lib/yui/build/moodle-core-formautosubmit/moodle-core-formautosubmit-coverage.js [new file with mode: 0644]
lib/yui/build/moodle-core-formautosubmit/moodle-core-formautosubmit-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-formautosubmit/moodle-core-formautosubmit-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-formautosubmit/moodle-core-formautosubmit.js [new file with mode: 0644]
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-coverage.js [new file with mode: 0644]
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker.js [new file with mode: 0644]
lib/yui/build/moodle-core-notification/moodle-core-notification-coverage.js [new file with mode: 0644]
lib/yui/build/moodle-core-notification/moodle-core-notification-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-notification/moodle-core-notification-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-notification/moodle-core-notification.js [new file with mode: 0644]
lib/yui/build/moodle-core-popuphelp/moodle-core-popuphelp-coverage.js [new file with mode: 0644]
lib/yui/build/moodle-core-popuphelp/moodle-core-popuphelp-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-popuphelp/moodle-core-popuphelp-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-popuphelp/moodle-core-popuphelp.js [new file with mode: 0644]
lib/yui/chooserdialogue/chooserdialogue.js [deleted file]
lib/yui/formautosubmit/formautosubmit.js [deleted file]
lib/yui/formchangechecker/formchangechecker.js [deleted file]
lib/yui/popuphelp/popuphelp.js [deleted file]
lib/yui/src/blocks/build.json [new file with mode: 0644]
lib/yui/src/blocks/js/blocks.js [new file with mode: 0644]
lib/yui/src/blocks/meta/blocks.json [new file with mode: 0644]
lib/yui/src/chooserdialogue/build.json [new file with mode: 0644]
lib/yui/src/chooserdialogue/js/chooserdialogue.js [new file with mode: 0644]
lib/yui/src/chooserdialogue/meta/chooserdialogue.json [new file with mode: 0644]
lib/yui/src/formautosubmit/build.json [new file with mode: 0644]
lib/yui/src/formautosubmit/js/formautosubmit.js [new file with mode: 0644]
lib/yui/src/formautosubmit/meta/formautosubmit.json [new file with mode: 0644]
lib/yui/src/formchangechecker/build.json [new file with mode: 0644]
lib/yui/src/formchangechecker/js/formchangechecker.js [new file with mode: 0644]
lib/yui/src/formchangechecker/meta/formchangechecker.json [new file with mode: 0644]
lib/yui/src/notification/build.json [new file with mode: 0644]
lib/yui/src/notification/js/notification.js [moved from lib/yui/notification/notification.js with 81% similarity]
lib/yui/src/notification/meta/notification.json [new file with mode: 0644]
lib/yui/src/popuphelp/build.json [new file with mode: 0644]
lib/yui/src/popuphelp/js/popuphelp.js [new file with mode: 0644]
lib/yui/src/popuphelp/meta/popuphelp.json [new file with mode: 0644]
mod/choice/mod_form.php
mod/folder/lib.php
mod/forum/tests/behat/add_forum.feature [new file with mode: 0644]
mod/forum/tests/behat/behat_mod_forum.php [new file with mode: 0644]
mod/forum/tests/behat/completion_condition_number_discussions.feature [new file with mode: 0644]
mod/forum/tests/behat/discussion_display.feature [new file with mode: 0644]
mod/forum/tests/behat/edit_post_student.feature [new file with mode: 0644]
mod/forum/tests/behat/edit_post_teacher.feature [new file with mode: 0644]
mod/forum/tests/behat/single_forum_discussion.feature [new file with mode: 0644]
mod/forum/tests/behat/track_read_posts.feature [new file with mode: 0644]
mod/forum/tests/externallib_test.php
mod/forum/tests/generator/lib.php
mod/forum/tests/generator_test.php
mod/imscp/mod_form.php
mod/lesson/format.php
mod/lesson/lib.php
mod/lesson/locallib.php
mod/lesson/mod_form.php
mod/lesson/pagetypes/branchtable.php
mod/lesson/pagetypes/essay.php
mod/lesson/pagetypes/matching.php
mod/lesson/pagetypes/multichoice.php
mod/lesson/pagetypes/numerical.php
mod/lesson/pagetypes/shortanswer.php
mod/lesson/pagetypes/truefalse.php
mod/lesson/report.php
mod/lesson/view.php
mod/quiz/attempt.php
mod/quiz/attemptlib.php
mod/quiz/autosave.ajax.php [new file with mode: 0644]
mod/quiz/db/upgrade.php
mod/quiz/lang/en/quiz.php
mod/quiz/renderer.php
mod/quiz/report/grading/db/install.php [new file with mode: 0644]
mod/quiz/report/overview/db/install.php [moved from mod/quiz/db/install.php with 60% similarity]
mod/quiz/report/responses/db/install.php [new file with mode: 0644]
mod/quiz/reviewquestion.php
mod/quiz/settings.php
mod/quiz/styles.css
mod/quiz/version.php
mod/quiz/yui/build/moodle-mod_quiz-autosave/moodle-mod_quiz-autosave-coverage.js [new file with mode: 0644]
mod/quiz/yui/build/moodle-mod_quiz-autosave/moodle-mod_quiz-autosave-debug.js [new file with mode: 0644]
mod/quiz/yui/build/moodle-mod_quiz-autosave/moodle-mod_quiz-autosave-min.js [new file with mode: 0644]
mod/quiz/yui/build/moodle-mod_quiz-autosave/moodle-mod_quiz-autosave.js [new file with mode: 0644]
mod/quiz/yui/src/autosave/build.json [new file with mode: 0644]
mod/quiz/yui/src/autosave/js/autosave.js [new file with mode: 0644]
mod/quiz/yui/src/autosave/meta/autosave.json [new file with mode: 0644]
mod/scorm/locallib.php
mod/survey/lib.php
mod/survey/tests/behat/survey_types.feature [new file with mode: 0644]
mod/url/mod_form.php
question/behaviour/behaviourbase.php
question/engine/datalib.php
question/engine/lib.php
question/engine/questionattempt.php
question/engine/questionusage.php
question/engine/tests/helpers.php
question/engine/tests/questionattempt_db_test.php [new file with mode: 0644]
question/engine/tests/questionattempt_test.php
question/engine/tests/questionattempt_with_steps_test.php [new file with mode: 0644]
question/engine/tests/questionusage_autosave_test.php [new file with mode: 0644]
question/engine/tests/unitofwork_test.php
question/format/blackboard_six/format.php
question/format/blackboard_six/formatpool.php
question/format/blackboard_six/lang/en/qformat_blackboard_six.php
question/format/blackboard_six/tests/blackboardformatpool_test.php
question/tests/generator/lib.php [new file with mode: 0644]
question/tests/generator_test.php [new file with mode: 0644]
question/type/calculated/datasetdefinitions_form.php
question/type/calculated/datasetitems_form.php
question/type/match/tests/walkthrough_test.php
question/type/multianswer/tests/walkthrough_test.php
question/type/numerical/tests/walkthrough_test.php
question/type/shortanswer/tests/helper.php
question/type/upgrade.txt
report/courseoverview/index.php
report/log/locallib.php
report/stats/locallib.php
report/stats/user.php
repository/tests/behat/behat_filepicker.php [moved from lib/tests/behat/behat_filepicker.php with 99% similarity]
repository/tests/behat/create_folders.feature [new file with mode: 0644]
repository/tests/behat/zip_and_unzip.feature [moved from admin/tool/behat/tests/behat/manipulate_filepicker.feature with 66% similarity]
repository/upload/tests/behat/upload_file.feature
theme/base/style/core.css
theme/base/style/user.css
theme/canvas/style/core.css
theme/jquery.php [new file with mode: 0644]
theme/magazine/style/core.css
theme/mymobile/config.php
theme/mymobile/javascript/jquery-1.7.1.min.js [deleted file]
theme/mymobile/jquery/custom.js [moved from theme/mymobile/javascript/custom.js with 100% similarity]
theme/mymobile/jquery/jquery.mobile-1.1.1.js [moved from theme/mymobile/javascript/jquery.mobile-1.1.1.js with 100% similarity]
theme/mymobile/jquery/plugins.php [new file with mode: 0644]
theme/mymobile/lib.php
theme/mymobile/renderers.php
theme/upgrade.txt
user/edit.php
user/edit_form.php
user/editadvanced.php
user/editadvanced_form.php
user/editlib.php
user/filters/courserole.php
user/filters/text.php
user/profile.php
user/profile/lib.php
user/view.php
version.php

index 584a9b0..61af243 100644 (file)
     <PHP_EXTENSIONS>
       <PHP_EXTENSION name="iconv" level="required">
         <FEEDBACK>
-          <ON_CHECK message="iconvrequired" />
+          <ON_ERROR message="iconvrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="mbstring" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="curl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="curlrequired" />
+          <ON_ERROR message="curlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="openssl" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="simplexml" level="required">
         <FEEDBACK>
-          <ON_CHECK message="simplexmlrequired" />
+          <ON_ERROR message="simplexmlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="spl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="splrequired" />
+          <ON_ERROR message="splrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="pcre" level="required">
     <PHP_EXTENSIONS>
       <PHP_EXTENSION name="iconv" level="required">
         <FEEDBACK>
-          <ON_CHECK message="iconvrequired" />
+          <ON_ERROR message="iconvrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="mbstring" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="curl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="curlrequired" />
+          <ON_ERROR message="curlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="openssl" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="simplexml" level="required">
         <FEEDBACK>
-          <ON_CHECK message="simplexmlrequired" />
+          <ON_ERROR message="simplexmlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="spl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="splrequired" />
+          <ON_ERROR message="splrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="pcre" level="required">
     <PHP_EXTENSIONS>
       <PHP_EXTENSION name="iconv" level="required">
         <FEEDBACK>
-          <ON_CHECK message="iconvrequired" />
+          <ON_ERROR message="iconvrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="mbstring" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="curl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="curlrequired" />
+          <ON_ERROR message="curlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="openssl" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="simplexml" level="required">
         <FEEDBACK>
-          <ON_CHECK message="simplexmlrequired" />
+          <ON_ERROR message="simplexmlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="spl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="splrequired" />
+          <ON_ERROR message="splrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="pcre" level="required">
     <PHP_EXTENSIONS>
       <PHP_EXTENSION name="iconv" level="required">
         <FEEDBACK>
-          <ON_CHECK message="iconvrequired" />
+          <ON_ERROR message="iconvrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="mbstring" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="curl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="curlrequired" />
+          <ON_ERROR message="curlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="openssl" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="simplexml" level="required">
         <FEEDBACK>
-          <ON_CHECK message="simplexmlrequired" />
+          <ON_ERROR message="simplexmlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="spl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="splrequired" />
+          <ON_ERROR message="splrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="pcre" level="required">
     <PHP_EXTENSIONS>
       <PHP_EXTENSION name="iconv" level="required">
         <FEEDBACK>
-          <ON_CHECK message="iconvrequired" />
+          <ON_ERROR message="iconvrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="mbstring" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="curl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="curlrequired" />
+          <ON_ERROR message="curlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="openssl" level="optional">
       </PHP_EXTENSION>
       <PHP_EXTENSION name="simplexml" level="required">
         <FEEDBACK>
-          <ON_CHECK message="simplexmlrequired" />
+          <ON_ERROR message="simplexmlrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="spl" level="required">
         <FEEDBACK>
-          <ON_CHECK message="splrequired" />
+          <ON_ERROR message="splrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="pcre" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="dom" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xml" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="intl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="intlrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="json" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="hash" level="required"/>
+    </PHP_EXTENSIONS>
+    <PHP_SETTINGS>
+      <PHP_SETTING name="memory_limit" value="40M" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="settingmemorylimit" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="safe_mode" value="0" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="settingsafemode" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="file_uploads" value="1" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="settingfileuploads" />
+        </FEEDBACK>
+      </PHP_SETTING>
+    </PHP_SETTINGS>
+  </MOODLE>
+  <MOODLE version="2.5" requires="2.2">
+    <UNICODE level="required">
+      <FEEDBACK>
+        <ON_ERROR message="unicoderequired" />
+      </FEEDBACK>
+    </UNICODE>
+    <DATABASE level="required">
+      <VENDOR name="mysql" version="5.1.33" />
+      <VENDOR name="postgres" version="8.3" />
+      <VENDOR name="mssql" version="9.0" />
+      <VENDOR name="odbc_mssql" version="9.0" />
+      <VENDOR name="mssql_n" version="9.0" />
+      <VENDOR name="oracle" version="10.2" />
+      <VENDOR name="sqlite" version="2.0" />
+    </DATABASE>
+    <PHP version="5.3.3" level="required">
+    </PHP>
+    <PCREUNICODE level="optional">
+      <FEEDBACK>
+        <ON_CHECK message="pcreunicodewarning" />
+      </FEEDBACK>
+    </PCREUNICODE>
+    <PHP_EXTENSIONS>
+      <PHP_EXTENSION name="iconv" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="iconvrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="mbstring" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="mbstringrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="curl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="curlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="openssl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="opensslrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="tokenizer" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="tokenizerrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xmlrpc" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="xmlrpcrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="soap" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="soaprecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="ctype" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ctyperequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="zip" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ziprequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="gd" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="gdrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="simplexml" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="simplexmlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="spl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="splrequired" />
         </FEEDBACK>
       </PHP_EXTENSION>
       <PHP_EXTENSION name="pcre" level="required">
index 61d2477..a11cbfa 100644 (file)
@@ -210,9 +210,7 @@ if ($hassiteconfig) {
                 $portfolio->get('name'),
                 $url . '?action=edit&pf=' . $portfolio->get('id'),
                 'moodle/site:config'
-            ),
-            $portfolio->get('name'),
-            $url . '?action=edit&pf=' . $portfolio->get('id')
+            )
         );
     }
 
index 3ba7201..4a12d2a 100644 (file)
@@ -7,9 +7,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
 
 // "systempaths" settingpage
 $temp = new admin_settingpage('systempaths', new lang_string('systempaths','admin'));
-$temp->add(new admin_setting_configselect('gdversion', new lang_string('gdversion','admin'), new lang_string('configgdversion', 'admin'), check_gd_version(), array('0' => new lang_string('gdnot'),
-                                                                                                                                                          '1' => new lang_string('gd1'),
-                                                                                                                                                          '2' => new lang_string('gd2'))));
+
 $temp->add(new admin_setting_configexecutable('pathtodu', new lang_string('pathtodu', 'admin'), new lang_string('configpathtodu', 'admin'), ''));
 $temp->add(new admin_setting_configexecutable('aspellpath', new lang_string('aspellpath', 'admin'), new lang_string('edhelpaspellpath'), ''));
 $temp->add(new admin_setting_configexecutable('pathtodot', new lang_string('pathtodot', 'admin'), new lang_string('pathtodot_help', 'admin'), ''));
diff --git a/admin/tests/behat/behat_admin.php b/admin/tests/behat/behat_admin.php
new file mode 100644 (file)
index 0000000..cdca881
--- /dev/null
@@ -0,0 +1,97 @@
+<?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/>.
+
+/**
+ * Steps definitions related with administration.
+ *
+ * @package   core
+ * @category  test
+ * @copyright 2013 David Monllaó
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
+
+require_once(__DIR__ . '/../../../lib/behat/behat_base.php');
+require_once(__DIR__ . '/../../../lib/behat/behat_field_manager.php');
+
+use Behat\Gherkin\Node\TableNode as TableNode,
+    Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
+
+/**
+ * Site administration level steps definitions.
+ *
+ * @package    core
+ * @category   test
+ * @copyright  2013 David Monllaó
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class behat_admin extends behat_base {
+
+    /**
+     * Sets the specified site settings. A table with | Setting label | value | is expected.
+     *
+     * @Given /^I set the following administration settings values:$/
+     * @param TableNode $table
+     */
+    public function i_set_the_following_administration_settings_values(TableNode $table) {
+
+        if (!$data = $table->getRowsHash()) {
+            return;
+        }
+
+        foreach ($data as $label => $value) {
+
+            // We expect admin block to be visible, otherwise go to homepage.
+            if (!$this->getSession()->getPage()->find('css', '.block_settings')) {
+                $this->getSession()->visit($this->locate_path('/'));
+                $this->getSession()->wait(self::TIMEOUT, '(document.readyState === "complete")');
+            }
+
+            // Search by label.
+            $searchbox = $this->find_field('Search in settings');
+            $searchbox->setValue($label);
+            $submitsearch = $this->find('css', 'form.adminsearchform input[type=submit]');
+            $submitsearch->press();
+
+            $this->getSession()->wait(self::TIMEOUT, '(document.readyState === "complete")');
+
+            // Admin settings does not use the same DOM structure than other moodle forms
+            // but we also need to use lib/behat/form_field/* to deal with the different moodle form elements.
+            $exception = new ElementNotFoundException($this->getSession(), '"' . $label . '" administration setting ');
+            $fieldxpath = "//*[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')]
+[@id=//label[contains(normalize-space(string(.)), '" . $label . "')]/@for]";
+            $fieldnode = $this->find('xpath', $fieldxpath, $exception);
+            $formfieldtypenode = $this->find('xpath', $fieldxpath . "/ancestor::div[@class='form-setting']
+/child::div[contains(concat(' ', @class, ' '),  ' form-')]/child::*/parent::div");
+
+            // Getting the class which contains the field type.
+            $classes = explode(' ', $formfieldtypenode->getAttribute('class'));
+            foreach ($classes as $class) {
+                if (substr($class, 0, 5) == 'form-') {
+                    $type = substr($class, 5);
+                }
+            }
+
+            // Instantiating the appropiate field type.
+            $field = behat_field_manager::get_field_instance($type, $fieldnode, $this->getSession());
+            $field->set_value($value);
+
+            $this->find_button('Save changes')->press();
+        }
+    }
+
+}
diff --git a/admin/tests/behat/display_short_names.feature b/admin/tests/behat/display_short_names.feature
new file mode 100644 (file)
index 0000000..836d753
--- /dev/null
@@ -0,0 +1,22 @@
+@admin
+Feature: Display extended course names
+  In order to display more info about the courses
+  As a moodle admin
+  I need to display courses short names along with courses full names
+
+  Background:
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Course fullname | C_shortname | 0 |
+    And I log in as "admin"
+
+  Scenario: Courses list without extended course names (default value)
+    Then I should see "Course fullname"
+    And I should not see "C_shortname Course fullname"
+
+  Scenario: Courses list with extended course names
+    Given I click on "Courses" "link" in the "//div[@id='settingsnav']//descendant::li[contains(concat(' ', @class, ' '), ' type_setting ')][not(contains(., 'Site administration'))][contains(., 'Appearance')]" "xpath_element"
+    And I check "Display extended course names"
+    When I press "Save changes"
+    And I am on homepage
+    Then I should see "C_shortname Course fullname"
diff --git a/admin/tests/behat/upload_users.feature b/admin/tests/behat/upload_users.feature
new file mode 100644 (file)
index 0000000..e61208e
--- /dev/null
@@ -0,0 +1,46 @@
+@admin @_only_local
+Feature: Upload users
+  In order to add users to the system
+  As a moodle admin
+  I need to upload files containing the users data
+
+  @javascript
+  Scenario: Upload users enrolling them on courses and groups
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Maths | math102 | 0 |
+    And the following "groups" exists:
+      | name | course | idnumber |
+      | Section 1 | math102 | S1 |
+      | Section 3 | math102 | S3 |
+    And I log in as "admin"
+    And I expand "Front page settings" node
+    And I expand "Site administration" node
+    And I expand "Users" node
+    And I expand "Accounts" node
+    And I follow "Upload users"
+    When I upload "lib/tests/fixtures/upload_users.csv" file to "File" filepicker
+    And I press "Upload users"
+    Then I should see "Upload users preview"
+    And I should see "Tom"
+    And I should see "Jones"
+    And I should see "verysecret"
+    And I should see "jonest@someplace.edu"
+    And I should see "Reznor"
+    And I should see "course1"
+    And I should see "math102"
+    And I should see "group1"
+    And I should see "Section 1"
+    And I press "Upload users"
+    And I press "Continue"
+    And I follow "Browse list of users"
+    And I should see "Tom Jones"
+    And I should see "Trent Reznor"
+    And I should see "reznor@someplace.edu"
+    And I am on homepage
+    And I follow "Maths"
+    And I expand "Users" node
+    And I follow "Groups"
+    And I select "Section 1 (1)" from "groups"
+    And I wait "4" seconds
+    And the "members" select box should contain "Tom Jones"
index 8162b0e..ca68c16 100644 (file)
@@ -65,13 +65,13 @@ if ($code == 0) {
     // Changing to moodle dirroot to run composer related commands at project level.
     chdir(__DIR__ . '/../../../..');
     if (!file_exists(__DIR__ . '/../../../../composer.phar')) {
-        passthru("curl http://getcomposer.org/install | php", $code);
+        passthru("curl http://getcomposer.org/installer | php", $code);
         if ($code != 0) {
             exit($code);
         }
     }
 
-    passthru("php composer.phar install --dev", $code);
+    passthru("php composer.phar update --dev", $code);
     if ($code != 0) {
         exit($code);
     }
index 0df7e3a..503bc09 100644 (file)
@@ -89,7 +89,7 @@ class tool_behat_renderer extends plugin_renderer_base {
             $stepsdefinitions = implode('', $stepsdefinitions);
 
             // Replace text selector type arguments with a user-friendly select.
-            $stepsdefinitions = preg_replace_callback('/(TEXT_SELECTOR_STRING)/',
+            $stepsdefinitions = preg_replace_callback('/(TEXT_SELECTOR\d?_STRING)/',
                 function ($matches) {
                     return html_writer::select(behat_command::$allowedtextselectors, uniqid());
                 },
@@ -97,7 +97,7 @@ class tool_behat_renderer extends plugin_renderer_base {
             );
 
             // Replace selector type arguments with a user-friendly select.
-            $stepsdefinitions = preg_replace_callback('/(SELECTOR_STRING)/',
+            $stepsdefinitions = preg_replace_callback('/(SELECTOR\d?_STRING)/',
                 function ($matches) {
                     return html_writer::select(behat_command::$allowedselectors, uniqid());
                 },
index 8a8713a..5f231e9 100644 (file)
@@ -71,6 +71,8 @@ class restore_course_task extends restore_task {
             $this->add_step(new restore_course_structure_step('course_info', 'course.xml'));
         }
 
+        $this->add_step(new restore_course_legacy_files_step('legacy_files'));
+
         // Restore course enrolments (plugins and membership). Conditionally prevented for any IMPORT/HUB operation
         if ($this->plan->get_mode() != backup::MODE_IMPORT && $this->plan->get_mode() != backup::MODE_HUB) {
             $this->add_step(new restore_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
index f254475..5afd99e 100644 (file)
@@ -1459,7 +1459,6 @@ class restore_course_structure_step extends restore_structure_step {
 
         // Add course related files, without itemid to match
         $this->add_related_files('course', 'summary', null);
-        $this->add_related_files('course', 'legacy', null);
 
         // Deal with legacy allowed modules.
         if ($this->legacyrestrictmodules) {
@@ -1486,6 +1485,29 @@ class restore_course_structure_step extends restore_structure_step {
     }
 }
 
+/**
+ * Execution step that will migrate legacy files if present.
+ */
+class restore_course_legacy_files_step extends restore_execution_step {
+    public function define_execution() {
+        global $DB;
+
+        // Do a check for legacy files and skip if there are none.
+        $sql = 'SELECT count(*)
+                  FROM {backup_files_temp}
+                 WHERE backupid = ?
+                   AND contextid = ?
+                   AND component = ?
+                   AND filearea  = ?';
+        $params = array($this->get_restoreid(), $this->task->get_old_contextid(), 'course', 'legacy');
+
+        if ($DB->count_records_sql($sql, $params)) {
+            $DB->set_field('course', 'legacyfiles', 2, array('id' => $this->get_courseid()));
+            restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'course',
+                'legacy', $this->task->get_old_contextid(), $this->task->get_userid());
+        }
+    }
+}
 
 /*
  * Structure step that will read the roles.xml file (at course/activity/block levels)
diff --git a/backup/util/ui/tests/behat/backup_courses.feature b/backup/util/ui/tests/behat/backup_courses.feature
new file mode 100644 (file)
index 0000000..584354e
--- /dev/null
@@ -0,0 +1,37 @@
+@backup
+Feature: Backup Moodle courses
+  In order to save and store course contents
+  As a moodle admin
+  I need to create backups of courses
+
+  Background:
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And I log in as "admin"
+
+  @javascript
+  Scenario: Backup a course providing options
+    When I backup "Course 1" course using this options:
+    Then I should see "Restore"
+    And I click on "Restore" "link" in the ".backup-files-table" "css_element"
+    And I should see "URL of backup"
+    And I should see "Anonymize user information"
+
+  @javascript
+  Scenario: Backup a course with default options
+    When I backup "Course 1" course using this options:
+      | Filename | test_backup.mbz |
+      | Include calendar events | 0 |
+      | Include course logs | 1 |
+      | setting_section_section_5_userinfo | 0 |
+      | setting_section_section_5_included | 0 |
+    Then I should see "Restore"
+    And I click on "Restore" "link" in the ".backup-files-table" "css_element"
+    And I should not see "Section 3"
+    And I press "Continue"
+    And I click on "Continue" "button" in the ".bcs-current-course" "css_element"
+    And I click on "//div[contains(concat(' ', @class, ' '), ' fitem ')][contains(., 'Include calendar events')]/descendant::img" "xpath_element"
+    And I click on "setting_root_logs" "checkbox" in the "//div[contains(@class, 'fitem')][contains(., 'Include course logs')]" "xpath_element"
+    And I press "Cancel"
+    And I click on "Cancel" "button" in the ".confirmation-dialogue" "css_element"
diff --git a/backup/util/ui/tests/behat/behat_backup.php b/backup/util/ui/tests/behat/behat_backup.php
new file mode 100644 (file)
index 0000000..8f02603
--- /dev/null
@@ -0,0 +1,288 @@
+<?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/>.
+
+/**
+ * Backup and restore actions to help behat feature files writting.
+ *
+ * @package    core
+ * @category   test
+ * @copyright  2013 David Monllaó
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
+
+require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
+require_once(__DIR__ . '/../../../../../lib/behat/behat_field_manager.php');
+
+use Behat\Gherkin\Node\TableNode as TableNode,
+    Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException,
+    Behat\Mink\Exception\ExpectationException as ExpectationException;
+
+/**
+ * Backup-related steps definitions.
+ *
+ * @package    core
+ * @category   test
+ * @copyright  2013 David Monllaó
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class behat_backup extends behat_base {
+
+    /**
+     * Backups the specified course using the provided options. If you are interested in restoring this backup would be useful to provide a 'Filename' option.
+     *
+     * @Given /^I backup "(?P<course_fullname_string>(?:[^"]|\\")*)" course using this options:$/
+     * @param string $backupcourse
+     * @param TableNode $options Backup options or false if no options provided
+     */
+    public function i_backup_course_using_this_options($backupcourse, $options = false) {
+
+        // We can not use other steps here as we don't know where the provided data
+        // table elements are used, and we need to catch exceptions contantly.
+
+        // Go to homepage.
+        $this->getSession()->visit($this->locate_path('/'));
+
+        // Click the course link.
+        $this->find_link($backupcourse)->click();
+
+        // Click the backup link.
+        $this->find_link('Backup')->click();
+
+        // Initial settings.
+        $this->fill_backup_restore_form($options);
+        $this->find_button('Next')->press();
+
+        // Schema settings.
+        $this->fill_backup_restore_form($options);
+        $this->find_button('Next')->press();
+
+        // Confirmation and review, backup filename can also be specified.
+        $this->fill_backup_restore_form($options);
+        $this->find_button('Perform backup')->press();
+
+        // Waiting for it to finish.
+        $this->wait(10);
+
+        // Last backup continue button.
+        $this->find_button('Continue')->press();
+    }
+
+    /**
+     * Restores the backup into the specified course and the provided options. You should be in the 'Restore' page where the backup is.
+     *
+     * @Given /^I restore "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into "(?P<existing_course_fullname_string>(?:[^"]|\\")*)" course using this options:$/
+     * @param string $backupfilename
+     * @param string $existingcourse
+     * @param TableNode $options Restore forms options or false if no options provided
+     */
+    public function i_restore_backup_into_course_using_this_options($backupfilename, $existingcourse, $options = false) {
+
+        // Confirm restore.
+        $this->select_backup($backupfilename);
+
+        // Selecting the specified course (we can not call behat_forms::select_radio here as is in another behat subcontext).
+        $existingcourse = str_replace("'", "\'", $existingcourse);
+        $radionode = $this->find('xpath', "//div[contains(@class, 'bcs-existing-course')]
+/descendant::div[@class='restore-course-search']
+/descendant::tr[contains(., '" . $existingcourse . "')]
+/descendant::input[@type='radio']");
+        $radionode->check();
+        $radionode->click();
+
+        // Pressing the continue button of the restore into an existing course section.
+        $continuenode = $this->find('xpath', "//div[contains(@class, 'bcs-existing-course')]/descendant::input[@type='submit'][@value='Continue']");
+        $continuenode->click();
+        $this->wait();
+
+        // Common restore process using provided key/value options.
+        $this->process_restore($options);
+    }
+
+    /**
+     * Restores the specified backup into a new course using the provided options. You should be in the 'Restore' page where the backup is.
+     *
+     * @Given /^I restore "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into a new course using this options:$/
+     * @param string $backupfilename
+     * @param TableNode $options Restore forms options or false if no options provided
+     */
+    public function i_restore_backup_into_a_new_course_using_this_options($backupfilename, $options = false) {
+
+        // Confirm restore.
+        $this->select_backup($backupfilename);
+
+        // The first category in the list.
+        $radionode = $this->find('xpath', "//div[contains(@class, 'bcs-new-course')]
+/descendant::div[@class='restore-course-search']
+/descendant::input[@type='radio']");
+        $radionode->check();
+        $radionode->click();
+
+        // Pressing the continue button of the restore into an existing course section.
+        $continuenode = $this->find('xpath', "//div[contains(@class, 'bcs-new-course')]/descendant::input[@type='submit'][@value='Continue']");
+        $continuenode->click();
+        $this->wait();
+
+        // Common restore process using provided key/value options.
+        $this->process_restore($options);
+    }
+
+    /**
+     * Merges the backup into the current course using the provided restore options. You should be in the 'Restore' page where the backup is.
+     *
+     * @Given /^I merge "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into the current course using this options:$/
+     * @param string $backupfilename
+     * @param TableNode $options Restore forms options or false if no options provided
+     */
+    public function i_merge_backup_into_the_current_course($backupfilename, $options = false) {
+
+        // Confirm restore.
+        $this->select_backup($backupfilename);
+
+        // Merge without deleting radio option.
+        $radionode = $this->find('xpath', "//div[contains(@class, 'bcs-current-course')]
+/descendant::input[@type='radio'][@name='target'][@value='1']");
+        $radionode->check();
+        $radionode->click();
+
+        // Pressing the continue button of the restore merging section.
+        $continuenode = $this->find('xpath', "//div[contains(@class, 'bcs-current-course')]/descendant::input[@type='submit'][@value='Continue']");
+        $continuenode->click();
+        $this->wait();
+
+        // Common restore process using provided key/value options.
+        $this->process_restore($options);
+    }
+
+    /**
+     * Merges the backup into the current course after deleting this contents, using the provided restore options. You should be in the 'Restore' page where the backup is.
+     *
+     * @Given /^I merge "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into the current course after deleting it's contents using this options:$/
+     * @param string $backupfilename
+     * @param TableNode $options Restore forms options or false if no options provided
+     */
+    public function i_merge_backup_into_current_course_deleting_its_contents($backupfilename, $options = false) {
+
+        // Confirm restore.
+        $this->select_backup($backupfilename);
+
+        // Delete contents radio option.
+        $radionode = $this->find('xpath', "//div[contains(@class, 'bcs-current-course')]
+/descendant::input[@type='radio'][@name='target'][@value='0']");
+        $radionode->check();
+        $radionode->click();
+
+        // Pressing the continue button of the restore merging section.
+        $continuenode = $this->find('xpath', "//div[contains(@class, 'bcs-current-course')]/descendant::input[@type='submit'][@value='Continue']");
+        $continuenode->click();
+        $this->wait();
+
+        // Common restore process using provided key/value options.
+        $this->process_restore($options);
+    }
+
+    /**
+     * Selects the backup to restore.
+     *
+     * @throws ExpectationException
+     * @param string $backupfilename
+     * @return void
+     */
+    protected function select_backup($backupfilename) {
+
+        // Using xpath as there are other restore links before this one.
+        $exception = new ExpectationException('The "' . $backupfilename . '" backup file can not be found in this page', $this->getSession());
+        $xpath = "//tr[contains(., '" . $backupfilename . "')]/descendant::a[contains(., 'Restore')]";
+        $restorelink = $this->find('xpath', $xpath, $exception);
+        $restorelink->click();
+
+        // Confirm the backup contents.
+        $restore = $this->find_button('Continue')->press();
+    }
+
+    /**
+     * Executes the common steps of all restore processes.
+     *
+     * @param TableNode $options The backup and restore options or false if no options provided
+     * @return void
+     */
+    protected function process_restore($options) {
+
+        // Settings.
+        $this->fill_backup_restore_form($options);
+        $this->find_button('Next')->press();
+
+        // Schema.
+        $this->fill_backup_restore_form($options);
+        $this->find_button('Next')->press();
+
+        // Review, no options here.
+        $this->find_button('Perform restore')->press();
+        $this->wait(10);
+
+        // Last restore continue button, redirected to restore course after this.
+        $this->find_button('Continue')->press();
+    }
+
+    /**
+     * Tries to fill the current page form elements with the provided options.
+     *
+     * This step is slow as it spins over each provided option, we are
+     * not expected to have lots of provided options, anyways, is better
+     * to be conservative and wait for the elements to appear rather than
+     * to have false failures.
+     *
+     * @param TableNode $options The backup and restore options or false if no options provided
+     * @return void
+     */
+    protected function fill_backup_restore_form($options) {
+
+        // Nothing to fill if no options are provided.
+        if (!$options) {
+            return;
+        }
+
+        // If we find any of the provided options in the current form we should set the value.
+        $datahash = $options->getRowsHash();
+        foreach ($datahash as $locator => $value) {
+
+            try {
+                $fieldnode = $this->find_field($locator);
+                $field = behat_field_manager::get_field($fieldnode, $locator, $this->getSession());
+                $field->set_value($value);
+
+            } catch (ElementNotFoundException $e) {
+                // Next provided option then, this one should be part of another page's fields.
+            }
+        }
+    }
+
+    /**
+     * Waits until the DOM is ready.
+     *
+     * @param int To override the default timeout
+     * @return void
+     */
+    protected function wait($timeout = false) {
+
+        if (!$timeout) {
+            $timeout = self::TIMEOUT;
+        }
+        $this->getSession()->wait($timeout, '(document.readyState === "complete")');
+    }
+
+}
diff --git a/backup/util/ui/tests/behat/duplicate_activities.feature b/backup/util/ui/tests/behat/duplicate_activities.feature
new file mode 100644 (file)
index 0000000..f23efc4
--- /dev/null
@@ -0,0 +1,33 @@
+@backup
+Feature: Duplicate activities
+  In order to set up my course contents quickly
+  As a moodle teacher
+  I need to duplicate activities inside the same course
+
+  @javascript
+  Scenario: Duplicate an activity
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@asd.com |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Database" to section "1" and I fill the form with:
+      | Name | Test database name |
+      | Description | Test database description |
+    When I click on "Duplicate" "link" in the "#section-1" "css_element"
+    And I press "Continue"
+    And I press "Edit the new copy"
+    And I fill the moodle form with:
+      | Name | Duplicated database name |
+      | Description | Duplicated database description |
+    And I press "Save and return to course"
+    Then I should see "Test database name" in the "#section-1" "css_element"
+    And I should see "Duplicated database name" in the "#section-1" "css_element"
+    And "Test database name" "link" should appear before "Duplicated database name" "link"
diff --git a/backup/util/ui/tests/behat/restore_moodle2_courses.feature b/backup/util/ui/tests/behat/restore_moodle2_courses.feature
new file mode 100644 (file)
index 0000000..2c4a57e
--- /dev/null
@@ -0,0 +1,100 @@
+@backup
+Feature: Restore Moodle 2 course backups
+  In order to continue using my stored course contents
+  As a moodle teacher and as a moodle admin
+  I need to restore them inside other Moodle courses or in new courses
+
+  Background:
+    Given the following "courses" exists:
+      | fullname | shortname | category | format |
+      | Course 1 | C1 | 0 | topics |
+      | Course 2 | C2 | 0 | topics |
+    And I log in as "admin"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "forum" to section "1" and I fill the form with:
+      | Forum name | Test forum name |
+      | Description | Test forum description |
+    And I add the "Community finder" block
+
+  @javascript
+  Scenario: Restore a course in another existing course
+    When I backup "Course 1" course using this options:
+      | Filename | test_backup.mbz |
+    And I restore "test_backup.mbz" backup into "Course 2" course using this options:
+    Then I should see "Course 2"
+    And I should see "Community finder"
+    And I should see "Test forum name"
+
+  @javascript
+  Scenario: Restore a course in a new course
+    When I backup "Course 1" course using this options:
+      | Filename | test_backup.mbz |
+    And I restore "test_backup.mbz" backup into a new course using this options:
+      | Course name | Course 1 restored in a new course |
+    Then I should see "Course 1 restored in a new course"
+    And I should see "Community finder"
+    And I should see "Test forum name"
+
+  @javascript
+  Scenario: Restore a backup into the same course
+    When I backup "Course 1" course using this options:
+      | Filename | test_backup.mbz |
+    And I merge "test_backup.mbz" backup into the current course using this options:
+      | setting_section_section_5_included | 0 |
+      | setting_section_section_5_userinfo | 0 |
+    Then I should see "Course 1"
+    And I should not see "Section 3"
+    And I should see "Community finder"
+    And I should see "Test forum name"
+
+  @javascript
+  Scenario: Restore a backup into the same course removing it's contents before that
+    When I backup "Course 1" course using this options:
+      | Filename | test_backup.mbz |
+    And I follow "Course 1"
+    And I add a "Forum" to section "1" and I fill the form with:
+      | Forum name | Test forum post backup name |
+      | Description | Test forum post backup description |
+    And I follow "Restore"
+    And I merge "test_backup.mbz" backup into the current course after deleting it's contents using this options:
+      | setting_section_section_5_userinfo | 0 |
+      | setting_section_section_5_included | 0 |
+    Then I should see "Course 1"
+    And I should not see "Section 3"
+    And I should not see "Test forum post backup name"
+    And I should see "Community finder"
+    And I should see "Test forum name"
+
+  @javascript
+  Scenario: Restore a backup into a new course changing the course format afterwards
+    Given I backup "Course 1" course using this options:
+      | Filename | test_backup.mbz |
+    When I restore "test_backup.mbz" backup into a new course using this options:
+    Then I should see "Topic 1"
+    And I should see "Test forum name"
+    And I follow "Edit settings"
+    And the "id_format" field should match "Topics format" value
+    And I fill the moodle form with:
+      | id_startdate_day | 1 |
+      | id_startdate_month | January |
+      | id_startdate_year | 2020 |
+      | id_format | Weekly format |
+    And I press "Save changes"
+    And I should see "1 January - 7 January"
+    And I should see "Test forum name"
+    And I follow "Edit settings"
+    And the "id_format" field should match "Weekly format" value
+    And I fill the moodle form with:
+      | id_format | Social format |
+    And I press "Save changes"
+    And I should see "An open forum for chatting about anything you want to"
+    And I follow "Edit settings"
+    And the "id_format" field should match "Social format" value
+    And I fill the moodle form with:
+      | id_format | SCORM format |
+    And I press "Save changes"
+    And I should see "Adding a new SCORM package"
+    And I follow "Edit settings"
+    And the "id_format" field should match "SCORM format" value
+    And I press "Cancel"
index 9f05b7f..88aa33f 100644 (file)
@@ -40,7 +40,7 @@ M.core_backup.select_all_init = function(str) {
                 '</div>';
     };
 
-    var firstsection = Y.one('fieldset#coursesettings .fcontainer.clearfix .grouped_settings.section_level');
+    var firstsection = Y.one('fieldset#id_coursesettings .fcontainer.clearfix .grouped_settings.section_level');
     if (!firstsection) {
         // This is not a relevant page.
         return;
index 540c49a..a9aeb45 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 include_once($CFG->dirroot . '/course/lib.php');
+include_once($CFG->libdir . '/coursecatlib.php');
 
 class block_course_list extends block_list {
     function init() {
@@ -53,11 +54,11 @@ class block_course_list extends block_list {
             }
         }
 
-        $categories = get_categories("0");  // Parent = 0   ie top-level categories only
+        $categories = coursecat::get(0)->get_children();  // Parent = 0   ie top-level categories only
         if ($categories) {   //Check we have categories
             if (count($categories) > 1 || (count($categories) == 1 && $DB->count_records('course') > 200)) {     // Just print top level category links
                 foreach ($categories as $category) {
-                    $categoryname = format_string($category->name, true, array('context' => context_coursecat::instance($category->id)));
+                    $categoryname = $category->get_formatted_name();
                     $linkcss = $category->visible ? "" : " class=\"dimmed\" ";
                     $this->content->items[]="<a $linkcss href=\"$CFG->wwwroot/course/category.php?id=$category->id\">".$icon . $categoryname . "</a>";
                 }
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-coverage.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-coverage.js
new file mode 100644 (file)
index 0000000..5ec86de
Binary files /dev/null and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-coverage.js differ
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js
new file mode 100644 (file)
index 0000000..9ba9df7
Binary files /dev/null and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js differ
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js
new file mode 100644 (file)
index 0000000..2f09116
Binary files /dev/null and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js differ
diff --git a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js
new file mode 100644 (file)
index 0000000..9ba9df7
Binary files /dev/null and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js differ
diff --git a/blocks/navigation/yui/src/navigation/build.json b/blocks/navigation/yui/src/navigation/build.json
new file mode 100644 (file)
index 0000000..5e28a6c
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "name": "moodle-block_navigation-navigation",
+  "builds": {
+    "moodle-block_navigation-navigation": {
+      "jsfiles": [
+        "navigation.js"
+      ]
+    }
+  }
+}
@@ -1,5 +1,3 @@
-YUI.add('moodle-block_navigation-navigation', function(Y){
-
 /**
  * A 'actionkey' Event to help with Y.delegate().
  * The event consists of the left arrow, right arrow, enter and space keys.
@@ -28,10 +26,11 @@ Y.Event.define("actionkey", {
     },
 
     _keyHandler: function (e, notifier, args) {
+        var actObj;
         if (!args.actions) {
-            var actObj = {collapse:true, expand:true, toggle:true, enter:true};
+            actObj = {collapse:true, expand:true, toggle:true, enter:true};
         } else {
-            var actObj = args.actions;
+            actObj = args.actions;
         }
         if (this._keys[e.keyCode] && actObj[this._keys[e.keyCode]]) {
             e.action = this._keys[e.keyCode];
@@ -41,7 +40,7 @@ Y.Event.define("actionkey", {
 
     on: function (node, sub, notifier) {
         // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
-        if (sub.args == null) {
+        if (sub.args === null) {
             //no actions given
             sub._detacher = node.on(this._event, this._keyHandler,this, notifier, {actions:false});
         } else {
@@ -49,14 +48,14 @@ Y.Event.define("actionkey", {
         }
     },
 
-    detach: function (node, sub, notifier) {
+    detach: function (node, sub) {
         //detach our _detacher handle of the subscription made in on()
         sub._detacher.detach();
     },
 
     delegate: function (node, sub, notifier, filter) {
         // subscribe to _event and ask keyHandler to handle with given args[0] (the desired actions).
-        if (sub.args == null) {
+        if (sub.args === null) {
             //no actions given
             sub._delegateDetacher = node.delegate(this._event, this._keyHandler,filter, this, notifier, {actions:false});
         } else {
@@ -64,14 +63,14 @@ Y.Event.define("actionkey", {
         }
     },
 
-    detachDelegate: function (node, sub, notifier) {
+    detachDelegate: function (node, sub) {
         sub._delegateDetacher.detach();
     }
 });
 
 var EXPANSIONLIMIT_EVERYTHING = 0,
-    EXPANSIONLIMIT_COURSE     = 20,
-    EXPANSIONLIMIT_SECTION    = 30,
+    //EXPANSIONLIMIT_COURSE     = 20,
+    //EXPANSIONLIMIT_SECTION    = 30,
     EXPANSIONLIMIT_ACTIVITY   = 40;
 
 /**
@@ -104,7 +103,7 @@ var NODETYPE = {
     USER : 80,
     /** @type int Container = 90 */
     CONTAINER : 90
-}
+};
 
 /**
  * Navigation tree class.
@@ -112,9 +111,9 @@ var NODETYPE = {
  * This class establishes the tree initially, creating expandable branches as
  * required, and delegating the expand/collapse event.
  */
-var TREE = function(config) {
+var TREE = function() {
     TREE.superclass.constructor.apply(this, arguments);
-}
+};
 TREE.prototype = {
     /**
      * The tree's ID, normally its block instance id.
@@ -189,7 +188,7 @@ TREE.prototype = {
         // First check if they managed to click on the li iteslf, then find the closest
         // LI ancestor and use that
 
-        if (e.target.test('a') && (e.keyCode == 0 || e.keyCode == 13)) {
+        if (e.target.test('a') && (e.keyCode === 0 || e.keyCode === 13)) {
             // A link has been clicked (or keypress is 'enter') don't fire any more events just do the default.
             e.stopPropagation();
             return;
@@ -198,7 +197,7 @@ TREE.prototype = {
         // Makes sure we can get to the LI containing the branch.
         var target = e.target;
         if (!target.test('li')) {
-            target = target.ancestor('li')
+            target = target.ancestor('li');
         }
         if (!target) {
             return;
@@ -206,7 +205,7 @@ TREE.prototype = {
 
         // Toggle expand/collapse providing its not a root level branch.
         if (!target.hasClass('depth_1')) {
-            if (e.type == 'actionkey') {
+            if (e.type === 'actionkey') {
                 switch (e.action) {
                     case 'expand' :
                         target.removeClass('collapsed');
@@ -247,7 +246,7 @@ TREE.prototype = {
             }
         }
     }
-}
+};
 // The tree extends the YUI base foundation.
 Y.extend(TREE, Y.Base, TREE.prototype, {
     NAME : 'navigation-tree',
@@ -266,7 +265,7 @@ Y.extend(TREE, Y.Base, TREE.prototype, {
         expansionlimit : {
             value : 0,
             setter : function(val) {
-                return parseInt(val);
+                return parseInt(val, 10);
             }
         }
     }
@@ -280,9 +279,9 @@ if (M.core_dock && M.core_dock.genericblock) {
  * This class is used to manage a tree branch, in particular its ability to load
  * its contents by AJAX.
  */
-var BRANCH = function(config) {
+BRANCH = function() {
     BRANCH.superclass.constructor.apply(this, arguments);
-}
+};
 BRANCH.prototype = {
     /**
      * The node for this branch (p)
@@ -292,17 +291,19 @@ BRANCH.prototype = {
      * Initialises the branch when it is first created.
      */
     initializer : function(config) {
+        var i,
+            children;
         if (config.branchobj !== null) {
             // Construct from the provided xml
-            for (var i in config.branchobj) {
+            for (i in config.branchobj) {
                 this.set(i, config.branchobj[i]);
             }
-            var children = this.get('children');
+            children = this.get('children');
             this.set('haschildren', (children.length > 0));
         }
         if (config.overrides !== null) {
             // Construct from the provided xml
-            for (var i in config.overrides) {
+            for (i in config.overrides) {
                 this.set(i, config.overrides[i]);
             }
         }
@@ -311,7 +312,7 @@ BRANCH.prototype = {
         // Now check whether the branch is not expandable because of the expansionlimit
         var expansionlimit = this.get('tree').get('expansionlimit');
         var type = this.get('type');
-        if (expansionlimit != EXPANSIONLIMIT_EVERYTHING &&  type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {
+        if (expansionlimit !== EXPANSIONLIMIT_EVERYTHING &&  type >= expansionlimit && type <= EXPANSIONLIMIT_ACTIVITY) {
             this.set('expandable', false);
             this.set('haschildren', false);
         }
@@ -413,12 +414,12 @@ BRANCH.prototype = {
      * request made here.
      */
     ajaxLoad : function(e) {
-        if (e.type == 'actionkey' && e.action != 'enter') {
+        if (e.type === 'actionkey' && e.action !== 'enter') {
             e.halt();
         } else {
             e.stopPropagation();
         }
-        if (e.type = 'actionkey' && e.action == 'enter' && e.target.test('A')) {
+        if (e.type === 'actionkey' && e.action === 'enter' && e.target.test('A')) {
             // No ajaxLoad for enter.
             this.node.setAttribute('data-expandable', '0');
             this.node.setAttribute('data-loaded', '1');
@@ -466,7 +467,7 @@ BRANCH.prototype = {
             if (object.children && object.children.length > 0) {
                 var coursecount = 0;
                 for (var i in object.children) {
-                    if (typeof(object.children[i])=='object') {
+                    if (typeof(object.children[i])==='object') {
                         if (object.children[i].type == NODETYPE.COURSE) {
                             coursecount++;
                         }
@@ -502,7 +503,7 @@ BRANCH.prototype = {
                 if (children[i].type == NODETYPE.COURSE) {
                     count++;
                 }
-                if (typeof(children[i])=='object') {
+                if (typeof(children[i]) === 'object') {
                     branch.addChild(children[i]);
                 }
             }
@@ -536,7 +537,7 @@ BRANCH.prototype = {
             icon : {'pix':"i/navigationitem",'component':'moodle'}
         });
     }
-}
+};
 Y.extend(BRANCH, Y.Base, BRANCH.prototype, {
     NAME : 'navigation-branch',
     ATTRS : {
@@ -558,7 +559,7 @@ Y.extend(BRANCH, Y.Base, BRANCH.prototype, {
             value : '',
             validator : Y.Lang.isString,
             getter : function(val) {
-                if (val == '') {
+                if (val === '') {
                     val = 'expandable_branch_'+M.block_navigation.expandablebranchcount;
                     M.block_navigation.expandablebranchcount++;
                 }
@@ -620,5 +621,3 @@ M.block_navigation = M.block_navigation || {
         new TREE(properties);
     }
 };
-
-}, '@VERSION@', {requires:['base', 'core_dock', 'io-base', 'node', 'dom', 'event-custom', 'event-delegate', 'json-parse']});
diff --git a/blocks/navigation/yui/src/navigation/meta/navigation.json b/blocks/navigation/yui/src/navigation/meta/navigation.json
new file mode 100644 (file)
index 0000000..b4c3760
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "moodle-block_navigation-navigation": {
+    "requires": [
+        "base",
+        "core_dock",
+        "io-base",
+        "node",
+        "dom",
+        "event-custom",
+        "event-delegate",
+        "json-parse"
+    ]
+  }
+}
index 922734a..e696c46 100644 (file)
@@ -54,7 +54,7 @@ class block_rss_client_edit_form extends block_edit_form {
                 FROM {block_rss_client}
                 WHERE userid = ? OR shared = 1
                 ORDER BY CASE WHEN preferredtitle = ? THEN ' . $DB->sql_compare_text('title', 64) . ' ELSE preferredtitle END ',
-                array($DB->sql_empty(), $USER->id, $DB->sql_empty()));
+                array('', $USER->id, ''));
         if ($rssfeeds) {
             $select = $mform->addElement('select', 'config_rssid', get_string('choosefeedlabel', 'block_rss_client'), $rssfeeds);
             $select->setMultiple(true);
index 7ee5644..47caaaa 100644 (file)
@@ -4,8 +4,7 @@ Feature: Add blocks
   As a teacher
   I need to add blocks to pages
 
-  @javascript
-  Scenario: Add a block to a course
+  Background:
     Given the following "users" exists:
       | username | firstname | lastname | email |
       | student1 | Student | 1 | student1@asd.com |
@@ -21,4 +20,9 @@ Feature: Add blocks
     And I follow "Course 1"
     And I turn editing mode on
     When I add the "Blog menu" block
-    Then I should see "View all of my entries"
+    Then I should see "View my entries about this course"
+
+  @javascript
+  Scenario: Add a block to a course with Javascript enabled
+
+  Scenario: Add a block to a course with Javascript disabled
index c90f1df..1c8f70d 100644 (file)
@@ -46,7 +46,16 @@ class behat_blocks extends behat_base {
      * @param string $blockname
      */
     public function i_add_the_block($blockname) {
-        return new Given('I select "' . $blockname . '" from "bui_addblock"');
+        $steps = new Given('I select "' . $blockname . '" from "bui_addblock"');
+
+        // If we are running without javascript we need to submit the form.
+        if (!$this->running_javascript()) {
+            $steps = array(
+                $steps,
+                new Given('I click on "Go" "button" in the "#add_block" "css_element"')
+            );
+        }
+        return $steps;
     }
 
 }
index 542e7a0..9708a01 100644 (file)
@@ -49,7 +49,9 @@ class cachestore_addinstance_form extends moodleform {
         $locks = $this->_customdata['locks'];
 
         $form->addElement('hidden', 'plugin', $plugin);
+        $form->setType('plugin', PARAM_PLUGIN);
         $form->addElement('hidden', 'editing', !empty($this->_customdata['store']));
+        $form->setType('editing', PARAM_BOOL);
 
         if (!$store) {
             $form->addElement('text', 'name', get_string('storename', 'cache'));
@@ -59,6 +61,7 @@ class cachestore_addinstance_form extends moodleform {
         } else {
             $form->addElement('hidden', 'name', $store);
             $form->addElement('static', 'name-value', get_string('storename', 'cache'), $store);
+            $form->setType('name', PARAM_TEXT);
         }
 
         if (is_array($locks)) {
@@ -214,4 +217,4 @@ class cache_mode_mappings_form extends moodleform {
 
         $this->add_action_buttons();
     }
-}
\ No newline at end of file
+}
index c23c249..fb7409e 100644 (file)
@@ -85,9 +85,9 @@ class cohort_edit_form extends moodleform {
     }
 
     protected function get_category_options($currentcontextid) {
-        $displaylist = array();
-        $parentlist = array();
-        make_categories_list($displaylist, $parentlist, 'moodle/cohort:manage');
+        global $CFG;
+        require_once($CFG->libdir. '/coursecatlib.php');
+        $displaylist = coursecat::make_categories_list('moodle/cohort:manage');
         $options = array();
         $syscontext = context_system::instance();
         if (has_capability('moodle/cohort:manage', $syscontext)) {
index b71b00b..61d56c9 100644 (file)
@@ -40,7 +40,6 @@ function cohort_add_cohort($cohort) {
         $cohort->idnumber = NULL;
     }
     if (!isset($cohort->description)) {
-        // sql_empty() does not belong here, this crazy Oracle hack is implemented in insert_record()!
         $cohort->description = '';
     }
     if (!isset($cohort->descriptionformat)) {
@@ -102,7 +101,7 @@ function cohort_delete_cohort($cohort) {
  * Somehow deal with cohorts when deleting course category,
  * we can not just delete them because they might be used in enrol
  * plugins or referenced in external systems.
- * @param  stdClass $category
+ * @param  stdClass|coursecat $category
  * @return void
  */
 function cohort_delete_category($category) {
diff --git a/completion/tests/behat/behat_completion.php b/completion/tests/behat/behat_completion.php
new file mode 100644 (file)
index 0000000..7bf57fb
--- /dev/null
@@ -0,0 +1,100 @@
+<?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/>.
+
+/**
+ * Completion steps definitions.
+ *
+ * @package    core_completion
+ * @category   test
+ * @copyright  2013 David Monllaó
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
+
+require_once(__DIR__ . '/../../../lib/behat/behat_base.php');
+
+use Behat\Behat\Context\Step\Given as Given,
+    Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
+
+/**
+ * Steps definitions to deal with course and activities completion.
+ *
+ * @package    core_completion
+ * @category   test
+ * @copyright  2013 David Monllaó
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class behat_completion extends behat_base {
+
+    /**
+     * Checks that the specified user has completed the specified activity of the current course.
+     *
+     * @Then /^"(?P<user_fullname_string>(?:[^"]|\\")*)" user has completed "(?P<activity_name_string>(?:[^"]|\\")*)" activity$/
+     * @param string $userfullname
+     * @param string $activityname
+     */
+    public function user_has_completed_activity($userfullname, $activityname) {
+
+        // Will throw an exception if the element can not be hovered.
+        $xpath = "//table[@id='completion-progress']/descendant::img[contains(@title, '" . $userfullname . ", " . $activityname . ": Completed')]";
+
+        return array(
+            new Given('I go to the current course activity completion report'),
+            new Given('I hover "' . $xpath . '" "xpath_element"')
+        );
+    }
+
+    /**
+     * Checks that the specified user has not completed the specified activity of the current course.
+     *
+     * @Then /^"(?P<user_fullname_string>(?:[^"]|\\")*)" user has not completed "(?P<activity_name_string>(?:[^"]|\\")*)" activity$/
+     * @param string $userfullname
+     * @param string $activityname
+     */
+    public function user_has_not_completed_activity($userfullname, $activityname) {
+
+        $xpath = "//table[@id='completion-progress']/descendant::img[contains(@title, '" . $userfullname . ", " . $activityname . ": Not completed')]";
+        return array(
+            new Given('I go to the current course activity completion report'),
+            new Given('I hover "' . $xpath . '" "xpath_element"')
+        );
+
+        return $steps;
+    }
+
+    /**
+     * Goes to the current course activity completion report.
+     *
+     * @Given /^I go to the current course activity completion report$/
+     */
+    public function go_to_the_current_course_activity_completion_report() {
+
+        $steps = array();
+
+        // Expand reports node if we can't see the link.
+        try {
+            $this->find('xpath', "//*[@id='settingsnav']/descendant::li/descendant::li[not(contains(@class,'collapsed'))]/descendant::p[contains(., 'Activity completion')]");
+        } catch (ElementNotFoundException $e) {
+            $steps[] = new Given('I expand "Reports" node');
+        }
+
+        $steps[] = new Given('I follow "Activity completion"');
+
+        return $steps;
+    }
+
+}
diff --git a/completion/tests/behat/enable_manual_complete_mark.feature b/completion/tests/behat/enable_manual_complete_mark.feature
new file mode 100644 (file)
index 0000000..0afd58f
--- /dev/null
@@ -0,0 +1,47 @@
+@core_completion
+Feature: Allow students to manually mark an activity as complete
+  In order to let students decide when an activity is completed
+  As a moodle teacher
+  I need to allow students to mark activities as completed
+
+  @javascript
+  Scenario: Mark an activity as completed
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | Frist | teacher1@asd.com |
+      | student1 | Student | First | student1@asd.com |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+    And I log in as "admin"
+    And I set the following administration settings values:
+      | Enable completion tracking | 1 |
+      | Enable conditional access | 1 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I follow "Edit settings"
+    And I fill the moodle form with:
+      | Completion tracking | Enabled, control via completion and activity settings |
+      | Completion tracking begins on enrolment | 1 |
+    And I press "Save changes"
+    When I add a "Forum" to section "1" and I fill the form with:
+      | Forum name | Test forum name |
+      | Description | Test forum description |
+    Then "Student First" user has not completed "Test forum name" activity
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I press "Mark as complete: Test forum name"
+    And I wait "3" seconds
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I expand "Reports" node
+    And I follow "Activity completion"
+    And "Student First" user has completed "Test forum name" activity
diff --git a/completion/tests/behat/restrict_section_availability.feature b/completion/tests/behat/restrict_section_availability.feature
new file mode 100644 (file)
index 0000000..88866b1
--- /dev/null
@@ -0,0 +1,53 @@
+@core_completion
+Feature: Restrict sections availability through completion conditions
+  In order to control section's contents access through activities completion
+  As a moodle teacher
+  I need to restrict sections availability using different conditions
+
+  @javascript
+  Scenario: Show section greyed-out to students when completion conditions are not satisfied
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "users" exists:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | Frist | teacher1@asd.com |
+      | student1 | Student | First | student1@asd.com |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+    And I log in as "admin"
+    And I set the following administration settings values:
+      | Enable completion tracking | 1 |
+      | Enable conditional access | 1 |
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I follow "Edit settings"
+    And I fill the moodle form with:
+      | Completion tracking | Enabled, control via completion and activity settings |
+      | Completion tracking begins on enrolment | 1 |
+    And I press "Save changes"
+    And I add a "Label" to section "1" and I fill the form with:
+      | Label text | Test label |
+      | Completion tracking | Students can manually mark the activity as completed |
+    And I add a "Page" to section "2" and I fill the form with:
+      | Name | Test page name |
+      | Description | Test page description |
+      | Page content | Test page contents |
+    When I click on "Edit summary" "link" in the "#section-2" "css_element"
+    And I fill the moodle form with:
+      | id_conditioncompletiongroup_0_conditionsourcecmid | Test label |
+      | id_conditioncompletiongroup_0_conditionrequiredcompletion | must be marked complete |
+      | Before section can be accessed | Show section greyed-out, with restriction information |
+    And I press "Save changes"
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    Then I should see "Not available until the activity Test label is marked complete."
+    And I should not see "Test page name"
+    And I press "Not completed: Test label. Select to mark as complete."
+    And I should see "Test page name"
+    And I should not see "Not available until the activity Test label is marked complete."
index e32eba9..6ed1898 100644 (file)
@@ -26,6 +26,7 @@
 require_once("../config.php");
 require_once($CFG->dirroot.'/course/lib.php');
 require_once($CFG->libdir.'/textlib.class.php');
+require_once($CFG->libdir. '/coursecatlib.php');
 
 $id = required_param('id', PARAM_INT); // Category id
 $page = optional_param('page', 0, PARAM_INT); // which page to show
@@ -69,9 +70,7 @@ $PAGE->set_button(print_course_search('', true, 'navbar'));
 echo $OUTPUT->header();
 
 /// Print the category selector
-$displaylist = array();
-$notused = array();
-make_categories_list($displaylist, $notused);
+$displaylist = coursecat::make_categories_list();
 
 echo '<div class="categorypicker">';
 $select = new single_select(new moodle_url('/course/category.php'), 'id', $displaylist, $category->id, null, 'switchcategory');
index 4344aa3..7dab70a 100644 (file)
@@ -97,9 +97,8 @@ class course_completion_form extends moodleform {
             }
 
             // Get category list
-            $list = array();
-            $parents = array();
-            make_categories_list($list, $parents);
+            require_once($CFG->libdir. '/coursecatlib.php');
+            $list = coursecat::make_categories_list();
 
             // Get course list for select box
             $selectbox = array();
index e7af4b1..f76655e 100644 (file)
@@ -6,69 +6,25 @@ if (!defined('MOODLE_INTERNAL')) {
 
 require_once($CFG->libdir.'/formslib.php');
 require_once($CFG->libdir.'/questionlib.php');
+require_once($CFG->libdir. '/coursecatlib.php');
 
 class delete_category_form extends moodleform {
 
     var $_category;
 
     function definition() {
-        global $CFG, $DB;
-
-        $mform    =& $this->_form;
-        $category = $this->_customdata;
-        $categorycontext = context_coursecat::instance($category->id);
-        $this->_category = $category;
-
-    /// Check permissions, to see if it OK to give the option to delete
-    /// the contents, rather than move elsewhere.
-    /// Are there any subcategories of this one, can they be deleted?
-        $candeletecontent = true;
-        $tocheck = get_child_categories($category->id);
-        $containscategories = !empty($tocheck);
-        $categoryids = array($category->id);
-        while (!empty($tocheck)) {
-            $checkcat = array_pop($tocheck);
-            $childcategoryids[] = $checkcat->id;
-            $tocheck = $tocheck + get_child_categories($checkcat->id);
-            $chcontext = context_coursecat::instance($checkcat->id);
-            if ($candeletecontent && !has_capability('moodle/category:manage', $chcontext)) {
-                $candeletecontent = false;
-            }
-        }
-
-    /// Are there any courses in here, can they be deleted?
-        list($test, $params) = $DB->get_in_or_equal($categoryids);
-        $containedcourses = $DB->get_records_sql(
-                "SELECT id,1 FROM {course} c WHERE c.category $test", $params);
-        $containscourses = false;
-        if ($containedcourses) {
-            $containscourses = true;
-            foreach ($containedcourses as $courseid => $notused) {
-                if ($candeletecontent && !can_delete_course($courseid)) {
-                    $candeletecontent = false;
-                    break;
-                }
-            }
-        }
+        $mform = & $this->_form;
+        $this->_category = $this->_customdata;
+        $categorycontext = context_coursecat::instance($this->_category->id);
 
-    /// Are there any questions in the question bank here?
-        $containsquestions = question_context_has_any_questions($categorycontext);
+        // Check permissions, to see if it OK to give the option to delete
+        // the contents, rather than move elsewhere.
+        $candeletecontent = $this->_category->can_delete_full();
 
-    /// Get the list of categories we might be able to move to.
-        $testcaps = array();
-        if ($containscourses) {
-            $testcaps[] = 'moodle/course:create';
-        }
-        if ($containscategories || $containsquestions) {
-            $testcaps[] = 'moodle/category:manage';
-        }
-        $displaylist = array();
-        $notused = array();
-        if (!empty($testcaps)) {
-            make_categories_list($displaylist, $notused, $testcaps, $category->id);
-        }
+        // Get the list of categories we might be able to move to.
+        $displaylist = $this->_category->move_content_targets_list();
 
-    /// Now build the options.
+        // Now build the options.
         $options = array();
         if ($displaylist) {
             $options[0] = get_string('movecontentstoanothercategory');
@@ -76,60 +32,57 @@ class delete_category_form extends moodleform {
         if ($candeletecontent) {
             $options[1] = get_string('deleteallcannotundo');
         }
+        if (empty($options)) {
+            print_error('youcannotdeletecategory', 'error', 'index.php', $this->_category->get_formatted_name());
+        }
 
-    /// Now build the form.
-        $mform->addElement('header','general', get_string('categorycurrentcontents', '', format_string($category->name, true, array('context' => $categorycontext))));
+        // Now build the form.
+        $mform->addElement('header','general', get_string('categorycurrentcontents', '', $this->_category->get_formatted_name()));
 
-        if ($containscourses || $containscategories || $containsquestions) {
-            if (empty($options)) {
-                print_error('youcannotdeletecategory', 'error', 'index.php', format_string($category->name, true, array('context' => $categorycontext)));
-            }
+        // Describe the contents of this category.
+        $contents = '';
+        if ($this->_category->has_children()) {
+            $contents .= '<li>' . get_string('subcategories') . '</li>';
+        }
+        if ($this->_category->has_courses()) {
+            $contents .= '<li>' . get_string('courses') . '</li>';
+        }
+        if (question_context_has_any_questions($categorycontext)) {
+            $contents .= '<li>' . get_string('questionsinthequestionbank') . '</li>';
+        }
+        if (!empty($contents)) {
+            $mform->addElement('static', 'emptymessage', get_string('thiscategorycontains'), html_writer::tag('ul', $contents));
+        } else {
+            $mform->addElement('static', 'emptymessage', '', get_string('deletecategoryempty'));
+        }
 
-        /// Describe the contents of this category.
-            $contents = '<ul>';
-            if ($containscategories) {
-                $contents .= '<li>' . get_string('subcategories') . '</li>';
-            }
-            if ($containscourses) {
-                $contents .= '<li>' . get_string('courses') . '</li>';
-            }
-            if ($containsquestions) {
-                $contents .= '<li>' . get_string('questionsinthequestionbank') . '</li>';
-            }
-            $contents .= '</ul>';
-            $mform->addElement('static', 'emptymessage', get_string('thiscategorycontains'), $contents);
-
-        /// Give the options for what to do.
-            $mform->addElement('select', 'fulldelete', get_string('whattodo'), $options);
-            if (count($options) == 1) {
-                $optionkeys = array_keys($options);
-                $option = reset($optionkeys);
-                $mform->hardFreeze('fulldelete');
-                $mform->setConstant('fulldelete', $option);
-            }
+        // Give the options for what to do.
+        $mform->addElement('select', 'fulldelete', get_string('whattodo'), $options);
+        if (count($options) == 1) {
+            $optionkeys = array_keys($options);
+            $option = reset($optionkeys);
+            $mform->hardFreeze('fulldelete');
+            $mform->setConstant('fulldelete', $option);
+        }
 
-            if ($displaylist) {
-                $mform->addElement('select', 'newparent', get_string('movecategorycontentto'), $displaylist);
-                if (in_array($category->parent, $displaylist)) {
-                    $mform->setDefault('newparent', $category->parent);
-                }
-                $mform->disabledIf('newparent', 'fulldelete', 'eq', '1');
+        if ($displaylist) {
+            $mform->addElement('select', 'newparent', get_string('movecategorycontentto'), $displaylist);
+            if (in_array($this->_category->parent, $displaylist)) {
+                $mform->setDefault('newparent', $this->_category->parent);
             }
-        } else {
-            $mform->addElement('hidden', 'fulldelete', 1);
-            $mform->setType('fulldelete', PARAM_INT);
-            $mform->addElement('static', 'emptymessage', '', get_string('deletecategoryempty'));
+            $mform->disabledIf('newparent', 'fulldelete', 'eq', '1');
         }
 
         $mform->addElement('hidden', 'deletecat');
         $mform->setType('deletecat', PARAM_ALPHANUM);
         $mform->addElement('hidden', 'sure');
         $mform->setType('sure', PARAM_ALPHANUM);
-        $mform->setDefault('sure', md5(serialize($category)));
+        $mform->setDefault('sure', md5(serialize($this->_category)));
 
 //--------------------------------------------------------------------------------
         $this->add_action_buttons(true, get_string('delete'));
 
+        $this->set_data(array('deletecat' => $this->_category->id));
     }
 
 /// perform some extra moodle validation
index b7e8994..41076c9 100644 (file)
@@ -51,7 +51,7 @@ function dndupload_add_to_course($course, $modnames) {
     // Add the javascript to the page.
     $jsmodule = array(
         'name' => 'coursedndupload',
-        'fullpath' => new moodle_url('/course/dndupload.js'),
+        'fullpath' => '/course/dndupload.js',
         'strings' => array(
             array('addfilehere', 'moodle'),
             array('dndworkingfiletextlink', 'moodle'),
index ce7d8b7..bfa6ca6 100644 (file)
@@ -4,6 +4,7 @@ defined('MOODLE_INTERNAL') || die;
 
 require_once($CFG->libdir.'/formslib.php');
 require_once($CFG->libdir.'/completionlib.php');
+require_once($CFG->libdir. '/coursecatlib.php');
 
 class course_edit_form extends moodleform {
     protected $course;
@@ -48,9 +49,7 @@ class course_edit_form extends moodleform {
         // verify permissions to change course category or keep current
         if (empty($course->id)) {
             if (has_capability('moodle/course:create', $categorycontext)) {
-                $displaylist = array();
-                $parentlist = array();
-                make_categories_list($displaylist, $parentlist, 'moodle/course:create');
+                $displaylist = coursecat::make_categories_list('moodle/course:create');
                 $mform->addElement('select', 'category', get_string('category'), $displaylist);
                 $mform->addHelpButton('category', 'category');
                 $mform->setDefault('category', $category->id);
@@ -61,12 +60,10 @@ class course_edit_form extends moodleform {
             }
         } else {
             if (has_capability('moodle/course:changecategory', $coursecontext)) {
-                $displaylist = array();
-                $parentlist = array();
-                make_categories_list($displaylist, $parentlist, 'moodle/course:create');
+                $displaylist = coursecat::make_categories_list('moodle/course:create');
                 if (!isset($displaylist[$course->category])) {
                     //always keep current
-                    $displaylist[$course->category] = format_string($DB->get_field('course_categories', 'name', array('id'=>$course->category)));
+                    $displaylist[$course->category] = coursecat::get($course->category)->get_formatted_name();
                 }
                 $mform->addElement('select', 'category', get_string('category'), $displaylist);
                 $mform->addHelpButton('category', 'category');
@@ -190,7 +187,9 @@ class course_edit_form extends moodleform {
         }
 
 //--------------------------------------------------------------------------------
+        // Just a placeholder..
         $mform->addElement('hidden', 'addcourseformatoptionshere');
+        $mform->setType('addcourseformatoptionshere', PARAM_BOOL);
 
 //--------------------------------------------------------------------------------
         enrol_course_edit_form($mform, $course, $context);
index b7184b7..355aca1 100644 (file)
@@ -27,8 +27,9 @@
  */
 
 require_once('../config.php');
-require_once('lib.php');
-require_once('editcategory_form.php');
+require_once($CFG->dirroot.'/course/lib.php');
+require_once($CFG->dirroot.'/course/editcategory_form.php');
+require_once($CFG->libdir.'/coursecatlib.php');
 
 require_login();
 
@@ -92,42 +93,16 @@ if ($mform->is_cancelled()) {
         redirect($CFG->wwwroot .'/course/manage.php');
     }
 } else if ($data = $mform->get_data()) {
-    $newcategory = new stdClass();
-    $newcategory->name = $data->name;
-    $newcategory->idnumber = $data->idnumber;
-    $newcategory->description_editor = $data->description_editor;
-    $newcategory->parent = $data->parent; // if $data->parent = 0, the new category will be a top-level category
-
-    if (isset($data->theme) && !empty($CFG->allowcategorythemes)) {
-        $newcategory->theme = $data->theme;
-    }
-
-    $logaction = 'update';
     if ($id) {
-        // Update an existing category.
-        $newcategory->id = $category->id;
-        if ($newcategory->parent != $category->parent) {
-            // check category manage capability if parent changed
-            require_capability('moodle/category:manage', get_category_or_system_context((int)$newcategory->parent));
-            $parent_cat = $DB->get_record('course_categories', array('id' => $newcategory->parent));
-            move_category($newcategory, $parent_cat);
+        $newcategory = coursecat::get($id);
+        if ($data->parent != $category->parent && !$newcategory->can_change_parent($data->parent)) {
+            print_error('cannotmovecategory');
         }
+        $newcategory->update($data, $editoroptions);
     } else {
-        // Create a new category.
-        $newcategory->description = $data->description_editor['text'];
-
-        // Don't overwrite the $newcategory object as it'll be processed by file_postupdate_standard_editor in a moment
-        $category = create_course_category($newcategory);
-        $newcategory->id = $category->id;
-        $categorycontext = $category->context;
-        $logaction = 'add';
+        $newcategory = coursecat::create($data, $editoroptions);
     }
 
-    $newcategory = file_postupdate_standard_editor($newcategory, 'description', $editoroptions, $categorycontext, 'coursecat', 'description', 0);
-    $DB->update_record('course_categories', $newcategory);
-    add_to_log(SITEID, "category", $logaction, "editcategory.php?id=$newcategory->id", $newcategory->id);
-    fix_course_sortorder();
-
     redirect('manage.php?id='.$newcategory->id);
 }
 
index 3e3cfe3..40ac48c 100644 (file)
@@ -4,6 +4,7 @@ if (!defined('MOODLE_INTERNAL')) {
 }
 
 require_once ($CFG->dirroot.'/course/moodleform_mod.php');
+require_once ($CFG->libdir.'/coursecatlib.php');
 class editcategory_form extends moodleform {
 
     // form definition
@@ -18,17 +19,16 @@ class editcategory_form extends moodleform {
         if (has_capability('moodle/category:manage', get_system_context()) || $category->parent == 0) {
             $options[0] = get_string('top');
         }
-        $parents = array();
         if ($category->id) {
             // Editing an existing category.
-            make_categories_list($options, $parents, 'moodle/category:manage', $category->id);
+            $options += coursecat::make_categories_list('moodle/category:manage', $category->id);
             if (empty($options[$category->parent])) {
                 $options[$category->parent] = $DB->get_field('course_categories', 'name', array('id'=>$category->parent));
             }
             $strsubmit = get_string('savechanges');
         } else {
             // Making a new category
-            make_categories_list($options, $parents, 'moodle/category:manage');
+            $options += coursecat::make_categories_list('moodle/category:manage');
             $strsubmit = get_string('createcategory');
         }
 
index 3063966..362f928 100644 (file)
@@ -1650,7 +1650,7 @@ class core_course_external extends external_api {
      */
     public static function create_categories($categories) {
         global $CFG, $DB;
-        require_once($CFG->dirroot . "/course/lib.php");
+        require_once($CFG->libdir . "/coursecatlib.php");
 
         $params = self::validate_parameters(self::create_categories_parameters(),
                         array('categories' => $categories));
@@ -1670,38 +1670,10 @@ class core_course_external extends external_api {
             self::validate_context($context);
             require_capability('moodle/category:manage', $context);
 
-            // Check name.
-            if (textlib::strlen($category['name'])>255) {
-                throw new moodle_exception('categorytoolong');
-            }
-
-            $newcategory = new stdClass();
-            $newcategory->name = $category['name'];
-            $newcategory->parent = $category['parent'];
-            // Format the description.
-            if (!empty($category['description'])) {
-                $newcategory->description = $category['description'];
-            }
-            $newcategory->descriptionformat = external_validate_format($category['descriptionformat']);
-            if (isset($category['theme']) and !empty($CFG->allowcategorythemes)) {
-                $newcategory->theme = $category['theme'];
-            }
-            // Check id number.
-            if (!empty($category['idnumber'])) { // Same as in course/editcategory_form.php .
-                if (textlib::strlen($category['idnumber'])>100) {
-                    throw new moodle_exception('idnumbertoolong');
-                }
-                if ($existing = $DB->get_record('course_categories', array('idnumber' => $category['idnumber']))) {
-                    if ($existing->id) {
-                        throw new moodle_exception('idnumbertaken');
-                    }
-                }
-                $newcategory->idnumber = $category['idnumber'];
-            }
+            // this will validate format and throw an exception if there are errors
+            external_validate_format($category['descriptionformat']);
 
-            $newcategory = create_course_category($newcategory);
-            // Populate special fields.
-            fix_course_sortorder();
+            $newcategory = coursecat::create($category);
 
             $createdcategories[] = array('id' => $newcategory->id, 'name' => $newcategory->name);
         }
@@ -1764,7 +1736,7 @@ class core_course_external extends external_api {
      */
     public static function update_categories($categories) {
         global $CFG, $DB;
-        require_once($CFG->dirroot . "/course/lib.php");
+        require_once($CFG->libdir . "/coursecatlib.php");
 
         // Validate parameters.
         $params = self::validate_parameters(self::update_categories_parameters(), array('categories' => $categories));
@@ -1772,49 +1744,16 @@ class core_course_external extends external_api {
         $transaction = $DB->start_delegated_transaction();
 
         foreach ($params['categories'] as $cat) {
-            if (!$category = $DB->get_record('course_categories', array('id' => $cat['id']))) {
-                throw new moodle_exception('unknowcategory');
-            }
+            $category = coursecat::get($cat['id']);
 
             $categorycontext = context_coursecat::instance($cat['id']);
             self::validate_context($categorycontext);
             require_capability('moodle/category:manage', $categorycontext);
 
-            if (!empty($cat['name'])) {
-                if (textlib::strlen($cat['name'])>255) {
-                     throw new moodle_exception('categorytoolong');
-                }
-                $category->name = $cat['name'];
-            }
-            if (!empty($cat['idnumber'])) {
-                if (textlib::strlen($cat['idnumber'])>100) {
-                    throw new moodle_exception('idnumbertoolong');
-                }
-                $category->idnumber = $cat['idnumber'];
-            }
-            if (!empty($cat['description'])) {
-                $category->description = $cat['description'];
-                $category->descriptionformat = external_validate_format($cat['descriptionformat']);
-            }
-            if (!empty($cat['theme'])) {
-                $category->theme = $cat['theme'];
-            }
-            if (!empty($cat['parent']) && ($category->parent != $cat['parent'])) {
-                // First check if parent exists.
-                if (!$parent_cat = $DB->get_record('course_categories', array('id' => $cat['parent']))) {
-                    throw new moodle_exception('unknowcategory');
-                }
-                // Then check if we have capability.
-                self::validate_context(get_category_or_system_context((int)$cat['parent']));
-                require_capability('moodle/category:manage', get_category_or_system_context((int)$cat['parent']));
-                // Finally move the category.
-                move_category($category, $parent_cat);
-                $category->parent = $cat['parent'];
-                // Get updated path by move_category().
-                $category->path = $DB->get_field('course_categories', 'path',
-                        array('id' => $category->id));
-            }
-            $DB->update_record('course_categories', $category);
+            // this will throw an exception if descriptionformat is not valid
+            external_validate_format($cat['descriptionformat']);
+
+            $category->update($cat);
         }
 
         $transaction->allow_commit();
@@ -1864,6 +1803,7 @@ class core_course_external extends external_api {
     public static function delete_categories($categories) {
         global $CFG, $DB;
         require_once($CFG->dirroot . "/course/lib.php");
+        require_once($CFG->libdir . "/coursecatlib.php");
 
         // Validate parameters.
         $params = self::validate_parameters(self::delete_categories_parameters(), array('categories' => $categories));
@@ -1871,9 +1811,7 @@ class core_course_external extends external_api {
         $transaction = $DB->start_delegated_transaction();
 
         foreach ($params['categories'] as $category) {
-            if (!$deletecat = $DB->get_record('course_categories', array('id' => $category['id']))) {
-                throw new moodle_exception('unknowcategory');
-            }
+            $deletecat = coursecat::get($category['id'], MUST_EXIST);
             $context = context_coursecat::instance($deletecat->id);
             require_capability('moodle/category:manage', $context);
             self::validate_context($context);
@@ -1881,29 +1819,32 @@ class core_course_external extends external_api {
 
             if ($category['recursive']) {
                 // If recursive was specified, then we recursively delete the category's contents.
-                category_delete_full($deletecat, false);
+                if ($deletecat->can_delete_full()) {
+                    $deletecat->delete_full(false);
+                } else {
+                    throw new moodle_exception('youcannotdeletecategory', '', '', $deletecat->get_formatted_name());
+                }
             } else {
                 // In this situation, we don't delete the category's contents, we either move it to newparent or parent.
                 // If the parent is the root, moving is not supported (because a course must always be inside a category).
                 // We must move to an existing category.
                 if (!empty($category['newparent'])) {
-                    if (!$DB->record_exists('course_categories', array('id' => $category['newparent']))) {
-                        throw new moodle_exception('unknowcategory');
-                    }
-                    $newparent = $category['newparent'];
+                    $newparentcat = coursecat::get($category['newparent']);
                 } else {
-                    $newparent = $deletecat->parent;
+                    $newparentcat = coursecat::get($deletecat->parent);
                 }
 
                 // This operation is not allowed. We must move contents to an existing category.
-                if ($newparent == 0) {
+                if (!$newparentcat->id) {
                     throw new moodle_exception('movecatcontentstoroot');
                 }
 
-                $parentcontext = get_category_or_system_context($newparent);
-                require_capability('moodle/category:manage', $parentcontext);
-                self::validate_context($parentcontext);
-                category_delete_move($deletecat, $newparent, false);
+                self::validate_context(context_coursecat::instance($newparentcat->id));
+                if ($deletecat->can_move_content_to($newparentcat->id)) {
+                    $deletecat->delete_move($newparentcat->id, false);
+                } else {
+                    throw new moodle_exception('youcannotdeletecategory', '', '', $deletecat->get_formatted_name());
+                }
             }
         }
 
index d9a7edc..6529716 100644 (file)
@@ -562,6 +562,39 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
         return $o;
     }
 
+    /**
+     * Generate the html for the 'Jump to' menu on a single section page.
+     *
+     * @param stdClass $course The course entry from DB
+     * @param array $sections The course_sections entries from the DB
+     * @param $displaysection the current displayed section number.
+     *
+     * @return string HTML to output.
+     */
+    protected function section_nav_selection($course, $sections, $displaysection) {
+        global $CFG;
+        $o = '';
+        $sectionmenu = array();
+        $sectionmenu[course_get_url($course)->out(false)] = get_string('maincoursepage');
+        $modinfo = get_fast_modinfo($course);
+        $section = 1;
+        while ($section <= $course->numsections) {
+            $thissection = $modinfo->get_section_info($section);
+            $showsection = $thissection->uservisible or !$course->hiddensections;
+            if (($showsection) && ($section != $displaysection) && ($url = course_get_url($course, $section))) {
+                $sectionmenu[$url->out(false)] = get_section_name($course, $section);
+            }
+            $section++;
+        }
+
+        $select = new url_select($sectionmenu, '', array('' => get_string('jumpto')));
+        $select->class = 'jumpmenu';
+        $select->formid = 'sectionmenu';
+        $o .= $this->output->render($select);
+
+        return $o;
+    }
+
     /**
      * Output the html for a single section page .
      *
@@ -642,16 +675,16 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
         echo $this->end_section_list();
 
         // Display section bottom navigation.
-        $courselink = html_writer::link(course_get_url($course), get_string('returntomaincoursepage'));
         $sectionbottomnav = '';
         $sectionbottomnav .= html_writer::start_tag('div', array('class' => 'section-navigation mdl-bottom'));
         $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['previous'], array('class' => 'mdl-left'));
         $sectionbottomnav .= html_writer::tag('span', $sectionnavlinks['next'], array('class' => 'mdl-right'));
-        $sectionbottomnav .= html_writer::tag('div', $courselink, array('class'&