1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4// Config must be included generally for availability of constants 5require_once('Services/UIComponent/CharSelector/classes/ilCharSelectorConfig.php'); 6 7/** 8* This shows a character selector 9*/ 10class ilCharSelectorGUI 11{ 12 /** 13 * @var ilLanguage 14 */ 15 protected $lng; 16 17 /** 18 * @var ilCtrl 19 */ 20 protected $ctrl; 21 22 /** 23 * @var ilTemplate 24 */ 25 protected $tpl; 26 27 /** 28 * @static list of command classes for which the char selector is allowed 29 * (can also be a parent class of the actual command class) 30 */ 31 private static $allowed_guis = array( 32 'assQuestionGUI', 33 'ilAssQuestionFeedbackEditingGUI', 34 'ilAssQuestionHintGUI', 35 'ilObjTestSettingsGeneralGUI', 36 'ilTestScoringGUI' 37 ); 38 39 /** 40 * @static ilCharSelectorGUI instance used for the current selector 41 */ 42 private static $current_gui; 43 44 /** 45 * @var ilCharSelectorConfig configuration object 46 */ 47 private $config = null; 48 49 /** 50 * @var boolean selector is already added to the page 51 */ 52 private $added_to_page = false; 53 54 55 /** 56 * Constructor 57 * @param string configuration context 58 */ 59 public function __construct($a_context = ilCharSelectorConfig::CONTEXT_NONE) 60 { 61 global $DIC; 62 63 $this->lng = $DIC->language(); 64 $this->ctrl = $DIC->ctrl(); 65 $this->tpl = $DIC["tpl"]; 66 $this->config = new ilCharSelectorConfig($a_context); 67 } 68 69 /** 70 * Check if the CharSelector is allowed for the current GUI 71 * @return boolean CharSelector is allowed 72 */ 73 public static function _isAllowed() 74 { 75 global $DIC; 76 77 $ilCtrl = $DIC->ctrl(); 78 79 // get the command class 80 // with correct case for checking parent classes 81 foreach ($ilCtrl->getCallHistory() as $call) { 82 if ($call['mode'] == 'execComm') { 83 $class = $call['class']; 84 } 85 } 86 87 // check the class and her parent classes 88 while ($class != false) { 89 if (in_array($class, self::$allowed_guis)) { 90 return true; 91 } 92 $class = get_parent_class($class); 93 } 94 95 return false; 96 } 97 98 /** 99 * Get the GUI that is used for the currently available selector 100 * (other GUI instances may exist for configuration in property forms) 101 * 102 * @param object (optional) current running test 103 * @return object 104 */ 105 public static function _getCurrentGUI(ilObjTest $a_test_obj = null) 106 { 107 if (!isset(self::$current_gui)) { 108 self::$current_gui = new ilCharSelectorGUI(); 109 self::$current_gui->setConfig(ilCharSelectorConfig::_getCurrentConfig($a_test_obj)); 110 } 111 return self::$current_gui; 112 } 113 114 /** 115 * Set the configuraton object 116 * @param ilCharSelectorConfig 117 */ 118 public function setConfig(ilCharSelectorConfig $a_config) 119 { 120 $this->config = $a_config; 121 } 122 123 /** 124 * Get the configuraton object 125 * @return ilCharSelectorConfig 126 */ 127 public function getConfig() 128 { 129 return $this->config; 130 } 131 132 /** 133 * add the configuration elements to a property form 134 * @param object property form 135 */ 136 public function addFormProperties(ilPropertyFormGUI $a_form) 137 { 138 $lng = $this->lng; 139 $lng->loadLanguageModule('adve'); 140 141 require_once('Services/UIComponent/CharSelector/classes/class.ilCharSelectorRadioGroupInputGUI.php'); 142 $availability = new ilCharSelectorRadioGroupInputGUI($lng->txt('char_selector_' . $this->config->getContext()), 'char_selector_availability'); 143 $inactive = new ilRadioOption($lng->txt('char_selector_inactive_' . $this->config->getContext()), ilCharSelectorConfig::INACTIVE); 144 $inactive->setInfo($lng->txt('char_selector_inactive_info_' . $this->config->getContext())); 145 $inherit = new ilRadioOption($lng->txt('char_selector_inherit_' . $this->config->getContext()), ilCharSelectorConfig::INHERIT); 146 $inherit->setInfo($lng->txt('char_selector_inherit_info_' . $this->config->getContext())); 147 $enabled = new ilRadioOption($lng->txt('char_selector_enabled_' . $this->config->getContext()), ilCharSelectorConfig::ENABLED); 148 $enabled->setInfo($lng->txt('char_selector_enabled_info_' . $this->config->getContext())); 149 $disabled = new ilRadioOption($lng->txt('char_selector_disabled_' . $this->config->getContext()), ilCharSelectorConfig::DISABLED); 150 $disabled->setInfo($lng->txt('char_selector_disabled_info_' . $this->config->getContext())); 151 152 $blocks = new ilSelectInputGUI($lng->txt('char_selector_blocks'), 'char_selector_blocks'); 153 $blocks->setInfo($lng->txt('char_selector_blocks_info')); 154 $blocks->setOptions($this->config->getBlockOptions()); 155 $blocks->setMulti(true); 156 $enabled->addSubItem($blocks); 157 158 $custom_items = new ilTextAreaInputGUI($lng->txt('char_selector_custom_items'), 'char_selector_custom_items'); 159 $tpl = new ilTemplate("tpl.char_selector_custom_info.html", true, true, "Services/UIComponent/CharSelector"); 160 $tpl->setVariable('1', $lng->txt('char_selector_custom_items_info1')); 161 $tpl->setVariable('2a', $lng->txt('char_selector_custom_items_info2a')); 162 $tpl->setVariable('2b', $lng->txt('char_selector_custom_items_info2b')); 163 $tpl->setVariable('3a', $lng->txt('char_selector_custom_items_info3a')); 164 $tpl->setVariable('3b', $lng->txt('char_selector_custom_items_info3b')); 165 $tpl->setVariable('4a', $lng->txt('char_selector_custom_items_info4a')); 166 $tpl->setVariable('4b', $lng->txt('char_selector_custom_items_info4b')); 167 $tpl->setVariable('5a', $lng->txt('char_selector_custom_items_info5a')); 168 $tpl->setVariable('5b', $lng->txt('char_selector_custom_items_info5b')); 169 $tpl->setVariable('6a', $lng->txt('char_selector_custom_items_info6a')); 170 $tpl->setVariable('6b', $lng->txt('char_selector_custom_items_info6b')); 171 $custom_items->setInfo($tpl->get()); 172 $enabled->addSubItem($custom_items); 173 174 switch ($this->config->getContext()) { 175 case ilCharSelectorConfig::CONTEXT_ADMIN: 176 $availability->addOption($inactive); 177 $availability->addOption($enabled); 178 $availability->addOption($disabled); 179 $a_form->addItem($availability); 180 break; 181 182 case ilCharSelectorConfig::CONTEXT_USER: 183 case ilCharSelectorConfig::CONTEXT_TEST: 184 $availability->addOption($inherit); 185 $availability->addOption($enabled); 186 $availability->addOption($disabled); 187 $a_form->addItem($availability); 188 break; 189 } 190 } 191 192 193 /** 194 * Set the values in a property form based on the configuration 195 * @param object property form 196 * @param string context of the form 197 */ 198 public function setFormValues(ilPropertyFormGUI $a_form) 199 { 200 $a_form->getItemByPostVar('char_selector_availability')->setValue($this->config->getAvailability()); 201 $a_form->getItemByPostVar('char_selector_blocks')->setValue($this->config->getAddedBlocks()); 202 $a_form->getItemByPostVar('char_selector_custom_items')->setValue($this->config->getCustomItems()); 203 } 204 205 206 /** 207 * Set the configuration based on the values of a property form 208 * @param object property form 209 * @param string context of the form 210 */ 211 public function getFormValues(ilPropertyFormGUI $a_form) 212 { 213 $this->config->setAvailability($a_form->getInput('char_selector_availability')); 214 $this->config->setAddedBlocks($a_form->getInput('char_selector_blocks')); 215 $this->config->setCustomItems($a_form->getInput('char_selector_custom_items')); 216 } 217 218 /** 219 * Adds the the character selector to the ilias page 220 * Initializes the selector according to the state saved in the user session 221 * @see self::saveState() 222 */ 223 public function addToPage() 224 { 225 $ilCtrl = $this->ctrl; 226 $tpl = $this->tpl; 227 $lng = $this->lng; 228 229 // don't add the panel twice 230 if ($this->added_to_page) { 231 return; 232 } 233 234 $lng->loadLanguageModule('adve'); 235 236 // prepare the configuration for the js script 237 $this->jsconfig = new stdClass(); 238 $this->jsconfig->pages = $this->config->getCharPages(); 239 $this->jsconfig->ajax_url = $ilCtrl->getLinkTargetByClass("ilcharselectorgui", "saveState", "", true); 240 $this->jsconfig->open = (int) $_SESSION['char_selector_open']; 241 $this->jsconfig->current_page = (int) $_SESSION['char_selector_current_page']; 242 $this->jsconfig->current_subpage = (int) $_SESSION['char_selector_current_subpage']; 243 244 // provide texts to be dynamically rendered in the js script 245 $this->jstexts = new stdClass(); 246 $this->jstexts->page = $lng->txt('page'); 247 // fau: testNav - add texts for open/close char selector actions in the question menu 248 $this->jstexts->open = $lng->txt('char_selector_menu_open'); 249 $this->jstexts->close = $lng->txt('char_selector_menu_close'); 250 // fau. 251 252 // add everything neded to the page 253 // addLightbox() is just used to add the panel template outside the body 254 // The panel template is added as <script> to be not included in the DOM by default 255 // It will be included by js below the main header when the selector is switched on 256 $tpl->addCss(ilUtil::getStyleSheetLocation('', 'char_selector_style.css', 'Services/UIComponent/CharSelector')); 257 $tpl->addJavascript('./Services/UIComponent/CharSelector/js/ilCharSelector.js'); 258 $tpl->addLightbox($this->getSelectorHTML(), 2); 259 $tpl->addOnLoadCode('il.CharSelector.init(' . json_encode($this->jsconfig) . ',' . json_encode($this->jstexts) . ')'); 260 $this->added_to_page = true; 261 } 262 263 /** 264 * Get the HTML code of the selector panel 265 * @return string panel html code 266 */ 267 public function getSelectorHTML() 268 { 269 $lng = $this->lng; 270 $tpl = new ilTemplate("tpl.char_selector_panel.html", true, true, "Services/UIComponent/CharSelector"); 271 272 if (count($this->jsconfig->pages) > 1) { 273 $index = 0; 274 foreach ($this->jsconfig->pages as $page) { 275 $tpl->setCurrentBlock('page_option'); 276 $tpl->setVariable("PAGE_INDEX", $index); 277 $tpl->setVariable("PAGE_NAME", $page[0]); 278 $tpl->parseCurrentBlock(); 279 $index++; 280 } 281 } 282 283 $tpl->setVariable('TXT_PREVIOUS_PAGE', $lng->txt('previous')); 284 $tpl->setVariable('TXT_NEXT_PAGE', $lng->txt('next')); 285 $tpl->setVariable('TXT_PAGE', $lng->txt('page')); 286 287 $tpl->touchBlock('chars'); 288 return '<script type="text/html" id="ilCharSelectorTemplate">' . $tpl->get() . '</script>'; 289 } 290 291 292 /** 293 * Save the selector panel state in the user session 294 * (This keeps the panel state between page moves) 295 * @see self::addToPage() 296 */ 297 public function saveState() 298 { 299 $_SESSION['char_selector_open'] = (int) $_GET['open']; 300 $_SESSION['char_selector_current_page'] = (int) $_GET['current_page']; 301 $_SESSION['char_selector_current_subpage'] = (int) $_GET['current_subpage']; 302 303 // debugging output (normally ignored by the js part) 304 echo json_encode(array( 305 'open' => $_SESSION['char_selector_open'], 306 'current_page' => $_SESSION['char_selector_current_page'], 307 'current_subpage' => $_SESSION['char_selector_current_subpage'], 308 )); 309 exit; 310 } 311 312 /** 313 * execute command 314 */ 315 public function executeCommand() 316 { 317 $ilCtrl = $this->ctrl; 318 $cmd = $ilCtrl->getCmd("saveState"); 319 switch ($cmd) { 320 case 'saveState': 321 $this->$cmd(); 322 break; 323 default: 324 return; 325 } 326 } 327} 328