View source
<?php
namespace Drupal\textimage;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\Core\StreamWrapper\StreamWrapperManager;
use Drupal\Core\Utility\Token;
use Drupal\image\Entity\ImageStyle;
use Drupal\image\ImageStyleInterface;
use Psr\Log\LoggerInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
class TextimageFactory implements TextimageFactoryInterface {
protected $token;
protected $logger;
protected $streamWrapperManager;
protected $cache;
protected $configFactory;
protected $currentUser;
protected $userStorage;
protected $fileSystem;
public function __construct(ConfigFactoryInterface $config_factory, Token $token_service, LoggerInterface $logger, CacheBackendInterface $cache_service, AccountInterface $current_user, StreamWrapperManager $stream_wrapper_manager, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system) {
$this->configFactory = $config_factory;
$this->token = $token_service;
$this->logger = $logger;
$this->cache = $cache_service;
$this->currentUser = $current_user;
$this->streamWrapperManager = $stream_wrapper_manager;
$this->userStorage = $entity_type_manager
->getStorage('user');
$this->fileSystem = $file_system;
}
public function get(BubbleableMetadata $bubbleable_metadata = NULL) {
$textimage = Textimage::create(\Drupal::getContainer());
$textimage
->setBubbleableMetadata($bubbleable_metadata);
return $textimage;
}
public function load($tiid) {
$textimage = $this
->get();
$textimage
->load($tiid);
return $textimage;
}
public function processTextString($text, $case_format, array $token_data = [], BubbleableMetadata $bubbleable_metadata = NULL) {
$token_data['user'] = !empty($token_data['user']) ? $token_data['user'] : $this->userStorage
->load($this->currentUser
->id());
return $this->token
->replace($text, $token_data, [], $bubbleable_metadata);
}
public function getState($variable = NULL) {
if ($variable) {
return $this
->setState($variable);
}
return NULL;
}
public function setState($variable = NULL, $value = NULL) {
static $keys;
if (!isset($keys) or !$variable) {
$keys = [];
}
if ($variable) {
if ($value) {
$keys[$variable] = $value;
return $value;
}
else {
return isset($keys[$variable]) ? $keys[$variable] : NULL;
}
}
}
public function isTextimage(ImageStyleInterface $image_style) {
foreach ($image_style
->getEffects() as $effect) {
$definition = $effect
->getPluginDefinition();
if ($definition['id'] == 'image_effects_text_overlay') {
return TRUE;
}
}
return FALSE;
}
public function getTextimageStyleOptions($limit_to_textimage = FALSE) {
$image_styles = ImageStyle::loadMultiple();
$options = [];
foreach ($image_styles as $name => $image_style) {
if ($limit_to_textimage) {
if ($this
->isTextimage($image_style)) {
$options[$name] = $image_style
->label();
}
}
else {
$options[$name] = $image_style
->label();
}
}
return $options;
}
public function flushStyle(ImageStyleInterface $style) {
$wrappers = $this->streamWrapperManager
->getWrappers(StreamWrapperInterface::WRITE_VISIBLE);
foreach ($wrappers as $wrapper => $wrapper_data) {
if (file_exists($directory = $this
->getStoreUri('/cache/styles/', $wrapper) . $style
->id())) {
$this->fileSystem
->deleteRecursive($directory);
}
}
if (file_exists($directory = 'public://textimage/' . $style
->id())) {
$this->fileSystem
->deleteRecursive($directory);
}
}
public function flushAll() {
$styles = ImageStyle::loadMultiple();
foreach ($styles as $style) {
$style
->flush();
}
$wrappers = $this->streamWrapperManager
->getWrappers(StreamWrapperInterface::WRITE_VISIBLE);
foreach ($wrappers as $wrapper => $wrapper_data) {
if (file_exists($directory = $this
->getStoreUri(NULL, $wrapper))) {
$this->fileSystem
->deleteRecursive($directory);
}
}
if (file_exists($directory = 'public://textimage')) {
$this->fileSystem
->deleteRecursive($directory);
}
$this->cache
->deleteAll();
$this->logger
->notice('All Textimage images were removed.');
}
public function getStoreUri($path, $scheme = NULL) {
if (!$scheme) {
$scheme = $this->configFactory
->get('system.file')
->get('default_scheme');
}
return $scheme . '://textimage_store' . $path;
}
public function processTokens($key, array $tokens, array $data, BubbleableMetadata $bubbleable_metadata) {
$node = isset($data['node']) ? $data['node'] : NULL;
static $nesting_level;
static $field_stack;
if (!isset($nesting_level)) {
$nesting_level = 0;
$field_stack = [];
}
else {
$nesting_level++;
}
$sub_tokens = $this->token
->findWithPrefix($tokens, $key);
if (empty($sub_tokens) || !$node) {
$this
->rollbackStack($nesting_level, $field_stack);
return [];
}
$replacements = [];
foreach ($sub_tokens as $sub_token => $original) {
unset($field_stack[$nesting_level]);
$sub_token_array = explode(':', $sub_token);
$field_name = isset($sub_token_array[0]) ? $sub_token_array[0] : NULL;
if (!$field_name) {
continue;
}
if (in_array($field_name, $field_stack)) {
$this
->rollbackStack($nesting_level, $field_stack);
throw new TextimageTokenException($original);
}
$field_stack[$nesting_level] = $field_name;
$display_mode = isset($sub_token_array[1]) ? $sub_token_array[1] ?: 'default' : 'default';
$index = isset($sub_token_array[2]) ? $sub_token_array[2] : NULL;
if (!($field_info = $node
->getFieldDefinition($field_name))) {
continue;
}
$entity_display = EntityViewDisplay::load('node.' . $node
->getType() . '.' . $display_mode);
if (!$entity_display) {
continue;
}
$entity_display_component = $entity_display
->getComponent($field_name);
if (empty($entity_display_component['type'])) {
continue;
}
if (in_array($entity_display_component['type'], [
'textimage_text_field_formatter',
'textimage_image_field_formatter',
])) {
$image_style_name = isset($entity_display_component['settings']['image_style']) ? $entity_display_component['settings']['image_style'] : NULL;
if (!$image_style_name) {
continue;
}
$image_style = ImageStyle::load($image_style_name);
$items = $node
->get($field_name);
if (in_array($field_info
->getFieldStorageDefinition()
->getTypeProvider(), [
'text',
'core',
])) {
$text = $this
->getTextFieldText($items);
if ($field_info
->getFieldStorageDefinition()
->getCardinality() != 1 && $entity_display_component['settings']['image_text_values'] == 'itemize') {
try {
$ret = [];
foreach ($text as $text_value) {
$textimage = $this
->get($bubbleable_metadata)
->setStyle($image_style)
->setTokenData($data)
->process($text_value);
$ret[] = $this
->getTokenReplacement($textimage, $key);
}
if (!is_null($index) && isset($ret[$index])) {
$replacements[$original] = $ret[$index];
}
else {
$replacements[$original] = implode(',', $ret);
}
} catch (TextimageTokenException $e) {
$replacements[$original] = str_replace('textimage', 'void-textimage', $original);
if ($nesting_level > 0) {
$this
->rollbackStack($nesting_level, $field_stack);
throw new TextimageTokenException($e
->getToken());
}
else {
$this->logger
->warning('Textimage token @token in node \'@node_title\' can not be resolved (circular reference). Remove the token to avoid this message.', [
'@token' => $original,
'@node_title' => $node
->getTitle(),
]);
}
}
}
else {
try {
$textimage = $this
->get($bubbleable_metadata)
->setStyle($image_style)
->setTokenData($data)
->process($text);
$replacements[$original] = $this
->getTokenReplacement($textimage, $key);
} catch (TextimageTokenException $e) {
$replacements[$original] = str_replace('textimage', 'void-textimage', $original);
if ($nesting_level > 0) {
$this
->rollbackStack($nesting_level, $field_stack);
throw new TextimageTokenException($e
->getToken());
}
else {
$this->logger
->warning('Textimage token @token in node \'@node_title\' can not be resolved (circular reference). Remove the token to avoid this message.', [
'@token' => $original,
'@node_title' => $node
->getTitle(),
]);
}
}
}
}
elseif ($field_info
->getFieldStorageDefinition()
->getTypeProvider() == 'image') {
try {
$ret = [];
foreach ($items as $item) {
$item_value = $item
->getValue();
$textimage = $this
->get($bubbleable_metadata)
->setStyle($image_style)
->setTokenData($data)
->setSourceImageFile($item->entity, $item_value['width'], $item_value['height'])
->process(NULL);
$ret[] = $this
->getTokenReplacement($textimage, $key);
}
if (!is_null($index) && isset($ret[$index])) {
$replacements[$original] = $ret[$index];
}
else {
$replacements[$original] = implode(',', $ret);
}
} catch (TextimageTokenException $e) {
$replacements[$original] = str_replace('textimage', 'void-textimage', $original);
if ($nesting_level > 0) {
$this
->rollbackStack($nesting_level, $field_stack);
throw new TextimageTokenException($e
->getToken());
}
else {
$this->logger
->warning('Textimage token @token in node \'@node_title\' can not be resolved (circular reference). Remove the token to avoid this message.', [
'@token' => $original,
'@node_title' => $node
->getTitle(),
]);
}
}
}
}
}
$this
->rollbackStack($nesting_level, $field_stack);
return $replacements;
}
protected function getTokenReplacement(TextimageInterface $textimage, $key) {
switch ($key) {
case 'uri':
return $textimage
->getUri();
case 'url':
return $textimage
->getUrl()
->toString();
}
}
protected function rollbackStack(&$nesting_level, &$field_stack) {
if ($nesting_level) {
unset($field_stack[$nesting_level]);
$nesting_level--;
}
else {
$nesting_level = NULL;
}
}
public function getTextFieldText(FieldItemListInterface $items) {
$text = [];
foreach ($items as $item) {
$value = $item
->getValue();
$text[] = !empty($value['value']) ? $value['value'] : '';
}
return $text;
}
}