/**
  * {@inheritdoc}
  */
 public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL)
 {
     /** @var \Drupal\tour\TourInterface[] $entities */
     $build = array();
     foreach ($entities as $entity_id => $entity) {
         $tips = $entity->getTips();
         $count = count($tips);
         $list_items = array();
         foreach ($tips as $index => $tip) {
             if ($output = $tip->getOutput()) {
                 $attributes = array('class' => array('tip-module-' . Html::cleanCssIdentifier($entity->getModule()), 'tip-type-' . Html::cleanCssIdentifier($tip->getPluginId()), 'tip-' . Html::cleanCssIdentifier($tip->id())));
                 $list_items[] = array('output' => $output, 'counter' => array('#type' => 'container', '#attributes' => array('class' => array('tour-progress')), '#children' => t('@tour_item of @total', array('@tour_item' => $index + 1, '@total' => $count))), '#wrapper_attributes' => $tip->getAttributes() + $attributes);
             }
         }
         // If there is at least one tour item, build the tour.
         if ($list_items) {
             end($list_items);
             $key = key($list_items);
             $list_items[$key]['#wrapper_attributes']['data-text'] = t('End tour');
             $build[$entity_id] = array('#theme' => 'item_list', '#items' => $list_items, '#list_type' => 'ol', '#attributes' => array('id' => 'tour', 'class' => array('hidden')), '#cache' => ['tags' => $entity->getCacheTags()]);
         }
     }
     // If at least one tour was built, attach the tour library.
     if ($build) {
         $build['#attached']['library'][] = 'tour/tour';
     }
     return $build;
 }
 /**
  * {@inheritdoc}
  */
 public function view(FieldItemListInterface $items, $langcode = NULL)
 {
     $elements = parent::view($items, $langcode);
     $gallery_type = $this->getSetting('gallery_type');
     $elements['#attributes']['class'][] = 'mfp-field';
     $elements['#attributes']['class'][] = 'mfp-video-embed-' . Html::cleanCssIdentifier($gallery_type);
     return $elements;
 }
Example #3
0
 /**
  * Tests the Html::cleanCssIdentifier() method.
  *
  * @param string $expected
  *   The expected result.
  * @param string $source
  *   The string being transformed to an ID.
  * @param array|null $filter
  *   (optional) An array of string replacements to use on the identifier. If
  *   NULL, no filter will be passed and a default will be used.
  *
  * @dataProvider providerTestCleanCssIdentifier
  *
  * @covers ::cleanCssIdentifier
  */
 public function testCleanCssIdentifier($expected, $source, $filter = NULL)
 {
     if ($filter !== NULL) {
         $this->assertSame($expected, Html::cleanCssIdentifier($source, $filter));
     } else {
         $this->assertSame($expected, Html::cleanCssIdentifier($source));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function alterForm(array &$form, FormStateInterface $form_state, $form_id = NULL)
 {
     $plugin_id = Html::cleanCssIdentifier($this->provider->getPluginId());
     $setting = $this->getElement($form, $form_state);
     $setting->setProperty('options', $this->provider->getVersions());
     $setting->setProperty('ajax', ['callback' => [get_class($this), 'ajaxCallback'], 'wrapper' => 'cdn-provider-' . $plugin_id]);
     if (!$this->provider->hasError() && !$this->provider->isImported()) {
         $setting->setProperty('description', t('These versions are automatically populated by the @provider API upon cache clear and newer versions may appear over time. It is highly recommended the version that the site was built with stays at that version. Until a newer version has been properly tested for updatability by the site maintainer, you should not arbitrarily "update" just because there is a newer version. This can cause many inconsistencies and undesired effects with an existing site.', ['@provider' => $this->provider->getLabel()]));
     }
 }
Example #5
0
 /**
  * Return the token-replaced row or column classes for the specified result.
  *
  * @param int $result_index
  *   The delta of the result item to get custom classes for.
  * @param string $type
  *   The type of custom grid class to return, either "row" or "col".
  *
  * @return string
  *   A space-delimited string of classes.
  */
 public function getCustomClass($result_index, $type)
 {
     $class = $this->options[$type . '_class_custom'];
     if ($this->usesFields() && $this->view->field) {
         $class = strip_tags($this->tokenizeValue($class, $result_index));
     }
     $classes = explode(' ', $class);
     foreach ($classes as &$class) {
         $class = Html::cleanCssIdentifier($class);
     }
     return implode(' ', $classes);
 }
Example #6
0
 /**
  * Tests upload and remove buttons for a single-valued File field.
  */
 function testSingleValuedWidget()
 {
     $node_storage = $this->container->get('entity.manager')->getStorage('node');
     $type_name = 'article';
     $field_name = strtolower($this->randomMachineName());
     $this->createFileField($field_name, 'node', $type_name);
     $test_file = $this->getTestFile('text');
     foreach (array('nojs', 'js') as $type) {
         // Create a new node with the uploaded file and ensure it got uploaded
         // successfully.
         // @todo This only tests a 'nojs' submission, because drupalPostAjaxForm()
         //   does not yet support file uploads.
         $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
         $node_storage->resetCache(array($nid));
         $node = $node_storage->load($nid);
         $node_file = file_load($node->{$field_name}->target_id);
         $this->assertFileExists($node_file, 'New file saved to disk on node creation.');
         // Ensure the file can be downloaded.
         $this->drupalGet(file_create_url($node_file->getFileUri()));
         $this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
         // Ensure the edit page has a remove button instead of an upload button.
         $this->drupalGet("node/{$nid}/edit");
         $this->assertNoFieldByXPath('//input[@type="submit"]', t('Upload'), 'Node with file does not display the "Upload" button.');
         $this->assertFieldByXpath('//input[@type="submit"]', t('Remove'), 'Node with file displays the "Remove" button.');
         // "Click" the remove button (emulating either a nojs or js submission).
         switch ($type) {
             case 'nojs':
                 $this->drupalPostForm(NULL, array(), t('Remove'));
                 break;
             case 'js':
                 $button = $this->xpath('//input[@type="submit" and @value="' . t('Remove') . '"]');
                 $this->drupalPostAjaxForm(NULL, array(), array((string) $button[0]['name'] => (string) $button[0]['value']));
                 break;
         }
         // Ensure the page now has an upload button instead of a remove button.
         $this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), 'After clicking the "Remove" button, it is no longer displayed.');
         $this->assertFieldByXpath('//input[@type="submit"]', t('Upload'), 'After clicking the "Remove" button, the "Upload" button is displayed.');
         // Test label has correct 'for' attribute.
         $label = $this->xpath("//label[@for='edit-" . Html::cleanCssIdentifier($field_name) . "-0-upload']");
         $this->assertTrue(isset($label[0]), 'Label for upload found.');
         // Save the node and ensure it does not have the file.
         $this->drupalPostForm(NULL, array(), t('Save and keep published'));
         $node_storage->resetCache(array($nid));
         $node = $node_storage->load($nid);
         $this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.');
     }
 }
Example #7
0
 /**
  * {@inheritdoc}
  */
 public function buildRow(EntityInterface $entity)
 {
     /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity */
     $row = parent::buildRow($entity);
     $status = $entity->status();
     $status_server = TRUE;
     $status_label = $status ? $this->t('Enabled') : $this->t('Disabled');
     if ($entity instanceof ServerInterface && $entity->status() && !$entity->isAvailable()) {
         $status = FALSE;
         $status_server = FALSE;
         $status_label = $this->t('Unavailable');
     }
     $status_icon = array('#theme' => 'image', '#uri' => $status ? 'core/misc/icons/73b355/check.svg' : 'core/misc/icons/e32700/error.svg', '#width' => 18, '#height' => 18, '#alt' => $status_label, '#title' => $status_label);
     $row = array('data' => array('type' => array('data' => $entity instanceof ServerInterface ? $this->t('Server') : $this->t('Index'), 'class' => array('search-api-type')), 'title' => array('data' => array('#type' => 'link', '#title' => $entity->label(), '#suffix' => '<div>' . $entity->get('description') . '</div>') + $entity->toUrl('canonical')->toRenderArray(), 'class' => array('search-api-title')), 'status' => array('data' => $status_icon, 'class' => array('checkbox')), 'operations' => $row['operations']), 'title' => $this->t('ID: @name', array('@name' => $entity->id())), 'class' => array(Html::cleanCssIdentifier($entity->getEntityTypeId() . '-' . $entity->id()), $status ? 'search-api-list-enabled' : 'search-api-list-disabled', $entity instanceof ServerInterface ? 'search-api-list-server' : 'search-api-list-index'));
     if (!$status_server) {
         $row['class'][] = 'color-error';
     }
     return $row;
 }
