association-1.0.0-alpha2/modules/association_menu/src/Form/RefreshMenuLinksForm.php
modules/association_menu/src/Form/RefreshMenuLinksForm.php
<?php namespace Drupal\association_menu\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; /** * Form which provides access to association content menu link rebuilding. * * When the association menu is first installed, existing association content * will not have any menus generated for their content and this form is meant * to provide access for building and updating links for current content. * * Association menus are designed to automatically update as content is added * and this form is around in case things get out of sync. */ class RefreshMenuLinksForm extends FormBase { /** * Gets the entity type manager. * * @return \Drupal\Core\Entity\EntityTypeManagerInterface * The entity type manager. */ protected static function getEntityTypeManager() { return \Drupal::entityTypeManager(); } /** * Get the association menu storage manager. * * @return \Drupal\association_menu\AssociationMenuStorageInterface * The association menu storage manager. */ protected static function getAssociationMenuStorage() { return \Drupal::service('association_menu.storage'); } /** * {@inheritdoc} */ public function getFormId() { return 'association_menu_refresh_links_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form['entity_types'] = [ '#type' => 'checkboxes', '#title' => $this->t('Entity association content to refresh menu links for'), '#required' => TRUE, '#options' => [ 'association_page' => $this->t('Entity association page'), 'association_link' => $this->t('Entity association content'), ], '#default_value' => ['association_page', 'association_link'], ]; $form['actions'] = [ '#type' => 'actions', 'refresh' => [ '#type' => 'submit', '#value' => $this->t('Refresh Menu Links'), ], ]; return $form; } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $entityTypes = array_filter($form_state->getValue('entity_types')); $operations = []; foreach ($entityTypes as $type) { $operations[] = [ static::class . '::refreshMenuLinks', [$type], ]; } batch_set([ 'title' => $this->t('Refresh entity association menu links'), 'finished' => static::class . '::finishBatch', 'operations' => $operations, ]); } /** * Batch callback to update a single entity type's menu links. * * @param string $entity_type * The entity type to update the association content links for. * @param mixed $context * The current batch state and progress information. */ public static function refreshMenuLinks($entity_type, &$context = []) { $entityTypeManager = static::getEntityTypeManager(); $entityStorage = $entityTypeManager->getStorage($entity_type); $entityDef = $entityTypeManager->getDefinition($entity_type); $query = $entityStorage->getQuery()->accessCheck(FALSE); if (!isset($context['sandbox']['progress'])) { $countQuery = clone $query; $context['sandbox']['total'] = $countQuery->count()->execute(); $context['sandbox']['progress'] = 0; $context['sandbox']['current'] = 0; $context['results'][$entity_type] = 0; // If no entities to create links for, exit out. if (!$context['sandbox']['total']) { return; } } $entityKey = $entityDef->getKey('id'); $ids = $query ->condition($entityKey, $context['sandbox']['current'], '>') ->sort($entityKey, 'ASC') ->range(0, 50) ->execute(); if ($ids) { $menuStorage = static::getAssociationMenuStorage(); foreach ($entityStorage->loadMultiple($ids) as $entity) { // Only adds if the menu link doesn't already exist. Is safe to use // even if the menu link already exists and won't harm user edits. $menuStorage->addAssociated($entity); $context['sandbox']['current'] = $entity->id(); $context['sandbox']['progress']++; $context['results'][$entity_type]++; } // Update the overall batch process. if ($context['sandbox']['progress'] < $context['sandbox']['total']) { $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['total']; } } } /** * The batch finish call back for the association menu refresh task. * * @param bool $success * Did the batch complete successfully. * @param array $results * Results information from the processed operations. * @param array $operations * The remaining unprocessed operations if they did not all complete. */ public static function finishBatch($success, array $results, array $operations) { if ($success) { $total = 0; foreach ($results as $entityCount) { $total += $entityCount; } $msg = t('Refreshed and added @updated association page and content menu links.', [ '@updated' => $total, ]); \Drupal::messenger()->addStatus($msg); } else { $entityTypes = []; foreach ($operations as $op) { $entityTypes[] = reset($op[1]); } $error = t('Unable to update menu links for the follow content types: @types', [ '@types' => implode(', ', $entityTypes), ]); \Drupal::messenger()->addError($error); } } }