ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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(
98  )
99  {
100  $this->ctrl = $ctrl;
101  $this->mainTpl = $mainTpl;
102  $this->tabs = $tabs;
103  $this->lng = $lng;
104  $this->tree = $tree;
105  $this->db = $db;
106  $this->pluginAdmin = $pluginAdmin;
107  $this->testOBJ = $testOBJ;
108  $this->access = $access;
109 
110  $this->setId('qpl_brows_tabl_' . $this->testOBJ->getId());
111 
112  parent::__construct($this, self::CMD_BROWSE_QUESTIONS);
113  $this->setFilterCommand(self::CMD_APPLY_FILTER);
114  $this->setResetCommand(self::CMD_RESET_FILTER);
115 
116  $this->setFormName('questionbrowser');
117  $this->setStyle('table', 'fullwidth');
118  $this->addColumn('','','1%', true);
119  $this->addColumn($this->lng->txt("tst_question_title"),'title', '');
120  $this->addColumn($this->lng->txt("description"),'description', '');
121  $this->addColumn($this->lng->txt("tst_question_type"),'ttype', '');
122  $this->addColumn($this->lng->txt("author"),'author', '');
123  $this->addColumn($this->lng->txt("create_date"),'created', '');
124  $this->addColumn($this->lng->txt("last_update"),'tstamp', ''); // name of col is proper "updated" but in data array the key is "tstamp"
125  $this->addColumn($this->getParentObjectLabel(),'qpl', '');
126  $this->addColumn($this->lng->txt("working_time"),'working_time', '');
127  $this->setSelectAllCheckbox('q_id');
128  $this->setRowTemplate("tpl.il_as_tst_question_browser_row.html", "Modules/Test");
129 
130  $this->setFormAction($this->ctrl->getFormAction($this->getParentObject(), $this->getParentCmd()));
131  $this->setDefaultOrderField("title");
132  $this->setDefaultOrderDirection("asc");
133 
134  $this->enable('sort');
135  //$this->enable('header');
136  $this->enable('select_all');
137  $this->initFilter();
138  $this->setDisableFilterHiding(true);
139  }
140 
141  public function setWriteAccess($value)
142  {
143  $this->writeAccess = $value;
144  }
145 
146  public function hasWriteAccess()
147  {
148  return $this->writeAccess;
149  }
150 
151  public function init()
152  {
153  if( $this->hasWriteAccess() )
154  {
155  $this->addMultiCommand(self::CMD_INSERT_QUESTIONS, $this->lng->txt('insert'));
156  }
157  }
158 
159  public function executeCommand()
160  {
161  $this->handleParameters();
162  $this->handleTabs();
163 
164  switch( $this->ctrl->getNextClass($this) )
165  {
166  case strtolower(__CLASS__):
167  case '':
168 
169  $cmd = $this->ctrl->getCmd().'Cmd';
170  return $this->$cmd();
171 
172  default:
173 
174  $this->ctrl->setReturn($this, self::CMD_BROWSE_QUESTIONS);
175  return parent::executeCommand();
176  }
177  }
178 
179  private function browseQuestionsCmd()
180  {
181  $this->setData($this->getQuestionsData());
182 
183  $this->mainTpl->setContent($this->ctrl->getHTML($this));
184  }
185 
186  private function applyFilterCmd()
187  {
188  $this->writeFilterToSession();
189  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
190  }
191 
192  private function resetFilterCmd()
193  {
194  $this->resetFilter();
195  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
196  }
197 
198  private function insertQuestionsCmd()
199  {
200  $selected_array = (is_array($_POST['q_id'])) ? $_POST['q_id'] : array();
201  if (!count($selected_array))
202  {
203  ilUtil::sendInfo($this->lng->txt("tst_insert_missing_question"), true);
204  $this->ctrl->redirect($this, self::CMD_BROWSE_QUESTIONS);
205  }
206 
207  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
208 
209  $testQuestionSetConfig = $this->buildTestQuestionSetConfig();
210 
211  $manscoring = FALSE;
212 
213  foreach ($selected_array as $key => $value)
214  {
215  $last_question_id = $this->testOBJ->insertQuestion($testQuestionSetConfig, $value);
216 
217  if (!$manscoring)
218  {
219  $manscoring = $manscoring | assQuestion::_needsManualScoring($value);
220  }
221  }
222 
223  $this->testOBJ->saveCompleteStatus($testQuestionSetConfig);
224 
225  if ($manscoring)
226  {
227  ilUtil::sendInfo($this->lng->txt("manscoring_hint"), TRUE);
228  }
229  else
230  {
231  ilUtil::sendSuccess($this->lng->txt("tst_questions_inserted"), TRUE);
232  }
233 
234  //$this->ctrl->setParameter($this, 'q_id', $last_question_id); // for page view ?
235 
236  $this->ctrl->redirectByClass($this->getBackTargetCmdClass(), $this->getBackTargetCommand());
237  }
238 
239  private function handleParameters()
240  {
241  $this->ctrl->saveParameter($this, self::CONTEXT_PARAMETER);
242  if(isset($_GET[self::CONTEXT_PARAMETER]))
243  {
244  $this->addHiddenInput(self::CONTEXT_PARAMETER, $_GET[self::CONTEXT_PARAMETER]);
245  }
246  else if(isset($_POST[self::CONTEXT_PARAMETER]))
247  {
248  $this->addHiddenInput(self::CONTEXT_PARAMETER, $_POST[self::CONTEXT_PARAMETER]);
249  }
250 
251  $this->ctrl->saveParameter($this, self::MODE_PARAMETER);
252  if(isset($_GET[self::MODE_PARAMETER]))
253  {
254  $this->addHiddenInput(self::MODE_PARAMETER, $_GET[self::MODE_PARAMETER]);
255  }
256  else if(isset($_POST[self::MODE_PARAMETER]))
257  {
258  $this->addHiddenInput(self::MODE_PARAMETER, $_POST[self::MODE_PARAMETER]);
259  }
260  }
261 
262  private function fetchContextParameter()
263  {
264  if( isset($_POST[self::CONTEXT_PARAMETER]) )
265  {
266  return $_POST[self::CONTEXT_PARAMETER];
267  }
268 
269  if( isset($_GET[self::CONTEXT_PARAMETER]) )
270  {
271  return $_GET[self::CONTEXT_PARAMETER];
272  }
273 
274  return null;
275  }
276 
277  private function fetchModeParameter()
278  {
279  if( isset($_POST[self::MODE_PARAMETER]) )
280  {
281  return $_POST[self::MODE_PARAMETER];
282  }
283 
284  if( isset($_GET[self::MODE_PARAMETER]) )
285  {
286  return $_GET[self::MODE_PARAMETER];
287  }
288 
289  return null;
290  }
291 
292  private function handleTabs()
293  {
294  $this->tabs->clearTargets();
295  $this->tabs->clearSubTabs();
296 
297  $this->tabs->setBackTarget(
298  $this->getBackTargetLabel(), $this->getBackTargetUrl()
299  );
300 
301  $this->tabs->addTab(
302  'browseQuestions', $this->getBrowseQuestionsTabLabel(), $this->getBrowseQuestionsTabUrl()
303  );
304  }
305 
306  private function getBackTargetLabel()
307  {
308  return $this->lng->txt('backtocallingtest');
309  }
310 
311  private function getBackTargetUrl()
312  {
313  return $this->ctrl->getLinkTargetByClass(
315  );
316  }
317 
318  private function getBackTargetCmdClass()
319  {
320  switch( $this->fetchContextParameter() )
321  {
322  case self::CONTEXT_LIST_VIEW:
323 
324  return 'ilObjTestGUI';
325 
326  case self::CONTEXT_PAGE_VIEW:
327 
328  return 'ilTestExpressPageObjectGUI';
329  }
330 
331  return '';
332  }
333 
334  private function getBackTargetCommand()
335  {
336  switch( $this->fetchContextParameter() )
337  {
338  case self::CONTEXT_LIST_VIEW:
339 
340  return 'questions';
341 
342  case self::CONTEXT_PAGE_VIEW:
343 
344  return 'showPage';
345  }
346 
347  return '';
348  }
349 
350  private function getBrowseQuestionsTabLabel()
351  {
352  switch( $this->fetchModeParameter() )
353  {
354  case self::MODE_BROWSE_POOLS:
355 
356  return $this->lng->txt('tst_browse_for_qpl_questions');
357 
358  case self::MODE_BROWSE_TESTS:
359 
360  return $this->lng->txt('tst_browse_for_tst_questions');
361  }
362 
363  return '';
364  }
365 
366  private function getBrowseQuestionsTabUrl()
367  {
368  return $this->ctrl->getLinkTarget($this, self::CMD_BROWSE_QUESTIONS);
369  }
370 
371  public function initFilter()
372  {
373  // title
374  include_once("./Services/Form/classes/class.ilTextInputGUI.php");
375  $ti = new ilTextInputGUI($this->lng->txt("tst_qbt_filter_question_title"), "title");
376  $ti->setMaxLength(64);
377  $ti->setSize(20);
378  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
379  $this->addFilterItem($ti);
380  $ti->readFromSession();
381  $this->filter["title"] = $ti->getValue();
382 
383  // description
384  $ti = new ilTextInputGUI($this->lng->txt("description"), "description");
385  $ti->setMaxLength(64);
386  $ti->setSize(20);
387  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
388  $this->addFilterItem($ti);
389  $ti->readFromSession();
390  $this->filter["description"] = $ti->getValue();
391 
392  // questiontype
393  include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
394  include_once("./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php");
396  $options = array();
397  $options[""] = $this->lng->txt('filter_all_question_types');
398  foreach ($types as $translation => $row)
399  {
400  $options[$row['type_tag']] = $translation;
401  }
402 
403  $si = new ilSelectInputGUI($this->lng->txt("question_type"), "type");
404  $si->setOptions($options);
405  $this->addFilterItem($si);
406  $si->readFromSession();
407  $this->filter["type"] = $si->getValue();
408 
409  // author
410  $ti = new ilTextInputGUI($this->lng->txt("author"), "author");
411  $ti->setMaxLength(64);
412  $ti->setSize(20);
413  $this->addFilterItem($ti);
414  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
415  $ti->readFromSession();
416  $this->filter["author"] = $ti->getValue();
417 
418  // question pool
419  $ti = new ilTextInputGUI($this->getParentObjectLabel(), 'parent_title');
420  $ti->setMaxLength(64);
421  $ti->setSize(20);
422  $ti->setValidationRegexp('/(^[^%]+$)|(^$)/is');
423  $this->addFilterItem($ti);
424  $ti->readFromSession();
425  $this->filter['parent_title'] = $ti->getValue();
426 
427  // repo root node
428  require_once 'Services/Form/classes/class.ilRepositorySelectorInputGUI.php';
429  $ri = new ilRepositorySelectorInputGUI($this->lng->txt('repository'), 'repository_root_node');
430  $ri->setHeaderMessage($this->lng->txt('question_browse_area_info'));
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  {
440  case self::MODE_BROWSE_POOLS:
441 
442  return $this->lng->txt('qpl');
443 
444  case self::MODE_BROWSE_TESTS:
445 
446  return $this->lng->txt('tst');
447  }
448 
449  return '';
450  }
451 
452  public function fillRow($data)
453  {
454  $this->tpl->setVariable("QUESTION_ID", $data["question_id"]);
455  $this->tpl->setVariable("QUESTION_TITLE", $data["title"]);
456  $this->tpl->setVariable("QUESTION_COMMENT", $data["description"]);
457  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
458  $this->tpl->setVariable("QUESTION_TYPE", assQuestion::_getQuestionTypeName($data["type_tag"]));
459  $this->tpl->setVariable("QUESTION_AUTHOR", $data["author"]);
460  $this->tpl->setVariable("QUESTION_CREATED", ilDatePresentation::formatDate(new ilDate($data['created'],IL_CAL_UNIX)));
461  $this->tpl->setVariable("QUESTION_UPDATED", ilDatePresentation::formatDate(new ilDate($data["tstamp"],IL_CAL_UNIX)));
462  $this->tpl->setVariable("QUESTION_POOL", $data['parent_title']);
463  $this->tpl->setVariable("WORKING_TIME", $data['working_time']);
464  }
465 
469  private function buildTestQuestionSetConfig()
470  {
471  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
472 
473  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory(
474  $this->tree, $this->db, $this->pluginAdmin, $this->testOBJ
475  );
476 
477  return $testQuestionSetConfigFactory->getQuestionSetConfig();
478  }
479 
483  private function getQuestionsData()
484  {
485  $questionList = new ilAssQuestionList($this->db, $this->lng, $this->pluginAdmin);
486 
487  $questionList->setQuestionInstanceTypeFilter($this->getQuestionInstanceTypeFilter());
488  $questionList->setExcludeQuestionIdsFilter($this->testOBJ->getExistingQuestions());
489 
490  $repositoryRootNode = self::REPOSITORY_ROOT_NODE_ID;
491 
492  foreach($this->getFilterItems() as $item)
493  {
494  if($item->getValue() !== false)
495  {
496  switch( $item->getPostVar() )
497  {
498  case 'title':
499  case 'description':
500  case 'author':
501  case 'type':
502  case 'parent_title':
503 
504  $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
505  break;
506 
507  case 'repository_root_node':
508 
509  $repositoryRootNode = $item->getValue();
510  }
511  }
512  }
513 
514  $parentObjectIds = $this->getQuestionParentObjIds($repositoryRootNode);
515 
516  if( !count($parentObjectIds) )
517  {
518  return array();
519  }
520 
521  $questionList->setParentObjIdsFilter($parentObjectIds);
522 
523  $questionList->load();
524 
525  return $questionList->getQuestionDataArray();
526  }
527 
528  private function getQuestionInstanceTypeFilter()
529  {
530  if( $this->fetchModeParameter() == self::MODE_BROWSE_TESTS )
531  {
533  }
534 
536  }
537 
538  private function getQuestionParentObjIds($repositoryRootNode)
539  {
540  $parents = $this->tree->getSubTree(
541  $this->tree->getNodeData($repositoryRootNode), true, $this->getQuestionParentObjectType()
542  );
543 
544  $parentIds = array();
545 
546  foreach($parents as $nodeData)
547  {
548  if( $nodeData['obj_id'] == $this->testOBJ->getId() )
549  {
550  continue;
551  }
552 
553  $parentIds[ $nodeData['obj_id'] ] = $nodeData['obj_id'];
554  }
555 
556  $parentIds = array_map('intval', array_values($parentIds));
557 
558  if($this->fetchModeParameter() == self::MODE_BROWSE_POOLS)
559  {
560  $available_pools = array_map('intval', array_keys(ilObjQuestionPool::_getAvailableQuestionpools(true)));
561  return array_intersect($parentIds, $available_pools);
562  }
563  else if($this->fetchModeParameter() == self::MODE_BROWSE_TESTS)
564  {
565  // TODO bheyser: Move this to another place ...
566  return array_filter($parentIds, function($obj_id) {
567  $refIds = ilObject::_getAllReferences($obj_id);
568  $refId = current($refIds);
569  return $this->access->checkAccess('write', '', $refId);
570  });
571  }
572 
573  // Return no parent ids if the user wants to hack...
574  return array();
575  }
576 
577  private function getQuestionParentObjectType()
578  {
579  if( $this->fetchModeParameter() == self::MODE_BROWSE_TESTS )
580  {
581  return 'tst';
582  }
583 
584  return 'qpl';
585  }
586 }
static sendSuccess($a_info="", $a_keep=false)
Send Success Message to Screen.
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.
static _getQuestionTypes($all_tags=FALSE, $fixOrder=false)
$_GET["client_id"]
static _needsManualScoring($question_id)
$cmd
Definition: sahs_server.php:35
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.
setId($a_val)
Set id.
static _getAllReferences($a_id)
get all reference ids of object
setDefaultOrderDirection($a_defaultorderdirection)
Set Default order direction.
Administration class for plugins.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
Interface ilDBInterface.
Class ilTable2GUI.
Class for single dates.
setResetCommand($a_val, $a_caption=null)
Set reset filter command.
if(!is_array($argv)) $options
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.
static formatDate(ilDateTime $date)
Format a date public.
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.
Create styles array
The data for the language used.
writeFilterToSession()
Write filter values to session.
setFormAction($a_form_action, $a_multipart=false)
Set Form action parameter.
setFormName($a_formname="")
Set Form name.
language handling
setSelectAllCheckbox($a_select_all_checkbox)
Set the name of the checkbox that should be toggled with a select all button.
getFilterItems($a_optionals=false)
Get filter items.
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.
$_POST["username"]
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.
resetFilter()
Reset filter.
Class ilAccessHandler.
setFilterCommand($a_val, $a_caption=null)
Set filter command.