Example #8
0
 /**
  * {@inheritdoc}
  */
 public function form(array $form, FormStateInterface $form_state)
 {
     $form['#attached']['library'][] = 'facets/drupal.facets.admin_css';
     /** @var \Drupal\facets\FacetInterface $facet */
     $facet = $this->entity;
     $widget_options = [];
     foreach ($this->getWidgetPluginManager()->getDefinitions() as $widget_id => $definition) {
         $widget_options[$widget_id] = !empty($definition['label']) ? $definition['label'] : $widget_id;
     }
     $form['widget'] = ['#type' => 'radios', '#title' => $this->t('Widget'), '#description' => $this->t('The widget used for displaying this facet.'), '#options' => $widget_options, '#default_value' => $facet->getWidget(), '#required' => TRUE, '#ajax' => ['trigger_as' => ['name' => 'widget_configure'], 'callback' => '::buildAjaxWidgetConfigForm', 'wrapper' => 'facets-widget-config-form', 'method' => 'replace', 'effect' => 'fade']];
     $form['widget_configs'] = ['#type' => 'container', '#attributes' => ['id' => 'facets-widget-config-form'], '#tree' => TRUE];
     $form['widget_configure_button'] = ['#type' => 'submit', '#name' => 'widget_configure', '#value' => $this->t('Configure widget'), '#limit_validation_errors' => [['widget']], '#submit' => ['::submitAjaxWidgetConfigForm'], '#ajax' => ['callback' => '::buildAjaxWidgetConfigForm', 'wrapper' => 'facets-widget-config-form'], '#attributes' => ['class' => ['js-hide']]];
     $this->buildWidgetConfigForm($form, $form_state);
     // Retrieve lists of all processors, and the stages and weights they have.
     if (!$form_state->has('processors')) {
         $all_processors = $facet->getProcessors(FALSE);
         $sort_processors = function (ProcessorInterface $a, ProcessorInterface $b) {
             return strnatcasecmp((string) $a->getPluginDefinition()['label'], (string) $b->getPluginDefinition()['label']);
         };
         uasort($all_processors, $sort_processors);
     } else {
         $all_processors = $form_state->get('processors');
     }
     $enabled_processors = $facet->getProcessors(TRUE);
     $stages = $this->processorPluginManager->getProcessingStages();
     $processors_by_stage = array();
     foreach ($stages as $stage => $definition) {
         $processors_by_stage[$stage] = $facet->getProcessorsByStage($stage, FALSE);
     }
     $form['#tree'] = TRUE;
     $form['#attached']['library'][] = 'facets/drupal.facets.index-active-formatters';
     $form['#title'] = $this->t('Edit %label facet', array('%label' => $facet->label()));
     // Add the list of all other processors with checkboxes to enable/disable
     // them.
     $form['facet_settings'] = array('#type' => 'fieldset', '#title' => $this->t('Facet settings'), '#attributes' => array('class' => array('search-api-status-wrapper')));
     foreach ($all_processors as $processor_id => $processor) {
         if (!$processor instanceof WidgetOrderProcessorInterface && !$processor instanceof UrlProcessorInterface) {
             $clean_css_id = Html::cleanCssIdentifier($processor_id);
             $form['facet_settings'][$processor_id]['status'] = array('#type' => 'checkbox', '#title' => (string) $processor->getPluginDefinition()['label'], '#default_value' => $processor->isLocked() || !empty($enabled_processors[$processor_id]), '#description' => $processor->getDescription(), '#attributes' => array('class' => array('search-api-processor-status-' . $clean_css_id), 'data-id' => $clean_css_id), '#disabled' => $processor->isLocked(), '#access' => !$processor->isHidden());
             $processor_form_state = new SubFormState($form_state, ['facet_settings', $processor_id, 'settings']);
             $processor_form = $processor->buildConfigurationForm($form, $processor_form_state, $facet);
             if ($processor_form) {
                 $form['facet_settings'][$processor_id]['settings'] = array('#type' => 'details', '#title' => $this->t('%processor settings', ['%processor' => (string) $processor->getPluginDefinition()['label']]), '#open' => TRUE, '#attributes' => array('class' => array('facets-processor-settings-' . Html::cleanCssIdentifier($processor_id), 'facets-processor-settings-facet', 'facets-processor-settings')), '#states' => array('visible' => array(':input[name="facet_settings[' . $processor_id . '][status]"]' => array('checked' => TRUE))));
                 $form['facet_settings'][$processor_id]['settings'] += $processor_form;
             }
         }
     }
     // Add the list of widget sort processors with checkboxes to enable/disable
     // them.
     $form['facet_sorting'] = array('#type' => 'fieldset', '#title' => $this->t('Facet sorting'), '#attributes' => array('class' => array('search-api-status-wrapper')));
     foreach ($all_processors as $processor_id => $processor) {
         if ($processor instanceof WidgetOrderProcessorInterface) {
             $clean_css_id = Html::cleanCssIdentifier($processor_id);
             $form['facet_sorting'][$processor_id]['status'] = array('#type' => 'checkbox', '#title' => (string) $processor->getPluginDefinition()['label'], '#default_value' => $processor->isLocked() || !empty($enabled_processors[$processor_id]), '#description' => $processor->getDescription(), '#attributes' => array('class' => array('search-api-processor-status-' . $clean_css_id), 'data-id' => $clean_css_id), '#disabled' => $processor->isLocked(), '#access' => !$processor->isHidden());
             $processor_form_state = new SubFormState($form_state, array('facet_sorting', $processor_id, 'settings'));
             $processor_form = $processor->buildConfigurationForm($form, $processor_form_state, $facet);
             if ($processor_form) {
                 $form['facet_sorting'][$processor_id]['settings'] = array('#type' => 'container', '#open' => TRUE, '#attributes' => array('class' => array('facets-processor-settings-' . Html::cleanCssIdentifier($processor_id), 'facets-processor-settings-sorting', 'facets-processor-settings')), '#states' => array('visible' => array(':input[name="facet_sorting[' . $processor_id . '][status]"]' => array('checked' => TRUE))));
                 $form['facet_sorting'][$processor_id]['settings'] += $processor_form;
             }
         }
     }
     $form['facet_settings']['only_visible_when_facet_source_is_visible'] = ['#type' => 'checkbox', '#title' => $this->t('Hide facet when facet source is not rendered'), '#description' => $this->t('When checked, this facet will only be rendered when the facet source is rendered.  If you want to show facets on other pages too, you need to uncheck this setting.'), '#default_value' => $facet->getOnlyVisibleWhenFacetSourceIsVisible()];
     $form['facet_settings']['show_only_one_result'] = ['#type' => 'checkbox', '#title' => $this->t('Make sure only one result can be shown.'), '#description' => $this->t('When checked, this will make sure that only one result can be selected for this facet at one time.'), '#default_value' => $facet->getShowOnlyOneResult()];
     $form['facet_settings']['url_alias'] = ['#type' => 'machine_name', '#title' => $this->t('Url alias'), '#default_value' => $facet->getUrlAlias(), '#maxlength' => 50, '#required' => TRUE, '#machine_name' => ['exists' => [\Drupal::service('entity_type.manager')->getStorage('facets_facet'), 'load'], 'source' => ['name']]];
     $empty_behavior_config = $facet->getEmptyBehavior();
     $form['facet_settings']['empty_behavior'] = ['#type' => 'radios', '#title' => t('Empty facet behavior'), '#default_value' => $empty_behavior_config['behavior'] ?: 'none', '#options' => ['none' => t('Do not display facet'), 'text' => t('Display text')], '#description' => $this->t('The action to take when a facet has no items.'), '#required' => TRUE];
     $form['facet_settings']['empty_behavior_container'] = ['#type' => 'container', '#states' => array('visible' => array(':input[name="facet_settings[empty_behavior]"]' => array('value' => 'text')))];
     $form['facet_settings']['empty_behavior_container']['empty_behavior_text'] = ['#type' => 'text_format', '#title' => $this->t('Empty text'), '#format' => isset($empty_behavior_config['text_format']) ? $empty_behavior_config['text_format'] : 'plain_text', '#editor' => TRUE, '#default_value' => isset($empty_behavior_config['text_format']) ? $empty_behavior_config['text'] : ''];
     $form['facet_settings']['query_operator'] = ['#type' => 'radios', '#title' => $this->t('Operator'), '#options' => ['OR' => $this->t('OR'), 'AND' => $this->t('AND')], '#description' => $this->t('AND filters are exclusive and narrow the result set. OR filters are inclusive and widen the result set.'), '#default_value' => $facet->getQueryOperator()];
     $form['facet_settings']['exclude'] = ['#type' => 'checkbox', '#title' => $this->t('Exclude'), '#description' => $this->t('Make the search exclude selected facets, instead of restricting it to them.'), '#default_value' => $facet->getExclude()];
     $form['facet_settings']['weight'] = ['#type' => 'number', '#title' => $this->t('Weight'), '#default_value' => $facet->getWeight(), '#maxlength' => 4, '#required' => TRUE];
     $form['weights'] = array('#type' => 'details', '#title' => t('Advanced settings'), '#collapsible' => TRUE, '#collapsed' => TRUE);
     $form['weights']['order'] = ['#markup' => "<h3>" . t('Processor order') . "</h3>"];
     // Order enabled processors per stage, create all the containers for the
     // different stages.
     foreach ($stages as $stage => $description) {
         $form['weights'][$stage] = array('#type' => 'fieldset', '#title' => $description['label'], '#attributes' => array('class' => array('search-api-stage-wrapper', 'search-api-stage-wrapper-' . Html::cleanCssIdentifier($stage))));
         $form['weights'][$stage]['order'] = array('#type' => 'table');
         $form['weights'][$stage]['order']['#tabledrag'][] = array('action' => 'order', 'relationship' => 'sibling', 'group' => 'search-api-processor-weight-' . Html::cleanCssIdentifier($stage));
     }
     $processor_settings = $facet->getProcessorConfigs();
     // Fill in the containers previously created with the processors that are
     // enabled on the facet.
     foreach ($processors_by_stage as $stage => $processors) {
         /** @var \Drupal\facets\Processor\ProcessorInterface $processor */
         foreach ($processors as $processor_id => $processor) {
             $weight = isset($processor_settings[$processor_id]['weights'][$stage]) ? $processor_settings[$processor_id]['weights'][$stage] : $processor->getDefaultWeight($stage);
             if ($processor->isHidden()) {
                 $form['processors'][$processor_id]['weights'][$stage] = array('#type' => 'value', '#value' => $weight);
                 continue;
             }
             $form['weights'][$stage]['order'][$processor_id]['#attributes']['class'][] = 'draggable';
             $form['weights'][$stage]['order'][$processor_id]['#attributes']['class'][] = 'search-api-processor-weight--' . Html::cleanCssIdentifier($processor_id);
             $form['weights'][$stage]['order'][$processor_id]['#weight'] = $weight;
             $form['weights'][$stage]['order'][$processor_id]['label']['#plain_text'] = (string) $processor->getPluginDefinition()['label'];
             $form['weights'][$stage]['order'][$processor_id]['weight'] = array('#type' => 'weight', '#title' => $this->t('Weight for processor %title', array('%title' => (string) $processor->getPluginDefinition()['label'])), '#title_display' => 'invisible', '#default_value' => $weight, '#parents' => array('processors', $processor_id, 'weights', $stage), '#attributes' => array('class' => array('search-api-processor-weight-' . Html::cleanCssIdentifier($stage))));
         }
     }
     // Add vertical tabs containing the settings for the processors. Tabs for
     // disabled processors are hidden with JS magic, but need to be included in
     // case the processor is enabled.
     $form['processor_settings'] = array('#title' => $this->t('Processor settings'), '#type' => 'vertical_tabs');
     return $form;
 }
