ÿØÿà 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-Ї Ç PKp\Rh Writing.phpnu[load->model([ 'm_settings', 'm_post_categories' ]); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Menulis'; $this->vars['settings'] = $this->vars['writing_settings'] = TRUE; $this->vars['options_categories'] = json_encode($this->m_post_categories->dropdown(), JSON_HEX_APOS | JSON_HEX_QUOT); $this->vars['content'] = 'settings/writing'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'writing', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'writing'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save | Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } } PKp\Do o Discussion.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Diskusi'; $this->vars['settings'] = $this->vars['discussion_settings'] = TRUE; $this->vars['content'] = 'settings/discussion'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'discussion', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'discussion'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save | Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } } PKp\piU U Media.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Media'; $this->vars['settings'] = $this->vars['media_settings'] = TRUE; $this->vars['content'] = 'settings/media'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'media', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'media'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save | Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } } PKp\!+ Mail_server.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Email Server'; $this->vars['sub_title'] = 'Email dikirim menggunakan third party https://sendgrid.com'; $this->vars['settings'] = $this->vars['mail_server_settings'] = TRUE; $this->vars['content'] = 'settings/mail_server'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'mail_server', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'mail_server'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save or Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } } PKp\6w` ` Reading.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Membaca'; $this->vars['settings'] = $this->vars['reading_settings'] = TRUE; $this->vars['content'] = 'settings/reading'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'reading', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'reading'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save | Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } } PKp\iaƺSchool_profile.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Profil ' . (__session('school_level') >= 5 ? 'Perguruan Tinggi' : 'Sekolah'); $this->vars['settings'] = $this->vars['school_profile_settings'] = TRUE; $this->vars['content'] = 'settings/school_profile'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'school_profile', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'school_profile'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save or Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } /** * Upload * @return Void */ public function upload() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if (_isNaturalNumber( $id )) { $query = $this->model->RowObject($this->pk, $id, $this->table); $file_name = $query->setting_value; $config['upload_path'] = './media_library/images/'; $config['allowed_types'] = 'jpg|png|jpeg|gif'; $config['max_size'] = 0; $config['encrypt_name'] = TRUE; $this->load->library('upload', $config); if ( ! $this->upload->do_upload('file') ) { $this->vars['status'] = 'error'; $this->vars['message'] = $this->upload->display_errors(); } else { $file = $this->upload->data(); $update = $this->model->update($id, $this->table, ['setting_value' => $file['file_name']]); if ($update) { // chmood new file @chmod(FCPATH.'media_library/images/'.$file['file_name'], 0777); // chmood old file @chmod(FCPATH.'media_library/images/'.$file_name, 0777); // unlink old file @unlink(FCPATH.'media_library/images/'.$file_name); // resize new image if ($query->setting_variable != 'headmaster_photo') { $this->image_resize('./media_library/images', $file['file_name'], $query->setting_variable); } } $this->vars['status'] = 'success'; $this->vars['message'] = 'uploaded'; } } else { $this->vars['status'] = 'error'; $this->vars['message'] = 'ID bukan merupakan tipe angka yang valid !'; } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Image Resize * @param String $path * @param String $file_name * @param String $setting_variable * @return Void */ private function image_resize($path, $file_name, $setting_variable = 'headmaster_photo') { $settings = [ 'headmaster_photo_height' => NULL !== __session('headmaster_photo_height') ? __session('headmaster_photo_height') : 344, 'headmaster_photo_width' => NULL !== __session('headmaster_photo_width') ? __session('headmaster_photo_width') : 252, 'logo_height' => NULL !== __session('logo_height') ? __session('logo_height') : 120, 'logo_width' => NULL !== __session('logo_width') ? __session('logo_width') : 120 ]; $this->load->library('image_lib'); $config['image_library'] = 'gd2'; $config['source_image'] = $path .'/'.$file_name; $config['maintain_ratio'] = TRUE; $config['width'] = _toInteger($settings[$setting_variable.'_width']); if ($setting_variable != 'headmaster_photo') { $config['height'] = _toInteger($settings[$setting_variable.'_height']); } $this->image_lib->initialize($config); $this->image_lib->resize(); } } PKp\ > General.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Umum'; $this->vars['settings'] = $this->vars['general_settings'] = TRUE; $this->vars['timezone_list'] = json_encode(timezone_list(), JSON_HEX_APOS | JSON_HEX_QUOT); $this->vars['content'] = 'settings/general'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'general', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'general'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save | Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value') ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } /** * Upload * @return Void */ public function upload() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if (_isNaturalNumber( $id )) { $query = $this->model->RowObject($this->pk, $id, $this->table); $file_name = $query->setting_value; $config['upload_path'] = './media_library/images/'; $config['allowed_types'] = 'jpg|png|jpeg|gif'; $config['max_size'] = 0; $config['encrypt_name'] = TRUE; $this->load->library('upload', $config); if ( ! $this->upload->do_upload('file') ) { $this->vars['status'] = 'error'; $this->vars['message'] = $this->upload->display_errors(); } else { $file = $this->upload->data(); $update = $this->model->update($id, $this->table, ['setting_value' => $file['file_name']]); if ($update) { // chmood new file @chmod(FCPATH.'media_library/images/'.$file['file_name'], 0777); // chmood old file @chmod(FCPATH.'media_library/images/'.$file_name, 0777); // unlink old file @unlink(FCPATH.'media_library/images/'.$file_name); // resize new image $this->image_resize(FCPATH.'media_library/images', $file['file_name'], $query->setting_variable); } $this->vars['status'] = 'success'; $this->vars['message'] = 'uploaded'; } } else { $this->vars['status'] = 'error'; $this->vars['message'] = 'ID bukan merupakan tipe angka yang valid !'; } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Image Resize * @param String $path * @param String $file_name * @param String $setting_variable * @return Void */ private function image_resize($path, $file_name, $setting_variable = 'favicon') { $settings = [ 'favicon_width' => 32, 'favicon_height' => 32, 'header_width' => __session('header_width'), 'header_height' => __session('header_height') ]; $this->load->library('image_lib'); $config['image_library'] = 'gd2'; $config['source_image'] = $path .'/'.$file_name; $config['maintain_ratio'] = false; $config['width'] = (int) $settings[$setting_variable . '_width']; $config['height'] = (int) $settings[$setting_variable . '_height']; $this->image_lib->initialize($config); $this->image_lib->resize(); } } PKp\"WS Social_account.phpnu[load->model('m_settings'); $this->pk = M_settings::$pk; $this->table = M_settings::$table; } /** * Index * @return Void */ public function index() { $this->vars['title'] = 'Pengaturan Jejaring Sosial'; $this->vars['settings'] = $this->vars['social_account_settings'] = TRUE; $this->vars['content'] = 'settings/social_account'; $this->load->view('backend/index', $this->vars); } /** * Pagination * @return Object */ public function pagination() { if ($this->input->is_ajax_request()) { $keyword = trim($this->input->post('keyword', true)); $page_number = _toInteger($this->input->post('page_number', true)); $limit = _toInteger($this->input->post('per_page', true)); $offset = ($page_number * $limit); $query = $this->m_settings->get_where($keyword, 'social_account', 'rows', $limit, $offset); $total_rows = $this->m_settings->get_where($keyword, 'social_account'); $total_page = $limit > 0 ? ceil(_toInteger($total_rows) / _toInteger($limit)) : 1; $this->vars['total_page'] = _toInteger($total_page); $this->vars['total_rows'] = _toInteger($total_rows); $this->vars['rows'] = $query->result(); $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Save | Update * @return Object */ public function save() { if ($this->input->is_ajax_request()) { $id = _toInteger($this->input->post('id', true)); if ($this->validation()) { $dataset = $this->dataset(); $dataset['updated_by'] = __session('user_id'); $query = $this->model->update($id, $this->table, $dataset); $this->vars['status'] = $query ? 'success' : 'error'; $this->vars['message'] = $query ? 'Data Anda berhasil disimpan.' : 'Terjadi kesalahan dalam menyimpan data'; } else { $this->vars['status'] = 'error'; $this->vars['message'] = validation_errors(); } $this->output ->set_content_type('application/json', 'utf-8') ->set_output(json_encode($this->vars, JSON_HEX_APOS | JSON_HEX_QUOT)) ->_display(); exit; } } /** * Dataset * @return Array */ private function dataset() { return [ 'setting_value' => $this->input->post('setting_value', true) ]; } /** * Validation Form * @return Boolean */ private function validation() { $this->load->library('form_validation'); $val = $this->form_validation; $val->set_rules('setting_value', 'Value', 'trim|required'); $val->set_error_delimiters('
⋅ ', '
'); return $val->run(); } } PKr\茒Iii styles.cssnu[.block_settings .block_tree ul { margin-left: 18px; } .block_settings .block_tree p.hasicon { text-indent: -21px; padding-left: 21px; } .block_settings .block_tree p.hasicon img { width: 16px; height: 16px; margin-top: 3px; margin-right: 5px; vertical-align: top; } .block_settings .block_tree p.hasicon.visibleifjs { display: block; } .block_settings .block_tree .tree_item.branch { padding-left: 21px; } .block_settings .block_tree .tree_item { cursor: pointer; margin: 3px 0; background-position: 0 50%; background-repeat: no-repeat; } .block_settings .block_tree .active_tree_node { font-weight: bold; } .block_settings .block_tree [aria-expanded="true"] { background-image: url('[[pix:t/expanded]]'); } .block_settings .block_tree [aria-expanded="false"] { background-image: url('[[pix:t/collapsed]]'); } .block_settings .block_tree [aria-expanded="true"].emptybranch { background-image: url('[[pix:t/collapsed_empty]]'); } .block_settings .block_tree [aria-expanded="false"] p.loading { background-image: url('[[pix:i/loading_small]]'); } /*rtl:raw: .block_settings .block_tree [aria-expanded="false"] {background-image: url('[[pix:t/collapsed_rtl]]');} .block_settings .block_tree [aria-expanded="true"].emptybranch {background-image: url('[[pix:t/collapsed_empty_rtl]]');} .block_settings .block_tree [aria-expanded="false"].loading {background-image: url('[[pix:i/loading_small]]');} */ .block_settings .block_tree [aria-hidden="false"] { display: block; } .block_settings .block_tree [aria-hidden="true"]:not(.icon) { display: none; } PKr\ / renderer.phpnu[. /** * Settings block * * @package block_settings * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class block_settings_renderer extends plugin_renderer_base { public function settings_tree(settings_navigation $navigation) { $count = 0; foreach ($navigation->children as &$child) { $child->preceedwithhr = ($count!==0); if ($child->display) { $count++; } } $navigationattrs = array( 'class' => 'block_tree list', 'role' => 'tree', 'data-ajax-loader' => 'block_navigation/site_admin_loader'); $content = $this->navigation_node($navigation, $navigationattrs); if (isset($navigation->id) && !is_numeric($navigation->id) && !empty($content)) { $content = $this->output->box($content, 'block_tree_box', $navigation->id); } return $content; } /** * Build the navigation node. * * @param navigation_node $node the navigation node object. * @param array $attrs list of attributes. * @param int $depth the depth, default to 1. * @return string the navigation node code. */ protected function navigation_node(navigation_node $node, $attrs=array(), $depth = 1) { $items = $node->children; // exit if empty, we don't want an empty ul element if ($items->count()==0) { return ''; } // array of nested li elements $lis = array(); $number = 0; foreach ($items as $item) { $number++; if (!$item->display) { continue; } $isbranch = ($item->children->count()>0 || $item->nodetype==navigation_node::NODETYPE_BRANCH); if ($isbranch) { $item->hideicon = true; } $content = $this->output->render($item); $id = $item->id ? $item->id : html_writer::random_id(); $ulattr = ['id' => $id . '_group', 'role' => 'group']; $liattr = ['class' => [$item->get_css_type(), 'depth_'.$depth], 'tabindex' => '-1', 'role' => 'treeitem']; $pattr = ['class' => ['tree_item']]; $pattr += !empty($item->id) ? ['id' => $item->id] : []; $hasicon = (!$isbranch && $item->icon instanceof renderable); if ($isbranch) { $liattr['class'][] = 'contains_branch'; if (!$item->forceopen || (!$item->forceopen && $item->collapse) || ($item->children->count() == 0 && $item->nodetype == navigation_node::NODETYPE_BRANCH)) { $liattr += ['aria-expanded' => 'false']; } else { $liattr += ['aria-expanded' => 'true']; } if ($item->requiresajaxloading) { $liattr['data-requires-ajax'] = 'true'; $liattr['data-loaded'] = 'false'; } else { $liattr += ['aria-owns' => $id . '_group']; } } else if ($hasicon) { $liattr['class'][] = 'item_with_icon'; $pattr['class'][] = 'hasicon'; } if ($item->isactive === true) { $liattr['class'][] = 'current_branch'; } if (!empty($item->classes) && count($item->classes) > 0) { $pattr['class'] = array_merge($pattr['class'], $item->classes); } // class attribute on the div item which only contains the item content $pattr['class'][] = 'tree_item'; if ($isbranch) { $pattr['class'][] = 'branch'; } else { $pattr['class'][] = 'leaf'; } $liattr['class'] = join(' ', $liattr['class']); $pattr['class'] = join(' ', $pattr['class']); if (isset($liattr['aria-expanded']) && $liattr['aria-expanded'] === 'false') { $ulattr += ['aria-hidden' => 'true']; } $content = html_writer::tag('p', $content, $pattr) . $this->navigation_node($item, $ulattr, $depth + 1); if (!empty($item->preceedwithhr) && $item->preceedwithhr===true) { $content = html_writer::empty_tag('hr') . $content; } $content = html_writer::tag('li', $content, $liattr); $lis[] = $content; } if (count($lis)) { if (empty($attrs['role'])) { $attrs['role'] = 'group'; } return html_writer::tag('ul', implode("\n", $lis), $attrs); } else { return ''; } } public function search_form(moodle_url $formtarget, $searchvalue) { $data = [ 'action' => $formtarget, 'inputname' => 'query', 'searchstring' => get_string('searchinsettings', 'admin'), 'query' => $searchvalue ]; return $this->render_from_template('core/search_input', $data); } } PKr\7?   db/access.phpnu[. /** * Settings block caps. * * @package block_settings * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $capabilities = array( 'block/settings:myaddinstance' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => array( 'user' => CAP_ALLOW ), 'clonepermissionsfrom' => 'moodle/my:manageblocks' ), 'block/settings:addinstance' => array( 'riskbitmask' => RISK_SPAM | RISK_XSS, 'captype' => 'write', 'contextlevel' => CONTEXT_BLOCK, 'archetypes' => array( 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ), 'clonepermissionsfrom' => 'moodle/site:manageblocks' ), ); PKr\qˁ db/upgrade.phpnu[. /** * This file keeps track of upgrades to the settings block * * Sometimes, changes between versions involve alterations to database structures * and other major things that may break installations. * * The upgrade function in this file will attempt to perform all the necessary * actions to upgrade your older installation to the current version. * * If there's something it cannot do itself, it will tell you what you need to do. * * The commands in here will all be database-neutral, using the methods of * database_manager class * * Please do not forget to use upgrade_set_timeout() * before any action that may take longer time to finish. * * @since Moodle 2.0 * @package block_settings * @copyright 2009 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * As of the implementation of this block and the general navigation code * in Moodle 2.0 the body of immediate upgrade work for this block and * settings is done in core upgrade {@see lib/db/upgrade.php} * * There were several reasons that they were put there and not here, both becuase * the process for the two blocks was very similar and because the upgrade process * was complex due to us wanting to remvoe the outmoded blocks that this * block was going to replace. * * @param int $oldversion * @param object $block */ function xmldb_block_settings_upgrade($oldversion, $block) { // Automatically generated Moodle v4.2.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.3.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.4.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.5.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v5.0.0 release upgrade line. // Put any upgrade step following this. return true; } PKr\s|slang/en/block_settings.phpnu[. /** * This file contains language strings used in the settings navigation block * * @since Moodle 2.0 * @package block_settings * @copyright 2009 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ $string['enabledock'] = 'Allow the user to dock this block'; $string['pluginname'] = 'Administration'; $string['settings:addinstance'] = 'Add a new administration block'; $string['settings:myaddinstance'] = 'Add a new administration block to Dashboard'; $string['privacy:metadata'] = 'The Administration block only shows data stored in other locations.'; PKr\|j edit_form.phpnu[. /** * Form for editing settings navigation instances. * * @since Moodle 2.0 * @package block_settings * @copyright 2009 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Form for setting navigation instances. * * @package block_settings * @copyright 2009 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class block_settings_edit_form extends block_edit_form { protected function specific_definition($mform) { $mform->addElement('header', 'configheader', get_string('blocksettings', 'block')); $yesnooptions = array('yes'=>get_string('yes'), 'no'=>get_string('no')); $mform->addElement('select', 'config_enabledock', get_string('enabledock', $this->block->blockname), $yesnooptions); if (empty($this->block->config->enabledock) || $this->block->config->enabledock=='yes') { $mform->getElement('config_enabledock')->setSelected('yes'); } else { $mform->getElement('config_enabledock')->setSelected('no'); } } }PKr\GL?block_settings.phpnu[. /** * This file contains classes used to manage the navigation structures in Moodle * and was introduced as part of the changes occuring in Moodle 2.0 * * @since Moodle 2.0 * @package block_settings * @copyright 2009 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * The settings navigation tree block class * * Used to produce the settings navigation block new to Moodle 2.0 * * @package block_settings * @copyright 2009 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class block_settings extends block_base { /** @var string */ public static $navcount; public $blockname = null; /** @var bool */ protected $contentgenerated = false; /** @var bool|null */ protected $docked = null; /** * Set the initial properties for the block */ function init() { $this->blockname = get_class($this); $this->title = get_string('pluginname', $this->blockname); } /** * All multiple instances of this block * @return bool Returns true */ function instance_allow_multiple() { return false; } /** * The settings block cannot be hidden by default as it is integral to * the navigation of Moodle. * * @return false */ function instance_can_be_hidden() { return false; } /** * Set the applicable formats for this block to all * @return array */ function applicable_formats() { return array('all' => true); } /** * Allow the user to configure a block instance * @return bool Returns true */ function instance_allow_config() { return true; } function instance_can_be_docked() { return (parent::instance_can_be_docked() && (empty($this->config->enabledock) || $this->config->enabledock=='yes')); } function get_required_javascript() { $adminnode = $this->page->settingsnav->find('siteadministration', navigation_node::TYPE_SITE_ADMIN); parent::get_required_javascript(); $arguments = array( 'instanceid' => $this->instance->id, 'adminnodeid' => $adminnode ? $adminnode->id : null ); $this->page->requires->js_call_amd('block_settings/settingsblock', 'init', $arguments); } /** * Gets the content for this block by grabbing it from $this->page */ function get_content() { global $CFG, $OUTPUT; // First check if we have already generated, don't waste cycles if ($this->contentgenerated === true) { return true; } // JS for navigation moved to the standard theme, the code will probably have to depend on the actual page structure // $this->page->requires->js('/lib/javascript-navigation.js'); block_settings::$navcount++; // Check if this block has been docked if ($this->docked === null) { $this->docked = get_user_preferences('nav_in_tab_panel_settingsnav'.block_settings::$navcount, 0); } // Check if there is a param to change the docked state if ($this->docked && optional_param('undock', null, PARAM_INT)==$this->instance->id) { unset_user_preference('nav_in_tab_panel_settingsnav'.block_settings::$navcount, 0); $url = $this->page->url; $url->remove_params(array('undock')); redirect($url); } else if (!$this->docked && optional_param('dock', null, PARAM_INT)==$this->instance->id) { set_user_preferences(array('nav_in_tab_panel_settingsnav'.block_settings::$navcount=>1)); $url = $this->page->url; $url->remove_params(array('dock')); redirect($url); } $renderer = $this->page->get_renderer('block_settings'); $this->content = new stdClass(); $this->content->text = $renderer->settings_tree($this->page->settingsnav); // only do search if you have moodle/site:config if (!empty($this->content->text)) { if (has_capability('moodle/site:config',context_system::instance()) ) { $this->content->footer = $renderer->search_form(new moodle_url("$CFG->wwwroot/$CFG->admin/search.php"), optional_param('query', '', PARAM_RAW)); } else { $this->content->footer = ''; } } $this->contentgenerated = true; return true; } /** * Returns the role that best describes the settings block. * * @return string 'navigation' */ public function get_aria_role() { return 'navigation'; } /** * Return the plugin config settings for external functions. * * @return stdClass the configs for both the block instance and plugin * @since Moodle 3.8 */ public function get_config_for_external() { // Return all settings for all users since it is safe (no private keys, etc..). $configs = !empty($this->config) ? $this->config : new stdClass(); return (object) [ 'instance' => $configs, 'plugin' => new stdClass(), ]; } } PKr\# version.phpnu[. /** * Version details * * @package block_settings * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2025040800; // Requires this Moodle version. $plugin->component = 'block_settings'; // Full name of the plugin (used for diagnostics) PKr\classes/privacy/provider.phpnu[. /** * Privacy Subsystem implementation for block_settings. * * @package block_settings * @copyright 2018 Zig Tan * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace block_settings\privacy; defined('MOODLE_INTERNAL') || die(); /** * Privacy Subsystem for block_settings implementing null_provider. * * @copyright 2018 Zig Tan * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements \core_privacy\local\metadata\null_provider { /** * Get the language string identifier with the component's language * file to explain why this plugin stores no data. * * @return string */ public static function get_reason(): string { return 'privacy:metadata'; } } PKr\amd/src/settingsblock.jsnu[// 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 . /** * Load the settings block tree javscript * * @module block_settings/settingsblock * @copyright 2015 John Okely * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import {notifyBlockContentUpdated} from 'core_block/events'; import Tree from 'core/tree'; export const init = (instanceId, siteAdminNodeId) => { const adminTree = new Tree(".block_settings .block_tree"); const blockNode = document.querySelector(`[data-instance-id="${instanceId}"]`); if (siteAdminNodeId) { const siteAdminLink = adminTree.treeRoot.get(0).querySelector(`#${siteAdminNodeId} a`); const newContainer = document.createElement('span'); newContainer.setAttribute('tabindex', '0'); siteAdminLink.childNodes.forEach(node => newContainer.appendChild(node)); siteAdminLink.replaceWith(newContainer); } /** * The method to call when then the navtree finishes expanding a group. * * @method finishExpandingGroup * @param {Object} item * @fires event:blockContentUpdated */ adminTree.finishExpandingGroup = function(item) { Tree.prototype.finishExpandingGroup.call(adminTree, item); notifyBlockContentUpdated(blockNode); }; /** * The method to call whe then the navtree collapses a group * * @method collapseGroup * @param {Object} item * @fires event:blockContentUpdated */ adminTree.collapseGroup = function(item) { Tree.prototype.collapseGroup.call(adminTree, item); notifyBlockContentUpdated(blockNode); }; }; PKr\-[V^ ^ "amd/build/settingsblock.min.js.mapnu[{"version":3,"file":"settingsblock.min.js","sources":["../src/settingsblock.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Load the settings block tree javscript\n *\n * @module block_settings/settingsblock\n * @copyright 2015 John Okely \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {notifyBlockContentUpdated} from 'core_block/events';\nimport Tree from 'core/tree';\n\nexport const init = (instanceId, siteAdminNodeId) => {\n const adminTree = new Tree(\".block_settings .block_tree\");\n const blockNode = document.querySelector(`[data-instance-id=\"${instanceId}\"]`);\n\n if (siteAdminNodeId) {\n const siteAdminLink = adminTree.treeRoot.get(0).querySelector(`#${siteAdminNodeId} a`);\n const newContainer = document.createElement('span');\n newContainer.setAttribute('tabindex', '0');\n siteAdminLink.childNodes.forEach(node => newContainer.appendChild(node));\n siteAdminLink.replaceWith(newContainer);\n }\n\n /**\n * The method to call when then the navtree finishes expanding a group.\n *\n * @method finishExpandingGroup\n * @param {Object} item\n * @fires event:blockContentUpdated\n */\n adminTree.finishExpandingGroup = function(item) {\n Tree.prototype.finishExpandingGroup.call(adminTree, item);\n notifyBlockContentUpdated(blockNode);\n };\n\n /**\n * The method to call whe then the navtree collapses a group\n *\n * @method collapseGroup\n * @param {Object} item\n * @fires event:blockContentUpdated\n */\n adminTree.collapseGroup = function(item) {\n Tree.prototype.collapseGroup.call(adminTree, item);\n notifyBlockContentUpdated(blockNode);\n };\n};\n"],"names":["instanceId","siteAdminNodeId","adminTree","Tree","blockNode","document","querySelector","siteAdminLink","treeRoot","get","newContainer","createElement","setAttribute","childNodes","forEach","node","appendChild","replaceWith","finishExpandingGroup","item","prototype","call","collapseGroup"],"mappings":";;;;;;;oJAyBoB,CAACA,WAAYC,yBACvBC,UAAY,IAAIC,cAAK,+BACrBC,UAAYC,SAASC,2CAAoCN,qBAE3DC,gBAAiB,OACXM,cAAgBL,UAAUM,SAASC,IAAI,GAAGH,yBAAkBL,uBAC5DS,aAAeL,SAASM,cAAc,QAC5CD,aAAaE,aAAa,WAAY,KACtCL,cAAcM,WAAWC,SAAQC,MAAQL,aAAaM,YAAYD,QAClER,cAAcU,YAAYP,cAU9BR,UAAUgB,qBAAuB,SAASC,oBACjCC,UAAUF,qBAAqBG,KAAKnB,UAAWiB,4CAC1Bf,YAU9BF,UAAUoB,cAAgB,SAASH,oBAC1BC,UAAUE,cAAcD,KAAKnB,UAAWiB,4CACnBf"}PKr\]:MCCamd/build/settingsblock.min.jsnu[define("block_settings/settingsblock",["exports","core_block/events","core/tree"],(function(_exports,_events,_tree){var obj; /** * Load the settings block tree javscript * * @module block_settings/settingsblock * @copyright 2015 John Okely * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_tree=(obj=_tree)&&obj.__esModule?obj:{default:obj};_exports.init=(instanceId,siteAdminNodeId)=>{const adminTree=new _tree.default(".block_settings .block_tree"),blockNode=document.querySelector('[data-instance-id="'.concat(instanceId,'"]'));if(siteAdminNodeId){const siteAdminLink=adminTree.treeRoot.get(0).querySelector("#".concat(siteAdminNodeId," a")),newContainer=document.createElement("span");newContainer.setAttribute("tabindex","0"),siteAdminLink.childNodes.forEach((node=>newContainer.appendChild(node))),siteAdminLink.replaceWith(newContainer)}adminTree.finishExpandingGroup=function(item){_tree.default.prototype.finishExpandingGroup.call(adminTree,item),(0,_events.notifyBlockContentUpdated)(blockNode)},adminTree.collapseGroup=function(item){_tree.default.prototype.collapseGroup.call(adminTree,item),(0,_events.notifyBlockContentUpdated)(blockNode)}}})); //# sourceMappingURL=settingsblock.min.js.mapPK-\FLLform.phpnu[. /** * A form for editing course grade settings * * @package core_grades * @copyright 2007 Petr Skoda * @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.'/formslib.php'); /** * First implementation of the preferences in the form of a moodleform. * TODO add "reset to site defaults" button */ class course_settings_form extends moodleform { function definition() { global $USER, $CFG; $mform =& $this->_form; $systemcontext = context_system::instance(); $can_view_admin_links = false; if (has_capability('moodle/grade:manage', $systemcontext)) { $can_view_admin_links = true; } // General settings $strchangedefaults = get_string('changedefaults', 'grades'); $mform->addElement('header', 'general', get_string('generalsettings', 'grades')); if ($can_view_admin_links) { $link = '' . $strchangedefaults . ''; $mform->addElement('static', 'generalsettingslink', null, $link); } $options = array(-1 => get_string('default', 'grades'), GRADE_REPORT_AGGREGATION_POSITION_FIRST => get_string('positionfirst', 'grades'), GRADE_REPORT_AGGREGATION_POSITION_LAST => get_string('positionlast', 'grades')); $default_gradedisplaytype = $CFG->grade_aggregationposition; foreach ($options as $key=>$option) { if ($key == $default_gradedisplaytype) { $options[-1] = get_string('defaultprev', 'grades', $option); break; } } $mform->addElement('select', 'aggregationposition', get_string('aggregationposition', 'grades'), $options); $mform->addHelpButton('aggregationposition', 'aggregationposition', 'grades'); if ($CFG->grade_minmaxtouse == GRADE_MIN_MAX_FROM_GRADE_ITEM) { $default = get_string('gradeitemminmax', 'grades'); } else if ($CFG->grade_minmaxtouse == GRADE_MIN_MAX_FROM_GRADE_GRADE) { $default = get_string('gradegrademinmax', 'grades'); } else { throw new coding_exception('Invalid $CFG->grade_minmaxtouse value.'); } $options = array( -1 => get_string('defaultprev', 'grades', $default), GRADE_MIN_MAX_FROM_GRADE_ITEM => get_string('gradeitemminmax', 'grades'), GRADE_MIN_MAX_FROM_GRADE_GRADE => get_string('gradegrademinmax', 'grades') ); $mform->addElement('select', 'minmaxtouse', get_string('minmaxtouse', 'grades'), $options); $mform->addHelpButton('minmaxtouse', 'minmaxtouse', 'grades'); // Grade item settings $mform->addElement('header', 'grade_item_settings', get_string('gradeitemsettings', 'grades')); $mform->setExpanded('grade_item_settings'); if ($can_view_admin_links) { $link = '' . $strchangedefaults . ''; $mform->addElement('static', 'gradeitemsettingslink', null, $link); } $options = array(-1 => get_string('default', 'grades'), GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'), GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'), GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'), GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'), GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades'), GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'), GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'), GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'), GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades')); $default_gradedisplaytype = $CFG->grade_displaytype; foreach ($options as $key=>$option) { if ($key == $default_gradedisplaytype) { $options[-1] = get_string('defaultprev', 'grades', $option); break; } } $mform->addElement('select', 'displaytype', get_string('gradedisplaytype', 'grades'), $options); $mform->addHelpButton('displaytype', 'gradedisplaytype', 'grades'); $mform->setDefault('displaytype', -1); $options = array(-1=> get_string('defaultprev', 'grades', $CFG->grade_decimalpoints), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5); $mform->addElement('select', 'decimalpoints', get_string('decimalpoints', 'grades'), $options); $mform->addHelpButton('decimalpoints', 'decimalpoints', 'grades'); // add setting options for plugins $types = array('report', 'export', 'import'); foreach($types as $type) { foreach (core_component::get_plugin_list('grade'.$type) as $plugin => $plugindir) { // Include all the settings commands for this plugin if there are any if (file_exists($plugindir.'/lib.php')) { require_once($plugindir.'/lib.php'); $functionname = 'grade_'.$type.'_'.$plugin.'_settings_definition'; if (function_exists($functionname)) { $mform->addElement('header', 'grade_'.$type.$plugin, get_string('pluginname', 'grade'.$type.'_'.$plugin, NULL)); $mform->setExpanded('grade_'.$type.$plugin); if ($can_view_admin_links) { $link = '' . $strchangedefaults . ''; $mform->addElement('static', 'gradeitemsettingslink', null, $link); } $functionname($mform); } } } } $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $this->add_action_buttons(false); } } PK-\QZv index.phpnu[. /** * A page for editing course grade settings * * @package core_grades * @copyright 2007 Petr Skoda * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once '../../../config.php'; require_once $CFG->dirroot.'/grade/lib.php'; require_once $CFG->libdir.'/gradelib.php'; require_once 'form.php'; $courseid = optional_param('id', SITEID, PARAM_INT); $PAGE->set_url('/grade/edit/settings/index.php', array('id'=>$courseid)); $PAGE->set_pagelayout('admin'); if (!$course = $DB->get_record('course', array('id' => $courseid))) { throw new \moodle_exception('invalidcourseid'); } require_login($course); $context = context_course::instance($course->id); require_capability('moodle/grade:manage', $context); $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'settings', 'courseid'=>$courseid)); $strgrades = get_string('grades'); $pagename = get_string('coursesettings', 'grades'); $mform = new course_settings_form(); $settings = grade_get_settings($course->id); $mform->set_data($settings); if ($data = $mform->get_data()) { $data = (array)$data; $general = array('displaytype', 'decimalpoints', 'aggregationposition', 'minmaxtouse'); foreach ($data as $key=>$value) { if (!in_array($key, $general) and strpos($key, 'report_') !== 0 and strpos($key, 'import_') !== 0 and strpos($key, 'export_') !== 0) { continue; } if ($value == -1) { $value = null; } grade_set_setting($course->id, $key, $value); $previousvalue = isset($settings->{$key}) ? $settings->{$key} : null; if ($key == 'minmaxtouse' && $previousvalue != $value) { // The min max has changed, we need to regrade the grades. grade_force_full_regrading($courseid); } } } print_grade_page_head($courseid, 'settings', 'coursesettings'); // The settings could have been changed due to a notice shown in print_grade_page_head, we need to refresh them. $settings = grade_get_settings($course->id); $mform->set_data($settings); echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthnormal centerpara'); echo get_string('coursesettingsexplanation', 'grades'); echo $OUTPUT->box_end(); $mform->display(); echo $OUTPUT->footer(); PK\t&T"root/root_backup_setting.class.phpnu[. /** * Defines root_backup_setting class * * @package core_backup * @category backup * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** * Abstract class containing all the common stuff for root backup settings */ abstract class root_backup_setting extends backup_setting { /** * {@inheritdoc} */ public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) { $this->level = self::ROOT_LEVEL; parent::__construct($name, $vtype, $value, $visibility, $status); } } PK\\{44(section/section_backup_setting.class.phpnu[. /** * @package moodlecore * @subpackage backup-settings * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Abstract class containing all the common stuff for section backup settings * * TODO: Finish phpdocs */ abstract class section_backup_setting extends backup_setting { public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) { $this->level = self::SECTION_LEVEL; parent::__construct($name, $vtype, $value, $visibility, $status); } } PK\11&course/course_backup_setting.class.phpnu[. /** * @package moodlecore * @subpackage backup-settings * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Abstract class containing all the common stuff for course backup settings * * TODO: Finish phpdocs */ abstract class course_backup_setting extends backup_setting { public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) { $this->level = self::COURSE_LEVEL; parent::__construct($name, $vtype, $value, $visibility, $status); } } PK\qYEEsetting_dependency.class.phpnu[. /** * @package moodlecore * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Generic abstract dependency class * * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class setting_dependency { /** * Used to define the type of a dependency. * * Note with these that checked and true, and not checked and false are equal. * This is because the terminology differs but the resulting action is the same. * Reduces code! */ const DISABLED_VALUE = 0; const DISABLED_NOT_VALUE = 1; const DISABLED_TRUE = 2; const DISABLED_FALSE = 3; const DISABLED_CHECKED = 4; const DISABLED_NOT_CHECKED = 5; const DISABLED_EMPTY = 6; const DISABLED_NOT_EMPTY = 7; /** * The parent setting (primary) * @var base_setting */ protected $setting; /** * The dependent setting (secondary) * @var base_setting */ protected $dependentsetting; /** * The default setting * @var mixed */ protected $defaultvalue; /** * The last value the dependent setting had * @var mixed */ protected $lastvalue; /** * Creates the dependency object * @param base_setting $setting The parent setting or the primary setting if you prefer * @param base_setting $dependentsetting The dependent setting * @param mixed $defaultvalue The default value to assign if the dependency is unmet */ public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { $this->setting = $setting; $this->dependentsetting = $dependentsetting; $this->defaultvalue = $defaultvalue; $this->lastvalue = $dependentsetting->get_value(); } /** * Destroy all circular references. It helps PHP 5.2 a lot! */ public function destroy() { // No need to destroy anything recursively here, direct reset. $this->setting = null; $this->dependentsetting = null; } /** * Processes a change is setting called by the primary setting * @param int $changetype * @param mixed $oldvalue * @return bool */ final public function process_change($changetype, $oldvalue) { // Check the type of change requested. switch ($changetype) { // Process a status change. case base_setting::CHANGED_STATUS: return $this->process_status_change($oldvalue); // Process a visibility change. case base_setting::CHANGED_VISIBILITY: return $this->process_visibility_change($oldvalue); // Process a value change. case base_setting::CHANGED_VALUE: return $this->process_value_change($oldvalue); } // Throw an exception if we get this far. throw new backup_ui_exception('unknownchangetype'); } /** * Processes a visibility change * @param bool $oldvisibility * @return bool */ protected function process_visibility_change($oldvisibility) { // Store the current dependent settings visibility for comparison. $prevalue = $this->dependentsetting->get_visibility(); // Set it regardless of whether we need to. $this->dependentsetting->set_visibility($this->setting->get_visibility()); // Return true if it changed. return ($prevalue != $this->dependentsetting->get_visibility()); } /** * All dependencies must define how they would like to deal with a status change * @param int $oldstatus */ abstract protected function process_status_change($oldstatus); /** * All dependencies must define how they would like to process a value change */ abstract protected function process_value_change($oldvalue); /** * Gets the primary setting * @return backup_setting */ public function get_setting() { return $this->setting; } /** * Gets the dependent setting * @return backup_setting */ public function get_dependent_setting() { return $this->dependentsetting; } /** * This function enforces the dependency */ abstract public function enforce(); /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ abstract public function get_moodleform_properties(); /** * Returns true if the dependent setting is locked by this setting_dependency. * @return bool */ abstract public function is_locked(); } /** * A dependency that disables the secondary setting if the primary setting is * equal to the provided value * * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class setting_dependency_disabledif_equals extends setting_dependency { /** * The value to compare to * @var mixed */ protected $value; /** * Creates the dependency * * @param base_setting $setting * @param base_setting $dependentsetting * @param mixed $value * @param mixed $defaultvalue */ public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) { parent::__construct($setting, $dependentsetting, $defaultvalue); $this->value = ($value) ? (string)$value : 0; } /** * Returns true if the dependent setting is locked by this setting_dependency. * @return bool */ public function is_locked() { // If the setting is locked or the dependent setting should be locked then return true. if ($this->setting->get_status() !== base_setting::NOT_LOCKED || $this->evaluate_disabled_condition($this->setting->get_value())) { return true; } // Else the dependent setting is not locked by this setting_dependency. return false; } /** * Processes a value change in the primary setting * @param mixed $oldvalue * @return bool */ protected function process_value_change($oldvalue) { if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_PERMISSION || $this->dependentsetting->get_status() == base_setting::LOCKED_BY_CONFIG) { // When setting is locked by permission or config do not apply dependencies. return false; } $prevalue = $this->dependentsetting->get_value(); // If the setting is the desired value enact the dependency. $settingvalue = $this->setting->get_value(); if ($this->evaluate_disabled_condition($settingvalue)) { // The dependent setting needs to be locked by hierachy and set to the // default value. $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY); // For checkboxes the default value is false, but when the setting is // locked, the value should inherit from the parent setting. if ($this->defaultvalue === false) { $this->dependentsetting->set_value($settingvalue); } else { $this->dependentsetting->set_value($this->defaultvalue); } } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) { // We can unlock the dependent setting. $this->dependentsetting->set_status(base_setting::NOT_LOCKED); } // Return true if the value has changed for the dependent setting. return ($prevalue != $this->dependentsetting->get_value()); } /** * Processes a status change in the primary setting * @param mixed $oldstatus * @return bool */ protected function process_status_change($oldstatus) { // Store the dependent status. $prevalue = $this->dependentsetting->get_status(); // Store the current status. $currentstatus = $this->setting->get_status(); if ($currentstatus == base_setting::NOT_LOCKED) { if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && !$this->evaluate_disabled_condition($this->setting->get_value())) { // Dependency has changes, is not fine, unlock the dependent setting. $this->dependentsetting->set_status(base_setting::NOT_LOCKED); } } else { // Make sure the dependent setting is also locked, in this case by hierarchy. $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY); } // Return true if the dependent setting has changed. return ($prevalue != $this->dependentsetting->get_status()); } /** * Enforces the dependency if required. * @return bool True if there were changes */ public function enforce() { // This will be set to true if ANYTHING changes. $changes = false; // First process any value changes. if ($this->process_value_change($this->setting->get_value())) { $changes = true; } // Second process any status changes. if ($this->process_status_change($this->setting->get_status())) { $changes = true; } // Finally process visibility changes. if ($this->process_visibility_change($this->setting->get_visibility())) { $changes = true; } return $changes; } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'eq', 'value' => $this->value ); } /** * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. * This function should be abstract, but there will probably be existing sub-classes so we must provide a default * implementation. * @param mixed $value The value of the parent setting. * @return bool */ protected function evaluate_disabled_condition($value) { return $value == $this->value; } } /** * A dependency that disables the secondary setting if the primary setting is * not equal to the provided value * * @copyright 2011 Darko Miletic * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class setting_dependency_disabledif_not_equals extends setting_dependency_disabledif_equals { /** * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. * @param mixed $value The value of the parent setting. * @return bool */ protected function evaluate_disabled_condition($value) { return $value != $this->value; } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'notequal', 'value' => $this->value ); } } /** * Disable if a value is in a list. */ class setting_dependency_disabledif_in_array extends setting_dependency_disabledif_equals { /** * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. * @param mixed $value The value of the parent setting. * @return bool */ protected function evaluate_disabled_condition($value) { return in_array($value, $this->value); } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'eq', 'value' => $this->value ); } } /** * This class is here for backwards compatibility (terrible name). */ class setting_dependency_disabledif_equals2 extends setting_dependency_disabledif_in_array { } /** * A dependency that disables the secondary element if the primary element is * true or checked * * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals { public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { parent::__construct($setting, $dependentsetting, true, $defaultvalue); $this->value = true; } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'checked' ); } } /** * A dependency that disables the secondary element if the primary element is * false or not checked * * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals { public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { parent::__construct($setting, $dependentsetting, false, $defaultvalue); $this->value = false; } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'notchecked' ); } } /** * A dependency that disables the secondary setting if the value of the primary setting * is not empty. * * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class setting_dependency_disabledif_not_empty extends setting_dependency_disabledif_equals { public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { parent::__construct($setting, $dependentsetting, false, $defaultvalue); $this->value = false; } /** * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. * @param mixed $value The value of the parent setting. * @return bool */ protected function evaluate_disabled_condition($value) { return !empty($value); } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'notequal', 'value' => '' ); } } /** * A dependency that disables the secondary setting if the value of the primary setting * is empty. * * @copyright 2010 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class setting_dependency_disabledif_empty extends setting_dependency_disabledif_equals { public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) { parent::__construct($setting, $dependentsetting, false, $defaultvalue); $this->value = false; } /** * Evaluate the current value of the setting and return true if the dependent setting should be locked or false. * @param mixed $value The value of the parent setting. * @return bool */ protected function evaluate_disabled_condition($value) { return empty($value); } /** * Returns an array of properties suitable to be used to define a moodleforms * disabled command * @return array */ public function get_moodleform_properties() { return array( 'setting' => $this->dependentsetting->get_ui_name(), 'dependenton' => $this->setting->get_ui_name(), 'condition' => 'notequal', 'value' => '' ); } } PK\Ezm^^tests/settings_test.phpnu[. /** * Setting tests (all). * * @package core_backup * @category test * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_backup; use activity_backup_setting; use backup_setting; use backup_setting_exception; use base_setting; use base_setting_exception; use course_backup_setting; use section_backup_setting; use setting_dependency; use setting_dependency_disabledif_empty; defined('MOODLE_INTERNAL') || die(); // Include all the needed stuff global $CFG; require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php'); require_once($CFG->dirroot . '/backup/backup.class.php'); require_once($CFG->dirroot . '/backup/util/settings/base_setting.class.php'); require_once($CFG->dirroot . '/backup/util/settings/backup_setting.class.php'); require_once($CFG->dirroot . '/backup/util/settings/setting_dependency.class.php'); require_once($CFG->dirroot . '/backup/util/settings/root/root_backup_setting.class.php'); require_once($CFG->dirroot . '/backup/util/settings/activity/activity_backup_setting.class.php'); require_once($CFG->dirroot . '/backup/util/settings/section/section_backup_setting.class.php'); require_once($CFG->dirroot . '/backup/util/settings/course/course_backup_setting.class.php'); require_once($CFG->dirroot . '/backup/util/ui/backup_ui_setting.class.php'); /** * Setting tests (all). * * @package core_backup * @category test * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ final class settings_test extends \basic_testcase { /** * test base_setting class */ public function test_base_setting(): void { // Instantiate base_setting and check everything $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); $this->assertTrue($bs instanceof base_setting); $this->assertEquals($bs->get_name(), 'test'); $this->assertEquals($bs->get_vtype(), base_setting::IS_BOOLEAN); $this->assertTrue(is_null($bs->get_value())); $this->assertEquals($bs->get_visibility(), base_setting::VISIBLE); $this->assertEquals($bs->get_status(), base_setting::NOT_LOCKED); // Instantiate base_setting with explicit nulls $bs = new mock_base_setting('test', base_setting::IS_FILENAME, 'filename.txt', null, null); $this->assertEquals($bs->get_value() , 'filename.txt'); $this->assertEquals($bs->get_visibility(), base_setting::VISIBLE); $this->assertEquals($bs->get_status(), base_setting::NOT_LOCKED); // Instantiate base_setting and set value, visibility and status $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); $bs->set_value(true); $this->assertNotEmpty($bs->get_value()); $bs->set_visibility(base_setting::HIDDEN); $this->assertEquals($bs->get_visibility(), base_setting::HIDDEN); $bs->set_status(base_setting::LOCKED_BY_HIERARCHY); $this->assertEquals($bs->get_status(), base_setting::LOCKED_BY_HIERARCHY); // Instantiate with wrong vtype try { $bs = new mock_base_setting('test', 'one_wrong_type'); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_invalid_type'); } // Instantiate with wrong integer value try { $bs = new mock_base_setting('test', base_setting::IS_INTEGER, 99.99); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_invalid_integer'); } // Instantiate with wrong filename value try { $bs = new mock_base_setting('test', base_setting::IS_FILENAME, '../../filename.txt'); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_invalid_filename'); } // Instantiate with wrong visibility try { $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, 'one_wrong_visibility'); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_invalid_visibility'); } // Instantiate with wrong status try { $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, 'one_wrong_status'); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_invalid_status'); } // Instantiate base_setting and try to set wrong ui_type // We need a custom error handler to catch the type hinting error // that should return incorrect_object_passed $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); set_error_handler('\core_backup\backup_setting_error_handler', E_RECOVERABLE_ERROR); try { $bs->set_ui('one_wrong_ui_type', 'label', array(), array()); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'incorrect_object_passed'); } catch (\TypeError $e) { // On PHP7+ we get a TypeError raised, lets check we've the right error. $this->assertMatchesRegularExpression('/must be (of type|an instance of) backup_setting_ui/', $e->getMessage()); } restore_error_handler(); // Instantiate base_setting and try to set wrong ui_label // We need a custom error handler to catch the type hinting error // that should return incorrect_object_passed $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); set_error_handler('\core_backup\backup_setting_error_handler', E_RECOVERABLE_ERROR); try { $bs->set_ui(base_setting::UI_HTML_CHECKBOX, 'one/wrong/label', array(), array()); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'incorrect_object_passed'); } catch (\TypeError $e) { // On PHP7+ we get a TypeError raised, lets check we've the right error. $this->assertMatchesRegularExpression('/must be (of type|an instance of) backup_setting_ui/', $e->getMessage()); } restore_error_handler(); // Try to change value of locked setting by permission $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, base_setting::LOCKED_BY_PERMISSION); try { $bs->set_value(true); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_locked_by_permission'); } // Try to change value of locked setting by config $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, base_setting::LOCKED_BY_CONFIG); try { $bs->set_value(true); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_locked_by_config'); } // Try to add same setting twice $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); $bs1->add_dependency($bs2, null, array('value'=>0)); try { $bs1->add_dependency($bs2); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_already_added'); } // Try to create one circular reference $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); try { $bs1->add_dependency($bs1); // self $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_circular_reference'); $this->assertTrue($e->a instanceof \stdClass); $this->assertEquals($e->a->main, 'test1'); $this->assertEquals($e->a->alreadydependent, 'test1'); } $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null); $bs4 = new mock_base_setting('test4', base_setting::IS_INTEGER, null); $bs1->add_dependency($bs2, null, array('value'=>0)); $bs2->add_dependency($bs3, null, array('value'=>0)); $bs3->add_dependency($bs4, null, array('value'=>0)); try { $bs4->add_dependency($bs1, null, array('value'=>0)); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_circular_reference'); $this->assertTrue($e->a instanceof \stdClass); $this->assertEquals($e->a->main, 'test1'); $this->assertEquals($e->a->alreadydependent, 'test4'); } $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); $bs1->register_dependency(new setting_dependency_disabledif_empty($bs1, $bs2)); try { // $bs1 is already dependent on $bs2 so this should fail. $bs2->register_dependency(new setting_dependency_disabledif_empty($bs2, $bs1)); $this->assertTrue(false, 'base_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'setting_circular_reference'); $this->assertTrue($e->a instanceof \stdClass); $this->assertEquals($e->a->main, 'test1'); $this->assertEquals($e->a->alreadydependent, 'test2'); } // Create 3 settings and observe between them, last one must // automatically inherit all the settings defined in the main one $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null); $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY); $bs2->add_dependency($bs3, setting_dependency::DISABLED_NOT_EMPTY); // Check values are spreaded ok $bs1->set_value(123); $this->assertEquals($bs1->get_value(), 123); $this->assertEquals($bs2->get_value(), $bs1->get_value()); $this->assertEquals($bs3->get_value(), $bs1->get_value()); // Add one more setting and set value again $bs4 = new mock_base_setting('test4', base_setting::IS_INTEGER, null); $bs2->add_dependency($bs4, setting_dependency::DISABLED_NOT_EMPTY); $bs2->set_value(321); // The above change should change $this->assertEquals($bs1->get_value(), 123); $this->assertEquals($bs2->get_value(), 321); $this->assertEquals($bs3->get_value(), 321); $this->assertEquals($bs4->get_value(), 321); // Check visibility is spreaded ok $bs1->set_visibility(base_setting::HIDDEN); $this->assertEquals($bs2->get_visibility(), $bs1->get_visibility()); $this->assertEquals($bs3->get_visibility(), $bs1->get_visibility()); // Check status is spreaded ok $bs1->set_status(base_setting::LOCKED_BY_HIERARCHY); $this->assertEquals($bs2->get_status(), $bs1->get_status()); $this->assertEquals($bs3->get_status(), $bs1->get_status()); // Create 3 settings and observe between them, put them in one array, // force serialize/deserialize to check the observable pattern continues // working after that $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null); $bs1->add_dependency($bs2, null, array('value'=>0)); $bs2->add_dependency($bs3, null, array('value'=>0)); // Serialize $arr = array($bs1, $bs2, $bs3); $ser = base64_encode(serialize($arr)); // Unserialize and copy to new objects $newarr = unserialize(base64_decode($ser)); $ubs1 = $newarr[0]; $ubs2 = $newarr[1]; $ubs3 = $newarr[2]; // Must continue being base settings $this->assertTrue($ubs1 instanceof base_setting); $this->assertTrue($ubs2 instanceof base_setting); $this->assertTrue($ubs3 instanceof base_setting); // Set parent setting $ubs1->set_value(1234); $ubs1->set_visibility(base_setting::HIDDEN); $ubs1->set_status(base_setting::LOCKED_BY_HIERARCHY); // Check changes have been spreaded $this->assertEquals($ubs2->get_visibility(), $ubs1->get_visibility()); $this->assertEquals($ubs3->get_visibility(), $ubs1->get_visibility()); $this->assertEquals($ubs2->get_status(), $ubs1->get_status()); $this->assertEquals($ubs3->get_status(), $ubs1->get_status()); } /** * Test that locked and unlocked states on dependent backup settings at the same level * correctly do not flow from the parent to the child setting when the setting is locked by permissions. */ public function test_dependency_empty_locked_by_permission_child_is_not_unlocked(): void { // Check dependencies are working ok. $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, 2); $bs1->set_level(1); $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, 2); $bs2->set_level(1); // Same level *must* work. $bs1->add_dependency($bs2, setting_dependency::DISABLED_EMPTY); $bs1->set_status(base_setting::LOCKED_BY_PERMISSION); $this->assertEquals(base_setting::LOCKED_BY_HIERARCHY, $bs2->get_status()); $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs1->get_status()); $bs2->set_status(base_setting::LOCKED_BY_PERMISSION); $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs1->get_status()); // Unlocking the parent should NOT unlock the child. $bs1->set_status(base_setting::NOT_LOCKED); $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs2->get_status()); } /** * Test that locked and unlocked states on dependent backup settings at the same level * correctly do flow from the parent to the child setting when the setting is locked by config. */ public function test_dependency_not_empty_locked_by_config_parent_is_unlocked(): void { $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, 0); $bs1->set_level(1); $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, 0); $bs2->set_level(1); // Same level *must* work. $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY); $bs1->set_status(base_setting::LOCKED_BY_CONFIG); $this->assertEquals(base_setting::LOCKED_BY_HIERARCHY, $bs2->get_status()); $this->assertEquals(base_setting::LOCKED_BY_CONFIG, $bs1->get_status()); // Unlocking the parent should unlock the child. $bs1->set_status(base_setting::NOT_LOCKED); $this->assertEquals(base_setting::NOT_LOCKED, $bs2->get_status()); } /** * test backup_setting class */ public function test_backup_setting(): void { // Instantiate backup_setting class and set level $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null); $bs->set_level(1); $this->assertEquals($bs->get_level(), 1); // Instantiate backup setting class and try to add one non backup_setting dependency set_error_handler('\core_backup\backup_setting_error_handler', E_RECOVERABLE_ERROR); $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null); try { $bs->add_dependency(new \stdClass()); $this->assertTrue(false, 'backup_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof backup_setting_exception); $this->assertEquals($e->errorcode, 'incorrect_object_passed'); } catch (\TypeError $e) { // On PHP7+ we get a TypeError raised, lets check we've the right error. $this->assertMatchesRegularExpression('/must be (an instance of|of type) base_setting/', $e->getMessage()); } restore_error_handler(); // Try to assing upper level dependency $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, null); $bs1->set_level(1); $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, null); $bs2->set_level(2); try { $bs2->add_dependency($bs1); $this->assertTrue(false, 'backup_setting_exception expected'); } catch (\Exception $e) { $this->assertTrue($e instanceof backup_setting_exception); $this->assertEquals($e->errorcode, 'cannot_add_upper_level_dependency'); } // Check dependencies are working ok $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, null); $bs1->set_level(1); $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, null); $bs2->set_level(1); // Same level *must* work $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY); $bs1->set_value(123456); $this->assertEquals($bs2->get_value(), $bs1->get_value()); } /** * test activity_backup_setting class */ public function test_activity_backup_setting(): void { $bs = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null); $this->assertEquals($bs->get_level(), backup_setting::ACTIVITY_LEVEL); // Check checksum implementation is working $bs1 = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null); $bs1->set_value(123); $checksum = $bs1->calculate_checksum(); $this->assertNotEmpty($checksum); $this->assertTrue($bs1->is_checksum_correct($checksum)); } /** * test section_backup_setting class */ public function test_section_backup_setting(): void { $bs = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null); $this->assertEquals($bs->get_level(), backup_setting::SECTION_LEVEL); // Check checksum implementation is working $bs1 = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null); $bs1->set_value(123); $checksum = $bs1->calculate_checksum(); $this->assertNotEmpty($checksum); $this->assertTrue($bs1->is_checksum_correct($checksum)); } /** * test course_backup_setting class */ public function test_course_backup_setting(): void { $bs = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null); $this->assertEquals($bs->get_level(), backup_setting::COURSE_LEVEL); // Check checksum implementation is working $bs1 = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null); $bs1->set_value(123); $checksum = $bs1->calculate_checksum(); $this->assertNotEmpty($checksum); $this->assertTrue($bs1->is_checksum_correct($checksum)); } } /** * helper extended base_setting class that makes some methods public for testing */ class mock_base_setting extends base_setting { public function get_vtype() { return $this->vtype; } public function process_change($setting, $ctype, $oldv) { // Simply, inherit from the main object $this->set_value($setting->get_value()); $this->set_visibility($setting->get_visibility()); $this->set_status($setting->get_status()); } } /** * helper extended backup_setting class that makes some methods public for testing */ class mock_backup_setting extends backup_setting { public function set_level($level) { $this->level = $level; } public function process_change($setting, $ctype, $oldv) { // Simply, inherit from the main object $this->set_value($setting->get_value()); $this->set_visibility($setting->get_visibility()); $this->set_status($setting->get_status()); } } /** * helper extended activity_backup_setting class that makes some methods public for testing */ class mock_activity_backup_setting extends activity_backup_setting { public function process_change($setting, $ctype, $oldv) { // Do nothing } } /** * helper extended section_backup_setting class that makes some methods public for testing */ class mock_section_backup_setting extends section_backup_setting { public function process_change($setting, $ctype, $oldv) { // Do nothing } } /** * helper extended course_backup_setting class that makes some methods public for testing */ class mock_course_backup_setting extends course_backup_setting { public function process_change($setting, $ctype, $oldv) { // Do nothing } } /** * This error handler is used to convert errors to excpetions so that simepltest can * catch them. * * This is required in order to catch type hint mismatches that result in a error * being thrown. It should only ever be used to catch E_RECOVERABLE_ERROR's. * * It throws a backup_setting_exception with 'incorrect_object_passed' * * @param int $errno E_RECOVERABLE_ERROR * @param string $errstr * @param string $errfile * @param int $errline * @return null */ function backup_setting_error_handler($errno, $errstr, $errfile, $errline) { if ($errno !== E_RECOVERABLE_ERROR) { // Currently we only want to deal with type hinting errors return false; } throw new backup_setting_exception('incorrect_object_passed'); } PK\3üuubackup_setting.class.phpnu[. /** * Defines backup_setting class * * @package core_backup * @category backup * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** * Parent class for all backup settings */ abstract class backup_setting extends base_setting implements checksumable { // Some constants defining levels of setting const ROOT_LEVEL = 1; const COURSE_LEVEL = 5; const SECTION_LEVEL = 9; const ACTIVITY_LEVEL = 13; /** @var int the subsection level. */ const SUBSECTION_LEVEL = 17; /** @var int the activity inside a subsection level. */ const SUBACTIVITY_LEVEL = 21; /** @var int Level of the setting, eg {@link self::ROOT_LEVEL} */ protected $level; /** * {@inheritdoc} */ public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) { parent::__construct($name, $vtype, $value, $visibility, $status); // Generate a default ui $this->uisetting = new backup_setting_ui_checkbox($this, $name); } /** * @return int Level of the setting, eg {@link self::ROOT_LEVEL} */ public function get_level() { return $this->level; } /** * Creates and sets a user interface for this setting given appropriate arguments * * @param int $type * @param string $label * @param array $attributes * @param array $options */ public function make_ui($type, $label, ?array $attributes = null, ?array $options = null) { $this->uisetting = backup_setting_ui::make($this, $type, $label, $attributes, $options); if (is_array($options) || is_object($options)) { $options = (array)$options; switch (get_class($this->uisetting)) { case 'backup_setting_ui_radio' : // text if (array_key_exists('text', $options)) { $this->uisetting->set_text($options['text']); } case 'backup_setting_ui_checkbox' : // value if (array_key_exists('value', $options)) { $this->uisetting->set_value($options['value']); } break; case 'backup_setting_ui_select' : // options if (array_key_exists('options', $options)) { $this->uisetting->set_values($options['options']); } break; } } } public function add_dependency(base_setting $dependentsetting, $type=setting_dependency::DISABLED_VALUE, $options=array()) { if (!($dependentsetting instanceof backup_setting)) { throw new backup_setting_exception('invalid_backup_setting_parameter'); } // Check the dependency level is >= current level if ($dependentsetting->get_level() < $this->level) { throw new backup_setting_exception('cannot_add_upper_level_dependency', [ $dependentsetting->get_level(), $dependentsetting->get_name(), $this->level, $this->get_name(), ]); } parent::add_dependency($dependentsetting, $type, $options); } // checksumable interface methods public function calculate_checksum() { // Checksum is a simple md5 hash of name, value, level // Not following dependencies at all. Each setting will // calculate its own checksum return md5($this->name . '-' . $this->value . '-' . $this->level); } public function is_checksum_correct($checksum) { return $this->calculate_checksum() === $checksum; } } /** * Exception class used by all the @backup_setting stuff */ class backup_setting_exception extends base_setting_exception { } PK\77*activity/activity_backup_setting.class.phpnu[. /** * @package moodlecore * @subpackage backup-settings * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Abstract class containing all the common stuff for activity backup settings * * TODO: Finish phpdocs */ abstract class activity_backup_setting extends backup_setting { public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) { $this->level = self::ACTIVITY_LEVEL; parent::__construct($name, $vtype, $value, $visibility, $status); } } PK\+ERERbase_setting.class.phpnu[. /** * @package moodlecore * @subpackage backup-settings * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * This abstract class defines one basic setting * * Each setting will be able to control its name, value (from a list), ui * representation (check box, drop down, text field...), visibility, status * (editable/locked...) and its hierarchy with other settings (using one * like-observer pattern. * * TODO: Finish phpdocs */ abstract class base_setting { // Some constants defining different ui representations for the setting const UI_NONE = 0; const UI_HTML_CHECKBOX = 10; const UI_HTML_RADIOBUTTON = 20; const UI_HTML_DROPDOWN = 30; const UI_HTML_TEXTFIELD = 40; // Type of validation to perform against the value (relaying in PARAM_XXX validations) const IS_BOOLEAN = 'bool'; const IS_INTEGER = 'int'; const IS_FILENAME= 'file'; const IS_PATH = 'path'; const IS_TEXT = 'text'; // Visible/hidden const VISIBLE = 1; const HIDDEN = 0; // Editable/locked (by different causes) const NOT_LOCKED = 3; const LOCKED_BY_CONFIG = 5; const LOCKED_BY_HIERARCHY = 7; const LOCKED_BY_PERMISSION = 9; // Type of change to inform dependencies const CHANGED_VALUE = 1; const CHANGED_VISIBILITY = 2; const CHANGED_STATUS = 3; protected $name; // name of the setting protected $value; // value of the setting protected $unlockedvalue; // Value to set after the setting is unlocked. protected $vtype; // type of value (setting_base::IS_BOOLEAN/setting_base::IS_INTEGER...) protected $visibility; // visibility of the setting (setting_base::VISIBLE/setting_base::HIDDEN) protected $status; // setting_base::NOT_LOCKED/setting_base::LOCKED_BY_PERMISSION... /** @var setting_dependency[] */ protected $dependencies = array(); // array of dependent (observer) objects (usually setting_base ones) protected $dependenton = array(); /** * The user interface for this setting * @var backup_setting_ui|backup_setting_ui_checkbox|backup_setting_ui_radio|backup_setting_ui_select|backup_setting_ui_text */ protected $uisetting; /** * An array that contains the identifier and component of a help string if one * has been set * @var array */ protected $help = array(); /** * Instantiates a setting object * * @param string $name Name of the setting * @param string $vtype Type of the setting, eg {@link self::IS_TEXT} * @param mixed $value Value of the setting * @param bool $visibility Is the setting visible in the UI, eg {@link self::VISIBLE} * @param int $status Status of the setting with regards to the locking, eg {@link self::NOT_LOCKED} */ public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) { // Check vtype if ($vtype !== self::IS_BOOLEAN && $vtype !== self::IS_INTEGER && $vtype !== self::IS_FILENAME && $vtype !== self::IS_PATH && $vtype !== self::IS_TEXT) { throw new base_setting_exception('setting_invalid_type'); } // Validate value $value = $this->validate_value($vtype, $value); // Check visibility $visibility = $this->validate_visibility($visibility); // Check status $status = $this->validate_status($status); $this->name = $name; $this->vtype = $vtype; $this->value = $value; $this->visibility = $visibility; $this->status = $status; $this->unlockedvalue = $this->value; // Generate a default ui $this->uisetting = new base_setting_ui($this); } /** * Destroy all circular references. It helps PHP 5.2 a lot! */ public function destroy() { // Before reseting anything, call destroy recursively foreach ($this->dependencies as $dependency) { $dependency->destroy(); } foreach ($this->dependenton as $dependenton) { $dependenton->destroy(); } if ($this->uisetting) { $this->uisetting->destroy(); } // Everything has been destroyed recursively, now we can reset safely $this->dependencies = array(); $this->dependenton = array(); $this->uisetting = null; } public function get_name() { return $this->name; } public function get_value() { return $this->value; } public function get_visibility() { return $this->visibility; } public function get_status() { return $this->status; } public function set_value($value) { // Validate value $value = $this->validate_value($this->vtype, $value); // Only can change value if setting is not locked if ($this->status != self::NOT_LOCKED) { switch ($this->status) { case self::LOCKED_BY_PERMISSION: throw new base_setting_exception('setting_locked_by_permission'); case self::LOCKED_BY_CONFIG: throw new base_setting_exception('setting_locked_by_config'); } } $oldvalue = $this->value; $this->value = $value; if ($value !== $oldvalue) { // Value has changed, let's inform dependencies $this->inform_dependencies(self::CHANGED_VALUE, $oldvalue); } } public function set_visibility($visibility) { $visibility = $this->validate_visibility($visibility); // If this setting is dependent on other settings first check that all // of those settings are visible if (count($this->dependenton) > 0 && $visibility == base_setting::VISIBLE) { foreach ($this->dependenton as $dependency) { if ($dependency->get_setting()->get_visibility() != base_setting::VISIBLE) { $visibility = base_setting::HIDDEN; break; } } } $oldvisibility = $this->visibility; $this->visibility = $visibility; if ($visibility !== $oldvisibility) { // Visibility has changed, let's inform dependencies $this->inform_dependencies(self::CHANGED_VISIBILITY, $oldvisibility); } } public function set_status($status) { $status = $this->validate_status($status); if (($this->status == base_setting::LOCKED_BY_PERMISSION || $this->status == base_setting::LOCKED_BY_CONFIG) && $status == base_setting::LOCKED_BY_HIERARCHY) { // Lock by permission or config can not be overriden by lock by hierarchy. return; } // If the setting is being unlocked first check whether an other settings // this setting is dependent on are locked. If they are then we still don't // want to lock this setting. if (count($this->dependenton) > 0 && $status == base_setting::NOT_LOCKED) { foreach ($this->dependenton as $dependency) { if ($dependency->is_locked()) { // It still needs to be locked $status = base_setting::LOCKED_BY_HIERARCHY; break; } } } $oldstatus = $this->status; $this->status = $status; if ($status !== $oldstatus) { // Status has changed, let's inform dependencies $this->inform_dependencies(self::CHANGED_STATUS, $oldstatus); if ($status == base_setting::NOT_LOCKED) { // When setting gets unlocked set it to the original value. $this->set_value($this->unlockedvalue); } } } /** * Gets an array of properties for all of the dependencies that will affect * this setting. * * This method returns an array rather than the dependencies in order to * minimise the memory footprint of for the potentially huge recursive * dependency structure that we may be dealing with. * * This method also ensures that all dependencies are transmuted to affect * the setting in question and that we don't provide any duplicates. * * @param string|null $settingname * @return array */ public function get_my_dependency_properties($settingname=null) { if ($settingname == null) { $settingname = $this->get_ui_name(); } $dependencies = array(); foreach ($this->dependenton as $dependenton) { $properties = $dependenton->get_moodleform_properties(); $properties['setting'] = $settingname; $dependencies[$properties['setting'].'-'.$properties['dependenton']] = $properties; $dependencies = array_merge($dependencies, $dependenton->get_setting()->get_my_dependency_properties($settingname)); } return $dependencies; } /** * Returns all of the dependencies that affect this setting. * e.g. settings this setting depends on. * * @return array Array of setting_dependency's */ public function get_settings_depended_on() { return $this->dependenton; } /** * Checks if there are other settings that are dependent on this setting * * @return bool True if there are other settings that are dependent on this setting */ public function has_dependent_settings() { return (count($this->dependencies)>0); } /** * Checks if this setting is dependent on any other settings * * @return bool True if this setting is dependent on any other settings */ public function has_dependencies_on_settings() { return (count($this->dependenton)>0); } /** * Sets the user interface for this setting * * @param base_setting_ui $ui */ public function set_ui(backup_setting_ui $ui) { $this->uisetting = $ui; } /** * Gets the user interface for this setting * * @return base_setting_ui */ public function get_ui() { return $this->uisetting; } /** * Adds a dependency where another setting depends on this setting. * @param setting_dependency $dependency */ public function register_dependency(setting_dependency $dependency) { if ($this->is_circular_reference($dependency->get_dependent_setting())) { $a = new stdclass(); $a->alreadydependent = $this->name; $a->main = $dependency->get_dependent_setting()->get_name(); throw new base_setting_exception('setting_circular_reference', $a); } $this->dependencies[$dependency->get_dependent_setting()->get_name()] = $dependency; $dependency->get_dependent_setting()->register_dependent_dependency($dependency); } /** * Adds a dependency where this setting is dependent on another. * * This should only be called internally once we are sure it is not cicrular. * * @param setting_dependency $dependency */ protected function register_dependent_dependency(setting_dependency $dependency) { $this->dependenton[$dependency->get_setting()->get_name()] = $dependency; } /** * Quick method to add a dependency to this setting. * * The dependency created is done so by inspecting this setting and the * setting that is passed in as the dependent setting. * * @param base_setting $dependentsetting * @param int $type One of setting_dependency::* * @param array $options */ public function add_dependency(base_setting $dependentsetting, $type=null, $options=array()) { if ($this->is_circular_reference($dependentsetting)) { $a = new stdclass(); $a->alreadydependent = $this->name; $a->main = $dependentsetting->get_name(); throw new base_setting_exception('setting_circular_reference', $a); } // Check the settings hasn't been already added if (array_key_exists($dependentsetting->get_name(), $this->dependencies)) { throw new base_setting_exception('setting_already_added'); } $options = (array)$options; if (!array_key_exists('defaultvalue', $options)) { $options['defaultvalue'] = false; } if ($type == null) { switch ($this->vtype) { case self::IS_BOOLEAN : if ($this->get_ui_type() == self::UI_HTML_CHECKBOX) { if ($this->value) { $type = setting_dependency::DISABLED_NOT_CHECKED; } else { $type = setting_dependency::DISABLED_CHECKED; } } else { if ($this->value) { $type = setting_dependency::DISABLED_FALSE; } else { $type = setting_dependency::DISABLED_TRUE; } } break; case self::IS_FILENAME : case self::IS_PATH : case self::IS_INTEGER : default : $type = setting_dependency::DISABLED_VALUE; break; } } switch ($type) { case setting_dependency::DISABLED_VALUE : if (!array_key_exists('value', $options)) { throw new base_setting_exception('dependency_needs_value'); } $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, $options['value'], $options['defaultvalue']); break; case setting_dependency::DISABLED_TRUE : $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, true, $options['defaultvalue']); break; case setting_dependency::DISABLED_FALSE : $dependency = new setting_dependency_disabledif_equals($this, $dependentsetting, false, $options['defaultvalue']); break; case setting_dependency::DISABLED_CHECKED : $dependency = new setting_dependency_disabledif_checked($this, $dependentsetting, $options['defaultvalue']); break; case setting_dependency::DISABLED_NOT_CHECKED : $dependency = new setting_dependency_disabledif_not_checked($this, $dependentsetting, $options['defaultvalue']); break; case setting_dependency::DISABLED_EMPTY : $dependency = new setting_dependency_disabledif_empty($this, $dependentsetting, $options['defaultvalue']); break; case setting_dependency::DISABLED_NOT_EMPTY : $dependency = new setting_dependency_disabledif_not_empty($this, $dependentsetting, $options['defaultvalue']); break; } $this->dependencies[$dependentsetting->get_name()] = $dependency; $dependency->get_dependent_setting()->register_dependent_dependency($dependency); } /** * Get the PARAM_XXXX validation to be applied to the setting * * @return string The PARAM_XXXX constant of null if the setting type is not defined */ public function get_param_validation() { switch ($this->vtype) { case self::IS_BOOLEAN: return PARAM_BOOL; case self::IS_INTEGER: return PARAM_INT; case self::IS_FILENAME: return PARAM_FILE; case self::IS_PATH: return PARAM_PATH; case self::IS_TEXT: return PARAM_TEXT; } return null; } // Protected API starts here protected function validate_value($vtype, $value) { if (is_null($value)) { // Nulls aren't validated return null; } $oldvalue = $value; switch ($vtype) { case self::IS_BOOLEAN: $value = clean_param($oldvalue, PARAM_BOOL); // Just clean break; case self::IS_INTEGER: $value = clean_param($oldvalue, PARAM_INT); if ($value != $oldvalue) { throw new base_setting_exception('setting_invalid_integer', $oldvalue); } break; case self::IS_FILENAME: $value = clean_param($oldvalue, PARAM_FILE); if ($value != $oldvalue) { throw new base_setting_exception('setting_invalid_filename', $oldvalue); } break; case self::IS_PATH: $value = clean_param($oldvalue, PARAM_PATH); if ($value != $oldvalue) { throw new base_setting_exception('setting_invalid_path', $oldvalue); } break; case self::IS_TEXT: $value = clean_param($oldvalue, PARAM_TEXT); if ($value != $oldvalue) { throw new base_setting_exception('setting_invalid_text', $oldvalue); } break; } return $value; } protected function validate_visibility($visibility) { if (is_null($visibility)) { $visibility = self::VISIBLE; } if ($visibility !== self::VISIBLE && $visibility !== self::HIDDEN) { throw new base_setting_exception('setting_invalid_visibility'); } return $visibility; } protected function validate_status($status) { if (is_null($status)) { $status = self::NOT_LOCKED; } if ($status !== self::NOT_LOCKED && $status !== self::LOCKED_BY_CONFIG && $status !== self::LOCKED_BY_PERMISSION && $status !== self::LOCKED_BY_HIERARCHY) { throw new base_setting_exception('setting_invalid_status', $status); } return $status; } protected function inform_dependencies($ctype, $oldv) { foreach ($this->dependencies as $dependency) { $dependency->process_change($ctype, $oldv); } } protected function is_circular_reference($obj) { // Get object dependencies recursively and check (by name) if $this is already there $dependencies = $obj->get_dependencies(); if (array_key_exists($this->name, $dependencies) || $obj == $this) { return true; } // Recurse the dependent settings one by one foreach ($dependencies as $dependency) { if ($dependency->get_dependent_setting()->is_circular_reference($obj)) { return true; } } return false; } public function get_dependencies() { return $this->dependencies; } public function get_ui_name() { return $this->uisetting->get_name(); } public function get_ui_type() { return $this->uisetting->get_type(); } /** * Sets a help string for this setting * * @param string $identifier * @param string $component */ public function set_help($identifier, $component='moodle') { $this->help = array($identifier, $component); } /** * Gets the help string params for this setting if it has been set * @return array|false An array (identifier, component) or false if not set */ public function get_help() { if ($this->has_help()) { return $this->help; } return false; } /** * Returns true if help has been set for this setting * @return cool */ public function has_help() { return (!empty($this->help)); } } /* * Exception class used by all the @setting_base stuff */ class base_setting_exception extends backup_exception { public function __construct($errorcode, $a=NULL, $debuginfo=null) { parent::__construct($errorcode, $a, $debuginfo); } } PKg\سU˵&& media.phpnu[load->view('backend/grid_index');?> PKg\^jj reading.phpnu[load->view('backend/grid_index');?> PKg\2W7mail_server.phpnu[load->view('backend/grid_index');?> PKg\) general.phpnu[ load->view('backend/grid_index');?> PKg\ء writing.phpnu[load->view('backend/grid_index');?> PKg\&% % social_account.phpnu[load->view('backend/grid_index');?> PKg\~Ƀ;y+y+school_profile.phpnu[ load->view('backend/grid_index');?> PKg\ discussion.phpnu[load->view('backend/grid_index');?> PKp\Rh Writing.phpnu[PKp\Do o 3Discussion.phpnu[PKp\piU U Media.phpnu[PKp\!+ n)Mail_server.phpnu[PKp\6w` ` 7Reading.phpnu[PKp\iaƺ#ESchool_profile.phpnu[PKp\ > ^General.phpnu[PKp\"WS iuSocial_account.phpnu[PKr\茒Iii 6styles.cssnu[PKr\ / ىrenderer.phpnu[PKr\7?   Ǡdb/access.phpnu[PKr\qˁ db/upgrade.phpnu[PKr\s|sбlang/en/block_settings.phpnu[PKr\|j  edit_form.phpnu[PKr\GL?Kblock_settings.phpnu[PKr\# version.phpnu[PKr\tclasses/privacy/provider.phpnu[PKr\amd/src/settingsblock.jsnu[PKr\-[V^ ^ "amd/build/settingsblock.min.js.mapnu[PKr\]:MCCamd/build/settingsblock.min.jsnu[PK-\FLL*form.phpnu[PK-\QZv index.phpnu[PK\t&T"$root/root_backup_setting.class.phpnu[PK\\{44(*section/section_backup_setting.class.phpnu[PK\11&,0course/course_backup_setting.class.phpnu[PK\qYEE5setting_dependency.class.phpnu[PK\Ezm^^{tests/settings_test.phpnu[PK\3üuubackup_setting.class.phpnu[PK\77*Qactivity/activity_backup_setting.class.phpnu[PK\+ERERbase_setting.class.phpnu[PKg\سU˵&& mEmedia.phpnu[PKg\^jj [lreading.phpnu[PKg\2W7umail_server.phpnu[PKg\) '|general.phpnu[PKg\ء  writing.phpnu[PKg\&% % social_account.phpnu[PKg\~Ƀ;y+y+Nschool_profile.phpnu[PKg\  discussion.phpnu[PK&&K