get('media_entity.settings')); $this->configFactory = $config_factory; $this->fetcher = $fetcher; $this->httpClient = $httpClient; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('entity_field.manager'), $container->get('config.factory'), $container->get('media_entity_instagram.instagram_embed_fetcher'), $container->get('http_client') ); } /** * List of validation regular expressions. * * @var array */ public static $validationRegexp = [ '@((http|https):){0,1}//(www\.){0,1}instagram\.com/p/(?[a-z0-9_-]+)@i' => 'shortcode', '@((http|https):){0,1}//(www\.){0,1}instagr\.am/p/(?[a-z0-9_-]+)@i' => 'shortcode', ]; /** * {@inheritdoc} */ public function providedFields() { return [ 'shortcode' => $this->t('Instagram shortcode'), 'id' => $this->t('Media ID'), 'type' => $this->t('Media type: image or video'), 'thumbnail' => $this->t('Link to the thumbnail'), 'thumbnail_local' => $this->t("Copies thumbnail locally and return it's URI"), 'thumbnail_local_uri' => $this->t('Returns local URI of the thumbnail'), 'username' => $this->t('Author of the post'), 'caption' => $this->t('Caption'), ]; } /** * {@inheritdoc} */ public function getField(MediaInterface $media, $name) { $matches = $this->matchRegexp($media); if (!$matches['shortcode']) { return FALSE; } if ($name == 'shortcode') { return $matches['shortcode']; } // If we have auth settings return the other fields. if ($instagram = $this->fetcher->fetchInstagramEmbed($matches['shortcode'])) { switch ($name) { case 'id': if (isset($instagram['media_id'])) { return $instagram['media_id']; } return FALSE; case 'type': if (isset($instagram['type'])) { return $instagram['type']; } return FALSE; case 'thumbnail': return 'http://instagram.com/p/' . $matches['shortcode'] . '/media/?size=m'; case 'thumbnail_local': $local_uri = $this->getField($media, 'thumbnail_local_uri'); if ($local_uri) { if (file_exists($local_uri)) { return $local_uri; } else { $directory = dirname($local_uri); file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); $image_url = $this->getField($media, 'thumbnail'); $response = $this->httpClient->get($image_url); if ($response->getStatusCode() == 200) { return file_unmanaged_save_data($response->getBody(), $local_uri, FILE_EXISTS_REPLACE); } } } return FALSE; case 'thumbnail_local_uri': if (isset($instagram['thumbnail_url'])) { return $this->configFactory->get('media_entity_instagram.settings')->get('local_images') . '/' . $matches['shortcode'] . '.' . pathinfo(parse_url($instagram['thumbnail_url'], PHP_URL_PATH), PATHINFO_EXTENSION); } return FALSE; case 'username': if (isset($instagram['author_name'])) { return $instagram['author_name']; } return FALSE; case 'caption': if (isset($instagram['title'])) { return $instagram['title']; } return FALSE; } } return FALSE; } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $options = []; $bundle = $form_state->getFormObject()->getEntity(); $allowed_field_types = ['string', 'string_long', 'link']; foreach ($this->entityFieldManager->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) { if (in_array($field->getType(), $allowed_field_types) && !$field->getFieldStorageDefinition()->isBaseField()) { $options[$field_name] = $field->getLabel(); } } $form['source_field'] = [ '#type' => 'select', '#title' => $this->t('Field with source information'), '#description' => $this->t('Field on media entity that stores Instagram embed code or URL. You can create a bundle without selecting a value for this dropdown initially. This dropdown can be populated after adding fields to the bundle.'), '#default_value' => empty($this->configuration['source_field']) ? NULL : $this->configuration['source_field'], '#options' => $options, ]; return $form; } /** * {@inheritdoc} */ public function attachConstraints(MediaInterface $media) { parent::attachConstraints($media); if (isset($this->configuration['source_field'])) { $source_field_name = $this->configuration['source_field']; if ($media->hasField($source_field_name)) { foreach ($media->get($source_field_name) as &$embed_code) { /** @var \Drupal\Core\TypedData\DataDefinitionInterface $typed_data */ $typed_data = $embed_code->getDataDefinition(); $typed_data->addConstraint('InstagramEmbedCode'); } } } } /** * Runs preg_match on embed code/URL. * * @param \Drupal\media_entity\MediaInterface $media * Media object. * * @return array|bool * Array of preg matches or FALSE if no match. * * @see preg_match() */ protected function matchRegexp(MediaInterface $media) { $matches = []; if (isset($this->configuration['source_field'])) { $source_field = $this->configuration['source_field']; if ($media->hasField($source_field)) { $property_name = $media->{$source_field}->first()->mainPropertyName(); foreach (static::$validationRegexp as $pattern => $key) { if (preg_match($pattern, $media->{$source_field}->{$property_name}, $matches)) { return $matches; } } } } return FALSE; } /** * {@inheritdoc} */ public function getDefaultThumbnail() { return $this->config->get('icon_base') . '/instagram.png'; } /** * {@inheritdoc} */ public function thumbnail(MediaInterface $media) { if ($local_image = $this->getField($media, 'thumbnail_local')) { return $local_image; } return $this->getDefaultThumbnail(); } /** * {@inheritdoc} */ public function getDefaultName(MediaInterface $media) { // Try to get some fields that need the API, if not available, just use the // shortcode as default name. $username = $this->getField($media, 'username'); $id = $this->getField($media, 'id'); if ($username && $id) { return $username . ' - ' . $id; } else { $code = $this->getField($media, 'shortcode'); if (!empty($code)) { return $code; } } return parent::getDefaultName($media); } }