vendor/contao/core-bundle/src/Routing/ResponseContext/JsonLd/JsonLdManager.php line 21

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of Contao.
  5. *
  6. * (c) Leo Feyer
  7. *
  8. * @license LGPL-3.0-or-later
  9. */
  10. namespace Contao\CoreBundle\Routing\ResponseContext\JsonLd;
  11. use Contao\ArrayUtil;
  12. use Contao\CoreBundle\Event\JsonLdEvent;
  13. use Contao\CoreBundle\Routing\ResponseContext\ResponseContext;
  14. use Spatie\SchemaOrg\Graph;
  15. use Spatie\SchemaOrg\Type;
  16. class JsonLdManager
  17. {
  18. public const SCHEMA_ORG = 'https://schema.org';
  19. public const SCHEMA_CONTAO = 'https://schema.contao.org';
  20. private ResponseContext $responseContext;
  21. /**
  22. * @var array<Graph>
  23. */
  24. private array $graphs = [];
  25. public function __construct(ResponseContext $responseContext)
  26. {
  27. $this->responseContext = $responseContext;
  28. }
  29. public function getGraphForSchema(string $schema): Graph
  30. {
  31. $schema = rtrim($schema, '/');
  32. if (!\array_key_exists($schema, $this->graphs)) {
  33. $this->graphs[$schema] = new Graph($schema);
  34. }
  35. return $this->graphs[$schema];
  36. }
  37. public function getGraphs(): array
  38. {
  39. return $this->graphs;
  40. }
  41. public function collectFinalScriptFromGraphs(): string
  42. {
  43. $data = [];
  44. $this->responseContext->dispatchEvent(new JsonLdEvent());
  45. foreach ($this->getGraphs() as $graph) {
  46. $data[] = $graph->toArray();
  47. }
  48. // Reset the graphs
  49. $this->graphs = [];
  50. if (0 === \count($data)) {
  51. return '';
  52. }
  53. ArrayUtil::recursiveKeySort($data);
  54. $return = [];
  55. // Create one <script> block per JSON-LD context (see #6401)
  56. foreach ($data as $context) {
  57. $return[] = sprintf(
  58. "<script type=\"application/ld+json\">\n%s\n</script>",
  59. json_encode($context, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
  60. );
  61. }
  62. return implode("\n", $return);
  63. }
  64. /**
  65. * @throws \InvalidArgumentException
  66. */
  67. public function createSchemaOrgTypeFromArray(array $jsonLd): Type
  68. {
  69. if (!isset($jsonLd['@type'])) {
  70. throw new \InvalidArgumentException('Must provide the @type property!');
  71. }
  72. $schemaClass = '\Spatie\SchemaOrg\\'.$jsonLd['@type'];
  73. if (!class_exists($schemaClass)) {
  74. throw new \InvalidArgumentException(sprintf('Unknown schema.org type "%s" provided!', $jsonLd['@type']));
  75. }
  76. $schema = new $schemaClass();
  77. unset($jsonLd['@type']);
  78. foreach ($jsonLd as $k => $v) {
  79. if (\is_array($v) && isset($v['@type'])) {
  80. $v = $this->createSchemaOrgTypeFromArray($v);
  81. }
  82. $schema->setProperty($k, $v);
  83. }
  84. return $schema;
  85. }
  86. }