/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, CartInterface $cart = NULL) { $form['#attached']['library'][] = 'uc_cart/uc_cart.styles'; $cart_config = $this->config('uc_cart.settings'); $form['items'] = array('#type' => 'table', '#tree' => TRUE, '#header' => array('remove' => array('data' => $this->t('Remove'), 'class' => array('remove')), 'image' => array('data' => $this->t('Products'), 'class' => array('image')), 'desc' => array('data' => '', 'class' => array('desc')), 'qty' => array('data' => $this->t('Quantity'), 'class' => array('qty')), 'total' => array('data' => $this->t('Total'), 'class' => array('price')))); $form['data'] = array('#tree' => TRUE, '#parents' => array('items')); $i = 0; $subtotal = 0; foreach ($cart->getContents() as $cart_item) { $item = \Drupal::moduleHandler()->invoke($cart_item->data->module, 'uc_cart_display', array($cart_item)); if (Element::children($item)) { $form['items'][$i]['remove'] = $item['remove']; $form['items'][$i]['remove']['#name'] = 'remove-' . $i; $form['items'][$i]['image'] = uc_product_get_picture($item['nid']['#value'], 'uc_cart'); $form['items'][$i]['desc']['title'] = $item['title']; $form['items'][$i]['desc']['description'] = $item['description']; $form['items'][$i]['qty'] = $item['qty']; $form['items'][$i]['total'] = array('#theme' => 'uc_price', '#price' => $item['#total'], '#wrapper_attributes' => array('class' => 'total')); if (!empty($item['#suffixes'])) { $form['items'][$i]['total']['#suffixes'] = $item['#suffixes']; } $form['data'][$i]['module'] = $item['module']; $form['data'][$i]['nid'] = $item['nid']; $form['data'][$i]['data'] = $item['data']; $form['data'][$i]['title'] = array('#type' => 'value', '#value' => $item['title']['#markup']); $subtotal += $item['#total']; } $i++; } $form['items'][]['total'] = array('#theme' => 'uc_price', '#prefix' => '<span id="subtotal-title">' . $this->t('Subtotal') . ':</span> ', '#price' => $subtotal, '#wrapper_attributes' => array('colspan' => 5, 'class' => array('subtotal'))); $form['actions'] = array('#type' => 'actions'); // If the continue shopping element is enabled... if (($cs_type = $cart_config->get('continue_shopping_type')) !== 'none') { // Add the element to the form based on the element type. if ($cart_config->get('continue_shopping_type') == 'link') { $form['actions']['continue_shopping'] = array('#markup' => $this->l($this->t('Continue shopping'), Url::fromUri('internal:' . $this->continueShoppingUrl()))); } elseif ($cart_config->get('continue_shopping_type') == 'button') { $form['actions']['continue_shopping'] = array('#type' => 'submit', '#value' => $this->t('Continue shopping'), '#submit' => array(array($this, 'submitForm'), array($this, 'continueShopping'))); } } // Add the empty cart button if enabled. if ($cart_config->get('empty_button')) { $form['actions']['empty'] = array('#type' => 'submit', '#value' => $this->t('Empty cart'), '#submit' => array(array($this, 'emptyCart'))); } // Add the control buttons for updating and proceeding to checkout. $form['actions']['update'] = array('#type' => 'submit', '#name' => 'update-cart', '#value' => $this->t('Update cart'), '#submit' => array(array($this, 'submitForm'), array($this, 'displayUpdateMessage'))); $form['actions']['checkout'] = array('#theme' => 'uc_cart_checkout_buttons'); if ($cart_config->get('checkout_enabled')) { $form['actions']['checkout']['checkout'] = array('#type' => 'submit', '#value' => $this->t('Checkout'), '#button_type' => 'primary', '#submit' => array(array($this, 'submitForm'), array($this, 'checkout'))); } $this->renderer->addCacheableDependency($form, $cart); $this->renderer->addCacheableDependency($form, $cart_config); return $form; }
/** * Displays add links for the available bundles. * * Redirects to the add form if there's only one bundle available. * * @param string $entity_type_id * The entity type ID. * @param \Symfony\Component\HttpFoundation\Request $request * The request. * * @return \Symfony\Component\HttpFoundation\RedirectResponse|array * If there's only one available bundle, a redirect response. * Otherwise, a render array with the add links for each bundle. */ public function addPage($entity_type_id, Request $request) { $entity_type = $this->entityTypeManager()->getDefinition($entity_type_id); $bundle_type = $entity_type->getBundleEntityType(); $bundle_key = $entity_type->getKey('bundle'); $form_route_name = 'entity.' . $entity_type_id . '.add_form'; $build = ['#theme' => 'entity_add_list', '#cache' => ['tags' => $entity_type->getListCacheTags()], '#bundle_type' => $bundle_type]; $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id); // Filter out the bundles the user doesn't have access to. $access_control_handler = $this->entityTypeManager()->getAccessControlHandler($bundle_type); foreach ($bundles as $bundle_name => $bundle_info) { $access = $access_control_handler->createAccess($bundle_name, NULL, [], TRUE); if (!$access->isAllowed()) { unset($bundles[$bundle_name]); } $this->renderer->addCacheableDependency($build, $access); } // Redirect if there's only one bundle available. if (count($bundles) == 1) { $bundle_names = array_keys($bundles); $bundle_name = reset($bundle_names); return $this->redirect($form_route_name, [$bundle_key => $bundle_name]); } // Prepare the #bundles array for the template. $bundles = $this->loadBundleDescriptions($bundles, $bundle_type); foreach ($bundles as $bundle_name => $bundle_info) { $build['#bundles'][$bundle_name] = ['label' => $bundle_info['label'], 'description' => $bundle_info['description'], 'add_link' => Link::createFromRoute($bundle_info['label'], $form_route_name, [$bundle_key => $bundle_name])]; } return $build; }
/** * {@inheritdoc} */ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) { if ($entity->status()) { $message = $this->contactMessageStorage->create([ 'contact_form' => $entity->id(), ]); $form = $this->entityFormBuilder->getForm($message); $form['#title'] = $entity->label(); $form['#cache']['contexts'][] = 'user.permissions'; $this->renderer->addCacheableDependency($form, $this->config); } else { // Form disabled, display a custom message using a template. $form['disabled_form_error'] = array( '#theme' => 'contact_storage_disabled_form', '#contact_form' => $entity, '#redirect_uri' => $entity->getThirdPartySetting('contact_storage', 'redirect_uri', ''), '#disabled_form_message' => $entity->getThirdPartySetting('contact_storage', 'disabled_form_message', t('This contact form has been disabled.')), ); } // Add required cacheability metadata from the contact form entity, so that // changing it invalidates the cache. $this->renderer->addCacheableDependency($form, $entity); return $form; }
/** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = []; $media = $this->getEntitiesToView($items, $langcode); // Early opt-out if the field is empty. if (empty($media)) { return $elements; } $url = NULL; $image_link_setting = $this->getSetting('image_link'); // Check if the formatter involves a link. if ($image_link_setting == 'content') { $entity = $items->getEntity(); if (!$entity->isNew()) { $url = $entity->urlInfo(); } } elseif ($image_link_setting == 'media') { $link_media = TRUE; } $image_style_setting = $this->getSetting('image_style'); foreach ($media as $delta => $media_item) { if (isset($link_media)) { $url = $media_item->url(); } $elements[$delta] = ['#theme' => 'image_formatter', '#item' => $media_item->get('thumbnail'), '#item_attributes' => [], '#image_style' => $image_style_setting, '#url' => $url]; // Collect cache tags to be added for each item in the field. $this->renderer->addCacheableDependency($elements[$delta], $media_item); } // Collect cache tags related to the image style setting. $image_style = $this->imageStyleStorage->load($image_style_setting); $this->renderer->addCacheableDependency($elements, $image_style); return $elements; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $args = array()) { /* @var $search_api_page \Drupal\search_api_page\SearchApiPageInterface */ $search_api_page = SearchApiPage::load($args['search_api_page']); $route = 'search_api_page.' . $this->languageManager->getCurrentLanguage()->getId() . '.' . $search_api_page->id(); $form['#action'] = $this->getUrlGenerator()->generateFromRoute($route); $form['search_api_page'] = array('#type' => 'value', '#value' => $search_api_page->id()); $form['keys'] = array('#type' => 'search', '#title' => $this->t('Search'), '#title_display' => 'invisible', '#size' => 15, '#default_value' => isset($args['keys']) ? $args['keys'] : '', '#attributes' => array('title' => $this->t('Enter the terms you wish to search for.'))); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Search')); if (!$search_api_page->getCleanUrl()) { $form['#method'] = 'get'; $form['actions']['submit']['#name'] = ''; } // Dependency on search api config entity. $this->renderer->addCacheableDependency($form, $search_api_page->getConfigDependencyName()); return $form; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { // Set up the form to submit using GET to the correct search page. $entity_id = $this->searchPageRepository->getDefaultSearchPage(); if (!$entity_id) { $form['message'] = array('#markup' => $this->t('Search is currently disabled')); return $form; } $route = 'search.view_' . $entity_id; $form['#action'] = $this->url($route); $form['#method'] = 'get'; $form['keys'] = array('#type' => 'search', '#title' => $this->t('Search'), '#title_display' => 'invisible', '#size' => 15, '#default_value' => '', '#attributes' => array('title' => $this->t('Enter the terms you wish to search for.'))); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Search'), '#name' => ''); // SearchPageRepository::getDefaultSearchPage() depends on search.settings. $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings')); return $form; }
/** * {@inheritdoc} */ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) { $message = $this->contactMessageStorage->create(['contact_form' => $entity->id()]); $form = $this->entityFormBuilder->getForm($message); $form['#title'] = $entity->label(); $form['#cache']['contexts'][] = 'user.permissions'; $this->renderer->addCacheableDependency($form, $this->config); return $form; }
/** * Generates an overview table of older revisions of a node. * * @param \Drupal\node\NodeInterface $node * A node object. * * @return array * An array as expected by drupal_render(). */ public function revisionOverview(NodeInterface $node) { $account = $this->currentUser(); $langcode = $node->language()->getId(); $langname = $node->language()->getName(); $languages = $node->getTranslationLanguages(); $has_translations = count($languages) > 1; $node_storage = $this->entityManager()->getStorage('node'); $type = $node->getType(); $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]); $header = array($this->t('Revision'), $this->t('Operations')); $revert_permission = ($account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update'); $delete_permission = ($account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete'); $rows = array(); $vids = $node_storage->revisionIds($node); $latest_revision = TRUE; foreach (array_reverse($vids) as $vid) { /** @var \Drupal\node\NodeInterface $revision */ $revision = $node_storage->loadRevision($vid); // Only show revisions that are affected by the language that is being // displayed. if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { $username = ['#theme' => 'username', '#account' => $revision->getRevisionAuthor()]; // Use revision link to link to revisions that are not active. $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short'); if ($vid != $node->getRevisionId()) { $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); } else { $link = $node->link($date); } $row = []; $column = ['data' => ['#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()]]]]; // @todo Simplify once https://www.drupal.org/node/2334319 lands. $this->renderer->addCacheableDependency($column['data'], $username); $row[] = $column; if ($latest_revision) { $row[] = ['data' => ['#prefix' => '<em>', '#markup' => $this->t('Current revision'), '#suffix' => '</em>']]; foreach ($row as &$current) { $current['class'] = ['revision-current']; } $latest_revision = FALSE; } else { $links = []; if ($revert_permission) { $links['revert'] = ['title' => $this->t('Revert'), 'url' => $has_translations ? Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) : Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } if ($delete_permission) { $links['delete'] = ['title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } $row[] = ['data' => ['#type' => 'operations', '#links' => $links]]; } $rows[] = $row; } } $build['node_revisions_table'] = array('#theme' => 'table', '#rows' => $rows, '#header' => $header, '#attached' => array('library' => array('node/drupal.node.admin'))); return $build; }
/** * Returns a renderable forum index page array. * * @param array $forums * A list of forums. * @param \Drupal\taxonomy\TermInterface $term * The taxonomy term of the forum. * @param array $topics * The topics of this forum. * @param array $parents * The parent forums in relation this forum. * @param array $header * Array of header cells. * * @return array * A render array. */ protected function build($forums, TermInterface $term, $topics = array(), $parents = array(), $header = array()) { $config = $this->config('forum.settings'); $build = array('#theme' => 'forums', '#forums' => $forums, '#topics' => $topics, '#parents' => $parents, '#header' => $header, '#term' => $term, '#sortby' => $config->get('topics.order'), '#forums_per_page' => $config->get('topics.page_limit')); $build['#attached']['library'][] = 'forum/forum.index'; if (empty($term->forum_container->value)) { $build['#attached']['feed'][] = array('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->getName()); } $this->renderer->addCacheableDependency($build, $config); return ['action' => $this->buildActionLinks($config->get('vocabulary'), $term), 'forum' => $build]; }
/** * Presents the site-wide contact form. * * @param \Drupal\contact\ContactFormInterface $contact_form * The contact form to use. * * @return array * The form as render array as expected by drupal_render(). * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException * Exception is thrown when user tries to access non existing default * contact form. */ public function contactSitePage(ContactFormInterface $contact_form = NULL) { $config = $this->config('contact.settings'); // Use the default form if no form has been passed. if (empty($contact_form)) { $contact_form = $this->entityManager()->getStorage('contact_form')->load($config->get('default_form')); // If there are no forms, do not display the form. if (empty($contact_form)) { if ($this->currentUser()->hasPermission('administer contact forms')) { drupal_set_message($this->t('The contact form has not been configured. <a href="@add">Add one or more forms</a> .', array('@add' => $this->url('contact.form_add'))), 'error'); return array(); } else { throw new NotFoundHttpException(); } } } $message = $this->entityManager()->getStorage('contact_message')->create(array('contact_form' => $contact_form->id())); $form = $this->entityFormBuilder()->getForm($message); $form['#title'] = SafeMarkup::checkPlain($contact_form->label()); $form['#cache']['contexts'][] = 'user.permissions'; $this->renderer->addCacheableDependency($form, $config); return $form; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('system.site'); // Display login form: $form['name'] = array('#type' => 'textfield', '#title' => $this->t('Username'), '#size' => 60, '#maxlength' => USERNAME_MAX_LENGTH, '#description' => $this->t('Enter your @s username.', array('@s' => $config->get('name'))), '#required' => TRUE, '#attributes' => array('autocorrect' => 'none', 'autocapitalize' => 'none', 'spellcheck' => 'false', 'autofocus' => 'autofocus')); $form['pass'] = array('#type' => 'password', '#title' => $this->t('Password'), '#size' => 60, '#description' => $this->t('Enter the password that accompanies your username.'), '#required' => TRUE); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Log in')); $form['#validate'][] = '::validateName'; $form['#validate'][] = '::validateAuthentication'; $form['#validate'][] = '::validateFinal'; $this->renderer->addCacheableDependency($form, $config); return $form; }
/** * Shows permission-dependent content. * * @return array * A render array. */ public function permissionDependentContent() { $build = []; // The content depends on the access result. $access = AccessResult::allowedIfHasPermission($this->currentUser, 'pet llamas'); $this->renderer->addCacheableDependency($build, $access); // Build the content. if ($access->isAllowed()) { $build['allowed'] = ['#markup' => 'Permission to pet llamas: yes!']; } else { $build['forbidden'] = ['#markup' => 'Permission to pet llamas: no!']; } return $build; }
/** * Creates a render array for the search page. * * @param \Symfony\Component\HttpFoundation\Request $request * The request object. * @param \Drupal\search\SearchPageInterface $entity * The search page entity. * * @return array * The search form and search results build array. */ public function view(Request $request, SearchPageInterface $entity) { $build = array(); $plugin = $entity->getPlugin(); // Build the form first, because it may redirect during the submit, // and we don't want to build the results based on last time's request. $build['#cache']['contexts'][] = 'url.query_args:keys'; if ($request->query->has('keys')) { $keys = trim($request->query->get('keys')); $plugin->setSearch($keys, $request->query->all(), $request->attributes->all()); } $build['#title'] = $plugin->suggestedTitle(); $build['search_form'] = $this->entityFormBuilder()->getForm($entity, 'search'); // Build search results, if keywords or other search parameters are in the // GET parameters. Note that we need to try the search if 'keys' is in // there at all, vs. being empty, due to advanced search. $results = array(); if ($request->query->has('keys')) { if ($plugin->isSearchExecutable()) { // Log the search. if ($this->config('search.settings')->get('logging')) { $this->logger->notice('Searched %type for %keys.', array('%keys' => $keys, '%type' => $entity->label())); } // Collect the search results. $results = $plugin->buildResults(); } else { // The search not being executable means that no keywords or other // conditions were entered. drupal_set_message($this->t('Please enter some keywords.'), 'error'); } } if (count($results)) { $build['search_results_title'] = array('#markup' => '<h2>' . $this->t('Search results') . '</h2>'); } $build['search_results'] = array('#theme' => array('item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'), '#items' => $results, '#empty' => array('#markup' => '<h3>' . $this->t('Your search yielded no results.') . '</h3>'), '#list_type' => 'ol', '#context' => array('plugin' => $plugin->getPluginId())); $this->renderer->addCacheableDependency($build, $entity); if ($plugin instanceof CacheableDependencyInterface) { $this->renderer->addCacheableDependency($build, $plugin); } // If this plugin uses a search index, then also add the cache tag tracking // that search index, so that cached search result pages are invalidated // when necessary. if ($plugin->getType()) { $build['search_results']['#cache']['tags'][] = 'search_index'; $build['search_results']['#cache']['tags'][] = 'search_index:' . $plugin->getType(); } $build['pager'] = array('#type' => 'pager'); return $build; }
/** * Generates an overview table of older revisions of a node. * * @param \Drupal\node\NodeInterface $node * A node object. * * @return array * An array as expected by drupal_render(). */ public function revisionOverview(NodeInterface $node) { $account = $this->currentUser(); $node_storage = $this->entityManager()->getStorage('node'); $type = $node->getType(); $build = array(); $build['#title'] = $this->t('Revisions for %title', array('%title' => $node->label())); $header = array($this->t('Revision'), $this->t('Operations')); $revert_permission = ($account->hasPermission("revert {$type} revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update'); $delete_permission = ($account->hasPermission("delete {$type} revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete'); $rows = array(); $vids = $node_storage->revisionIds($node); foreach (array_reverse($vids) as $vid) { $revision = $node_storage->loadRevision($vid); $username = ['#theme' => 'username', '#account' => $revision->uid->entity]; // Use revision link to link to revisions that are not active. $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short'); if ($vid != $node->getRevisionId()) { $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); } else { $link = $node->link($date); } $row = []; $column = ['data' => ['#type' => 'inline_template', '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', '#context' => ['date' => $link, 'username' => $this->renderer->renderPlain($username), 'message' => Xss::filter($revision->revision_log->value)]]]; // @todo Simplify once https://www.drupal.org/node/2334319 lands. $this->renderer->addCacheableDependency($column['data'], $username); $row[] = $column; if ($vid == $node->getRevisionId()) { $row[0]['class'] = ['revision-current']; $row[] = ['data' => SafeMarkup::placeholder($this->t('current revision')), 'class' => ['revision-current']]; } else { $links = []; if ($revert_permission) { $links['revert'] = ['title' => $this->t('Revert'), 'url' => Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } if ($delete_permission) { $links['delete'] = ['title' => $this->t('Delete'), 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid])]; } $row[] = ['data' => ['#type' => 'operations', '#links' => $links]]; } $rows[] = $row; } $build['node_revisions_table'] = array('#theme' => 'table', '#rows' => $rows, '#header' => $header, '#attached' => array('library' => array('node/drupal.node.admin'))); return $build; }
/** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = array(); $entity = current($this->getEntitiesToView($items, $langcode)); if ($entity) { if ($entity->id()) { // @see \Drupal\contact\Controller\ContactController::contactSitePage(). $config = $this->configFactory->get('contact.settings')->get(); $message = $this->entityManager->getStorage('contact_message')->create(array('contact_form' => $entity->id())); $form = $this->entityFormBuilder->getForm($message); $form['#title'] = $entity->label(); $form['#cache']['contexts'][] = 'user.permissions'; $this->renderer->addCacheableDependency($form, $config); $elements[] = $form; } } return $elements; }
/** * Displays add links for the available bundles. * * Redirects to the add form if there's only one bundle available. * * @param string $entity_type_id * The entity type ID. * * @return \Symfony\Component\HttpFoundation\RedirectResponse|array * If there's only one available bundle, a redirect response. * Otherwise, a render array with the add links for each bundle. */ public function addPage($entity_type_id) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id); $bundle_key = $entity_type->getKey('bundle'); $bundle_entity_type_id = $entity_type->getBundleEntityType(); $build = ['#theme' => 'entity_add_list', '#bundles' => []]; if ($bundle_entity_type_id) { $bundle_argument = $bundle_entity_type_id; $bundle_entity_type = $this->entityTypeManager->getDefinition($bundle_entity_type_id); $bundle_entity_type_label = $bundle_entity_type->getLowercaseLabel(); $build['#cache']['tags'] = $bundle_entity_type->getListCacheTags(); // Build the message shown when there are no bundles. $link_text = $this->t('Add a new @entity_type.', ['@entity_type' => $bundle_entity_type_label]); $link_route_name = 'entity.' . $bundle_entity_type->id() . '.add_form'; $build['#add_bundle_message'] = $this->t('There is no @entity_type yet. @add_link', ['@entity_type' => $bundle_entity_type_label, '@add_link' => Link::createFromRoute($link_text, $link_route_name)->toString()]); // Filter out the bundles the user doesn't have access to. $access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type_id); foreach ($bundles as $bundle_name => $bundle_info) { $access = $access_control_handler->createAccess($bundle_name, NULL, [], TRUE); if (!$access->isAllowed()) { unset($bundles[$bundle_name]); } $this->renderer->addCacheableDependency($build, $access); } // Add descriptions from the bundle entities. $bundles = $this->loadBundleDescriptions($bundles, $bundle_entity_type); } else { $bundle_argument = $bundle_key; } $form_route_name = 'entity.' . $entity_type_id . '.add_form'; // Redirect if there's only one bundle available. if (count($bundles) == 1) { $bundle_names = array_keys($bundles); $bundle_name = reset($bundle_names); return $this->redirect($form_route_name, [$bundle_argument => $bundle_name]); } // Prepare the #bundles array for the template. foreach ($bundles as $bundle_name => $bundle_info) { $build['#bundles'][$bundle_name] = ['label' => $bundle_info['label'], 'description' => isset($bundle_info['description']) ? $bundle_info['description'] : '', 'add_link' => Link::createFromRoute($bundle_info['label'], $form_route_name, [$bundle_argument => $bundle_name])]; } return $build; }
/** * Returns a renderable forum index page array. * * @param array $forums * A list of forums. * @param \Drupal\taxonomy\TermInterface $term * The taxonomy term of the forum. * @param array $topics * The topics of this forum. * @param array $parents * The parent forums in relation this forum. * @param array $header * Array of header cells. * * @return array * A render array. */ protected function build($forums, TermInterface $term, $topics = array(), $parents = array(), $header = array()) { $config = $this->config('forum.settings'); $build = array('#theme' => 'forums', '#forums' => $forums, '#topics' => $topics, '#parents' => $parents, '#header' => $header, '#term' => $term, '#sortby' => $config->get('topics.order'), '#forums_per_page' => $config->get('topics.page_limit')); if (empty($term->forum_container->value)) { $build['#attached']['feed'][] = array('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->getName()); } $this->renderer->addCacheableDependency($build, $config); foreach ($forums as $forum) { $this->renderer->addCacheableDependency($build, $forum); } foreach ($topics as $topic) { $this->renderer->addCacheableDependency($build, $topic); } foreach ($parents as $parent) { $this->renderer->addCacheableDependency($build, $parent); } $this->renderer->addCacheableDependency($build, $term); return ['action' => $this->buildActionLinks($config->get('vocabulary'), $term), 'forum' => $build, '#cache' => ['tags' => Cache::mergeTags($this->nodeEntityTypeDefinition->getListCacheTags(), $this->commentEntityTypeDefinition->getListCacheTags())]]; }
/** * {@inheritdoc} */ public function build() { $limit = 5; $items = array(); $build = array(); $nids = $this->entityQuery->get('node')->range(0, $limit)->condition('status', 1)->sort('created', 'DESC')->execute(); // Quick and dirty exit if no content was created. if (empty($nids)) { return 'Bummer, you have no content yet.'; } // Build node links and collect the cache metadata. /** @var \Drupal\node\Entity\Node[] $nodes */ $nodes = $this->entityTypeManager->getStorage('node')->loadMultiple($nids); foreach ($nodes as $node) { $items[] = $node->link(); $this->renderer->addCacheableDependency($build, $node); } // Adding a Cache tag allows cache invalidation when content is added. // @see cacheit_entity_insert() $build['recent_content'] = array('#theme' => 'item_list', '#items' => $items, '#cache' => ['tags' => ['cacheit_recent_content']]); return $build; }
/** * Builds the parent selection form element for the node form or outline tab. * * This function is also called when generating a new set of options during * the Ajax callback, so an array is returned that can be used to replace an * existing form element. * * @param array $book_link * A fully loaded book link that is part of the book hierarchy. * * @return array * A parent selection form element. */ protected function addParentSelectFormElements(array $book_link) { $config = $this->configFactory->get('book.settings'); if ($config->get('override_parent_selector')) { return array(); } // Offer a message or a drop-down to choose a different parent page. $form = array('#type' => 'hidden', '#value' => -1, '#prefix' => '<div id="edit-book-plid-wrapper">', '#suffix' => '</div>'); if ($book_link['nid'] === $book_link['bid']) { // This is a book - at the top level. if ($book_link['original_bid'] === $book_link['bid']) { $form['#prefix'] .= '<em>' . $this->t('This is the top-level page in this book.') . '</em>'; } else { $form['#prefix'] .= '<em>' . $this->t('This will be the top-level page in this book.') . '</em>'; } } elseif (!$book_link['bid']) { $form['#prefix'] .= '<em>' . $this->t('No book selected.') . '</em>'; } else { $form = array('#type' => 'select', '#title' => $this->t('Parent item'), '#default_value' => $book_link['pid'], '#description' => $this->t('The parent page in the book. The maximum depth for a book and all child pages is @maxdepth. Some pages in the selected book may not be available as parents if selecting them would exceed this limit.', array('@maxdepth' => static::BOOK_MAX_DEPTH)), '#options' => $this->getTableOfContents($book_link['bid'], $book_link['parent_depth_limit'], array($book_link['nid'])), '#attributes' => array('class' => array('book-title-select')), '#prefix' => '<div id="edit-book-plid-wrapper">', '#suffix' => '</div>'); } $this->renderer->addCacheableDependency($form, $config); return $form; }
/** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { /** @var \Drupal\comment\CommentInterface $comment */ $comment = $this->entity; $entity = $this->entityManager->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId()); $field_name = $comment->getFieldName(); $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; $config = $this->config('user.settings'); // In several places within this function, we vary $form on: // - The current user's permissions. // - Whether the current user is authenticated or anonymous. // - The 'user.settings' configuration. // - The comment field's definition. $form['#cache']['contexts'][] = 'user.permissions'; $form['#cache']['contexts'][] = 'user.roles:authenticated'; $this->renderer->addCacheableDependency($form, $config); $this->renderer->addCacheableDependency($form, $field_definition->getConfig($entity->bundle())); // Use #comment-form as unique jump target, regardless of entity type. $form['#id'] = Html::getUniqueId('comment_form'); $form['#theme'] = array('comment_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name, 'comment_form'); $anonymous_contact = $field_definition->getSetting('anonymous'); $is_admin = $comment->id() && $this->currentUser->hasPermission('administer comments'); if (!$this->currentUser->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) { $form['#attached']['library'][] = 'core/drupal.form'; $form['#attributes']['data-user-info-from-browser'] = TRUE; } // If not replying to a comment, use our dedicated page callback for new // Comments on entities. if (!$comment->id() && !$comment->hasParentComment()) { $form['#action'] = $this->url('comment.reply', array('entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name)); } $comment_preview = $form_state->get('comment_preview'); if (isset($comment_preview)) { $form += $comment_preview; } $form['author'] = array(); // Display author information in a details element for comment moderators. if ($is_admin) { $form['author'] += array('#type' => 'details', '#title' => $this->t('Administration')); } // Prepare default values for form elements. $author = ''; if ($is_admin) { if (!$comment->getOwnerId()) { $author = $comment->getAuthorName(); } $status = $comment->getStatus(); if (empty($comment_preview)) { $form['#title'] = $this->t('Edit comment %title', array('%title' => $comment->getSubject())); } } else { $status = $this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED; } $date = ''; if ($comment->id()) { $date = !empty($comment->date) ? $comment->date : DrupalDateTime::createFromTimestamp($comment->getCreatedTime()); } // The uid field is only displayed when a user with the permission // 'administer comments' is editing an existing comment from an // authenticated user. $owner = $comment->getOwner(); $form['author']['uid'] = ['#type' => 'entity_autocomplete', '#target_type' => 'user', '#default_value' => $owner->isAnonymous() ? NULL : $owner, '#selection_settings' => ['include_anonymous' => FALSE], '#title' => $this->t('Authored by'), '#description' => $this->t('Leave blank for %anonymous.', ['%anonymous' => $config->get('anonymous')]), '#access' => $is_admin]; // The name field is displayed when an anonymous user is adding a comment or // when a user with the permission 'administer comments' is editing an // existing comment from an anonymous user. $form['author']['name'] = array('#type' => 'textfield', '#title' => $is_admin ? $this->t('Name for @anonymous', ['@anonymous' => $config->get('anonymous')]) : $this->t('Your name'), '#default_value' => $author, '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 60, '#access' => $this->currentUser->isAnonymous() || $is_admin, '#size' => 30, '#attributes' => ['data-drupal-default-value' => $config->get('anonymous')]); if ($is_admin) { // When editing a comment only display the name textfield if the uid field // is empty. $form['author']['name']['#states'] = ['visible' => [':input[name="uid"]' => array('empty' => TRUE)]]; } // Add author email and homepage fields depending on the current user. $form['author']['mail'] = array('#type' => 'email', '#title' => $this->t('Email'), '#default_value' => $comment->getAuthorEmail(), '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 64, '#size' => 30, '#description' => $this->t('The content of this field is kept private and will not be shown publicly.'), '#access' => $comment->getOwner()->isAnonymous() && $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); $form['author']['homepage'] = array('#type' => 'url', '#title' => $this->t('Homepage'), '#default_value' => $comment->getHomepage(), '#maxlength' => 255, '#size' => 30, '#access' => $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); // Add administrative comment publishing options. $form['author']['date'] = array('#type' => 'datetime', '#title' => $this->t('Authored on'), '#default_value' => $date, '#size' => 20, '#access' => $is_admin); $form['author']['status'] = array('#type' => 'radios', '#title' => $this->t('Status'), '#default_value' => $status, '#options' => array(CommentInterface::PUBLISHED => $this->t('Published'), CommentInterface::NOT_PUBLISHED => $this->t('Not published')), '#access' => $is_admin); return parent::form($form, $form_state, $comment); }
/** * Overrides Drupal\Core\Entity\EntityForm::form(). */ public function form(array $form, FormStateInterface $form_state) { /** @var \Drupal\comment\CommentInterface $comment */ $comment = $this->entity; $entity = $this->entityManager->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId()); $field_name = $comment->getFieldName(); $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; $config = $this->config('user.settings'); // Use #comment-form as unique jump target, regardless of entity type. $form['#id'] = Html::getUniqueId('comment_form'); $form['#theme'] = array('comment_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name, 'comment_form'); $anonymous_contact = $field_definition->getSetting('anonymous'); $is_admin = $comment->id() && $this->currentUser->hasPermission('administer comments'); if (!$this->currentUser->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) { $form['#attached']['library'][] = 'core/drupal.form'; $form['#attributes']['data-user-info-from-browser'] = TRUE; } // Vary per role, because we check a permission above and attach an asset // library only for authenticated users. $form['#cache']['contexts'][] = 'user.roles'; // If not replying to a comment, use our dedicated page callback for new // Comments on entities. if (!$comment->id() && !$comment->hasParentComment()) { $form['#action'] = $this->url('comment.reply', array('entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name)); } $comment_preview = $form_state->get('comment_preview'); if (isset($comment_preview)) { $form += $comment_preview; } $form['author'] = array(); // Display author information in a details element for comment moderators. if ($is_admin) { $form['author'] += array('#type' => 'details', '#title' => $this->t('Administration')); } // Prepare default values for form elements. if ($is_admin) { $author = $comment->getAuthorName(); $status = $comment->getStatus(); if (empty($comment_preview)) { $form['#title'] = $this->t('Edit comment %title', array('%title' => $comment->getSubject())); } } else { if ($this->currentUser->isAuthenticated()) { $author = $this->currentUser->getUsername(); } else { $author = $comment->getAuthorName() ? $comment->getAuthorName() : ''; } $status = $this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED; } $date = ''; if ($comment->id()) { $date = !empty($comment->date) ? $comment->date : DrupalDateTime::createFromTimestamp($comment->getCreatedTime()); } // Add the author name field depending on the current user. $form['author']['name'] = array('#type' => 'textfield', '#title' => $this->t('Your name'), '#default_value' => $author, '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 60, '#size' => 30); if ($is_admin) { $form['author']['name']['#type'] = 'entity_autocomplete'; $form['author']['name']['#target_type'] = 'user'; $form['author']['name']['#selection_settings'] = ['include_anonymous' => FALSE]; $form['author']['name']['#process_default_value'] = FALSE; // The user name is validated and processed in static::buildEntity() and // static::validate(). $form['author']['name']['#element_validate'] = array(); $form['author']['name']['#title'] = $this->t('Authored by'); $form['author']['name']['#description'] = $this->t('Leave blank for %anonymous.', array('%anonymous' => $config->get('anonymous'))); } elseif ($this->currentUser->isAuthenticated()) { $form['author']['name']['#type'] = 'item'; $form['author']['name']['#value'] = $form['author']['name']['#default_value']; $form['author']['name']['#theme'] = 'username'; $form['author']['name']['#account'] = $this->currentUser; } elseif ($this->currentUser->isAnonymous()) { $form['author']['name']['#attributes']['data-drupal-default-value'] = $config->get('anonymous'); } // Add author email and homepage fields depending on the current user. $form['author']['mail'] = array('#type' => 'email', '#title' => $this->t('Email'), '#default_value' => $comment->getAuthorEmail(), '#required' => $this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT, '#maxlength' => 64, '#size' => 30, '#description' => $this->t('The content of this field is kept private and will not be shown publicly.'), '#access' => $comment->getOwner()->isAnonymous() && $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); $form['author']['homepage'] = array('#type' => 'url', '#title' => $this->t('Homepage'), '#default_value' => $comment->getHomepage(), '#maxlength' => 255, '#size' => 30, '#access' => $is_admin || $this->currentUser->isAnonymous() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT); // Add administrative comment publishing options. $form['author']['date'] = array('#type' => 'datetime', '#title' => $this->t('Authored on'), '#default_value' => $date, '#size' => 20, '#access' => $is_admin); $form['author']['status'] = array('#type' => 'radios', '#title' => $this->t('Status'), '#default_value' => $status, '#options' => array(CommentInterface::PUBLISHED => $this->t('Published'), CommentInterface::NOT_PUBLISHED => $this->t('Not published')), '#access' => $is_admin); $this->renderer->addCacheableDependency($form, $config); // The form depends on the field definition. $this->renderer->addCacheableDependency($form, $field_definition->getConfig($entity->bundle())); return parent::form($form, $form_state, $comment); }