/**
  * Autocomplete the label of an entity.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object that contains the typed tags.
  * @param string $target_type
  *   The ID of the target entity type.
  * @param string $selection_handler
  *   The plugin ID of the entity reference selection handler.
  * @param string $selection_settings_key
  *   The hashed key of the key/value entry that holds the selection handler
  *   settings.
  *
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  *   The matched entity labels as a JSON response.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  *   Thrown if the selection settings key is not found in the key/value store
  *   or if it does not match the stored data.
  */
 public function handleAutocomplete(Request $request, $target_type, $selection_handler, $selection_settings_key)
 {
     $matches = array();
     // Get the typed string from the URL, if it exists.
     if ($input = $request->query->get('q')) {
         $typed_string = Tags::explode($input);
         $typed_string = Unicode::strtolower(array_pop($typed_string));
         // Selection settings are passed in as a hashed key of a serialized array
         // stored in the key/value store.
         $selection_settings = $this->keyValue->get($selection_settings_key, FALSE);
         if ($selection_settings !== FALSE) {
             $selection_settings_hash = Crypt::hmacBase64(serialize($selection_settings) . $target_type . $selection_handler, Settings::getHashSalt());
             if ($selection_settings_hash !== $selection_settings_key) {
                 // Disallow access when the selection settings hash does not match the
                 // passed-in key.
                 throw new AccessDeniedHttpException('Invalid selection settings key.');
             }
         } else {
             // Disallow access when the selection settings key is not found in the
             // key/value store.
             throw new AccessDeniedHttpException();
         }
         $matches = $this->matcher->getMatches($target_type, $selection_handler, $selection_settings, $typed_string);
     }
     return new JsonResponse($matches);
 }
Example #2
0
 /**
  * Implodes a series of tags.
  */
 public function testImplodeTags()
 {
     $tags = array_values($this->validTags);
     // Let's explode and implode to our heart's content.
     for ($i = 0; $i < 10; $i++) {
         $string = Tags::implode($tags);
         $tags = Tags::explode($string);
     }
     $this->assertTags($tags);
 }
 /**
  * Autocomplete the label of an entity.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object that contains the typed tags.
  * @param string $target_type
  *   The ID of the target entity type.
  * @param string $selection_handler
  *   The plugin ID of the entity reference selection handler.
  * @param string $selection_settings
  *   The settings that will be passed to the selection handler.
  *
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  *   The matched entity labels as a JSON response.
  */
 public function handleAutocomplete(Request $request, $target_type, $selection_handler, $selection_settings = '')
 {
     $matches = array();
     // Get the typed string from the URL, if it exists.
     if ($input = $request->query->get('q')) {
         $typed_string = Tags::explode($input);
         $typed_string = Unicode::strtolower(array_pop($typed_string));
         // Selection settings are passed in as an encoded serialized array.
         $selection_settings = $selection_settings ? unserialize(base64_decode($selection_settings)) : array();
         $matches = $this->matcher->getMatches($target_type, $selection_handler, $selection_settings, $typed_string);
     }
     return new JsonResponse($matches);
 }
 /**
  * Returns autocompletion content for file name textfield.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request of the page.
  *
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  *   A JSON response.
  */
 public function autocompleteFilename(Request $request)
 {
     $matches = array();
     // Get the typed string from the URL, if it exists.
     if ($input = $request->query->get('q')) {
         $typed_string = Tags::explode($input);
         $typed_string = Unicode::strtolower(array_pop($typed_string));
         $filenames = db_select('uc_files', 'f')->fields('f', ['filename'])->condition('filename', '%' . db_like($typed_string) . '%', 'LIKE')->execute();
         while ($name = $filenames->fetchField()) {
             $matches[] = array('value' => $name);
         }
     }
     return new JsonResponse($matches);
 }
