learnosity-1.0.x-dev/src/LearnosityItemsInlineHandler.php

src/LearnosityItemsInlineHandler.php
<?php

namespace Drupal\learnosity;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Render\Markup;

/**
 * The Learnosity Items Inline Handler.
 *
 * This handler allows you to add inline learnosity items to a node page. To use
 * it, invoke hook_learnosity_inline_items() and return an indexed array of
 * item references.
 *
 * @package Drupal\learnosity
 */
class LearnosityItemsInlineHandler implements ContainerInjectionInterface {

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The learnosity Sdk service.
   *
   * @var \Drupal\learnosity\LearnositySdk
   */
  protected $learnosity;

  /**
   * The learnosity session handler.
   *
   * @var \Drupal\learnosity\LearnositySessionHandler
   */
  protected $learnositySession;

  /**
   * The learnosity mappings handler.
   *
   * @var \Drupal\learnosity\LearnosityMappingsHandler
   */
  protected $learnosityMappings;

  /**
   * Constructs a new LearnosityItemsInlineHandler object.
   *
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\learnosity\LearnositySdk $learnosity
   *   The learnosity sdk.
   * @param \Drupal\learnosity\LearnositySessionHandler $learnosity_session
   *   The learnosity session handler.
   * @param \Drupal\learnosity\LearnosityMappingsHandler $learnosity_mappings
   *   The learnosity mappings handler.
   */
  public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, LearnositySdk $learnosity, LearnositySessionHandler $learnosity_session, LearnosityMappingsHandler $learnosity_mappings) {
    $this->currentUser = $current_user;
    $this->entityTypeManager = $entity_type_manager;
    $this->learnosity = $learnosity;
    $this->learnositySession = $learnosity_session;
    $this->learnosityMappings = $learnosity_mappings;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('current_user'),
      $container->get('entity_type.manager'),
      $container->get('learnosity.sdk'),
      $container->get('learnosity.session_handler'),
      $container->get('learnosity.mappings_handler'),
    );
  }

  /**
   * Manipulates the view display to show inline learnosity items.
   *
   * @param array $build
   *   The current view build.
   * @param \Drupal\Core\Entity\EntityInterface $node
   *   The node.
   * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
   *   The current view display.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   *
   * @see hook_node_view_alter()
   */
  public function nodeViewAlter(array &$build, EntityInterface $node, EntityViewDisplayInterface $display) {
    $view_modes = [
      'full',
      'default',
    ];
    if (in_array($build['#view_mode'], $view_modes)) {
      $inline_items = $this->getInlineItems($node, $display);

      if (!empty($inline_items) && $this->currentUser->isAuthenticated()) {
        $user = $this->entityTypeManager->getStorage('user')->load($this->currentUser->id());
        $session_id = $this->learnositySession->init($this->learnosityMappings->get($node, 'activity_id'));

        $build['#context'] = [
          'entity' => $node,
          'user_id' => $user->id(),
        ];
        $signed_request = $this->learnosity->init('items', [
          'activity_id' => $this->learnosityMappings->get($node, 'activity_id'),
          'name' => $this->learnosityMappings->get($node, 'name'),
          'rendering_type' => 'inline',
          'type' => 'submit_practice',
          'session_id' => $session_id,
          'user_id' => $this->learnosityMappings->get($user, 'id'),
          'items' => $inline_items,
          'config' => [
            'questions_api_init_options' => [
              'attribute_overrides' => [
                'instant_feedback' => TRUE,
              ],
              'show_distractor_rationale' => [
                'per_question' => 'incorrect',
                'per_response' => 'always',
              ],
            ],
          ],
        ], $build['#context']);

        // Make sure that session_id is always passed as part of the context
        // for assessment items. We can use this to determine most of the
        // contextual information. E.g user, activity etc.
        $build['#context'] += [
          'session_id' => $session_id,
        ];

        // Load core learnosity drupal js file and pass signed request.
        $build['#attached']['library'][] = 'learnosity/learnosity';
        $build['#attached']['library'][] = 'learnosity/api.items';
        $build['#attached']['library'][] = 'learnosity/learnosity.inline_items';
        $build['#attached']['drupalSettings']['learnosity'] = [
          'service' => 'items',
          'signedRequest' => Markup::create($signed_request),
          'context' => $this->getScalarContextValues($build['#context']),
        ];
      }
    }
  }

  /**
   * Return a formatted list of inline items.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity.
   *
   * @return array
   *   The array of inline items ready to be rendered.
   */
  protected function getInlineItems(EntityInterface $entity, EntityViewDisplayInterface $display) {
    // Prepare the inline items. By default, it doesn't know where the inline
    // items come from. Use this hook to prepare them.
    $inline_items = \Drupal::moduleHandler()->invokeAll('learnosity_inline_items', [$entity, $display]);

    // Make sure that that items are unique otherwise it can trigger an error
    // with learnosity and it won't render.
    $inline_items = array_unique($inline_items);

    $items = [];
    foreach ($inline_items as $item) {
      $items[] = ['id' => $item, 'reference' => $item];
    }

    return $items;
  }

  /**
   * Parse context and return scalar values.
   *
   * Only attach scalar values because arrays and objects should not be
   * passed through javascript.
   *
   * @param array $context
   *   The current context.
   *
   * @return array
   *   The array of scalar values.
   */
  protected function getScalarContextValues(array $context) {
    $new_context = [];
    foreach ($context as $key => $value) {
      if (is_scalar($value)) {
        $new_context[$key] = $value;
      }
    }
    return $new_context;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc