8 Fakoli::usingFile(
"/cms/components/questionnaire/abstract_questionnaire_manager.inc");
28 function AbstractQuestionnaireCreateManager($item)
36 abstract function getComponentName();
41 abstract function getQuestionClass();
49 abstract function getXrefClass();
54 function getTitleField()
72 function getQuestionDeleteHandler()
74 return "question_delete";
77 function getQuestionRemoveHandler()
79 return "question_remove";
82 function getReorderHandler()
84 return "reorder_questions";
87 function getClassName()
89 return $this->item->prettifyClassName();
99 function getQuestionListIdentifier()
101 return "{$this->item->table}_questions";
109 function getQuestionForm()
111 return "{$this->item->table}_question_form";
120 function getQuestionnaireFormIdentifier()
126 return "{$this->item->table}_form";
136 $question_form_id = $this->getQuestionForm();
139 return $question->format(
"<a href='{$question_form_id}?{$qPk}={{$qPk}}'>{question}</a>\n");
149 function cloneQuestionnaire($title_field, $cloneFields = array())
152 $itemClass = get_class(
$src);
153 $dst =
new $itemClass();
155 if(is_callable(array($dst, setDefaults)))
159 $dst->$title_field =
$src->$title_field;
161 if(count($cloneFields) > 0)
163 foreach($cloneFields as
$field)
165 $dst->$field =
$src->$field;
179 $itemPk = $dst->getPrimaryKey();
191 $obj->$sort_field = $sort_order;
193 $obj->$itemPk = $dst->$itemPk;
205 function deleteQuestionnaire()
209 if(!$item->allowDelete())
213 $itemPk = $item->getPrimaryKey();
219 $tx =
new DataTransaction();
227 $obj->delete(
"WHERE {$itemPk}={$item->$itemPk}");
234 $item->joinTransaction(
$tx);
246 function logicalDeleteQuestionnaire()
248 $this->item->filter =
null;
250 if($this->item->hasField(
"deleted"))
252 $this->item->deleted =
true;
253 $this->item->filter =
new InclusionFilter(
"deleted");
265 function removeQuestionXref($xref_id)
268 $itemPk = $item->getPrimaryKey();
274 $xrefPk = $xref->getPrimaryKey();
276 if ($item->$itemPk != $xref->$itemPk)
278 throw new FakoliException(
"QuestionnaireManager removeQuestion Data Mismatch");
280 $xref->delete(
"WHERE $xrefPk={$xref_id}");
281 $this->reNumberQuestions();
289 $qClass = $this->getQuestionClass();
303 $itemPk = $item->getPrimaryKey();
304 $qClass = $this->getQuestionClass();
311 $xref->delete(
"WHERE {$itemPk}={$item->$itemPk} AND {$qPk}={$question->$qpK}");
312 $this->reNumberQuestions();
330 function saveQuestionXref(
$question, $sort_order = 0)
344 if($xref->exists(
"WHERE {$itemPk}={$item->$itemPk} AND {$qPk}={$question->$qPk}"))
349 $xref->$itemPk = $item->$itemPk;
350 $xref->sort_order = (!$sort_order) ? $this->getNextSortOrder() : $sort_order;
373 ->executeValue(
"COUNT(1)");
392 $qClass = $this->getQuestionClass();
393 $itemPk = $item->getPrimaryKey();
396 $item_class = $this->item->prettifyClassName();
397 $question_class =
$question->prettifyClassName();
401 Fakoli::end(
"Delete not permitted for question id {$question->$qPk} {$question->question}");
406 if ($item->$itemPk !=
$question->$itemPk)
408 throw new FakoliException(
"QuestionnaireManager deleteQuestion Data Mismatch $item_class {$itemPk} {$item->$itemPk} does not match question $question_class {$itemPk} {$question->$itemPk} {$qPk} {$question->$qPk}");
412 $this->reNumberQuestions();
431 function reOrderQuestions()
437 $sortableObj =
new $sortableClass();
438 $pk = $sortableObj->getPrimaryKey();
439 $itemPk = $item->getPrimaryKey();
443 foreach($_POST as
$name => $sort_order)
445 if (!strncmp(
$name,
"question_", 9))
449 checkNumeric($sort_order);
451 $sortableObj =
new $sortableClass(
$id);
452 $sortableObj->filter =
new InclusionFilter(
$pk, $sort_field);
453 $sortableObj->$itemPk = $item->$itemPk;
454 $sortableObj->$pk =
$id;
455 $sortableObj->$sort_field = $sort_order;
456 $sortableObj->save();
460 $this->reNumberQuestions();
473 function reNumberQuestions()
477 $sortableObj =
new $sortableClass();
478 $pk = $sortableObj->getPrimaryKey();
484 foreach($objs as
$obj)
486 $obj->filter =
new InclusionFilter($sort_field);
487 $obj->$sort_field = $sort_order;
503 function getQuestionSets()
505 $itemPk = $this->item->getPrimaryKey();
515 $query = GroupedQuery::create(
$xref_class,
"",
"{$itemPk}");
516 if($this->item->$itemPk)
518 $query->constraints =
"WHERE {$qPk} NOT IN (SELECT {$qPk} FROM {$xref->table} WHERE {$itemPk} = :{$itemPk})";
519 $query->bind(
":{$itemPk}", $this->item->$itemPk);
522 return $query->execute();
539 function buildQuestionSelectForm(
$items =
null)
541 $class = $this->getClassName();
542 $this->item->filter =
new InclusionFilter();
543 $form =
new AutoForm($this->item);
545 $title_field = $this->getTitleField();
549 $items = $this->getQuestionnaires();
557 $table->column(
"Question",
"{Question.question}",
false)
559 ->column(
"Required", array(
QuestionTableHelper, formatRequired),
false,
"text-align: center")
562 $table->emptyMessage =
"There are no $class questions to select.";
566 if(!array_key_exists($item_id,
$items))
continue;
569 $table->group($item->$title_field, $item_id);
573 $questionSelect =
new DataListFieldRenderer(
$form,
$table,
"survey_question_select",
"<h3>Select Survey Questions</h3>$instructions");
574 $questionSelect->hideLabel =
true;
575 $form->submitLabel =
"Select";
576 $form->buttons_at_top =
true;
580 $form->readOnlyForm =
true;
583 $questionSelect->onPostProcess = array($this, saveSelectedQuestions);
597 function saveSelectedQuestions($questionSelect,
$field)
608 $xrefPk = $xref->getPrimaryKey();
609 $questionClass = $this->getQuestionClass();
612 $questionIds =
$_POST[$xrefPk];
614 if(isset($questionIds) AND count($questionIds) > 0)
616 $list = implode(
",", array_values($questionIds));
618 $questions = Query::create($questionClass,
"WHERE {$qPk} IN (SELECT {$qPk} FROM {$xref->table} WHERE {$xrefPk} IN ($list))")
623 $sort_order = $this->getNextSortOrder();
627 $this->saveQuestionXref(
$question, $sort_order);
634 function filterActions(&$actions)
636 if(!count($actions))
return;
639 if(!is_callable(array($item, isAuthor)))
return;
641 if(!$item->isAuthor())
643 unset($actions[
"edit"], $actions[
"send"], $actions[
"open"],
644 $actions[
"close"], $actions[
"send_reminders"], $actions[
"reopen"],
645 $actions[
"share"], $actions[
"unshare"], $actions[
"delete"], $actions[
"send_test"]);
654 function enableDragReorder(&
$table)
656 $component_name = $this->getComponentName();
657 $reorder_handler = $this->getReorderHandler();
660 $table->enableDragReorder(
"/action/{$component_name}/{$reorder_handler}?{$itemPk}={$this->item->$itemPk}");
661 $table->dragText =
"<span style='font-size: 10px'>Click and drag to change the order of the questions</span>";
674 function saveDraggableQuestionOrder()
677 $itemPk = $item->getPrimaryKey();
679 $sortableObj =
new $sortableClass();
682 $pk = $sortableObj->getPrimaryKey();
683 $tx =
new DataTransaction();
687 foreach($_GET[
$pk] as
$id => $sort_order)
690 checkNumeric($sort_order);
692 $sortableObj =
new $sortableClass();
693 $sortableObj->joinTransaction(
$tx);
695 $sortableObj->load(
$id);
697 if ($item->$itemPk != $sortableObj->$itemPk)
702 $sortableObj->filter =
new InclusionFilter(
$pk, $sort_field);
703 $sortableObj->$sort_field = $sort_order;
704 $sortableObj->save();
725 function getNextSortOrder()
729 $itemPk = $item->getPrimaryKey();
732 return Query::create($sortableClass,
"WHERE {$itemPk}=:{$itemPk}")
733 ->bind(
":{$itemPk}", $item->$itemPk)
734 ->executeValue(
"MAX($sort_field)") + 1;
737 function validateQuestionnaire()
740 $id = $this->item->$pk;
745 $msg =
"Your <a href='{$identifier}?$pk=$id'>questionnaire</a> must have at least one question.";
752 function writeQuestionnaireValidationMsg()
754 $msg = $this->validateQuestionnaire();
755 echo
"<div id='warning'>{$msg}</div>\n";
764 function getJSManagerName()
766 return "questionnaireMgr";
781 function writeScript()
785 $itemPk = $item->getPrimaryKey();
786 $item_id = $item->$itemPk;
787 $component_name = $this->getComponentName();
788 $question_delete_handler = $this->getQuestionDeleteHandler();
789 $question_remove_handler = $this->getQuestionRemoveHandler();
790 $question_list_identifier = $this->getQuestionListIdentifier();
791 $mgrName = $this->getJSManagerName();
797 $xrefPk = $xref->getPrimaryKey();
802 <script type=
"text/javascript" src=
"/components/questionnaire/js/questionnaire_create.js"></script>
803 <script type=
"text/javascript">
804 var <?php echo $mgrName ?>;
806 window.addEvent(
'domready',
function()
809 '<?php echo $qPk ?>',
810 '<?php echo $itemPk ?>',
811 <?php echo $item_id ?>,
812 '<?php echo $xrefPk ?>',
813 '<?php echo $component_name ?>',
814 '<?php echo $question_delete_handler ?>',
815 '<?php echo $question_remove_handler ?>',
816 '<?php echo $question_list_identifier ?>'
Questionnaire/Survey Implementation instructions.
getQuestionKey()
Returns the primar key name of the question obj.
getSortableItems()
Retrieves the table that has the question sort order field either Question or a QuestionXref.
getQuestions()
Retrieves questions through the questionnaire or survey DataItem object.
FakoliException is the base exception class for all Fakoli errors.
static using()
Import the datamodels, views and manifest for the specified component(s).
static end($message="")
Use this method to terminate execution of a script instead of using the php keywords exit() or die().
static usingFile()
Uses the specified framework file(s) from the framework directory.
static getText($code, $obj=null, $blank=false)
Retrieves text for display on a page, given the code.