Example #5
0
 public function validateExposed(&$form, &$form_state)
 {
     if (empty($this->options['exposed'])) {
         return;
     }
     if (empty($this->options['expose']['identifier'])) {
         return;
     }
     $identifier = $this->options['expose']['identifier'];
     $input = $form_state['values'][$identifier];
     if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) {
         $this->operator = $this->options['group_info']['group_items'][$input]['operator'];
         $input = $this->options['group_info']['group_items'][$input]['value'];
     }
     $values = Tags::explode($input);
     if (!$this->options['is_grouped'] || $this->options['is_grouped'] && $input != 'All') {
         $uids = $this->validate_user_strings($form[$identifier], $form_state, $values);
     } else {
         $uids = FALSE;
     }
     if ($uids) {
         $this->validated_exposed_input = $uids;
     }
 }
 /**
  * Autocomplete the label of an entity.
  *
  * @param Request $request
  *   The request object that contains the typed tags.
  * @param string $type
  *   The widget type (i.e. 'single' or 'tags').
  * @param string $field_name
  *   The name of the entity reference field.
  * @param string $entity_type
  *   The entity type.
  * @param string $bundle_name
  *   The bundle name.
  * @param string $entity_id
  *   (optional) The entity ID the entity reference field is attached to.
  *   Defaults to ''.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  *   Throws access denied when either the field or field instance does not
  *   exists or the user does not have access to edit the field.
  *
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  *   The matched labels as json.
  */
 public function handleAutocomplete(Request $request, $type, $field_name, $entity_type, $bundle_name, $entity_id)
 {
     $definitions = $this->entityManager()->getFieldDefinitions($entity_type, $bundle_name);
     if (!isset($definitions[$field_name])) {
         throw new AccessDeniedHttpException();
     }
     $field_definition = $definitions[$field_name];
     $access_controller = $this->entityManager()->getAccessController($entity_type);
     if ($field_definition->getType() != 'entity_reference' || !$access_controller->fieldAccess('edit', $field_definition)) {
         throw new AccessDeniedHttpException();
     }
     // Get the typed string, if exists from the URL.
     $items_typed = $request->query->get('q');
     $items_typed = Tags::explode($items_typed);
     $last_item = drupal_strtolower(array_pop($items_typed));
     $prefix = '';
     // The user entered a comma-separated list of entity labels, so we generate
     // a prefix.
     if ($type == 'tags' && !empty($last_item)) {
         $prefix = count($items_typed) ? Tags::implode($items_typed) . ', ' : '';
     }
     $matches = $this->entityReferenceAutocomplete->getMatches($field_definition, $entity_type, $bundle_name, $entity_id, $prefix, $last_item);
     return new JsonResponse($matches);
 }
 /**
  * {@inheritdoc}
  */
 public function elementValidate($element, &$form_state, $form)
 {
     $value = array();
     // If a value was entered into the autocomplete.
     $handler = \Drupal::service('plugin.manager.entity_reference.selection')->getSelectionHandler($this->fieldDefinition);
     $bundles = entity_get_bundles($this->getFieldSetting('target_type'));
     $auto_create = $this->getSelectionHandlerSetting('auto_create');
     if (!empty($element['#value'])) {
         $value = array();
         foreach (Tags::explode($element['#value']) as $input) {
             $match = FALSE;
             // Take "label (entity id)', match the ID from parenthesis when it's a
             // number.
             if (preg_match("/.+\\((\\d+)\\)/", $input, $matches)) {
                 $match = $matches[1];
             } elseif (preg_match("/.+\\(([\\w.]+)\\)/", $input, $matches)) {
                 $match = $matches[1];
             } else {
                 // Try to get a match from the input string when the user didn't use
                 // the autocomplete but filled in a value manually.
                 $match = $handler->validateAutocompleteInput($input, $element, $form_state, $form, !$auto_create);
             }
             if ($match) {
                 $value[] = array('target_id' => $match);
             } elseif ($auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1 || count($bundles) == 1)) {
                 // Auto-create item. See
                 // \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::presave().
                 $value[] = array('target_id' => NULL, 'entity' => $this->createNewEntity($input, $element['#autocreate_uid']));
             }
         }
     }
     // Change the element['#parents'], so in form_set_value() we
     // populate the correct key.
     array_pop($element['#parents']);
     form_set_value($element, $value, $form_state);
 }
 /**
  * Retrieves suggestions for taxonomy term autocompletion by vocabulary ID.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  * @param \Drupal\taxonomy\VocabularyInterface $taxonomy_vocabulary
  *   The vocabulary to filter by.
  *
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  *   A JSON response containing the autocomplete suggestions for taxonomy
  *   terms.
  */
 public function autocompletePerVid(Request $request, VocabularyInterface $taxonomy_vocabulary)
 {
     // A comma-separated list of term names entered in the autocomplete form
     // element. Only the last term is used for autocompletion.
     $tags_typed = $request->query->get('q');
     $tags_typed = Tags::explode($tags_typed);
     $tag_last = Unicode::strtolower(array_pop($tags_typed));
     $matches = array();
     if ($tag_last != '') {
         $vids = array($taxonomy_vocabulary->id());
         $matches = $this->getMatchingTerms($tags_typed, $vids, $tag_last);
     }
     return new JsonResponse($matches);
 }
