Deserializes question data.

@param array        $questionData
@param AbstractItem $question
@param array        $options

@return AbstractItem
346500
public function deserializeQuestion(array $questionData, AbstractItem $question = null, array $options = [])
    {
        return $this->getQuestionSerializer()->deserialize($questionData, $question, $options);
    }
1040796
public function deserialize($data, ChoiceQuestion $choiceQuestion = null, array $options = [])
    {
        if (empty($choiceQuestion)) {
            $choiceQuestion = new ChoiceQuestion();
        }

        $this->sipe('multiple', 'setMultiple', $data, $choiceQuestion);
        $this->sipe('random', 'setShuffle', $data, $choiceQuestion);
        $this->sipe('numbering', 'setNumbering', $data, $choiceQuestion);

        $this->deserializeChoices($choiceQuestion, $data['choices'], $data['solutions'], $options);

        return $choiceQuestion;
    }
174843
public function deserialize($data, Answer $answer = null, array $options = [])
    {
        $answer = $answer ?: new Answer();

        $this->sipe('id', 'setUuid', $data, $answer);
        $this->sipe('questionId', 'setQuestionId', $data, $answer);
        $this->sipe('tries', 'setTries', $data, $answer);
        $this->sipe('score', 'setScore', $data, $answer);
        $this->sipe('feedback', 'setFeedback', $data, $answer);

        if (isset($data['usedHints'])) {
            foreach ($data['usedHints'] as $usedHint) {
                $answer->addUsedHint($usedHint['id']);
            }
        }
        if (!empty($data['data'])) {
            $answer->setData(json_encode($data['data']));
        }

        return $answer;
    }
1171413
public function serialize(PairQuestion $pairQuestion, array $options = [])
    {
        $serialized = [
            'random' => $pairQuestion->getShuffle(),
            'penalty' => $pairQuestion->getPenalty(),
            'rows' => $pairQuestion->getRows()->filter(function (GridRow $row) {
                return 0 < $row->getScore();
            })->count(),  // The grid only contains expected answers
        ];

        $items = $this->serializeItems($pairQuestion, $options);

        if (in_array(Transfer::SHUFFLE_ANSWERS, $options)) {
            shuffle($items); // shuffle the pool of items
        }

        $serialized['items'] = $items;

        if (in_array(Transfer::INCLUDE_SOLUTIONS, $options)) {
            $serialized['solutions'] = $this->serializeSolutions($pairQuestion);
        }

        return $serialized;
    }
403667
private function deserializeResources(Item $question, array $resources = [], array $options = [])
    {
        $resourceEntities = $question->getResources()->toArray();

        foreach ($resources as $resourceData) {
            $existingResource = null;

            // Searches for an existing resource entity.
            foreach ($resourceEntities as $entityIndex => $entityResource) {
                /** @var ItemResource $entityResource */
                if ((string) $entityResource->getId() === $resourceData['id']) {
                    $existingResource = $entityResource;
                    unset($resourceEntities[$entityIndex]);
                    break;
                }
            }

            // Link resource to item
            if (empty($existingResource)) {
                $obj = $this->resourceContentSerializer->deserialize($resourceData, $existingResource, $options);
                if ($obj) {
                    if ($obj instanceof ResourceNode) {
                        $itemResource = new ItemResource();
                        $itemResource->setResourceNode($obj);
                        $itemResource->setQuestion($question);
                        $obj = $itemResource;
                    }
                    $question->addResource($obj);
                }
            }
        }

        // Remaining resources are no longer in the Item
        if (0 < count($resourceEntities)) {
            foreach ($resourceEntities as $resourceToRemove) {
                $question->removeResource($resourceToRemove);
            }
        }
    }
701192
public function serialize(MatchQuestion $setQuestion, array $options = [])
    {
        $serialized = [
            'random' => $setQuestion->getShuffle(),
            'penalty' => $setQuestion->getPenalty(),
        ];

        $items = array_map(function (Proposal $proposal) use ($options) {
            $setData = $this->contentSerializer->serialize($proposal, $options);
            $setData['id'] = $proposal->getUuid();

            return $setData;
        }, $setQuestion->getProposals()->toArray());

        $sets = array_map(function (Label $label) use ($options) {
            $itemData = $this->contentSerializer->serialize($label, $options);
            $itemData['id'] = $label->getUuid();

            return $itemData;
        }, $setQuestion->getLabels()->toArray());

        if ($setQuestion->getShuffle() && in_array(Transfer::SHUFFLE_ANSWERS, $options)) {
            shuffle($sets);
            shuffle($items);
        }

        $serialized['sets'] = $sets;
        $serialized['items'] = $items;

        if (in_array(Transfer::INCLUDE_SOLUTIONS, $options)) {
            $serialized['solutions'] = $this->serializeSolutions($setQuestion);
        }

        return $serialized;
    }
120979
public function make_question($questiondata) {
        $question = $this->make_question_instance($questiondata);
        $this->initialise_question_instance($question, $questiondata);
        return $question;
    }
1369868
public function deserializeItems(Step $step, array $items = [], array $options = [])
    {
        $stepQuestions = $step->getStepQuestions()->toArray();

        foreach ($items as $index => $itemData) {
            $item = null;
            $stepQuestion = null;

            // Searches for an existing item entity.
            foreach ($stepQuestions as $entityIndex => $entityStepQuestion) {
                /** @var StepItem $entityStepQuestion */
                if ($entityStepQuestion->getQuestion()->getUuid() === $itemData['id']) {
                    $stepQuestion = $entityStepQuestion;
                    $item = $stepQuestion->getQuestion();
                    unset($stepQuestions[$entityIndex]);
                    break;
                }
            }

            $entity = $this->itemSerializer->deserialize($itemData, $item, $options);

            if (empty($stepQuestion)) {
                // Creation of a new item (we need to link it to the Step)
                $stepQuestion = $step->addQuestion($entity);
            } else {
                // Update order of the Item in the Step
                $stepQuestion->setOrder($index);
            }

            if (isset($itemData['meta']['mandatory'])) {
                $stepQuestion->setMandatory($itemData['meta']['mandatory']);
            }
        }

        // Remaining items are no longer in the Step
        if (0 < count($stepQuestions)) {
            foreach ($stepQuestions as $stepQuestionToRemove) {
                $step->removeStepQuestion($stepQuestionToRemove);
            }
        }
    }
760312
public function deserialize($data, ClozeQuestion $clozeQuestion = null, array $options = [])
    {
        if (empty($clozeQuestion)) {
            $clozeQuestion = new ClozeQuestion();
        }
        $this->sipe('text', 'setText', $data, $clozeQuestion);

        $this->deserializeHoles($clozeQuestion, $data['holes'], $data['solutions'], $options);

        return $clozeQuestion;
    }
884535
public function serialize(OrderingQuestion $question, array $options = [])
    {
        $serialized = [
            'mode' => $question->getMode(),
            'direction' => $question->getDirection(),
            'penalty' => $question->getPenalty(),
        ];

        // Serializes items
        $items = $this->serializeItems($question, $options);

        // shuffle items only in player
        if (in_array(Transfer::SHUFFLE_ANSWERS, $options)) {
            shuffle($items);
        }
        $serialized['items'] = $items;

        if (in_array(Transfer::INCLUDE_SOLUTIONS, $options)) {
            $serialized['solutions'] = $this->serializeSolutions($question);
        }

        return $serialized;
    }
1334529
public function deserialize(array $data, PanelFacet $panel, array $options = [])
    {
        $this->sipe('id', 'setUuid', $data, $panel);
        $this->sipe('title', 'setName', $data, $panel);
        $this->sipe('position', 'setPosition', $data, $panel);

        if (isset($data['roles'])) {
            $this->deserializeRoles($data['roles'], $panel);
        }

        if (isset($data['fields']) && in_array(Options::DEEP_DESERIALIZE, $options)) {
            $panel->resetFieldFacets();
            $i = 0;

            foreach ($data['fields'] as $field) {
                if (!isset($field['restrictions']['order'])) {
                    $field['restrictions']['order'] = $i;
                }
                ++$i;
                $fieldFacet = $this->_om->getObject($field, FieldFacet::class) ?? new FieldFacet();
                $fieldFacet = $this->ffSerializer->deserialize($field, $fieldFacet, $options);
                $fieldFacet->setPanelFacet($panel);
            }
        }
    }
221571
private function deserializeSolutions(OpenQuestion $wordsQuestion, array $solutions, array $options = [])
    {
        $updatedKeywords = $this->keywordSerializer->deserializeCollection($solutions, $wordsQuestion->getKeywords()->toArray(), $options);

        // Replace keywords collection by the updated one
        $wordsQuestion->setKeywords($updatedKeywords);
    }
1159006
private function serializeChoices(ChoiceQuestion $choiceQuestion, array $options = [])
    {
        return array_map(function (Choice $choice) use ($options) {
            $choiceData = $this->contentSerializer->serialize($choice, $options);
            // TODO : finish content management. For now the choice id overlaps the content ID.
            $choiceData['id'] = $choice->getUuid();

            return $choiceData;
        }, $choiceQuestion->getChoices()->toArray());
    }
850890
public function validateAfterSchema($answerData, array $options = [])
    {
        $errors = [];

        /** @var PairQuestion $question */
        $question = !empty($options[Validation::QUESTION]) ? $options[Validation::QUESTION] : null;
        if (empty($question)) {
            throw new \LogicException('Answer validation : Cannot perform additional validation without question.');
        }

        foreach ($answerData as $rowIndex => $answerRow) {
            foreach ($answerRow as $itemIndex => $answerItem) {
                if (empty($question->getItem($answerItem))) {
                    $errors[] = [
                        'path' => "/[{$rowIndex}]/[{$itemIndex}]",
                        'message' => 'answers must reference a question item',
                    ];
                }
            }
        }

        return $errors;
    }
916736
protected function askChoice($question, $options, $default = NULL) {
    return $this->doAsk(new ChoiceQuestion($this->formatQuestion($question),
      $options, $default));
  }
154252
private function serializeResources(Item $question, array $options = [])
    {
        return array_map(function (ItemResource $resource) use ($options) {
            return $this->resourceContentSerializer->serialize($resource->getResourceNode(), $options);
        }, $question->getResources()->toArray());
    }
1002788
public function deserialize($data, Keyword $keyword = null, array $options = [])
    {
        if (empty($keyword)) {
            $keyword = new Keyword();
        }
        $cleanedText = trim(strip_tags(html_entity_decode($data['text'])));
        $keyword->setText($cleanedText);

        $this->sipe('caseSensitive', 'setCaseSensitive', $data, $keyword);
        $this->sipe('score', 'setScore', $data, $keyword);
        $this->sipe('feedback', 'setFeedback', $data, $keyword);

        return $keyword;
    }