Example #9
0
 /**
  * Builds a read-only form element for a field.
  *
  * @param string $label
  *   The element label.
  * @param string $value
  *   The element value.
  *
  * @return array
  *   The form element.
  */
 protected function fieldAsReadOnly($label, $value)
 {
     return ['#type' => 'item', '#wrapper_attributes' => ['class' => [Html::cleanCssIdentifier(strtolower($label)), 'container-inline']], '#markup' => '<h4 class="label inline">' . $label . '</h4> ' . $value];
 }
Example #10
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state)
 {
     // Don't show the form when batch operations are in progress.
     if ($batch = batch_get() && isset($batch['current_set'])) {
         return array('#theme' => '');
     }
     // Make sure that we validate because this form might be submitted
     // multiple times per page.
     $form_state->setValidationEnforced();
     /** @var \Drupal\views\ViewExecutable $view */
     $view = $form_state->get('view');
     $display =& $form_state->get('display');
     $form_state->setUserInput($view->getExposedInput());
     // Let form plugins know this is for exposed widgets.
     $form_state->set('exposed', TRUE);
     // Check if the form was already created
     if ($cache = $this->exposedFormCache->getForm($view->storage->id(), $view->current_display)) {
         return $cache;
     }
     $form['#info'] = array();
     // Go through each handler and let it generate its exposed widget.
     foreach ($view->display_handler->handlers as $type => $value) {
         /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface $handler */
         foreach ($view->{$type} as $id => $handler) {
             if ($handler->canExpose() && $handler->isExposed()) {
                 // Grouped exposed filters have their own forms.
                 // Instead of render the standard exposed form, a new Select or
                 // Radio form field is rendered with the available groups.
                 // When an user choose an option the selected value is split
                 // into the operator and value that the item represents.
                 if ($handler->isAGroup()) {
                     $handler->groupForm($form, $form_state);
                     $id = $handler->options['group_info']['identifier'];
                 } else {
                     $handler->buildExposedForm($form, $form_state);
                 }
                 if ($info = $handler->exposedInfo()) {
                     $form['#info']["{$type}-{$id}"] = $info;
                 }
             }
         }
     }
     $form['actions'] = array('#type' => 'actions');
     $form['actions']['submit'] = array('#name' => '', '#type' => 'submit', '#value' => $this->t('Apply'), '#id' => Html::getUniqueId('edit-submit-' . $view->storage->id()));
     $form['#action'] = $view->hasUrl() ? $view->getUrl()->toString() : Url::fromRoute('<current>')->toString();
     $form['#theme'] = $view->buildThemeFunctions('views_exposed_form');
     $form['#id'] = Html::cleanCssIdentifier('views_exposed_form-' . SafeMarkup::checkPlain($view->storage->id()) . '-' . SafeMarkup::checkPlain($display['id']));
     /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
     $exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
     $exposed_form_plugin->exposedFormAlter($form, $form_state);
     // Save the form.
     $this->exposedFormCache->setForm($view->storage->id(), $view->current_display, $form);
     return $form;
 }
Example #11
0
 /**
  * {@inheritdoc}
  */
 public function elementWrapperClasses($row_index = NULL)
 {
     $classes = explode(' ', $this->options['element_wrapper_class']);
     foreach ($classes as &$class) {
         $class = $this->tokenizeValue($class, $row_index);
         $class = Html::cleanCssIdentifier($class);
     }
     return implode(' ', $classes);
 }
