X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fmodules%2Fcontrib%2Fmedia_entity_instagram%2Fsrc%2FPlugin%2FMediaEntity%2FType%2FInstagram.php;fp=web%2Fmodules%2Fcontrib%2Fmedia_entity_instagram%2Fsrc%2FPlugin%2FMediaEntity%2FType%2FInstagram.php;h=04e37568d125612d1e1da87c63a5512e69d22321;hb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;hp=0000000000000000000000000000000000000000;hpb=57c063afa3f66b07c4bbddc2d6129a96d90f0aad;p=yaffs-website diff --git a/web/modules/contrib/media_entity_instagram/src/Plugin/MediaEntity/Type/Instagram.php b/web/modules/contrib/media_entity_instagram/src/Plugin/MediaEntity/Type/Instagram.php new file mode 100644 index 000000000..04e37568d --- /dev/null +++ b/web/modules/contrib/media_entity_instagram/src/Plugin/MediaEntity/Type/Instagram.php @@ -0,0 +1,361 @@ +get('media_entity.settings')); + $this->configFactory = $config_factory; + } + + /** + * {@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') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'use_instagram_api' => FALSE, + ]; + } + + /** + * List of validation regular expressions. + * + * @var array + */ + public static $validationRegexp = array( + '@((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() { + $fields = array( + 'shortcode' => $this->t('Instagram shortcode'), + ); + + if ($this->configuration['use_instagram_api']) { + $fields += array( + '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'), + 'tags' => $this->t('Tags'), + ); + } + + return $fields; + } + + /** + * {@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 ($this->configuration['use_instagram_api'] && $instagram = $this->fetchInstagram($matches['shortcode'])) { + switch ($name) { + case 'id': + if (isset($instagram->id)) { + return $instagram->id; + } + return FALSE; + + case 'type': + if (isset($instagram->type)) { + return $instagram->type; + } + return FALSE; + + case 'thumbnail': + if (isset($instagram->images->thumbnail->url)) { + return $instagram->images->thumbnail->url; + } + return FALSE; + + case 'thumbnail_local': + if (isset($instagram->images->thumbnail->url)) { + $local_uri = $this->configFactory->get('media_entity_instagram.settings')->get('local_images') . '/' . $matches['shortcode'] . '.' . pathinfo($instagram->images->thumbnail->url, PATHINFO_EXTENSION); + + if (!file_exists($local_uri)) { + file_prepare_directory($local_uri, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); + + $image = file_get_contents($local_uri); + file_unmanaged_save_data($image, $local_uri, FILE_EXISTS_REPLACE); + + return $local_uri; + } + } + return FALSE; + + case 'thumbnail_local_uri': + if (isset($instagram->images->thumbnail->url)) { + return $this->configFactory->get('media_entity_instagram.settings')->get('local_images') . '/' . $matches['shortcode'] . '.' . pathinfo($instagram->images->thumbnail->url, PATHINFO_EXTENSION); + } + return FALSE; + + case 'username': + if (isset($instagram->user->username)) { + return $instagram->user->username; + } + return FALSE; + + case 'caption': + if (isset($instagram->caption->text)) { + return $instagram->caption->text; + } + return FALSE; + + case 'tags': + if (isset($instagram->tags)) { + return implode(" ", $instagram->tags); + } + 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, + ]; + + $form['use_instagram_api'] = [ + '#type' => 'select', + '#title' => $this->t('Whether to use Instagram api to fetch instagrams or not.'), + '#description' => $this->t("In order to use Instagram's api you have to create a developer account and an application. For more information consult the readme file."), + '#default_value' => empty($this->configuration['use_instagram_api']) ? 0 : $this->configuration['use_instagram_api'], + '#options' => [ + 0 => $this->t('No'), + 1 => $this->t('Yes'), + ], + ]; + + // @todo Evaluate if this should be a site-wide configuration. + $form['client_id'] = [ + '#type' => 'textfield', + '#title' => $this->t('Client ID'), + '#default_value' => empty($this->configuration['client_id']) ? NULL : $this->configuration['client_id'], + '#states' => [ + 'visible' => [ + ':input[name="type_configuration[instagram][use_instagram_api]"]' => ['value' => '1'], + ], + ], + ]; + + 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 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 = array(); + + 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; + } + + /** + * Get a single instagram. + * + * @param string $shortcode + * The instagram shortcode. + */ + protected function fetchInstagram($shortcode) { + $instagram = &drupal_static(__FUNCTION__); + + if (!isset($instagram)) { + // Check for dependencies. + // @todo There is perhaps a better way to do that. + if (!class_exists('\Instagram\Instagram')) { + drupal_set_message($this->t('Instagram library is not available. Consult the README.md for installation instructions.'), 'error'); + return; + } + + if (!isset($this->configuration['client_id'])) { + drupal_set_message($this->t('The client ID is not available. Consult the README.md for installation instructions.'), 'error'); + return; + } + if (empty($this->configuration['client_id'])) { + drupal_set_message($this->t('The client ID is missing. Please add it in your Instagram settings.'), 'error'); + return; + } + $instagram_object = new InstagramApi(); + $instagram_object->setClientID($this->configuration['client_id']); + $result = $instagram_object->getMediaByShortcode($shortcode)->getData(); + + if ($result) { + return $result; + } + else { + throw new MediaTypeException(NULL, 'The media could not be retrieved.'); + } + } + } + + /** + * {@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); + } + +}