Example #9
0
 /**
  * Provide a full array of possible theme functions to try for a given hook.
  *
  * @param string $hook
  *   The hook to use. This is the base theme/template name.
  *
  * @return array
  *   An array of theme hook suggestions.
  */
 public function buildThemeFunctions($hook)
 {
     $themes = array();
     $display = isset($this->display_handler) ? $this->display_handler->display : NULL;
     $id = $this->storage->id();
     if ($display) {
         $themes[] = $hook . '__' . $id . '__' . $display['id'];
         $themes[] = $hook . '__' . $display['id'];
         // Add theme suggestions for each single tag.
         foreach (Tags::explode($this->storage->get('tag')) as $tag) {
             $themes[] = $hook . '__' . preg_replace('/[^a-z0-9]/', '_', strtolower($tag));
         }
         if ($display['id'] != $display['display_plugin']) {
             $themes[] = $hook . '__' . $id . '__' . $display['display_plugin'];
             $themes[] = $hook . '__' . $display['display_plugin'];
         }
     }
     $themes[] = $hook . '__' . $id;
     $themes[] = $hook;
     return $themes;
 }
 /**
  * {@inheritdoc}
  */
 public function submitConfigurationForm(array &$form, FormStateInterface $form_state)
 {
     $this->configuration['keywords'] = Tags::explode($form_state->getValue('keywords'));
 }
 /**
  * Form element validation handler for entity_autocomplete elements.
  */
 public static function validateEntityAutocomplete(array &$element, FormStateInterface $form_state, array &$complete_form)
 {
     $value = NULL;
     if (!empty($element['#value'])) {
         $options = array('target_type' => $element['#target_type'], 'handler' => $element['#selection_handler'], 'handler_settings' => $element['#selection_settings']);
         /** @var /Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler */
         $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($options);
         $autocreate = (bool) $element['#autocreate'] && $handler instanceof SelectionWithAutocreateInterface;
         $input_values = $element['#tags'] ? Tags::explode($element['#value']) : array($element['#value']);
         foreach ($input_values as $input) {
             $match = static::extractEntityIdFromAutocompleteInput($input);
             if ($match === NULL) {
                 // Try to get a match from the input string when the user didn't use
                 // the autocomplete but filled in a value manually.
                 $match = static::matchEntityByTitle($handler, $input, $element, $form_state, !$autocreate);
             }
             if ($match !== NULL) {
                 $value[] = array('target_id' => $match);
             } elseif ($autocreate) {
                 /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface $handler */
                 // Auto-create item. See an example of how this is handled in
                 // \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::presave().
                 $value[] = array('entity' => $handler->createNewEntity($element['#target_type'], $element['#autocreate']['bundle'], $input, $element['#autocreate']['uid']));
             }
         }
         // Check that the referenced entities are valid, if needed.
         if ($element['#validate_reference'] && !empty($value)) {
             // Validate existing entities.
             $ids = array_reduce($value, function ($return, $item) {
                 if (isset($item['target_id'])) {
                     $return[] = $item['target_id'];
                 }
                 return $return;
             });
             if ($ids) {
                 $valid_ids = $handler->validateReferenceableEntities($ids);
                 if ($invalid_ids = array_diff($ids, $valid_ids)) {
                     foreach ($invalid_ids as $invalid_id) {
                         $form_state->setError($element, t('The referenced entity (%type: %id) does not exist.', array('%type' => $element['#target_type'], '%id' => $invalid_id)));
                     }
                 }
             }
             // Validate newly created entities.
             $new_entities = array_reduce($value, function ($return, $item) {
                 if (isset($item['entity'])) {
                     $return[] = $item['entity'];
                 }
                 return $return;
             });
             if ($new_entities) {
                 if ($autocreate) {
                     $valid_new_entities = $handler->validateReferenceableNewEntities($new_entities);
                     $invalid_new_entities = array_diff_key($new_entities, $valid_new_entities);
                 } else {
                     // If the selection handler does not support referencing newly
                     // created entities, all of them should be invalidated.
                     $invalid_new_entities = $new_entities;
                 }
                 foreach ($invalid_new_entities as $entity) {
                     /** @var \Drupal\Core\Entity\EntityInterface $entity */
                     $form_state->setError($element, t('This entity (%type: %label) cannot be referenced.', array('%type' => $element['#target_type'], '%label' => $entity->label())));
                 }
             }
         }
         // Use only the last value if the form element does not support multiple
         // matches (tags).
         if (!$element['#tags'] && !empty($value)) {
             $last_value = $value[count($value) - 1];
             $value = isset($last_value['target_id']) ? $last_value['target_id'] : $last_value;
         }
     }
     $form_state->setValueForElement($element, $value);
 }
 /**
  * {@inheritdoc}
  */
 public function submitConfigurationForm(array &$form, array &$form_state)
 {
     $this->configuration['keywords'] = Tags::explode($form_state['values']['keywords']);
 }
