View source
<?php
namespace Drupal\schema_metatag;
use Drupal\Component\Utility\Random;
class SchemaMetatagManager implements SchemaMetatagManagerInterface {
public static function parseJsonld(array &$elements) {
$schema_metatags = [];
foreach ($elements as $key => $item) {
if (!empty($item[0]['#attributes']['schema_metatag'])) {
$group = $item[0]['#attributes']['group'];
$name = $item[0]['#attributes']['name'];
$content = $item[0]['#attributes']['content'];
$schema_metatags[$group][$name] = $content;
unset($elements[$key]);
}
}
$items = [];
$group_key = 0;
foreach ($schema_metatags as $data) {
if (empty($items)) {
$items['@context'] = 'https://schema.org';
}
if (!empty($data)) {
$items['@graph'][$group_key] = $data;
}
$group_key++;
}
return $items;
}
public static function encodeJsonld(array $items) {
if (!empty($items)) {
return json_encode($items, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE);
}
else {
return '';
}
}
public static function renderArrayJsonLd($jsonld) {
return [
'#type' => 'html_tag',
'#tag' => 'script',
'#value' => $jsonld,
'#attributes' => [
'type' => 'application/ld+json',
],
];
}
public static function getRenderedJsonld($entity = NULL, $entity_type = NULL) {
if (empty($entity)) {
$entity = metatag_get_route_entity();
}
$metatag_manager = \Drupal::service('metatag.manager');
if (!empty($entity) && $entity instanceof ContentEntityInterface) {
foreach ($metatag_manager
->tagsFromEntity($entity) as $tag => $data) {
$metatags[$tag] = $data;
}
}
$context = [
'entity' => $entity,
];
\Drupal::service('module_handler')
->alter('metatags', $metatags, $context);
$elements = $metatag_manager
->generateElements($metatags, $entity);
if ($items = self::parseJsonld($elements)) {
if ($jsonld = self::encodeJsonld($items)) {
return \Drupal::service('renderer')
->render(self::renderArrayJsonLd($jsonld));
}
}
}
public static function pivot($content) {
if (!is_array($content) || empty($content)) {
return $content;
}
$count = max(array_map([
__CLASS__,
'countNumericKeys',
], $content));
$pivoted = [];
$exploded = [];
for ($i = 0; $i < $count; $i++) {
foreach ($content as $key => $item) {
if (is_array($item) && array_key_exists('pivot', $item)) {
unset($item['pivot']);
$item = self::pivot($item);
}
if (is_string($item) || !is_string($item) && self::countNumericKeys($item) <= $count) {
$exploded[$key] = [];
$prev = '';
for ($x = 0; $x < $count; $x++) {
if (!is_string($item) && self::countNumericKeys($item) > $x) {
$exploded[$key][$x] = $item[$x];
$prev = $item[$x];
}
elseif (!is_string($item) && self::countNumericKeys($item) > 0) {
$exploded[$key][$x] = $prev;
}
else {
$exploded[$key][$x] = $item;
}
}
$pivoted[$i][$key] = $exploded[$key][$i];
}
else {
$pivoted[$i][$key] = $item;
}
}
}
return $pivoted;
}
public static function countNumericKeys($item) {
if (!is_array($item)) {
return 0;
}
foreach (array_keys($item) as $key) {
if (!is_numeric($key)) {
return 0;
}
}
return count($item);
}
public static function explode($value) {
if (is_string($value)) {
$value = explode(',', $value);
}
if (is_array($value)) {
$value = array_map('trim', $value);
if (count($value) == 1) {
return $value[0];
}
}
return $value;
}
public static function serialize($value) {
if (is_array($value)) {
$trimmed = self::arrayTrim($value);
if (empty($trimmed)) {
return '';
}
else {
$value = serialize($trimmed);
}
}
return $value;
}
public static function unserialize($value) {
if (self::isSerialized($value)) {
$value = str_replace("\n", "", $value);
$value = self::recomputeSerializedLength($value);
if ($value = @unserialize($value)) {
$value = self::arrayTrim($value);
}
else {
$value = [];
}
}
return $value;
}
public static function isSerialized($value) {
if (!is_string($value)) {
return FALSE;
}
if ('N' == $value) {
return TRUE;
}
if (!preg_match('/^([adObis]):/', $value, $badions)) {
return FALSE;
}
switch ($badions[1]) {
case 'a':
case 'O':
case 's':
if (preg_match("/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $value)) {
return TRUE;
}
break;
case 'b':
case 'i':
case 'd':
if (preg_match("/^{$badions[1]}:[0-9.E-]+;\$/", $value)) {
return TRUE;
}
break;
}
return FALSE;
}
public static function arrayTrim($array) {
$needs_type = static::isObject($array);
foreach ($array as $key => &$value) {
if (empty($value)) {
unset($array[$key]);
}
else {
if (is_array($value)) {
$value = static::arrayTrim($value);
if (empty($value)) {
unset($array[$key]);
}
}
}
}
if ($array == [
'pivot' => 1,
]) {
return [];
}
if (count($array) == 1 && key($array) == '@type') {
return [];
}
if ($needs_type && is_array($array) && !array_key_exists('@type', $array) && !array_key_exists('@id', $array)) {
return [];
}
return (array) $array;
}
public static function isObject($array) {
return empty(static::countNumericKeys($array));
}
public static function recomputeSerializedLength($value) {
$value = preg_replace_callback('!s:(\\d+):"(.*?)";!', function ($match) {
return $match[1] == strlen($match[2]) ? $match[0] : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
}, $value);
return $value;
}
public static function randomString($length = 8) {
$randomGenerator = new Random();
if ($length < 4) {
return $randomGenerator
->string($length, TRUE);
}
$replacement_pos = floor($length / 2);
$string = $randomGenerator
->string($length - 2, TRUE);
return substr_replace($string, '>&', $replacement_pos, 0);
}
public static function randomMachineName($length = 8) {
$randomGenerator = new Random();
return $randomGenerator
->name($length, TRUE);
}
public static function defaultInputValues() {
return [
'title' => '',
'description' => '',
'value' => [],
'visibility_selector' => '',
'tree_parent' => [],
'tree_depth' => -1,
'multiple' => FALSE,
];
}
public static function altSelector($selector) {
$metatag_manager = \Drupal::service('metatag.manager');
$metatag_groups = $metatag_manager
->sortedGroupsWithTags();
$group = '';
$matches = [];
$regex = '/:input\\[name="(\\w+)\\[/';
preg_match($regex, $selector, $matches);
$id = $matches[1];
foreach ($metatag_groups as $group_info) {
if (!empty($group_info['tags'])) {
if (array_key_exists($id, $group_info['tags'])) {
$tag = $group_info['tags'][$id];
$group = $tag['group'];
break;
}
}
}
$original = $id . '[';
$alternate = 'field_metatags[0][' . $group . '][' . $id . '][';
$new = str_replace($original, $alternate, $selector);
return $new;
}
}