View source
<?php
namespace Drupal\avatars;
use Drupal\Core\File\FileSystemInterface;
use Drupal\avatars\Entity\AvatarPreview;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\file\FileUsage\FileUsageInterface;
use Drupal\file\FileInterface;
use Drupal\user\UserInterface;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ClientException;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
class AvatarManager implements AvatarManagerInterface {
use ContainerAwareTrait;
use StringTranslationTrait;
protected $configFactory;
protected $httpClient;
protected $cacheTagInvalidator;
protected $loggerFactory;
protected $fileUsage;
protected $avatarGeneratorStorage;
protected $avatarGenerator;
public function __construct(ConfigFactoryInterface $config_factory, ClientInterface $http_client, CacheTagsInvalidatorInterface $cache_tag_invalidator, LoggerChannelFactoryInterface $logger_factory, EntityTypeManagerInterface $entity_type_manager, FileUsageInterface $file_usage, AvatarGeneratorPluginManagerInterface $avatar_generator) {
$this->configFactory = $config_factory;
$this->httpClient = $http_client;
$this->cacheTagInvalidator = $cache_tag_invalidator;
$this->loggerFactory = $logger_factory;
$this->avatarGeneratorStorage = $entity_type_manager
->getStorage('avatar_generator');
$this->fileUsage = $file_usage;
$this->avatarGenerator = $avatar_generator;
}
public function syncAvatar(UserInterface $user) {
if ($user
->isAnonymous()) {
return;
}
$field_item_list =& $user->{AK_FIELD_PICTURE_ACTIVE};
$file1 = isset($field_item_list->entity) ? $field_item_list->entity : NULL;
$avatar_preview = $this
->findValidAvatar($user);
$file2 = $avatar_preview ? $avatar_preview
->getAvatar() : NULL;
if ($file1 !== $file2) {
$user->{AK_FIELD_PICTURE_ACTIVE} = $file2;
$user
->save();
}
}
public function findValidAvatar(UserInterface $user) {
foreach ($this
->getPreferences($user) as $avatar_generator => $scope) {
$avatar_generator = $this->avatarGeneratorStorage
->load($avatar_generator);
if ($avatar_generator instanceof AvatarGeneratorInterface) {
$this
->refreshAvatarGenerator($user, $avatar_generator, $scope);
if ($avatar_preview = AvatarPreview::getAvatarPreview($avatar_generator, $user)) {
if ($avatar_preview
->getAvatar()) {
return $avatar_preview;
}
}
}
}
return NULL;
}
public function refreshAvatarGenerator(UserInterface $user, AvatarGeneratorInterface $avatar_generator, $scope) {
if ($user
->isNew()) {
return FALSE;
}
if ($avatar_preview = AvatarPreview::getAvatarPreview($avatar_generator, $user)) {
if ($scope != AvatarPreviewInterface::SCOPE_TEMPORARY && $scope != $avatar_preview
->getScope()) {
$avatar_preview
->setScope($scope)
->save();
}
}
else {
$file = $this
->getAvatarFile($avatar_generator, $user);
$avatar_preview = AvatarPreview::create()
->setAvatarGeneratorId($avatar_generator
->id())
->setAvatar($file instanceof FileInterface ? $file : NULL)
->setUser($user)
->setScope($file instanceof FileInterface ? $scope : AvatarPreviewInterface::SCOPE_TEMPORARY);
$avatar_preview
->save();
}
return $avatar_preview;
}
public function refreshAllAvatars(UserInterface $user) {
$previews = [];
foreach ($this
->getAvatarGeneratorsForUser($user) as $avatar_generator) {
$avatar_preview = $this
->refreshAvatarGenerator($user, $avatar_generator, AvatarPreviewInterface::SCOPE_TEMPORARY);
if ($avatar_preview) {
$previews[] = $avatar_preview;
}
}
return $previews;
}
public function getAvatarFile(AvatarGeneratorInterface $avatar_generator, UserInterface $user) {
$plugin = $avatar_generator
->getPlugin();
$file = $plugin
->getFile($user);
if (!$file && ($url = $plugin
->generateUri($user))) {
$directory = 'public://avatar_kit/' . $avatar_generator
->id();
$fileSystem = \Drupal::service('file_system');
if ($fileSystem
->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY)) {
try {
if (($result = $this->httpClient
->get($url)) && $result
->getStatusCode() == 200) {
$file_path = $directory . '/' . $user
->id() . '.jpg';
$file = file_save_data($result
->getBody(), $file_path, FileSystemInterface::EXISTS_REPLACE);
}
} catch (ClientException $e) {
return FALSE;
} catch (\Exception $e) {
$this->loggerFactory
->get('avatars')
->error($this
->t('Failed to get @id avatar for @generator: %exception', [
'@id' => $user
->id(),
'@generator' => $avatar_generator
->id(),
'%exception' => $e
->getMessage(),
]));
return FALSE;
}
}
else {
throw new \Exception('Cannot create avatar kit directory.');
}
}
return $file;
}
public function getPreferences(UserInterface $user) {
$avatar_generators = $this
->getAvatarGeneratorsForUser($user, FALSE);
uasort($avatar_generators, '\\Drupal\\avatars\\Entity\\AvatarGenerator::sort');
foreach ($avatar_generators as $avatar_generator) {
$id = $avatar_generator
->id();
if ($avatar_generator
->getPlugin()
->getPluginId() == 'user_preference') {
$id = $user->{AK_FIELD_AVATAR_GENERATOR}->value;
$scope = AvatarPreviewInterface::SCOPE_USER_SELECTED;
}
else {
$scope = AvatarPreviewInterface::SCOPE_SITE_FALLBACK;
}
if ($id) {
(yield $id => $scope);
}
}
}
public function invalidateUserAvatar(UserInterface $user) {
if (isset($user->{AK_FIELD_PICTURE_ACTIVE}->entity)) {
$this->cacheTagInvalidator
->invalidateTags($user->{AK_FIELD_PICTURE_ACTIVE}->entity
->getCacheTags());
}
}
public function notifyDynamicChange(AvatarGeneratorInterface $avatar_generator, UserInterface $user) {
if ($avatar_preview = AvatarPreview::getAvatarPreview($avatar_generator, $user)) {
$avatar_preview
->delete();
}
}
public function getAvatarGeneratorsForUser(UserInterface $user, $exclude_user_preference = TRUE) {
$avatar_generators = [];
foreach ($this->avatarGeneratorStorage
->getEnabledAvatarGenerators() as $avatar_generator) {
if ($avatar_generator
->getPlugin()
->getPluginId() == 'user_preference') {
if ($exclude_user_preference) {
continue;
}
}
elseif (!$user
->hasPermission("avatars avatar_generator user " . $avatar_generator
->id())) {
continue;
}
$avatar_generators[] = $avatar_generator;
}
return $avatar_generators;
}
public function getAvatarPreviewByFile(FileInterface $file) {
$usages = $this->fileUsage
->listUsage($file);
if (isset($usages['avatars']['avatars_preview'])) {
$avatar_previews = array_keys($usages['avatars']['avatars_preview']);
return reset($avatar_previews);
}
return FALSE;
}
}