plugin/exo/Library/Attempt/PaperGenerator.php
private function pickStepsByTags(Exercise $exercise, array $previousExercise = null)
    {
        $pickConfig = $exercise->getPick();

        // Retrieve the list of items to use
        $items = [];

        if (!empty($previousExercise) && Recurrence::ALWAYS !== $exercise->getRandomPick()) {
            // Just get the list of items from the previous paper
            foreach ($previousExercise['steps'] as $pickedStep) {
                foreach ($pickedStep['items'] as $pickedItem) {
                    $items[] = $exercise->getQuestion($pickedItem['id']);
                }
            }
        } else {
            // Get the list of items from exercise
            foreach ($exercise->getSteps() as $step) {
                $items = array_merge($items, $step->getQuestions());
            }
        }

        // Serialize items (we will automatically get items tags for filtering)
        $serializedItems = array_map(function (Item $pickedItem) {
            return $this->itemSerializer->serialize($pickedItem, [
                Transfer::SHUFFLE_ANSWERS,
                Transfer::INCLUDE_SOLUTIONS,
            ]);
        }, $items);

        $pickedItems = [];

        if (!empty($previousExercise) && Recurrence::ALWAYS !== $exercise->getRandomPick()) {
            // items are already filtered
            $pickedItems = $serializedItems;
        } else {
            // Only pick wanted tags (format : ['tagName', itemCount])
            foreach ($pickConfig['tags'] as $pickedTag) {
                $taggedItems = array_filter($serializedItems, function ($serializedItem) use ($pickedTag) {
                    return !empty($serializedItem['tags']) && in_array($pickedTag[0], $serializedItem['tags']);
                });

                // Get the correct number of items with the current tag
                // There is no error if we want more items than there are in the quiz,
                // we just stop to pick when there are no more available items
                $pickedItems = array_merge($pickedItems, static::pick($taggedItems, $pickedTag[1], true));
            }
        }

        // Shuffle items according to config
        if ((empty($previousExercise) && Recurrence::ONCE === $exercise->getRandomOrder())
            || Recurrence::ALWAYS === $exercise->getRandomOrder()) {
            shuffle($pickedItems);
        }

        // Create steps and fill it with the correct number of questions
        $pickedSteps = [];
        while (!empty($pickedItems)) {
            $pickedStep = $this->stepSerializer->serialize(new Step());
            $pickedStep['items'] = array_splice($pickedItems, 0, $pickConfig['pageSize']);
            $pickedSteps[] = $pickedStep;
        }

        return $pickedSteps;
    }
private function pickStepsByTags(Exercise $exercise, array $previousExercise = null)
    {
        $pickConfig = $exercise->getPick();

        // Retrieve the list of items to use
        $items = [];

        if (!empty($previousExercise) && Recurrence::ALWAYS !== $exercise->getRandomPick()) {
            // Just get the list of items from the previous paper
            foreach ($previousExercise['steps'] as $pickedStep) {
                foreach ($pickedStep['items'] as $pickedItem) {
                    $items[] = $exercise->getQuestion($pickedItem['id']);
                }
            }
        } else {
            // Get the list of items from exercise
            foreach ($exercise->getSteps() as $step) {
                $items = array_merge($items, $step->getQuestions());
            }
        }

        // Serialize items (we will automatically get items tags for filtering)
        $serializedItems = array_map(function (Item $pickedItem) {
            return $this->itemSerializer->serialize($pickedItem, [
                Transfer::SHUFFLE_ANSWERS,
                Transfer::INCLUDE_SOLUTIONS,
            ]);
        }, $items);

        $pickedItems = [];

        if (!empty($previousExercise) && Recurrence::ALWAYS !== $exercise->getRandomPick()) {
            // items are already filtered
            $pickedItems = $serializedItems;
        } else {
            // Only pick wanted tags (format : ['tagName', itemCount])
            foreach ($pickConfig['tags'] as $pickedTag) {
                $taggedItems = array_filter($serializedItems, function ($serializedItem) use ($pickedTag) {
                    return !empty($serializedItem['tags']) && in_array($pickedTag[0], $serializedItem['tags']);
                });

                // Get the correct number of items with the current tag
                // There is no error if we want more items than there are in the quiz,
                // we just stop to pick when there are no more available items
                $pickedItems = array_merge($pickedItems, static::pick($taggedItems, $pickedTag[1], true));
            }
        }

        // Shuffle items according to config
        if ((empty($previousExercise) && Recurrence::ONCE === $exercise->getRandomOrder())
            || Recurrence::ALWAYS === $exercise->getRandomOrder()) {
            shuffle($pickedItems);
        }

        // Create steps and fill it with the correct number of questions
        $pickedSteps = [];
        while (!empty($pickedItems)) {
            $pickedStep = $this->stepSerializer->serialize(new Step());
            $pickedStep['items'] = array_splice($pickedItems, 0, $pickConfig['pageSize']);
            $pickedSteps[] = $pickedStep;
        }

        return $pickedSteps;
    }
