Merge branch 'MDL-25884' of git://github.com/timhunt/moodle
authorSam Hemelryk <sam@moodle.com>
Mon, 24 Jan 2011 02:20:22 +0000 (10:20 +0800)
committerSam Hemelryk <sam@moodle.com>
Mon, 24 Jan 2011 02:20:22 +0000 (10:20 +0800)
465 files changed:
admin/dbtransfer/lib.php
admin/qtypes.php
admin/settings/plugins.php
admin/uploaduser.php
admin/xmldb/index.php
blocks/course_overview/block_course_overview.php
calendar/export_execute.php
config-dist.php
course/lib.php
enrol/database/lib.php
filter/algebra/algebradebug.php
filter/tex/texdebug.php
grade/import/csv/index.php [changed mode: 0755->0644]
grade/import/grade_import_form.php [changed mode: 0755->0644]
grade/import/lib.php [changed mode: 0755->0644]
grade/report/grader/lib.php
grade/report/lib.php [changed mode: 0755->0644]
grade/report/user/index.php
grade/report/user/lib.php
grade/report/user/settings.php
grade/report/user/styles.css
group/assign.php
install/lang/lv/install.php
install/lang/pt_br/install.php
install/lang/ta_lk/install.php
lang/en/grades.php [changed mode: 0755->0644]
lib/ajax/getnavbranch.php
lib/db/access.php
lib/db/install.xml [changed mode: 0755->0644]
lib/db/upgrade.php
lib/dml/mysqli_native_moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/editor/tinymce/lib.php
lib/environmentlib.php
lib/moodlelib.php
lib/outputcomponents.php
lib/outputrenderers.php
lib/sessionlib.php
lib/setup.php
lib/setuplib.php
lib/simpletest/testcomponentlib.php [new file with mode: 0644]
lib/simpletest/testfilelib.php
lib/simpletest/testoutputcomponents.php
lib/simpletestlib.php
lib/yui/2.8.1/build/animation/animation-debug.js [deleted file]
lib/yui/2.8.1/build/animation/animation-min.js [deleted file]
lib/yui/2.8.1/build/animation/animation.js [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/ajax-loader.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/asc.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/autocomplete.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/back-h.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/back-v.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/bar-h.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/bar-v.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/bg-h.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/bg-v.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/blankimage.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/button.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/calendar.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/carousel.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/check0.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/check1.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/check2.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/colorpicker.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/container.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/datatable.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/desc.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/dt-arrow-dn.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/dt-arrow-up.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/editor-knob.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/editor-sprite-active.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/editor-sprite.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/editor.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/header_background.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/hue_bg.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/imagecropper.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/layout.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/layout_sprite.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/loading.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/logger.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menu-button-arrow-disabled.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menu-button-arrow.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menu.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menubaritem_submenuindicator.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menubaritem_submenuindicator_disabled.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menuitem_checkbox.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menuitem_checkbox_disabled.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menuitem_submenuindicator.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/menuitem_submenuindicator_disabled.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/paginator.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/picker_mask.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/profilerviewer.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/progressbar.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/resize.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/simpleeditor.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/skin.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/slider.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/split-button-arrow-active.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/split-button-arrow-disabled.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/split-button-arrow-focus.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/split-button-arrow-hover.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/split-button-arrow.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/sprite.png [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/sprite.psd [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/tabview.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/treeview-loading.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/treeview-sprite.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/treeview.css [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/wait.gif [deleted file]
lib/yui/2.8.1/build/assets/skins/sam/yuitest.css [deleted file]
lib/yui/2.8.1/build/autocomplete/assets/autocomplete-core.css [deleted file]
lib/yui/2.8.1/build/autocomplete/assets/skins/sam/autocomplete-skin.css [deleted file]
lib/yui/2.8.1/build/autocomplete/assets/skins/sam/autocomplete.css [deleted file]
lib/yui/2.8.1/build/autocomplete/autocomplete-debug.js [deleted file]
lib/yui/2.8.1/build/autocomplete/autocomplete-min.js [deleted file]
lib/yui/2.8.1/build/autocomplete/autocomplete.js [deleted file]
lib/yui/2.8.1/build/base/base-min.css [deleted file]
lib/yui/2.8.1/build/base/base.css [deleted file]
lib/yui/2.8.1/build/button/assets/button-core.css [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/button-skin.css [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/button.css [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/menu-button-arrow-disabled.png [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/menu-button-arrow.png [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/split-button-arrow-active.png [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/split-button-arrow-disabled.png [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/split-button-arrow-focus.png [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/split-button-arrow-hover.png [deleted file]
lib/yui/2.8.1/build/button/assets/skins/sam/split-button-arrow.png [deleted file]
lib/yui/2.8.1/build/button/button-debug.js [deleted file]
lib/yui/2.8.1/build/button/button-min.js [deleted file]
lib/yui/2.8.1/build/button/button.js [deleted file]
lib/yui/2.8.1/build/calendar/assets/calendar-core.css [deleted file]
lib/yui/2.8.1/build/calendar/assets/calendar.css [deleted file]
lib/yui/2.8.1/build/calendar/assets/calgrad.png [deleted file]
lib/yui/2.8.1/build/calendar/assets/callt.gif [deleted file]
lib/yui/2.8.1/build/calendar/assets/calrt.gif [deleted file]
lib/yui/2.8.1/build/calendar/assets/calx.gif [deleted file]
lib/yui/2.8.1/build/calendar/assets/skins/sam/calendar-skin.css [deleted file]
lib/yui/2.8.1/build/calendar/assets/skins/sam/calendar.css [deleted file]
lib/yui/2.8.1/build/calendar/calendar-debug.js [deleted file]
lib/yui/2.8.1/build/calendar/calendar-min.js [deleted file]
lib/yui/2.8.1/build/calendar/calendar.js [deleted file]
lib/yui/2.8.1/build/carousel/assets/ajax-loader.gif [deleted file]
lib/yui/2.8.1/build/carousel/assets/carousel-core.css [deleted file]
lib/yui/2.8.1/build/carousel/assets/skins/sam/ajax-loader.gif [deleted file]
lib/yui/2.8.1/build/carousel/assets/skins/sam/carousel-skin.css [deleted file]
lib/yui/2.8.1/build/carousel/assets/skins/sam/carousel.css [deleted file]
lib/yui/2.8.1/build/carousel/carousel-debug.js [deleted file]
lib/yui/2.8.1/build/carousel/carousel-min.js [deleted file]
lib/yui/2.8.1/build/carousel/carousel.js [deleted file]
lib/yui/2.8.1/build/charts/assets/charts.swf [deleted file]
lib/yui/2.8.1/build/charts/charts-debug.js [deleted file]
lib/yui/2.8.1/build/charts/charts-min.js [deleted file]
lib/yui/2.8.1/build/charts/charts.js [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/colorpicker-core.css [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/hue_thumb.png [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/picker_mask.png [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/picker_thumb.png [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/skins/sam/colorpicker-skin.css [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/skins/sam/colorpicker.css [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/skins/sam/hue_bg.png [deleted file]
lib/yui/2.8.1/build/colorpicker/assets/skins/sam/picker_mask.png [deleted file]
lib/yui/2.8.1/build/colorpicker/colorpicker-debug.js [deleted file]
lib/yui/2.8.1/build/colorpicker/colorpicker-min.js [deleted file]
lib/yui/2.8.1/build/colorpicker/colorpicker.js [deleted file]
lib/yui/2.8.1/build/connection/connection-debug.js [deleted file]
lib/yui/2.8.1/build/connection/connection-min.js [deleted file]
lib/yui/2.8.1/build/connection/connection.js [deleted file]
lib/yui/2.8.1/build/connection/connection.swf [deleted file]
lib/yui/2.8.1/build/connection/connection_core-debug.js [deleted file]
lib/yui/2.8.1/build/connection/connection_core-min.js [deleted file]
lib/yui/2.8.1/build/connection/connection_core.js [deleted file]
lib/yui/2.8.1/build/container/assets/alrt16_1.gif [deleted file]
lib/yui/2.8.1/build/container/assets/blck16_1.gif [deleted file]
lib/yui/2.8.1/build/container/assets/close12_1.gif [deleted file]
lib/yui/2.8.1/build/container/assets/container-core.css [deleted file]
lib/yui/2.8.1/build/container/assets/container.css [deleted file]
lib/yui/2.8.1/build/container/assets/hlp16_1.gif [deleted file]
lib/yui/2.8.1/build/container/assets/info16_1.gif [deleted file]
lib/yui/2.8.1/build/container/assets/skins/sam/container-skin.css [deleted file]
lib/yui/2.8.1/build/container/assets/skins/sam/container.css [deleted file]
lib/yui/2.8.1/build/container/assets/tip16_1.gif [deleted file]
lib/yui/2.8.1/build/container/assets/warn16_1.gif [deleted file]
lib/yui/2.8.1/build/container/container-debug.js [deleted file]
lib/yui/2.8.1/build/container/container-min.js [deleted file]
lib/yui/2.8.1/build/container/container.js [deleted file]
lib/yui/2.8.1/build/container/container_core-debug.js [deleted file]
lib/yui/2.8.1/build/container/container_core-min.js [deleted file]
lib/yui/2.8.1/build/container/container_core.js [deleted file]
lib/yui/2.8.1/build/cookie/cookie-debug.js [deleted file]
lib/yui/2.8.1/build/cookie/cookie-min.js [deleted file]
lib/yui/2.8.1/build/cookie/cookie.js [deleted file]
lib/yui/2.8.1/build/datasource/datasource-debug.js [deleted file]
lib/yui/2.8.1/build/datasource/datasource-min.js [deleted file]
lib/yui/2.8.1/build/datasource/datasource.js [deleted file]
lib/yui/2.8.1/build/datatable/assets/datatable-core.css [deleted file]
lib/yui/2.8.1/build/datatable/assets/datatable.css [deleted file]
lib/yui/2.8.1/build/datatable/assets/skins/sam/datatable-skin.css [deleted file]
lib/yui/2.8.1/build/datatable/assets/skins/sam/datatable.css [deleted file]
lib/yui/2.8.1/build/datatable/assets/skins/sam/dt-arrow-dn.png [deleted file]
lib/yui/2.8.1/build/datatable/assets/skins/sam/dt-arrow-up.png [deleted file]
lib/yui/2.8.1/build/datatable/datatable-debug.js [deleted file]
lib/yui/2.8.1/build/datatable/datatable-min.js [deleted file]
lib/yui/2.8.1/build/datatable/datatable.js [deleted file]
lib/yui/2.8.1/build/datemath/datemath-debug.js [deleted file]
lib/yui/2.8.1/build/datemath/datemath-min.js [deleted file]
lib/yui/2.8.1/build/datemath/datemath.js [deleted file]
lib/yui/2.8.1/build/dom/dom-debug.js [deleted file]
lib/yui/2.8.1/build/dom/dom-min.js [deleted file]
lib/yui/2.8.1/build/dom/dom.js [deleted file]
lib/yui/2.8.1/build/dragdrop/dragdrop-debug.js [deleted file]
lib/yui/2.8.1/build/dragdrop/dragdrop-min.js [deleted file]
lib/yui/2.8.1/build/dragdrop/dragdrop.js [deleted file]
lib/yui/2.8.1/build/editor/assets/editor-core.css [deleted file]
lib/yui/2.8.1/build/editor/assets/simpleeditor-core.css [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/blankimage.png [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/editor-knob.gif [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/editor-skin.css [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/editor-sprite-active.gif [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/editor-sprite.gif [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/editor.css [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/simpleeditor-skin.css [deleted file]
lib/yui/2.8.1/build/editor/assets/skins/sam/simpleeditor.css [deleted file]
lib/yui/2.8.1/build/editor/editor-debug.js [deleted file]
lib/yui/2.8.1/build/editor/editor-min.js [deleted file]
lib/yui/2.8.1/build/editor/editor.js [deleted file]
lib/yui/2.8.1/build/editor/simpleeditor-debug.js [deleted file]
lib/yui/2.8.1/build/editor/simpleeditor-min.js [deleted file]
lib/yui/2.8.1/build/editor/simpleeditor.js [deleted file]
lib/yui/2.8.1/build/element-delegate/element-delegate-debug.js [deleted file]
lib/yui/2.8.1/build/element-delegate/element-delegate-min.js [deleted file]
lib/yui/2.8.1/build/element-delegate/element-delegate.js [deleted file]
lib/yui/2.8.1/build/element/element-debug.js [deleted file]
lib/yui/2.8.1/build/element/element-min.js [deleted file]
lib/yui/2.8.1/build/element/element.js [deleted file]
lib/yui/2.8.1/build/event-delegate/event-delegate-debug.js [deleted file]
lib/yui/2.8.1/build/event-delegate/event-delegate-min.js [deleted file]
lib/yui/2.8.1/build/event-delegate/event-delegate.js [deleted file]
lib/yui/2.8.1/build/event-mouseenter/event-mouseenter-debug.js [deleted file]
lib/yui/2.8.1/build/event-mouseenter/event-mouseenter-min.js [deleted file]
lib/yui/2.8.1/build/event-mouseenter/event-mouseenter.js [deleted file]
lib/yui/2.8.1/build/event-simulate/event-simulate-debug.js [deleted file]
lib/yui/2.8.1/build/event-simulate/event-simulate-min.js [deleted file]
lib/yui/2.8.1/build/event-simulate/event-simulate.js [deleted file]
lib/yui/2.8.1/build/event/event-debug.js [deleted file]
lib/yui/2.8.1/build/event/event-min.js [deleted file]
lib/yui/2.8.1/build/event/event.js [deleted file]
lib/yui/2.8.1/build/fonts/fonts-min.css [deleted file]
lib/yui/2.8.1/build/fonts/fonts.css [deleted file]
lib/yui/2.8.1/build/get/get-debug.js [deleted file]
lib/yui/2.8.1/build/get/get-min.js [deleted file]
lib/yui/2.8.1/build/get/get.js [deleted file]
lib/yui/2.8.1/build/grids/grids-min.css [deleted file]
lib/yui/2.8.1/build/grids/grids.css [deleted file]
lib/yui/2.8.1/build/history/assets/blank.html [deleted file]
lib/yui/2.8.1/build/history/history-debug.js [deleted file]
lib/yui/2.8.1/build/history/history-min.js [deleted file]
lib/yui/2.8.1/build/history/history.js [deleted file]
lib/yui/2.8.1/build/imagecropper/assets/imagecropper-core.css [deleted file]
lib/yui/2.8.1/build/imagecropper/assets/skins/sam/imagecropper-skin.css [deleted file]
lib/yui/2.8.1/build/imagecropper/assets/skins/sam/imagecropper.css [deleted file]
lib/yui/2.8.1/build/imagecropper/imagecropper-debug.js [deleted file]
lib/yui/2.8.1/build/imagecropper/imagecropper-min.js [deleted file]
lib/yui/2.8.1/build/imagecropper/imagecropper.js [deleted file]
lib/yui/2.8.1/build/imageloader/imageloader-debug.js [deleted file]
lib/yui/2.8.1/build/imageloader/imageloader-min.js [deleted file]
lib/yui/2.8.1/build/imageloader/imageloader.js [deleted file]
lib/yui/2.8.1/build/json/json-debug.js [deleted file]
lib/yui/2.8.1/build/json/json-min.js [deleted file]
lib/yui/2.8.1/build/json/json.js [deleted file]
lib/yui/2.8.1/build/layout/assets/layout-core.css [deleted file]
lib/yui/2.8.1/build/layout/assets/skins/sam/layout-skin.css [deleted file]
lib/yui/2.8.1/build/layout/assets/skins/sam/layout.css [deleted file]
lib/yui/2.8.1/build/layout/assets/skins/sam/layout_sprite.png [deleted file]
lib/yui/2.8.1/build/layout/layout-debug.js [deleted file]
lib/yui/2.8.1/build/layout/layout-min.js [deleted file]
lib/yui/2.8.1/build/layout/layout.js [deleted file]
lib/yui/2.8.1/build/logger/assets/logger-core.css [deleted file]
lib/yui/2.8.1/build/logger/assets/logger.css [deleted file]
lib/yui/2.8.1/build/logger/assets/skins/sam/logger-skin.css [deleted file]
lib/yui/2.8.1/build/logger/assets/skins/sam/logger.css [deleted file]
lib/yui/2.8.1/build/logger/logger-debug.js [deleted file]
lib/yui/2.8.1/build/logger/logger-min.js [deleted file]
lib/yui/2.8.1/build/logger/logger.js [deleted file]
lib/yui/2.8.1/build/menu/assets/menu-core.css [deleted file]
lib/yui/2.8.1/build/menu/assets/menu.css [deleted file]
lib/yui/2.8.1/build/menu/assets/menu_down_arrow.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menu_down_arrow_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menu_up_arrow.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menu_up_arrow_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menubaritem_submenuindicator.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menubaritem_submenuindicator_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menubaritem_submenuindicator_selected.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menuitem_checkbox.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menuitem_checkbox_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menuitem_checkbox_selected.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menuitem_submenuindicator.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menuitem_submenuindicator_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/menuitem_submenuindicator_selected.png [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menu-skin.css [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menu.css [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menubaritem_submenuindicator.png [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menubaritem_submenuindicator_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menuitem_checkbox.png [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menuitem_checkbox_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menuitem_submenuindicator.png [deleted file]
lib/yui/2.8.1/build/menu/assets/skins/sam/menuitem_submenuindicator_disabled.png [deleted file]
lib/yui/2.8.1/build/menu/menu-debug.js [deleted file]
lib/yui/2.8.1/build/menu/menu-min.js [deleted file]
lib/yui/2.8.1/build/menu/menu.js [deleted file]
lib/yui/2.8.1/build/paginator/assets/paginator-core.css [deleted file]
lib/yui/2.8.1/build/paginator/assets/skins/sam/paginator-skin.css [deleted file]
lib/yui/2.8.1/build/paginator/assets/skins/sam/paginator.css [deleted file]
lib/yui/2.8.1/build/paginator/paginator-debug.js [deleted file]
lib/yui/2.8.1/build/paginator/paginator-min.js [deleted file]
lib/yui/2.8.1/build/paginator/paginator.js [deleted file]
lib/yui/2.8.1/build/profiler/profiler-debug.js [deleted file]
lib/yui/2.8.1/build/profiler/profiler-min.js [deleted file]
lib/yui/2.8.1/build/profiler/profiler.js [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/profilerviewer-core.css [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/skins/sam/asc.gif [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/skins/sam/desc.gif [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/skins/sam/header_background.png [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/skins/sam/profilerviewer-skin.css [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/skins/sam/profilerviewer.css [deleted file]
lib/yui/2.8.1/build/profilerviewer/assets/skins/sam/wait.gif [deleted file]
lib/yui/2.8.1/build/profilerviewer/profilerviewer-debug.js [deleted file]
lib/yui/2.8.1/build/profilerviewer/profilerviewer-min.js [deleted file]
lib/yui/2.8.1/build/profilerviewer/profilerviewer.js [deleted file]
lib/yui/2.8.1/build/progressbar/assets/progressbar-core.css [deleted file]
lib/yui/2.8.1/build/progressbar/assets/skins/sam/back-h.png [deleted file]
lib/yui/2.8.1/build/progressbar/assets/skins/sam/back-v.png [deleted file]
lib/yui/2.8.1/build/progressbar/assets/skins/sam/bar-h.png [deleted file]
lib/yui/2.8.1/build/progressbar/assets/skins/sam/bar-v.png [deleted file]
lib/yui/2.8.1/build/progressbar/assets/skins/sam/progressbar-skin.css [deleted file]
lib/yui/2.8.1/build/progressbar/assets/skins/sam/progressbar.css [deleted file]
lib/yui/2.8.1/build/progressbar/progressbar-debug.js [deleted file]
lib/yui/2.8.1/build/progressbar/progressbar-min.js [deleted file]
lib/yui/2.8.1/build/progressbar/progressbar.js [deleted file]
lib/yui/2.8.1/build/reset-fonts-grids/reset-fonts-grids.css [deleted file]
lib/yui/2.8.1/build/reset-fonts/reset-fonts.css [deleted file]
lib/yui/2.8.1/build/reset/reset-min.css [deleted file]
lib/yui/2.8.1/build/reset/reset.css [deleted file]
lib/yui/2.8.1/build/resize/assets/resize-core.css [deleted file]
lib/yui/2.8.1/build/resize/assets/skins/sam/layout_sprite.png [deleted file]
lib/yui/2.8.1/build/resize/assets/skins/sam/resize-skin.css [deleted file]
lib/yui/2.8.1/build/resize/assets/skins/sam/resize.css [deleted file]
lib/yui/2.8.1/build/resize/resize-debug.js [deleted file]
lib/yui/2.8.1/build/resize/resize-min.js [deleted file]
lib/yui/2.8.1/build/resize/resize.js [deleted file]
lib/yui/2.8.1/build/selector/selector-debug.js [deleted file]
lib/yui/2.8.1/build/selector/selector-min.js [deleted file]
lib/yui/2.8.1/build/selector/selector.js [deleted file]
lib/yui/2.8.1/build/slider/assets/bg-fader.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/bg-h.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/bg-v-e.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/bg-v.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/left-thumb.png [deleted file]
lib/yui/2.8.1/build/slider/assets/right-thumb.png [deleted file]
lib/yui/2.8.1/build/slider/assets/skins/sam/bg-h.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/skins/sam/bg-v.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/skins/sam/slider-skin.css [deleted file]
lib/yui/2.8.1/build/slider/assets/skins/sam/slider.css [deleted file]
lib/yui/2.8.1/build/slider/assets/slider-core.css [deleted file]
lib/yui/2.8.1/build/slider/assets/slider-skin.css [deleted file]
lib/yui/2.8.1/build/slider/assets/thumb-bar.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/thumb-e.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/thumb-fader.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/thumb-n.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/thumb-s.gif [deleted file]
lib/yui/2.8.1/build/slider/assets/thumb-w.gif [deleted file]
lib/yui/2.8.1/build/slider/slider-debug.js [deleted file]
lib/yui/2.8.1/build/slider/slider-min.js [deleted file]
lib/yui/2.8.1/build/slider/slider.js [deleted file]
lib/yui/2.8.1/build/storage/storage-debug.js [deleted file]
lib/yui/2.8.1/build/storage/storage-min.js [deleted file]
lib/yui/2.8.1/build/storage/storage.js [deleted file]
lib/yui/2.8.1/build/stylesheet/stylesheet-debug.js [deleted file]
lib/yui/2.8.1/build/stylesheet/stylesheet-min.js [deleted file]
lib/yui/2.8.1/build/stylesheet/stylesheet.js [deleted file]
lib/yui/2.8.1/build/swf/swf-debug.js [deleted file]
lib/yui/2.8.1/build/swf/swf-min.js [deleted file]
lib/yui/2.8.1/build/swf/swf.js [deleted file]
lib/yui/2.8.1/build/swfdetect/swfdetect-debug.js [deleted file]
lib/yui/2.8.1/build/swfdetect/swfdetect-min.js [deleted file]
lib/yui/2.8.1/build/swfdetect/swfdetect.js [deleted file]
lib/yui/2.8.1/build/swfstore/swf.js [deleted file]
lib/yui/2.8.1/build/swfstore/swfstore-debug.js [deleted file]
lib/yui/2.8.1/build/swfstore/swfstore-min.js [deleted file]
lib/yui/2.8.1/build/swfstore/swfstore.js [deleted file]
lib/yui/2.8.1/build/swfstore/swfstore.swf [deleted file]
lib/yui/2.8.1/build/tabview/assets/border_tabs.css [deleted file]
lib/yui/2.8.1/build/tabview/assets/loading.gif [deleted file]
lib/yui/2.8.1/build/tabview/assets/skin-sam.css [deleted file]
lib/yui/2.8.1/build/tabview/assets/skins/sam/tabview-skin.css [deleted file]
lib/yui/2.8.1/build/tabview/assets/skins/sam/tabview.css [deleted file]
lib/yui/2.8.1/build/tabview/assets/tabview-core.css [deleted file]
lib/yui/2.8.1/build/tabview/assets/tabview.css [deleted file]
lib/yui/2.8.1/build/tabview/tabview-debug.js [deleted file]
lib/yui/2.8.1/build/tabview/tabview-min.js [deleted file]
lib/yui/2.8.1/build/tabview/tabview.js [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/check0.gif [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/check1.gif [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/check2.gif [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/loading.gif [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/treeview-loading.gif [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/treeview-skin.css [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/treeview-sprite.gif [deleted file]
lib/yui/2.8.1/build/treeview/assets/skins/sam/treeview.css [deleted file]
lib/yui/2.8.1/build/treeview/assets/treeview-core.css [deleted file]
lib/yui/2.8.1/build/treeview/treeview-debug.js [deleted file]
lib/yui/2.8.1/build/treeview/treeview-min.js [deleted file]
lib/yui/2.8.1/build/treeview/treeview.js [deleted file]
lib/yui/2.8.1/build/uploader/assets/uploader.swf [deleted file]
lib/yui/2.8.1/build/uploader/uploader-debug.js [deleted file]
lib/yui/2.8.1/build/uploader/uploader-min.js [deleted file]
lib/yui/2.8.1/build/uploader/uploader.js [deleted file]
lib/yui/2.8.1/build/utilities/utilities.js [deleted file]
lib/yui/2.8.1/build/yahoo-dom-event/yahoo-dom-event.js [deleted file]
lib/yui/2.8.1/build/yahoo/yahoo-debug.js [deleted file]
lib/yui/2.8.1/build/yahoo/yahoo-min.js [deleted file]
lib/yui/2.8.1/build/yahoo/yahoo.js [deleted file]
lib/yui/2.8.1/build/yuiloader-dom-event/yuiloader-dom-event.js [deleted file]
lib/yui/2.8.1/build/yuiloader/yuiloader-debug.js [deleted file]
lib/yui/2.8.1/build/yuiloader/yuiloader-min.js [deleted file]
lib/yui/2.8.1/build/yuiloader/yuiloader.js [deleted file]
lib/yui/2.8.1/build/yuitest/assets/skins/sam/yuitest-skin.css [deleted file]
lib/yui/2.8.1/build/yuitest/assets/skins/sam/yuitest.css [deleted file]
lib/yui/2.8.1/build/yuitest/assets/testlogger.css [deleted file]
lib/yui/2.8.1/build/yuitest/assets/yuitest-core.css [deleted file]
lib/yui/2.8.1/build/yuitest/yuitest-debug.js [deleted file]
lib/yui/2.8.1/build/yuitest/yuitest-min.js [deleted file]
lib/yui/2.8.1/build/yuitest/yuitest.js [deleted file]
lib/yui/2.8.1/build/yuitest/yuitest_core-debug.js [deleted file]
lib/yui/2.8.1/build/yuitest/yuitest_core-min.js [deleted file]
lib/yui/2.8.1/build/yuitest/yuitest_core.js [deleted file]
mnet/publickey.php
mnet/service/enrol/course.php
mnet/service/enrol/locallib.php
mod/chat/chatd.php
mod/data/css.php
mod/data/js.php
mod/quiz/module.js
mod/scorm/db/install.xml
mod/scorm/db/upgrade.php
mod/scorm/version.php [changed mode: 0755->0644]
mod/workshop/allocation/random/lang/en/workshopallocation_random.php
mod/workshop/allocation/random/lib.php
mod/workshop/allocation/random/settings_form.php
mod/workshop/allocation/random/styles.css [new file with mode: 0644]
question/format/gift/format.php
question/format/gift/simpletest/testgiftformat.php
repository/repository_ajax.php
tag/edit.php
tag/lib.php
tag/tag_autocomplete.php
theme/javascript.php
theme/overlay/style/pagelayout.css
theme/splash/lang/en/theme_splash.php
theme/styles.php
theme/styles_debug.php
user/selector/search.php
version.php
webservice/rest/locallib.php
webservice/soap/locallib.php

index 6d1b819..de868b3 100644 (file)
@@ -26,7 +26,7 @@ function dbtransfer_export_xml_database($description, $mdb) {
 
     session_get_instance()->write_close(); // release session
 
-    header('Content-Type: application/xhtml+xml');
+    header('Content-Type: application/xhtml+xml; charset=utf-8');
     header('Content-Disposition: attachment; filename=database.xml');
     header('Expires: 0');
     header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
index 5536540..33a70d8 100644 (file)
         }
 
         // Settings link, if available.
-        if (file_exists($qtype->plugin_dir() . '/settings.php')) {
+        $settings = admin_get_root()->locate('qtypesetting' . $qtypename);
+        if ($settings instanceof admin_externalpage) {
+            $row[] = '<a href="' . $settings->url .
+                    '">' . get_string('settings') . '</a>';
+        } else if ($settings instanceof admin_settingpage) {
             $row[] = '<a href="' . admin_url('settings.php?section=qtypesetting' . $qtypename) .
                     '">' . get_string('settings') . '</a>';
         } else {
index d107eca..825673c 100644 (file)
@@ -372,13 +372,12 @@ if ($hassiteconfig || has_capability('moodle/question:config', $systemcontext))
     // Question type settings.
     $ADMIN->add('modules', new admin_category('qtypesettings', get_string('questiontypes', 'admin')));
     $ADMIN->add('qtypesettings', new admin_page_manageqtypes());
-    require_once($CFG->libdir . '/questionlib.php');
-    global $QTYPES;
-    foreach ($QTYPES as $qtype) {
-        $settingsfile = $qtype->plugin_dir() . '/settings.php';
+    $qtypes = get_plugin_list('qtype');
+    foreach ($qtypes as $qtype => $path) {
+        $settingsfile = $path . '/settings.php';
         if (file_exists($settingsfile)) {
-            $settings = new admin_settingpage('qtypesetting' . $qtype->name(),
-                    $qtype->local_name(), 'moodle/question:config');
+            $settings = new admin_settingpage('qtypesetting' . $qtype,
+                    get_string('pluginname', 'qtype_' . $qtype), 'moodle/question:config');
             include($settingsfile);
             if ($settings) {
                 $ADMIN->add('qtypesettings', $settings);
index 6da2efb..605a53d 100755 (executable)
@@ -668,10 +668,16 @@ if ($formdata = $mform->is_cancelled()) {
             $courseid      = $ccache[$shortname]->id;
             $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid);
             if (!isset($manualcache[$courseid])) {
-                if ($instances = enrol_get_instances($courseid, false)) {
-                    $manualcache[$courseid] = reset($instances);
-                } else {
-                    $manualcache[$courseid] = false;
+                $manualcache[$courseid] = false;
+                if ($manual) {
+                    if ($instances = enrol_get_instances($courseid, false)) {
+                        foreach ($instances as $instance) {
+                            if ($instance->enrol === 'manual') {
+                                $manualcache[$courseid] = $instance;
+                                break;
+                            }
+                        }
+                    }
                 }
             }
 
index 4b80b28..70c3f6d 100644 (file)
                         echo $OUTPUT->footer();
                         break;
                     case ACTION_GENERATE_XML:
-                        header('Content-type: application/xhtml+xml');
+                        header('Content-type: application/xhtml+xml; charset=utf-8');
                         echo $xmldb_action->getOutput();
                         break;
                 }
index 1de41bc..df79e3b 100644 (file)
@@ -64,7 +64,7 @@ class block_course_overview extends block_base {
             $courses_limit = $courses_limit + 1;
         }
 
-        $courses = enrol_get_my_courses('id, shortname', 'visible DESC,sortorder ASC', $courses_limit);
+        $courses = enrol_get_my_courses('id, shortname, modinfo', 'visible DESC,sortorder ASC', $courses_limit);
         $site = get_site();
         $course = $site; //just in case we need the old global $course hack
 
index e4d62bd..3fe48f1 100644 (file)
@@ -165,6 +165,6 @@ header('Pragma: no-cache');
 header('Accept-Ranges: none'); // Comment out if PDFs do not work...
 header('Content-disposition: attachment; filename='.$filename);
 header('Content-length: '.strlen($serialized));
-header('Content-type: text/calendar');
+header('Content-type: text/calendar; charset=utf-8');
 
 echo $serialized;
index 66f6bad..f9909be 100644 (file)
@@ -50,9 +50,12 @@ $CFG->dboptions = array(
                                 //  used? set to 'false' for the most stable
                                 //  setting, 'true' can improve performance
                                 //  sometimes
-    'dbsocket'  => false,       // should connection via UNIX socket be
-                                //  used? if you set it to 'true' here,
-                                //  set dbhost to 'localhost'
+    'dbsocket'  => false,       // should connection via UNIX socket be used?
+                                //  if you set it to 'true' or custom path
+                                //  here set dbhost to 'localhost',
+                                //  (please note mysql is always using socket
+                                //  if dbhost is 'localhost' - if you need
+                                //  local port connection use '127.0.0.1')
     'dbport'    => '',          // the TCP port number to use when connecting
                                 //  to the server. keep empty string for the
                                 //  default port
index 10d7178..28983a9 100644 (file)
@@ -351,7 +351,7 @@ function print_log($course, $user=0, $date=0, $order="l.time ASC", $page=0, $per
     $table->head = array(
         get_string('time'),
         get_string('ip_address'),
-        get_string('fullnamecourse'),
+        get_string('fullname'),
         get_string('action'),
         get_string('info')
     );
index a40c807..50f2571 100644 (file)
@@ -430,8 +430,8 @@ class enrol_database_plugin extends enrol_plugin {
             unset($user_mapping);
 
             // enrol all users and sync roles
-            foreach ($requested_roles as $userid=>$roles) {
-                foreach ($roles as $roleid) {
+            foreach ($requested_roles as $userid=>$userroles) {
+                foreach ($userroles as $roleid) {
                     if (empty($current_roles[$userid])) {
                         $this->enrol_user($instance, $userid, $roleid);
                         $current_roles[$userid][$roleid] = $roleid;
@@ -441,7 +441,7 @@ class enrol_database_plugin extends enrol_plugin {
 
                 // unassign removed roles
                 foreach($current_roles[$userid] as $cr) {
-                    if (empty($roles[$cr])) {
+                    if (empty($userroles[$cr])) {
                         role_unassign($cr, $userid, $context->id, 'enrol_database', $instance->id);
                         unset($current_roles[$userid][$cr]);
                     }
index 05853b4..67b715c 100644 (file)
@@ -183,7 +183,7 @@ function refineTeX($texexp) {
 }
 
 function outputText($texexp) {
-  header("Content-type: text/html");
+  header("Content-type: text/html; charset=utf-8");
   echo "<html><body><pre>\n";
   if ($texexp) {
     $texexp = str_replace('<','&lt;',$texexp);
index 4862224..a53f2ee 100644 (file)
@@ -96,7 +96,7 @@
 
 
     function outputText($texexp) {
-        header("Content-type: text/html");
+        header("Content-type: text/html; charset=utf-8");
         echo "<html><body><pre>\n";
         if ($texexp) {
             $texexp = str_replace('<', '&lt;', $texexp);
old mode 100755 (executable)
new mode 100644 (file)
index 4cd70b3..8681a83
@@ -79,8 +79,13 @@ if ($id) {
                 continue;
             }
 
-            // this was idnumber
-            $gradeitems[$grade_item->id] = $grade_item->get_name();
+            $displaystring = null;
+            if (!empty($grade_item->itemmodule)) {
+                $displaystring = get_string('modulename', $grade_item->itemmodule).': '.$grade_item->get_name();
+            } else {
+                $displaystring = $grade_item->get_name();
+            }
+            $gradeitems[$grade_item->id] = $displaystring;
         }
     }
 }
@@ -88,7 +93,9 @@ if ($id) {
 if ($importcode = optional_param('importcode', '', PARAM_FILE)) {
     $filename = $CFG->dataroot.'/temp/gradeimport/cvs/'.$USER->id.'/'.$importcode;
     $fp = fopen($filename, "r");
-    $header = explode($csv_delimiter, fgets($fp,GRADE_CSV_LINE_LENGTH), PARAM_RAW);
+    $headers = fgets($fp, GRADE_CSV_LINE_LENGTH);
+    $header = explode($csv_delimiter, $headers);
+    fclose($fp);
 }
 
 $mform2 = new grade_import_mapping_form(null, array('gradeitems'=>$gradeitems, 'header'=>$header));
@@ -122,7 +129,7 @@ if ($formdata = $mform->get_data()) {
     $fp = fopen($filename, "r");
 
     // --- get header (field names) ---
-    $header = explode($csv_delimiter, fgets($fp,GRADE_CSV_LINE_LENGTH));
+    $header = explode($csv_delimiter, fgets($fp, GRADE_CSV_LINE_LENGTH));
 
     // print some preview
     $numlines = 0; // 0 preview lines displayed
@@ -136,10 +143,10 @@ if ($formdata = $mform->get_data()) {
     }
     echo '</tr>';
     while (!feof ($fp) && $numlines <= $formdata->previewrows) {
-        $lines = explode($csv_delimiter, fgets($fp,GRADE_CSV_LINE_LENGTH));
+        $lines = explode($csv_delimiter, fgets($fp, GRADE_CSV_LINE_LENGTH));
         echo '<tr>';
         foreach ($lines as $line) {
-            echo '<td>'.$line.'</td>';;
+            echo '<td>'.$line.'</td>';
         }
         $numlines ++;
         echo '</tr>';
@@ -177,7 +184,9 @@ if ($formdata = $mform->get_data()) {
     $map = array();
     // loops mapping_0, mapping_1 .. mapping_n and construct $map array
     foreach ($header as $i => $head) {
-        $map[$i] = $formdata->{'mapping_'.$i};
+        if (isset($formdata->{'mapping_'.$i})) {
+            $map[$i] = $formdata->{'mapping_'.$i};
+        }
     }
 
     // if mapping information is supplied
@@ -185,7 +194,7 @@ if ($formdata = $mform->get_data()) {
 
     // check for mapto collisions
     $maperrors = array();
-    foreach ($map as $i=>$j) {
+    foreach ($map as $i => $j) {
         if ($j == 0) {
             // you can have multiple ignores
             continue;
@@ -211,14 +220,14 @@ if ($formdata = $mform->get_data()) {
     if ($fp = fopen($filename, "r")) {
 
         // read the first line makes sure this doesn't get read again
-        $header = explode($csv_delimiter, fgets($fp,GRADE_CSV_LINE_LENGTH));
+        $header = explode($csv_delimiter, fgets($fp, GRADE_CSV_LINE_LENGTH));
 
         $newgradeitems = array(); // temporary array to keep track of what new headers are processed
         $status = true;
 
         while (!feof ($fp)) {
             // add something
-            $line = explode($csv_delimiter, fgets($fp,GRADE_CSV_LINE_LENGTH));
+            $line = explode($csv_delimiter, fgets($fp, GRADE_CSV_LINE_LENGTH));
 
             if(count($line) <= 1){
                 // there is no data on this line, move on
@@ -303,18 +312,19 @@ if ($formdata = $mform->get_data()) {
                             $newgradeitem->importcode = $importcode;
                             $newgradeitem->importer   = $USER->id;
 
-                            // failed to insert into new grade item buffer
+                            // insert into new grade item buffer
                             $newgradeitems[$key] = $DB->insert_record('grade_import_newitem', $newgradeitem);
-                            // add this to grade_import_newitem table
-                            // add the new id to $newgradeitem[$key]
                         }
                         $newgrade = new stdClass();
                         $newgrade->newgradeitem = $newgradeitems[$key];
-                        $newgrade->finalgrade   = $value;
-                        $newgrades[] = $newgrade;
 
-                        // if not, put it in
-                        // else, insert grade into the table
+                        // if the user has a grade for this grade item
+                        if (trim($value) != '-') {
+                            // instead of omitting the grade we could insert one with finalgrade set to 0
+                            // we do not have access to grade item min grade
+                            $newgrade->finalgrade   = $value;
+                            $newgrades[] = $newgrade;
+                        }
                     break;
                     case 'feedback':
                         if ($t1) {
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 574b354..1209e1c
@@ -163,22 +163,31 @@ function get_unenrolled_users_in_import($importcode, $courseid) {
     global $CFG, $DB;
     $relatedctxcondition = get_related_contexts_string(get_context_instance(CONTEXT_COURSE, $courseid));
 
-    list($usql, $params) = $DB->get_in_or_equal(explode(',', $CFG->gradebookroles));
+    //users with a gradeable role
+    list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $CFG->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+
+    //enrolled users
+    $context = get_context_instance(CONTEXT_COURSE, $courseid);
+    list($enrolledsql, $enrolledparams) = get_enrolled_sql($context);
 
     $sql = "SELECT giv.id, u.firstname, u.lastname, u.idnumber AS useridnumber,
-                COALESCE(gi.idnumber, gin.itemname) AS gradeidnumber
-            FROM
-                {grade_import_values} giv
-                JOIN {user} u ON giv.userid = u.id
-                LEFT JOIN {grade_items} gi ON gi.id = giv.itemid
-                LEFT JOIN {grade_import_newitem} gin ON gin.id = giv.newgradeitem
-                LEFT JOIN {role_assignments} ra ON (giv.userid = ra.userid AND
-                    ra.roleid $usql AND
-                    ra.contextid $relatedctxcondition)
-                WHERE giv.importcode = ?
-                    AND ra.id IS NULL
-                ORDER BY gradeidnumber, u.lastname, u.firstname";
-    $params[] = $importcode;
+                   COALESCE(gi.idnumber, gin.itemname) AS gradeidnumber
+              FROM {grade_import_values} giv
+              JOIN {user} u
+                   ON giv.userid = u.id
+              LEFT JOIN {grade_items} gi
+                        ON gi.id = giv.itemid
+              LEFT JOIN {grade_import_newitem} gin
+                        ON gin.id = giv.newgradeitem
+              LEFT JOIN ($enrolledsql) je
+                        ON je.id = u.id
+              LEFT JOIN {role_assignments} ra
+                        ON (giv.userid = ra.userid AND ra.roleid $gradebookrolessql AND ra.contextid $relatedctxcondition)
+             WHERE giv.importcode = :importcode
+                   AND (ra.id IS NULL OR je.id IS NULL)
+          ORDER BY gradeidnumber, u.lastname, u.firstname";
+    $params = array_merge($gradebookrolesparams, $enrolledparams);
+    $params['importcode'] = $importcode;
 
     return $DB->get_records_sql($sql, $params);
 }
index d3bedfe..d76d679 100644 (file)
@@ -333,23 +333,35 @@ class grade_report_grader extends grade_report {
     public function load_users() {
         global $CFG, $DB;
 
-        list($usql, $gbrparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+        //limit to users with a gradeable role
+        list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
 
+        //limit to users with an active enrollment
+        list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context);
+
+        //fields we need from the user table
+        $userfields = user_picture::fields('u', array('idnumber'));
+
+        //if the user has clicked one of the sort asc/desc arrows
         if (is_numeric($this->sortitemid)) {
-            $params = array_merge(array('gitemid'=>$this->sortitemid), $gbrparams, $this->groupwheresql_params);
+            $params = array_merge(array('gitemid'=>$this->sortitemid), $gradebookrolesparams, $this->groupwheresql_params, $enrolledparams);
             // the MAX() magic is required in order to please PG
             $sort = "MAX(g.finalgrade) $this->sortorder";
 
-            $ufields = user_picture::fields('u', array('idnumber'));
-            $sql = "SELECT $ufields
+            $sql = "SELECT $userfields
                       FROM {user} u
-                           JOIN {role_assignments} ra ON ra.userid = u.id
-                           $this->groupsql
-                           LEFT JOIN {grade_grades} g ON (g.userid = u.id AND g.itemid = :gitemid)
-                     WHERE ra.roleid $usql AND u.deleted = 0
-                           $this->groupwheresql
+                      JOIN ($enrolledsql) je
+                           ON je.id = u.id
+                      JOIN {role_assignments} ra
+                           ON ra.userid = u.id
+                      $this->groupsql
+                      LEFT JOIN {grade_grades} g
+                                ON (g.userid = u.id AND g.itemid = :gitemid)
+                     WHERE ra.roleid $gradebookrolessql
+                           AND u.deleted = 0
                            AND ra.contextid ".get_related_contexts_string($this->context)."
-                  GROUP BY $ufields
+                           $this->groupwheresql
+                  GROUP BY $userfields
                   ORDER BY $sort";
 
         } else {
@@ -363,16 +375,19 @@ class grade_report_grader extends grade_report {
                     $sort = "u.idnumber $this->sortorder"; break;
             }
 
-            $params = array_merge($gbrparams, $this->groupwheresql_params);
+            $params = array_merge($gradebookrolesparams, $this->groupwheresql_params, $enrolledparams);
 
-            $userfields = user_picture::fields('u', array('idnumber'));
             $sql = "SELECT DISTINCT $userfields
                       FROM {user} u
-                           JOIN {role_assignments} ra ON u.id = ra.userid
+                      JOIN ($enrolledsql) je
+                           ON je.id = u.id
+                      JOIN {role_assignments} ra
+                           ON u.id = ra.userid
                            $this->groupsql
-                     WHERE ra.roleid $usql AND u.deleted = 0
-                           $this->groupwheresql
+                     WHERE ra.roleid $gradebookrolessql
+                           AND u.deleted = 0
                            AND ra.contextid ".get_related_contexts_string($this->context)."
+                           $this->groupwheresql
                   ORDER BY $sort";
         }
 
@@ -1269,20 +1284,29 @@ class grade_report_grader extends grade_report {
 
         $totalcount = $this->get_numusers($grouponly);
 
-        list($usql, $rolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+        //limit to users with a gradeable role
+        list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+
+        //limit to users with an active enrollment
+        list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context);
 
         if ($showaverages) {
-            $params = array_merge(array('courseid'=>$this->courseid), $rolesparams, $groupwheresqlparams);
+            $params = array_merge(array('courseid'=>$this->courseid), $gradebookrolesparams, $enrolledparams, $groupwheresqlparams);
 
             // find sums of all grade items in course
             $SQL = "SELECT g.itemid, SUM(g.finalgrade) AS sum
                       FROM {grade_items} gi
-                           JOIN {grade_grades} g      ON g.itemid = gi.id
-                           JOIN {user} u              ON u.id = g.userid
-                           JOIN {role_assignments} ra ON ra.userid = u.id
-                           $groupsql
+                      JOIN {grade_grades} g
+                           ON g.itemid = gi.id
+                      JOIN {user} u
+                           ON u.id = g.userid
+                      JOIN ($enrolledsql) je
+                           ON je.id = u.id
+                      JOIN {role_assignments} ra
+                           ON ra.userid = u.id
+                      $groupsql
                      WHERE gi.courseid = :courseid
-                           AND ra.roleid $usql
+                           AND ra.roleid $gradebookrolessql
                            AND ra.contextid ".get_related_contexts_string($this->context)."
                            AND g.finalgrade IS NOT NULL
                            $groupwheresql
@@ -1296,15 +1320,18 @@ class grade_report_grader extends grade_report {
 
             // MDL-10875 Empty grades must be evaluated as grademin, NOT always 0
             // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table)
-            $params = array_merge(array('courseid'=>$this->courseid), $rolesparams, $groupwheresqlparams);
             $SQL = "SELECT gi.id, COUNT(u.id) AS count
                       FROM {grade_items} gi
-                           CROSS JOIN {user} u
-                           JOIN {role_assignments} ra        ON ra.userid = u.id
-                           LEFT OUTER JOIN  {grade_grades} g ON (g.itemid = gi.id AND g.userid = u.id AND g.finalgrade IS NOT NULL)
-                           $groupsql
+                      CROSS JOIN {user} u
+                      JOIN ($enrolledsql) je
+                           ON je.id = u.id
+                      JOIN {role_assignments} ra
+                           ON ra.userid = u.id
+                      LEFT OUTER JOIN {grade_grades} g
+                           ON (g.itemid = gi.id AND g.userid = u.id AND g.finalgrade IS NOT NULL)
+                      $groupsql
                      WHERE gi.courseid = :courseid
-                           AND ra.roleid $usql
+                           AND ra.roleid $gradebookrolessql
                            AND ra.contextid ".get_related_contexts_string($this->context)."
                            AND g.id IS NULL
                            $groupwheresql
old mode 100755 (executable)
new mode 100644 (file)
index 45540a9..a49b89e
@@ -274,7 +274,14 @@ abstract class grade_report {
 
         $groupsql      = "";
         $groupwheresql = "";
-        list($usql, $params) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+
+        //limit to users with a gradeable role
+        list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+
+        //limit to users with an active enrollment
+        list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context);
+
+        $params = array_merge($gradebookrolesparams, $enrolledparams);
 
         if ($groups) {
             $groupsql      = $this->groupsql;
@@ -284,9 +291,13 @@ abstract class grade_report {
 
         $countsql = "SELECT COUNT(DISTINCT u.id)
                        FROM {user} u
-                            JOIN {role_assignments} ra ON u.id = ra.userid
-                            $groupsql
-                      WHERE ra.roleid $usql AND u.deleted = 0
+                       JOIN ($enrolledsql) je
+                            ON je.id = u.id
+                       JOIN {role_assignments} ra
+                            ON u.id = ra.userid
+                       $groupsql
+                      WHERE ra.roleid $gradebookrolessql
+                            AND u.deleted = 0
                             $groupwheresql
                             AND ra.contextid ".get_related_contexts_string($this->context);
         return $DB->count_records_sql($countsql, $params);
index b2030eb..a452a33 100644 (file)
@@ -149,4 +149,4 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
     }
 }
 
-echo $OUTPUT->footer();
\ No newline at end of file
+echo $OUTPUT->footer();
index 71aac49..6d66a6e 100644 (file)
@@ -47,7 +47,29 @@ class grade_report_user extends grade_report {
      */
     public $table;
 
-    var $gtree;
+    /**
+     * An array of table headers
+     * @var array
+     */
+    public $tableheaders = array();
+
+    /**
+     * An array of table columns
+     * @var array
+     */
+    public $tablecolumns = array();
+
+    /**
+     * An array containing rows of data for the table.
+     * @var type
+     */
+    public $tabledata = array();
+
+    /**
+     * The grade tree structure
+     * @var grade_tree
+     */
+    public $gtree;
 
     /**
      * Flat structure similar to grade tree
@@ -67,23 +89,65 @@ class grade_report_user extends grade_report {
     /**
      * Show range
      */
-    var $showrange;
+    public $showrange = true;
 
-    var $tableheaders;
-    var $tablecolumns;
+    /**
+     * Show grades in the report, default true
+     * @var bool
+     */
+    public $showgrade = true;
 
-    var $maxdepth;
-    var $evenodd;
+    /**
+     * Decimal points to use for values in the report, default 2
+     * @var int
+     */
+    public $decimals = 2;
 
-    var $tabledata;
-    var $canviewhidden;
+    /**
+     * The number of decimal places to round range to, default 0
+     * @var int
+     */
+    public $rangedecimals = 0;
 
-    var $switch;
+    /**
+     * Show grade feedback in the report, default true
+     * @var bool
+     */
+    public $showfeedback = true;
+
+    /**
+     * Show grade weighting in the report, default false
+     * @var bool
+     */
+    public $showweight = false;
+
+    /**
+     * Show letter grades in the report, default false
+     * @var bool
+     */
+    public $showlettergrade = false;
+
+    /**
+     * Show average grades in the report, default false.
+     * @var false
+     */
+    public $showaverage = false;
+
+    public $maxdepth;
+    public $evenodd;
+
+    public $canviewhidden;
+
+    public $switch;
 
     /**
      * Show hidden items even when user does not have required cap
      */
     public $showhiddenitems;
+    public $showtotalsifcontainhidden;
+
+    public $baseurl;
+    public $pbarurl;
 
     /**
      * Constructor. Sets local copies of user preferences and initialises grade_tree.
@@ -93,7 +157,7 @@ class grade_report_user extends grade_report {
      * @param int $userid The id of the user
      */
     public function __construct($courseid, $gpr, $context, $userid) {
-        global $CFG, $DB;
+        global $DB, $CFG;
         parent::__construct($courseid, $gpr, $context);
 
         $this->showrank        = grade_get_setting($this->courseid, 'report_user_showrank', $CFG->grade_report_user_showrank);
@@ -101,6 +165,27 @@ class grade_report_user extends grade_report {
         $this->showhiddenitems = grade_get_setting($this->courseid, 'report_user_showhiddenitems', $CFG->grade_report_user_showhiddenitems);
         $this->showtotalsifcontainhidden = grade_get_setting($this->courseid, 'report_user_showtotalsifcontainhidden', $CFG->grade_report_user_showtotalsifcontainhidden);
 
+        $this->showgrade       = grade_get_setting($this->courseid, 'report_user_showgrade',       !empty($CFG->grade_report_user_showgrade));
+        $this->showrange       = grade_get_setting($this->courseid, 'report_user_showrange',       !empty($CFG->grade_report_user_showrange));
+        $this->showfeedback    = grade_get_setting($this->courseid, 'report_user_showfeedback',    !empty($CFG->grade_report_user_showfeedback));
+        $this->showweight      = grade_get_setting($this->courseid, 'report_user_showweight',      !empty($CFG->grade_report_user_showweight));
+        $this->showlettergrade = grade_get_setting($this->courseid, 'report_user_showlettergrade', !empty($CFG->grade_report_user_showlettergrade));
+        $this->showaverage     = grade_get_setting($this->courseid, 'report_user_showaverage',     !empty($CFG->grade_report_user_showaverage));
+
+        // The default grade decimals is 2
+        $defaultdecimals = 2;
+        if (property_exists($CFG, 'grade_decimalpoints')) {
+            $defaultdecimals = $CFG->grade_decimalpoints;
+        }
+        $this->decimals = grade_get_setting($this->courseid, 'decimalpoints', $defaultdecimals);
+
+        // The default range decimals is 0
+        $defaultrangedecimals = 0;
+        if (property_exists($CFG, 'grade_report_user_rangedecimals')) {
+            $defaultrangedecimals = $CFG->grade_report_user_rangedecimals;
+        }
+        $this->rangedecimals = grade_get_setting($this->courseid, 'report_user_rangedecimals', $defaultrangedecimals);
+
         $this->switch = grade_get_setting($this->courseid, 'aggregationposition', $CFG->grade_aggregationposition);
 
         // Grab the grade_tree for this course
@@ -127,6 +212,9 @@ class grade_report_user extends grade_report {
 
         // no groups on this report - rank is from all course users
         $this->setup_table();
+
+        //optionally calculate grade item averages
+        $this->calculate_averages();
     }
 
     function inject_rowspans(&$element) {
@@ -149,16 +237,25 @@ class grade_report_user extends grade_report {
      * Prepares the headers and attributes of the flexitable.
      */
     public function setup_table() {
-        global $CFG;
         /*
-         * Table has 5-6 columns
-         *| itemname/description | final grade | percentage final grade | rank (optional) | feedback |
+         * Table has 1-8 columns
+         *| All columns except for itemname/description are optional
          */
 
         // setting up table headers
-        $this->tablecolumns = array('itemname', 'grade');
-        $this->tableheaders = array($this->get_lang_string('gradeitem', 'grades'),
-                              $this->get_lang_string('grade'));
+
+        $this->tablecolumns = array('itemname');
+        $this->tableheaders = array($this->get_lang_string('gradeitem', 'grades'));
+
+        if ($this->showweight) {
+            $this->tablecolumns[] = 'weight';
+            $this->tableheaders[] = $this->get_lang_string('weightuc', 'grades');
+        }
+
+        if ($this->showgrade) {
+            $this->tablecolumns[] = 'grade';
+            $this->tableheaders[] = $this->get_lang_string('grade', 'grades');
+        }
 
         if ($this->showrange) {
             $this->tablecolumns[] = 'range';
@@ -170,15 +267,25 @@ class grade_report_user extends grade_report {
             $this->tableheaders[] = $this->get_lang_string('percentage', 'grades');
         }
 
+        if ($this->showlettergrade) {
+            $this->tablecolumns[] = 'lettergrade';
+            $this->tableheaders[] = $this->get_lang_string('lettergrade', 'grades');
+        }
+
         if ($this->showrank) {
-            // TODO: this is broken if hidden grades present!!
             $this->tablecolumns[] = 'rank';
             $this->tableheaders[] = $this->get_lang_string('rank', 'grades');
         }
 
-        $this->tablecolumns[] = 'feedback';
-        $this->tableheaders[] = $this->get_lang_string('feedback', 'grades');
+        if ($this->showaverage) {
+            $this->tablecolumns[] = 'average';
+            $this->tableheaders[] = $this->get_lang_string('average', 'grades');
+        }
 
+        if ($this->showfeedback) {
+            $this->tablecolumns[] = 'feedback';
+            $this->tableheaders[] = $this->get_lang_string('feedback', 'grades');
+        }
     }
 
     function fill_table() {
@@ -191,7 +298,7 @@ class grade_report_user extends grade_report {
     }
 
     private function fill_table_recursive(&$element) {
-        global $CFG, $DB;
+        global $DB, $CFG;
 
         $type = $element['type'];
         $depth = $element['depth'];
@@ -257,42 +364,78 @@ class grade_report_user extends grade_report {
 
                 /// Actual Grade
                 $gradeval = $grade_grade->finalgrade;
-                if ($grade_grade->grade_item->needsupdate) {
-                    $data['grade']['class'] = $class.' gradingerror';
-                    $data['grade']['content'] = get_string('error');
-                } else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden()
-                       and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) {
-                    // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
-                    $class .= ' datesubmitted';
-                    $data['grade']['class'] = $class;
-                    $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort')));
-
-                } elseif ($grade_grade->is_hidden()) {
-                        $data['grade']['class'] = $class.' hidden';
-                        $data['grade']['content'] = '-';
-                } else {
-                    $data['grade']['class'] = $class;
-                    $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval);
-                    $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true);
+
+                $class .= " itemcenter ";
+                if ($this->showweight) {
+                    $data['weight']['class'] = $class;
+                    $data['weight']['content'] = '-';
+                    // has a weight assigned, might be extra credit
+                    if ($grade_object->aggregationcoef > 0 && $type <> 'courseitem') {
+                        $data['weight']['content'] = number_format($grade_object->aggregationcoef,2).'%';
+                    }
                 }
 
-                /// Percentage
+                if ($this->showgrade) {
+                    if ($grade_grade->grade_item->needsupdate) {
+                        $data['grade']['class'] = $class.' gradingerror';
+                        $data['grade']['content'] = get_string('error');
+                    } else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden()
+                           and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) {
+                        // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
+                        $class .= ' datesubmitted';
+                        $data['grade']['class'] = $class;
+                        $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort')));
+
+                    } elseif ($grade_grade->is_hidden()) {
+                            $data['grade']['class'] = $class.' hidden';
+                            $data['grade']['content'] = '-';
+                    } else {
+                        $data['grade']['class'] = $class;
+                        $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval);
+                        $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true);
+                    }
+                }
+
+                // Range
+                if ($this->showrange) {
+                    $data['range']['class'] = $class;
+                    $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals);
+                }
+
+                // Percentage
                 if ($this->showpercentage) {
                     if ($grade_grade->grade_item->needsupdate) {
                         $data['percentage']['class'] = $class.' gradingerror';
                         $data['percentage']['content'] = get_string('error');
-                        } elseif ($grade_grade->is_hidden()) {
-                            $data['percentage']['class'] = $class.' hidden';
-                            $data['percentage']['content'] = '-';
+                    } else if ($grade_grade->is_hidden()) {
+                        $data['percentage']['class'] = $class.' hidden';
+                        $data['percentage']['content'] = '-';
                     } else {
                         $data['percentage']['class'] = $class;
                         $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
                     }
                 }
 
-                /// Rank
+                // Lettergrade
+                if ($this->showlettergrade) {
+                    if ($grade_grade->grade_item->needsupdate) {
+                        $data['lettergrade']['class'] = $class.' gradingerror';
+                        $data['lettergrade']['content'] = get_string('error');
+                    } else if ($grade_grade->is_hidden()) {
+                        $data['lettergrade']['class'] = $class.' hidden';
+                        if (!$this->canviewhidden) {
+                            $data['lettergrade']['content'] = '-';
+                        } else {
+                            $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER);
+                        }
+                    } else {
+                        $data['lettergrade']['class'] = $class;
+                        $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER);
+                    }
+                }
+
+                // Rank
                 if ($this->showrank) {
-                    // TODO: this is broken if hidden grades present!!
                     if ($grade_grade->grade_item->needsupdate) {
                         $data['rank']['class'] = $class.' gradingerror';
                         $data['rank']['content'] = get_string('error');
@@ -309,7 +452,8 @@ class grade_report_user extends grade_report {
                         $sql = "SELECT COUNT(DISTINCT(userid))
                                   FROM {grade_grades}
                                  WHERE finalgrade > ?
-                                       AND itemid = ?";
+                                       AND itemid = ?
+                                       AND hidden = 0";
                         $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1;
 
                         $data['rank']['class'] = $class;
@@ -317,20 +461,28 @@ class grade_report_user extends grade_report {
                     }
                 }
 
-                /// Feedback
-                if (empty($grade_grade->feedback) or (!$this->canviewhidden and $grade_grade->is_hidden())) {
-                    $data['feedback']['class'] = $class.' feedbacktext';
-                    $data['feedback']['content'] = '&nbsp;';
-
-                } else {
-                    $data['feedback']['class'] = $class.' feedbacktext';
-                    $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat, array('overflowdiv'=>true));
+                // Average
+                if ($this->showaverage) {
+                    $data['average']['class'] = $class;
+                    if (!empty($this->gtree->items[$eid]->avg)) {
+                        $data['average']['content'] = $this->gtree->items[$eid]->avg;
+                    } else {
+                        $data['average']['content'] = '-';
+                    }
                 }
 
-                /// Range
-                if ($this->showrange) {
-                    $data['range']['class'] = $class;
-                    $data['range']['content'] = $grade_grade->grade_item->get_formatted_range();
+                // Feedback
+                if ($this->showfeedback) {
+                    if ($grade_grade->overridden > 0 AND ($type == 'categoryitem' OR $type == 'courseitem')) {
+                    $data['feedback']['class'] = $class.' feedbacktext';
+                        $data['feedback']['content'] = get_string('overridden', 'grades').': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat);
+                    } else if (empty($grade_grade->feedback) or (!$this->canviewhidden and $grade_grade->is_hidden())) {
+                        $data['feedback']['class'] = $class.' feedbacktext';
+                        $data['feedback']['content'] = '&nbsp;';
+                    } else {
+                        $data['feedback']['class'] = $class.' feedbacktext';
+                        $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
+                    }
                 }
             }
         }
@@ -422,6 +574,165 @@ class grade_report_user extends grade_report {
     }
     function process_action($target, $action) {
     }
+
+    /**
+     * Builds the grade item averages.
+     *
+     */
+    function calculate_averages() {
+        global $USER, $DB;
+
+        if ($this->showaverage) {
+            // this settings are actually grader report settings (not user report)
+            // however we're using them as having two separate but identical settings the
+            // user would have to keep in sync would be annoying
+            $averagesdisplaytype   = $this->get_pref('averagesdisplaytype');
+            $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints');
+            $meanselection         = $this->get_pref('meanselection');
+            $shownumberofgrades    = $this->get_pref('shownumberofgrades');
+
+            $avghtml = '';
+            $avgcssclass = 'avg';
+
+            $straverage = get_string('overallaverage', 'grades');
+
+            $groupsql = $this->groupsql;
+            $groupwheresql = $this->groupwheresql;
+            //$groupwheresqlparams = ;
+
+            if ($shownumberofgrades) {
+                $straverage .= ' (' . get_string('submissions', 'grades') . ') ';
+            }
+
+            $totalcount = $this->get_numusers(false);
+
+            //limit to users with a gradeable role ie students
+            list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
+
+            //limit to users with an active enrolment
+            list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context);
+
+            $params = array_merge($this->groupwheresql_params, $gradebookrolesparams, $enrolledparams);
+            $params['courseid'] = $this->courseid;
+
+            // find sums of all grade items in course
+            $sql = "SELECT gg.itemid, SUM(gg.finalgrade) AS sum
+                      FROM {grade_items} gi
+                      JOIN {grade_grades} gg
+                           ON gg.itemid = gi.id
+                      JOIN ($enrolledsql) je
+                           ON je.id = gg.userid
+                      JOIN {role_assignments} ra
+                           ON ra.userid = gg.userid
+                      $groupsql
+                     WHERE gi.courseid = :courseid
+                           AND ra.roleid $gradebookrolessql
+                           AND ra.contextid ".get_related_contexts_string($this->context)."
+                           AND gg.finalgrade IS NOT NULL
+                           AND gg.hidden = 0
+                           $groupwheresql
+                  GROUP BY gg.itemid";
+
+            $sum_array = array();
+            if ($sums = $DB->get_recordset_sql($sql, $params)) {
+                foreach ($sums as $itemid => $csum) {
+                    $sum_array[$itemid] = $csum->sum;
+                }
+                $sums->close();
+            }
+
+            $columncount=0;
+
+            // Empty grades must be evaluated as grademin, NOT always 0
+            // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table)
+            // No join condition when joining grade_items and user to get a grade item row for every user
+            // Then left join with grade_grades and look for rows with null final grade (which includes grade items with no grade_grade)
+            $sql = "SELECT gi.id, COUNT(u.id) AS count
+                      FROM {grade_items} gi
+                      JOIN {user} u
+                      JOIN ($enrolledsql) je
+                           ON je.id = u.id
+                      JOIN {role_assignments} ra
+                           ON ra.userid = u.id
+                      LEFT JOIN {grade_grades} gg
+                           ON (gg.itemid = gi.id AND gg.userid = u.id AND gg.finalgrade IS NOT NULL AND gg.hidden = 0)
+                      $groupsql
+                    WHERE gi.courseid = :courseid
+                          AND ra.roleid $gradebookrolessql
+                          AND ra.contextid ".get_related_contexts_string($this->context)."
+                          AND gg.finalgrade IS NULL
+                          $groupwheresql
+                    GROUP BY gi.id";
+
+            $ungraded_counts = $DB->get_records_sql($sql, $params);
+
+            foreach ($this->gtree->items as $itemid=>$unused) {
+                if (!empty($this->gtree->items[$itemid]->avg)) {
+                    continue;
+                }
+                $item = $this->gtree->items[$itemid];
+
+                if ($item->needsupdate) {
+                    $avghtml .= '<td class="cell c' . $columncount++.'"><span class="gradingerror">'.get_string('error').'</span></td>';
+                    continue;
+                }
+
+                if (empty($sum_array[$item->id])) {
+                    $sum_array[$item->id] = 0;
+                }
+
+                if (empty($ungraded_counts[$itemid])) {
+                    $ungraded_count = 0;
+                } else {
+                    $ungraded_count = $ungraded_counts[$itemid]->count;
+                }
+
+                //do they want the averages to include all grade items
+                if ($meanselection == GRADE_REPORT_MEAN_GRADED) {
+                    $mean_count = $totalcount - $ungraded_count;
+                } else { // Bump up the sum by the number of ungraded items * grademin
+                    $sum_array[$item->id] += ($ungraded_count * $item->grademin);
+                    $mean_count = $totalcount;
+                }
+
+                $decimalpoints = $item->get_decimals();
+
+                // Determine which display type to use for this average
+                if (!empty($USER->gradeediting) && $USER->gradeediting[$this->courseid]) {
+                    $displaytype = GRADE_DISPLAY_TYPE_REAL;
+
+                } else if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave the report and user preferences
+                    $displaytype = $item->get_displaytype();
+
+                } else {
+                    $displaytype = $averagesdisplaytype;
+                }
+
+                // Override grade_item setting if a display preference (not inherit) was set for the averages
+                if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) {
+                    $decimalpoints = $item->get_decimals();
+
+                } else {
+                    $decimalpoints = $averagesdecimalpoints;
+                }
+
+                if (empty($sum_array[$item->id]) || $mean_count == 0) {
+                    $this->gtree->items[$itemid]->avg = '-';
+                } else {
+                    $sum = $sum_array[$item->id];
+                    $avgradeval = $sum/$mean_count;
+                    $gradehtml = grade_format_gradevalue($avgradeval, $item, true, $displaytype, $decimalpoints);
+
+                    $numberofgrades = '';
+                    if ($shownumberofgrades) {
+                        $numberofgrades = " ($mean_count)";
+                    }
+
+                    $this->gtree->items[$itemid]->avg = $gradehtml.$numberofgrades;
+                }
+            }
+        }
+    }
 }
 
 function grade_report_user_settings_definition(&$mform) {
@@ -449,6 +760,61 @@ function grade_report_user_settings_definition(&$mform) {
     $mform->addElement('select', 'report_user_showpercentage', get_string('showpercentage', 'grades'), $options);
     $mform->addHelpButton('report_user_showpercentage', 'showpercentage', 'grades');
 
+    if (empty($CFG->grade_report_user_showgrade)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
+    }
+
+    $mform->addElement('select', 'report_user_showgrade', get_string('showgrade', 'grades'), $options);
+
+    if (empty($CFG->grade_report_user_showfeedback)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
+    }
+
+    $mform->addElement('select', 'report_user_showfeedback', get_string('showfeedback', 'grades'), $options);
+
+    if (empty($CFG->grade_report_user_showweight)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
+    }
+
+    $mform->addElement('select', 'report_user_showweight', get_string('showweight', 'grades'), $options);
+
+    if (empty($CFG->grade_report_user_showaverage)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
+    }
+
+    $mform->addElement('select', 'report_user_showaverage', get_string('showaverage', 'grades'), $options);
+    $mform->addHelpButton('report_user_showaverage', 'showaverage', 'grades');
+
+    if (empty($CFG->grade_report_user_showlettergrade)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
+    }
+
+    $mform->addElement('select', 'report_user_showlettergrade', get_string('showlettergrade', 'grades'), $options);
+
+    if (empty($CFG->grade_report_user_showrange)) {
+        $options[-1] = get_string('defaultprev', 'grades', $options[0]);
+    } else {
+        $options[-1] = get_string('defaultprev', 'grades', $options[1]);
+    }
+
+    $mform->addElement('select', 'report_user_showrange', get_string('showrange', 'grades'), $options);
+
+    $options = array(0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
+    if (! empty($CFG->grade_report_user_rangedecimals)) {
+        $options[-1] = $options[$CFG->grade_report_user_rangedecimals];
+    }
+    $mform->addElement('select', 'report_user_rangedecimals', get_string('rangedecimals', 'grades'), $options);
+
     $options = array(-1 => get_string('default', 'grades'),
                       0 => get_string('shownohidden', 'grades'),
                       1 => get_string('showhiddenuntilonly', 'grades'),
index d5de814..5d53534 100644 (file)
@@ -21,8 +21,16 @@ defined('MOODLE_INTERNAL') || die;
 
 if ($ADMIN->fulltree) {
 
-    $settings->add(new admin_setting_configcheckbox('grade_report_user_showrank', get_string('showrank', 'grades'), get_string('showrank_help', 'grades'), 0, PARAM_INT));
-    $settings->add(new admin_setting_configcheckbox('grade_report_user_showpercentage', get_string('showpercentage', 'grades'), get_string('showpercentage_help', 'grades'), 2, PARAM_INT));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showrank', get_string('showrank', 'grades'), get_string('showrank_help', 'grades'), 0));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showpercentage', get_string('showpercentage', 'grades'), get_string('showpercentage_help', 'grades'), 1));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showgrade', get_string('showgrade', 'grades'), get_string('showgrade_help', 'grades'), 1));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showfeedback', get_string('showfeedback', 'grades'), get_string('showfeedback_help', 'grades'), 1));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showrange', get_string('showrange', 'grades'), get_string('showrange_help', 'grades'), 1));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showweight', get_string('showweight', 'grades'), get_string('showweight_help', 'grades'), 0));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showaverage', get_string('showaverage', 'grades'), get_string('showaverage_help', 'grades'), 0));
+    $settings->add(new admin_setting_configcheckbox('grade_report_user_showlettergrade', get_string('showlettergrade', 'grades'), get_string('showlettergrade_help', 'grades'), 0));
+    $settings->add(new admin_setting_configselect('grade_report_user_rangedecimals', get_string('rangedecimals', 'grades'),
+            get_string('rangedecimals_help', 'grades'), 0,array(0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5)));
 
     $options = array(0 => get_string('shownohidden', 'grades'),
                      1 => get_string('showhiddenuntilonly', 'grades'),
index d11d9d9..b7751e1 100644 (file)
@@ -34,4 +34,7 @@
 .user-grade td.excluded {background-color: #666;}
 .user-grade td.hidden {color: #aaa;}
 .user-grade td.feedbacktext {max-width:600px;padding:0;}
-.pagelayout-report .user-grade .feedbacktext .no-overflow {overflow:auto;padding:0.25em;}
\ No newline at end of file
+.pagelayout-report .user-grade .feedbacktext .no-overflow {overflow:auto;padding:0.25em;}
+
+table.user-grade td.feedbacktext {text-align:left;width: 40%;font-size: 0.8em;white-space:normal;}
+table.user-grade td.itemcenter {text-align:center;}
\ No newline at end of file
index 41130b5..8e91578 100644 (file)
@@ -115,6 +115,9 @@ $straddgroupstogroupings = get_string('addgroupstogroupings', 'group');
 
 $groupingname = format_string($grouping->name);
 
+navigation_node::override_active_url(new moodle_url('/group/index.php', array('id'=>$course->id)));
+$PAGE->set_pagelayout('standard');
+
 $PAGE->navbar->add($strparticipants, new moodle_url('/user/index.php', array('id'=>$courseid)));
 $PAGE->navbar->add($strgroups, new moodle_url('/group/index.php', array('id'=>$courseid)));
 $PAGE->navbar->add($straddgroupstogroupings);
index 84701c8..f250af7 100644 (file)
@@ -44,19 +44,14 @@ $string['memorylimithelp'] = '<p>Pašlaik iestatītais PHP atmiņas apjoma ierob
 <p>Sistēmā Moodle tas vēlāk var izraisīt atmiņas izmantošanas problēmas, it īpaši tad, 
    ja būsit iespējojis lielu skaitu moduļu un/vai lietotāju.</p>
 
-<p>Ieteicams konfigurēt PHP ar pēc iespējas lielāku atmiņas apjomu, piemēram, 40 MB.  
-   Ir vairāki veidi, kā to var izdarīt, piemēram:</p>
+<p>Ja iespējams, ieteicams konfigurēt PHP ar lielāku maksimālās atmiņas apjomu, piemēram, 40 MB. Ir vairāki veidi, kā to var izdarīt, piemēram:</p>
 <ol>
 <li>Ja iespējams, atkārtoti kompilējiet PHP, izmantojot <i>--enable-memory-limit</i>.  
     Šādā gadījumā sistēma Moodle atmiņas apjoma ierobežojumu varēs iestatīt automātiski.</li>
-<li>Ja jums ir piekļuve php.ini failam, varat mainīt tajā esošo parametra <b>memory_limit</b> 
-    iestatījumu, piemēram, uz 40 MB.  Ja jums nav piekļuves šim failam, palūdziet 
-    to izdarīt administratoram.</li>
-<li>Dažos PHP serveros Moodle direktorijā var izveidot failu .htaccess, kurā 
-    ir šāda rinda:
-    <p><blockquote>php_value memory_limit 40M</blockquote></p>
+<li>Ja jums ir piekļuve php.ini failam, varat mainīt tajā esošo parametra <b>memory_limit</b> iestatījumu, piemēram, uz 40 MB.  Ja jums nav piekļuves šim failam, palūdziet to izdarīt administratoram.</li>
+<li>Dažos PHP serveros Moodle direktorijā var izveidot failu .htaccess, kurā ir šāda rinda:    <p><blockquote>php_value memory_limit 40M</blockquote></p>
     <p>Tomēr dažos serveros tas neļaus darboties <b>nevienai</b> PHP lapai 
-    (atverot šīs lapas, tiks parādīti kļūdas ziņojumi), un fails .htaccess būs jānoņem.</p></li>
+(atverot šīs lapas, tiks parādīti kļūdas ziņojumi), un fails .htaccess būs jānoņem.</p></li>
 </ol>';
 $string['phpversion'] = 'PHP versija';
 $string['phpversionhelp'] = '<p>Sistēmā Moodle jāizmanto PHP, kuras versija ir vismaz 4.3.0 vai 5.1.0 (versijai 5.0.x piemīt vairākas zināmas problēmas).</p>
index 053387a..0dd99a8 100644 (file)
@@ -39,6 +39,7 @@ $string['dataroot'] = 'Diretório de Dados';
 $string['dbprefix'] = 'Prefixo das tabelas';
 $string['dirroot'] = 'Diretório Moodle';
 $string['environmenthead'] = 'Verificando o ambiente ...';
+$string['errorsinenvironment'] = 'Verificação do Ambiente falhou!';
 $string['installation'] = 'Instalação';
 $string['langdownloaderror'] = 'Infelizmente o idioma "{$a}" não foi instalado. A instalação vai continuar em Inglês.';
 $string['memorylimithelp'] = '<p>O limite de memória do PHP configurado atualmente no seu servidor é de {$a}.</p>
@@ -54,6 +55,8 @@ Com esta operação Moodle será capaz de configurar o limite de memória sózin
 <p><blockquote>php_value memory_limit 40M</blockquote></p>
 <p>Alguns servidores não aceitam este procedimento e <b>todas</b> as páginas PHP do servidor ficam bloqueadas ou imprimem mensagens de erro. Neste caso será necessário excluir o arquivo .htaccess .</p>
 </li></ol>';
+$string['pathssubdataroot'] = 'Você precisa de um local onde o Moodle possa salvar arquivos enviados. Este diretório deve possuir permissões de leitura e escrita pelo usuário do servidor web
+(geralmente \'nobody\' ou \'apache \'), mas não deverá ser acessível diretamente através da web. O instalador irá tentar criá-lo se ele não existir.';
 $string['pathssubdirroot'] = 'Caminho completo do diretório para instalação do Moddle.';
 $string['pathssubwwwroot'] = 'Endereço web completo onde o Moodle será acessado.
 Não é possível acessar o Moodle usando múltiplos endereços. Se seu site tem múltiplos endereços públicos você deve configurar redirecionamentos permantentes em todos eles exceto esse. Se seu site é acessado tanto da Intranet como Internet, use o endereço público aqui e configure o DNS para que os usuários da Intranet possam usar o endereço público também. Se o endereço não estiver correto, por favo mude a URL no seu navegador para reiniciar a instalação com um valor diferente.';
index fe94399..6ac0950 100644 (file)
@@ -60,7 +60,7 @@ $string['paths'] = 'பாதைகள்';
 $string['pathshead'] = 'பாதைகளை ஊர்ஜிதப்படுத்து';
 $string['phpextension'] = '{$a} PHP நீட்சி';
 $string['phpversion'] = 'PHP பதிப்பு';
-$string['phpversionhelp'] = '<p>Moodle குறைந்தளவு ஒரு PHP பதிப்பின் 4.3.0 or 5.1.0 ஐ (5.0.x அறியப்பட்ட பிரச்சினைகளின் ஒரு எண்ணிக்கையைக் கொண்டிருக்கின்றது) வேண்டுகின்றது).</p>
+$string['phpversionhelp'] = '<p>Moodle குறைந்தளவு ஒரு PHP பதிப்பின் 4.3.0 or 5.1.0 ஐ (5.0.x அறியப்பட்ட பிரச்சினைகளின் ஒரு எண்ணிக்கையைக் கொண்டிருக்கின்றது) வேண்டுகின்றது.</p>
 <p>நீங்கள் தற்போதைய பதிப்பு {$a} ஐ இயக்குகின்றீர்கள்</p>
 <p>நீங்கள் PHP ஐ மேம்படுத்த  அல்லது PHP இன் ஒரு புதிய பதிப்புடன் ஒரு வழங்கியிற்கு நகர்த்த வேண்டும்!<br/>
 
old mode 100755 (executable)
new mode 100644 (file)
index bfdf6d1..4ab4aa0
@@ -531,6 +531,20 @@ $string['setpreferences'] = 'Set preferences';
 $string['setting'] = 'Setting';
 $string['settings'] = 'Settings';
 $string['setweights'] = 'Set weights';
+$string['showaverage'] = 'Show average';
+$string['showaverage_help'] = 'Show the average column? Students may be able to estimate other student\'s grades if the average is calculated from a small number of grades. For performance reasons the average is approximate if it is dependent on any hidden items.';
+$string['showfeedback'] = 'Show feedback';
+$string['showfeedback_help'] = 'Show the feedback column?';
+$string['showgrade'] = 'Show grades';
+$string['showgrade_help'] = 'Show the grade column?';
+$string['showlettergrade'] = 'Show letter grades';
+$string['showlettergrade_help'] = 'Show the letter grade column?';
+$string['showrange'] = 'Show ranges';
+$string['showrange_help'] = 'Show the range column?';
+$string['showweight'] = 'Show weightings';
+$string['showweight_help'] = 'Show the grade weight column?';
+$string['rangedecimals'] = 'Range decimal points';
+$string['rangedecimals_help'] = 'The number of decimal points to display for range.';
 $string['showactivityicons'] = 'Show activity icons';
 $string['showactivityicons_help'] = 'If enabled, activity icons are shown next to activity names.';
 $string['showallhidden'] = 'Show hidden';
@@ -557,7 +571,7 @@ $string['shownooutcomes'] = 'Hide outcomes';
 $string['shownumberofgrades'] = 'Show number of grades in averages';
 $string['shownumberofgrades_help'] = 'If enabled, the number of grades used when calculating the average (mean) is displayed in brackets after each average.';
 $string['showpercentage'] = 'Show percentage';
-$string['showpercentage_help'] = 'This setting determines whether the percentage value of each grade item is shown.';
+$string['showpercentage_help'] = 'Show the percentage value of each grade item?';
 $string['showquickfeedback'] = 'Show quick feedback';
 $string['showquickfeedback_help'] = 'If enabled, when editing is turned on, a feedback text input box with a dotted border appears for each grade, allowing the feedback for many grades to be edited at the same time. Changes are saved and highlighted when the update button is clicked.
 
@@ -565,7 +579,7 @@ Note that when feedback is edited in the grader report, an overridden flag is se
 $string['showranges'] = 'Show ranges';
 $string['showranges_help'] = 'If enabled, the grader report will contain an additional row displaying the range for each category and grade item.';
 $string['showrank'] = 'Show rank';
-$string['showrank_help'] = 'This setting determines whether the position of the student in relation to the rest of the class is shown for each grade item.';
+$string['showrank_help'] = 'Show the position of the student in relation to the rest of the class for each grade item?';
 $string['showuseridnumber'] = 'Show user ID numbers';
 $string['showuseridnumber_help'] = 'If enabled, user ID numbers are shown in an additional column.';
 $string['showuserimage'] = 'Show user profile images';
index 623f790..d00bef9 100644 (file)
@@ -48,7 +48,7 @@ try {
     $navigation = new global_navigation_for_ajax($PAGE, $branchtype, $branchid);
 
     $linkcategories = false;
-    
+
     if ($instanceid!==null) {
         // Get the db record for the block instance
         $blockrecord = $DB->get_record('block_instances', array('id'=>$instanceid,'blockname'=>'navigation'));
@@ -86,17 +86,17 @@ try {
         $block->trim($navigation, $trimmode, $trimlength, ceil($trimlength/2));
     }
     $converter = new navigation_json();
-    
+
     // Find the actuall branch we are looking for
     $branch = $navigation->find($branchid, $branchtype);
-    
+
     // Remove links to categories if required.
     if (!$linkcategories) {
         foreach ($branch->find_all_of_type(navigation_node::TYPE_CATEGORY) as $category) {
             $category->action = null;
         }
     }
-    
+
     // Stop buffering errors at this point
     $html = ob_get_contents();
     ob_end_clean();
@@ -116,6 +116,6 @@ if (empty($branch) || $branch->nodetype !== navigation_node::NODETYPE_BRANCH) {
 // Prepare an XML converter for the branch
 $converter->set_expandable($navigation->get_expandable());
 // Set XML headers
-header('Content-type: text/plain');
+header('Content-type: text/plain; charset=utf-8');
 // Convert and output the branch as XML
 echo $converter->convert($branch);
index 38729ea..e3e6d68 100644 (file)
@@ -727,7 +727,6 @@ $capabilities = array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
         'archetypes' => array(
-            'editingteacher' => CAP_ALLOW,
             'manager' => CAP_ALLOW
         )
     ),
old mode 100755 (executable)
new mode 100644 (file)
index 0ff739b..7580795
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20101121" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20110114" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
     <TABLE NAME="message" COMMENT="Stores all unread messages" PREVIOUS="log_display" NEXT="message_read">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="useridfrom"/>
-        <FIELD NAME="useridfrom" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="useridto"/>
-        <FIELD NAME="useridto" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="useridfrom" NEXT="subject"/>
+        <FIELD NAME="useridfrom" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="useridto"/>
+        <FIELD NAME="useridto" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="useridfrom" NEXT="subject"/>
         <FIELD NAME="subject" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" COMMENT="The message subject" PREVIOUS="useridto" NEXT="fullmessage"/>
         <FIELD NAME="fullmessage" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" PREVIOUS="subject" NEXT="fullmessageformat"/>
         <FIELD NAME="fullmessageformat" TYPE="int" LENGTH="4" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the full message" PREVIOUS="fullmessage" NEXT="fullmessagehtml"/>
     <TABLE NAME="message_read" COMMENT="Stores all messages that have been read" PREVIOUS="message" NEXT="message_contacts">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="useridfrom"/>
-        <FIELD NAME="useridfrom" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="useridto"/>
-        <FIELD NAME="useridto" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="useridfrom" NEXT="subject"/>
+        <FIELD NAME="useridfrom" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="useridto"/>
+        <FIELD NAME="useridto" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="useridfrom" NEXT="subject"/>
         <FIELD NAME="subject" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" COMMENT="The message subject" PREVIOUS="useridto" NEXT="fullmessage"/>
         <FIELD NAME="fullmessage" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" PREVIOUS="subject" NEXT="fullmessageformat"/>
         <FIELD NAME="fullmessageformat" TYPE="int" LENGTH="4" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the full message" PREVIOUS="fullmessage" NEXT="fullmessagehtml"/>
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" PREVIOUS="timecreated"/>
       </FIELDS>
       <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="contextid"/>
+        <KEY NAME="contextid" TYPE="foreign" FIELDS="contextid" REFTABLE="context" REFFIELDS="id" COMMENT="Relates to context.id" PREVIOUS="primary" NEXT="userid"/>
+        <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" COMMENT="Relates to user.id" PREVIOUS="contextid"/>
       </KEYS>
+      <INDEXES>
+        <INDEX NAME="itemid" UNIQUE="false" FIELDS="itemid"/>
+      </INDEXES>
     </TABLE>
     <TABLE NAME="license" COMMENT="store licenses used by moodle" PREVIOUS="rating" NEXT="registration_hubs">
       <FIELDS>
       </KEYS>
     </TABLE>
   </TABLES>
-</XMLDB>
+</XMLDB>
\ No newline at end of file
index 9bd9684..b45bf47 100644 (file)
@@ -239,7 +239,7 @@ function xmldb_main_upgrade($oldversion) {
         // add field
         $field = new xmldb_field('tiuserid');
         if (!$dbman->field_exists($table, $field)) {
-            $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'itemid');
+            $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, 'itemid');
             $dbman->add_field($table, $field);
         }
         // modify index
@@ -645,49 +645,49 @@ function xmldb_main_upgrade($oldversion) {
     if ($oldversion < 2008081500) {
     /// Changing the type of all the columns that the question bank uses to store grades to be NUMBER(12, 7).
         $table = new xmldb_table('question');
-        $field = new xmldb_field('defaultgrade', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'generalfeedback');
+        $field = new xmldb_field('defaultgrade', XMLDB_TYPE_NUMBER, '12, 7', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1.0000000', 'generalfeedback');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081500);
     }
 
     if ($oldversion < 2008081501) {
         $table = new xmldb_table('question');
-        $field = new xmldb_field('penalty', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'defaultgrade');
+        $field = new xmldb_field('penalty', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0.1000000', 'defaultgrade');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081501);
     }
 
     if ($oldversion < 2008081502) {
         $table = new xmldb_table('question_answers');
-        $field = new xmldb_field('fraction', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'answer');
+        $field = new xmldb_field('fraction', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'answer');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081502);
     }
 
     if ($oldversion < 2008081503) {
         $table = new xmldb_table('question_sessions');
-        $field = new xmldb_field('sumpenalty', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'newgraded');
+        $field = new xmldb_field('sumpenalty', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'newgraded');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081503);
     }
 
     if ($oldversion < 2008081504) {
         $table = new xmldb_table('question_states');
-        $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'event');
+        $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'event');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081504);
     }
 
     if ($oldversion < 2008081505) {
         $table = new xmldb_table('question_states');
-        $field = new xmldb_field('raw_grade', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'grade');
+        $field = new xmldb_field('raw_grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'grade');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081505);
     }
 
     if ($oldversion < 2008081506) {
         $table = new xmldb_table('question_states');
-        $field = new xmldb_field('penalty', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null, 'raw_grade');
+        $field = new xmldb_field('penalty', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'raw_grade');
         $dbman->change_field_type($table, $field);
         upgrade_main_savepoint(true, 2008081506);
     }
@@ -1552,7 +1552,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
         $table = new xmldb_table('block_instances');
 
     /// Rename field weight on table block_instances to defaultweight
-        $field = new xmldb_field('weight', XMLDB_TYPE_INTEGER, '3', null, XMLDB_NOTNULL, null, '0', 'position');
+        $field = new xmldb_field('weight', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, null, 'position');
         $dbman->rename_field($table, $field, 'defaultweight');
 
     /// Rename field position on table block_instances to defaultregion
@@ -1817,11 +1817,11 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
 
     /// Adding fields to table block_positions
         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('blockinstanceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
+        $table->add_field('blockinstanceid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
         $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
         $table->add_field('pagetype', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null);
         $table->add_field('subpage', XMLDB_TYPE_CHAR, '16', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('visible', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '1');
+        $table->add_field('visible', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
         $table->add_field('region', XMLDB_TYPE_CHAR, '16', null, XMLDB_NOTNULL, null, null);
         $table->add_field('weight', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
 
@@ -2351,19 +2351,19 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
 
     if ($oldversion < 2009110400) {
         // list of tables where we need to add new format field and convert texts
-        $extendtables = array('course' => 'summary',
-                              'course_categories' => 'description',
-                              'course_categories' => 'description',
-                              'course_request' => 'summary',
-                              'grade_outcomes' => 'description',
-                              'groups' => 'description',
-                              'groupings' => 'description',
-                              'scale' => 'description',
-                              'user_info_field' => 'description',
-                              'user_info_field' => 'defaultdata',
-                              'user_info_data' => 'data');
-
-        foreach ($extendtables as $tablestr=>$fieldstr) {
+        $extendtables = array('course'              => 'summary',
+                              'course_categories'   => 'description',
+                              'course_categories'   => 'description',
+                              'course_request'      => 'summary',
+                              'grade_outcomes'      => 'description',
+                              'groups'              => 'description',
+                              'groupings'           => 'description',
+                              'scale'               => 'description',
+                              'user_info_field'     => 'description',
+                              'user_info_field'     => 'defaultdata',
+                              'user_info_data'      => 'data');
+
+        foreach ($extendtables as $tablestr => $fieldstr) {
             $formatfieldstr = $fieldstr.'format';
 
             $table = new xmldb_table($tablestr);
@@ -2374,7 +2374,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
                 $dbman->add_field($table, $field);
             }
             if ($CFG->texteditors !== 'textarea') {
-                $rs = $DB->get_recordset($tablestr, array($formatfieldstr=>FORMAT_MOODLE), '', "id,$fieldstr,$formatfieldstr");
+                $rs = $DB->get_recordset($tablestr, array($formatfieldstr => FORMAT_MOODLE), '', "id,$fieldstr,$formatfieldstr");
                 foreach ($rs as $rec) {
                     $rec->$fieldstr       = text_to_html($rec->$fieldstr, false, false, true);
                     $rec->$formatfieldstr = FORMAT_HTML;
@@ -2382,6 +2382,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
                     upgrade_set_timeout();
                 }
                 $rs->close();
+                unset($rs);
             }
         }
 
@@ -2430,7 +2431,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
 
     if ($oldversion < 2010011200) {
         $table = new xmldb_table('grade_categories');
-        $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0);
+        $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'timemodified');
 
         if (!$dbman->field_exists($table, $field)) {
             $dbman->add_field($table, $field);
@@ -3594,8 +3595,8 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, 0);
         $table->add_field('name', XMLDB_TYPE_CHAR, '200', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('private', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0);
-        $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
+        $table->add_field('private', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1');
+        $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '6', null, XMLDB_NOTNULL, null, '0');
 
 
     /// Adding keys to table my_pages
@@ -5351,7 +5352,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
     //install.xml so there are 2.0 sites that are missing it.
     if ($oldversion < 2010101900) {
         $table = new xmldb_table('grade_categories');
-        $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0);
+        $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'timemodified');
 
         if (!$dbman->field_exists($table, $field)) {
             $dbman->add_field($table, $field);
@@ -5371,9 +5372,9 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
     //MDL-24771
     if ($oldversion < 2010102601) {
 
-        $fieldnotification = new xmldb_field('notification', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'smallmessage');
-        $fieldcontexturl = new xmldb_field('contexturl', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'notification');
-        $fieldcontexturlname = new xmldb_field('contexturlname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'contexturl');
+        $fieldnotification = new xmldb_field('notification', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, 0, 'smallmessage');
+        $fieldcontexturl = new xmldb_field('contexturl', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'notification');
+        $fieldcontexturlname = new xmldb_field('contexturlname', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'contexturl');
         $fieldstoadd = array($fieldnotification, $fieldcontexturl, $fieldcontexturlname);
 
         $tablestomodify = array(new xmldb_table('message'), new xmldb_table('message_read'));
@@ -5421,7 +5422,7 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
     if ($oldversion < 2010102700) {
 
         $table = new xmldb_table('post');
-        $field = new xmldb_field('uniquehash', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'content');
+        $field = new xmldb_field('uniquehash', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, 'content');
         // Launch change of precision for field name
         $dbman->change_field_precision($table, $field);
 
@@ -5512,6 +5513,449 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
         upgrade_main_savepoint(true, 2010121401);
     }
 
+    if ($oldversion < 2011011401) {
+        $columns = $DB->get_columns('block_instances');
+
+        // Check if we need to fix the default weight column
+        if (array_key_exists('defaultweight', $columns) && $columns['defaultweight']->max_length != 10) {
+            // Fix discrepancies in the block_instances table after upgrade from 1.9
+            $table = new xmldb_table('block_instances');
+
+            // defaultweight is smallint(3) after upgrade should be bigint 10
+            // Also fixed in earlier upgrade code
+            $field = new xmldb_field('defaultweight', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, null, 'defaultregion');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_type($table, $field);
+            }
+
+            // add missing key `blocinst_par_ix` (`parentcontextid`)
+            $index = new xmldb_index('parentcontextid', XMLDB_INDEX_NOTUNIQUE, array('parentcontextid'));
+            if (!$dbman->index_exists($table, $index)) {
+                $dbman->add_index($table, $index);
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2011011401);
+    }
+
+    if ($oldversion < 2011011402) {
+        // Fix discrepancies in the block_positions table after upgrade from 1.9
+        $table = new xmldb_table('block_positions');
+        $columns = $DB->get_columns('block_positions');
+
+        // Check if we need to fix the blockinstanceid field
+        if (array_key_exists('blockinstanceid', $columns) && empty($columns['blockinstanceid']->unsigned)) {
+            // Fix blockinstanceid
+            // First remove the indexs on the field
+            $indexone = new xmldb_index('blockinstanceid', XMLDB_INDEX_NOTUNIQUE, array('blockinstanceid'));
+            $indexall = new xmldb_index('blockinstanceid-contextid-pagetype-subpage', XMLDB_INDEX_UNIQUE, array('blockinstanceid','contextid','pagetype','subpage'));
+            if ($dbman->index_exists($table, $indexone)) {
+                $dbman->drop_index($table, $indexone);
+            }
+            if ($dbman->index_exists($table, $indexall)) {
+                $dbman->drop_index($table, $indexall);
+            }
+            // blockinstanceid should be unsigned
+            // Also fixed in earlier upgrade code
+            $field = new xmldb_field('blockinstanceid', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, 'id');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_unsigned($table, $field);
+            }
+
+            // Add the indexs back in
+            $dbman->add_index($table, $indexone);
+            $dbman->add_index($table, $indexall);
+        }
+
+        // Check if the visible field needs fixing.
+        if (array_key_exists('visible', $columns) && !empty($columns['visible']->has_default)) {
+            // visible shouldn't have a default
+            // Also fixed in earlier upgrade code
+            $field = new xmldb_field('visible', XMLDB_TYPE_INTEGER, 4, null, XMLDB_NOTNULL, null, null, 'subpage');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2011011402);
+    }
+
+    if ($oldversion < 2011011403) {
+        $columns = $DB->get_columns('grade_categories');
+        // Check if we need to fix the hidden field
+        if (array_key_exists('hidden', $columns) && $columns['hidden']->max_length != 1) {
+            // Fix discrepancies in the grade_categories table after upgrade from 1.9
+            $table = new xmldb_table('grade_categories');
+
+            // hidden should be tinyint(1)
+            // Also fixed in earlier upgrade code
+            $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, 1, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'timemodified');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_precision($table, $field);
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2011011403);
+    }
+
+    if ($oldversion < 2011011404) {
+        // Fix discrepancies in the message table after upgrade from 1.9
+        $columns = $DB->get_columns('message');
+        $table = new xmldb_table('message');
+
+        // Check if we need to fix the useridfrom field
+        if (array_key_exists('useridfrom', $columns) && empty($columns['useridfrom']->unsigned)) {
+            // useridfrom should be unsigned
+            $field = new xmldb_field('useridfrom', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'id');
+            $index = new xmldb_index('useridfrom', XMLDB_INDEX_NOTUNIQUE, array('useridfrom'));
+            if ($dbman->index_exists($table, $index)) {
+                $dbman->drop_index($table, $index);
+            }
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_unsigned($table, $field);
+            }
+            $dbman->add_index($table, $index);
+        }
+
+        // Check if we need to fix the useridto field
+        if (array_key_exists('useridto', $columns) && empty($columns['useridto']->unsigned)) {
+            // useridto should be unsigned
+            $field = new xmldb_field('useridto', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'useridfrom');
+            $index = new xmldb_index('useridto', XMLDB_INDEX_NOTUNIQUE, array('useridto'));
+            if ($dbman->index_exists($table, $index)) {
+                $dbman->drop_index($table, $index);
+            }
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_unsigned($table, $field);
+            }
+            $dbman->add_index($table, $index);
+        }
+
+        // Check if we need to fix the notification field
+        if (array_key_exists('notification', $columns) && !empty($columns['notification']->not_null)) {
+            // notification should allow null
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('notification', XMLDB_TYPE_INTEGER, 1, XMLDB_UNSIGNED, null, null, 0, 'smallmessage');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_notnull($table, $field);
+            }
+        }
+
+        // Check if we need to fix the contexturl field
+        if (array_key_exists('contexturl', $columns) && strpos($columns['contexturl']->type, 'text') === false) {
+            // contexturl should be text
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('contexturl', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'notification');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_type($table, $field);
+            }
+        }
+
+        // Check if we need to fix the contexturl field
+        if (array_key_exists('contexturlname', $columns) && strpos($columns['contexturlname']->type, 'text') === false) {
+            // contexturlname should be text
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('contexturlname', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'contexturl');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_type($table, $field);
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2011011404);
+    }
+
+    if ($oldversion < 2011011405) {
+        // Fix discrepancies in the message_read table after upgrade from 1.9
+        $columns = $DB->get_columns('message_read');
+        $table = new xmldb_table('message_read');
+
+        // Check if we need to fix the useridfrom field
+        if (array_key_exists('useridfrom', $columns) && empty($columns['useridfrom']->unsigned)) {
+            // useridfrom should be unsigned
+            $field = new xmldb_field('useridfrom', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'id');
+            $index = new xmldb_index('useridfrom', XMLDB_INDEX_NOTUNIQUE, array('useridfrom'));
+            if ($dbman->index_exists($table, $index)) {
+                $dbman->drop_index($table, $index);
+            }
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_unsigned($table, $field);
+            }
+            $dbman->add_index($table, $index);
+        }
+
+        // Check if we need to fix the useridto field
+        if (array_key_exists('useridto', $columns) && empty($columns['useridto']->unsigned)) {
+            // useridto should be unsigned
+            $field = new xmldb_field('useridto', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'useridfrom');
+            $index = new xmldb_index('useridto', XMLDB_INDEX_NOTUNIQUE, array('useridto'));
+            if ($dbman->index_exists($table, $index)) {
+                $dbman->drop_index($table, $index);
+            }
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_unsigned($table, $field);
+            }
+            $dbman->add_index($table, $index);
+        }
+
+        // Check if we need to fix the notification field
+        if (array_key_exists('notification', $columns) && !empty($columns['notification']->not_null)) {
+            // notification should allow null
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('notification', XMLDB_TYPE_INTEGER, 1, XMLDB_UNSIGNED, null, null, 0, 'smallmessage');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_notnull($table, $field);
+            }
+        }
+
+        // Check if we need to fix the contexturl field
+        if (array_key_exists('contexturl', $columns) && strpos($columns['contexturl']->type, 'text') === false) {
+            // contexturl should be text
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('contexturl', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'notification');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_type($table, $field);
+            }
+        }
+
+        // Check if we need to fix the contexturl field
+        if (array_key_exists('contexturlname', $columns) && strpos($columns['contexturlname']->type, 'text') === false) {
+            // contexturlname should be text
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('contexturlname', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'contexturl');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_type($table, $field);
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint(true, 2011011405);
+    }
+
+    if ($oldversion < 2011011406) {
+        // Fix discrepancies in the my_pages table after upgrade from 1.9
+        $columns = $DB->get_columns('my_pages');
+        $table = new xmldb_table('my_pages');
+
+        // Check if we need to fix the private column
+        if (array_key_exists('private', $columns) && $columns['private']->default_value != '1') {
+            // private should be default 1
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('private', XMLDB_TYPE_INTEGER, 1, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 1, 'name');
+            $index = new xmldb_index('user_idx', XMLDB_INDEX_NOTUNIQUE, array('userid','private'));
+            if ($dbman->index_exists($table, $index)) {
+                $dbman->drop_index($table, $index);
+            }
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+            $dbman->add_index($table, $index);
+        }
+
+        // Check if we need to fix the sortorder field
+        if (array_key_exists('sortorder', $columns) && !empty($columns['sortorder']->unsigned)) {
+            // Sortorder should not be unsigned
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('sortorder', XMLDB_TYPE_INTEGER, 6, null, XMLDB_NOTNULL, null, 0, 'private');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_notnull($table, $field);
+            }
+        }
+
+        upgrade_main_savepoint(true, 2011011406);
+    }
+
+    if ($oldversion < 2011011407) {
+        // Check if we need to fix post.uniquehash
+        $columns = $DB->get_columns('my_pages');
+        if (array_key_exists('uniquehash', $columns) && $columns['uniquehash']->max_length != 128) {
+            // Fix discrepancies in the post table after upgrade from 1.9
+            $table = new xmldb_table('post');
+
+            // Uniquehash should be 128 chars
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('uniquehash', XMLDB_TYPE_CHAR, 128, null, XMLDB_NOTNULL, null, null, 'content');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_precision($table, $field);
+            }
+        }
+
+        upgrade_main_savepoint(true, 2011011407);
+    }
+
+    if ($oldversion < 2011011408) {
+        // Fix question in the post table after upgrade from 1.9
+        $columns = $DB->get_columns('question');
+        $table = new xmldb_table('question');
+
+        // Check if we need to fix default grade
+        if (array_key_exists('defaultgrade', $columns) && (
+                empty($columns['defaultgrade']->unsigned) || 
+                empty($columns['defaultgrade']->not_null) || 
+                $columns['defaultgrade']->default_value !== '1.0000000')) {
+            // defaultgrade should be unsigned NOT NULL DEFAULT '1.0000000'
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('defaultgrade', XMLDB_TYPE_NUMBER, '12, 7', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1.0000000', 'generalfeedbackformat');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        // Check if we need to fix penalty
+        if (array_key_exists('penalty', $columns) && (empty($columns['penalty']->not_null) || $columns['penalty']->default_value !== '0.1000000')) {
+            // penalty should be NOT NULL DEFAULT '0.1000000'
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('penalty', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0.1000000', 'defaultgrade');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        upgrade_main_savepoint(true, 2011011408);
+    }
+
+    if ($oldversion < 2011011409) {
+        // Fix question_answers in the post table after upgrade from 1.9
+        $columns = $DB->get_columns('question_answers');
+        $table = new xmldb_table('question_answers');
+
+        if (array_key_exists('fraction', $columns) && empty($columns['fraction']->not_null)) {
+            // fraction should be NOT NULL DEFAULT '0.0000000',
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('fraction', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'feedback');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        upgrade_main_savepoint(true, 2011011409);
+    }
+
+    if ($oldversion < 2011011410) {
+        // Fix question_sessions in the post table after upgrade from 1.9
+        $columns = $DB->get_columns('question_sessions');
+        $table = new xmldb_table('question_sessions');
+
+        // Check if we need to fix sumpenalty
+        if (array_key_exists('sumpenalty', $columns) && empty($columns['sumpenalty']->not_null)) {
+            // sumpenalty should be NOT NULL DEFAULT '0.0000000',
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('sumpenalty', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'newgraded');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        upgrade_main_savepoint(true, 2011011410);
+    }
+
+    if ($oldversion < 2011011411) {
+        // Fix question_states in the post table after upgrade from 1.9
+        $columns = $DB->get_columns('question_states');
+        $table = new xmldb_table('question_states');
+
+        // Check if we need to fix grade
+        if (array_key_exists('grade', $columns) && empty($columns['grade']->not_null)) {
+            // grade should be NOT NULL DEFAULT '0.0000000',
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'event');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        // Check if we need to fix raw_grade
+        if (array_key_exists('raw_grade', $columns) && empty($columns['raw_grade']->not_null)) {
+            // raw_grade should be NOT NULL DEFAULT '0.0000000',
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('raw_grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'grade');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        // Check if we need to fix raw_grade
+        if (array_key_exists('penalty', $columns) && empty($columns['penalty']->not_null)) {
+            // penalty should be NOT NULL DEFAULT '0.0000000',
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('penalty', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'raw_grade');
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+        }
+
+        upgrade_main_savepoint(true, 2011011411);
+    }
+
+    if ($oldversion < 2011011412) {
+        // Fix tag_instance in the post table after upgrade from 1.9
+        $columns = $DB->get_columns('tag_instance');
+        $table = new xmldb_table('tag_instance');
+
+        // Check if we need to fix tiuserid
+        if (array_key_exists('tiuserid', $columns) && !empty($columns['tiuserid']->has_default)) {
+            // tiuserid should have no default
+            // Fixed in earlier upgrade code
+            $field = new xmldb_field('tiuserid', XMLDB_TYPE_INTEGER, 10, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, 'itemid');
+            $index = new xmldb_index('itemtype-itemid-tagid-tiuserid', XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid', 'tiuserid'));
+            if ($dbman->index_exists($table, $index)) {
+                $dbman->drop_index($table, $index);
+            }
+            if ($dbman->field_exists($table, $field)) {
+                $dbman->change_field_default($table, $field);
+            }
+            $dbman->add_index($table, $index);
+        }
+
+        upgrade_main_savepoint(true, 2011011412);
+    }
+
+    if ($oldversion < 2011011413) {
+        // Fix user_info_field in the post table after upgrade from 1.9
+        $table = new xmldb_table('user_info_field');
+
+        // Missing field descriptionformat
+        // Fixed in earlier upgrade code
+        $field = new xmldb_field('descriptionformat', XMLDB_TYPE_INTEGER, 2, XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'description');
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        upgrade_main_savepoint(true, 2011011413);
+    }
+
+    if ($oldversion < 2011011414) {
+        // Drop the adodb_logsql table if it exists... it was never actually used anyway.
+        $table = new xmldb_table('adodb_logsql');
+
+        if ($dbman->table_exists($table)) {
+            $dbman->drop_table($table);
+        }
+
+        upgrade_main_savepoint(true, 2011011414);
+    }
+    
+    if ($oldversion < 2011011415) {
+        //create the rating table indexes if required
+        $table = new xmldb_table('rating');
+        
+        $index = new xmldb_index('itemid', XMLDB_INDEX_NOTUNIQUE, array('itemid'));
+        if (!$dbman->index_exists($table, $index)) {
+            $dbman->add_index($table, $index);
+            
+            $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
+            $dbman->add_key($table, $key);
+            
+            $key = new xmldb_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
+            $dbman->add_key($table, $key);
+        }
+        
+        upgrade_main_savepoint(true, 2011011415);
+    }
+
     return true;
 }
 
index d4cb065..b22ca09 100644 (file)
@@ -264,15 +264,21 @@ class mysqli_native_moodle_database extends moodle_database {
         }
 
         $this->store_settings($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
-        unset($this->dboptions['dbsocket']);
 
+        // dbsocket is used ONLY if host is NULL or 'localhost',
+        // you can not disable it because it is always tried if dbhost is 'localhost'
+        if (!empty($this->dboptions['dbsocket']) and strpos($this->dboptions['dbsocket'], '/') !== false) {
+            $dbsocket = $this->dboptions['dbsocket'];
+        } else {
+            $dbsocket = ini_get('mysqli.default_socket');
+        }
         if (empty($this->dboptions['dbport'])) {
             $dbport = ini_get('mysqli.default_port');
         } else {
             $dbport = (int)$this->dboptions['dbport'];
         }
         ob_start();
-        $this->mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname, $dbport);
+        $this->mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbsocket);
         $dberr = ob_get_contents();
         ob_end_clean();
         $errorno = @$this->mysqli->connect_errno;
index d78bf57..030e954 100644 (file)
@@ -138,8 +138,11 @@ class pgsql_native_moodle_database extends moodle_database {
         // Unix socket connections should have lower overhead
         if (!empty($this->dboptions['dbsocket']) and ($this->dbhost === 'localhost' or $this->dbhost === '127.0.0.1')) {
             $connection = "user='$this->dbuser' password='$pass' dbname='$this->dbname'";
+            if (strpos($this->dboptions['dbsocket'], '/') !== false) {
+                $connection = $connection." host='".$this->dboptions['dbsocket']."'";
+            }
         } else {
-            $this->dboptions['dbsocket'] = 0;
+            $this->dboptions['dbsocket'] = '';
             if (empty($this->dbname)) {
                 // probably old style socket connection - do not add port
                 $port = "";
index 5a54a91..b0f3bf0 100644 (file)
@@ -158,7 +158,7 @@ class tinymce_texteditor extends texteditor {
         if (empty($CFG->xmlstrictheaders) and (!empty($options['legacy']) or !empty($options['noclean']) or !empty($options['trusted']))) {
             // now deal somehow with non-standard tags, people scream when we do not make moodle code xtml strict,
             // but they scream even more when we strip all tags that are not strict :-(
-            $params['valid_elements'] = '*[*]';
+            $params['valid_elements'] = 'script[src|type],*[*]'; // for some reason the *[*] does not inlcude javascript src attribute MDL-25836
             $params['invalid_elements'] = '';
         }
 
index fde432c..f530b04 100644 (file)
@@ -716,7 +716,8 @@ function environment_check_php_settings($version, $env_select) {
         $result = new environment_results('php_setting');
         $result->setStatus(false);
         $result->setErrorCode(NO_VERSION_DATA_FOUND);
-        return $result;
+        $results[] = $result;
+        return $results;
     }
 
 /// Extract the php_setting part
index 30eb421..dd9bbef 100644 (file)
@@ -792,10 +792,9 @@ function clean_param($param, $type) {
             }
 
         case PARAM_TAG:
-            //as long as magic_quotes_gpc is used, a backslash will be a
-            //problem, so remove *all* backslash.
-            //$param = str_replace('\\', '', $param);
-            //remove some nasties
+            // Please note it is not safe to use the tag name directly anywhere,
+            // it must be processed with s(), urlencode() before embedding anywhere.
+            // remove some nasties
             $param = preg_replace('~[[:cntrl:]]|[<>`]~u', '', $param);
             //convert many whitespace chars into one
             $param = preg_replace('/\s+/', ' ', $param);
@@ -803,7 +802,6 @@ function clean_param($param, $type) {
             $param = $textlib->substr(trim($param), 0, TAG_MAX_LENGTH);
             return $param;
 
-
         case PARAM_TAGLIST:
             $tags = explode(',', $param);
             $result = array();
@@ -3045,6 +3043,10 @@ function &get_fast_modinfo(&$course, $userid=0) {
         return $cache[$course->id];
     }
 
+    if (!property_exists($course, 'modinfo')) {
+        debugging('Coding problem - missing course modinfo property in get_fast_modinfo() call');
+    }
+
     if (empty($course->modinfo)) {
         // no modinfo yet - load it
         rebuild_course_cache($course->id);
index 3ffed7c..3dfdbf7 100644 (file)
@@ -237,11 +237,11 @@ class user_picture implements renderable {
 
         foreach (self::$fields as $field) {
             if ($field === 'id') {
-                if (isset($record->{$idalias})) {
+                if (property_exists($record, $idalias)) {
                     $return->id = $record->{$idalias};
                 }
             } else {
-                if (isset($record->{$fieldprefix.$field})) {
+                if (property_exists($record, $fieldprefix.$field)) {
                     $return->{$field} = $record->{$fieldprefix.$field};
                 }
             }
@@ -249,7 +249,7 @@ class user_picture implements renderable {
         // add extra fields if not already there
         if ($extrafields) {
             foreach ($extrafields as $e) {
-                if ($e === 'id' or isset($return->{$e})) {
+                if ($e === 'id' or property_exists($return, $e)) {
                     continue;
                 }
                 $return->{$e} = $record->{$fieldprefix.$e};
@@ -1038,6 +1038,12 @@ class html_writer {
 
         $attributes['name'] = $name;
 
+        if (!empty($attributes['disabled'])) {
+            $attributes['disabled'] = 'disabled';
+        } else {
+            unset($attributes['disabled']);
+        }
+
         $output = '';
         foreach ($options as $value=>$label) {
             if (is_array($label)) {
index 39a0ac5..bbcad53 100644 (file)
@@ -324,7 +324,7 @@ class core_renderer extends renderer_base {
             $output .= html_writer::empty_tag('link', array('rel' => 'alternate',
                     'type' => $type, 'title' => $alt->title, 'href' => $alt->url));
         }
-        
+
         if (!empty($CFG->additionalhtmlhead)) {
             $output .= "\n".$CFG->additionalhtmlhead;
         }
@@ -2719,9 +2719,9 @@ class core_renderer_ajax extends core_renderer {
     public function header() {
         // unfortunately YUI iframe upload does not support application/json
         if (!empty($_FILES)) {
-            @header('Content-type: text/plain');
+            @header('Content-type: text/plain; charset=utf-8');
         } else {
-            @header('Content-type: application/json');
+            @header('Content-type: application/json; charset=utf-8');
         }
 
         /// Headers to make it not cacheable and json
index 80e2198..f655068 100644 (file)
@@ -751,6 +751,12 @@ function session_gc() {
             $DB->delete_records('sessions', array('sid'=>$user->sid));
         }
         $rs->close();
+
+        $purgebefore = time() - $maxlifetime;
+        // delete expired sessions for guest user account
+        $DB->delete_records_select('sessions', 'userid = ? AND timemodified < ?', array($CFG->siteguest, $purgebefore));
+        // delete expired sessions for userid = 0 (not logged in)
+        $DB->delete_records_select('sessions', 'userid = 0 AND timemodified < ?', array($purgebefore));
     } catch (dml_exception $ex) {
         error_log('Error gc-ing sessions');
     }
index b1b9fbf..e677754 100644 (file)
@@ -162,7 +162,7 @@ if (defined('WEB_CRON_EMULATED_CLI')) {
 // Detect CLI maintenance mode - this is useful when you need to mess with database, such as during upgrades
 if (file_exists("$CFG->dataroot/climaintenance.html")) {
     if (!CLI_SCRIPT) {
-        header('Content-type: text/html');
+        header('Content-type: text/html; charset=utf-8');
         /// Headers to make it not cacheable and json
         header('Cache-Control: no-store, no-cache, must-revalidate');
         header('Cache-Control: post-check=0, pre-check=0', false);
index 33ddf81..cbf6ffd 100644 (file)
@@ -1268,7 +1268,7 @@ width: 80%; -moz-border-radius: 20px; padding: 15px">
                     $e->stacktrace = format_backtrace($backtrace, true);
                 }
             }
-            @header('Content-Type: application/json');
+            @header('Content-Type: application/json; charset=utf-8');
             echo json_encode($e);
             return;
         }
diff --git a/lib/simpletest/testcomponentlib.php b/lib/simpletest/testcomponentlib.php
new file mode 100644 (file)
index 0000000..a5918fc
--- /dev/null
@@ -0,0 +1,63 @@
+<?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/>.
+
+
+/**
+ * Unit tests for /lib/componentlib.class.php.
+ *
+ * @package   moodlecore
+ * @copyright 2011 Tomasz Muras
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+require_once($CFG->libdir.'/componentlib.class.php');
+
+class componentlib_test extends UnitTestCase {
+
+    public function test_component_installer() {
+        global $CFG;
+
+        $ci = new component_installer('http://download.moodle.org', 'unittest', 'downloadtests.zip');
+        $this->assertTrue($ci->check_requisites());
+
+        $destpath = $CFG->dataroot.'/downloadtests';
+
+        //carefully remove component files to enforce fresh installation
+        @unlink($destpath.'/'.'downloadtests.md5');
+        @unlink($destpath.'/'.'test.html');
+        @unlink($destpath.'/'.'test.jpg');
+        @rmdir($destpath);
+
+        $this->assertEqual(COMPONENT_NEEDUPDATE, $ci->need_upgrade());
+
+        $status = $ci->install();
+        $this->assertEqual(COMPONENT_INSTALLED, $status);
+        $this->assertEqual('9e94f74b3efb1ff6cf075dc6b2abf15c', $ci->get_component_md5());
+
+        //it's already installed, so Moodle should detect it's up to date
+        $this->assertEqual(COMPONENT_UPTODATE, $ci->need_upgrade());
+        $status = $ci->install();
+        $this->assertEqual(COMPONENT_UPTODATE, $status);
+
+        //check if correct files were downloaded
+        $this->assertEqual('2af180e813dc3f446a9bb7b6af87ce24', md5_file($destpath.'/'.'test.jpg'));
+        $this->assertEqual('47250a973d1b88d9445f94db4ef2c97a', md5_file($destpath.'/'.'test.html'));
+
+    }
+}
index 6674106..ffea131 100644 (file)
@@ -79,4 +79,10 @@ class filelib_test extends UnitTestCase {
         $postdata = format_postdata_for_curlcall($postdatatoconvert);
         $this->assertEqual($postdata, $expectedresult);
     }
+
+    public function test_download_file_content() {
+        $testhtml = "http://download.moodle.org/unittest/test.html";
+        $contents = download_file_content($testhtml);
+        $this->assertEqual('47250a973d1b88d9445f94db4ef2c97a', md5($contents));
+    }
 }
index 0ca721c..61f6708 100644 (file)
@@ -85,4 +85,30 @@ class user_picture_test extends UnitTestCase {
         }
         $this->assertEqual($returned->custom1, 'Value of custom1');
     }
+
+    public function test_user_picture_fields_unaliasing_null() {
+        $fields = user_picture::fields();
+        $fields = array_map('trim', explode(',', $fields));
+
+        $fakerecord = new stdClass();
+        $fakerecord->aliasedid = 42;
+        foreach ($fields as $field) {
+            if ($field !== 'id') {
+                $fakerecord->{'prefix'.$field} = "Value of $field";
+            }
+        }
+        $fakerecord->prefixcustom1 = 'Value of custom1';
+        $fakerecord->prefiximagealt = null;
+
+        $returned = user_picture::unalias($fakerecord, array('custom1'), 'aliasedid', 'prefix');
+
+        $this->assertEqual($returned->id, 42);
+        $this->assertEqual($returned->imagealt, null);
+        foreach ($fields as $field) {
+            if ($field !== 'id' and $field !== 'imagealt') {
+                $this->assertEqual($returned->{$field}, "Value of $field");
+            }
+        }
+        $this->assertEqual($returned->custom1, 'Value of custom1');
+    }
 }
index 7ae7766..ad3d5c5 100644 (file)
@@ -180,6 +180,8 @@ class CheckSpecifiedFieldsExpectation extends SimpleExpectation {
                 // OK
             } else if (is_null($value) && is_null($actual->$key)) {
                 // OK
+            } else if (!isset($actual->$key)) {
+                $mismatches[] = $key . ' (expected [' . $value . '] but was missing.';
             } else {
                 $mismatches[] = $key . ' (expected [' . $value . '] got [' . $actual->$key . '].';
             }
diff --git a/lib/yui/2.8.1/build/animation/animation-debug.js b/lib/yui/2.8.1/build/animation/animation-debug.js
deleted file mode 100644 (file)
index 13638e9..0000000
+++ /dev/null
@@ -1,1396 +0,0 @@
-/*
-Copyright (c) 2010, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.com/yui/license.html
-version: 2.8.1
-*/
-(function() {
-
-var Y = YAHOO.util;
-
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-*/
-
-/**
- * The animation module provides allows effects to be added to HTMLElements.
- * @module animation
- * @requires yahoo, event, dom
- */
-
-/**
- *
- * Base animation class that provides the interface for building animated effects.
- * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
- * @class Anim
- * @namespace YAHOO.util
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @requires YAHOO.util.CustomEvent
- * @constructor
- * @param {String | HTMLElement} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.  
- * Each attribute is an object with at minimum a "to" or "by" member defined.  
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-
-var Anim = function(el, attributes, duration, method) {
-    if (!el) {
-        YAHOO.log('element required to create Anim instance', 'error', 'Anim');
-    }
-    this.init(el, attributes, duration, method); 
-};
-
-Anim.NAME = 'Anim';
-
-Anim.prototype = {
-    /**
-     * Provides a readable name for the Anim instance.
-     * @method toString
-     * @return {String}
-     */
-    toString: function() {
-        var el = this.getEl() || {};
-        var id = el.id || el.tagName;
-        return (this.constructor.NAME + ': ' + id);
-    },
-    
-    patterns: { // cached for performance
-        noNegatives:        /width|height|opacity|padding/i, // keep at zero or above
-        offsetAttribute:  /^((width|height)|(top|left))$/, // use offsetValue as default
-        defaultUnit:        /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
-        offsetUnit:         /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
-    },
-    
-    /**
-     * Returns the value computed by the animation's "method".
-     * @method doMethod
-     * @param {String} attr The name of the attribute.
-     * @param {Number} start The value this attribute should start from for this animation.
-     * @param {Number} end  The value this attribute should end at for this animation.
-     * @return {Number} The Value to be applied to the attribute.
-     */
-    doMethod: function(attr, start, end) {
-        return this.method(this.currentFrame, start, end - start, this.totalFrames);
-    },
-    
-    /**
-     * Applies a value to an attribute.
-     * @method setAttribute
-     * @param {String} attr The name of the attribute.
-     * @param {Number} val The value to be applied to the attribute.
-     * @param {String} unit The unit ('px', '%', etc.) of the value.
-     */
-    setAttribute: function(attr, val, unit) {
-        var el = this.getEl();
-        if ( this.patterns.noNegatives.test(attr) ) {
-            val = (val > 0) ? val : 0;
-        }
-
-        if (attr in el && !('style' in el && attr in el.style)) {
-            el[attr] = val;
-        } else {
-            Y.Dom.setStyle(el, attr, val + unit);
-        }
-    },                        
-    
-    /**
-     * Returns current value of the attribute.
-     * @method getAttribute
-     * @param {String} attr The name of the attribute.
-     * @return {Number} val The current value of the attribute.
-     */
-    getAttribute: function(attr) {
-        var el = this.getEl();
-        var val = Y.Dom.getStyle(el, attr);
-
-        if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
-            return parseFloat(val);
-        }
-        
-        var a = this.patterns.offsetAttribute.exec(attr) || [];
-        var pos = !!( a[3] ); // top or left
-        var box = !!( a[2] ); // width or height
-        
-        if ('style' in el) {
-            // use offsets for width/height and abs pos top/left
-            if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
-                val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
-            } else { // default to zero for other 'auto'
-                val = 0;
-            }
-        } else if (attr in el) {
-            val = el[attr];
-        }
-
-        return val;
-    },
-    
-    /**
-     * Returns the unit to use when none is supplied.
-     * @method getDefaultUnit
-     * @param {attr} attr The name of the attribute.
-     * @return {String} The default unit to be used.
-     */
-    getDefaultUnit: function(attr) {
-         if ( this.patterns.defaultUnit.test(attr) ) {
-            return 'px';
-         }
-         
-         return '';
-    },
-        
-    /**
-     * Sets the actual values to be used during the animation.  Should only be needed for subclass use.
-     * @method setRuntimeAttribute
-     * @param {Object} attr The attribute object
-     * @private 
-     */
-    setRuntimeAttribute: function(attr) {
-        var start;
-        var end;
-        var attributes = this.attributes;
-
-        this.runtimeAttributes[attr] = {};
-        
-        var isset = function(prop) {
-            return (typeof prop !== 'undefined');
-        };
-        
-        if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
-            return false; // note return; nothing to animate to
-        }
-        
-        start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
-
-        // To beats by, per SMIL 2.1 spec
-        if ( isset(attributes[attr]['to']) ) {
-            end = attributes[attr]['to'];
-        } else if ( isset(attributes[attr]['by']) ) {
-            if (start.constructor == Array) {
-                end = [];
-                for (var i = 0, len = start.length; i < len; ++i) {
-                    end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by" 
-                }
-            } else {
-                end = start + attributes[attr]['by'] * 1;
-            }
-        }
-        
-        this.runtimeAttributes[attr].start = start;
-        this.runtimeAttributes[attr].end = end;
-
-        // set units if needed
-        this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
-                attributes[attr]['unit'] : this.getDefaultUnit(attr);
-        return true;
-    },
-
-    /**
-     * Constructor for Anim instance.
-     * @method init
-     * @param {String | HTMLElement} el Reference to the element that will be animated
-     * @param {Object} attributes The attribute(s) to be animated.  
-     * Each attribute is an object with at minimum a "to" or "by" member defined.  
-     * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
-     * All attribute names use camelCase.
-     * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
-     * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
-     */ 
-    init: function(el, attributes, duration, method) {
-        /**
-         * Whether or not the animation is running.
-         * @property isAnimated
-         * @private
-         * @type Boolean
-         */
-        var isAnimated = false;
-        
-        /**
-         * A Date object that is created when the animation begins.
-         * @property startTime
-         * @private
-         * @type Date
-         */
-        var startTime = null;
-        
-        /**
-         * The number of frames this animation was able to execute.
-         * @property actualFrames
-         * @private
-         * @type Int
-         */
-        var actualFrames = 0; 
-
-        /**
-         * The element to be animated.
-         * @property el
-         * @private
-         * @type HTMLElement
-         */
-        el = Y.Dom.get(el);
-        
-        /**
-         * The collection of attributes to be animated.  
-         * Each attribute must have at least a "to" or "by" defined in order to animate.  
-         * If "to" is supplied, the animation will end with the attribute at that value.  
-         * If "by" is supplied, the animation will end at that value plus its starting value. 
-         * If both are supplied, "to" is used, and "by" is ignored. 
-         * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
-         * @property attributes
-         * @type Object
-         */
-        this.attributes = attributes || {};
-        
-        /**
-         * The length of the animation.  Defaults to "1" (second).
-         * @property duration
-         * @type Number
-         */
-        this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
-        
-        /**
-         * The method that will provide values to the attribute(s) during the animation. 
-         * Defaults to "YAHOO.util.Easing.easeNone".
-         * @property method
-         * @type Function
-         */
-        this.method = method || Y.Easing.easeNone;
-
-        /**
-         * Whether or not the duration should be treated as seconds.
-         * Defaults to true.
-         * @property useSeconds
-         * @type Boolean
-         */
-        this.useSeconds = true; // default to seconds
-        
-        /**
-         * The location of the current animation on the timeline.
-         * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
-         * @property currentFrame
-         * @type Int
-         */
-        this.currentFrame = 0;
-        
-        /**
-         * The total number of frames to be executed.
-         * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
-         * @property totalFrames
-         * @type Int
-         */
-        this.totalFrames = Y.AnimMgr.fps;
-        
-        /**
-         * Changes the animated element
-         * @method setEl
-         */
-        this.setEl = function(element) {
-            el = Y.Dom.get(element);
-        };
-        
-        /**
-         * Returns a reference to the animated element.
-         * @method getEl
-         * @return {HTMLElement}
-         */
-        this.getEl = function() { return el; };
-        
-        /**
-         * Checks whether the element is currently animated.
-         * @method isAnimated
-         * @return {Boolean} current value of isAnimated.     
-         */
-        this.isAnimated = function() {
-            return isAnimated;
-        };
-        
-        /**
-         * Returns the animation start time.
-         * @method getStartTime
-         * @return {Date} current value of startTime.      
-         */
-        this.getStartTime = function() {
-            return startTime;
-        };        
-        
-        this.runtimeAttributes = {};
-        
-        var logger = {};
-        logger.log = function() {YAHOO.log.apply(window, arguments)};
-        
-        logger.log('creating new instance of ' + this);
-        
-        /**
-         * Starts the animation by registering it with the animation manager. 
-         * @method animate  
-         */
-        this.animate = function() {
-            if ( this.isAnimated() ) {
-                return false;
-            }
-            
-            this.currentFrame = 0;
-            
-            this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
-    
-            if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration 
-                this.totalFrames = 1; 
-            }
-            Y.AnimMgr.registerElement(this);
-            return true;
-        };
-          
-        /**
-         * Stops the animation.  Normally called by AnimMgr when animation completes.
-         * @method stop
-         * @param {Boolean} finish (optional) If true, animation will jump to final frame.
-         */ 
-        this.stop = function(finish) {
-            if (!this.isAnimated()) { // nothing to stop
-                return false;
-            }
-
-            if (finish) {
-                 this.currentFrame = this.totalFrames;
-                 this._onTween.fire();
-            }
-            Y.AnimMgr.stop(this);
-        };
-        
-        var onStart = function() {            
-            this.onStart.fire();
-            
-            this.runtimeAttributes = {};
-            for (var attr in this.attributes) {
-                this.setRuntimeAttribute(attr);
-            }
-            
-            isAnimated = true;
-            actualFrames = 0;
-            startTime = new Date(); 
-        };
-        
-        /**
-         * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
-         * @private
-         */
-         
-        var onTween = function() {
-            var data = {
-                duration: new Date() - this.getStartTime(),
-                currentFrame: this.currentFrame
-            };
-            
-            data.toString = function() {
-                return (
-                    'duration: ' + data.duration +
-                    ', currentFrame: ' + data.currentFrame
-                );
-            };
-            
-            this.onTween.fire(data);
-            
-            var runtimeAttributes = this.runtimeAttributes;
-            
-            for (var attr in runtimeAttributes) {
-                this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit); 
-            }
-            
-            actualFrames += 1;
-        };
-        
-        var onComplete = function() {
-            var actual_duration = (new Date() - startTime) / 1000 ;
-            
-            var data = {
-                duration: actual_duration,
-                frames: actualFrames,
-                fps: actualFrames / actual_duration
-            };
-            
-            data.toString = function() {
-                return (
-                    'duration: ' + data.duration +
-                    ', frames: ' + data.frames +
-                    ', fps: ' + data.fps
-                );
-            };
-            
-            isAnimated = false;
-            actualFrames = 0;
-            this.onComplete.fire(data);
-        };
-        
-        /**
-         * Custom event that fires after onStart, useful in subclassing
-         * @private
-         */    
-        this._onStart = new Y.CustomEvent('_start', this, true);
-
-        /**
-         * Custom event that fires when animation begins
-         * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
-         * @event onStart
-         */    
-        this.onStart = new Y.CustomEvent('start', this);
-        
-        /**
-         * Custom event that fires between each frame
-         * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
-         * @event onTween
-         */
-        this.onTween = new Y.CustomEvent('tween', this);
-        
-        /**
-         * Custom event that fires after onTween
-         * @private
-         */
-        this._onTween = new Y.CustomEvent('_tween', this, true);
-        
-        /**
-         * Custom event that fires when animation ends
-         * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
-         * @event onComplete
-         */
-        this.onComplete = new Y.CustomEvent('complete', this);
-        /**
-         * Custom event that fires after onComplete
-         * @private
-         */
-        this._onComplete = new Y.CustomEvent('_complete', this, true);
-
-        this._onStart.subscribe(onStart);
-        this._onTween.subscribe(onTween);
-        this._onComplete.subscribe(onComplete);
-    }
-};
-
-    Y.Anim = Anim;
-})();
-/**
- * Handles animation queueing and threading.
- * Used by Anim and subclasses.
- * @class AnimMgr
- * @namespace YAHOO.util
- */
-YAHOO.util.AnimMgr = new function() {
-    /** 
-     * Reference to the animation Interval.
-     * @property thread
-     * @private
-     * @type Int
-     */
-    var thread = null;
-    
-    /** 
-     * The current queue of registered animation objects.
-     * @property queue
-     * @private
-     * @type Array
-     */    
-    var queue = [];
-
-    /** 
-     * The number of active animations.
-     * @property tweenCount
-     * @private
-     * @type Int
-     */        
-    var tweenCount = 0;
-
-    /** 
-     * Base frame rate (frames per second). 
-     * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
-     * @property fps
-     * @type Int
-     * 
-     */
-    this.fps = 1000;
-
-    /** 
-     * Interval delay in milliseconds, defaults to fastest possible.
-     * @property delay
-     * @type Int
-     * 
-     */
-    this.delay = 1;
-
-    /**
-     * Adds an animation instance to the animation queue.
-     * All animation instances must be registered in order to animate.
-     * @method registerElement
-     * @param {object} tween The Anim instance to be be registered
-     */
-    this.registerElement = function(tween) {
-        queue[queue.length] = tween;
-        tweenCount += 1;
-        tween._onStart.fire();
-        this.start();
-    };
-    
-    /**
-     * removes an animation instance from the animation queue.
-     * All animation instances must be registered in order to animate.
-     * @method unRegister
-     * @param {object} tween The Anim instance to be be registered
-     * @param {Int} index The index of the Anim instance
-     * @private
-     */
-    this.unRegister = function(tween, index) {
-        index = index || getIndex(tween);
-        if (!tween.isAnimated() || index === -1) {
-            return false;
-        }
-        
-        tween._onComplete.fire();
-        queue.splice(index, 1);
-
-        tweenCount -= 1;
-        if (tweenCount <= 0) {
-            this.stop();
-        }
-
-        return true;
-    };
-    
-    /**
-     * Starts the animation thread.
-       * Only one thread can run at a time.
-     * @method start
-     */    
-    this.start = function() {
-        if (thread === null) {
-            thread = setInterval(this.run, this.delay);
-        }
-    };
-
-    /**
-     * Stops the animation thread or a specific animation instance.
-     * @method stop
-     * @param {object} tween A specific Anim instance to stop (optional)
-     * If no instance given, Manager stops thread and all animations.
-     */    
-    this.stop = function(tween) {
-        if (!tween) {
-            clearInterval(thread);
-            
-            for (var i = 0, len = queue.length; i < len; ++i) {
-                this.unRegister(queue[0], 0);  
-            }
-
-            queue = [];
-            thread = null;
-            tweenCount = 0;
-        }
-        else {
-            this.unRegister(tween);
-        }
-    };
-    
-    /**
-     * Called per Interval to handle each animation frame.
-     * @method run
-     */    
-    this.run = function() {
-        for (var i = 0, len = queue.length; i < len; ++i) {
-            var tween = queue[i];
-            if ( !tween || !tween.isAnimated() ) { continue; }
-
-            if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
-            {
-                tween.currentFrame += 1;
-                
-                if (tween.useSeconds) {
-                    correctFrame(tween);
-                }
-                tween._onTween.fire();          
-            }
-            else { YAHOO.util.AnimMgr.stop(tween, i); }
-        }
-    };
-    
-    var getIndex = function(anim) {
-        for (var i = 0, len = queue.length; i < len; ++i) {
-            if (queue[i] === anim) {
-                return i; // note return;
-            }
-        }
-        return -1;
-    };
-    
-    /**
-     * On the fly frame correction to keep animation on time.
-     * @method correctFrame
-     * @private
-     * @param {Object} tween The Anim instance being corrected.
-     */
-    var correctFrame = function(tween) {
-        var frames = tween.totalFrames;
-        var frame = tween.currentFrame;
-        var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
-        var elapsed = (new Date() - tween.getStartTime());
-        var tweak = 0;
-        
-        if (elapsed < tween.duration * 1000) { // check if falling behind
-            tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
-        } else { // went over duration, so jump to end
-            tweak = frames - (frame + 1); 
-        }
-        if (tweak > 0 && isFinite(tweak)) { // adjust if needed
-            if (tween.currentFrame + tweak >= frames) {// dont go past last frame
-                tweak = frames - (frame + 1);
-            }
-            
-            tween.currentFrame += tweak;      
-        }
-    };
-    this._queue = queue;
-    this._getIndex = getIndex;
-};
-/**
- * Used to calculate Bezier splines for any number of control points.
- * @class Bezier
- * @namespace YAHOO.util
- *
- */
-YAHOO.util.Bezier = new function() {
-    /**
-     * Get the current position of the animated element based on t.
-     * Each point is an array of "x" and "y" values (0 = x, 1 = y)
-     * At least 2 points are required (start and end).
-     * First point is start. Last point is end.
-     * Additional control points are optional.     
-     * @method getPosition
-     * @param {Array} points An array containing Bezier points
-     * @param {Number} t A number between 0 and 1 which is the basis for determining current position
-     * @return {Array} An array containing int x and y member data
-     */
-    this.getPosition = function(points, t) {  
-        var n = points.length;
-        var tmp = [];
-
-        for (var i = 0; i < n; ++i){
-            tmp[i] = [points[i][0], points[i][1]]; // save input
-        }
-        
-        for (var j = 1; j < n; ++j) {
-            for (i = 0; i < n - j; ++i) {
-                tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
-                tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; 
-            }
-        }
-    
-        return [ tmp[0][0], tmp[0][1] ]; 
-    
-    };
-};
-(function() {
-/**
- * Anim subclass for color transitions.
- * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233, 
- * [255,255,255], or rgb(255,255,255)</p>
- * @class ColorAnim
- * @namespace YAHOO.util
- * @requires YAHOO.util.Anim
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Bezier
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @constructor
- * @extends YAHOO.util.Anim
- * @param {HTMLElement | String} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.
- * Each attribute is an object with at minimum a "to" or "by" member defined.
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-    var ColorAnim = function(el, attributes, duration,  method) {
-        ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
-    };
-    
-    ColorAnim.NAME = 'ColorAnim';
-
-    ColorAnim.DEFAULT_BGCOLOR = '#fff';
-    // shorthand
-    var Y = YAHOO.util;
-    YAHOO.extend(ColorAnim, Y.Anim);
-
-    var superclass = ColorAnim.superclass;
-    var proto = ColorAnim.prototype;
-    
-    proto.patterns.color = /color$/i;
-    proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
-    proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
-    proto.patterns.hex3          = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
-    proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
-    
-    /**
-     * Attempts to parse the given string and return a 3-tuple.
-     * @method parseColor
-     * @param {String} s The string to parse.
-     * @return {Array} The 3-tuple of rgb values.
-     */
-    proto.parseColor = function(s) {
-        if (s.length == 3) { return s; }
-    
-        var c = this.patterns.hex.exec(s);
-        if (c && c.length == 4) {
-            return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
-        }
-    
-        c = this.patterns.rgb.exec(s);
-        if (c && c.length == 4) {
-            return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
-        }
-    
-        c = this.patterns.hex3.exec(s);
-        if (c && c.length == 4) {
-            return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
-        }
-        
-        return null;
-    };
-
-    proto.getAttribute = function(attr) {
-        var el = this.getEl();
-        if (this.patterns.color.test(attr) ) {
-            var val = YAHOO.util.Dom.getStyle(el, attr);
-            
-            var that = this;
-            if (this.patterns.transparent.test(val)) { // bgcolor default
-                var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
-                    return !that.patterns.transparent.test(val);
-                });
-
-                if (parent) {
-                    val = Y.Dom.getStyle(parent, attr);
-                } else {
-                    val = ColorAnim.DEFAULT_BGCOLOR;
-                }
-            }
-        } else {
-            val = superclass.getAttribute.call(this, attr);
-        }
-
-        return val;
-    };
-    
-    proto.doMethod = function(attr, start, end) {
-        var val;
-    
-        if ( this.patterns.color.test(attr) ) {
-            val = [];
-            for (var i = 0, len = start.length; i < len; ++i) {
-                val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
-            }
-            
-            val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
-        }
-        else {
-            val = superclass.doMethod.call(this, attr, start, end);
-        }
-
-        return val;
-    };
-
-    proto.setRuntimeAttribute = function(attr) {
-        superclass.setRuntimeAttribute.call(this, attr);
-        
-        if ( this.patterns.color.test(attr) ) {
-            var attributes = this.attributes;
-            var start = this.parseColor(this.runtimeAttributes[attr].start);
-            var end = this.parseColor(this.runtimeAttributes[attr].end);
-            // fix colors if going "by"
-            if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
-                end = this.parseColor(attributes[attr].by);
-            
-                for (var i = 0, len = start.length; i < len; ++i) {
-                    end[i] = start[i] + end[i];
-                }
-            }
-            
-            this.runtimeAttributes[attr].start = start;
-            this.runtimeAttributes[attr].end = end;
-        }
-    };
-
-    Y.ColorAnim = ColorAnim;
-})();
-/*!
-TERMS OF USE - EASING EQUATIONS
-Open source under the BSD License.
-Copyright 2001 Robert Penner All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
- * Singleton that determines how an animation proceeds from start to end.
- * @class Easing
- * @namespace YAHOO.util
-*/
-
-YAHOO.util.Easing = {
-
-    /**
-     * Uniform speed between points.
-     * @method easeNone
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeNone: function (t, b, c, d) {
-       return c*t/d + b;
-    },
-    
-    /**
-     * Begins slowly and accelerates towards end.
-     * @method easeIn
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeIn: function (t, b, c, d) {
-       return c*(t/=d)*t + b;
-    },
-
-    /**
-     * Begins quickly and decelerates towards end.
-     * @method easeOut
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeOut: function (t, b, c, d) {
-       return -c *(t/=d)*(t-2) + b;
-    },
-    
-    /**
-     * Begins slowly and decelerates towards end.
-     * @method easeBoth
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeBoth: function (t, b, c, d) {
-       if ((t/=d/2) < 1) {
-            return c/2*t*t + b;
-        }
-        
-       return -c/2 * ((--t)*(t-2) - 1) + b;
-    },
-    
-    /**
-     * Begins slowly and accelerates towards end.
-     * @method easeInStrong
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeInStrong: function (t, b, c, d) {
-       return c*(t/=d)*t*t*t + b;
-    },
-    
-    /**
-     * Begins quickly and decelerates towards end.
-     * @method easeOutStrong
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeOutStrong: function (t, b, c, d) {
-       return -c * ((t=t/d-1)*t*t*t - 1) + b;
-    },
-    
-    /**
-     * Begins slowly and decelerates towards end.
-     * @method easeBothStrong
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    easeBothStrong: function (t, b, c, d) {
-       if ((t/=d/2) < 1) {
-            return c/2*t*t*t*t + b;
-        }
-        
-       return -c/2 * ((t-=2)*t*t*t - 2) + b;
-    },
-
-    /**
-     * Snap in elastic effect.
-     * @method elasticIn
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @param {Number} a Amplitude (optional)
-     * @param {Number} p Period (optional)
-     * @return {Number} The computed value for the current animation frame
-     */
-
-    elasticIn: function (t, b, c, d, a, p) {
-       if (t == 0) {
-            return b;
-        }
-        if ( (t /= d) == 1 ) {
-            return b+c;
-        }
-        if (!p) {
-            p=d*.3;
-        }
-        
-       if (!a || a < Math.abs(c)) {
-            a = c; 
-            var s = p/4;
-        }
-       else {
-            var s = p/(2*Math.PI) * Math.asin (c/a);
-        }
-        
-       return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
-    },
-
-    /**
-     * Snap out elastic effect.
-     * @method elasticOut
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @param {Number} a Amplitude (optional)
-     * @param {Number} p Period (optional)
-     * @return {Number} The computed value for the current animation frame
-     */
-    elasticOut: function (t, b, c, d, a, p) {
-       if (t == 0) {
-            return b;
-        }
-        if ( (t /= d) == 1 ) {
-            return b+c;
-        }
-        if (!p) {
-            p=d*.3;
-        }
-        
-       if (!a || a < Math.abs(c)) {
-            a = c;
-            var s = p / 4;
-        }
-       else {
-            var s = p/(2*Math.PI) * Math.asin (c/a);
-        }
-        
-       return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
-    },
-    
-    /**
-     * Snap both elastic effect.
-     * @method elasticBoth
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @param {Number} a Amplitude (optional)
-     * @param {Number} p Period (optional)
-     * @return {Number} The computed value for the current animation frame
-     */
-    elasticBoth: function (t, b, c, d, a, p) {
-       if (t == 0) {
-            return b;
-        }
-        
-        if ( (t /= d/2) == 2 ) {
-            return b+c;
-        }
-        
-        if (!p) {
-            p = d*(.3*1.5);
-        }
-        
-       if ( !a || a < Math.abs(c) ) {
-            a = c; 
-            var s = p/4;
-        }
-       else {
-            var s = p/(2*Math.PI) * Math.asin (c/a);
-        }
-        
-       if (t < 1) {
-            return -.5*(a*Math.pow(2,10*(t-=1)) * 
-                    Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
-        }
-       return a*Math.pow(2,-10*(t-=1)) * 
-                Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
-    },
-
-
-    /**
-     * Backtracks slightly, then reverses direction and moves to end.
-     * @method backIn
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @param {Number} s Overshoot (optional)
-     * @return {Number} The computed value for the current animation frame
-     */
-    backIn: function (t, b, c, d, s) {
-       if (typeof s == 'undefined') {
-            s = 1.70158;
-        }
-       return c*(t/=d)*t*((s+1)*t - s) + b;
-    },
-
-    /**
-     * Overshoots end, then reverses and comes back to end.
-     * @method backOut
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @param {Number} s Overshoot (optional)
-     * @return {Number} The computed value for the current animation frame
-     */
-    backOut: function (t, b, c, d, s) {
-       if (typeof s == 'undefined') {
-            s = 1.70158;
-        }
-       return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
-    },
-    
-    /**
-     * Backtracks slightly, then reverses direction, overshoots end, 
-     * then reverses and comes back to end.
-     * @method backBoth
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @param {Number} s Overshoot (optional)
-     * @return {Number} The computed value for the current animation frame
-     */
-    backBoth: function (t, b, c, d, s) {
-       if (typeof s == 'undefined') {
-            s = 1.70158; 
-        }
-        
-       if ((t /= d/2 ) < 1) {
-            return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
-        }
-       return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
-    },
-
-    /**
-     * Bounce off of start.
-     * @method bounceIn
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    bounceIn: function (t, b, c, d) {
-       return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
-    },
-    
-    /**
-     * Bounces off end.
-     * @method bounceOut
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    bounceOut: function (t, b, c, d) {
-       if ((t/=d) < (1/2.75)) {
-               return c*(7.5625*t*t) + b;
-       } else if (t < (2/2.75)) {
-               return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
-       } else if (t < (2.5/2.75)) {
-               return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
-       }
-        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
-    },
-    
-    /**
-     * Bounces off start and end.
-     * @method bounceBoth
-     * @param {Number} t Time value used to compute current value
-     * @param {Number} b Starting value
-     * @param {Number} c Delta between start and end values
-     * @param {Number} d Total length of animation
-     * @return {Number} The computed value for the current animation frame
-     */
-    bounceBoth: function (t, b, c, d) {
-       if (t < d/2) {
-            return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
-        }
-       return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
-    }
-};
-
-(function() {
-/**
- * Anim subclass for moving elements along a path defined by the "points" 
- * member of "attributes".  All "points" are arrays with x, y coordinates.
- * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
- * @class Motion
- * @namespace YAHOO.util
- * @requires YAHOO.util.Anim
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Bezier
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @requires YAHOO.util.CustomEvent 
- * @constructor
- * @extends YAHOO.util.ColorAnim
- * @param {String | HTMLElement} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.  
- * Each attribute is an object with at minimum a "to" or "by" member defined.  
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-    var Motion = function(el, attributes, duration,  method) {
-        if (el) { // dont break existing subclasses not using YAHOO.extend
-            Motion.superclass.constructor.call(this, el, attributes, duration, method);
-        }
-    };
-
-
-    Motion.NAME = 'Motion';
-
-    // shorthand
-    var Y = YAHOO.util;
-    YAHOO.extend(Motion, Y.ColorAnim);
-    
-    var superclass = Motion.superclass;
-    var proto = Motion.prototype;
-
-    proto.patterns.points = /^points$/i;
-    
-    proto.setAttribute = function(attr, val, unit) {
-        if (  this.patterns.points.test(attr) ) {
-            unit = unit || 'px';
-            superclass.setAttribute.call(this, 'left', val[0], unit);
-            superclass.setAttribute.call(this, 'top', val[1], unit);
-        } else {
-            superclass.setAttribute.call(this, attr, val, unit);
-        }
-    };
-
-    proto.getAttribute = function(attr) {
-        if (  this.patterns.points.test(attr) ) {
-            var val = [
-                superclass.getAttribute.call(this, 'left'),
-                superclass.getAttribute.call(this, 'top')
-            ];
-        } else {
-            val = superclass.getAttribute.call(this, attr);
-        }
-
-        return val;
-    };
-
-    proto.doMethod = function(attr, start, end) {
-        var val = null;
-
-        if ( this.patterns.points.test(attr) ) {
-            var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;                            
-            val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
-        } else {
-            val = superclass.doMethod.call(this, attr, start, end);
-        }
-        return val;
-    };
-
-    proto.setRuntimeAttribute = function(attr) {
-        if ( this.patterns.points.test(attr) ) {
-            var el = this.getEl();
-            var attributes = this.attributes;
-            var start;
-            var control = attributes['points']['control'] || [];
-            var end;
-            var i, len;
-            
-            if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
-                control = [control];
-            } else { // break reference to attributes.points.control
-                var tmp = []; 
-                for (i = 0, len = control.length; i< len; ++i) {
-                    tmp[i] = control[i];
-                }
-                control = tmp;
-            }
-
-            if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
-                Y.Dom.setStyle(el, 'position', 'relative');
-            }
-    
-            if ( isset(attributes['points']['from']) ) {
-                Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
-            } 
-            else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
-            
-            start = this.getAttribute('points'); // get actual top & left
-            
-            // TO beats BY, per SMIL 2.1 spec
-            if ( isset(attributes['points']['to']) ) {
-                end = translateValues.call(this, attributes['points']['to'], start);
-                
-                var pageXY = Y.Dom.getXY(this.getEl());
-                for (i = 0, len = control.length; i < len; ++i) {
-                    control[i] = translateValues.call(this, control[i], start);
-                }
-
-                
-            } else if ( isset(attributes['points']['by']) ) {
-                end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
-                
-                for (i = 0, len = control.length; i < len; ++i) {
-                    control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
-                }
-            }
-
-            this.runtimeAttributes[attr] = [start];
-            
-            if (control.length > 0) {
-                this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control); 
-            }
-
-            this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
-        }
-        else {
-            superclass.setRuntimeAttribute.call(this, attr);
-        }
-    };
-    
-    var translateValues = function(val, start) {
-        var pageXY = Y.Dom.getXY(this.getEl());
-        val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
-
-        return val; 
-    };
-    
-    var isset = function(prop) {
-        return (typeof prop !== 'undefined');
-    };
-
-    Y.Motion = Motion;
-})();
-(function() {
-/**
- * Anim subclass for scrolling elements to a position defined by the "scroll"
- * member of "attributes".  All "scroll" members are arrays with x, y scroll positions.
- * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
- * @class Scroll
- * @namespace YAHOO.util
- * @requires YAHOO.util.Anim
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Bezier
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @requires YAHOO.util.CustomEvent 
- * @extends YAHOO.util.ColorAnim
- * @constructor
- * @param {String or HTMLElement} el Reference to the element that will be animated