Example #12
0
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_usecss'] = array('#type' => 'checkbox', '#title' => t('Use CSS'), '#default_value' => null !== theme_get_setting('settings.slideshow_' . $i . '_usecss') ? theme_get_setting('settings.slideshow_' . $i . '_usecss') : 1, '#description' => t('Slider will use CSS3 transitions if the browser supports them. Uncheck this if you have issues with slides flashing or flickering, or if you prefer to use JavaScript animation.'));
       // touch            : true,           // Boolean Allow touch swipe navigation of the slider on enabled devices
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_touch'] = array('#type' => 'checkbox', '#title' => t('Touch swipe navigation'), '#default_value' => null !== theme_get_setting('settings.slideshow_' . $i . '_touch') ? theme_get_setting('settings.slideshow_' . $i . '_touch') : 1, '#description' => t('Allow touch swipe navigation of the slider on enabled devices.'));
       // video            : false,          // Boolean Will prevent use of CSS3 3D Transforms, avoiding graphical glitches
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_video'] = array('#type' => 'checkbox', '#title' => t('Video'), '#default_value' => theme_get_setting('settings.slideshow_' . $i . '_video'), '#description' => t('Checking this setting will prevent use of CSS3 3D Transforms, avoiding graphical glitches when embedding video.'));
       // prevText : String Set the text for the "previous" directionNav item
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_prevtext'] = array('#type' => 'textfield', '#title' => t('Previous text'), '#default_value' => null !== theme_get_setting('settings.slideshow_' . $i . '_prevtext') ? theme_get_setting('settings.slideshow_' . $i . '_prevtext') : t('Previous'), '#description' => t('Text for the "previous" direction nav item.'));
       //nextText : String Set the text for the "next" directionNav item
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_nexttext'] = array('#type' => 'textfield', '#title' => t('Next text'), '#default_value' => null !== theme_get_setting('settings.slideshow_' . $i . '_nexttext') ? theme_get_setting('settings.slideshow_' . $i . '_nexttext') : t('Next'), '#description' => t('Text for the "next" direction nav item.'));
       // slideshow selector         : themename-slideshow-N i.e. $slideshow_class
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_slideshow_class'] = array('#type' => 'textfield', '#title' => t('Slideshow selector'), '#default_value' => null !== theme_get_setting('settings.slideshow_' . $i . '_slideshow_class') ? theme_get_setting('settings.slideshow_' . $i . '_slideshow_class') : '.' . $slideshow_class, '#description' => t('Change this if you are using your own markup, e.g. a custom block with image fields.'));
       // slide selector         : ".slides > li", // Selector Must match a simple pattern. '{container} > {slide}'.
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['advanced_options']['settings_slideshow_' . $i . '_selector'] = array('#type' => 'textfield', '#title' => t('Slide selector'), '#default_value' => null !== theme_get_setting('settings.slideshow_' . $i . '_selector') ? theme_get_setting('settings.slideshow_' . $i . '_selector') : '.slides > li', '#description' => t('Selector must match the pattern <code>{container} &#62; {slide}</code>. Modify with caution. The generated markup snippet will not reflect changes here, and you will need to account for changes both in markup and CSS. Changing this without editing the markup in your slideshow or CSS will break the slideshow.'));
       if (theme_get_setting('settings.slideshow_' . $i . '_slideshow_class') !== null) {
           $slideshow_class_setting = theme_get_setting('settings.slideshow_' . $i . '_slideshow_class');
           $this_slideshow_class = Html::cleanCssIdentifier($slideshow_class_setting);
       } else {
           $this_slideshow_class = $slideshow_class;
       }
       // Class and markup generator TODO: markup generator
       $form['slideshows']['slideshow_' . $i]['slideshow_options']['wrapper']['slideshow_markup'] = array('#type' => 'textarea', '#title' => t('Generated markup for this slideshow (with working examples)'), '#default_value' => '<div class="flexslider loading ' . ltrim($this_slideshow_class, '.') . '">
 <ul class="slides">
   <li>
     <img src="' . base_path() . $subtheme_path . '/images/slides/test-slide-1.png" alt="Test slide one" />
     <p class="flex-caption">Test slide one</p>
   </li>
   <li>
     <img src="' . base_path() . $subtheme_path . '/images/slides/test-slide-2.png" alt="Test slide two" />
     <p class="flex-caption">Test slide two</p>
   </li>
   <li>
Example #13
0
 /**
  * Returns a views exposed form ID.
  *
  * @param \Drupal\views\ViewExecutable $view
  *   The view to create an ID for.
  *
  * @return string
  *   The form ID.
  */
 protected function getExpectedExposedFormId(ViewExecutable $view)
 {
     return Html::cleanCssIdentifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display);
 }
 /**
  * Asserts enable/disable operations for a search server or index.
  *
  * @param \Drupal\search_api\ServerInterface|\Drupal\search_api\IndexInterface $entity
  *   A search server or index.
  */
 protected function assertEntityStatusChange($entity)
 {
     $this->drupalGet($this->overviewPageUrl);
     $row_class = Html::cleanCssIdentifier($entity->getEntityTypeId() . '-' . $entity->id());
     $this->assertFieldByXPath('//tr[contains(@class,"' . $row_class . '") and contains(@class, "search-api-list-enabled")]', NULL, 'The newly created entity is enabled by default.');
     // The first "Disable" link on the page belongs to our server, the second
     // one to our index.
     $this->clickLink('Disable', $entity instanceof ServerInterface ? 0 : 1);
     // Submit the confirmation form and test that the entity has been disabled.
     $this->drupalPostForm(NULL, array(), 'Disable');
     $this->assertFieldByXPath('//tr[contains(@class,"' . $row_class . '") and contains(@class, "search-api-list-disabled")]', NULL, 'The entity has been disabled.');
     // Now enable the entity and verify that the operation succeeded.
     $this->clickLink('Enable');
     $this->drupalGet($this->overviewPageUrl);
     $this->assertFieldByXPath('//tr[contains(@class,"' . $row_class . '") and contains(@class, "search-api-list-enabled")]', NULL, 'The entity has benn enabled.');
 }
Example #15
0
  /**
   * {@inheritdoc}
   */
  public function buildRow(EntityInterface $entity) {
    /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity */
    $row = parent::buildRow($entity);

    $status_label = $entity->status() ? $this->t('Enabled') : $this->t('Disabled');
    $status_icon = array(
      '#theme' => 'image',
      '#uri' => $entity->status() ? 'core/misc/icons/73b355/check.svg' : 'core/misc/icons/ea2800/error.svg',
      '#width' => 18,
      '#height' => 18,
      '#alt' => $status_label,
      '#title' => $status_label,
    );

    return array(
      'data' => array(
        'type' => array(
          'data' => $entity instanceof ServerInterface ? $this->t('Server') : $this->t('Index'),
          'class' => array('search-api-type'),
        ),
        'title' => array(
          'data' => array(
              '#type' => 'link',
              '#title' => $entity->label(),
              '#suffix' => '<div>' . $entity->get('description') . '</div>',
            ) + $entity->urlInfo('canonical')->toRenderArray(),
          'class' => array('search-api-title'),
        ),
        'status' => array(
          'data' => $status_icon,
          'class' => array('checkbox'),
        ),
        'operations' => $row['operations'],
      ),
      'title' => $this->t('ID: @name', array('@name' => $entity->id())),
      'class' => array(
        Html::cleanCssIdentifier($entity->getEntityTypeId() . '-' . $entity->id()),
        $entity->status() ? 'search-api-list-enabled' : 'search-api-list-disabled',
        $entity instanceof ServerInterface ? 'search-api-list-server' : 'search-api-list-index',
      ),
    );
  }