private function pickStepsByTags ( Exercise $ exercise , array $ previousExercise = null ) { $ pickConfig = $ exercise -> getPick ( ) ; // Retrieve the list of items to use $ items = [ ] ; if ( ! empty ( $ previousExercise ) && Recurrence :: ALWAYS !== $ exercise -> getRandomPick ( ) ) { // Just get the list of items from the previous paper foreach ( $ previousExercise [ 'steps' ] as $ pickedStep ) { foreach ( $ pickedStep [ 'items' ] as $ pickedItem ) { $ items [ ] = $ exercise -> getQuestion ( $ pickedItem [ 'id' ] ) ; } } } else { // Get the list of items from exercise foreach ( $ exercise -> getSteps ( ) as $ step ) { $ items = array_merge ( $ items , $ step -> getQuestions ( ) ) ; } } // Serialize items (we will automatically get items tags for filtering) $ serializedItems = array_map ( function ( Item $ pickedItem ) { return $ this -> itemSerializer -> serialize ( $ pickedItem , [ Transfer :: SHUFFLE_ANSWERS , Transfer :: INCLUDE_SOLUTIONS , ] ) ; } , $ items ) ; $ pickedItems = [ ] ; if ( ! empty ( $ previousExercise ) && Recurrence :: ALWAYS !== $ exercise -> getRandomPick ( ) ) { // items are already filtered $ pickedItems = $ serializedItems ; } else { // Only pick wanted tags (format : ['tagName', itemCount]) foreach ( $ pickConfig [ 'tags' ] as $ pickedTag ) { $ taggedItems = array_filter ( $ serializedItems , function ( $ serializedItem ) use ( $ pickedTag ) { return ! empty ( $ serializedItem [ 'tags' ] ) && in_array ( $ pickedTag [ 0 ] , $ serializedItem [ 'tags' ] ) ; } ) ; // Get the correct number of items with the current tag // There is no error if we want more items than there are in the quiz, // we just stop to pick when there are no more available items $ pickedItems = array_merge ( $ pickedItems , static :: pick ( $ taggedItems , $ pickedTag [ 1 ] , true ) ) ; } } // Shuffle items according to config if ( ( empty ( $ previousExercise ) && Recurrence :: ONCE === $ exercise -> getRandomOrder ( ) ) || Recurrence :: ALWAYS === $ exercise -> getRandomOrder ( ) ) { shuffle ( $ pickedItems ) ; } // Create steps and fill it with the correct number of questions $ pickedSteps = [ ] ; while ( ! empty ( $ pickedItems ) ) { $ pickedStep = $ this -> stepSerializer -> serialize ( new Step ( ) ) ; $ pickedStep [ 'items' ] = array_splice ( $ pickedItems , 0 , $ pickConfig [ 'pageSize' ] ) ; $ pickedSteps [ ] = $ pickedStep ; } return $ pickedSteps ; }
Generates steps based on the quiz configuration and a list of items.
In this kind of quiz all items are stored in a single step.

@param Exercise $exercise
@param array    $previousExercise

@return array
Generates steps based on the quiz configuration and a list of items . In this kind of quiz all items are stored in a single step .