ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç home/smkb8269/public_html/lms.smk-almanshuriyah.sch.id/lib/classes/context_helper.php000064400000037001152267273370024637 0ustar00. namespace core; use stdClass; use coding_exception; /** * Context maintenance and helper methods. * * This is "extends context" is a bloody hack that tires to work around the deficiencies * in the "protected" keyword in PHP, this helps us to hide all the internals of context * level implementation from the rest of code, the code completion returns what developers need. * * Thank you Tim Hunt for helping me with this nasty trick. * * @package core_access * @category access * @copyright Petr Skoda * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 4.2 */ abstract class context_helper extends context { /** * @var array An array definitions of all context levels */ private static $alllevels; /** * Reset internal context levels array. */ public static function reset_levels() { self::$alllevels = null; } /** * Initialise context levels, call before using self::$alllevels. */ private static function init_levels(): void { global $CFG; if (isset(self::$alllevels)) { return; } self::$alllevels = array( CONTEXT_SYSTEM => \core\context\system::class, CONTEXT_USER => \core\context\user::class, CONTEXT_COURSECAT => \core\context\coursecat::class, CONTEXT_COURSE => \core\context\course::class, CONTEXT_MODULE => \core\context\module::class, CONTEXT_BLOCK => \core\context\block::class, ); if (empty($CFG->custom_context_classes)) { return; } $levels = $CFG->custom_context_classes; if (!is_array($levels)) { $levels = @unserialize($levels); } if (!is_array($levels)) { debugging('Invalid $CFG->custom_context_classes detected, value ignored.', DEBUG_DEVELOPER); return; } // Unsupported custom levels, use with care!!! foreach ($levels as $level => $classname) { self::$alllevels[$level] = $classname; } ksort(self::$alllevels); } /** * Converts legacy context_* class name to new class name. * * NOTE: this is needed for external API which uses short context names. * @since Moodle 4.2 * * @param int|string $extlevel * @return string|null context class name or null if not found */ public static function parse_external_level($extlevel): ?string { self::init_levels(); if (is_number($extlevel)) { if (isset(self::$alllevels[$extlevel])) { return self::$alllevels[$extlevel]; } else { return null; } } if ($extlevel && is_string($extlevel)) { $found = null; foreach (self::$alllevels as $classname) { if ($classname::get_short_name() === $extlevel) { if ($found) { debugging("Duplicate short context level name found '$extlevel', use numeric value instead", DEBUG_DEVELOPER); } else { $found = $classname; } } } return $found; } return null; } /** * Resolve reference to context used in behat feature files. * * @param string $level * @param string $reference * @return context|null */ public static function resolve_behat_reference(string $level, string $reference): ?context { global $DB; if (!PHPUNIT_TEST && !defined('BEHAT_SITE_RUNNING')) { throw new coding_exception('resolve_behat_reference() cannot be used outside of tests'); } self::init_levels(); $classname = null; if (is_number($level)) { if (isset(self::$alllevels[$level])) { $classname = self::$alllevels[$level]; } } else { foreach (self::$alllevels as $levelclassname) { if ($level === $levelclassname::get_level_name()) { $classname = $levelclassname; break; } if ($level === $levelclassname::get_short_name()) { $classname = $levelclassname; break; } } } if (!$classname) { return null; } if ($classname::LEVEL === context\system::LEVEL) { return context\system::instance(); } if (trim($reference) === '') { return null; } $table = $classname::get_instance_table(); if (!$table) { return null; } $columns = $classname::get_behat_reference_columns(); foreach ($columns as $column) { $instance = $DB->get_record($table, [$column => $reference]); if ($instance) { $context = $classname::instance($instance->id, IGNORE_MISSING); if ($context) { return $context; } return null; } } return null; } /** * Returns a class name of the context level class * * @param int $contextlevel (CONTEXT_SYSTEM, etc.) * @return string class name of the context class * @throws coding_exception if level does not exist */ public static function get_class_for_level(int $contextlevel): string { self::init_levels(); if (isset(self::$alllevels[$contextlevel])) { return self::$alllevels[$contextlevel]; } else { throw new coding_exception('Invalid context level specified'); } } /** * Returns a list of all context levels * * @return array int=>string (level=>level class name) */ public static function get_all_levels(): array { self::init_levels(); return self::$alllevels; } /** * Get list of possible child levels for given level. * @since Moodle 4.2 * * @param int $parentlevel * @return int[] list of context levels that my be children of given context level. */ public static function get_child_levels(int $parentlevel): array { self::init_levels(); $result = []; $definitions = self::$alllevels; $recursion = function(int $pl) use (&$result, $definitions, &$recursion): void { foreach ($definitions as $contextlevel => $classname) { $parentlevels = $classname::get_possible_parent_levels(); if (in_array($pl, $parentlevels)) { if (isset($result[$contextlevel])) { continue; } $result[$contextlevel] = $contextlevel; $recursion($contextlevel); } } }; $recursion($parentlevel); $classname = self::get_class_for_level($parentlevel); $parentlevels = $classname::get_possible_parent_levels(); if (!in_array($parentlevel, $parentlevels)) { unset($result[$parentlevel]); } return array_values($result); } /** * Returns context levels that compatible with role archetype assignments. * @since Moodle 4.2 * * @param string $archetype * @return array */ public static function get_compatible_levels(string $archetype): array { self::init_levels(); $result = []; foreach (self::$alllevels as $contextlevel => $classname) { $compatiblearchetypes = $classname::get_compatible_role_archetypes(); foreach ($compatiblearchetypes as $at) { if ($at === $archetype) { $result[] = $contextlevel; } } } return $result; } /** * Remove stale contexts that belonged to deleted instances. * Ideally all code should cleanup contexts properly, unfortunately accidents happen... * * @return void */ public static function cleanup_instances() { global $DB; self::init_levels(); $sqls = array(); foreach (self::$alllevels as $classname) { $sqls[] = $classname::get_cleanup_sql(); } $sql = implode(" UNION ", $sqls); // It is probably better to use transactions, it might be faster too. $transaction = $DB->start_delegated_transaction(); $rs = $DB->get_recordset_sql($sql); foreach ($rs as $record) { $context = context::create_instance_from_record($record); $context->delete(); } $rs->close(); $transaction->allow_commit(); } /** * Create all context instances at the given level and above. * * @param int $contextlevel null means all levels * @param bool $buildpaths * @return void */ public static function create_instances($contextlevel = null, $buildpaths = true) { self::init_levels(); foreach (self::$alllevels as $level => $classname) { if ($contextlevel && $contextlevel != context\block::LEVEL && $level > $contextlevel) { // Skip potential sub-contexts, // in case of blocks build all contexts because plugin contexts may have higher levels. continue; } $classname::create_level_instances(); if ($buildpaths) { $classname::build_paths(false); } } } /** * Rebuild paths and depths in all context levels. * * @param bool $force false means add missing only * @return void */ public static function build_all_paths($force = false) { self::init_levels(); foreach (self::$alllevels as $classname) { $classname::build_paths($force); } // Reset static course cache - it might have incorrect cached data. accesslib_clear_all_caches(true); } /** * Resets the cache to remove all data. */ public static function reset_caches() { context::reset_caches(); } /** * Returns all fields necessary for context preloading from user $rec. * * This helps with performance when dealing with hundreds of contexts. * * @param string $tablealias context table alias in the query * @return array (table.column=>alias, ...) */ public static function get_preload_record_columns($tablealias) { return [ "$tablealias.id" => "ctxid", "$tablealias.path" => "ctxpath", "$tablealias.depth" => "ctxdepth", "$tablealias.contextlevel" => "ctxlevel", "$tablealias.instanceid" => "ctxinstance", "$tablealias.locked" => "ctxlocked", ]; } /** * Returns all fields necessary for context preloading from user $rec. * * This helps with performance when dealing with hundreds of contexts. * * @param string $tablealias context table alias in the query * @return string */ public static function get_preload_record_columns_sql($tablealias) { return "$tablealias.id AS ctxid, " . "$tablealias.path AS ctxpath, " . "$tablealias.depth AS ctxdepth, " . "$tablealias.contextlevel AS ctxlevel, " . "$tablealias.instanceid AS ctxinstance, " . "$tablealias.locked AS ctxlocked"; } /** * Preloads context cache with information from db record and strips the cached info. * * The db request has to contain all columns from context_helper::get_preload_record_columns(). * * @param stdClass $rec * @return void This is intentional. See MDL-37115. You will need to get the context * in the normal way, but it is now cached, so that will be fast. */ public static function preload_from_record(stdClass $rec): void { context::preload_from_record($rec); } /** * Preload a set of contexts using their contextid. * * @param array $contextids */ public static function preload_contexts_by_id(array $contextids): void { global $DB; // Determine which contexts are not already cached. $tofetch = []; foreach ($contextids as $contextid) { if (!self::cache_get_by_id($contextid)) { $tofetch[] = $contextid; } } if (count($tofetch) > 1) { // There are at least two to fetch. // There is no point only fetching a single context as this would be no more efficient than calling the existing code. list($insql, $inparams) = $DB->get_in_or_equal($tofetch, SQL_PARAMS_NAMED); $ctxs = $DB->get_records_select('context', "id {$insql}", $inparams, '', self::get_preload_record_columns_sql('{context}')); foreach ($ctxs as $ctx) { self::preload_from_record($ctx); } } } /** * Preload all contexts instances from course. * * To be used if you expect multiple queries for course activities... * * @param int $courseid */ public static function preload_course($courseid) { // Users can call this multiple times without doing any harm. if (isset(context::$cache_preloaded[$courseid])) { return; } $coursecontext = context\course::instance($courseid); $coursecontext->get_child_contexts(); context::$cache_preloaded[$courseid] = true; } /** * Delete context instance * * @param int $contextlevel * @param int $instanceid * @return void */ public static function delete_instance($contextlevel, $instanceid) { global $DB; // Double check the context still exists. if ($record = $DB->get_record('context', array('contextlevel' => $contextlevel, 'instanceid' => $instanceid))) { $context = context::create_instance_from_record($record); $context->delete(); } } /** * Returns the name of specified context level * * @param int $contextlevel * @return string name of the context level */ public static function get_level_name($contextlevel) { $classname = self::get_class_for_level($contextlevel); return $classname::get_level_name(); } /** * Gets the current context to be used for navigation tree filtering. * * @param context|null $context The current context to be checked against. * @return context|null the context that navigation tree filtering should use. */ public static function get_navigation_filter_context(?context $context): ?context { global $CFG; if (!empty($CFG->filternavigationwithsystemcontext)) { return context\system::instance(); } else { return $context; } } }