~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to lib/pagelib.php

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
 * @property-read array $legacythemeinuse True if the legacy browser theme is in use.
81
81
 * @property-read navbar $navbar The navbar object used to display the navbar
82
82
 * @property-read global_navigation $navigation The navigation structure for this page.
83
 
 * @property-read xml_container_stack $opencontainers Tracks XHTML tags on this page that have been opened but not closed.
 
83
 * @property-read xhtml_container_stack $opencontainers Tracks XHTML tags on this page that have been opened but not closed.
84
84
 *      mainly for internal use by the rendering code.
85
85
 * @property-read string $pagelayout The general type of page this is. For example 'normal', 'popup', 'home'.
86
86
 *      Allows the theme to display things differently, if it wishes to.
219
219
    protected $_alternateversions = array();
220
220
 
221
221
    /**
222
 
     * @var block_manager The blocks manager for this page. It is reponsible for
 
222
     * @var block_manager The blocks manager for this page. It is responsible for
223
223
     * the blocks and there content on this page.
224
224
     */
225
225
    protected $_blocks = null;
226
226
 
227
227
    /**
228
 
     * @var page_requirements_manager Page requirements manager. It is reponsible
 
228
     * @var page_requirements_manager Page requirements manager. It is responsible
229
229
     * for all JavaScript and CSS resources required by this page.
230
230
     */
231
231
    protected $_requires = null;
