ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilTestQuestionBrowserTableGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once './Services/Table/classes/class.ilTable2GUI.php';
5 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
6 
19 {
21 
22  const CONTEXT_PARAMETER = 'question_browse_context';
23  const CONTEXT_PAGE_VIEW = 'contextPageView';
24  const CONTEXT_LIST_VIEW = 'contextListView';
25 
26  const MODE_PARAMETER = 'question_browse_mode';
27  const MODE_BROWSE_POOLS = 'modeBrowsePools';
28  const MODE_BROWSE_TESTS = 'modeBrowseTests';
29 
30  const CMD_BROWSE_QUESTIONS = 'browseQuestions';
31  const CMD_APPLY_FILTER = 'applyFilter';
32  const CMD_RESET_FILTER = 'resetFilter';
33  const CMD_INSERT_QUESTIONS = 'insertQuestions';
34 
35  protected $writeAccess = false;
36 
40  protected $ctrl;
41 
45  protected $mainTpl;
46 
50  protected $tabs;
51 
55  protected $lng;
56 
60  protected $tree;
61 
65  protected $db;
66 
70  protected $pluginAdmin;
71 
75  protected $testOBJ;
76 
80  protected $access;
81 
94  public function __construct(
95  ilCtrl $ctrl,
99  ilTree $tree,
104  ) {
105  $this->ctrl = $ctrl;
106  $this->mainTpl = $mainTpl;
107  $this->tabs = $tabs;
108  $this->lng = $lng;
109  $this->tree = $tree;
110  $this->db = $db;
111  $this->pluginAdmin = $pluginAdmin;
112  $this->testOBJ = $testOBJ;
113  $this->access = $access;
114 
115  $this->setId('qpl_brows_tabl_' . $this->testOBJ->getId());
116 
117  parent::__construct($this, self::CMD_BROWSE_QUESTIONS);
118  $this->setFilterCommand(self::CMD_APPLY_FILTER);
119  $this->setResetCommand(self::CMD_RESET_FILTER);
120 
121  $this->setFormName('questionbrowser');
122  $this->setStyle('table', 'fullwidth');
123  $this->addColumn('', '', '1%', true);
124  $this->addColumn($this->lng->txt("tst_question_title"), 'title', '');
125  $this->addColumn($this->lng->txt("description"), 'description', '');
126  $this->addColumn($this->lng->txt("tst_question_type"), 'ttype', '');
127  $this->addColumn($this->lng->txt("author"), 'author', '');
128  $this->addColumn($this->lng->txt('qst_lifecycle'), 'lifecycle', '');
129  $this->addColumn($this->lng->txt("create_date"), 'created', '');
130  $this->addColumn($this->lng->txt("last_update"), 'tstamp', ''); // name of col is proper "updated" but in data array the key is "tstamp"
131  $this->addColumn($this->getParentObjectLabel(), 'qpl', '');
132  $this->addColumn($this->lng->txt("working_time"), 'working_time', '');
133  $this->setSelectAllCheckbox('q_id');
134  $this->setRowTemplate("tpl.il_as_tst_question_browser_row.html", "Modules/Test");
135 
136  $this->setFormAction($this->ctrl->getFormAction($this->getParentObject(), $this->getParentCmd()));
137  $this->setDefaultOrderField("title");
138  $this->setDefaultOrderDirection("asc");
139 
140  $this->enable('sort');
141  //$this->enable('header');
142  $this->enable('select_all');
143  $this->initFilter();
144  $this->setDisableFilterHiding(true);
145  }
146 
147  public function setWriteAccess($value)
148  {
149  $this->writeAccess = $value;
150  }
151 
152  public function hasWriteAccess()
153  {
154  return $this->writeAccess;
155  }
156 
157  public function init()
158  {
159  if ($this->hasWriteAccess()) {
160  $this->addMultiCommand(self::CMD_INSERT_QUESTIONS, $this->lng->txt('insert'));
161  }
162  }
163 
164  public function executeCommand()
165  {
166  $this->handleParameters();
167  $this->handleTabs();
168 
169  switch ($this->ctrl->getNextClass($this)) {
170  case strtolower(__CLASS__):
171  case '':
172 
173  $cmd = $this->ctrl->getCmd() . 'Cmd';
174  return $this->$cmd();
175 
176  default:
177 
178  $this->ctrl->setReturn($this, self::CMD_BROWSE_QUESTIONS);
179  return parent::executeCommand();
180  }
181  }
182 
183  private function browseQuestionsCmd()
184  {
185  $this->setData($this->getQuestionsData());
186 
187  $this->mainTpl->setContent($this->ctrl->getHTML($this));
188  }
189 
190  private function applyFilterCmd()
191  {
192  $this->writeFilterToSession();
193  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
194  }
195 
196  private function resetFilterCmd()
197  {
198  $this->resetFilter();
199  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
200  }
201 
202  private function insertQuestionsCmd()
203  {
204  $selected_array = (is_array($_POST['q_id'])) ? $_POST['q_id'] : array();
205  if (!count($selected_array)) {
206  ilUtil::sendInfo($this->lng->txt("tst_insert_missing_question"), true);
207  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
208  }
209 
210  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
211 
212  $testQuestionSetConfig = $this->buildTestQuestionSetConfig();
213 
214  $manscoring = false;
215 
216  foreach ($selected_array as $key => $value) {
217  $last_question_id = $this->testOBJ->insertQuestion($testQuestionSetConfig, $value);
218 
219  if (!$manscoring) {
220  $manscoring = $manscoring | assQuestion::_needsManualScoring($value);
221  }
222  }
223 
224  $this->testOBJ->saveCompleteStatus($testQuestionSetConfig);
225 
226  if ($manscoring) {
227  ilUtil::sendInfo($this->lng->txt("manscoring_hint"), true);
228  } else {
229  ilUtil::sendSuccess($this->lng->txt("tst_questions_inserted"), true);
230  }
231 
232  //$this->ctrl->setParameter($this, 'q_id', $last_question_id); // for page view ?
233 
234  $this->ctrl->redirectByClass($this->getBackTargetCmdClass(), $this->getBackTargetCommand());
235  }
236 
237  private function handleParameters()
238  {
239  $this->ctrl->saveParameter($this, self::CONTEXT_PARAMETER);
240  if (isset($_GET[self::CONTEXT_PARAMETER])) {
241  $this->addHiddenInput(self::CONTEXT_PARAMETER, $_GET[self::CONTEXT_PARAMETER]);
242  } elseif (isset($_POST[self::CONTEXT_PARAMETER])) {
243  $this->addHiddenInput(self::CONTEXT_PARAMETER, $_POST[self::CONTEXT_PARAMETER]);
244  }
245 
246  $this->ctrl->saveParameter($this, self::MODE_PARAMETER);
247  if (isset($_GET[self::MODE_PARAMETER])) {
248  $this->addHiddenInput(self::MODE_PARAMETER, $_GET[self::MODE_PARAMETER]);
249  } elseif (isset($_POST[self::MODE_PARAMETER])) {
250  $this->addHiddenInput(self::MODE_PARAMETER, $_POST[self::MODE_PARAMETER]);
251  }
252  }
253 
254  private function fetchContextParameter()
255  {
256  if (isset($_POST[self::CONTEXT_PARAMETER])) {
257  return $_POST[self::CONTEXT_PARAMETER];
258  }
259 
260  if (isset($_GET[self::CONTEXT_PARAMETER])) {
261  return $_GET[self::CONTEXT_PARAMETER];
262  }
263 
264  return null;
265  }
266 
267  private function fetchModeParameter()
268  {
269  if (isset($_POST[self::MODE_PARAMETER])) {
270  return $_POST[self::MODE_PARAMETER];
271  }
272 
273  if (isset($_GET[self::MODE_PARAMETER])) {
274  return $_GET[self::MODE_PARAMETER];
275  }
276 
277  return null;
278  }
279 
280  private function handleTabs()
281  {
282  $this->tabs->clearTargets();
283  $this->tabs->clearSubTabs();
284 
285  $this->tabs->setBackTarget(
286  $this->getBackTargetLabel(),
287  $this->getBackTargetUrl()
288  );
289 
290  $this->tabs->addTab(
291  'browseQuestions',
293  $this->getBrowseQuestionsTabUrl()
294  );
295  }
296 
297  private function getBackTargetLabel()
298  {
299  return $this->lng->txt('backtocallingtest');
300  }
301 
302  private function getBackTargetUrl()
303  {
304  return $this->ctrl->getLinkTargetByClass(
305  $this->getBackTargetCmdClass(),
306  $this->getBackTargetCommand()
307  );
308  }
309 
310  private function getBackTargetCmdClass()
311  {
312  switch ($this->fetchContextParameter()) {
313  case self::CONTEXT_LIST_VIEW:
314 
315  return 'ilObjTestGUI';
316 
317  case self::CONTEXT_PAGE_VIEW:
318 
319  return 'ilTestExpressPageObjectGUI';
320  }
321 
322  return '';
323  }
324 
325  private function getBackTargetCommand()
326  {
327  switch ($this->fetchContextParameter()) {
328  case self::CONTEXT_LIST_VIEW:
329 
330  return 'questions';
331 
332  case self::CONTEXT_PAGE_VIEW:
333 
334  return 'showPage';
335  }
336 
337  return '';
338  }
339 
340  private function getBrowseQuestionsTabLabel()
341  {
342  switch ($this->fetchModeParameter()) {
343  case self::MODE_BROWSE_POOLS:
344 
345  return $this->lng->txt('tst_browse_for_qpl_questions');
346 
347  case self::MODE_BROWSE_TESTS:
348 
349  return $this->lng->txt('tst_browse_for_tst_questions');
350  }
351 
352  return '';
353  }
354 
355  private function getBrowseQuestionsTabUrl()
356  {
357  return $this->ctrl->getLinkTarget($this, self::CMD_BROWSE_QUESTIONS);
358  }
359 
360  public function initFilter()
361  {
362  // title
363  include_once("./Services/Form/classes/class.ilTextInputGUI.php");
364  $ti = new ilTextInputGUI($this->lng->txt("tst_qbt_filter_question_title"), "title");
365  $ti->setMaxLength(64);
366  $ti->setSize(20);
367  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
368  $this->addFilterItem($ti);
369  $ti->readFromSession();
370  $this->filter["title"] = $ti->getValue();
371 
372  // description
373  $ti = new ilTextInputGUI($this->lng->txt("description"), "description");
374  $ti->setMaxLength(64);
375  $ti->setSize(20);
376  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
377  $this->addFilterItem($ti);
378  $ti->readFromSession();
379  $this->filter["description"] = $ti->getValue();
380 
381  // author
382  $ti = new ilTextInputGUI($this->lng->txt("author"), "author");
383  $ti->setMaxLength(64);
384  $ti->setSize(20);
385  $this->addFilterItem($ti);
386  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
387  $ti->readFromSession();
388  $this->filter["author"] = $ti->getValue();
389 
390  // lifecycle
391  $lifecycleOptions = array_merge(
392  array('' => $this->lng->txt('qst_lifecycle_filter_all')),
393  ilAssQuestionLifecycle::getDraftInstance()->getSelectOptions($this->lng)
394  );
395  $lifecycleInp = new ilSelectInputGUI($this->lng->txt('qst_lifecycle'), 'lifecycle');
396  $lifecycleInp->setOptions($lifecycleOptions);
397  $this->addFilterItem($lifecycleInp);
398  $lifecycleInp->readFromSession();
399  $this->filter['lifecycle'] = $lifecycleInp->getValue();
400 
401  // questiontype
402  include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
403  include_once("./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php");
405  $options = array();
406  $options[""] = $this->lng->txt('filter_all_question_types');
407  foreach ($types as $translation => $row) {
408  $options[$row['type_tag']] = $translation;
409  }
410 
411  $si = new ilSelectInputGUI($this->lng->txt("question_type"), "type");
412  $si->setOptions($options);
413  $this->addFilterItem($si);
414  $si->readFromSession();
415  $this->filter["type"] = $si->getValue();
416 
417  // question pool
418  $ti = new ilTextInputGUI($this->getParentObjectLabel(), 'parent_title');
419  $ti->setMaxLength(64);
420  $ti->setSize(20);
421  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
422  $this->addFilterItem($ti);
423  $ti->readFromSession();
424  $this->filter['parent_title'] = $ti->getValue();
425 
426  // repo root node
427  require_once 'Services/Form/classes/class.ilRepositorySelectorInputGUI.php';
428  $ri = new ilRepositorySelectorInputGUI($this->lng->txt('repository'), 'repository_root_node');
429  $ri->setHeaderMessage($this->lng->txt('question_browse_area_info'));
430  $ri->setClickableTypes(array('qpl'));
431  $this->addFilterItem($ri);
432  $ri->readFromSession();
433  $this->filter['repository_root_node'] = $ri->getValue();
434  }
435 
436  private function getParentObjectLabel()
437  {
438  switch ($this->fetchModeParameter()) {
439  case self::MODE_BROWSE_POOLS:
440 
441  return $this->lng->txt('qpl');
442 
443  case self::MODE_BROWSE_TESTS:
444 
445  return $this->lng->txt('tst');
446  }
447 
448  return '';
449  }
450 
451  protected function getTranslatedLifecycle($lifecycle)
452  {
453  try {
454  return ilAssQuestionLifecycle::getInstance($lifecycle)->getTranslation($this->lng);
456  return '';
457  }
458  }
459 
460  public function fillRow($data)
461  {
462  $this->tpl->setVariable("QUESTION_ID", $data["question_id"]);
463  $this->tpl->setVariable("QUESTION_TITLE", $data["title"]);
464  $this->tpl->setVariable("QUESTION_COMMENT", $data["description"]);
465  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
466  $this->tpl->setVariable("QUESTION_TYPE", assQuestion::_getQuestionTypeName($data["type_tag"]));
467  $this->tpl->setVariable("QUESTION_AUTHOR", $data["author"]);
468  $this->tpl->setVariable("QUESTION_LIFECYCLE", $this->getTranslatedLifecycle($data['lifecycle']));
469  $this->tpl->setVariable("QUESTION_CREATED", ilDatePresentation::formatDate(new ilDate($data['created'], IL_CAL_UNIX)));
470  $this->tpl->setVariable("QUESTION_UPDATED", ilDatePresentation::formatDate(new ilDate($data["tstamp"], IL_CAL_UNIX)));
471  $this->tpl->setVariable("QUESTION_POOL", $data['parent_title']);
472  $this->tpl->setVariable("WORKING_TIME", $data['working_time']);
473  }
474 
478  private function buildTestQuestionSetConfig()
479  {
480  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
481 
482  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory(
483  $this->tree,
484  $this->db,
485  $this->pluginAdmin,
486  $this->testOBJ
487  );
488 
489  return $testQuestionSetConfigFactory->getQuestionSetConfig();
490  }
491 
495  private function getQuestionsData()
496  {
497  $questionList = new ilAssQuestionList($this->db, $this->lng, $this->pluginAdmin);
498 
499  $questionList->setQuestionInstanceTypeFilter($this->getQuestionInstanceTypeFilter());
500  $questionList->setExcludeQuestionIdsFilter($this->testOBJ->getExistingQuestions());
501 
502  $repositoryRootNode = self::REPOSITORY_ROOT_NODE_ID;
503 
504  foreach ($this->getFilterItems() as $item) {
505  if ($item->getValue() !== false) {
506  switch ($item->getPostVar()) {
507  case 'title':
508  case 'description':
509  case 'author':
510  case 'lifecycle':
511  case 'type':
512  case 'parent_title':
513 
514  $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
515  break;
516 
517  case 'repository_root_node':
518 
519  $repositoryRootNode = $item->getValue();
520  }
521  }
522  }
523 
524  $parentObjectIds = $this->getQuestionParentObjIds($repositoryRootNode);
525 
526  if (!count($parentObjectIds)) {
527  return array();
528  }
529 
530  $questionList->setParentObjIdsFilter($parentObjectIds);
531 
532  $questionList->load();
533 
534  return $questionList->getQuestionDataArray();
535  }
536 
537  private function getQuestionInstanceTypeFilter()
538  {
539  if ($this->fetchModeParameter() == self::MODE_BROWSE_TESTS) {
541  }
542 
544  }
545 
546  private function getQuestionParentObjIds($repositoryRootNode)
547  {
548  $parents = $this->tree->getSubTree(
549  $this->tree->getNodeData($repositoryRootNode),
550  true,
552  );
553 
554  $parentIds = array();
555 
556  foreach ($parents as $nodeData) {
557  if ($nodeData['obj_id'] == $this->testOBJ->getId()) {
558  continue;
559  }
560 
561  $parentIds[ $nodeData['obj_id'] ] = $nodeData['obj_id'];
562  }
563 
564  $parentIds = array_map('intval', array_values($parentIds));
565 
566  if ($this->fetchModeParameter() == self::MODE_BROWSE_POOLS) {
567  $available_pools = array_map('intval', array_keys(ilObjQuestionPool::_getAvailableQuestionpools(true)));
568  return array_intersect($parentIds, $available_pools);
569  } elseif ($this->fetchModeParameter() == self::MODE_BROWSE_TESTS) {
570  // TODO bheyser: Move this to another place ...
571  return array_filter($parentIds, function ($obj_id) {
572  $refIds = ilObject::_getAllReferences($obj_id);
573  $refId = current($refIds);
574  return $this->access->checkAccess('write', '', $refId);
575  });
576  }
577 
578  // Return no parent ids if the user wants to hack...
579  return array();
580  }
581 
582  private function getQuestionParentObjectType()
583  {
584  if ($this->fetchModeParameter() == self::MODE_BROWSE_TESTS) {
585  return 'tst';
586  }
587 
588  return 'qpl';
589  }
590 }
static _getAvailableQuestionpools($use_object_id=false, $equal_points=false, $could_be_offline=false, $showPath=false, $with_questioncount=false, $permission="read", $usr_id="")
Returns the available question pools for the active user.
__construct(ilCtrl $ctrl, ilGlobalTemplateInterface $mainTpl, ilTabsGUI $tabs, ilLanguage $lng, ilTree $tree, ilDBInterface $db, ilPluginAdmin $pluginAdmin, ilObjTest $testOBJ, ilAccessHandler $access)
ilTestQuestionBrowserTableGUI constructor.
This class provides processing control methods.
setDefaultOrderField($a_defaultorderfield)
Set Default order field.
addHiddenInput($a_name, $a_value)
Add Hidden Input field.
setStyle($a_element, $a_style)
Tabs GUI.
$_GET["client_id"]
static _needsManualScoring($question_id)
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
addFilterItem($a_input_item, $a_optional=false)
Add filter item.
$refId
Definition: xapitoken.php:42
const IL_CAL_UNIX
getParentCmd()
Get parent command.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
setId($a_val)
Set id.
static _getAllReferences($a_id)
get all reference ids of object
setDefaultOrderDirection($a_defaultorderdirection)
Set Default order direction.
Interface ilAccessHandler.
Administration class for plugins.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
Interface ilDBInterface.
Class for single dates.
setResetCommand($a_val, $a_caption=null)
Set reset filter command.
setSelectAllCheckbox($a_select_all_checkbox, $a_select_all_on_top=false)
Set the name of the checkbox that should be toggled with a select all button.
setDisableFilterHiding($a_val=true)
Set disable filter hiding.
addMultiCommand($a_cmd, $a_text)
Add Command button.
enable($a_module_name)
enables particular modules of table
setRowTemplate($a_template, $a_template_dir="")
Set row template.
writeFilterToSession()
Write filter values to session.
setFormAction($a_form_action, $a_multipart=false)
Set Form action parameter.
setFormName($a_formname="")
Set Form name.
__construct(Container $dic, ilPlugin $plugin)
addColumn( $a_text, $a_sort_field="", $a_width="", $a_is_checkbox_action_column=false, $a_class="", $a_tooltip="", $a_tooltip_with_html=false)
Add a column to the header.
language handling
getFilterItems($a_optionals=false)
Get filter items.
$_POST["username"]
resetFilter()
Reset filter.
static _getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)
setFilterCommand($a_val, $a_caption=null)
Set filter command.