Example #13
0
  /**
   * {@inheritdoc}
   */
  public function validateExposed(&$form, FormStateInterface $form_state) {
    if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) {
      return;
    }

    $identifier = $this->options['expose']['identifier'];
    $input = $form_state->getValues()[$identifier];

    if ($this->options['is_grouped'] && isset($this->options['group_info']['group_items'][$input])) {
      $this->operator = $this->options['group_info']['group_items'][$input]['operator'];
      $input = $this->options['group_info']['group_items'][$input]['value'];
    }

    $values = $this->isMultiValued() ? Tags::explode($input) : array($input);

    if (!$this->options['is_grouped'] || ($this->options['is_grouped'] && ($input != 'All'))) {
      $this->validatedExposedInput = $this->validateEntityStrings($form[$identifier], $values, $form_state);
    }
    else {
      $this->validatedExposedInput = FALSE;
    }
  }
 /**
  * Retrieves suggestions for taxonomy term autocompletion.
  *
  * This function outputs term name suggestions in response to Ajax requests
  * made by the taxonomy autocomplete widget for taxonomy term reference
  * fields. The output is a JSON object of plain-text term suggestions, keyed
  * by the user-entered value with the completed term name appended.
  * Term names containing commas are wrapped in quotes.
  *
  * For example, suppose the user has entered the string 'red fish, blue' in
  * the field, and there are two taxonomy terms, 'blue fish' and 'blue moon'.
  * The JSON output would have the following structure:
  * @code
  *   {
  *     "red fish, blue fish": "blue fish",
  *     "red fish, blue moon": "blue moon",
  *   };
  * @endcode
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  * @param string $entity_type
  *   The entity_type.
  * @param string $field_name
  *   The name of the term reference field.
  *
  * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response
  *   When valid field name is specified, a JSON response containing the
  *   autocomplete suggestions for taxonomy terms. Otherwise a normal response
  *   containing an error message.
  */
 public function autocomplete(Request $request, $entity_type, $field_name)
 {
     // A comma-separated list of term names entered in the autocomplete form
     // element. Only the last term is used for autocompletion.
     $tags_typed = $request->query->get('q');
     // Make sure the field exists and is a taxonomy field.
     $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type);
     if (!isset($field_storage_definitions[$field_name]) || $field_storage_definitions[$field_name]->getType() !== 'taxonomy_term_reference') {
         // Error string. The JavaScript handler will realize this is not JSON and
         // will display it as debugging information.
         return new Response(t('Taxonomy field @field_name not found.', array('@field_name' => $field_name)), 403);
     }
     $field_storage = $field_storage_definitions[$field_name];
     // The user enters a comma-separated list of tags. We only autocomplete the
     // last tag.
     $tags_typed = Tags::explode($tags_typed);
     $tag_last = Unicode::strtolower(array_pop($tags_typed));
     $matches = array();
     if ($tag_last != '') {
         // Part of the criteria for the query come from the field's own settings.
         $vids = array();
         foreach ($field_storage->getSetting('allowed_values') as $tree) {
             $vids[] = $tree['vocabulary'];
         }
         $matches = $this->getMatchingTerms($tags_typed, $vids, $tag_last);
     }
     return new JsonResponse($matches);
 }
Example #15
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 #16
0
 public function validateExposed(&$form, &$form_state)
 {
     if (empty($this->options['exposed'])) {
         return;
     }
     $identifier = $this->options['expose']['identifier'];
     // We only validate if they've chosen the text field style.
     if ($this->options['type'] != 'textfield') {
         if ($form_state['values'][$identifier] != 'All') {
             $this->validated_exposed_input = (array) $form_state['values'][$identifier];
         }
         return;
     }
     if (empty($this->options['expose']['identifier'])) {
         return;
     }
     $values = Tags::explode($form_state['values'][$identifier]);
     $tids = $this->validate_term_strings($form[$identifier], $values);
     if ($tids) {
         $this->validated_exposed_input = $tids;
     }
 }