ww_publish-8.x-1.x-dev/src/Template.php
src/Template.php
<?php
namespace Drupal\ww_publish;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Render\Markup;
use \Drupal\ww_publish\Entity\TemplateEntity;
use Drupal\ww_publish\Entity\TemplateEntityInterface;
class Template {
/**
* A logger instance.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* SnsNotificationSubscriber constructor.
*
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory service.
*/
public function __construct(LoggerChannelFactoryInterface $logger_factory) {
$this->logger = $logger_factory->get('ww_publish');
}
/**
* Loads a template entity.
*
* @param string $target
* Identifier of the target WoodWing Studio component.
* @param string $type
* Type of the template: component, attribute.
*
* @return \Drupal\ww_publish\Entity\TemplateEntityInterface|null
* Either the matching template entity or NULL.
*/
protected function loadTemplate($target, $type): ?TemplateEntityInterface {
$query = \Drupal::entityQuery('ww_publish_template');
$query->accessCheck(FALSE);
$query->condition('target', $target);
$query->condition('type', $type);
$templateEntityIds = $query->execute();
if (!empty($templateEntityIds)) {
return TemplateEntity::load(reset($templateEntityIds));
}
return NULL;
}
/**
* Apply template.
*
* @param string $target
* Identifier of the target WoodWing Studio component.
* @param string $type
* Type of the template: component, attribute.
* @param array $parameters
* Parameters used in the template.
*
* @return string
*/
public function apply($target, $type, array $parameters): string {
if ($templateEntity = $this->loadTemplate($target, $type)) {
$template = $templateEntity->template;
$templateObjects = $this->parse($template);
$text = '';
foreach ($templateObjects as $templateObject) {
foreach ($parameters as $parameter => $content) {
if ($templateObject->dynamical && $parameter === $templateObject->parameter && !$templateObject->functions) {
$text .= $content;
}
// Backwards compatibility layer, if there is a single parameter and
// the template expects insert, apply the value.
elseif ($templateObject->dynamical && 'insert' === $templateObject->parameter && count($parameters) === 1) {
if (!empty($templateObject->functions)) {
foreach ($templateObject->functions as $function) {
$content = $this->applyFunction($content, $function);
}
}
$text .= $content;
}
elseif ($templateObject->dynamical && $parameter === $templateObject->parameter) {
foreach ($templateObject->functions as $function) {
$content = $this->applyFunction($content, $function);
}
$text .= $content;
}
elseif (!$templateObject->dynamical && !$templateObject->applied) {
$text .= $templateObject->content;
$templateObject->applied = TRUE;
}
}
}
return $text;
} else {
$this->logger->warning('No template entity found with target: @target and type: @type.', ['@target' => $target, '@type' => $type]);
return '';
}
}
/**
* Returns wether the given template is defined.
*
* @param string $target
* Identifier of the target WoodWing Studio component.
* @param string $type
* Type of the template: component, attribute.
*
* @return bool
*/
public function exist(string $target, string $type) {
return (bool) $this->loadTemplate($target, $type);
}
/**
* Parse the template.
*
* @param string $template
* Template to be parsed.
*
* @return array
*/
private function parse(string $template): array {
$splittedTemplate = preg_split("/({{.*}})/U", $template, -1, PREG_SPLIT_DELIM_CAPTURE);
$templateObjects = [];
foreach ($splittedTemplate as $templateSnippet) {
if (\strpos($templateSnippet, '{{') === 0) {
$parameterAndFunctions = explode('::', trim(str_replace(['{{', '}}'], '', $templateSnippet)));
$templateObjects[] = (object) [
'dynamical' => TRUE,
'parameter' => reset($parameterAndFunctions),
'functions' => count($parameterAndFunctions) > 1 ? array_slice($parameterAndFunctions, 1) : FALSE,
];
} else {
$templateObjects[] = (object) [
'dynamical' => FALSE,
'content' => $templateSnippet,
'applied' => FALSE,
];
}
}
return $templateObjects;
}
/**
* Apply a function.
*
* @param string $content
* Content which should be updated.
* @param string $function
* Name of the function from the template object.
*
* @return string
*/
private function applyFunction(string $content, string $function): string {
if ($function === 'toLower') {
return strtolower($content);
}
if ($function === 'toUpper') {
return strtoupper($content);
}
if (strpos($function, 'replace') === 0 && preg_match('/\((.*?)\)/U', $function, $match) === 1){
$replaceObject = json_decode($match[1]);
if (
property_exists($replaceObject, 'search') &&
property_exists($replaceObject, 'replace')
) {
return str_replace($replaceObject->search, $replaceObject->replace, $content);
}
}
return $content;
}
}