443
443
    protected function magic_get_context() {
444
444
        if (is_null($this->_context)) {
445
445
            if (CLI_SCRIPT or NO_MOODLE_COOKIES) {
446
 
                // cli scripts work in system context, do not annoy devs with debug info
447
 
                // very few scripts do not use cookies, we can safely use system as default context there
 
446
                // Cli scripts work in system context, do not annoy devs with debug info.
 
447
                // Very few scripts do not use cookies, we can safely use system as default context there.
448
448
            } else {
449
449
                debugging('Coding problem: $PAGE->context was not set. You may have forgotten '
450
450
                    .'to call require_login() or $PAGE->set_context(). The page may not display '
573
573
 
574
574
    /**
575
575
     * Please do not call this method directly, use the ->blocks syntax. {@link moodle_page::__get()}.
576
 
     * @return blocks_manager the blocks manager object for this page.
 
576
     * @return block_manager the blocks manager object for this page.
577
577
     */
578
578
    protected function magic_get_blocks() {
579
579
        global $CFG;
596
596
     * @return page_requirements_manager tracks the JavaScript, CSS files, etc. required by this page.
597
597
     */
598
598
    protected function magic_get_requires() {
599
 
        global $CFG;
600
599
        if (is_null($this->_requires)) {
601
600
            $this->_requires = new page_requirements_manager();
602
601
        }
660
659
     */
661
660
    protected function magic_get_devicetypeinuse() {
662
661
        if (empty($this->_devicetypeinuse)) {
663
 
            $this->_devicetypeinuse = get_user_device_type();
 
662
            $this->_devicetypeinuse = core_useragent::get_user_device_type();
664
663
        }
665
664
        return $this->_devicetypeinuse;
666
665
    }
727
726
     *
728
727
     * @param string $name property name
729
728
     * @return mixed
 
729
     * @throws coding_exception
730
730
     */
731
731
    public function __get($name) {
732
732
        $getmethod = 'magic_get_' . $name;
748
748
     * @param string $name property name
749
749
     * @param mixed $value Value
750
750
     * @return void Throws exception if field not defined in page class
 
751
     * @throws coding_exception
751
752
     */
752
753
    public function __set($name, $value) {
753
754
        if (method_exists($this, 'set_' . $name)) {
757
758
        }
758
759
    }
759
760
 
760
 
    // Other information getting methods ==========================================
 
761
    // Other information getting methods ==========================================.
761
762
 
762
763
    /**
763
764
     * Returns instance of page renderer
768
769
     * @return renderer_base
769
770
     */
770
771
    public function get_renderer($component, $subtype = null, $target = null) {
 
772
        if ($this->pagelayout === 'maintenance') {
 
773
            // If the page is using the maintenance layout then we're going to force target to maintenance.
 
774
            // This leads to a special core renderer that is designed to block access to API's that are likely unavailable for this
 
775
            // page layout.
 
776
            $target = RENDERER_TARGET_MAINTENANCE;
 
777
        }
771
778
        return $this->magic_get_theme()->get_renderer($this, $component, $subtype, $target);
772
779
    }
773
780
 
811
818
    }
812
819
 
813
820
    /**
814
 
     * Get a description of this page. Normally displayed in the footer in
815
 
     * developer debug mode.
 
821
     * Get a description of this page. Normally displayed in the footer in developer debug mode.
816
822
     * @return string
817
823
     */
818
824
    public function debug_summary() {
819
825
        $summary = '';
820
826
        $summary .= 'General type: ' . $this->pagelayout . '. ';
821
827
        if (!during_initial_install()) {
822
 
            $summary .= 'Context ' . print_context_name($this->_context) . ' (context id ' . $this->_context->id . '). ';
 
828
            $summary .= 'Context ' . $this->context->get_context_name() . ' (context id ' . $this->_context->id . '). ';
823
829
        }
824
830
        $summary .= 'Page type ' . $this->pagetype .  '. ';
825
831
        if ($this->subpage) {
826
 
            'Sub-page ' . $this->subpage .  '. ';
 
832
            $summary .= 'Sub-page ' . $this->subpage .  '. ';
827
833
        }
828
834
        return $summary;
829
835
    }
830
836
 
831
 
    // Setter methods =============================================================
 
837
    // Setter methods =============================================================.
832
838
 
833
839
    /**
834
 
     * Set the state. The state must be one of that STATE_... constants, and
835
 
     * the state is only allowed to advance one step at a time.
836
 
     *
837
 
     * @param integer $state The new state.
 
840
     * Set the state.
 
841
     *
 
842
     * The state must be one of that STATE_... constants, and the state is only allowed to advance one step at a time.
 
843
     *
 
844
     * @param int $state The new state.
 
845
     * @throws coding_exception
838
846
     */
839
847
    public function set_state($state) {
840
848
        if ($state != $this->_state + 1 || $state > self::STATE_DONE) {
860
868
     * Sets $PAGE->context to the course context, if it is not already set.
861
869
     *
862
870
     * @param stdClass $course the course to set as the global course.
 
871
     * @throws coding_exception
863
872
     */
864
873
    public function set_course($course) {
865
874
        global $COURSE, $PAGE, $CFG, $SITE;
885
894
            $this->set_context(context_course::instance($this->_course->id));
886
895
        }
887
896
 
888
 
        // notify course format that this page is set for the course
 
897
        // Notify course format that this page is set for the course.
889
898
        if ($this->_course->id != $SITE->id) {
890
899
            require_once($CFG->dirroot.'/course/lib.php');
891
900
            $courseformat = course_get_format($this->_course);
899
908
    /**
900
909
     * Set the main context to which this page belongs.
901
910
     *
902
 
     * @param context $context a context object, normally obtained with get_context_instance.
 
911
     * @param context $context a context object. You normally get this with context_xxxx::instance().
903
912
     */
904
913
    public function set_context($context) {
905
914
        if ($context === null) {
906
 
            // extremely ugly hack which sets context to some value in order to prevent warnings,
 
915
            // Extremely ugly hack which sets context to some value in order to prevent warnings,
907
916
            // use only for core error handling!!!!
908
917
            if (!$this->_context) {
909
918
                $this->_context = context_system::instance();
911
920
            return;
912
921
        }
913
922
 
914
 
        // ideally we should set context only once
915
 
        if (isset($this->_context)) {
916
 
            if ($context->id == $this->_context->id) {
917
 
                // fine - no change needed
918
 
            } else if ($this->_context->contextlevel == CONTEXT_SYSTEM or $this->_context->contextlevel == CONTEXT_COURSE) {
919
 
                // hmm - not ideal, but it might produce too many warnings due to the design of require_login
920
 
            } else if ($this->_context->contextlevel == CONTEXT_MODULE and $this->_context->id == get_parent_contextid($context)) {
921
 
                // hmm - most probably somebody did require_login() and after that set the block context
 
923
        // Ideally we should set context only once.
 
924
        if (isset($this->_context) && $context->id !== $this->_context->id) {
 
925
            $current = $this->_context->contextlevel;
 
926
            if ($current == CONTEXT_SYSTEM or $current == CONTEXT_COURSE) {
 
927
                // Hmm - not ideal, but it might produce too many warnings due to the design of require_login.
 
928
            } else if ($current == CONTEXT_MODULE and ($parentcontext = $context->get_parent_context()) and
 
929
                $this->_context->id == $parentcontext->id) {
 
930
                // Hmm - most probably somebody did require_login() and after that set the block context.
922
931
            } else {
923
 
                // we do not want devs to do weird switching of context levels on the fly,
924
 
                // because we might have used the context already such as in text filter in page title
925
 
                debugging('Coding problem: unsupported modification of PAGE->context from '.$this->_context->contextlevel.' to '.$context->contextlevel);
 
932
                // We do not want devs to do weird switching of context levels on the fly because we might have used
 
933
                // the context already such as in text filter in page title.
 
934
                debugging("Coding problem: unsupported modification of PAGE->context from {$current} to {$context->contextlevel}");
926
935
            }
927
936
        }
928
937
 
936
945
     * @param stdClass $course
937
946
     * @param stdClass $module
938
947
     * @return void
 
948
     * @throws coding_exception
939
949
     */
940
950
    public function set_cm($cm, $course = null, $module = null) {
941
951
        global $DB, $CFG, $SITE;
942
952
 
943
953
        if (!isset($cm->id) || !isset($cm->course)) {
944
 
            throw new coding_exception('Invalid $cm parameter for $PAGE object, it has to be instance of cm_info or record from the course_modules table.');
 
954
            throw new coding_exception('Invalid $cm. It has to be instance of cm_info or record from the course_modules table.');
945
955
        }
946
956
 
947
957
        if (!$this->_course || $this->_course->id != $cm->course) {
954
964
            $this->set_course($course);
955
965
        }
956
966
 
957
 
        // make sure we have a $cm from get_fast_modinfo as this contains activity access details
 
967
        // Make sure we have a $cm from get_fast_modinfo as this contains activity access details.
958
968
        if (!($cm instanceof cm_info)) {
959
969
            $modinfo = get_fast_modinfo($this->_course);
960
970
            $cm = $modinfo->get_cm($cm->id);
961
971
        }
962
972
        $this->_cm = $cm;
963
973
 
964
 
        // unfortunately the context setting is a mess, let's try to work around some common block problems and show some debug messages
 
974
        // Unfortunately the context setting is a mess.
 
975
        // Let's try to work around some common block problems and show some debug messages.
965
976
        if (empty($this->_context) or $this->_context->contextlevel != CONTEXT_BLOCK) {
966
977
            $context = context_module::instance($cm->id);
967
978
            $this->set_context($context);
971
982
            $this->set_activity_record($module);
972
983
        }
973
984
 
974
 
        // notify course format that this page is set for the course module
 
985
        // Notify course format that this page is set for the course module.
975
986
        if ($this->_course->id != $SITE->id) {
976
987
            require_once($CFG->dirroot.'/course/lib.php');
977
988
            course_get_format($this->_course)->page_set_cm($this);
983
994
     * module. For instance if the current module (cm) is a forum this should be a row
984
995
     * from the forum table.
985
996
     *
986
 
     * @param stdClass $module A row from the main database table for the module that this
987
 
     * page belongs to.
988
 
     * @return void
 
997
     * @param stdClass $module A row from the main database table for the module that this page belongs to.
 
998
     * @throws coding_exception
989
999
     */
990
1000
    public function set_activity_record($module) {
991
1001
        if (is_null($this->_cm)) {
992
1002
            throw new coding_exception('You cannot call $PAGE->set_activity_record until after $PAGE->cm has been set.');
993
1003
        }
994
1004
        if ($module->id != $this->_cm->instance || $module->course != $this->_course->id) {
995
 
            throw new coding_exception('The activity record your are trying to set does not seem to correspond to the cm that has been set.');
 
1005
            throw new coding_exception('The activity record does not seem to correspond to the cm that has been set.');
996
1006
        }
997
1007
        $this->_module = $module;
998
1008
    }
1032
1042
     * @param string $pagelayout the page layout this is. For example 'popup', 'home'.
1033
1043
     */
1034
1044
    public function set_pagelayout($pagelayout) {
1035
 
        /**
1036
 
         * Uncomment this to debug theme pagelayout issues like missing blocks.
1037
 
         *
1038
 
         * if (!empty($this->_wherethemewasinitialised) && $pagelayout != $this->_pagelayout) {
1039
 
         *     debugging('Page layout has already been set and cannot be changed.', DEBUG_DEVELOPER);
1040
 
         * }
1041
 
         */
 
1045
        // Uncomment this to debug theme pagelayout issues like missing blocks.
 
1046
        // if (!empty($this->_wherethemewasinitialised) && $pagelayout != $this->_pagelayout)
 
1047
        //     debugging('Page layout has already been set and cannot be changed.', DEBUG_DEVELOPER);
1042
1048
        $this->_pagelayout = $pagelayout;
1043
1049
    }
1044
1050
 
1061
1067
     * Adds a CSS class to the body tag of the page.
1062
1068
     *
1063
1069
     * @param string $class add this class name ot the class attribute on the body tag.
 
1070
     * @throws coding_exception
1064
1071
     */
1065
1072
    public function add_body_class($class) {
1066
1073
        if ($this->_state > self::STATE_BEFORE_HEADER) {
1120
1127
     * the category must be the one that the course belongs to. This also
1121
1128
     * automatically sets the page context to the category context.
1122
1129
     *
1123
 
     * @param integer $categoryid The id of the category to set.
 
1130
     * @param int $categoryid The id of the category to set.
 
1131
     * @throws coding_exception
1124
1132
     */
1125
1133
    public function set_category_by_id($categoryid) {
1126
 
        global $SITE, $DB;
 
1134
        global $SITE;
1127
1135
        if (!is_null($this->_course)) {
1128
 
            throw new coding_exception('Attempt to manually set the course category when the course has been set. This is not allowed.');
 
1136
            throw new coding_exception('Course has already been set. You cannot change the category now.');
1129
1137
        }
1130
1138
        if (is_array($this->_categories)) {
1131
 
            throw new coding_exception('Course category has already been set. You are not allowed to change it.');
 
1139
            throw new coding_exception('Course category has already been set. You cannot to change it now.');
1132
1140
        }
1133
1141
        $this->ensure_theme_not_set();
1134
1142
        $this->set_course($SITE);
1150
1158
    }
1151
1159
 
1152
1160
    /**
1153
 
     * You should call this method from every page to set the cleaned-up URL
1154
 
     * that should be used to return to this page.
 
1161
     * You should call this method from every page to set the URL that should be used to return to this page.
1155
1162
     *
1156
1163
     * Used, for example, by the blocks editing UI to know where to return the
1157
1164
     * user after an action.
1161
1168
     *
1162
1169
     * @param moodle_url|string $url URL relative to $CFG->wwwroot or {@link moodle_url} instance
1163
1170
     * @param array $params parameters to add to the URL
 
1171
     * @throws coding_exception
1164
1172
     */
1165
1173
    public function set_url($url, array $params = null) {
1166
1174
        global $CFG;
1167
1175
 
1168
 
        if (is_string($url)) {
1169
 
            if (strpos($url, 'http') === 0) {
1170
 
                // ok
1171
 
            } else if (strpos($url, '/') === 0) {
1172
 
                // we have to use httpswwwroot here, because of loginhttps pages
 
1176
        if (is_string($url) && strpos($url, 'http') !== 0) {
 
1177
            if (strpos($url, '/') === 0) {
 
1178
                // We have to use httpswwwroot here, because of loginhttps pages.
1173
1179
                $url = $CFG->httpswwwroot . $url;
1174
1180
            } else {
1175
1181
                throw new coding_exception('Invalid parameter $url, has to be full url or in shortened form starting with /.');
1202
1208
     * page URL.
1203
1209
     */
1204
1210
    public function ensure_param_not_in_url($param) {
1205
 
        $discard = $this->url; // Make sure $this->url is lazy-loaded;
1206
1211
        $this->_url->remove_params($param);
1207
1212
    }
1208
1213
 
1209
1214
    /**
 
1215
     * Sets an alternative version of this page.
 
1216
     *
1210
1217
     * There can be alternate versions of some pages (for example an RSS feed version).
1211
 
     * If such other version exist, call this method, and a link to the alternate
1212
 
     * version will be included in the <head> of the page.
 
1218
     * Call this method for each alternative version available.
 
1219
     * For each alternative version a link will be included in the <head> tag.
1213
1220
     *
1214
1221
     * @param string $title The title to give the alternate version.
1215
1222
     * @param string|moodle_url $url The URL of the alternate version.
1216
1223
     * @param string $mimetype The mime-type of the alternate version.
 
1224
     * @throws coding_exception
1217
1225
     */
1218
1226
    public function add_alternate_version($title, $url, $mimetype) {
1219
1227
        if ($this->_state > self::STATE_BEFORE_HEADER) {
1274
1282
    /**
1275
1283
     * Sets whether the browser should cache this page or not.
1276
1284
     *
1277
 
     * @return bool $cacheable can this page be cached by the user's browser.
 
1285
     * @param bool $cacheable can this page be cached by the user's browser.
1278
1286
     */
1279
1287
    public function set_cacheable($cacheable) {
1280
1288
        $this->_cacheable = $cacheable;
1286
1294
     * This function must be called before $OUTPUT->header has been called or
1287
1295
     * a coding exception will be thrown.
1288
1296
     *
1289
 
     * @param int $delay Sets the delay before refreshing the page, if set to null
1290
 
     *     refresh is cancelled
 
1297
     * @param int $delay Sets the delay before refreshing the page, if set to null refresh is cancelled.
 
1298
     * @throws coding_exception
1291
1299
     */
1292
 
    public function set_periodic_refresh_delay($delay=null) {
 
1300
    public function set_periodic_refresh_delay($delay = null) {
1293
1301
        if ($this->_state > self::STATE_BEFORE_HEADER) {
1294
1302
            throw new coding_exception('You cannot set a periodic refresh delay after the header has been printed');
1295
1303
        }
1296
 
        if ($delay===null) {
 
1304
        if ($delay === null) {
1297
1305
            $this->_periodicrefreshdelay = null;
1298
1306
        } else if (is_int($delay)) {
1299
1307
            $this->_periodicrefreshdelay = $delay;
1326
1334
    }
1327
1335
 
1328
1336
    /**
1329
 
     * This function indicates that current page requires the https
1330
 
     * when $CFG->loginhttps enabled.
 
1337
     * This function indicates that current page requires the https when $CFG->loginhttps enabled.
1331
1338
     *
1332
1339
     * By using this function properly, we can ensure 100% https-ized pages
1333
1340
     * at our entire discretion (login, forgot_password, change_password)
 
1341
     *
1334
1342
     * @return void
 
1343
     * @throws coding_exception
1335
1344
     */
1336
1345
    public function https_required() {
1337
1346
        global $CFG;
1352
1361
    }
1353
1362
 
1354
1363
    /**
1355
 
     * Makes sure that page previously marked with https_required()
1356
 
     * is really using https://, if not it redirects to https://
 
1364
     * Makes sure that page previously marked with https_required() is really using https://, if not it redirects to https://
1357
1365
     *
1358
1366
     * @return void (may redirect to https://self)
 
1367
     * @throws coding_exception
1359
1368
     */
1360
1369
    public function verify_https_required() {
1361
1370
        global $CFG, $FULLME;
1369
1378
        }
1370
1379
 
1371
1380
        if (empty($CFG->loginhttps)) {
1372
 
            // https not required, so stop checking
 
1381
            // Https not required, so stop checking.
1373
1382
            return;
1374
1383
        }
1375
1384
 
1376
1385
        if (strpos($this->_url, 'https://')) {
1377
 
            // detect if incorrect PAGE->set_url() used, it is recommended to use root-relative paths there
1378
 
            throw new coding_exception('Invalid page url specified, it must start with https:// for pages that set https_required()!');
 
1386
            // Detect if incorrect PAGE->set_url() used, it is recommended to use root-relative paths there.
 
1387
            throw new coding_exception('Invalid page url. It must start with https:// for pages that set https_required()!');
1379
1388
        }
1380
1389
 
1381
1390
        if (!empty($CFG->sslproxy)) {
1382
 
            // it does not make much sense to use sslproxy and loginhttps at the same time
 
1391
            // It does not make much sense to use sslproxy and loginhttps at the same time.
1383
1392
            return;
1384
1393
        }
1385
1394
 
1386
 
        // now the real test and redirect!
 
1395
        // Now the real test and redirect!
1387
1396
        // NOTE: do NOT use this test for detection of https on current page because this code is not compatible with SSL proxies,
1388
 
        //       instead use strpos($CFG->httpswwwroot, 'https:') === 0
 
1397
        //       instead use (strpos($CFG->httpswwwroot, 'https:') === 0).
1389
1398
        if (strpos($FULLME, 'https:') !== 0) {
1390
 
            // this may lead to infinite redirect on misconfigured sites, in that case use $CFG->loginhttps=0; in /config.php
 
1399
            // This may lead to infinite redirect on an incorrectly configured site.
 
1400
            // In that case set $CFG->loginhttps=0; within /config.php.
1391
1401
            redirect($this->_url);
1392
1402
        }
1393
1403
    }
1425
1435
            }
1426
1436
            $this->set_title($title . get_string('maintenancemode', 'admin'));
1427
1437
        } else {
1428
 
            // Show the messaging popup if there are messages
 
1438
            // Show the messaging popup if there are messages.
1429
1439
            message_popup_window();
1430
1440
        }
1431
1441
 
1443
1453
     * @return void
1444
1454
     */
1445
1455
    public function initialise_theme_and_output() {
1446
 
        global $OUTPUT, $PAGE, $SITE;
 
1456
        global $OUTPUT, $PAGE, $SITE, $CFG;
1447
1457
 
1448
1458
        if (!empty($this->_wherethemewasinitialised)) {
1449
1459
            return;
1450
1460
        }
1451
1461
 
1452
1462
        if (!during_initial_install()) {
1453
 
            // detect PAGE->context mess
 
1463
            // Detect PAGE->context mess.
1454
1464
            $this->magic_get_context();
1455
1465
        }
1456
1466
 
1464
1474
        }
1465
1475
 
1466
1476
        $this->_theme->setup_blocks($this->pagelayout, $this->blocks);
 
1477
        if ($this->_theme->enable_dock && !empty($CFG->allowblockstodock)) {
 
1478
            $this->requires->strings_for_js(array('addtodock', 'undockitem', 'dockblock', 'undockblock', 'undockall', 'hidedockpanel', 'hidepanel'), 'block');
 
1479
            $this->requires->string_for_js('thisdirectionvertical', 'langconfig');
 
1480
            $this->requires->yui_module('moodle-core-dock-loader', 'M.core.dock.loader.initLoader');
 
1481
        }
1467
1482
 
1468
1483
        if ($this === $PAGE) {
1469
 
            $OUTPUT = $this->get_renderer('core');
 
1484
            $target = null;
 
1485
            if ($this->pagelayout === 'maintenance') {
 
1486
                // If the page is using the maintenance layout then we're going to force target to maintenance.
 
1487
                // This leads to a special core renderer that is designed to block access to API's that are likely unavailable for this
 
1488
                // page layout.
 
1489
                $target = RENDERER_TARGET_MAINTENANCE;
 
1490
            }
 
1491
            $OUTPUT = $this->get_renderer('core', null, $target);
1470
1492
        }
1471
1493
 
1472
1494
        $this->_wherethemewasinitialised = debug_backtrace();
1540
1562
                        return $mnetpeertheme;
1541
1563
                    }
1542
1564
                    // First try for the device the user is using.
1543
 
                    $devicetheme = get_selected_theme_for_device_type($this->devicetypeinuse);
 
1565
                    $devicetheme = core_useragent::get_device_type_theme($this->devicetypeinuse);
1544
1566
                    if (!empty($devicetheme)) {
1545
1567
                        return $devicetheme;
1546
1568
                    }
1547
 
                    // Next try for the default device (as a fallback)
1548
 
                    $devicetheme = get_selected_theme_for_device_type('default');
 
1569
                    // Next try for the default device (as a fallback).
 
1570
                    $devicetheme = core_useragent::get_device_type_theme('default');
1549
1571
                    if (!empty($devicetheme)) {
1550
1572
                        return $devicetheme;
1551
1573
                    }
1553
1575
                    return theme_config::DEFAULT_THEME;
1554
1576
            }
1555
1577
        }
 
1578
 
 
1579
        // We should most certainly have resolved a theme by now. Something has gone wrong.
 
1580
        debugging('Error resolving the theme to use for this page.', DEBUG_DEVELOPER);
 
1581
        return theme_config::DEFAULT_THEME;
1556
1582
    }
1557
1583
 
1558
1584
 
1619
1645
        $this->add_body_class($this->_legacyclass);
1620
1646
 
1621
1647
        $pathbits = explode('-', trim($pagetype));
1622
 
        for ($i=1;$i<count($pathbits);$i++) {
1623
 
            $this->add_body_class('path-'.join('-',array_slice($pathbits, 0, $i)));
 
1648
        for ($i = 1; $i < count($pathbits); $i++) {
 
1649
            $this->add_body_class('path-' . join('-', array_slice($pathbits, 0, $i)));
1624
1650
        }
1625
1651
 
1626
 
        $this->add_body_classes(get_browser_version_classes());
 
1652
        $this->add_body_classes(core_useragent::get_browser_version_classes());
1627
1653
        $this->add_body_class('dir-' . get_string('thisdirection', 'langconfig'));
1628
1654
        $this->add_body_class('lang-' . current_language());
1629
1655
        $this->add_body_class('yui-skin-sam'); // Make YUI happy, if it is used.
1630
1656
        $this->add_body_class('yui3-skin-sam'); // Make YUI3 happy, if it is used.
1631
1657
        $this->add_body_class($this->url_to_class_name($CFG->wwwroot));
1632
1658
 
1633
 
        $this->add_body_class('pagelayout-' . $this->_pagelayout); // extra class describing current page layout
 
1659
        // Extra class describing current page layout.
 
1660
        $this->add_body_class('pagelayout-' . $this->_pagelayout);
1634
1661
 
1635
1662
        if (!during_initial_install()) {
1636
1663
            $this->add_body_class('course-' . $this->_course->id);
1666
1693
        if (!empty($USER->editing)) {
1667
1694
            $this->add_body_class('editing');
1668
1695
            if (optional_param('bui_moveid', false, PARAM_INT)) {
1669
 
               $this->add_body_class('blocks-moving');
1670
 
        }
 
1696
                $this->add_body_class('blocks-moving');
 
1697
            }
1671
1698
        }
1672
1699
 
1673
1700
        if (!empty($CFG->blocksdrag)) {
1720
1747
    /**
1721
1748
     * Loads the requested category into the pages categories array.
1722
1749
     *
1723
 
     * @param ing $categoryid
 
1750
     * @param int $categoryid
1724
1751
     * @throws moodle_exception
1725
1752
     */
1726
1753
    protected function load_category($categoryid) {