crossword-8.x-1.x-dev/modules/crossword_contest/src/Controller/CrosswordContestController.php
modules/crossword_contest/src/Controller/CrosswordContestController.php
<?php
namespace Drupal\crossword_contest\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\file\Entity\File;
use Drupal\media\Entity\Media;
use Drupal\media\MediaInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* For the crossword contest.
*/
class CrosswordContestController extends ControllerBase {
/**
* Returns the media in the appropriate view mode based on answer.
*
* The request should have been validated already to determine whether
* the mid is for a crossword_contest media entity to which the user
* has access.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param string $mid
* The id of the crossword_contest media.
* @param string $answer
* The answer as a json string.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The crossword_contest media in the appropriate view mode.
*/
public function build(Request $request, $mid, $answer) {
$media = Media::load($mid);
if ($this->isCorrectAnswer($media, $answer)) {
// Correct! Use crossword_contest_correct view mode.
$content = \Drupal::entityTypeManager()->getViewBuilder('media')->view($media, 'crossword_contest_correct');
}
else {
// Incorrect! Use crossword_contest_incorrect view mode.
$content = \Drupal::entityTypeManager()->getViewBuilder('media')->view($media, 'crossword_contest_incorrect');
}
$response = new AjaxResponse();
$response->addCommand(new OpenModalDialogCommand($media->label(), $content));
return $response;
}
/**
* Check if mid is for an allowed media item.
*
* This is a custom access on the route. The user must have access to
* the media and the media should be of the bundle crossword_contest.
*
* @param string $mid
* The id of the media entity.
*
* @return \Drupal\Core\Access\AccessResult
* The custom access.
*/
public function validateMid($mid) {
$media = Media::load($mid);
// Is it media?
if (empty($media)) {
return AccessResult::forbidden();
}
// Does user have permission to view it?
if (!$media->access('view', $this->currentUser())) {
return AccessResult::forbidden();
}
// Is it the right bundle?
if ($media->bundle() !== 'crossword_contest') {
return AccessResult::forbidden();
}
// Does it have a crossword?
if (!isset($media->field_crossword_contest_xword->target_id)) {
return AccessResult::forbidden();
}
// Mid looks good.
return AccessResult::allowed();
}
/**
* Compares submitted answer to the correct answer.
*
* @param \Drupal\media\MediaInterface $media
* The loaded crossword_content media.
* @param string $answer
* Json encoded answer submitted by user.
*
* @return bool
* True if the submitted answer is correct.
*/
protected function isCorrectAnswer(MediaInterface $media, $answer) {
$fid = $media->field_crossword_contest_xword->target_id;
$file = File::load($fid);
if ($file) {
$solution = \Drupal::service('crossword.data_service')->getSolution($file);
if (is_array($solution)) {
// The answer is json, while the solution is an array.
return strtolower($answer) == strtolower(json_encode($solution));
}
}
return FALSE;
}
}
