ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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("create_date"), 'created', '');
129  $this->addColumn($this->lng->txt("last_update"), 'tstamp', ''); // name of col is proper "updated" but in data array the key is "tstamp"
130  $this->addColumn($this->getParentObjectLabel(), 'qpl', '');
131  $this->addColumn($this->lng->txt("working_time"), 'working_time', '');
132  $this->setSelectAllCheckbox('q_id');
133  $this->setRowTemplate("tpl.il_as_tst_question_browser_row.html", "Modules/Test");
134 
135  $this->setFormAction($this->ctrl->getFormAction($this->getParentObject(), $this->getParentCmd()));
136  $this->setDefaultOrderField("title");
137  $this->setDefaultOrderDirection("asc");
138 
139  $this->enable('sort');
140  //$this->enable('header');
141  $this->enable('select_all');
142  $this->initFilter();
143  $this->setDisableFilterHiding(true);
144  }
145 
146  public function setWriteAccess($value)
147  {
148  $this->writeAccess = $value;
149  }
150 
151  public function hasWriteAccess()
152  {
153  return $this->writeAccess;
154  }
155 
156  public function init()
157  {
158  if ($this->hasWriteAccess()) {
159  $this->addMultiCommand(self::CMD_INSERT_QUESTIONS, $this->lng->txt('insert'));
160  }
161  }
162 
163  public function executeCommand()
164  {
165  $this->handleParameters();
166  $this->handleTabs();
167 
168  switch ($this->ctrl->getNextClass($this)) {
169  case strtolower(__CLASS__):
170  case '':
171 
172  $cmd = $this->ctrl->getCmd() . 'Cmd';
173  return $this->$cmd();
174 
175  default:
176 
177  $this->ctrl->setReturn($this, self::CMD_BROWSE_QUESTIONS);
178  return parent::executeCommand();
179  }
180  }
181 
182  private function browseQuestionsCmd()
183  {
184  $this->setData($this->getQuestionsData());
185 
186  $this->mainTpl->setContent($this->ctrl->getHTML($this));
187  }
188 
189  private function applyFilterCmd()
190  {
191  $this->writeFilterToSession();
192  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
193  }
194 
195  private function resetFilterCmd()
196  {
197  $this->resetFilter();
198  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
199  }
200 
201  private function insertQuestionsCmd()
202  {
203  $selected_array = (is_array($_POST['q_id'])) ? $_POST['q_id'] : array();
204  if (!count($selected_array)) {
205  ilUtil::sendInfo($this->lng->txt("tst_insert_missing_question"), true);
206  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
207  }
208 
209  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
210 
211  $testQuestionSetConfig = $this->buildTestQuestionSetConfig();
212 
213  $manscoring = false;
214 
215  foreach ($selected_array as $key => $value) {
216  $last_question_id = $this->testOBJ->insertQuestion($testQuestionSetConfig, $value);
217 
218  if (!$manscoring) {
219  $manscoring = $manscoring | assQuestion::_needsManualScoring($value);
220  }
221  }
222 
223  $this->testOBJ->saveCompleteStatus($testQuestionSetConfig);
224 
225  if ($manscoring) {
226  ilUtil::sendInfo($this->lng->txt("manscoring_hint"), true);
227  } else {
228  ilUtil::sendSuccess($this->lng->txt("tst_questions_inserted"), true);
229  }
230 
231  //$this->ctrl->setParameter($this, 'q_id', $last_question_id); // for page view ?
232 
233  $this->ctrl->redirectByClass($this->getBackTargetCmdClass(), $this->getBackTargetCommand());
234  }
235 
236  private function handleParameters()
237  {
238  $this->ctrl->saveParameter($this, self::CONTEXT_PARAMETER);
239  if (isset($_GET[self::CONTEXT_PARAMETER])) {
240  $this->addHiddenInput(self::CONTEXT_PARAMETER, $_GET[self::CONTEXT_PARAMETER]);
241  } elseif (isset($_POST[self::CONTEXT_PARAMETER])) {
242  $this->addHiddenInput(self::CONTEXT_PARAMETER, $_POST[self::CONTEXT_PARAMETER]);
243  }
244 
245  $this->ctrl->saveParameter($this, self::MODE_PARAMETER);
246  if (isset($_GET[self::MODE_PARAMETER])) {
247  $this->addHiddenInput(self::MODE_PARAMETER, $_GET[self::MODE_PARAMETER]);
248  } elseif (isset($_POST[self::MODE_PARAMETER])) {
249  $this->addHiddenInput(self::MODE_PARAMETER, $_POST[self::MODE_PARAMETER]);
250  }
251  }
252 
253  private function fetchContextParameter()
254  {
255  if (isset($_POST[self::CONTEXT_PARAMETER])) {
256  return $_POST[self::CONTEXT_PARAMETER];
257  }
258 
259  if (isset($_GET[self::CONTEXT_PARAMETER])) {
260  return $_GET[self::CONTEXT_PARAMETER];
261  }
262 
263  return null;
264  }
265 
266  private function fetchModeParameter()
267  {
268  if (isset($_POST[self::MODE_PARAMETER])) {
269  return $_POST[self::MODE_PARAMETER];
270  }
271 
272  if (isset($_GET[self::MODE_PARAMETER])) {
273  return $_GET[self::MODE_PARAMETER];
274  }
275 
276  return null;
277  }
278 
279  private function handleTabs()
280  {
281  $this->tabs->clearTargets();
282  $this->tabs->clearSubTabs();
283 
284  $this->tabs->setBackTarget(
285  $this->getBackTargetLabel(),
286  $this->getBackTargetUrl()
287  );
288 
289  $this->tabs->addTab(
290  'browseQuestions',
292  $this->getBrowseQuestionsTabUrl()
293  );
294  }
295 
296  private function getBackTargetLabel()
297  {
298  return $this->lng->txt('backtocallingtest');
299  }
300 
301  private function getBackTargetUrl()
302  {
303  return $this->ctrl->getLinkTargetByClass(
304  $this->getBackTargetCmdClass(),
305  $this->getBackTargetCommand()
306  );
307  }
308 
309  private function getBackTargetCmdClass()
310  {
311  switch ($this->fetchContextParameter()) {
312  case self::CONTEXT_LIST_VIEW:
313 
314  return 'ilObjTestGUI';
315 
316  case self::CONTEXT_PAGE_VIEW:
317 
318  return 'ilTestExpressPageObjectGUI';
319  }
320 
321  return '';
322  }
323 
324  private function getBackTargetCommand()
325  {
326  switch ($this->fetchContextParameter()) {
327  case self::CONTEXT_LIST_VIEW:
328 
329  return 'questions';
330 
331  case self::CONTEXT_PAGE_VIEW:
332 
333  return 'showPage';
334  }
335 
336  return '';
337  }
338 
339  private function getBrowseQuestionsTabLabel()
340  {
341  switch ($this->fetchModeParameter()) {
342  case self::MODE_BROWSE_POOLS:
343 
344  return $this->lng->txt('tst_browse_for_qpl_questions');
345 
346  case self::MODE_BROWSE_TESTS:
347 
348  return $this->lng->txt('tst_browse_for_tst_questions');
349  }
350 
351  return '';
352  }
353 
354  private function getBrowseQuestionsTabUrl()
355  {
356  return $this->ctrl->getLinkTarget($this, self::CMD_BROWSE_QUESTIONS);
357  }
358 
359  public function initFilter()
360  {
361  // title
362  include_once("./Services/Form/classes/class.ilTextInputGUI.php");
363  $ti = new ilTextInputGUI($this->lng->txt("tst_qbt_filter_question_title"), "title");
364  $ti->setMaxLength(64);
365  $ti->setSize(20);
366  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
367  $this->addFilterItem($ti);
368  $ti->readFromSession();
369  $this->filter["title"] = $ti->getValue();
370 
371  // description
372  $ti = new ilTextInputGUI($this->lng->txt("description"), "description");
373  $ti->setMaxLength(64);
374  $ti->setSize(20);
375  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
376  $this->addFilterItem($ti);
377  $ti->readFromSession();
378  $this->filter["description"] = $ti->getValue();
379 
380  // questiontype
381  include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
382  include_once("./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php");
384  $options = array();
385  $options[""] = $this->lng->txt('filter_all_question_types');
386  foreach ($types as $translation => $row) {
387  $options[$row['type_tag']] = $translation;
388  }
389 
390  $si = new ilSelectInputGUI($this->lng->txt("question_type"), "type");
391  $si->setOptions($options);
392  $this->addFilterItem($si);
393  $si->readFromSession();
394  $this->filter["type"] = $si->getValue();
395 
396  // author
397  $ti = new ilTextInputGUI($this->lng->txt("author"), "author");
398  $ti->setMaxLength(64);
399  $ti->setSize(20);
400  $this->addFilterItem($ti);
401  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
402  $ti->readFromSession();
403  $this->filter["author"] = $ti->getValue();
404 
405  // question pool
406  $ti = new ilTextInputGUI($this->getParentObjectLabel(), 'parent_title');
407  $ti->setMaxLength(64);
408  $ti->setSize(20);
409  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
410  $this->addFilterItem($ti);
411  $ti->readFromSession();
412  $this->filter['parent_title'] = $ti->getValue();
413 
414  // repo root node
415  require_once 'Services/Form/classes/class.ilRepositorySelectorInputGUI.php';
416  $ri = new ilRepositorySelectorInputGUI($this->lng->txt('repository'), 'repository_root_node');
417  $ri->setHeaderMessage($this->lng->txt('question_browse_area_info'));
418  $ri->setClickableTypes(array('qpl'));
419  $this->addFilterItem($ri);
420  $ri->readFromSession();
421  $this->filter['repository_root_node'] = $ri->getValue();
422  }
423 
424  private function getParentObjectLabel()
425  {
426  switch ($this->fetchModeParameter()) {
427  case self::MODE_BROWSE_POOLS:
428 
429  return $this->lng->txt('qpl');
430 
431  case self::MODE_BROWSE_TESTS:
432 
433  return $this->lng->txt('tst');
434  }
435 
436  return '';
437  }
438 
439  public function fillRow($data)
440  {
441  $this->tpl->setVariable("QUESTION_ID", $data["question_id"]);
442  $this->tpl->setVariable("QUESTION_TITLE", $data["title"]);
443  $this->tpl->setVariable("QUESTION_COMMENT", $data["description"]);
444  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
445  $this->tpl->setVariable("QUESTION_TYPE", assQuestion::_getQuestionTypeName($data["type_tag"]));
446  $this->tpl->setVariable("QUESTION_AUTHOR", $data["author"]);
447  $this->tpl->setVariable("QUESTION_CREATED", ilDatePresentation::formatDate(new ilDate($data['created'], IL_CAL_UNIX)));
448  $this->tpl->setVariable("QUESTION_UPDATED", ilDatePresentation::formatDate(new ilDate($data["tstamp"], IL_CAL_UNIX)));
449  $this->tpl->setVariable("QUESTION_POOL", $data['parent_title']);
450  $this->tpl->setVariable("WORKING_TIME", $data['working_time']);
451  }
452 
456  private function buildTestQuestionSetConfig()
457  {
458  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
459 
460  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory(
461  $this->tree,
462  $this->db,
463  $this->pluginAdmin,
464  $this->testOBJ
465  );
466 
467  return $testQuestionSetConfigFactory->getQuestionSetConfig();
468  }
469 
473  private function getQuestionsData()
474  {
475  $questionList = new ilAssQuestionList($this->db, $this->lng, $this->pluginAdmin);
476 
477  $questionList->setQuestionInstanceTypeFilter($this->getQuestionInstanceTypeFilter());
478  $questionList->setExcludeQuestionIdsFilter($this->testOBJ->getExistingQuestions());
479 
480  $repositoryRootNode = self::REPOSITORY_ROOT_NODE_ID;
481 
482  foreach ($this->getFilterItems() as $item) {
483  if ($item->getValue() !== false) {
484  switch ($item->getPostVar()) {
485  case 'title':
486  case 'description':
487  case 'author':
488  case 'type':
489  case 'parent_title':
490 
491  $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
492  break;
493 
494  case 'repository_root_node':
495 
496  $repositoryRootNode = $item->getValue();
497  }
498  }
499  }
500 
501  $parentObjectIds = $this->getQuestionParentObjIds($repositoryRootNode);
502 
503  if (!count($parentObjectIds)) {
504  return array();
505  }
506 
507  $questionList->setParentObjIdsFilter($parentObjectIds);
508 
509  $questionList->load();
510 
511  return $questionList->getQuestionDataArray();
512  }
513 
514  private function getQuestionInstanceTypeFilter()
515  {
516  if ($this->fetchModeParameter() == self::MODE_BROWSE_TESTS) {
518  }
519 
521  }
522 
523  private function getQuestionParentObjIds($repositoryRootNode)
524  {
525  $parents = $this->tree->getSubTree(
526  $this->tree->getNodeData($repositoryRootNode),
527  true,
529  );
530 
531  $parentIds = array();
532 
533  foreach ($parents as $nodeData) {
534  if ($nodeData['obj_id'] == $this->testOBJ->getId()) {
535  continue;
536  }
537 
538  $parentIds[ $nodeData['obj_id'] ] = $nodeData['obj_id'];
539  }
540 
541  $parentIds = array_map('intval', array_values($parentIds));
542 
543  if ($this->fetchModeParameter() == self::MODE_BROWSE_POOLS) {
544  $available_pools = array_map('intval', array_keys(ilObjQuestionPool::_getAvailableQuestionpools(true)));
545  return array_intersect($parentIds, $available_pools);
546  } elseif ($this->fetchModeParameter() == self::MODE_BROWSE_TESTS) {
547  // TODO bheyser: Move this to another place ...
548  return array_filter($parentIds, function ($obj_id) {
549  $refIds = ilObject::_getAllReferences($obj_id);
550  $refId = current($refIds);
551  return $this->access->checkAccess('write', '', $refId);
552  });
553  }
554 
555  // Return no parent ids if the user wants to hack...
556  return array();
557  }
558 
559  private function getQuestionParentObjectType()
560  {
561  if ($this->fetchModeParameter() == self::MODE_BROWSE_TESTS) {
562  return 'tst';
563  }
564 
565  return 'qpl';
566  }
567 }
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.
This class provides processing control methods.
setDefaultOrderField($a_defaultorderfield)
Set Default order field.
addHiddenInput($a_name, $a_value)
Add Hidden Input field.
This class represents a selection list property in a property form.
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.
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.
Class ilTable2GUI.
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.
This class represents a repository selector in a property form.
setDisableFilterHiding($a_val=true)
Set disable filter hiding.
special template class to simplify handling of ITX/PEAR
addMultiCommand($a_cmd, $a_text)
Add Command button.
enable($a_module_name)
enables particular modules of table
This class represents a text property in a property form.
setMaxLength($a_maxlength)
Set Max Length.
__construct(ilCtrl $ctrl, ilTemplate $mainTpl, ilTabsGUI $tabs, ilLanguage $lng, ilTree $tree, ilDBInterface $db, ilPluginAdmin $pluginAdmin, ilObjTest $testOBJ, ilAccessHandler $access)
ilTestQuestionBrowserTableGUI constructor.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
setRowTemplate($a_template, $a_template_dir="")
Set row template.
$row
writeFilterToSession()
Write filter values to session.
setFormAction($a_form_action, $a_multipart=false)
Set Form action parameter.
setFormName($a_formname="")
Set Form name.
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.
$key
Definition: croninfo.php:18
$_POST["username"]
resetFilter()
Reset filter.
static _getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)
setFilterCommand($a_val, $a_caption=null)
Set filter command.