epub_reader_framework-2.0.0-alpha2/src/Form/ReaderPublicationFormAlter.php
src/Form/ReaderPublicationFormAlter.php
<?php
namespace Drupal\epub_reader_framework\Form;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\epub_reader_framework\EpubReaderFrameworkHelpers;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Handles the form alters for the reader publication.
*/
class ReaderPublicationFormAlter {
use StringTranslationTrait;
/**
* The access manager service.
*
* @var \Drupal\Core\Routing\CurrentRouteMatch
*/
protected $routeMatch;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new ReaderPublicationFormAlter object.
*
* @param \Drupal\Core\Routing\CurrentRouteMatch $route_match
* The route match service.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* The current user.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
*/
public function __construct(
CurrentRouteMatch $route_match,
AccountProxyInterface $current_user,
EntityTypeManagerInterface $entity_type_manager
) {
$this->routeMatch = $route_match;
$this->currentUser = $current_user;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('current_route_match'),
$container->get('current_user'),
$container->get('entity_type.manager')
);
}
/**
* Callback implementation of hook_form_FORM_ID_alter().
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
* @param string $form_id
* The form ID.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function formAlter(array &$form, FormStateInterface $form_state, $form_id) {
// If we are on the publication reader page.
if (isset($form['field_reader_chapters']['widget']['add_more'])) {
// If we are on the node add page, remove chapters completely.
if ($this->routeMatch->getRouteName() == 'node.add') {
$form['field_reader_chapters']['#access'] = FALSE;
}
// Remove normal add more button.
$form['field_reader_chapters']['widget']['add_more']['#access'] = FALSE;
// Update the chapter items to be non-editable.
foreach ($form['field_reader_chapters']['widget'] as $key => &$item) {
if (is_numeric($key)) {
// Don't allow the add new item.
if (!$item['target_id']['#default_value']) {
unset($form['field_reader_chapters']['widget'][$key]);
}
elseif ($item['target_id']['#default_value'] instanceof NodeInterface) {
/** @var \Drupal\node\NodeInterface $target_node */
$target_node = $item['target_id']['#default_value'];
$item['target_id']['#access'] = FALSE;
// Add a link to the edit node screen.
$url = Url::fromRoute('entity.node.edit_form', [
'node' => $target_node->id(),
]);
$link = Link::fromTextAndUrl($target_node->label(), $url);
$item['#suffix'] = $link->toString();
}
}
}
// Add an "Add new chapter" button.
/** @var \Drupal\Core\Session\AccountProxyInterface $user */
$user = $this->currentUser;
$access_check = $this->entityTypeManager
->getAccessControlHandler('node');
if ($access_check->createAccess('reader_chapter', $user)) {
$url = Url::fromRoute('node.add', ['node_type' => 'reader_chapter']);
if ($url->access($user)) {
// If we have a node ID (ie, editing existing), append the ID.
/** @var \Drupal\Core\Entity\EntityForm $form_object */
$form_object = $form_state->getFormObject();
if ($form_object instanceof EntityFormInterface && $entity = $form_object->getEntity()) {
if (!$entity->isNew()) {
$url->setOption('query', [
'reader_publication_id' => $entity->id(),
]);
}
}
// Add chapter button.
$label = $this->t('Add Chapter');
$render = Link::fromTextAndUrl($label, $url)->toRenderable();
$render['#attributes'] = [
'class' => [
'button',
],
];
$render['#suffix'] = ' ' . $this->t('Clicking each link here (as well as the add a new chapter button) will open the chapter edit screen, discarding any changes you have made here.');
$form['field_reader_chapters']['create_chapter'] = $render;
}
}
// Destination parameter prevents submission batch start.
$query = \Drupal::request()->query->all();
if (\Drupal::request()->query->has('destination')) {
unset($query['destination']);
$url = Url::fromRoute('<current>', [], ['query' => $query]);
$response = new RedirectResponse($url->toString());
$response->send();
}
// Add submit handler to trigger batch.
$form['actions']['submit']['#submit'][] = [self::class, 'submitFormHandler'];
// Support for save & edit module.
if (isset($form['actions']['save_edit']['#submit'])) {
$form['actions']['save_edit']['#submit'][] = [self::class, 'submitFormHandler'];
}
}
}
/**
* Maybe trigger the batch import of the epub.
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return void
*/
public static function submitFormHandler(array &$form, FormStateInterface $form_state) {
if (self::checkIfReimportNeeded($form_state)) {
/** @var \Drupal\node\NodeInterface $node */
$node = $form_state->getFormObject()->getEntity();
EpubReaderFrameworkHelpers::startExtractionBatch($node);
}
}
/**
* Check if we need to trigger a reimport of the publication EPUB.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return bool
* Whether re-import is needed.
*/
protected static function checkIfReimportNeeded(FormStateInterface $form_state): bool {
// Forced re-import.
$file_processed = $form_state->getValue('field_reader_file_processed');
if (isset($file_processed['value']) && !$file_processed['value']) {
return TRUE;
}
return FALSE;
}
}