Example #16
0
 /**
  * Add information about a section to a display.
  */
 public function getFormBucket(ViewUI $view, $type, $display)
 {
     $executable = $view->getExecutable();
     $executable->setDisplay($display['id']);
     $executable->initStyle();
     $types = $executable->getHandlerTypes();
     $build = array('#theme_wrappers' => array('views_ui_display_tab_bucket'));
     $build['#overridden'] = FALSE;
     $build['#defaulted'] = FALSE;
     $build['#name'] = $type;
     $build['#title'] = $types[$type]['title'];
     $rearrange_url = Url::fromRoute('views_ui.form_rearrange', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type]);
     $class = 'icon compact rearrange';
     // Different types now have different rearrange forms, so we use this switch
     // to get the right one.
     switch ($type) {
         case 'filter':
             // The rearrange form for filters contains the and/or UI, so override
             // the used path.
             $rearrange_url = Url::fromRoute('views_ui.form_rearrange_filter', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id']]);
             // TODO: Add another class to have another symbol for filter rearrange.
             $class = 'icon compact rearrange';
             break;
         case 'field':
             // Fetch the style plugin info so we know whether to list fields or not.
             $style_plugin = $executable->style_plugin;
             $uses_fields = $style_plugin && $style_plugin->usesFields();
             if (!$uses_fields) {
                 $build['fields'][] = array('#markup' => $this->t('The selected style or row format does not use fields.'), '#theme_wrappers' => array('views_ui_container'), '#attributes' => array('class' => array('views-display-setting')));
                 return $build;
             }
             break;
         case 'header':
         case 'footer':
         case 'empty':
             if (!$executable->display_handler->usesAreas()) {
                 $build[$type][] = array('#markup' => $this->t('The selected display type does not use @type plugins', array('@type' => $type)), '#theme_wrappers' => array('views_ui_container'), '#attributes' => array('class' => array('views-display-setting')));
                 return $build;
             }
             break;
     }
     // Create an array of actions to pass to links template.
     $actions = array();
     $count_handlers = count($executable->display_handler->getHandlers($type));
     // Create the add text variable for the add action.
     $add_text = $this->t('Add <span class="visually-hidden">@type</span>', array('@type' => $types[$type]['ltitle']));
     $actions['add'] = array('title' => $add_text, 'url' => Url::fromRoute('views_ui.form_add_handler', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type]), 'attributes' => array('class' => array('icon compact add', 'views-ajax-link'), 'id' => 'views-add-' . $type));
     if ($count_handlers > 0) {
         // Create the rearrange text variable for the rearrange action.
         $rearrange_text = $type == 'filter' ? $this->t('And/Or Rearrange <span class="visually-hidden">filter criteria</span>') : $this->t('Rearrange <span class="visually-hidden">@type</span>', array('@type' => $types[$type]['ltitle']));
         $actions['rearrange'] = array('title' => $rearrange_text, 'url' => $rearrange_url, 'attributes' => array('class' => array($class, 'views-ajax-link'), 'id' => 'views-rearrange-' . $type));
     }
     // Render the array of links
     $build['#actions'] = array('#type' => 'dropbutton', '#links' => $actions, '#attributes' => array('class' => array('views-ui-settings-bucket-operations')));
     if (!$executable->display_handler->isDefaultDisplay()) {
         if (!$executable->display_handler->isDefaulted($types[$type]['plural'])) {
             $build['#overridden'] = TRUE;
         } else {
             $build['#defaulted'] = TRUE;
         }
     }
     static $relationships = NULL;
     if (!isset($relationships)) {
         // Get relationship labels.
         $relationships = array();
         foreach ($executable->display_handler->getHandlers('relationship') as $id => $handler) {
             $relationships[$id] = $handler->adminLabel();
         }
     }
     // Filters can now be grouped so we do a little bit extra:
     $groups = array();
     $grouping = FALSE;
     if ($type == 'filter') {
         $group_info = $executable->display_handler->getOption('filter_groups');
         // If there is only one group but it is using the "OR" filter, we still
         // treat it as a group for display purposes, since we want to display the
         // "OR" label next to items within the group.
         if (!empty($group_info['groups']) && (count($group_info['groups']) > 1 || current($group_info['groups']) == 'OR')) {
             $grouping = TRUE;
             $groups = array(0 => array());
         }
     }
     $build['fields'] = array();
     foreach ($executable->display_handler->getOption($types[$type]['plural']) as $id => $field) {
         // Build the option link for this handler ("Node: ID = article").
         $build['fields'][$id] = array();
         $build['fields'][$id]['#theme'] = 'views_ui_display_tab_setting';
         $handler = $executable->display_handler->getHandler($type, $id);
         if ($handler->broken()) {
             $build['fields'][$id]['#class'][] = 'broken';
             $field_name = $handler->adminLabel();
             $build['fields'][$id]['#link'] = $this->l($field_name, new Url('views_ui.form_handler', array('js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id), array('attributes' => array('class' => array('views-ajax-link')))));
             continue;
         }
         $field_name = $handler->adminLabel(TRUE);
         if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
             $field_name = '(' . $relationships[$field['relationship']] . ') ' . $field_name;
         }
         $description = Xss::filterAdmin($handler->adminSummary());
         $link_text = $field_name . (empty($description) ? '' : " ({$description})");
         $link_attributes = array('class' => array('views-ajax-link'));
         if (!empty($field['exclude'])) {
             $link_attributes['class'][] = 'views-field-excluded';
             // Add a [hidden] marker, if the field is excluded.
             $link_text .= ' [' . $this->t('hidden') . ']';
         }
         $build['fields'][$id]['#link'] = $this->l($link_text, new Url('views_ui.form_handler', array('js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id), array('attributes' => $link_attributes)));
         $build['fields'][$id]['#class'][] = Html::cleanCssIdentifier($display['id'] . '-' . $type . '-' . $id);
         if ($executable->display_handler->useGroupBy() && $handler->usesGroupBy()) {
             $build['fields'][$id]['#settings_links'][] = $this->l(SafeMarkup::format('<span class="label">@text</span>', array('@text' => $this->t('Aggregation settings'))), new Url('views_ui.form_handler_group', array('js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id), array('attributes' => array('class' => array('views-button-configure', 'views-ajax-link'), 'title' => $this->t('Aggregation settings')))));
         }
         if ($handler->hasExtraOptions()) {
             $build['fields'][$id]['#settings_links'][] = $this->l(SafeMarkup::format('<span class="label">@text</span>', array('@text' => $this->t('Settings'))), new Url('views_ui.form_handler_extra', array('js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id), array('attributes' => array('class' => array('views-button-configure', 'views-ajax-link'), 'title' => $this->t('Settings')))));
         }
         if ($grouping) {
             $gid = $handler->options['group'];
             // Show in default group if the group does not exist.
             if (empty($group_info['groups'][$gid])) {
                 $gid = 0;
             }
             $groups[$gid][] = $id;
         }
     }
     // If using grouping, re-order fields so that they show up properly in the list.
     if ($type == 'filter' && $grouping) {
         $store = $build['fields'];
         $build['fields'] = array();
         foreach ($groups as $gid => $contents) {
             // Display an operator between each group.
             if (!empty($build['fields'])) {
                 $build['fields'][] = array('#theme' => 'views_ui_display_tab_setting', '#class' => array('views-group-text'), '#link' => $group_info['operator'] == 'OR' ? $this->t('OR') : $this->t('AND'));
             }
             // Display an operator between each pair of filters within the group.
             $keys = array_keys($contents);
             $last = end($keys);
             foreach ($contents as $key => $pid) {
                 if ($key != $last) {
                     $operator = $group_info['groups'][$gid] == 'OR' ? $this->t('OR') : $this->t('AND');
                     $store[$pid]['#link'] = SafeMarkup::format('@link <span>@operator</span>', ['@link' => $store[$pid]['#link'], '@operator' => $operator]);
                 }
                 $build['fields'][$pid] = $store[$pid];
             }
         }
     }
     return $build;
 }
Example #17
0
 /**
  * Creates the necessary containers for each provider.
  *
  * @param \Drupal\bootstrap\Utility\Element $group
  *   The group element instance.
  * @param \Drupal\bootstrap\Plugin\Provider\ProviderInterface $provider
  *   The provider instance.
  */
 private function createProviderGroup(Element $group, ProviderInterface $provider)
 {
     $plugin_id = Html::cleanCssIdentifier($provider->getPluginId());
     // Create the provider container.
     $group->{$plugin_id} = ['#type' => 'container', '#prefix' => '<div id="cdn-provider-' . $plugin_id . '">', '#suffix' => '</div>', '#states' => ['visible' => [':input[name="cdn_provider"]' => ['value' => $plugin_id]]]];
     // Add in the provider description.
     if ($description = $provider->getDescription()) {
         $group->{$plugin_id}->description = ['#markup' => '<div class="lead">' . $description . '</div>', '#weight' => -99];
     }
     // Indicate there was an error retrieving the provider's API data.
     if ($provider->hasError() || $provider->isImported()) {
         if ($provider->hasError()) {
             $group->{$plugin_id}->error = ['#markup' => '<div class="alert alert-danger messages error"><strong>' . t('ERROR') . ':</strong> ' . t('Unable to reach or parse the data provided by the @title API. Ensure the server this website is hosted on is able to initiate HTTP requests. If the request consistently fails, it is likely that there are certain PHP functions that have been disabled by the hosting provider for security reasons. It is possible to manually copy and paste the contents of the following URL into the "Imported @title data" section below.<br /><br /><a href=":provider_api" target="_blank">:provider_api</a>.', ['@title' => $provider->getLabel(), ':provider_api' => $provider->getApi()]) . '</div>', '#weight' => -20];
         }
         $group->{$plugin_id}->import = ['#type' => 'details', '#title' => t('Imported @title data', ['@title' => $provider->getLabel()]), '#description' => t('The provider will attempt to parse the data entered here each time it is saved. If no data has been entered, any saved files associated with this provider will be removed and the provider will again attempt to request the API data normally through the following URL: <a href=":provider_api" target="_blank">:provider_api</a>.', [':provider_api' => $provider->getPluginDefinition()['api']]), '#weight' => 10, '#open' => FALSE];
         $group->{$plugin_id}->import->cdn_provider_import_data = ['#type' => 'textarea', '#default_value' => file_exists(ProviderManager::FILE_PATH . '/' . $plugin_id . '.json') ? file_get_contents(ProviderManager::FILE_PATH . '/' . $plugin_id . '.json') : NULL];
         $group->{$plugin_id}->import->submit = ['#type' => 'submit', '#value' => t('Save provider data'), '#executes_submit_callback' => FALSE, '#ajax' => ['callback' => [get_class($this), 'ajaxCallback'], 'wrapper' => 'cdn-provider-' . $plugin_id]];
     }
 }
 /**
  * {@inheritdoc}
  */
 public function view(OrderInterface $order, array $form, FormStateInterface $form_state)
 {
     $contents['#attached']['library'][] = 'uc_payment/uc_payment.styles';
     if ($this->configuration['show_preview']) {
         $contents['line_items'] = array('#theme' => 'uc_payment_totals', '#order' => $order, '#weight' => -20);
     }
     // Ensure that the form builder uses #default_value to determine which
     // button should be selected after an ajax submission. This is
     // necessary because the previously selected value may have become
     // unavailable, which would result in an invalid selection.
     $input = $form_state->getUserInput();
     unset($input['panes']['payment']['payment_method']);
     $form_state->setUserInput($input);
     $options = array();
     $methods = PaymentMethod::loadMultiple();
     uasort($methods, 'Drupal\\uc_payment\\Entity\\PaymentMethod::sort');
     foreach ($methods as $method) {
         // $set = rules_config_load('uc_payment_method_' . $method['id']);
         // if ($set && !$set->execute($order)) {
         //   continue;
         // }
         if ($method->status()) {
             $options[$method->id()] = $method->getDisplayLabel();
         }
     }
     \Drupal::moduleHandler()->alter('uc_payment_method_checkout', $options, $order);
     if (!$options) {
         $contents['#description'] = $this->t('Checkout cannot be completed without any payment methods enabled. Please contact an administrator to resolve the issue.');
         $options[''] = $this->t('No payment methods available');
     } elseif (count($options) > 1) {
         $contents['#description'] = $this->t('Select a payment method from the following options.');
     }
     if (!$order->getPaymentMethodId() || !isset($options[$order->getPaymentMethodId()])) {
         $order->setPaymentMethodId(key($options));
     }
     $contents['payment_method'] = array('#type' => 'radios', '#title' => $this->t('Payment method'), '#title_display' => 'invisible', '#options' => $options, '#default_value' => $order->getPaymentMethodId(), '#disabled' => count($options) == 1, '#required' => TRUE, '#ajax' => array('callback' => array($this, 'ajaxRender'), 'wrapper' => 'payment-details', 'progress' => array('type' => 'throbber')));
     // If there are no payment methods available, this will be ''.
     if ($order->getPaymentMethodId()) {
         $plugin = $this->paymentMethodManager->createFromOrder($order);
         $definition = $plugin->getPluginDefinition();
         $contents['details'] = array('#prefix' => '<div id="payment-details" class="clearfix ' . Html::cleanCssIdentifier('payment-details-' . $definition['id']) . '">', '#markup' => $this->t('Continue with checkout to complete payment.'), '#suffix' => '</div>');
         try {
             $details = $plugin->cartDetails($order, $form, $form_state);
             if ($details) {
                 unset($contents['details']['#markup']);
                 $contents['details'] += $details;
             }
         } catch (PluginException $e) {
         }
     }
     return $contents;
 }
 protected static function cleanCssIdentifier($id)
 {
     return 'token-' . Html::cleanCssIdentifier(trim($id, '[]'), static::$cssFilter);
 }
Example #20
0
  public function rowAttributes() {
    $variables = array();
    $active_row_regions = array();
    $config_settings = \Drupal::config($this->theme_name . '.settings')->get('settings');

    // If rows are empty return early.
    if (empty($this->layout_config['rows'])) {
      return;
    }

    // Build array of rows with region values.
    foreach ($this->layout_config['rows'] as $row_name => $row_data) {

      // Set a bool for active regions, assume false.
      $variables[$row_name . '__regions']['active'] = FALSE;

      $i = 1;
      foreach ($row_data['regions'] as $region_key => $region_name) {
        $region_source_order[$row_name][$region_key] = $i++; // Set an increment value for each region for the .hr class (has-regions)
        $row_regions[$row_name][] = $region_key; // Build array to intersect and use for the .arc class (active region count).
      }

      // Pass on row wrapper attributes only for rows with active regions
      $active_row_regions[$row_name]['attributes'] = $row_data['attributes'];

      // Remove inactive regions.
      $active_row_regions[$row_name]['regions'] = array_intersect($row_regions[$row_name], $this->active_regions);

      // Unset inactive rows.
      if (empty($active_row_regions[$row_name]['regions'])) {
        unset($active_row_regions[$row_name]);
      }
    }

    // Set additional attributes for rows.
    foreach ($active_row_regions as $row_key => $row_values) {
      //if (!empty($row_values['regions'])) {}

      // If active regions set to true to print the row, basically a catch all condition.
      $variables[$row_key . '__regions']['active'] = TRUE;

      // Wrapper attributes.
      $variables[$row_key . '__wrapper_attributes'] = new Attribute;
      $variables[$row_key . '__wrapper_attributes']['class'] = array('l-pr', 'page__row', 'pr-' . $row_key);
      foreach ($row_values['attributes'] as $attribute_type => $attribute_values) {
        if (is_array($attribute_values)) {
          $variables[$row_key . '__wrapper_attributes'][$attribute_type] = array(implode(' ', $attribute_values));
        }
        else {
          $variables[$row_key . '__wrapper_attributes'][$attribute_type] = array($attribute_values);
        }
      }

      // Container attributes.
      $variables[$row_key . '__container_attributes'] = new Attribute;
      $variables[$row_key . '__container_attributes']['class'] = array('l-rw', 'regions', 'container', 'pr-'. str_replace('_', '-', $row_key) . '__rw');

      // Active Regions: "arc" is "active region count", this is number of active regions in this row on this page.
      $count = count($row_values['regions']);
      $variables[$row_key . '__container_attributes']['class'][] = 'arc--'. $count;

      // Match each active region with its'corrosponding source order increment.
      foreach ($row_values['regions'] as $region) {
        if (isset($region_source_order[$row_key][$region])) {
          $row_has_regions[$row_key][] = $region_source_order[$row_key][$region];
        }
      }

      // Has Regions: the "hr" class tells us which regions are active by source order (as per the layout markup yml),
      // this allows us to push layout dependant on exactly which regions are active.
      if (isset($row_has_regions[$row_key])) {
        $variables[$row_key . '__container_attributes']['class'][] =  'hr--' . implode('-', $row_has_regions[$row_key]);
      }

      // Shortcode classes.
      if (isset($config_settings['enable_extensions']) && $config_settings['enable_extensions'] === 1) {
        if (isset($config_settings['enable_shortcodes']) && $config_settings['enable_shortcodes'] === 1) {

          // Wrapper codes
          if (!empty($config_settings['page_classes_row_wrapper_' . $row_key])) {
            $shortcodes = Tags::explode($config_settings['page_classes_row_wrapper_' . $row_key]);
            foreach ($shortcodes as $class) {
              $variables[$row_key . '__wrapper_attributes']['class'][] = Html::cleanCssIdentifier($class);
            }
          }

          // Container codes
          if (!empty($config_settings['page_classes_row_container_' . $row_key])) {
            $shortcodes = Tags::explode($config_settings['page_classes_row_container_' . $row_key]);
            foreach ($shortcodes as $class) {
              $variables[$row_key . '__container_attributes']['class'][] = Html::cleanCssIdentifier($class);
            }
          }
        }
      }
    }

    return $variables;
  }
Example #21
0
 /**
  * Generates the content and opens the modal.
  *
  * @param array $form
  *   The form array.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The form state object.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse
  *   An ajax response.
  */
 public function openModal(array &$form, FormStateInterface $form_state)
 {
     $triggering_element = $form_state->getTriggeringElement();
     $parents = $triggering_element['#parents'];
     array_pop($parents);
     $parents = array_merge($parents, ['path']);
     $input = $form_state->getUserInput();
     $src = NestedArray::getValue($input, $parents);
     $content = ['#type' => 'html_tag', '#tag' => 'iframe', '#attributes' => ['src' => $src, 'width' => '100%', 'height' => $this->configuration['height'] - 90, 'frameborder' => 0, 'style' => 'padding:', 'name' => Html::cleanCssIdentifier('entity-browser-iframe-' . $this->configuration['entity_browser_id'])]];
     $html = drupal_render($content);
     $response = new AjaxResponse();
     $response->addCommand(new OpenModalDialogCommand($this->configuration['link_text'], $html, ['width' => $this->configuration['width'], 'height' => $this->configuration['height']]));
     return $response;
 }
Example #22
0
 /**
  * Wrapper for handling AJAX forms.
  *
  * Wrapper around \Drupal\Core\Form\FormBuilderInterface::buildForm() to
  * handle some AJAX stuff automatically.
  * This makes some assumptions about the client.
  *
  * @param \Drupal\Core\Form\FormInterface|string $form_class
  *   The value must be one of the following:
  *   - The name of a class that implements \Drupal\Core\Form\FormInterface.
  *   - An instance of a class that implements \Drupal\Core\Form\FormInterface.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  *
  * @return \Drupal\Core\Ajax\AjaxResponse|string|array
  *   Returns one of three possible values:
  *   - A \Drupal\Core\Ajax\AjaxResponse object.
  *   - The rendered form, as a string.
  *   - A render array with the title in #title and the rendered form in the
  *   #markup array.
  */
 protected function ajaxFormWrapper($form_class, FormStateInterface &$form_state)
 {
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
     $renderer = \Drupal::service('renderer');
     // This won't override settings already in.
     if (!$form_state->has('rerender')) {
         $form_state->set('rerender', FALSE);
     }
     $ajax = $form_state->get('ajax');
     // Do not overwrite if the redirect has been disabled.
     if (!$form_state->isRedirectDisabled()) {
         $form_state->disableRedirect($ajax);
     }
     $form_state->disableCache();
     // Builds the form in a render context in order to ensure that cacheable
     // metadata is bubbled up.
     $render_context = new RenderContext();
     $callable = function () use($form_class, &$form_state) {
         return \Drupal::formBuilder()->buildForm($form_class, $form_state);
     };
     $form = $renderer->executeInRenderContext($render_context, $callable);
     if (!$render_context->isEmpty()) {
         BubbleableMetadata::createFromRenderArray($form)->merge($render_context->pop())->applyTo($form);
     }
     $output = $renderer->renderRoot($form);
     drupal_process_attached($form);
     // These forms have the title built in, so set the title here:
     $title = $form_state->get('title') ?: '';
     if ($ajax && (!$form_state->isExecuted() || $form_state->get('rerender'))) {
         // If the form didn't execute and we're using ajax, build up an
         // Ajax command list to execute.
         $response = new AjaxResponse();
         // Attach the library necessary for using the OpenModalDialogCommand and
         // set the attachments for this Ajax response.
         $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
         $response->setAttachments($form['#attached']);
         $display = '';
         $status_messages = array('#type' => 'status_messages');
         if ($messages = $renderer->renderRoot($status_messages)) {
             $display = '<div class="views-messages">' . $messages . '</div>';
         }
         $display .= $output;
         $options = array('dialogClass' => 'views-ui-dialog', 'width' => '75%');
         $response->addCommand(new OpenModalDialogCommand($title, $display, $options));
         if ($section = $form_state->get('#section')) {
             $response->addCommand(new Ajax\HighlightCommand('.' . Html::cleanCssIdentifier($section)));
         }
         return $response;
     }
     return $title ? ['#title' => $title, '#markup' => $output] : $output;
 }
Example #23
0
  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';

    // Retrieve lists of all processors, and the stages and weights they have.
    if (!$form_state->has('processors')) {
      $all_processors = $this->entity->getProcessors(FALSE);
      $sort_processors = function (ProcessorInterface $a, ProcessorInterface $b) {
        return strnatcasecmp($a->label(), $b->label());
      };
      uasort($all_processors, $sort_processors);
    }
    else {
      $all_processors = $form_state->get('processors');
    }

    $stages = $this->processorPluginManager->getProcessingStages();
    $processors_by_stage = array();
    foreach ($stages as $stage => $definition) {
      $processors_by_stage[$stage] = $this->entity->getProcessorsByStage($stage, FALSE);
    }

    $processor_settings = $this->entity->getOption('processors');

    $form['#tree'] = TRUE;
    $form['#attached']['library'][] = 'search_api/drupal.search_api.index-active-formatters';
    $form['#title'] = $this->t('Manage processors for search index %label', array('%label' => $this->entity->label()));
    $form['description']['#markup'] = '<p>' . $this->t('Configure processors which will pre- and post-process data at index and search time.') . '</p>';

    // Add the list of processors with checkboxes to enable/disable them.
    $form['status'] = array(
      '#type' => 'fieldset',
      '#title' => $this->t('Enabled'),
      '#attributes' => array('class' => array(
        'search-api-status-wrapper',
      )),
    );
    foreach ($all_processors as $processor_id => $processor) {
      $clean_css_id = Html::cleanCssIdentifier($processor_id);
      $form['status'][$processor_id] = array(
        '#type' => 'checkbox',
        '#title' => $processor->label(),
        '#default_value' => $processor->isLocked() || !empty($processor_settings[$processor_id]),
        '#description' => $processor->getDescription(),
        '#attributes' => array(
          'class' => array(
            'search-api-processor-status-' . $clean_css_id,
          ),
          'data-id' => $clean_css_id,
        ),
        '#disabled' => $processor->isLocked(),
        '#access' => !$processor->isHidden(),
      );
    }

    $form['weights'] = array(
      '#type' => 'fieldset',
      '#title' => t('Processor order'),
    );
    // Order enabled processors per stage.
    foreach ($stages as $stage => $description) {
      $form['weights'][$stage] = array (
        '#type' => 'fieldset',
        '#title' => $description['label'],
        '#attributes' => array('class' => array(
          'search-api-stage-wrapper',
          'search-api-stage-wrapper-' . Html::cleanCssIdentifier($stage),
        )),
      );
      $form['weights'][$stage]['order'] = array(
        '#type' => 'table',
      );
      $form['weights'][$stage]['order']['#tabledrag'][] = array(
        'action' => 'order',
        'relationship' => 'sibling',
        'group' => 'search-api-processor-weight-' . Html::cleanCssIdentifier($stage),
      );
    }
    foreach ($processors_by_stage as $stage => $processors) {
      /** @var \Drupal\search_api\Processor\ProcessorInterface $processor */
      foreach ($processors as $processor_id => $processor) {
        $weight = isset($processor_settings[$processor_id]['weights'][$stage])
          ? $processor_settings[$processor_id]['weights'][$stage]
          : $processor->getDefaultWeight($stage);
        if ($processor->isHidden()) {
          $form['processors'][$processor_id]['weights'][$stage] = array(
            '#type' => 'value',
            '#value' => $weight,
          );
          continue;
        }
        $form['weights'][$stage]['order'][$processor_id]['#attributes']['class'][] = 'draggable';
        $form['weights'][$stage]['order'][$processor_id]['#attributes']['class'][] = 'search-api-processor-weight--' . Html::cleanCssIdentifier($processor_id);
        $form['weights'][$stage]['order'][$processor_id]['#weight'] = $weight;
        $form['weights'][$stage]['order'][$processor_id]['label']['#plain_text'] = $processor->label();
        $form['weights'][$stage]['order'][$processor_id]['weight'] = array(
          '#type' => 'weight',
          '#title' => $this->t('Weight for processor %title', array('%title' => $processor->label())),
          '#title_display' => 'invisible',
          '#default_value' => $weight,
          '#parents' => array('processors', $processor_id, 'weights', $stage),
          '#attributes' => array('class' => array(
            'search-api-processor-weight-' . Html::cleanCssIdentifier($stage),
          )),
        );
      }
    }

    // Add vertical tabs containing the settings for the processors. Tabs for
    // disabled processors are hidden with JS magic, but need to be included in
    // case the processor is enabled.
    $form['processor_settings'] = array(
      '#title' => $this->t('Processor settings'),
      '#type' => 'vertical_tabs',
    );

    foreach ($all_processors as $processor_id => $processor) {
      $processor_form_state = new SubFormState($form_state, array('processors', $processor_id, 'settings'));
      $processor_form = $processor->buildConfigurationForm($form, $processor_form_state);
      if ($processor_form) {
        $form['settings'][$processor_id] = array(
          '#type' => 'details',
          '#title' => $processor->label(),
          '#group' => 'processor_settings',
          '#parents' => array('processors', $processor_id, 'settings'),
          '#attributes' => array('class' => array(
            'search-api-processor-settings-' . Html::cleanCssIdentifier($processor_id),
          )),
        );
        $form['settings'][$processor_id] += $processor_form;
      }
    }

    return $form;
  }
Example #24
0
 /**
  * Return the token replaced row class for the specified row.
  */
 public function getRowClass($row_index)
 {
     if ($this->usesRowClass()) {
         $class = $this->options['row_class'];
         if ($this->usesFields() && $this->view->field) {
             $class = strip_tags($this->tokenizeValue($class, $row_index));
         }
         $classes = explode(' ', $class);
         foreach ($classes as &$class) {
             $class = Html::cleanCssIdentifier($class);
         }
         return implode(' ', $classes);
     }
 }
Example #25
0
/**
 * Implementation of hook_form_system_theme_settings_alter()
 *
 * @param $form
 *   Nested array of form elements that comprise the form.
 *
 * @param $form_state
 *   A keyed array containing the current state of the form.
 */
function at_core_form_system_theme_settings_alter(&$form, &$form_state)
{
    // Set the theme name.
    $build_info = $form_state->getBuildInfo();
    $theme = $build_info['args'][0];
    // Instantiate our Theme info object.
    $themeInfo = new ThemeInfo($theme);
    $getThemeInfo = $themeInfo->getThemeInfo('info');
    // Get this themes config settings
    $config = \Drupal::config($theme . '.settings')->get('settings');
    // Common paths.
    $at_core_path = drupal_get_path('theme', 'at_core');
    $subtheme_path = drupal_get_path('theme', $theme);
    $generated_files_path = NULL;
    // Path to save generated CSS files. We don't want this happening for at_core or the generator.
    if (isset($getThemeInfo['subtheme type']) && $getThemeInfo['subtheme type'] === 'adaptive_subtheme') {
        $directoryOperations = new DirectoryOperations();
        $generated_files_path = $directoryOperations->directoryPrepare($backup_file_path = array($subtheme_path, 'styles/css/generated'));
    }
    // Get the active themes regions so we can use this in
    // various other places.
    $theme_regions = system_region_list($theme, $show = REGIONS_VISIBLE);
    // Active themes active blocks
    $theme_blocks = entity_load_multiple_by_properties('block', ['theme' => $theme]);
    // Check for breakpoints module and set a warning and a flag to disable much
    // of the theme settings if its not available.
    $breakpoints_module = \Drupal::moduleHandler()->moduleExists('breakpoint');
    if ($breakpoints_module == TRUE) {
        $breakpoint_groups = \Drupal::service('breakpoint.manager')->getGroups();
        $breakpoints = array();
        // Unset core breakpoint groups due to notices and other issues, until this
        // is resolved: SEE: https://www.drupal.org/node/2379283
        unset($breakpoint_groups['toolbar']);
        unset($breakpoint_groups['seven']);
        unset($breakpoint_groups['bartik']);
        // Set breakpoint options, we use these in layout and other extensions like
        // Responsive menus.
        foreach ($breakpoint_groups as $group_key => $group_values) {
            $breakpoints[$group_key] = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($group_key);
        }
        foreach ($breakpoints as $group => $breakpoint_values) {
            if ($breakpoint_values !== array()) {
                $breakpoint_options[$group] = $group;
            }
        }
    } else {
        drupal_set_message(t('Adaptivetheme requires the <b>Breakpoint module</b>. Open the <a href="!extendpage" target="_blank">Extend</a> page and enable Breakpoint.', array('!extendpage' => base_path() . 'admin/modules')), 'warning');
    }
    // Get node types (bundles).
    $node_types = \Drupal\node\Entity\NodeType::loadMultiple();
    // View or "Display modes".
    // TODO entityManager() is deprecated, but how to replace?
    $node_view_modes = \Drupal::entityManager()->getViewModes('node');
    // Unset unwanted view modes
    unset($node_view_modes['rss']);
    unset($node_view_modes['search_index']);
    unset($node_view_modes['search_result']);
    // Set a class on the form for the current admin theme, note if this is set to
    // "Default theme" the result is always 0.
    $system_theme_config = \Drupal::config('system.theme');
    $admin_theme = $system_theme_config->get('admin');
    if (!empty($admin_theme)) {
        $admin_theme_class = 'admin-theme--' . Html::cleanCssIdentifier($admin_theme);
        $form['#attributes'] = array('class' => array($admin_theme_class));
    }
    // Attached required CSS and JS.
    $form['#attached']['library'][] = 'at_core/at.appearance_settings';
    // AT Core
    if ($theme == 'at_core') {
        $form['at_core']['message'] = array('#type' => 'container', '#markup' => t('AT Core has no configuration and cannot be used as a front end theme - it is a base them only. Use the <b>AT Theme Generator</b> to generate or clone a theme to get started.'));
        // Hide form items.
        $form['theme_settings']['#attributes']['class'] = array('visually-hidden');
        $form['logo']['#attributes']['class'] = array('visually-hidden');
        $form['favicon']['#attributes']['class'] = array('visually-hidden');
        $form['actions']['#attributes']['class'] = array('visually-hidden');
    }
    // AT Subtheme
    if (isset($getThemeInfo['subtheme type'])) {
        if ($getThemeInfo['subtheme type'] !== 'adaptive_generator') {
            // Pass in the generated files path to values and settings.
            $form['at']['settings_generated_files_path'] = array('#type' => 'hidden', '#value' => $generated_files_path);
            // Extension settings.
            require_once $at_core_path . '/forms/ext/extension_settings.php';
            // Layouts.
            require_once $at_core_path . '/forms/layout/layouts.php';
            // Basic settings - move into details wrapper and collapse.
            $form['basic_settings'] = array('#type' => 'details', '#title' => t('Basic Settings'), '#open' => FALSE);
            $form['theme_settings']['#open'] = FALSE;
            $form['theme_settings']['#group'] = 'basic_settings';
            $form['logo']['#open'] = FALSE;
            $form['logo']['#group'] = 'basic_settings';
            $form['favicon']['#open'] = FALSE;
            $form['favicon']['#group'] = 'basic_settings';
            // Buttons don't work with #group, move it the hard way.
            $form['actions']['#type'] = $form['basic_settings']['actions']['#type'] = 'actions';
            $form['actions']['submit']['#type'] = $form['basic_settings']['actions']['submit']['#type'] = 'submit';
            $form['actions']['submit']['#value'] = $form['basic_settings']['actions']['submit']['#value'] = t('Save basic settings');
            $form['actions']['submit']['#button_type'] = $form['basic_settings']['actions']['submit']['#button_type'] = 'primary';
            unset($form['actions']);
        }
    }
    // Modify the color scheme form.
    if (\Drupal::moduleHandler()->moduleExists('color')) {
        include_once $at_core_path . '/forms/color/color_submit.php';
        if (isset($build_info['args'][0]) && ($theme = $build_info['args'][0]) && color_get_info($theme) && function_exists('gd_info')) {
            $form['#process'][] = 'at_core_make_collapsible';
        }
    }
}