Merge branch 'master_MDL-34544' of git://github.com/danmarsden/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 11 Sep 2012 19:33:06 +0000 (21:33 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 11 Sep 2012 19:33:06 +0000 (21:33 +0200)
503 files changed:
admin/environment.xml
admin/settings/courses.php
backup/moodle2/backup_custom_fields.php
backup/moodle2/restore_qtype_plugin.class.php
backup/upgrade.txt [new file with mode: 0644]
backup/util/dbops/backup_plan_dbops.class.php
backup/util/dbops/restore_dbops.class.php
backup/util/helper/backup_cron_helper.class.php
backup/util/plan/backup_structure_step.class.php
backup/util/plan/restore_structure_step.class.php
backup/util/structure/backup_nested_element.class.php
backup/util/ui/backup_ui_stage.class.php
backup/util/ui/restore_ui_stage.class.php
blocks/community/yui/comments/comments.js
blocks/completionstatus/block_completionstatus.php
blocks/completionstatus/details.php
blocks/completionstatus/lang/en/block_completionstatus.php
blog/external_blogs.php
blog/locallib.php
course/category.php
course/format/weeks/format.js
course/lib.php
course/pending.php
course/request_form.php
course/tests/courselib_test.php
course/tests/courserequest_test.php [new file with mode: 0644]
course/tests/externallib_test.php
enrol/cohort/locallib.php
enrol/manual/yui/quickenrolment/quickenrolment.js
enrol/paypal/ipn.php
filter/mediaplugin/tests/filter_test.php
grade/edit/tree/category_form.php
group/tests/externallib_test.php [new file with mode: 0644]
index.php
install/lang/ko/install.php
lang/en/admin.php
lang/en/backup.php
lang/en/block.php
lang/en/calendar.php
lang/en/moodle.php
lib/accesslib.php
lib/adminlib.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-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-ar.inc.php [deleted file]
lib/adodb/lang/adodb-bg.inc.php [deleted file]
lib/adodb/lang/adodb-bgutf8.inc.php [deleted file]
lib/adodb/lang/adodb-ca.inc.php [deleted file]
lib/adodb/lang/adodb-cn.inc.php [deleted file]
lib/adodb/lang/adodb-cz.inc.php [deleted file]
lib/adodb/lang/adodb-da.inc.php [deleted file]
lib/adodb/lang/adodb-de.inc.php [deleted file]
lib/adodb/lang/adodb-es.inc.php [deleted file]
lib/adodb/lang/adodb-esperanto.inc.php [deleted file]
lib/adodb/lang/adodb-fa.inc.php [deleted file]
lib/adodb/lang/adodb-fr.inc.php [deleted file]
lib/adodb/lang/adodb-hu.inc.php [deleted file]
lib/adodb/lang/adodb-it.inc.php [deleted file]
lib/adodb/lang/adodb-nl.inc.php [deleted file]
lib/adodb/lang/adodb-pl.inc.php [deleted file]
lib/adodb/lang/adodb-pt-br.inc.php [deleted file]
lib/adodb/lang/adodb-ro.inc.php [deleted file]
lib/adodb/lang/adodb-ru1251.inc.php [deleted file]
lib/adodb/lang/adodb-sv.inc.php [deleted file]
lib/adodb/lang/adodb-uk1251.inc.php [deleted file]
lib/adodb/lang/adodb_th.inc.php [deleted file]
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/blocklib.php
lib/conditionlib.php
lib/datalib.php
lib/db/install.xml
lib/db/upgrade.php
lib/db/upgradelib.php
lib/editor/tinymce/adminlib.php
lib/editor/tinymce/all_strings.php [moved from lib/editor/tinymce/extra/strings.php with 67% similarity]
lib/editor/tinymce/classes/plugin.php
lib/editor/tinymce/cli/update_lang_files.php [new file with mode: 0644]
lib/editor/tinymce/db/upgrade.php [new file with mode: 0644]
lib/editor/tinymce/extra/tools/download_langs.sh [deleted file]
lib/editor/tinymce/extra/tools/update_lang_files.php [deleted file]
lib/editor/tinymce/lang/en/editor_tinymce.php
lib/editor/tinymce/lib.php
lib/editor/tinymce/module.js
lib/editor/tinymce/plugins/dragmath/pix/icon.png [new file with mode: 0644]
lib/editor/tinymce/plugins/moodleemoticon/pix/icon.png [new file with mode: 0644]
lib/editor/tinymce/plugins/moodleimage/lang/en/tinymce_moodleimage.php
lib/editor/tinymce/plugins/moodleimage/pix/icon.png [new file with mode: 0644]
lib/editor/tinymce/plugins/moodleimage/tinymce/image.htm
lib/editor/tinymce/plugins/moodlemedia/lang/en/tinymce_moodlemedia.php
lib/editor/tinymce/plugins/moodlemedia/pix/icon.png [new file with mode: 0644]
lib/editor/tinymce/plugins/moodlemedia/tinymce/moodlemedia.htm
lib/editor/tinymce/plugins/moodlenolink/pix/icon.png [new file with mode: 0644]
lib/editor/tinymce/plugins/spellchecker/pix/icon.png [new file with mode: 0644]
lib/editor/tinymce/readme_moodle.txt
lib/editor/tinymce/settings.php
lib/editor/tinymce/tests/editor_test.php
lib/editor/tinymce/tiny_mce/3.6.0/jquery.tinymce.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/license.txt
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advhr/css/advhr.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advhr/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advhr/js/rule.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advhr/rule.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advimage/css/advimage.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advimage/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advimage/image.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advimage/js/image.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advlink/css/advlink.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advlink/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advlink/js/advlink.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advlink/link.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/advlist/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/autosave/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/autosave/langs/en.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/bbcode/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/contextmenu/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/directionality/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/emotions/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/emotions/emotions.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/emotions/js/emotions.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/example/dialog.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/example/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/example/js/dialog.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/example/langs/en.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/example/langs/en_dlg.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/fullpage/css/fullpage.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/fullpage/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/fullpage/fullpage.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/fullpage/js/fullpage.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/fullscreen/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/fullscreen/fullscreen.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/iespell/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/inlinepopups/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/inlinepopups/template.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/insertdatetime/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/layer/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/legacyoutput/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/media/css/media.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/media/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/media/js/embed.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/media/js/media.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/media/media.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/nonbreaking/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/noneditable/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/pagebreak/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/paste/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/paste/js/pastetext.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/paste/js/pasteword.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/paste/pastetext.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/paste/pasteword.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/preview/example.html
lib/editor/tinymce/tiny_mce/3.6.0/plugins/preview/jscripts/embed.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/preview/preview.html
lib/editor/tinymce/tiny_mce/3.6.0/plugins/print/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/save/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/searchreplace/css/searchreplace.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/searchreplace/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/searchreplace/js/searchreplace.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/searchreplace/searchreplace.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/spellchecker/css/content.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/spellchecker/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/style/css/props.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/style/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/style/js/props.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/style/props.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/cell.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/css/cell.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/css/row.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/css/table.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/js/cell.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/js/merge_cells.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/js/row.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/js/table.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/merge_cells.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/row.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/table/table.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/template/blank.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/template/css/template.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/template/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/template/js/template.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/template/template.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/css/visualblocks.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/address.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/article.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/aside.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/blockquote.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/div.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/figure.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/h1.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/h2.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/h3.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/h4.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/h5.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/h6.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/hgroup.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/p.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/pre.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualblocks/img/section.gif [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/plugins/visualchars/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/wordcount/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/abbr.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/acronym.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/attributes.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/cite.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/css/attributes.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/css/popup.css
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/del.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/ins.htm
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/abbr.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/acronym.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/attributes.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/cite.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/del.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/element_common.js
lib/editor/tinymce/tiny_mce/3.6.0/plugins/xhtmlxtras/js/ins.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/about.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/anchor.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/charmap.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/color_picker.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/editor_template_src.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/image.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/js/about.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/js/anchor.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/js/charmap.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/js/image.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/js/link.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/js/source_editor.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/link.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/shortcuts.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/default/content.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/default/dialog.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/default/ui.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/highcontrast/content.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/highcontrast/dialog.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/highcontrast/ui.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/o2k7/content.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/o2k7/dialog.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/o2k7/ui.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/o2k7/ui_black.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/skins/o2k7/ui_silver.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/advanced/source_editor.htm
lib/editor/tinymce/tiny_mce/3.6.0/themes/simple/editor_template_src.js
lib/editor/tinymce/tiny_mce/3.6.0/themes/simple/skins/default/content.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/simple/skins/default/ui.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/simple/skins/o2k7/content.css
lib/editor/tinymce/tiny_mce/3.6.0/themes/simple/skins/o2k7/ui.css
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce.js
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_dev.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_jquery.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_jquery_src.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_popup.js
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_popup_src.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_prototype.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_prototype_src.js [deleted file]
lib/editor/tinymce/tiny_mce/3.6.0/tiny_mce_src.js
lib/editor/tinymce/tiny_mce/3.6.0/utils/editable_selects.js
lib/editor/tinymce/tiny_mce/3.6.0/utils/form_utils.js
lib/editor/tinymce/tiny_mce/3.6.0/utils/mctabs.js
lib/editor/tinymce/tiny_mce/3.6.0/utils/validate.js
lib/editor/tinymce/upgrade.txt
lib/editor/tinymce/version.php
lib/flowplayer/README.txt
lib/flowplayer/README_audio.txt
lib/flowplayer/flowplayer-3.2.11.js [moved from lib/flowplayer/flowplayer-3.2.8.js with 96% similarity]
lib/flowplayer/flowplayer-3.2.11.min.js [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.14.swf [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.8.min.js [deleted file]
lib/flowplayer/flowplayer-3.2.9.swf [deleted file]
lib/flowplayer/flowplayer.audio-3.2.10.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.audio-3.2.8.swf [deleted file]
lib/flowplayer/flowplayer.controls-3.2.13.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.controls-3.2.9.swf [deleted file]
lib/formslib.php
lib/googleapi.php
lib/javascript-static.js
lib/medialib.php
lib/moodlelib.php
lib/outputrenderers.php
lib/outputrequirementslib.php
lib/phpmailer/README
lib/phpmailer/README_MOODLE.txt
lib/phpmailer/changelog.txt
lib/phpmailer/class.phpmailer.php
lib/phpmailer/class.smtp.php
lib/phpmailer/moodle_phpmailer.php
lib/phpunit/classes/util.php
lib/pluginlib.php
lib/questionlib.php
lib/sessionlib.php
lib/tcpdf/2dbarcodes.php
lib/tcpdf/CHANGELOG.TXT
lib/tcpdf/README.TXT
lib/tcpdf/barcodes.php
lib/tcpdf/composer.json [new file with mode: 0644]
lib/tcpdf/qrcode.php
lib/tcpdf/readme_moodle.txt
lib/tcpdf/tcpdf.php
lib/tcpdf/tcpdf_parser.php
lib/tests/moodlelib_test.php
lib/tests/pluginlib_test.php
lib/thirdpartylibs.xml
lib/typo3/class.t3lib_cs.php
lib/typo3/class.t3lib_div.php
lib/typo3/class.t3lib_l10n_locales.php
lib/typo3/readme_moodle.txt
lib/weblib.php
message/lib.php
message/tests/externallib_test.php [new file with mode: 0644]
mod/assign/assignmentplugin.php
mod/assign/backup/moodle2/backup_assign_stepslib.php
mod/assign/backup/moodle2/restore_assign_stepslib.php
mod/assign/db/access.php
mod/assign/db/install.xml
mod/assign/db/log.php
mod/assign/db/upgrade.php
mod/assign/extensionform.php [new file with mode: 0644]
mod/assign/feedback/comments/locallib.php
mod/assign/feedback/file/batchuploadfilesform.php [new file with mode: 0644]
mod/assign/feedback/file/importzipform.php [new file with mode: 0644]
mod/assign/feedback/file/importziplib.php [new file with mode: 0644]
mod/assign/feedback/file/lang/en/assignfeedback_file.php
mod/assign/feedback/file/locallib.php
mod/assign/feedback/file/renderable.php [new file with mode: 0644]
mod/assign/feedback/file/renderer.php [new file with mode: 0644]
mod/assign/feedback/file/uploadzipform.php [new file with mode: 0644]
mod/assign/feedback/offline/db/access.php [new file with mode: 0644]
mod/assign/feedback/offline/importgradesform.php [new file with mode: 0644]
mod/assign/feedback/offline/importgradeslib.php [new file with mode: 0644]
mod/assign/feedback/offline/lang/en/assignfeedback_offline.php [new file with mode: 0644]
mod/assign/feedback/offline/locallib.php [new file with mode: 0644]
mod/assign/feedback/offline/settings.php [new file with mode: 0644]
mod/assign/feedback/offline/uploadgradesform.php [new file with mode: 0644]
mod/assign/feedback/offline/version.php [new file with mode: 0644]
mod/assign/feedbackplugin.php
mod/assign/gradingbatchoperationsform.php
mod/assign/gradingtable.php
mod/assign/lang/en/assign.php
mod/assign/lib.php
mod/assign/locallib.php
mod/assign/mod_form.php
mod/assign/module.js
mod/assign/renderable.php
mod/assign/renderer.php
mod/assign/styles.css
mod/assign/submission/comments/locallib.php
mod/assign/submission/onlinetext/locallib.php
mod/assign/upgradelib.php
mod/assign/version.php
mod/book/backup/moodle2/restore_book_activity_task.class.php
mod/book/lib.php
mod/book/version.php
mod/book/view.php
mod/chat/chatd.php
mod/chat/gui_sockets/chatinput.php
mod/choice/backup/moodle2/backup_choice_stepslib.php
mod/data/field/checkbox/mod.html
mod/data/field/latlong/field.class.php
mod/data/field/menu/mod.html
mod/data/field/multimenu/mod.html
mod/data/field/picture/field.class.php
mod/data/field/picture/mod.html
mod/data/field/radiobutton/mod.html
mod/data/field/textarea/mod.html
mod/data/lib.php
mod/data/styles.css
mod/data/templates.php
mod/folder/renderer.php
mod/lesson/format.php
mod/lesson/pagetypes/multichoice.php
mod/page/lib.php
mod/quiz/accessrule/safebrowser/rule.php
mod/quiz/accessrule/securewindow/rule.php
mod/quiz/lib.php
mod/quiz/styles.css
mod/scorm/locallib.php
mod/scorm/player.php
mod/scorm/styles.css
mod/scorm/view.js
mod/scorm/view.php
mod/workshop/form/comments/backup/moodle1/lib.php
mod/workshop/form/numerrors/backup/moodle1/lib.php
mod/workshop/form/rubric/backup/moodle1/lib.php
notes/tests/externallib_test.php [new file with mode: 0644]
question/category_class.php
question/format.php
question/format/aiken/format.php
question/format/blackboard_six/lang/en/qformat_blackboard_six.php
question/format/examview/format.php
question/format/gift/examples.txt
question/format/gift/format.php
question/format/learnwise/format.php
question/format/missingword/format.php
question/format/webct/format.php
question/format/xhtml/format.php
question/format/xml/format.php
question/type/calculatedmulti/styles.css
question/type/match/styles.css
question/type/multianswer/styles.css
question/type/multichoice/styles.css
report/backups/index.php
report/stats/lib.php
report/stats/settings.php
repository/flickr/lib.php
repository/flickr_public/lib.php
repository/googledocs/lib.php
repository/lib.php
repository/manage_instances.php
theme/afterburner/config.php
theme/afterburner/style/afterburner_styles.css
theme/anomaly/style/general.css
theme/base/config.php
theme/base/style/admin.css
theme/base/style/core.css
theme/base/style/course.css
theme/canvas/config.php
theme/formal_white/layout/frontpage.php
theme/formal_white/layout/general.php
theme/formal_white/layout/report.php
theme/formal_white/settings.php
theme/mymobile/renderers.php
theme/overlay/layout/general.php
theme/upgrade.txt
theme/yui_combo.php
user/editadvanced_form.php
user/profile.php
user/selector/module.js
version.php
webservice/externallib.php
webservice/tests/externallib_test.php [new file with mode: 0644]

index 004cab0..584a9b0 100644 (file)
         </FEEDBACK>
       </PHP_SETTING>
     </PHP_SETTINGS>
-</MOODLE>
+  </MOODLE>
+  <MOODLE version="2.4" 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.2" level="required">
+    </PHP>
+    <PCREUNICODE level="optional">
+      <FEEDBACK>
+        <ON_CHECK message="pcreunicodewarning" />
+      </FEEDBACK>
+    </PCREUNICODE>
+    <PHP_EXTENSIONS>
+      <PHP_EXTENSION name="iconv" level="required">
+        <FEEDBACK>
+          <ON_CHECK 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_CHECK 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="optional">
+        <FEEDBACK>
+          <ON_CHECK message="gdrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="simplexml" level="required">
+        <FEEDBACK>
+          <ON_CHECK message="simplexmlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="spl" level="required">
+        <FEEDBACK>
+          <ON_CHECK 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>
 </COMPATIBILITY_MATRIX>
index f07107c..04f7975 100644 (file)
@@ -85,6 +85,7 @@ if ($hassiteconfig
     $temp = new admin_settingpage('courserequest', new lang_string('courserequest'));
     $temp->add(new admin_setting_configcheckbox('enablecourserequests', new lang_string('enablecourserequests', 'admin'), new lang_string('configenablecourserequests', 'admin'), 0));
     $temp->add(new admin_settings_coursecat_select('defaultrequestcategory', new lang_string('defaultrequestcategory', 'admin'), new lang_string('configdefaultrequestcategory', 'admin'), 1));
+    $temp->add(new admin_setting_configcheckbox('requestcategoryselection', new lang_string('requestcategoryselection', 'admin'), new lang_string('configrequestcategoryselection', 'admin'), 0));
     $temp->add(new admin_setting_users_with_capability('courserequestnotify', new lang_string('courserequestnotify', 'admin'), new lang_string('configcourserequestnotify2', 'admin'), array(), 'moodle/site:approvecourse'));
     $ADMIN->add('courses', $temp);
 
index e0ceb33..12929de 100644 (file)
@@ -96,14 +96,19 @@ class file_nested_element extends backup_nested_element {
         if (is_null($this->backupid)) {
             $this->backupid = $processor->get_var(backup::VAR_BACKUPID);
         }
-        parent::process($processor);
+        return parent::process($processor);
     }
 
     public function fill_values($values) {
         // Fill values
         parent::fill_values($values);
         // Do our own tasks (copy file from moodle to backup)
-        backup_file_manager::copy_file_moodle2backup($this->backupid, $values);
+        try {
+            backup_file_manager::copy_file_moodle2backup($this->backupid, $values);
+        } catch (file_exception $e) {
+            $this->add_result(array('missing_files_in_pool' => true));
+            $this->add_log('missing file in pool: ' . $e->debuginfo, backup::LOG_WARNING);
+        }
     }
 }
 
index 40b06ac..99365ba 100644 (file)
@@ -154,6 +154,22 @@ abstract class restore_qtype_plugin extends restore_plugin {
                        AND ' . $DB->sql_compare_text('answer', 255) . ' = ' . $DB->sql_compare_text('?', 255);
             $params = array($newquestionid, $data->answertext);
             $newitemid = $DB->get_field_sql($sql, $params);
+
+            // Not able to find the answer, let's try cleaning the answertext
+            // of all the question answers in DB as slower fallback. MDL-30018.
+            if (!$newitemid) {
+                $params = array('question' => $newquestionid);
+                $answers = $DB->get_records('question_answers', $params, '', 'id, answer');
+                foreach ($answers as $answer) {
+                    // Clean in the same way than {@link xml_writer::xml_safe_utf8()}.
+                    $clean = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is','', $answer->answer); // Clean CTRL chars.
+                    $clean = preg_replace("/\r\n|\r/", "\n", $clean); // Normalize line ending.
+                    if ($clean === $data->answertext) {
+                        $newitemid = $data->id;
+                    }
+                }
+            }
+
             // If we haven't found the newitemid, something has gone really wrong, question in DB
             // is missing answers, exception
             if (!$newitemid) {
diff --git a/backup/upgrade.txt b/backup/upgrade.txt
new file mode 100644 (file)
index 0000000..cb02095
--- /dev/null
@@ -0,0 +1,17 @@
+This files describes API changes in /backup/*,
+information provided here is intended especially for developers.
+
+=== 2.4 ===
+
+* Since 2.3.1+ the backup file name schema has changed. The ID of the course will always be part of
+    the filename regardless of the setting 'backup_shortname'. See MDL-33812.
+
+=== 2.3 ===
+
+* Since 2.3.1+ the backup file name schema has changed. The ID of the course will always be part of
+    the filename regardless of the setting 'backup_shortname'. See MDL-33812.
+
+=== 2.2 ===
+
+* Since 2.2.4+ the backup file name schema has changed. The ID of the course will always be part of
+    the filename regardless of the setting 'backup_shortname'. See MDL-33812.
\ No newline at end of file
index e169a8a..2e2faae 100644 (file)
@@ -197,19 +197,19 @@ abstract class backup_plan_dbops extends backup_dbops {
     * @param int $courseid/$sectionid/$cmid
     * @param bool $users Should be true is users were included in the backup
     * @param bool $anonymised Should be true is user information was anonymized.
-    * @param bool $useidasname true to use id, false to use strings (default)
+    * @param bool $useidonly only use the ID in the file name
     * @return string The filename to use
     */
-    public static function get_default_backup_filename($format, $type, $id, $users, $anonymised, $useidasname = false) {
+    public static function get_default_backup_filename($format, $type, $id, $users, $anonymised, $useidonly = false) {
         global $DB;
 
         // Calculate backup word
         $backupword = str_replace(' ', '_', textlib::strtolower(get_string('backupfilename')));
         $backupword = trim(clean_filename($backupword), '_');
 
+        // Not $useidonly, lets fetch the name
         $shortname = '';
-        // Not $useidasname, lets calculate it, else $id will be used
-        if (!$useidasname) {
+        if (!$useidonly) {
             // Calculate proper name element (based on type)
             switch ($type) {
                 case backup::TYPE_1COURSE:
@@ -231,7 +231,11 @@ abstract class backup_plan_dbops extends backup_dbops {
             $shortname = textlib::strtolower(trim(clean_filename($shortname), '_'));
         }
 
-        $name = empty($shortname) ? $id : $shortname;
+        // The name will always contain the ID, but we append the course short name if requested.
+        $name = $id;
+        if (!$useidonly && $shortname != '') {
+            $name .= '-' . $shortname;
+        }
 
         // Calculate date
         $backupdateformat = str_replace(' ', '_', get_string('backupnameformat', 'langconfig'));
index 3bd86e3..4b6c63c 100644 (file)
@@ -818,10 +818,13 @@ abstract class restore_dbops {
      * @param int|null $olditemid
      * @param int|null $forcenewcontextid explicit value for the new contextid (skip mapping)
      * @param bool $skipparentitemidctxmatch
+     * @return array of result object
      */
     public static function send_files_to_pool($basepath, $restoreid, $component, $filearea, $oldcontextid, $dfltuserid, $itemname = null, $olditemid = null, $forcenewcontextid = null, $skipparentitemidctxmatch = false) {
         global $DB;
 
+        $results = array();
+
         if ($forcenewcontextid) {
             // Some components can have "forced" new contexts (example: questions can end belonging to non-standard context mappings,
             // with questions originally at system/coursecat context in source being restored to course context in target). So we need
@@ -901,8 +904,14 @@ abstract class restore_dbops {
                 // this is a regular file, it must be present in the backup pool
                 $backuppath = $basepath . backup_file_manager::get_backup_content_file_location($file->contenthash);
 
+                // The file is not found in the backup.
                 if (!file_exists($backuppath)) {
-                    throw new restore_dbops_exception('file_not_found_in_pool', $file);
+                    $result = new stdClass();
+                    $result->code = 'file_missing_in_backup';
+                    $result->message = sprintf('missing file %s%s in backup', $file->filepath, $file->filename);
+                    $result->level = backup::LOG_WARNING;
+                    $results[] = $result;
+                    continue;
                 }
 
                 // create the file in the filepool if it does not exist yet
@@ -959,6 +968,7 @@ abstract class restore_dbops {
             }
         }
         $rs->close();
+        return $results;
     }
 
     /**
index ea8fda0..e3ada4f 100644 (file)
@@ -46,6 +46,8 @@ abstract class backup_cron_automated_helper {
     const BACKUP_STATUS_UNFINISHED = 2;
     /** Course automated backup was skipped */
     const BACKUP_STATUS_SKIPPED = 3;
+    /** Course automated backup had warnings */
+    const BACKUP_STATUS_WARNING = 4;
 
     /** Run if required by the schedule set in config. Default. **/
     const RUN_ON_SCHEDULE = 0;
@@ -139,7 +141,7 @@ abstract class backup_cron_automated_helper {
                     $params = array('courseid' => $course->id, 'time' => $now-31*24*60*60, 'action' => '%view%');
                     $logexists = $DB->record_exists_select('log', $sqlwhere, $params);
                     if (!$logexists) {
-                        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
+                        $backupcourse->laststatus = self::BACKUP_STATUS_SKIPPED;
                         $backupcourse->nextstarttime = $nextstarttime;
                         $DB->update_record('backup_courses', $backupcourse);
                         mtrace('Skipping unchanged course '.$course->fullname);
@@ -160,7 +162,7 @@ abstract class backup_cron_automated_helper {
                         $starttime = time();
 
                         $backupcourse->laststarttime = time();
-                        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_UNFINISHED;
+                        $backupcourse->laststatus = self::BACKUP_STATUS_UNFINISHED;
                         $DB->update_record('backup_courses', $backupcourse);
 
                         $backupcourse->laststatus = backup_cron_automated_helper::launch_automated_backup($course, $backupcourse->laststarttime, $admin->id);
@@ -169,7 +171,7 @@ abstract class backup_cron_automated_helper {
 
                         $DB->update_record('backup_courses', $backupcourse);
 
-                        if ($backupcourse->laststatus) {
+                        if ($backupcourse->laststatus === self::BACKUP_STATUS_OK) {
                             // Clean up any excess course backups now that we have
                             // taken a successful backup.
                             $removedcount = backup_cron_automated_helper::remove_excess_backups($course);
@@ -188,17 +190,18 @@ abstract class backup_cron_automated_helper {
             $message = "";
 
             $count = backup_cron_automated_helper::get_backup_status_array();
-            $haserrors = ($count[backup_cron_automated_helper::BACKUP_STATUS_ERROR] != 0 || $count[backup_cron_automated_helper::BACKUP_STATUS_UNFINISHED] != 0);
+            $haserrors = ($count[self::BACKUP_STATUS_ERROR] != 0 || $count[self::BACKUP_STATUS_UNFINISHED] != 0);
 
             //Build the message text
             //Summary
             $message .= get_string('summary')."\n";
             $message .= "==================================================\n";
             $message .= "  ".get_string('courses').": ".array_sum($count)."\n";
-            $message .= "  ".get_string('ok').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_OK]."\n";
-            $message .= "  ".get_string('skipped').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_SKIPPED]."\n";
-            $message .= "  ".get_string('error').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_ERROR]."\n";
-            $message .= "  ".get_string('unfinished').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_UNFINISHED]."\n\n";
+            $message .= "  ".get_string('ok').": ".$count[self::BACKUP_STATUS_OK]."\n";
+            $message .= "  ".get_string('skipped').": ".$count[self::BACKUP_STATUS_SKIPPED]."\n";
+            $message .= "  ".get_string('error').": ".$count[self::BACKUP_STATUS_ERROR]."\n";
+            $message .= "  ".get_string('unfinished').": ".$count[self::BACKUP_STATUS_UNFINISHED]."\n";
+            $message .= "  ".get_string('warning').": ".$count[self::BACKUP_STATUS_WARNING]."\n\n";
 
             //Reference
             if ($haserrors) {
@@ -261,6 +264,7 @@ abstract class backup_cron_automated_helper {
             self::BACKUP_STATUS_OK => 0,
             self::BACKUP_STATUS_UNFINISHED => 0,
             self::BACKUP_STATUS_SKIPPED => 0,
+            self::BACKUP_STATUS_WARNING => 0
         );
 
         $statuses = $DB->get_records_sql('SELECT DISTINCT bc.laststatus, COUNT(bc.courseid) AS statuscount FROM {backup_courses} bc GROUP BY bc.laststatus');
@@ -334,7 +338,7 @@ abstract class backup_cron_automated_helper {
      */
     public static function launch_automated_backup($course, $starttime, $userid) {
 
-        $outcome = true;
+        $outcome = self::BACKUP_STATUS_OK;
         $config = get_config('backup');
         $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_AUTOMATED, $userid);
 
@@ -369,6 +373,7 @@ abstract class backup_cron_automated_helper {
 
             $bc->execute_plan();
             $results = $bc->get_results();
+            $outcome = self::outcome_from_results($results);
             $file = $results['backup_destination']; // may be empty if file already moved to target location
             $dir = $config->backup_auto_destination;
             $storage = (int)$config->backup_auto_storage;
@@ -377,8 +382,10 @@ abstract class backup_cron_automated_helper {
             }
             if ($file && !empty($dir) && $storage !== 0) {
                 $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised, !$config->backup_shortname);
-                $outcome = $file->copy_content_to($dir.'/'.$filename);
-                if ($outcome && $storage === 1) {
+                if (!$file->copy_content_to($dir.'/'.$filename)) {
+                    $outcome = self::BACKUP_STATUS_ERROR;
+                }
+                if ($outcome != self::BACKUP_STATUS_ERROR && $storage === 1) {
                     $file->delete();
                 }
             }
@@ -387,7 +394,7 @@ abstract class backup_cron_automated_helper {
             $bc->log('backup_auto_failed_on_course', backup::LOG_ERROR, $course->shortname); // Log error header.
             $bc->log('Exception: ' . $e->errorcode, backup::LOG_ERROR, $e->a, 1); // Log original exception problem.
             $bc->log('Debug: ' . $e->debuginfo, backup::LOG_DEBUG, null, 1); // Log original debug information.
-            $outcome = false;
+            $outcome = self::BACKUP_STATUS_ERROR;
         }
 
         $bc->destroy();
@@ -396,6 +403,30 @@ abstract class backup_cron_automated_helper {
         return $outcome;
     }
 
+    /**
+     * Returns the backup outcome by analysing its results.
+     *
+     * @param array $results returned by a backup
+     * @return int {@link self::BACKUP_STATUS_OK} and other constants
+     */
+    public static function outcome_from_results($results) {
+        $outcome = self::BACKUP_STATUS_OK;
+        foreach ($results as $code => $value) {
+            // Each possible error and warning code has to be specified in this switch
+            // which basically analyses the results to return the correct backup status.
+            switch ($code) {
+                case 'missing_files_in_pool':
+                    $outcome = self::BACKUP_STATUS_WARNING;
+                    break;
+            }
+            // If we found the highest error level, we exit the loop.
+            if ($outcome == self::BACKUP_STATUS_ERROR) {
+                break;
+            }
+        }
+        return $outcome;
+    }
+
     /**
      * Removes deleted courses fromn the backup_courses table so that we don't
      * waste time backing them up.
@@ -530,18 +561,7 @@ abstract class backup_cron_automated_helper {
         if (!empty($dir) && ($storage == 1 || $storage == 2)) {
             // Calculate backup filename regex, ignoring the date/time/info parts that can be
             // variable, depending of languages, formats and automated backup settings
-
-
-            // MDL-33531: use different filenames depending on backup_shortname option
-            if ( !empty($config->backup_shortname) ) {
-                $context = get_context_instance(CONTEXT_COURSE, $course->id);
-                $courseref = format_string($course->shortname, true, array('context' => $context));
-                $courseref = str_replace(' ', '_', $courseref);
-                $courseref = textlib::strtolower(trim(clean_filename($courseref), '_'));
-            } else {
-                $courseref = $course->id;
-            }
-            $filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' .$courseref . '-';
+            $filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' .$course->id . '-';
             $regex = '#^'.preg_quote($filename, '#').'.*\.mbz$#';
 
             // Store all the matching files into fullpath => timemodified array
index f62fee9..964dd3f 100644 (file)
@@ -94,11 +94,22 @@ abstract class backup_structure_step extends backup_step {
         // Process structure definition
         $structure->process($pr);
 
+        // Get the results from the nested elements
+        $results = $structure->get_results();
+
+        // Get the log messages to append to the log
+        $logs = $structure->get_logs();
+        foreach ($logs as $log) {
+            $this->log($log->message, $log->level, $log->a, $log->depth, $log->display);
+        }
+
         // Close everything
         $xw->stop();
 
         // Destroy the structure. It helps PHP 5.2 memory a lot!
         $structure->destroy();
+
+        return $results;
     }
 
     /**
index 42491cf..7a1cfa2 100644 (file)
@@ -218,8 +218,14 @@ abstract class restore_structure_step extends restore_step {
      */
     public function add_related_files($component, $filearea, $mappingitemname, $filesctxid = null, $olditemid = null) {
         $filesctxid = is_null($filesctxid) ? $this->task->get_old_contextid() : $filesctxid;
-        restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component,
-                                          $filearea, $filesctxid, $this->task->get_userid(), $mappingitemname, $olditemid);
+        $results = restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component,
+                $filearea, $filesctxid, $this->task->get_userid(), $mappingitemname, $olditemid);
+        $resultstoadd = array();
+        foreach ($results as $result) {
+            $this->log($result->message, $result->level);
+            $resultstoadd[$result->code] = true;
+        }
+        $this->task->add_result($resultstoadd);
     }
 
     /**
index 9a47901..8557ec8 100644 (file)
@@ -37,6 +37,8 @@ class backup_nested_element extends base_nested_element implements processable {
     protected $aliases;   // Define DB->final element aliases
     protected $fileannotations;   // array of file areas to be searched by file annotations
     protected $counter;   // Number of instances of this element that have been processed
+    protected $results;  // Logs the results we encounter during the process.
+    protected $logs;     // Some log messages that could be retrieved later.
 
     /**
      * Constructor - instantiates one backup_nested_element, specifying its basic info.
@@ -55,8 +57,16 @@ class backup_nested_element extends base_nested_element implements processable {
         $this->aliases   = array();
         $this->fileannotations = array();
         $this->counter   = 0;
+        $this->results  = array();
+        $this->logs     = array();
     }
 
+    /**
+     * Process the nested element
+     *
+     * @param object $processor the processor
+     * @return void
+     */
     public function process($processor) {
         if (!$processor instanceof base_processor) { // No correct processor, throw exception
             throw new base_element_struct_exception('incorrect_processor');
@@ -113,6 +123,69 @@ class backup_nested_element extends base_nested_element implements processable {
         $iterator->close();
     }
 
+    /**
+     * Saves a log message to an array
+     *
+     * @see backup_helper::log()
+     * @param string $message to add to the logs
+     * @param int $level level of importance {@link backup::LOG_DEBUG} and other constants
+     * @param mixed $a to be included in $message
+     * @param int $depth of the message
+     * @param display $bool supporting translation via get_string() if true
+     * @return void
+     */
+    protected function add_log($message, $level, $a = null, $depth = null, $display = false) {
+        // Adding the result to the oldest parent.
+        if ($this->get_parent()) {
+            $parent = $this->get_grandparent();
+            $parent->add_log($message, $level, $a, $depth, $display);
+        } else {
+            $log = new stdClass();
+            $log->message = $message;
+            $log->level = $level;
+            $log->a = $a;
+            $log->depth = $depth;
+            $log->display = $display;
+            $this->logs[] = $log;
+        }
+    }
+
+    /**
+     * Saves the results to an array
+     *
+     * @param array $result associative array
+     * @return void
+     */
+    protected function add_result($result) {
+        if (is_array($result)) {
+            // Adding the result to the oldest parent.
+            if ($this->get_parent()) {
+                $parent = $this->get_grandparent();
+                $parent->add_result($result);
+            } else {
+                $this->results = array_merge($this->results, $result);
+            }
+        }
+    }
+
+    /**
+     * Returns the logs
+     *
+     * @return array of log objects
+     */
+    public function get_logs() {
+        return $this->logs;
+    }
+
+    /**
+     * Returns the results
+     *
+     * @return associative array of results
+     */
+    public function get_results() {
+        return $this->results;
+    }
+
     public function set_source_array($arr) {
         // TODO: Only elements having final elements can set source
         $this->var_array = $arr;
index 472294a..4065212 100644 (file)
@@ -487,6 +487,9 @@ class backup_ui_stage_complete extends backup_ui_stage_final {
         if (!empty($this->results['include_file_references_to_external_content'])) {
             $output .= $renderer->notification(get_string('filereferencesincluded', 'backup'), 'notifyproblem');
         }
+        if (!empty($this->results['missing_files_in_pool'])) {
+            $output .= $renderer->notification(get_string('missingfilesinpool', 'backup'), 'notifyproblem');
+        }
         $output .= $renderer->notification(get_string('executionsuccess', 'backup'), 'notifysuccess');
         $output .= $renderer->continue_button($restorerul);
         $output .= $renderer->box_end();
index 6c28254..a7464bf 100644 (file)
@@ -772,6 +772,9 @@ class restore_ui_stage_complete extends restore_ui_stage_process {
             $html .= $renderer->box_end();
         }
         $html .= $renderer->box_start();
+        if (array_key_exists('file_missing_in_backup', $this->results)) {
+            $html .= $renderer->notification(get_string('restorefileweremissing', 'backup'), 'notifyproblem');
+        }
         $html .= $renderer->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess');
         $html .= $renderer->continue_button(new moodle_url('/course/view.php', array(
             'id' => $this->get_ui()->get_controller()->get_courseid())), 'get');
index 817e3ac..c32b75e 100644 (file)
@@ -23,8 +23,7 @@ YUI.add('moodle-block_community-comments', function(Y) {
                     bodyContent:Y.one('#commentoverlay-'+commentid).get('innerHTML'),
                     visible: false, //by default it is not displayed
                     lightbox : false,
-                    zIndex:100,
-                    height: '350px'
+                    zIndex:100
                 });
 
                 this.overlays[commentid].get('contentBox').one('.commenttitle').remove();
index 2b598ce..b339e9a 100644 (file)
  *
  * @package    block
  * @subpackage completion
- * @copyright  2009 Catalyst IT Ltd
+ * @copyright  2009-2012 Catalyst IT Ltd
  * @author     Aaron Barnes <aaronb@catalyst.net.nz>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
-
-require_once($CFG->libdir.'/completionlib.php');
+require_once("{$CFG->libdir}/completionlib.php");
 
 /**
  * Course completion status
@@ -36,25 +35,28 @@ require_once($CFG->libdir.'/completionlib.php');
 class block_completionstatus extends block_base {
 
     public function init() {
-        $this->title   = get_string('pluginname', 'block_completionstatus');
+        $this->title = get_string('pluginname', 'block_completionstatus');
     }
 
     public function get_content() {
-        global $USER, $CFG, $DB, $COURSE;
+        global $USER;
 
         // If content is cached
         if ($this->content !== NULL) {
             return $this->content;
         }
 
+        $course  = $this->page->course;
+        $context = context_course::instance($course->id);
+
         // Create empty content
-        $this->content = new stdClass;
+        $this->content = new stdClass();
 
         // Can edit settings?
-        $can_edit = has_capability('moodle/course:update', context_course::instance($this->page->course->id));
+        $can_edit = has_capability('moodle/course:update', $context);
 
         // Get course completion data
-        $info = new completion_info($this->page->course);
+        $info = new completion_info($course);
 
         // Don't display if completion isn't enabled!
         if (!completion_info::is_enabled_for_site()) {
@@ -84,9 +86,9 @@ class block_completionstatus extends block_base {
         // Check this user is enroled
         if (!$info->is_tracked_user($USER->id)) {
             // If not enrolled, but are can view the report:
-            if (has_capability('report/completion:view', context_course::instance($COURSE->id))) {
-                $this->content->text = '<a href="'.$CFG->wwwroot.'/report/completion/index.php?course='.$COURSE->id.
-                                       '">'.get_string('viewcoursereport', 'completion').'</a>';
+            if (has_capability('report/completion:view', $context)) {
+                $report = new moodle_url('/report/completion/index.php', array('course' => $course->id));
+                $this->content->text = '<a href="'.$report->out().'">'.get_string('viewcoursereport', 'completion').'</a>';
                 return $this->content;
             }
 
@@ -187,7 +189,7 @@ class block_completionstatus extends block_base {
         // Load course completion
         $params = array(
             'userid' => $USER->id,
-            'course' => $COURSE->id
+            'course' => $course->id
         );
         $ccompletion = new completion_completion($params);
 
@@ -221,7 +223,8 @@ class block_completionstatus extends block_base {
         $this->content->text .= $shtml.'</tbody></table>';
 
         // Display link to detailed view
-        $this->content->footer = '<br><a href="'.$CFG->wwwroot.'/blocks/completionstatus/details.php?course='.$COURSE->id.'">'.get_string('moredetails', 'completion').'</a>';
+        $details = new moodle_url('/blocks/completionstatus/details.php', array('course' => $course->id));
+        $this->content->footer = '<br><a href="'.$details->out().'">'.get_string('moredetails', 'completion').'</a>';
 
         return $this->content;
     }
index a71da02..bb1b051 100644 (file)
  *
  * @package    block
  * @subpackage completion
- * @copyright  2009 Catalyst IT Ltd
+ * @copyright  2009-2012 Catalyst IT Ltd
  * @author     Aaron Barnes <aaronb@catalyst.net.nz>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-require_once('../../config.php');
-require_once($CFG->libdir.'/completionlib.php');
-
-
-// TODO:  Make this page Moodle 2.0 compliant
+require_once(dirname(__FILE__).'/../../config.php');
+require_once("{$CFG->libdir}/completionlib.php");
 
 
 ///
 /// Load data
 ///
 $id = required_param('course', PARAM_INT);
-// User id
 $userid = optional_param('user', 0, PARAM_INT);
 
 // Load course
-$course = $DB->get_record('course', array('id' => $id));
+$course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST);
 
 // Load user
 if ($userid) {
@@ -76,21 +72,13 @@ if (!$can_view) {
 // Load completion data
 $info = new completion_info($course);
 
-$returnurl = "{$CFG->wwwroot}/course/view.php?id={$id}";
+$returnurl = new moodle_url('/course/view.php', array('id' => $id));
 
 // Don't display if completion isn't enabled!
 if (!$info->is_enabled()) {
     print_error('completionnotenabled', 'completion', $returnurl);
 }
 
-// Load criteria to display
-$completions = $info->get_completions($user->id);
-
-// Check if this course has any criteria
-if (empty($completions)) {
-    print_error('nocriteriaset', 'completion', $returnurl);
-}
-
 // Check this user is enroled
 if (!$info->is_tracked_user($user->id)) {
     if ($USER->id == $user->id) {
@@ -104,6 +92,7 @@ if (!$info->is_tracked_user($user->id)) {
 ///
 /// Display page
 ///
+$PAGE->set_context(context_course::instance($course->id));
 
 // Print header
 $page = get_string('completionprogressdetails', 'block_completionstatus');
@@ -111,7 +100,7 @@ $title = format_string($course->fullname) . ': ' . $page;
 
 $PAGE->navbar->add($page);
 $PAGE->set_pagelayout('standard');
-$PAGE->set_url('/blocks/completionstatus/details.php', array('course' => $course->id));
+$PAGE->set_url('/blocks/completionstatus/details.php', array('course' => $course->id, 'user' => $user->id));
 $PAGE->set_title(get_string('course') . ': ' . $course->fullname);
 $PAGE->set_heading($title);
 echo $OUTPUT->header();
@@ -135,122 +124,148 @@ $coursecomplete = $info->is_course_complete($user->id);
 // Has this user completed any criteria?
 $criteriacomplete = $info->count_course_user_data($user->id);
 
+// Load course completion
+$params = array(
+    'userid' => $user->id,
+    'course' => $course->id,
+);
+$ccompletion = new completion_completion($params);
+
 if ($coursecomplete) {
     echo get_string('complete');
-} else if (!$criteriacomplete) {
+} else if (!$criteriacomplete && !$ccompletion->timestarted) {
     echo '<i>'.get_string('notyetstarted', 'completion').'</i>';
 } else {
     echo '<i>'.get_string('inprogress','completion').'</i>';
 }
 
 echo '</td></tr>';
-echo '<tr><td colspan="2"><b>'.get_string('required').':</b> ';
 
-// Get overall aggregation method
-$overall = $info->get_aggregation_method();
+// Load criteria to display
+$completions = $info->get_completions($user->id);
 
-if ($overall == COMPLETION_AGGREGATION_ALL) {
-    echo get_string('criteriarequiredall', 'completion');
+// Check if this course has any criteria
+if (empty($completions)) {
+    echo '<tr><td colspan="2"><br />';
+    echo $OUTPUT->box(get_string('err_nocriteria', 'completion'), 'noticebox');
+    echo '</td></tr></tbody></table>';
 } else {
-    echo get_string('criteriarequiredany', 'completion');
-}
+    echo '<tr><td colspan="2"><b>'.get_string('required').':</b> ';
 
-echo '</td></tr></tbody></table>';
-
-// Generate markup for criteria statuses
-echo '<table class="generalbox boxaligncenter" cellpadding="3"><tbody>';
-echo '<tr class="ccheader">';
-echo '<th class="c0 header" scope="col">'.get_string('criteriagroup', 'block_completionstatus').'</th>';
-echo '<th class="c1 header" scope="col">'.get_string('criteria', 'completion').'</th>';
-echo '<th class="c2 header" scope="col">'.get_string('requirement', 'block_completionstatus').'</th>';
-echo '<th class="c3 header" scope="col">'.get_string('status').'</th>';
-echo '<th class="c4 header" scope="col">'.get_string('complete').'</th>';
-echo '<th class="c5 header" scope="col">'.get_string('completiondate', 'report_completion').'</th>';
-echo '</tr>';
-
-// Save row data
-$rows = array();
-
-global $COMPLETION_CRITERIA_TYPES;
-
-// Loop through course criteria
-foreach ($completions as $completion) {
-    $criteria = $completion->get_criteria();
-    $complete = $completion->is_complete();
-
-    $row = array();
-    $row['type'] = $criteria->criteriatype;
-    $row['title'] = $criteria->get_title();
-    $row['status'] = $completion->get_status();
-    $row['timecompleted'] = $completion->timecompleted;
-    $row['details'] = $criteria->get_details($completion);
-    $rows[] = $row;
-}
+    // Get overall aggregation method
+    $overall = $info->get_aggregation_method();
 
-// Print table
-$last_type = '';
-$agg_type = false;
+    if ($overall == COMPLETION_AGGREGATION_ALL) {
+        echo get_string('criteriarequiredall', 'completion');
+    } else {
+        echo get_string('criteriarequiredany', 'completion');
+    }
+
+    echo '</td></tr></tbody></table>';
+
+    // Generate markup for criteria statuses
+    echo '<table class="generalbox logtable boxaligncenter" id="criteriastatus" width="100%"><tbody>';
+    echo '<tr class="ccheader">';
+    echo '<th class="c0 header" scope="col">'.get_string('criteriagroup', 'block_completionstatus').'</th>';
+    echo '<th class="c1 header" scope="col">'.get_string('criteria', 'completion').'</th>';
+    echo '<th class="c2 header" scope="col">'.get_string('requirement', 'block_completionstatus').'</th>';
+    echo '<th class="c3 header" scope="col">'.get_string('status').'</th>';
+    echo '<th class="c4 header" scope="col">'.get_string('complete').'</th>';
+    echo '<th class="c5 header" scope="col">'.get_string('completiondate', 'report_completion').'</th>';
+    echo '</tr>';
 
-foreach ($rows as $row) {
+    // Save row data
+    $rows = array();
+
+    // Loop through course criteria
+    foreach ($completions as $completion) {
+        $criteria = $completion->get_criteria();
+
+        $row = array();
+        $row['type'] = $criteria->criteriatype;
+        $row['title'] = $criteria->get_title();
+        $row['status'] = $completion->get_status();
+        $row['complete'] = $completion->is_complete();
+        $row['timecompleted'] = $completion->timecompleted;
+        $row['details'] = $criteria->get_details($completion);
+        $rows[] = $row;
+    }
 
-    // Criteria group
-    echo '<td class="c0">';
-    if ($last_type !== $row['details']['type']) {
-        $last_type = $row['details']['type'];
-        echo $last_type;
+    // Print table
+    $last_type = '';
+    $agg_type = false;
+    $oddeven = 0;
 
-        // Reset agg type
-        $agg_type = true;
-    } else {
-        // Display aggregation type
-        if ($agg_type) {
-            $agg = $info->get_aggregation_method($row['type']);
+    foreach ($rows as $row) {
 
-            echo '(<i>';
+        echo '<tr class="r' . $oddeven . '">';
 
-            if ($agg == COMPLETION_AGGREGATION_ALL) {
-                echo strtolower(get_string('all', 'completion'));
-            } else {
-                echo strtolower(get_string('any', 'completion'));
-            }
+        // Criteria group
+        echo '<td class="cell c0">';
+        if ($last_type !== $row['details']['type']) {
+            $last_type = $row['details']['type'];
+            echo $last_type;
+
+            // Reset agg type
+            $agg_type = true;
+        } else {
+            // Display aggregation type
+            if ($agg_type) {
+                $agg = $info->get_aggregation_method($row['type']);
 
-            echo '</i> '.strtolower(get_string('required')).')';
-            $agg_type = false;
+                echo '(<i>';
+
+                if ($agg == COMPLETION_AGGREGATION_ALL) {
+                    echo strtolower(get_string('aggregateall', 'completion'));
+                } else {
+                    echo strtolower(get_string('aggregateany', 'completion'));
+                }
+
+                echo '</i> '.strtolower(get_string('required')).')';
+                $agg_type = false;
+            }
         }
+        echo '</td>';
+
+        // Criteria title
+        echo '<td class="cell c1">';
+        echo $row['details']['criteria'];
+        echo '</td>';
+
+        // Requirement
+        echo '<td class="cell c2">';
+        echo $row['details']['requirement'];
+        echo '</td>';
+
+        // Status
+        echo '<td class="cell c3">';
+        echo $row['details']['status'];
+        echo '</td>';
+
+        // Is complete
+        echo '<td class="cell c4">';
+        echo $row['complete'] ? get_string('yes') : get_string('no');
+        echo '</td>';
+
+        // Completion data
+        echo '<td class="cell c5">';
+        if ($row['timecompleted']) {
+            echo userdate($row['timecompleted'], get_string('strftimedate', 'langconfig'));
+        } else {
+            echo '-';
+        }
+        echo '</td>';
+        echo '</tr>';
+        // for row striping
+        $oddeven = $oddeven ? 0 : 1;
     }
-    echo '</td>';
-
-    // Criteria title
-    echo '<td class="c1">';
-    echo $row['details']['criteria'];
-    echo '</td>';
-
-    // Requirement
-    echo '<td class="c2">';
-    echo $row['details']['requirement'];
-    echo '</td>';
-
-    // Status
-    echo '<td class="c3">';
-    echo $row['details']['status'];
-    echo '</td>';
-
-    // Is complete
-    echo '<td class="c4">';
-    echo ($row['status'] === get_string('yes')) ? get_string('yes') : get_string('no');
-    echo '</td>';
-
-    // Completion data
-    echo '<td class="c5">';
-    if ($row['timecompleted']) {
-        echo userdate($row['timecompleted'], '%e %B %G');
-    } else {
-        echo '-';
-    }
-    echo '</td>';
-    echo '</tr>';
+
+    echo '</tbody></table>';
 }
 
-echo '</tbody></table>';
+echo '<div class="buttons">';
+$courseurl = new moodle_url("/course/view.php", array('id' => $course->id));
+echo $OUTPUT->single_button($courseurl, get_string('returntocourse', 'block_completionstatus'), 'get');
+echo '</div>';
 
 echo $OUTPUT->footer();
index fcc965a..6658c17 100644 (file)
@@ -5,3 +5,4 @@ $string['criteriagroup'] = 'Criteria group';
 $string['firstofsecond'] = '{$a->first} of {$a->second}';
 $string['pluginname'] = 'Course completion status';
 $string['requirement'] = 'Requirement';
+$string['returntocourse'] = 'Return to course';
index bdf30ef..bc91d40 100644 (file)
@@ -44,7 +44,16 @@ $message = null;
 if ($delete && confirm_sesskey()) {
     $externalbloguserid = $DB->get_field('blog_external', 'userid', array('id' => $delete));
     if ($externalbloguserid == $USER->id) {
+        // Delete the external blog
         $DB->delete_records('blog_external', array('id' => $delete));
+
+        // Delete the external blog's posts
+        $deletewhere = 'module = :module
+                            AND userid = :userid
+                            AND ' . $DB->sql_isnotempty('post', 'uniquehash', false, false) . '
+                            AND ' . $DB->sql_compare_text('content') . ' = ' . $DB->sql_compare_text(':delete');
+        $DB->delete_records_select('post', $deletewhere, array('module' => 'blog_external', 'userid' => $USER->id, 'delete' => $delete));
+
         $message = get_string('externalblogdeleted', 'blog');
     }
 }
index 43b36af..9a07fba 100644 (file)
@@ -292,11 +292,10 @@ class blog_entry implements renderable {
      * @return void
      */
     public function delete() {
-        global $DB, $USER;
-
-        $returnurl = '';
+        global $DB;
 
         $this->delete_attachments();
+        $this->remove_associations();
 
         $DB->delete_records('post', array('id' => $this->id));
         tag_set('post', $this->id, array());
index f88d867..1b822cc 100644 (file)
@@ -27,6 +27,7 @@
 
 require_once("../config.php");
 require_once($CFG->dirroot.'/course/lib.php');
+require_once($CFG->libdir.'/textlib.class.php');
 
 $id = required_param('id', PARAM_INT); // Category id
 $page = optional_param('page', 0, PARAM_INT); // which page to show
@@ -75,7 +76,8 @@ $sesskeyprovided = !empty($sesskey) && confirm_sesskey($sesskey);
 // Process any category actions.
 if ($canmanage && $resort && $sesskeyprovided) {
     // Resort the category if requested
-    if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) {
+    if ($courses = get_courses($category->id, '', 'c.id,c.fullname,c.sortorder')) {
+        collatorlib::asort_objects_by_property($courses, 'fullname', collatorlib::SORT_NATURAL);
         $i = 1;
         foreach ($courses as $course) {
             $DB->set_field('course', 'sortorder', $category->sortorder+$i, array('id'=>$course->id));
index f410e07..28ec82a 100644 (file)
@@ -36,7 +36,7 @@ M.course.format.get_config = function() {
 M.course.format.swap_sections = function(Y, node1, node2) {
     var CSS = {
         COURSECONTENT : 'course-content',
-        SECTIONADDMENUS : 'section_add_menus',
+        SECTIONADDMENUS : 'section_add_menus'
     };
 
     var sectionlist = Y.Node.all('.'+CSS.COURSECONTENT+' '+M.course.format.get_section_selector(Y));
index cf8f372..c4233f4 100644 (file)
@@ -4144,6 +4144,11 @@ class course_request {
         global $USER, $DB, $CFG;
         $data->requester = $USER->id;
 
+        // Setting the default category is none set.
+        if (empty($data->category) || empty($CFG->requestcategoryselection)) {
+            $data->category = $CFG->defaultrequestcategory;
+        }
+
         // Summary is a required field so copy the text over
         $data->summary       = $data->summary_editor['text'];
         $data->summaryformat = $data->summary_editor['format'];
@@ -4293,7 +4298,6 @@ class course_request {
 
         $user = $DB->get_record('user', array('id' => $this->properties->requester, 'deleted'=>0), '*', MUST_EXIST);
 
-        $category = get_course_category($CFG->defaultrequestcategory);
         $courseconfig = get_config('moodlecourse');
 
         // Transfer appropriate settings
@@ -4302,6 +4306,14 @@ class course_request {
         unset($data->reason);
         unset($data->requester);
 
+        // If the current user does not have the rights to change the category, or if the
+        // category does not exist, we set the default category to the course to be approved.
+        // The system level is used because the capability moodle/site:approvecourse is based on a system level.
+        if (!has_capability('moodle/course:changecategory', context_system::instance()) ||
+                (!$category = get_course_category($data->category))) {
+            $category = get_course_category($CFG->defaultrequestcategory);
+        }
+
         // Set category
         $data->category = $category->id;
         $data->sortorder = $category->sortorder; // place as the first in category
index 205a429..8ac5832 100644 (file)
@@ -101,8 +101,8 @@ if (empty($pending)) {
     $table = new html_table();
     $table->attributes['class'] = 'pendingcourserequests generaltable';
     $table->align = array('center', 'center', 'center', 'center', 'center', 'center');
-    $table->head = array(get_string('shortnamecourse'), get_string('fullnamecourse'),
-            get_string('requestedby'), get_string('summary'), get_string('requestreason'), get_string('action'));
+    $table->head = array(get_string('shortnamecourse'), get_string('fullnamecourse'), get_string('requestedby'),
+            get_string('summary'), get_string('category'), get_string('requestreason'), get_string('action'));
 
     foreach ($pending as $course) {
         $course = new course_request($course);
@@ -110,11 +110,22 @@ if (empty($pending)) {
         // Check here for shortname collisions and warn about them.
         $course->check_shortname_collision();
 
+        // Retreiving category name.
+        // If the user does not have the capability to change the category, we fallback on the default one.
+        // Else, the category proposed is fetched, but we fallback on the default one if we can't find it.
+        // It is just a matter of displaying the right information because the logic when approving the category
+        // proceeds the same way. The system context level is used as moodle/site:approvecourse uses it.
+        if (!has_capability('moodle/course:changecategory', context_system::instance()) ||
+                (!$category = get_course_category($course->category))) {
+            $category = get_course_category($CFG->defaultrequestcategory);
+        }
+
         $row = array();
         $row[] = format_string($course->shortname);
         $row[] = format_string($course->fullname);
         $row[] = fullname($course->get_requester());
         $row[] = $course->summary;
+        $row[] = format_string($category->name);
         $row[] = format_string($course->reason);
         $row[] = $OUTPUT->single_button(new moodle_url($baseurl, array('approve' => $course->id, 'sesskey' => sesskey())), get_string('approve'), 'get') .
                  $OUTPUT->single_button(new moodle_url($baseurl, array('reject' => $course->id)), get_string('rejectdots'), 'get');
index e74e40b..867a684 100644 (file)
@@ -42,7 +42,7 @@ require_once($CFG->libdir.'/formslib.php');
  */
 class course_request_form extends moodleform {
     function definition() {
-        global $DB, $USER;
+        global $CFG, $DB, $USER;
 
         $mform =& $this->_form;
 
@@ -68,6 +68,15 @@ class course_request_form extends moodleform {
         $mform->addRule('shortname', get_string('missingshortname'), 'required', null, 'client');
         $mform->setType('shortname', PARAM_TEXT);
 
+        if (!empty($CFG->requestcategoryselection)) {
+            $displaylist = array();
+            $parentlist = array();
+            make_categories_list($displaylist, $parentlist, '');
+            $mform->addElement('select', 'category', get_string('category'), $displaylist);
+            $mform->setDefault('category', $CFG->defaultrequestcategory);
+            $mform->addHelpButton('category', 'category');
+        }
+
         $mform->addElement('editor', 'summary_editor', get_string('summary'), null, course_request::summary_editor_options());
         $mform->addHelpButton('summary_editor', 'coursesummary');
         $mform->setType('summary_editor', PARAM_RAW);
index 42b8057..0004f7d 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
+global $CFG;
+require_once($CFG->dirroot.'/course/lib.php');
 
 class courselib_testcase extends advanced_testcase {
 
+    public function test_create_course() {
+        global $DB;
+        $this->resetAfterTest(true);
+        $defaultcategory = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
+
+        $course = new stdClass();
+        $course->fullname = 'Apu loves Unit Təsts';
+        $course->shortname = 'Spread the lŭve';
+        $course->idnumber = '123';
+        $course->summary = 'Awesome!';
+        $course->summaryformat = FORMAT_PLAIN;
+        $course->format = 'topics';
+        $course->newsitems = 0;
+        $course->numsections = 5;
+        $course->category = $defaultcategory;
+
+        $created = create_course($course);
+        $context = context_course::instance($created->id);
+
+        // Compare original and created.
+        $original = (array) $course;
+        $this->assertEquals($original, array_intersect_key((array) $created, $original));
+
+        // Ensure default section is created.
+        $sectioncreated = $DB->record_exists('course_sections', array('course' => $created->id, 'section' => 0));
+        $this->assertTrue($sectioncreated);
+
+        // Ensure blocks have been associated to the course.
+        $blockcount = $DB->count_records('block_instances', array('parentcontextid' => $context->id));
+        $this->assertGreaterThan(0, $blockcount);
+    }
+
     public function test_reorder_sections() {
         global $DB;
         $this->resetAfterTest(true);
diff --git a/course/tests/courserequest_test.php b/course/tests/courserequest_test.php
new file mode 100644 (file)
index 0000000..a4c6f6d
--- /dev/null
@@ -0,0 +1,145 @@
+<?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/>.
+
+/**
+ * Course request related unit tests
+ *
+ * @package    core
+ * @category   phpunit
+ * @copyright  2012 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot.'/course/lib.php');
+
+class courserequest_testcase extends advanced_testcase {
+
+    public function test_create_request() {
+        global $DB, $USER;
+        $this->resetAfterTest(true);
+
+        $defaultcategory = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
+        set_config('enablecourserequests', 1);
+        set_config('requestcategoryselection', 0);
+        set_config('defaultrequestcategory', $defaultcategory);
+
+        // Create some categories.
+        $cat1 = $this->getDataGenerator()->create_category();
+        $cat2 = $this->getDataGenerator()->create_category();
+        $cat3 = $this->getDataGenerator()->create_category();
+
+        // Basic course request.
+        $data = new stdClass();
+        $data->fullname = 'Həllo World!';
+        $data->shortname = 'Hi th€re!';
+        $data->summary_editor['text'] = 'Lorem Ipsum ©';
+        $data->summary_editor['format'] = FORMAT_HTML;
+        $data->reason = 'Because PHP Unit is cool.';
+        $cr = course_request::create($data);
+
+        $this->assertEquals($data->fullname, $cr->fullname);
+        $this->assertEquals($data->shortname, $cr->shortname);
+        $this->assertEquals($data->summary_editor['text'], $cr->summary);
+        $this->assertEquals($data->summary_editor['format'], $cr->summaryformat);
+        $this->assertEquals($data->reason, $cr->reason);
+        $this->assertEquals($USER->id, $cr->requester);
+        $this->assertEquals($defaultcategory, $cr->category);
+
+        // Request with category but category selection not allowed.
+        set_config('defaultrequestcategory', $cat2->id);
+        $data->category = $cat1->id;
+        $cr = course_request::create($data);
+        $this->assertEquals($cat2->id, $cr->category);
+
+        // Request with category different than default and category selection allowed.
+        set_config('defaultrequestcategory', $cat3->id);
+        set_config('requestcategoryselection', 1);
+        $data->category = $cat1->id;
+        $cr = course_request::create($data);
+        $this->assertEquals($cat1->id, $cr->category);
+    }
+
+    public function test_approve_request() {
+        global $DB;
+        $this->resetAfterTest(true);
+        $this->preventResetByRollback();
+
+        $this->setAdminUser();
+        $defaultcategory = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
+        set_config('enablecourserequests', 1);
+        set_config('requestcategoryselection', 0);
+        set_config('defaultrequestcategory', $defaultcategory);
+
+        // Create some categories.
+        $cat1 = $this->getDataGenerator()->create_category();
+        $cat2 = $this->getDataGenerator()->create_category();
+
+        $data = new stdClass();
+        $data->fullname = 'Həllo World!';
+        $data->shortname = 'Hi th€re!';
+        $data->summary_editor['text'] = 'Lorem Ipsum ©';
+        $data->summary_editor['format'] = FORMAT_HTML;
+        $data->reason = 'Because PHP Unit is cool.';
+
+        // Test without category.
+        $cr = course_request::create($data);
+        $id = $cr->approve();
+        $course = $DB->get_record('course', array('id' => $id));
+        $this->assertEquals($data->fullname, $course->fullname);
+        $this->assertEquals($data->shortname, $course->shortname);
+        $this->assertEquals($data->summary_editor['text'], $course->summary);
+        $this->assertEquals($data->summary_editor['format'], $course->summaryformat);
+        $this->assertEquals(1, $course->requested);
+        $this->assertEquals($defaultcategory, $course->category);
+
+        // Test with category.
+        set_config('requestcategoryselection', 1);
+        set_config('defaultrequestcategory', $cat2->id);
+        $data->shortname .= ' 2nd';
+        $data->category = $cat1->id;
+        $cr = course_request::create($data);
+        $id = $cr->approve();
+        $course = $DB->get_record('course', array('id' => $id));
+        $this->assertEquals($data->category, $course->category);
+    }
+
+    public function test_reject_request() {
+        global $DB;
+        $this->resetAfterTest(true);
+        $this->preventResetByRollback();
+        $this->setAdminUser();
+        set_config('enablecourserequests', 1);
+        set_config('requestcategoryselection', 0);
+        set_config('defaultrequestcategory', $DB->get_field_select('course_categories', "MIN(id)", "parent=0"));
+
+        $data = new stdClass();
+        $data->fullname = 'Həllo World!';
+        $data->shortname = 'Hi th€re!';
+        $data->summary_editor['text'] = 'Lorem Ipsum ©';
+        $data->summary_editor['format'] = FORMAT_HTML;
+        $data->reason = 'Because PHP Unit is cool.';
+
+        $cr = course_request::create($data);
+        $this->assertTrue($DB->record_exists('course_request', array('id' => $cr->id)));
+        $cr->reject('Sorry!');
+        $this->assertFalse($DB->record_exists('course_request', array('id' => $cr->id)));
+    }
+
+}
index 08f8b4a..984b9ed 100644 (file)
@@ -165,20 +165,28 @@ class core_course_external_testcase extends externallib_advanced_testcase {
         global $DB;
 
         $this->resetAfterTest(true);
+
+        $generatedcats = array();
         $category1data['idnumber'] = 'idnumbercat1';
         $category1data['name'] = 'Category 1 for PHPunit test';
         $category1data['description'] = 'Category 1 description';
         $category1data['descriptionformat'] = FORMAT_MOODLE;
         $category1  = self::getDataGenerator()->create_category($category1data);
+        $generatedcats[$category1->id] = $category1;
         $category2  = self::getDataGenerator()->create_category(
                 array('parent' => $category1->id));
+        $generatedcats[$category2->id] = $category2;
         $category6  = self::getDataGenerator()->create_category(
                 array('parent' => $category1->id, 'visible' => 0));
+        $generatedcats[$category6->id] = $category6;
         $category3  = self::getDataGenerator()->create_category();
+        $generatedcats[$category3->id] = $category3;
         $category4  = self::getDataGenerator()->create_category(
                 array('parent' => $category3->id));
+        $generatedcats[$category4->id] = $category4;
         $category5  = self::getDataGenerator()->create_category(
                 array('parent' => $category4->id));
+        $generatedcats[$category5->id] = $category5;
 
         // Set the required capabilities by the external function.
         $context = context_system::instance();
@@ -193,11 +201,13 @@ class core_course_external_testcase extends externallib_advanced_testcase {
         $this->assertEquals(2, count($categories));
 
         // Check the return values
-        $this->assertEquals($categories[0]['id'], $category1->id);
-        $this->assertEquals($categories[0]['idnumber'], $category1->idnumber);
-        $this->assertEquals($categories[0]['name'], $category1->name);
-        $this->assertEquals($categories[0]['description'], $category1->description);
-        $this->assertEquals($categories[0]['descriptionformat'], FORMAT_HTML);
+        foreach ($categories as $category) {
+            $generatedcat = $generatedcats[$category['id']];
+            $this->assertEquals($category['idnumber'], $generatedcat->idnumber);
+            $this->assertEquals($category['name'], $generatedcat->name);
+            $this->assertEquals($category['description'], $generatedcat->description);
+            $this->assertEquals($category['descriptionformat'], FORMAT_HTML);
+        }
 
         // Check different params.
         $categories = core_course_external::get_categories(array(
@@ -440,13 +450,17 @@ class core_course_external_testcase extends externallib_advanced_testcase {
 
         $this->resetAfterTest(true);
 
+        $generatedcourses = array();
         $coursedata['idnumber'] = 'idnumbercourse1';
         $coursedata['fullname'] = 'Course 1 for PHPunit test';
         $coursedata['summary'] = 'Course 1 description';
         $coursedata['summaryformat'] = FORMAT_MOODLE;
         $course1  = self::getDataGenerator()->create_course($coursedata);
+        $generatedcourses[$course1->id] = $course1;
         $course2  = self::getDataGenerator()->create_course();
+        $generatedcourses[$course2->id] = $course2;
         $course3  = self::getDataGenerator()->create_course();
+        $generatedcourses[$course3->id] = $course3;
 
         // Set the required capabilities by the external function.
         $context = context_system::instance();
@@ -464,33 +478,33 @@ class core_course_external_testcase extends externallib_advanced_testcase {
         // Check we retrieve the good total number of categories.
         $this->assertEquals(2, count($courses));
 
-        // Check the return values for course 1
-        $dbcourse = $DB->get_record('course', array('id' => $course1->id));
-        $this->assertEquals($courses[0]['id'], $dbcourse->id);
-        $this->assertEquals($courses[0]['idnumber'], $coursedata['idnumber']);
-        $this->assertEquals($courses[0]['fullname'], $coursedata['fullname']);
-        $this->assertEquals($courses[0]['summary'], $coursedata['summary']);
-        $this->assertEquals($courses[0]['summaryformat'], FORMAT_HTML);
-        $this->assertEquals($courses[0]['shortname'], $dbcourse->shortname);
-        $this->assertEquals($courses[0]['categoryid'], $dbcourse->category);
-        $this->assertEquals($courses[0]['format'], $dbcourse->format);
-        $this->assertEquals($courses[0]['showgrades'], $dbcourse->showgrades);
-        $this->assertEquals($courses[0]['newsitems'], $dbcourse->newsitems);
-        $this->assertEquals($courses[0]['startdate'], $dbcourse->startdate);
-        $this->assertEquals($courses[0]['numsections'], $dbcourse->numsections);
-        $this->assertEquals($courses[0]['maxbytes'], $dbcourse->maxbytes);
-        $this->assertEquals($courses[0]['showreports'], $dbcourse->showreports);
-        $this->assertEquals($courses[0]['visible'], $dbcourse->visible);
-        $this->assertEquals($courses[0]['hiddensections'], $dbcourse->hiddensections);
-        $this->assertEquals($courses[0]['groupmode'], $dbcourse->groupmode);
-        $this->assertEquals($courses[0]['groupmodeforce'], $dbcourse->groupmodeforce);
-        $this->assertEquals($courses[0]['defaultgroupingid'], $dbcourse->defaultgroupingid);
-        $this->assertEquals($courses[0]['completionnotify'], $dbcourse->completionnotify);
-        $this->assertEquals($courses[0]['lang'], $dbcourse->lang);
-        $this->assertEquals($courses[0]['forcetheme'], $dbcourse->theme);
-        $this->assertEquals($courses[0]['completionstartonenrol'], $dbcourse->completionstartonenrol);
-        $this->assertEquals($courses[0]['enablecompletion'], $dbcourse->enablecompletion);
-        $this->assertEquals($courses[0]['completionstartonenrol'], $dbcourse->completionstartonenrol);
+        foreach ($courses as $course) {
+            $dbcourse = $generatedcourses[$course['id']];
+            $this->assertEquals($course['idnumber'], $dbcourse->idnumber);
+            $this->assertEquals($course['fullname'], $dbcourse->fullname);
+            $this->assertEquals($course['summary'], $dbcourse->summary);
+            $this->assertEquals($course['summaryformat'], FORMAT_HTML);
+            $this->assertEquals($course['shortname'], $dbcourse->shortname);
+            $this->assertEquals($course['categoryid'], $dbcourse->category);
+            $this->assertEquals($course['format'], $dbcourse->format);
+            $this->assertEquals($course['showgrades'], $dbcourse->showgrades);
+            $this->assertEquals($course['newsitems'], $dbcourse->newsitems);
+            $this->assertEquals($course['startdate'], $dbcourse->startdate);
+            $this->assertEquals($course['numsections'], $dbcourse->numsections);
+            $this->assertEquals($course['maxbytes'], $dbcourse->maxbytes);
+            $this->assertEquals($course['showreports'], $dbcourse->showreports);
+            $this->assertEquals($course['visible'], $dbcourse->visible);
+            $this->assertEquals($course['hiddensections'], $dbcourse->hiddensections);
+            $this->assertEquals($course['groupmode'], $dbcourse->groupmode);
+            $this->assertEquals($course['groupmodeforce'], $dbcourse->groupmodeforce);
+            $this->assertEquals($course['defaultgroupingid'], $dbcourse->defaultgroupingid);
+            $this->assertEquals($course['completionnotify'], $dbcourse->completionnotify);
+            $this->assertEquals($course['lang'], $dbcourse->lang);
+            $this->assertEquals($course['forcetheme'], $dbcourse->theme);
+            $this->assertEquals($course['completionstartonenrol'], $dbcourse->completionstartonenrol);
+            $this->assertEquals($course['enablecompletion'], $dbcourse->enablecompletion);
+            $this->assertEquals($course['completionstartonenrol'], $dbcourse->completionstartonenrol);
+        }
 
         // Get all courses in the DB
         $courses = core_course_external::get_courses(array());
index 869e06c..a00c267 100644 (file)
@@ -51,8 +51,8 @@ class enrol_cohort_handler {
         $sql = "SELECT e.*, r.id as roleexists
                   FROM {enrol} e
              LEFT JOIN {role} r ON (r.id = e.roleid)
-                 WHERE customint1 = :cohortid AND enrol = 'cohort'
-              ORDER BY id ASC";
+                 WHERE e.customint1 = :cohortid AND e.enrol = 'cohort'
+              ORDER BY e.id ASC";
         if (!$instances = $DB->get_records_sql($sql, array('cohortid'=>$ca->cohortid))) {
             return true;
         }
index 08f8d70..4efe967 100644 (file)
@@ -339,7 +339,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                 count++;
                 var user = result.response.users[i];
                 users.append(create('<div class="'+CSS.USER+' clearfix" rel="'+user.id+'"></div>')
-                    .addClass((i%2)?CSS.ODD:CSS.EVEN)
+                    .addClass((count%2)?CSS.ODD:CSS.EVEN)
                     .append(create('<div class="'+CSS.COUNT+'">'+count+'</div>'))
                     .append(create('<div class="'+CSS.PICTURE+'"></div>')
                         .append(create(user.picture)))
index 2a28c24..67fb06f 100644 (file)
@@ -34,6 +34,7 @@ require("../../config.php");
 require_once("lib.php");
 require_once($CFG->libdir.'/eventslib.php');
 require_once($CFG->libdir.'/enrollib.php');
+require_once($CFG->libdir . '/filelib.php');
 
 
 /// Keep out casual intruders
@@ -89,14 +90,17 @@ if (! $plugin_instance = $DB->get_record("enrol", array("id"=>$data->instanceid,
 $plugin = enrol_get_plugin('paypal');
 
 /// Open a connection back to PayPal to validate the data
-$header = '';
-$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
-$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
-$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
+$c = new curl();
+$options = array(
+    'returntransfer' => true,
+    'httpheader' => array('application/x-www-form-urlencoded'),
+    'timeout' => 30,
+);
 $paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';
-$fp = fsockopen ($paypaladdr, 80, $errno, $errstr, 30);
+$location = "https://$paypaladdr/cgi-bin/webscr";
+$result = $c->post($location, $req, $options);
 
-if (!$fp) {  /// Could not open a socket to PayPal - FAIL
+if (!$result) {  /// Could not connect to PayPal - FAIL
     echo "<p>Error: could not access paypal.com</p>";
     message_paypal_error_to_admin("Could not access paypal.com to verify payment", $data);
     die;
@@ -104,12 +108,9 @@ if (!$fp) {  /// Could not open a socket to PayPal - FAIL
 
 /// Connection is OK, so now we post the data to validate it
 
-fputs ($fp, $header.$req);
-
 /// Now read the response and check if everything is OK.
 
-while (!feof($fp)) {
-    $result = fgets($fp, 1024);
+if (strlen($result) > 0) {
     if (strcmp($result, "VERIFIED") == 0) {          // VALID PAYMENT!
 
 
@@ -296,7 +297,6 @@ while (!feof($fp)) {
     }
 }
 
-fclose($fp);
 exit;
 
 
index 8687610..c0044fb 100644 (file)
@@ -57,6 +57,9 @@ class filter_mediaplugin_testcase extends advanced_testcase {
             '<a id="movie player" class="center" href="http://moodle.org/testfile/test.mpg">test mpg</a>',
             '<a href="http://moodle.org/testfile/test.ram">test</a>',
             '<a href="http://www.youtube.com/watch?v=JghQgA2HMX8" class="href=css">test file</a>',
+            '<a href="http://www.youtube-nocookie.com/watch?v=JghQgA2HMX8" class="href=css">test file</a>',
+            '<a href="http://youtu.be/JghQgA2HMX8" class="href=css">test file</a>',
+            '<a href="http://y2u.be/JghQgA2HMX8" class="href=css">test file</a>',
             '<a class="youtube" href="http://www.youtube.com/watch?v=JghQgA2HMX8">test file</a>',
             '<a class="_blanktarget" href="http://moodle.org/testfile/test.flv?d=100x100">test flv</a>',
             '<a class="hrefcss" href="http://www.youtube.com/watch?v=JghQgA2HMX8">test file</a>',
index 5a1d8f7..c155565 100644 (file)
@@ -225,7 +225,7 @@ class edit_category_form extends moodleform {
         $mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
 
         $options = array();
-        $default = '';
+        $default = -1;
         $categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
 
         foreach ($categories as $cat) {
@@ -238,6 +238,7 @@ class edit_category_form extends moodleform {
 
         if (count($categories) > 1) {
             $mform->addElement('select', 'parentcategory', get_string('parentcategory', 'grades'), $options);
+            $mform->setDefault('parentcategory', $default);
             $mform->addElement('static', 'currentparentaggregation', get_string('currentparentaggregation', 'grades'));
         }
 
diff --git a/group/tests/externallib_test.php b/group/tests/externallib_test.php
new file mode 100644 (file)
index 0000000..5963937
--- /dev/null
@@ -0,0 +1,204 @@
+<?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/>.
+
+/**
+ * Group external PHPunit tests
+ *
+ * @package    core_group
+ * @category   external
+ * @copyright  2012 Jerome Mouneyrac
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since Moodle 2.4
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+require_once($CFG->dirroot . '/webservice/tests/helpers.php');
+require_once($CFG->dirroot . '/group/externallib.php');
+
+class core_group_external_testcase extends externallib_advanced_testcase {
+
+    /**
+     * Test create_groups
+     */
+    public function test_create_groups() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $course  = self::getDataGenerator()->create_course();
+
+        $group1 = array();
+        $group1['courseid'] = $course->id;
+        $group1['name'] = 'Group Test 1';
+        $group1['description'] = 'Group Test 1 description';
+        $group1['descriptionformat'] = FORMAT_MOODLE;
+        $group1['enrolmentkey'] = 'Test group enrol secret phrase';
+        $group2 = array();
+        $group2['courseid'] = $course->id;
+        $group2['name'] = 'Group Test 2';
+        $group2['description'] = 'Group Test 2 description';
+        $group3 = array();
+        $group3['courseid'] = $course->id;
+        $group3['name'] = 'Group Test 3';
+        $group3['description'] = 'Group Test 3 description';
+
+        // Set the required capabilities by the external function
+        $context = context_course::instance($course->id);
+        $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
+        $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
+
+        // Call the external function.
+        $groups = core_group_external::create_groups(array($group1, $group2));
+
+        // Checks against DB values
+        $this->assertEquals(2, count($groups));
+        foreach ($groups as $group) {
+            $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
+            switch ($dbgroup->name) {
+                case $group1['name']:
+                    $groupdescription = $group1['description'];
+                    $groupcourseid = $group1['courseid'];
+                    $this->assertEquals($dbgroup->descriptionformat, $group1['descriptionformat']);
+                    $this->assertEquals($dbgroup->enrolmentkey, $group1['enrolmentkey']);
+                    break;
+                case $group2['name']:
+                    $groupdescription = $group2['description'];
+                    $groupcourseid = $group2['courseid'];
+                    break;
+                default:
+                    throw new moodle_exception('unknowgroupname');
+                    break;
+            }
+            $this->assertEquals($dbgroup->description, $groupdescription);
+            $this->assertEquals($dbgroup->courseid, $groupcourseid);
+        }
+
+        // Call without required capability
+        $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
+        $this->setExpectedException('required_capability_exception');
+        $froups = core_group_external::create_groups(array($group3));
+    }
+
+    /**
+     * Test get_groups
+     */
+    public function test_get_groups() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $course = self::getDataGenerator()->create_course();
+        $group1data = array();
+        $group1data['courseid'] = $course->id;
+        $group1data['name'] = 'Group Test 1';
+        $group1data['description'] = 'Group Test 1 description';
+        $group1data['descriptionformat'] = FORMAT_MOODLE;
+        $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
+        $group2data = array();
+        $group2data['courseid'] = $course->id;
+        $group2data['name'] = 'Group Test 2';
+        $group2data['description'] = 'Group Test 2 description';
+        $group1 = self::getDataGenerator()->create_group($group1data);
+        $group2 = self::getDataGenerator()->create_group($group2data);
+
+        // Set the required capabilities by the external function
+        $context = context_course::instance($course->id);
+        $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
+        $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
+
+        // Call the external function.
+        $groups = core_group_external::get_groups(array($group1->id, $group2->id));
+
+        // Checks against DB values
+        $this->assertEquals(2, count($groups));
+        foreach ($groups as $group) {
+            $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
+            switch ($dbgroup->name) {
+                case $group1->name:
+                    $groupdescription = $group1->description;
+                    $groupcourseid = $group1->courseid;
+                    $this->assertEquals($dbgroup->descriptionformat, $group1->descriptionformat);
+                    $this->assertEquals($dbgroup->enrolmentkey, $group1->enrolmentkey);
+                    break;
+                case $group2->name:
+                    $groupdescription = $group2->description;
+                    $groupcourseid = $group2->courseid;
+                    break;
+                default:
+                    throw new moodle_exception('unknowgroupname');
+                    break;
+            }
+            $this->assertEquals($dbgroup->description, $groupdescription);
+            $this->assertEquals($dbgroup->courseid, $groupcourseid);
+        }
+
+        // Call without required capability
+        $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
+        $this->setExpectedException('required_capability_exception');
+        $froups = core_group_external::get_groups(array($group1->id, $group2->id));
+    }
+
+    /**
+     * Test delete_groups
+     */
+    public function test_delete_groups() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $course = self::getDataGenerator()->create_course();
+        $group1data = array();
+        $group1data['courseid'] = $course->id;
+        $group1data['name'] = 'Group Test 1';
+        $group1data['description'] = 'Group Test 1 description';
+        $group1data['descriptionformat'] = FORMAT_MOODLE;
+        $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
+        $group2data = array();
+        $group2data['courseid'] = $course->id;
+        $group2data['name'] = 'Group Test 2';
+        $group2data['description'] = 'Group Test 2 description';
+        $group3data['courseid'] = $course->id;
+        $group3data['name'] = 'Group Test 3';
+        $group3data['description'] = 'Group Test 3 description';
+        $group1 = self::getDataGenerator()->create_group($group1data);
+        $group2 = self::getDataGenerator()->create_group($group2data);
+        $group3 = self::getDataGenerator()->create_group($group3data);
+
+        // Set the required capabilities by the external function
+        $context = context_course::instance($course->id);
+        $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
+        $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
+
+        // Checks against DB values
+        $groupstotal = $DB->count_records('groups', array());
+        $this->assertEquals(3, $groupstotal);
+
+        // Call the external function.
+        core_group_external::delete_groups(array($group1->id, $group2->id));
+
+        // Checks against DB values
+        $groupstotal = $DB->count_records('groups', array());
+        $this->assertEquals(1, $groupstotal);
+
+        // Call without required capability
+        $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
+        $this->setExpectedException('required_capability_exception');
+        $froups = core_group_external::delete_groups(array($group3->id));
+    }
+}
\ No newline at end of file
index 38a4438..dd35032 100644 (file)
--- a/index.php
+++ b/index.php
             break;
 
             case FRONTPAGECOURSELIST:
+                $ncourses = $DB->count_records('course');
                 if (isloggedin() and !$hassiteconfig and !isguestuser() and empty($CFG->disablemycourses)) {
                     echo html_writer::tag('a', get_string('skipa', 'access', textlib::strtolower(get_string('mycourses'))), array('href'=>'#skipmycourses', 'class'=>'skip-block'));
                     echo $OUTPUT->heading(get_string('mycourses'), 2, 'headingblock header');
                     print_my_moodle();
                     echo html_writer::tag('span', '', array('class'=>'skip-block-to', 'id'=>'skipmycourses'));
-                } else if ((!$hassiteconfig and !isguestuser()) or ($DB->count_records('course') <= FRONTPAGECOURSELIMIT)) {
+                } else if ((!$hassiteconfig and !isguestuser()) or ($ncourses <= FRONTPAGECOURSELIMIT)) {
                     // admin should not see list of courses when there are too many of them
                     echo html_writer::tag('a', get_string('skipa', 'access', textlib::strtolower(get_string('availablecourses'))), array('href'=>'#skipavailablecourses', 'class'=>'skip-block'));
                     echo $OUTPUT->heading(get_string('availablecourses'), 2, 'headingblock header');
                     print_courses(0);
                     echo html_writer::tag('span', '', array('class'=>'skip-block-to', 'id'=>'skipavailablecourses'));
+                } else {
+                    echo html_writer::tag('div', get_string('therearecourses', '', $ncourses), array('class' => 'notifyproblem'));
+                    print_course_search('', false, 'short');
                 }
             break;
 
index c8574b5..0dd2488 100644 (file)
@@ -34,7 +34,8 @@ $string['admindirname'] = '관리 디렉토리';
 $string['availablelangs'] = '가능한 언어 목록';
 $string['chooselanguagehead'] = '언어를 선택하시오';
 $string['chooselanguagesub'] = '설치 과정에서 사용할 언어를 선택하십시오. 선택한 언어는 사이트의 기본 언어로 사용할 수 있으며, 추후 다른 언어로 바꿀 수도 있습니다.';
-$string['clialreadyinstalled'] = '이미 config.php 파일이 존재함. 사이트를 업데이트하려면 admin/cli/upgrade.php를 사용하십시오';
+$string['clialreadyconfigured'] = '만일 이 사이트를 설치하고 싶은데 이미 config.php파일이 있다면, admin/cli/install_database.php 를 이용하시기 바랍니다.';
+$string['clialreadyinstalled'] = '이미 config.php 파일이 존재함. 사이트를 업그레이드하려면 admin/cli/upgrade.php를 사용하시기 바랍니다.';
 $string['cliinstallheader'] = '무들 {$a} 명령 입력 설치 프로그램';
 $string['databasehost'] = '데이터베이스 호스트';
 $string['databasename'] = '데이터베이스 명칭';
@@ -82,10 +83,10 @@ $string['phpversionhelp'] = '<p>무들은 적어도 PHP4.3.0 혹은 5.1.0. 이
 <p>PHP를 업그레이드 하시거나 새버전을 제공하는 웹호스팅 업체로 이전하기를 권합니다!<br />(만일 5.0.x버전을 사용 중이라면 4.4.x 버전으로 다운그레이드 할 수 있습니다)</p>';
 $string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
 $string['welcomep20'] = '당신의 컴퓨터에 <strong>{$a->packname} {$a->packversion}</strong> 패키지를 성공적으로 설치한 것을 축하합니다!';
-$string['welcomep30'] = '<strong>{$a->installername}</strong> 의 이 릴리스는 <strong>무들</strong>이 그 속에서 동작하는 환경을 생성하기 위한 어플리케이션을 포함하고 있습니다.';
+$string['welcomep30'] = '<strong>{$a->installername}</strong> 판본은 <strong>무들</strong>이 동작하는 환경을 생성하기 위한 어플리케이션을 포함하고 있습니다.';
 $string['welcomep40'] = '이 패키지는 <strong>무들 {$a->moodlerelease} ({$a->moodleversion})</strong> 을 포함하고 있습니다.';
 $string['welcomep50'] = '이 패키지에 있는 모든 어플리케이션을 사용하는 것은 각각의 라이센스에의해 지배받습니다. 완전한<strong>{$a->installername}</strong> 패키지는
 <a href="http://www.opensource.org/docs/definition_plain.html">공개 소스이며 </a> <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> 라이선스에 의해 배포됩니다.';
-$string['welcomep60'] = '다음 페이지들은 당신의 컴퓨터에 <strong>무들</strong>을 설정하고 설치하는 길라잡이 역할을 할 것입니다. 기본 설정을 선택하거나 목적에 맞게 선택적으로 수정할 수 있습니다.';
+$string['welcomep60'] = '다음 페이지들은 컴퓨터에 <strong>무들</strong>을 설치하고 설정하는 길라잡이 역할을 할 것입니다. 기본 설정을 선택하거나 목적에 맞게 선택적으로 수정할 수 있습니다.';
 $string['welcomep70'] = '<strong>무들</strong> 설정을 계속하기 위해서는 "다음" 버튼을 클릭하세요.';
 $string['wwwroot'] = '웹 주소';
index 7f8972a..9f62c29 100644 (file)
@@ -68,7 +68,7 @@ $string['availablelicenses'] = 'Available licences';
 $string['backgroundcolour'] = 'Transparent colour';
 $string['backups'] = 'Backups';
 $string['backup_shortname'] = 'Use course name in backup filename';
-$string['backup_shortnamehelp'] = 'Use the course name as part of the backup filename instead of the course id number.';
+$string['backup_shortnamehelp'] = 'Use the course name as part of the backup filename.';
 $string['badwordsconfig'] = 'Enter your list of bad words separated by commas.';
 $string['badwordsdefault'] = 'If the custom list is empty, a default list from the language pack will be used.';
 $string['badwordslist'] = 'Custom bad words list';
@@ -283,6 +283,7 @@ $string['configrcache'] = 'Use the cache to store database records. Remember to
 $string['configrcachettl'] = 'Time-to-live for cached records, in seconds. Use a short (&lt;15) value here.';
 $string['configrecaptchaprivatekey'] = 'String of characters used to communicate between your Moodle server and the recaptcha server. Obtain one for this site by visiting http://www.google.com/recaptcha';
 $string['configrecaptchapublickey'] = 'String of characters used to display the reCAPTCHA element in the signup form. Generated by http://www.google.com/recaptcha';
+$string['configrequestcategoryselection'] = 'Allow the selection of a category when requesting a course.';
 $string['configrequestedstudentname'] = 'Word for student used in requested courses';
 $string['configrequestedstudentsname'] = 'Word for students used in requested courses';
 $string['configrequestedteachername'] = 'Word for teacher used in requested courses';
@@ -871,6 +872,7 @@ $string['requires'] = 'Requires';
 $string['purgecaches']= 'Purge all caches';
 $string['purgecachesconfirm']= 'Moodle can cache themes, javascript, language strings, filtered text, rss feeds and many other pieces of calculated data.  Purging these caches will delete that data from the server and force browsers to refetch data, so that you can be sure you are seeing the most up-to-date values produced by the current code.  There is no danger in purging caches, but your site may appear slower for a while until the server and clients calculate new information and cache it.';
 $string['purgecachesfinished']= 'All caches were purged.';
+$string['requestcategoryselection'] = 'Enable category selection';
 $string['restorernewroleid'] = 'Restorers\' role in courses';
 $string['restorernewroleid_help'] = 'If the user does not already have the permission to manage the newly restored course, the user is automatically assigned this role and enrolled if necessary. Select "None" if you do not want restorers to be able to manage every restored course.';
 $string['reverseproxy'] = 'Reverse proxy';
index 5fde19e..e053c96 100644 (file)
@@ -163,6 +163,7 @@ $string['lockedbypermission'] = 'You don\'t have sufficient permissions to chang
 $string['lockedbyconfig'] = 'This setting has been locked by the default backup settings';
 $string['lockedbyhierarchy'] = 'Locked by dependencies';
 $string['managefiles'] = 'Manage backup files';
+$string['missingfilesinpool'] = 'Some files could not be saved during the backup, it won\'t be possible to restore them.';
 $string['moodleversion'] = 'Moodle version';
 $string['moreresults'] = 'There are too many results, enter a more specific search.';
 $string['nomatchingcourses'] = 'There are no courses to display';
@@ -177,6 +178,7 @@ $string['restoreactivity'] = 'Restore activity';
 $string['restorecourse'] = 'Restore course';
 $string['restorecoursesettings'] = 'Course settings';
 $string['restoreexecutionsuccess'] = 'The course was restored successfully, clicking the continue button below will take you to view the course you restored.';
+$string['restorefileweremissing'] = 'Some files could not be restored because they were missing in the backup.';
 $string['restorenewcoursefullname'] = 'New course name';
 $string['restorenewcourseshortname'] = 'New course short name';
 $string['restorenewcoursestartdate'] = 'New start date';
index c0b8f01..a685f0e 100644 (file)
@@ -37,6 +37,8 @@ $string['defaultregion'] = 'Default region';
 $string['defaultregion_help'] = 'Themes may define one or more named block regions where blocks are displayed. This setting defines which of these you want this block to appear in by default. The region may be overridden on specific pages if required.';
 $string['defaultweight'] = 'Default weight';
 $string['defaultweight_help'] = 'The default weight allows you to choose roughly where you want the block to appear in the chosen region, either at the top or the bottom. The final location is calculated from all the blocks in that region (for example, only one block can actually be at the top). This value can be overridden on specific pages if required.';
+$string['deletecheck'] = 'Delete {$a} block?';
+$string['deleteblockcheck'] = 'Are you sure that you want to delete this block titled {$a}?';
 $string['moveblockhere'] = 'Move block here';
 $string['movingthisblockcancel'] = 'Moving this block ({$a})';
 $string['onthispage'] = 'On this page';
index dd0b7b4..3f1cc5f 100644 (file)
@@ -59,7 +59,7 @@ $string['eventduration'] = 'Duration';
 $string['eventendtime'] = 'End time';
 $string['eventinstanttime'] = 'Time';
 $string['eventkind'] = 'Type of event';
-$string['eventname'] = 'Name';
+$string['eventname'] = 'Event title';
 $string['eventnone'] = 'No events';
 $string['eventrepeat'] = 'Repeats';
 $string['eventsall'] = 'All events';
index 2fc4fac..ba2def6 100644 (file)
@@ -363,6 +363,7 @@ $string['createaccount'] = 'Create my new account';
 $string['createcategory'] = 'Create category';
 $string['createfolder'] = 'Create a folder in {$a}';
 $string['createuserandpass'] = 'Choose your username and password';
+$string['createuser'] = 'Create user';
 $string['createziparchive'] = 'Create zip archive';
 $string['creatingblocks'] = 'Creating blocks';
 $string['creatingblocksroles'] = 'Creating block level role assignments and overrides';
@@ -1670,6 +1671,7 @@ $string['theme'] = 'Theme';
 $string['themes'] = 'Themes';
 $string['themesaved'] = 'New theme saved';
 $string['thereareno'] = 'There are no {$a} in this course';
+$string['therearecourses'] = 'There are {$a} courses';
 $string['thiscategorycontains'] = 'This category contains';
 $string['time'] = 'Time';
 $string['timezone'] = 'Timezone';
@@ -1802,6 +1804,7 @@ $string['virusfounduser'] = 'The file you have uploaded, {$a->filename}, has bee
 $string['virusplaceholder'] = 'This file that has been uploaded was found to contain a virus and has been moved or deleted and the user notified.';
 $string['visible'] = 'Visible';
 $string['visibletostudents'] = 'Visible to {$a}';
+$string['warning'] = 'Warning';
 $string['warningdeleteresource'] = 'Warning: {$a} is referred in a resource. Would you like to update the resource?';
 $string['webpage'] = 'Web page';
 $string['week'] = 'Week';
index 5230863..2163435 100644 (file)
@@ -6676,7 +6676,7 @@ class context_module extends context {
                     if ($withprefix){
                         $name = get_string('modulename', $cm->modname).': ';
                     }
-                    $name .= $mod->name;
+                    $name .= format_string($mod->name, true, array('context' => $this));
                 }
             }
         return $name;
index 8ee900a..1bc2a43 100644 (file)
@@ -6377,9 +6377,8 @@ function format_admin_setting($setting, $title='', $form='', $description='', $l
     $str = '
 <div class="form-item clearfix" id="admin-'.$setting->name.'">
   <div class="form-label">
-    <label '.$labelfor.'>'.highlightfast($query, $title).'<span class="form-shortname">'.highlightfast($query, $name).'</span>
-      '.$override.$warning.'
-    </label>
+    <label '.$labelfor.'>'.highlightfast($query, $title).$override.$warning.'</label>
+    <span class="form-shortname">'.highlightfast($query, $name).'</span>
   </div>
   <div class="form-setting">'.$form.$defaultinfo.'</div>
   <div class="form-description">'.highlight($query, markdown_to_html($description)).'</div>
index bf20639..9ea8175 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-@version V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+@version V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Latest version is available at http://adodb.sourceforge.net
  
   Released under both BSD license and Lesser GPL library license. 
index 8cfb91f..4165715 100644 (file)
@@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1;
 
 /* 
 
-  V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
index e0a7940..45dab49 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 1847838..9de38b9 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license. 
  * Whenever there is any discrepancy between the two licenses, 
  * the BSD license will take precedence. 
index cdec610..948c7c4 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
index f47a241..aec991f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 40ca3bb..b00ae54 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @version V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
index e45882c..d774ea7 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 780d2dc..28969f0 100644 (file)
@@ -6,7 +6,7 @@ global $ADODB_INCLUDED_LIB;
 $ADODB_INCLUDED_LIB = 1;
 
 /* 
-  @version V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  @version V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
index 906c55a..77a6fae 100644 (file)
@@ -11,7 +11,7 @@ if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
 
 /* 
 
-  V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
index 39a8fdc..ab2026b 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-       V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+       V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
          Released under both BSD license and Lesser GPL library license. 
          Whenever there is any discrepancy between the two licenses, 
          the BSD license will take precedence. 
index 4009aa5..9b26d0c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license. 
  * Whenever there is any discrepancy between the two licenses, 
  * the BSD license will take precedence. 
index 7c34e96..8d0e40a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
index bb58207..897ba75 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 8207f5e..af89cf5 100644 (file)
@@ -14,7 +14,7 @@
 /**
        \mainpage
        
-        @version V5.16 26 Mar 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+        @version V5.17 17 May 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
 
        Released under both BSD license and Lesser GPL library license. You can choose which license
        you prefer.
                /**
                 * ADODB version as a string.
                 */
-               $ADODB_vers = 'V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.';
+               $ADODB_vers = 'V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.';
        
                /**
                 * Determines whether recordset->RecordCount() is used. 
@@ -3499,23 +3499,22 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
    *
    * $upper  0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField
    */
-       function GetRowAssoc($upper=1)
+       function GetRowAssoc($upper=1) 
        {
                $record = array();
-        //     if (!$this->fields) return $record;
-               
-               if (!$this->bind) {
+               if (!$this->bind) {
                        $this->GetAssocKeys($upper);
                }
-               
                foreach($this->bind as $k => $v) {
-                       $record[$k] = $this->fields[$v];
+                       if( isset( $this->fields[$v] ) ) {
+                               $record[$k] = $this->fields[$v];
+                       } else if (isset($this->fields[$k])) {
+                               $record[$k] = $this->fields[$k];
+                       }
                }
-
                return $record;
        }
        
-       
        /**
         * Clean up recordset
         *
index f5685f3..c9efb1f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. See License.txt. 
index 8a48ffd..867eb77 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index e0c90d8..7aeb0c5 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 77892ed..6a8ebdf 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
 Released under both BSD license and Lesser GPL library license. 
 Whenever there is any discrepancy between the two licenses, 
 the BSD license will take precedence. See License.txt. 
index dd59a67..96108fc 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 78dbfe3..ea9a521 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 2fb03d0..8f221e0 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 9974a6d..f072d5a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-  V5.16 26 Mar 2012  (c) 2000-2012 (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012  (c) 2000-2012 (jlim#natsoft.com). All rights reserved.
 
   This is a version of the ADODB driver for DB2.  It uses the 'ibm_db2' PECL extension
   for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
index 8d92b43..cf8d0b3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 38953d1..8f699a1 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index a95ed7a..ef08310 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- @version V5.16 26 Mar 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ @version V5.17 17 May 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 86b6b97..2104159 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 6f2801b..f05a98d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.  
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.  
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index a0f17e5..18ed5ff 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version V5.16 26 Mar 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+* @version V5.17 17 May 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
 * Released under both BSD license and Lesser GPL library license.
 * Whenever there is any discrepancy between the two licenses,
 * the BSD license will take precedence.
index a469a17..0346dcf 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim. All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim. All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
index 2a1e478..79884c9 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
    Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 80742cd..c32cf3d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
index 24e33d2..084c1dc 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence. 
@@ -130,6 +130,7 @@ class ADODB_mssqlnative extends ADOConnection {
        var $uniqueOrderBy = true;
        var $_bindInputArray = true;
        var $_dropSeqSQL = "drop table %s";
+       var $connectionInfo = array();
        
        function ADODB_mssqlnative() 
        {               
@@ -378,7 +379,10 @@ class ADODB_mssqlnative extends ADOConnection {
        function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
        {
                if (!function_exists('sqlsrv_connect')) return null;
-        $connectionInfo = array("Database"=>$argDatabasename,'UID'=>$argUsername,'PWD'=>$argPassword);
+               $connectionInfo = $this->connectionInfo;
+               $connectionInfo["Database"]=$argDatabasename;
+               $connectionInfo["UID"]=$argUsername;
+               $connectionInfo["PWD"]=$argPassword;
         if ($this->debug) error_log("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
         //if ($this->debug) error_log("<hr>_connectionID before: ".serialize($this->_connectionID));
         if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) { 
index 76dfe24..60bc9c7 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version V5.16 26 Mar 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+* @version V5.17 17 May 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
 * Released under both BSD license and Lesser GPL library license.
 * Whenever there is any discrepancy between the two licenses,
 * the BSD license will take precedence.
index 8849559..47fa00f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
@@ -36,6 +36,7 @@ class ADODB_mysql extends ADOConnection {
        var $forceNewConnect = false;
        var $poorAffectedRows = true;
        var $clientFlags = 0;
+       var $charSet = '';
        var $substr = "substring";
        var $nameQuote = '`';           /// string to use to quote identifiers and names
        var $compat323 = false;                 // true if compat with mysql 3.23
@@ -44,7 +45,25 @@ class ADODB_mysql extends ADOConnection {
        {                       
                if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
        }
-       
+
+
+  // SetCharSet - switch the client encoding
+  function SetCharSet($charset_name)
+  {
+    if (!function_exists('mysql_set_charset'))
+       return false;
+
+    if ($this->charSet !== $charset_name) {
+      $ok = @mysql_set_charset($charset_name,$this->_connectionID);
+      if ($ok) {
+               $this->charSet = $charset_name;
+        return true;
+      }
+         return false;
+    }
+       return true;
+  }
+  
        function ServerInfo()
        {
                $arr['description'] = ADOConnection::GetOne("select version()");
index b1d5d4d..bb556a1 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 5517656..ad008a1 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 424b173..923147a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
index 7f0280e..0a0e97f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.17 17 May 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  
   First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com
  Based on the previous postgres drivers.
index 4574b3e..eefc3e1 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-  version V5.16 26 Mar 2012 (c) 2000-2012 John Lim. All rights reserved.
+  version V5.17 17 May 2012 (c) 2000-2012 John Lim. All rights reserved.
 
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
@@ -88,7 +88,7 @@ END;
        var $connectSID = false;
        var $_bind = false;
        var $_nestedSQL = true;
-       var $_hasOCIFetchStatement = false;
+       var $_hasOciFetchStatement = false;
        var $_getarray = false; // currently not working
        var $leftOuter = '';  // oracle wierdness, $col = $value (+) for LEFT OUTER, $col (+)= $value for RIGHT OUTER
        var $session_sharing_force_blob = false; // alter session on updateblob if set to true 
@@ -104,7 +104,7 @@ END;
     
        function ADODB_oci8() 
        {
-               $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
+               $this->_hasOciFetchStatement = ADODB_PHPVER >= 0x4200;
                if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
        }
        
@@ -201,7 +201,7 @@ NATSOFT.DOMAIN =
 */
        function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode=0)
        {
-               if (!function_exists('OCIPLogon')) return null;
+               if (!function_exists('oci_pconnect')) return null;
                #adodb_backtrace(); 
                
         $this->_errorMsg = false;
@@ -235,22 +235,22 @@ NATSOFT.DOMAIN =
                //if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
                if ($mode==1) {
                        $this->_connectionID = ($this->charSet) ? 
-                               OCIPLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
+                               oci_pconnect($argUsername,$argPassword, $argDatabasename,$this->charSet)
                                :
-                               OCIPLogon($argUsername,$argPassword, $argDatabasename)
+                               oci_pconnect($argUsername,$argPassword, $argDatabasename)
                                ;
-                       if ($this->_connectionID && $this->autoRollback)  OCIrollback($this->_connectionID);
+                       if ($this->_connectionID && $this->autoRollback)  oci_rollback($this->_connectionID);
                } else if ($mode==2) {
                        $this->_connectionID = ($this->charSet) ? 
-                               OCINLogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
+                               oci_new_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
                                :
-                               OCINLogon($argUsername,$argPassword, $argDatabasename);
+                               oci_new_connect($argUsername,$argPassword, $argDatabasename);
                                
                } else {
                        $this->_connectionID = ($this->charSet) ? 
-                               OCILogon($argUsername,$argPassword, $argDatabasename,$this->charSet)
+                               oci_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
                                :
-                               OCILogon($argUsername,$argPassword, $argDatabasename);
+                               oci_connect($argUsername,$argPassword, $argDatabasename);
                }
                if (!$this->_connectionID) return false;
                if ($this->_initdate) {
@@ -259,7 +259,7 @@ NATSOFT.DOMAIN =
                
                // looks like: 
                // Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production With the Partitioning option JServer Release 8.1.7.0.0 - Production
-               // $vers = OCIServerVersion($this->_connectionID);
+               // $vers = oci_server_version($this->_connectionID);
                // if (strpos($vers,'8i') !== false) $this->ansiOuter = true;
                return true;
        }
@@ -267,7 +267,7 @@ NATSOFT.DOMAIN =
        function ServerInfo()
        {
                $arr['compat'] = $this->GetOne('select value from sys.database_compatible_level');
-               $arr['description'] = @OCIServerVersion($this->_connectionID);
+               $arr['description'] = @oci_server_version($this->_connectionID);
                $arr['version'] = ADOConnection::_findvers($arr['description']);
                return $arr;
        }
@@ -285,7 +285,7 @@ NATSOFT.DOMAIN =
        
        function _affectedrows()
        {
-               if (is_resource($this->_stmt)) return @OCIRowCount($this->_stmt);
+               if (is_resource($this->_stmt)) return @oci_num_rows($this->_stmt);
                return 0;
        }
        
@@ -386,6 +386,13 @@ NATSOFT.DOMAIN =
 
                $false = false;
                $rs = $this->Execute(sprintf("SELECT * FROM ALL_CONSTRAINTS WHERE UPPER(TABLE_NAME)='%s' AND CONSTRAINT_TYPE='P'",$table));
+               if (!is_object($rs)) {
+                       if (isset($savem)) 
+                               $this->SetFetchMode($savem);
+                       $ADODB_FETCH_MODE = $save;
+            return $false;
+        }
+               
                if ($row = $rs->FetchRow())
                   $primary_key = $row[1]; //constraint_name
 
@@ -451,7 +458,7 @@ NATSOFT.DOMAIN =
                if (!$ok) return $this->RollbackTrans();
                
                if ($this->transCnt) $this->transCnt -= 1;
-               $ret = OCIcommit($this->_connectionID);
+               $ret = oci_commit($this->_connectionID);
                $this->_commit = OCI_COMMIT_ON_SUCCESS;
                $this->autoCommit = true;
                return $ret;
@@ -461,7 +468,7 @@ NATSOFT.DOMAIN =
        {
                if ($this->transOff) return true;
                if ($this->transCnt) $this->transCnt -= 1;
-               $ret = OCIrollback($this->_connectionID);
+               $ret = oci_rollback($this->_connectionID);
                $this->_commit = OCI_COMMIT_ON_SUCCESS;
                $this->autoCommit = true;
                return $ret;
@@ -477,10 +484,10 @@ NATSOFT.DOMAIN =
        {
                if ($this->_errorMsg !== false) return $this->_errorMsg;
 
-               if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
+               if (is_resource($this->_stmt)) $arr = @oci_error($this->_stmt);
                if (empty($arr)) {
-                       if (is_resource($this->_connectionID)) $arr = @OCIError($this->_connectionID);
-                       else $arr = @OCIError();
+                       if (is_resource($this->_connectionID)) $arr = @oci_error($this->_connectionID);
+                       else $arr = @oci_error();
                        if ($arr === false) return '';
                }
                $this->_errorMsg = $arr['message'];
@@ -492,10 +499,10 @@ NATSOFT.DOMAIN =
        {
                if ($this->_errorCode !== false) return $this->_errorCode;
                
-               if (is_resource($this->_stmt)) $arr = @OCIError($this->_stmt);
+               if (is_resource($this->_stmt)) $arr = @oci_error($this->_stmt);
                if (empty($arr)) {
-                       $arr = @OCIError($this->_connectionID);
-                       if ($arr == false) $arr = @OCIError();
+                       $arr = @oci_error($this->_connectionID);
+                       if ($arr == false) $arr = @oci_error();
                        if ($arr == false) return '';
                }
                
@@ -651,34 +658,34 @@ NATSOFT.DOMAIN =
                                foreach($inputarr as $k => $v) {
                                        if (is_array($v)) {
                                                if (sizeof($v) == 2) // suggested by g.giunta@libero.
-                                                       OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
+                                                       oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1]);
                                                else
-                                                       OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
+                                                       oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
                                        } else {
                                                $len = -1;
                                                if ($v === ' ') $len = 1;
-                                               if (isset($bindarr)) {  // is prepared sql, so no need to ocibindbyname again
+                                               if (isset($bindarr)) {  // is prepared sql, so no need to oci_bind_by_name again
                                                        $bindarr[$k] = $v;
                                                } else {                                // dynamic sql, so rebind every time
-                                                       OCIBindByName($stmt,":$k",$inputarr[$k],$len);
+                                                       oci_bind_by_name($stmt,":$k",$inputarr[$k],$len);
                                                        
                                                }
                                        }
                                }
                        }
                        
-                        if (!OCIExecute($stmt, OCI_DEFAULT)) {
-                                OCIFreeStatement($stmt); 
+                        if (!oci_execute($stmt, OCI_DEFAULT)) {
+                                oci_free_statement($stmt); 
                                 return $false;
                         }
                         
-                        $ncols = OCINumCols($stmt);
+                        $ncols = oci_num_fields($stmt);
                         for ( $i = 1; $i <= $ncols; $i++ ) {
-                                $cols[] = '"'.OCIColumnName($stmt, $i).'"';
+                                $cols[] = '"'.oci_field_name($stmt, $i).'"';
                         }
                         $result = false;
                        
-                        OCIFreeStatement($stmt); 
+                        oci_free_statement($stmt); 
                         $fields = implode(',', $cols);
                         if ($nrows <= 0) $nrows = 999999999999;
                         else $nrows += $offset;
@@ -741,7 +748,7 @@ NATSOFT.DOMAIN =
                else 
                        $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
                
-               $desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
+               $desc = oci_new_descriptor($this->_connectionID, OCI_D_LOB);
                $arr['blob'] = array($desc,-1,$type);
                if ($this->session_sharing_force_blob) $this->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
                $commit = $this->autoCommit;
@@ -772,7 +779,7 @@ NATSOFT.DOMAIN =
                else 
                        $sql = "UPDATE $table set $column=EMPTY_{$blobtype}() WHERE $where RETURNING $column INTO :blob";
                
-               $desc = OCINewDescriptor($this->_connectionID, OCI_D_LOB);
+               $desc = oci_new_descriptor($this->_connectionID, OCI_D_LOB);
                $arr['blob'] = array($desc,-1,$type);
                
                $this->BeginTrans();
@@ -873,12 +880,12 @@ NATSOFT.DOMAIN =
        {
        static $BINDNUM = 0;
        
-               $stmt = OCIParse($this->_connectionID,$sql);
+               $stmt = oci_parse($this->_connectionID,$sql);
 
                if (!$stmt) {
                        $this->_errorMsg = false;
                        $this->_errorCode = false;
-                       $arr = @OCIError($this->_connectionID);
+                       $arr = @oci_error($this->_connectionID);
                        if ($arr === false) return false;
                
                        $this->_errorMsg = $arr['message'];
@@ -888,9 +895,9 @@ NATSOFT.DOMAIN =
                
                $BINDNUM += 1;
                
-               $sttype = @OCIStatementType($stmt);
+               $sttype = @oci_statement_type($stmt);
                if ($sttype == 'BEGIN' || $sttype == 'DECLARE') {
-                       return array($sql,$stmt,0,$BINDNUM, ($cursor) ? OCINewCursor($this->_connectionID) : false);
+                       return array($sql,$stmt,0,$BINDNUM, ($cursor) ? oci_new_cursor($this->_connectionID) : false);
                }
                return array($sql,$stmt,0,$BINDNUM);
        }
@@ -912,7 +919,7 @@ NATSOFT.DOMAIN =
        function ExecuteCursor($sql,$cursorName='rs',$params=false)
        {
                if (is_array($sql)) $stmt = $sql;
-               else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
+               else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate oci_new_cursor
        
                if (is_array($stmt) && sizeof($stmt) >= 5) {
                        $hasref = true;
@@ -928,7 +935,7 @@ NATSOFT.DOMAIN =
                        
                $rs = $this->Execute($stmt);
                if ($rs) {
-                       if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
+                       if ($rs->databaseType == 'array') oci_free_cursor($stmt[4]);
                        else if ($hasref) $rs->_refcursor = $stmt[4];
                }
                return $rs;
@@ -955,13 +962,13 @@ NATSOFT.DOMAIN =
                        
                Some timings:           
                        ** Test table has 3 cols, and 1 index. Test to insert 1000 records
-                       Time 0.6081s (1644.60 inserts/sec) with direct OCIParse/OCIExecute
+                       Time 0.6081s (1644.60 inserts/sec) with direct oci_parse/oci_execute
                        Time 0.6341s (1577.16 inserts/sec) with ADOdb Prepare/Bind/Execute
                        Time 1.5533s ( 643.77 inserts/sec) with pure SQL using Execute
                        
                Now if PHP only had batch/bulk updating like Java or PL/SQL...
        
-               Note that the order of parameters differs from OCIBindByName,
+               Note that the order of parameters differs from oci_bind_by_name,
                because we default the names to :0, :1, :2
        */
        function Bind(&$stmt,&$var,$size=4000,$type=false,$name=false,$isOutput=false)
@@ -970,12 +977,12 @@ NATSOFT.DOMAIN =
                if (!is_array($stmt)) return false;
         
         if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) { 
-            return OCIBindByName($stmt[1],":".$name,$stmt[4],$size,$type);
+            return oci_bind_by_name($stmt[1],":".$name,$stmt[4],$size,$type);
         }
         
                if ($name == false) {
-                       if ($type !== false) $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size,$type);
-                       else $rez = OCIBindByName($stmt[1],":".$stmt[2],$var,$size); // +1 byte for null terminator
+                       if ($type !== false) $rez = oci_bind_by_name($stmt[1],":".$stmt[2],$var,$size,$type);
+                       else $rez = oci_bind_by_name($stmt[1],":".$stmt[2],$var,$size); // +1 byte for null terminator
                        $stmt[2] += 1;
                } else if (oci_lob_desc($type)) {
                        if ($this->debug) {
@@ -983,11 +990,11 @@ NATSOFT.DOMAIN =
                        }
             //we have to create a new Descriptor here
                        $numlob = count($this->_refLOBs);
-               $this->_refLOBs[$numlob]['LOB'] = OCINewDescriptor($this->_connectionID, oci_lob_desc($type));
+               $this->_refLOBs[$numlob]['LOB'] = oci_new_descriptor($this->_connectionID, oci_lob_desc($type));
                        $this->_refLOBs[$numlob]['TYPE'] = $isOutput;
                        
                        $tmp = $this->_refLOBs[$numlob]['LOB'];
-               $rez = OCIBindByName($stmt[1], ":".$name, $tmp, -1, $type);
+               $rez = oci_bind_by_name($stmt[1], ":".$name, $tmp, -1, $type);
                        if ($this->debug) {
                                ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
                        }
@@ -1008,8 +1015,8 @@ NATSOFT.DOMAIN =
                        if ($this->debug) 
                                ADOConnection::outp("<b>Bind</b>: name = $name");
                        
-                       if ($type !== false) $rez = OCIBindByName($stmt[1],":".$name,$var,$size,$type);
-                       else $rez = OCIBindByName($stmt[1],":".$name,$var,$size); // +1 byte for null terminator
+                       if ($type !== false) $rez = oci_bind_by_name($stmt[1],":".$name,$var,$size,$type);
+                       else $rez = oci_bind_by_name($stmt[1],":".$name,$var,$size); // +1 byte for null terminator
                }
                
                return $rez;
@@ -1034,7 +1041,7 @@ NATSOFT.DOMAIN =
                @param [$maxLen] Holds an maximum length of the variable.
                @param [$type] The data type of $var. Legal values depend on driver.
                
-               See OCIBindByName documentation at php.net.
+               See oci_bind_by_name documentation at php.net.
        */
        function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
        {
@@ -1066,7 +1073,7 @@ NATSOFT.DOMAIN =
                if (is_array($sql)) { // is prepared sql
                        $stmt = $sql[1];
                        
-                       // we try to bind to permanent array, so that OCIBindByName is persistent
+                       // we try to bind to permanent array, so that oci_bind_by_name is persistent
                        // and carried out once only - note that max array element size is 4000 chars
                        if (is_array($inputarr)) {
                                $bindpos = $sql[3];
@@ -1078,27 +1085,27 @@ NATSOFT.DOMAIN =
                                        $bindarr = array();
                                        foreach($inputarr as $k => $v) {
                                                $bindarr[$k] = $v;
-                                               OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
+                                               oci_bind_by_name($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
                                        }
                                        $this->_bind[$bindpos] = $bindarr;
                                }
                        }
                } else {
-                       $stmt=OCIParse($this->_connectionID,$sql);
+                       $stmt=oci_parse($this->_connectionID,$sql);
                }
                        
                $this->_stmt = $stmt;
                if (!$stmt) return false;
        
-               if (defined('ADODB_PREFETCH_ROWS')) @OCISetPrefetch($stmt,ADODB_PREFETCH_ROWS);
+               if (defined('ADODB_PREFETCH_ROWS')) @oci_set_prefetch($stmt,ADODB_PREFETCH_ROWS);
                        
                if (is_array($inputarr)) {
                        foreach($inputarr as $k => $v) {
                                if (is_array($v)) {
                                        if (sizeof($v) == 2) // suggested by g.giunta@libero.
-                                               OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
+                                               oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1]);
                                        else
-                                               OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
+                                               oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
                                        
                                        if ($this->debug==99) {
                                                if (is_object($v[0])) 
@@ -1110,10 +1117,10 @@ NATSOFT.DOMAIN =
                                } else {
                                        $len = -1;
                                        if ($v === ' ') $len = 1;
-                                       if (isset($bindarr)) {  // is prepared sql, so no need to ocibindbyname again
+                                       if (isset($bindarr)) {  // is prepared sql, so no need to oci_bind_by_name again
                                                $bindarr[$k] = $v;
                                        } else {                                // dynamic sql, so rebind every time
-                                               OCIBindByName($stmt,":$k",$inputarr[$k],$len);
+                                               oci_bind_by_name($stmt,":$k",$inputarr[$k],$len);
                                        }
                                }
                        }
@@ -1121,8 +1128,8 @@ NATSOFT.DOMAIN =
                
         $this->_errorMsg = false;
                $this->_errorCode = false;
-               if (OCIExecute($stmt,$this->_commit)) {
-//OCIInternalDebug(1);                 
+               if (oci_execute($stmt,$this->_commit)) {
+                       
                        if (count($this -> _refLOBs) > 0) {
                
                                foreach ($this -> _refLOBs as $key => $value) {
@@ -1144,7 +1151,7 @@ NATSOFT.DOMAIN =
                                }
                        }
                
-            switch (@OCIStatementType($stmt)) {
+            switch (@oci_statement_type($stmt)) {
                 case "SELECT":
                                        return $stmt;
                                
@@ -1153,20 +1160,20 @@ NATSOFT.DOMAIN =
                     if (is_array($sql) && !empty($sql[4])) {
                                                $cursor = $sql[4];
                                                if (is_resource($cursor)) {
-                                                       $ok = OCIExecute($cursor);      
+                                                       $ok = oci_execute($cursor);     
                                return $cursor;
                                                }
                                                return $stmt;
                     } else {
                                                if (is_resource($stmt)) {
-                                                       OCIFreeStatement($stmt);
+                                                       oci_free_statement($stmt);
                                                        return true;
                                                }
                         return $stmt;
                     }
                     break;
                 default :
-                                       // ociclose -- no because it could be used in a LOB?
+                                       
                     return true;
             }
                }
@@ -1204,14 +1211,14 @@ NATSOFT.DOMAIN =
        {
                if (!$this->_connectionID) return;
                
-               if (!$this->autoCommit) OCIRollback($this->_connectionID);
+               if (!$this->autoCommit) oci_rollback($this->_connectionID);
                if (count($this->_refLOBs) > 0) {
                        foreach ($this ->_refLOBs as $key => $value) {
                                $this->_refLOBs[$key]['LOB']->free();
                                unset($this->_refLOBs[$key]);
                        }
                }
-               OCILogoff($this->_connectionID);
+               oci_close($this->_connectionID);
                
                $this->_stmt = false;
                $this->_connectionID = false;
@@ -1383,7 +1390,7 @@ class ADORecordset_oci8 extends ADORecordSet {
                        /*
                        // based on idea by Gaetano Giunta to detect unusual oracle errors
                        // see http://phplens.com/lens/lensforum/msgs.php?id=6771
-                       $err = OCIError($this->_queryID);
+                       $err = oci_error($this->_queryID);
                        if ($err && $this->connection->debug) ADOConnection::outp($err);
                        */
                        
@@ -1402,7 +1409,7 @@ class ADORecordset_oci8 extends ADORecordSet {
        function _initrs()
        {
                $this->_numOfRows = -1;
-               $this->_numOfFields = OCInumcols($this->_queryID);
+               $this->_numOfFields = oci_num_fields($this->_queryID);
                if ($this->_numOfFields>0) {
                        $this->_fieldobjs = array();
                        $max = $this->_numOfFields;
@@ -1419,13 +1426,13 @@ class ADORecordset_oci8 extends ADORecordSet {
        {
                $fld = new ADOFieldObject;
                $fieldOffset += 1;
-               $fld->name =OCIcolumnname($this->_queryID, $fieldOffset);
-               $fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
-               $fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
+               $fld->name =oci_field_name($this->_queryID, $fieldOffset);
+               $fld->type = oci_field_type($this->_queryID, $fieldOffset);
+               $fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
                switch($fld->type) {
                case 'NUMBER':
-                       $p = OCIColumnPrecision($this->_queryID, $fieldOffset);
-                       $sc = OCIColumnScale($this->_queryID, $fieldOffset);
+                       $p = oci_field_precision($this->_queryID, $fieldOffset);
+                       $sc = oci_field_scale($this->_queryID, $fieldOffset);
                        if ($p != 0 && $sc == 0) $fld->type = 'INT';
                        $fld->scale = $p;
                        break;
@@ -1439,7 +1446,7 @@ class ADORecordset_oci8 extends ADORecordSet {
                return $fld;
        }
        
-       /* For some reason, OCIcolumnname fails when called after _initrs() so we cache it */
+       /* For some reason, oci_field_name fails when called after _initrs() so we cache it */
        function FetchField($fieldOffset = -1)
        {
     &