include_path
.
+ *
+ * @author Roman Borschel
+ *
+ *
+ *
+ * @param string $string The string to operate on.
+ * @param string $delimiters A list of word separators.
+ *
+ * @return string The string with all delimiter-separated words capitalized.
+ *
+ * @deprecated
+ */
+ public static function ucwords(string $string, string $delimiters = " \n\t\r\0\x0B-") : string
+ {
+ @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please use the "ucwords" function instead.', __METHOD__), E_USER_DEPRECATED);
+
+ return ucwords($string, $delimiters);
+ }
+
+ /**
+ * Clears Inflectors inflected value caches, and resets the inflection
+ * rules to the initial values.
+ *
+ * @deprecated
+ */
+ public static function reset() : void
+ {
+ @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED);
+
+ self::$factory = null;
+ self::$instance = null;
+ }
+
+ /**
+ * Adds custom inflection $rules, of either 'plural' or 'singular' $type.
+ *
+ * ### Usage:
+ *
+ * {{{
+ * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
+ * Inflector::rules('plural', array(
+ * 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
+ * 'uninflected' => array('dontinflectme'),
+ * 'irregular' => array('red' => 'redlings')
+ * ));
+ * }}}
+ *
+ * @param string $type The type of inflection, either 'plural' or 'singular'
+ * @param array
+ * capitalize($string);
+ * // Top-O-The-Morning To All_of_you!
+ *
+ * echo $inflector->capitalize($string, '-_ ');
+ * // Top-O-The-Morning To All_Of_You!
+ * ?>
+ *
+ *
+ * @param string $string The string to operate on.
+ * @param string $delimiters A list of word separators.
+ *
+ * @return string The string with all delimiter-separated words capitalized.
+ */
+ public function capitalize(string $string, string $delimiters = " \n\t\r\0\x0B-"): string
+ {
+ return ucwords($string, $delimiters);
+ }
+
+ /**
+ * Checks if the given string seems like it has utf8 characters in it.
+ *
+ * @param string $string The string to check for utf8 characters in.
+ */
+ public function seemsUtf8(string $string): bool
+ {
+ for ($i = 0; $i < strlen($string); $i++) {
+ if (ord($string[$i]) < 0x80) {
+ continue; // 0bbbbbbb
+ }
+
+ if ((ord($string[$i]) & 0xE0) === 0xC0) {
+ $n = 1; // 110bbbbb
+ } elseif ((ord($string[$i]) & 0xF0) === 0xE0) {
+ $n = 2; // 1110bbbb
+ } elseif ((ord($string[$i]) & 0xF8) === 0xF0) {
+ $n = 3; // 11110bbb
+ } elseif ((ord($string[$i]) & 0xFC) === 0xF8) {
+ $n = 4; // 111110bb
+ } elseif ((ord($string[$i]) & 0xFE) === 0xFC) {
+ $n = 5; // 1111110b
+ } else {
+ return false; // Does not match any model
+ }
+
+ for ($j = 0; $j < $n; $j++) { // n bytes matching 10bbbbbb follow ?
+ if (++$i === strlen($string) || ((ord($string[$i]) & 0xC0) !== 0x80)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove any illegal characters, accents, etc.
+ *
+ * @param string $string String to unaccent
+ *
+ * @return string Unaccented string
+ */
+ public function unaccent(string $string): string
+ {
+ if (preg_match('/[\x80-\xff]/', $string) === false) {
+ return $string;
+ }
+
+ if ($this->seemsUtf8($string)) {
+ $string = strtr($string, self::ACCENTED_CHARACTERS);
+ } else {
+ $characters = [];
+
+ // Assume ISO-8859-1 if not UTF-8
+ $characters['in'] =
+ chr(128)
+ . chr(131)
+ . chr(138)
+ . chr(142)
+ . chr(154)
+ . chr(158)
+ . chr(159)
+ . chr(162)
+ . chr(165)
+ . chr(181)
+ . chr(192)
+ . chr(193)
+ . chr(194)
+ . chr(195)
+ . chr(196)
+ . chr(197)
+ . chr(199)
+ . chr(200)
+ . chr(201)
+ . chr(202)
+ . chr(203)
+ . chr(204)
+ . chr(205)
+ . chr(206)
+ . chr(207)
+ . chr(209)
+ . chr(210)
+ . chr(211)
+ . chr(212)
+ . chr(213)
+ . chr(214)
+ . chr(216)
+ . chr(217)
+ . chr(218)
+ . chr(219)
+ . chr(220)
+ . chr(221)
+ . chr(224)
+ . chr(225)
+ . chr(226)
+ . chr(227)
+ . chr(228)
+ . chr(229)
+ . chr(231)
+ . chr(232)
+ . chr(233)
+ . chr(234)
+ . chr(235)
+ . chr(236)
+ . chr(237)
+ . chr(238)
+ . chr(239)
+ . chr(241)
+ . chr(242)
+ . chr(243)
+ . chr(244)
+ . chr(245)
+ . chr(246)
+ . chr(248)
+ . chr(249)
+ . chr(250)
+ . chr(251)
+ . chr(252)
+ . chr(253)
+ . chr(255);
+
+ $characters['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
+
+ $string = strtr($string, $characters['in'], $characters['out']);
+
+ $doubleChars = [];
+
+ $doubleChars['in'] = [
+ chr(140),
+ chr(156),
+ chr(198),
+ chr(208),
+ chr(222),
+ chr(223),
+ chr(230),
+ chr(240),
+ chr(254),
+ ];
+
+ $doubleChars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];
+
+ $string = str_replace($doubleChars['in'], $doubleChars['out'], $string);
+ }
+
+ return $string;
+ }
+
+ /**
+ * Convert any passed string to a url friendly string.
+ * Converts 'My first blog post' to 'my-first-blog-post'
+ *
+ * @param string $string String to urlize.
+ *
+ * @return string Urlized string.
+ */
+ public function urlize(string $string): string
+ {
+ // Remove all non url friendly characters with the unaccent function
+ $unaccented = $this->unaccent($string);
+
+ if (function_exists('mb_strtolower')) {
+ $lowered = mb_strtolower($unaccented);
+ } else {
+ $lowered = strtolower($unaccented);
+ }
+
+ $replacements = [
+ '/\W/' => ' ',
+ '/([A-Z]+)([A-Z][a-z])/' => '\1_\2',
+ '/([a-z\d])([A-Z])/' => '\1_\2',
+ '/[^A-Z^a-z^0-9^\/]+/' => '-',
+ ];
+
+ $urlized = $lowered;
+
+ foreach ($replacements as $pattern => $replacement) {
+ $replaced = preg_replace($pattern, $replacement, $urlized);
+
+ if ($replaced === null) {
+ throw new RuntimeException(sprintf(
+ 'preg_replace returned null for value "%s"',
+ $urlized
+ ));
+ }
+
+ $urlized = $replaced;
+ }
+
+ return trim($urlized, '-');
+ }
+
+ /**
+ * Returns a word in singular form.
+ *
+ * @param string $word The word in plural form.
+ *
+ * @return string The word in singular form.
+ */
+ public function singularize(string $word): string
+ {
+ return $this->singularizer->inflect($word);
+ }
+
+ /**
+ * Returns a word in plural form.
+ *
+ * @param string $word The word in singular form.
+ *
+ * @return string The word in plural form.
+ */
+ public function pluralize(string $word): string
+ {
+ return $this->pluralizer->inflect($word);
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php
new file mode 100644
index 000000000..a0740a741
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php
@@ -0,0 +1,52 @@
+getFlippedSubstitutions()
+ );
+ }
+
+ public static function getPluralRuleset(): Ruleset
+ {
+ return new Ruleset(
+ new Transformations(...Inflectible::getPlural()),
+ new Patterns(...Uninflected::getPlural()),
+ new Substitutions(...Inflectible::getIrregular())
+ );
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php
new file mode 100644
index 000000000..e2656cc45
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php
@@ -0,0 +1,193 @@
+getFlippedSubstitutions()
+ );
+ }
+
+ public static function getPluralRuleset(): Ruleset
+ {
+ return new Ruleset(
+ new Transformations(...Inflectible::getPlural()),
+ new Patterns(...Uninflected::getPlural()),
+ new Substitutions(...Inflectible::getIrregular())
+ );
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php
new file mode 100644
index 000000000..3cf2444ae
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php
@@ -0,0 +1,34 @@
+getFlippedSubstitutions()
+ );
+ }
+
+ public static function getPluralRuleset(): Ruleset
+ {
+ return new Ruleset(
+ new Transformations(...Inflectible::getPlural()),
+ new Patterns(...Uninflected::getPlural()),
+ new Substitutions(...Inflectible::getIrregular())
+ );
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php
new file mode 100644
index 000000000..5d878c6d2
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php
@@ -0,0 +1,36 @@
+pattern = $pattern;
+
+ if (isset($this->pattern[0]) && $this->pattern[0] === '/') {
+ $this->regex = $this->pattern;
+ } else {
+ $this->regex = '/' . $this->pattern . '/i';
+ }
+ }
+
+ public function getPattern(): string
+ {
+ return $this->pattern;
+ }
+
+ public function getRegex(): string
+ {
+ return $this->regex;
+ }
+
+ public function matches(string $word): bool
+ {
+ return preg_match($this->getRegex(), $word) === 1;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php
new file mode 100644
index 000000000..e8d45cb75
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php
@@ -0,0 +1,34 @@
+patterns = $patterns;
+
+ $patterns = array_map(static function (Pattern $pattern): string {
+ return $pattern->getPattern();
+ }, $this->patterns);
+
+ $this->regex = '/^(?:' . implode('|', $patterns) . ')$/i';
+ }
+
+ public function matches(string $word): bool
+ {
+ return preg_match($this->regex, $word, $regs) === 1;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php
new file mode 100644
index 000000000..95564d495
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php
@@ -0,0 +1,104 @@
+getFlippedSubstitutions()
+ );
+ }
+
+ public static function getPluralRuleset(): Ruleset
+ {
+ return new Ruleset(
+ new Transformations(...Inflectible::getPlural()),
+ new Patterns(...Uninflected::getPlural()),
+ new Substitutions(...Inflectible::getIrregular())
+ );
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php
new file mode 100644
index 000000000..58c34f9b5
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php
@@ -0,0 +1,38 @@
+regular = $regular;
+ $this->uninflected = $uninflected;
+ $this->irregular = $irregular;
+ }
+
+ public function getRegular(): Transformations
+ {
+ return $this->regular;
+ }
+
+ public function getUninflected(): Patterns
+ {
+ return $this->uninflected;
+ }
+
+ public function getIrregular(): Substitutions
+ {
+ return $this->irregular;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php
new file mode 100644
index 000000000..c6862fa40
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php
@@ -0,0 +1,53 @@
+getFlippedSubstitutions()
+ );
+ }
+
+ public static function getPluralRuleset(): Ruleset
+ {
+ return new Ruleset(
+ new Transformations(...Inflectible::getPlural()),
+ new Patterns(...Uninflected::getPlural()),
+ new Substitutions(...Inflectible::getIrregular())
+ );
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php
new file mode 100644
index 000000000..c743b3931
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php
@@ -0,0 +1,36 @@
+from = $from;
+ $this->to = $to;
+ }
+
+ public function getFrom(): Word
+ {
+ return $this->from;
+ }
+
+ public function getTo(): Word
+ {
+ return $this->to;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php
new file mode 100644
index 000000000..17ee29619
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php
@@ -0,0 +1,57 @@
+substitutions[$substitution->getFrom()->getWord()] = $substitution;
+ }
+ }
+
+ public function getFlippedSubstitutions(): Substitutions
+ {
+ $substitutions = [];
+
+ foreach ($this->substitutions as $substitution) {
+ $substitutions[] = new Substitution(
+ $substitution->getTo(),
+ $substitution->getFrom()
+ );
+ }
+
+ return new Substitutions(...$substitutions);
+ }
+
+ public function inflect(string $word): string
+ {
+ $lowerWord = strtolower($word);
+
+ if (isset($this->substitutions[$lowerWord])) {
+ $firstLetterUppercase = $lowerWord[0] !== $word[0];
+
+ $toWord = $this->substitutions[$lowerWord]->getTo()->getWord();
+
+ if ($firstLetterUppercase) {
+ return strtoupper($toWord[0]) . substr($toWord, 1);
+ }
+
+ return $toWord;
+ }
+
+ return $word;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php
new file mode 100644
index 000000000..30dcd5945
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php
@@ -0,0 +1,39 @@
+pattern = $pattern;
+ $this->replacement = $replacement;
+ }
+
+ public function getPattern(): Pattern
+ {
+ return $this->pattern;
+ }
+
+ public function getReplacement(): string
+ {
+ return $this->replacement;
+ }
+
+ public function inflect(string $word): string
+ {
+ return (string) preg_replace($this->pattern->getRegex(), $this->replacement, $word);
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php
new file mode 100644
index 000000000..b6a48fa80
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php
@@ -0,0 +1,29 @@
+transformations = $transformations;
+ }
+
+ public function inflect(string $word): string
+ {
+ foreach ($this->transformations as $transformation) {
+ if ($transformation->getPattern()->matches($word)) {
+ return $transformation->inflect($word);
+ }
+ }
+
+ return $word;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php
new file mode 100644
index 000000000..d7b7064cb
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php
@@ -0,0 +1,40 @@
+getFlippedSubstitutions()
+ );
+ }
+
+ public static function getPluralRuleset(): Ruleset
+ {
+ return new Ruleset(
+ new Transformations(...Inflectible::getPlural()),
+ new Patterns(...Uninflected::getPlural()),
+ new Substitutions(...Inflectible::getIrregular())
+ );
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php
new file mode 100644
index 000000000..a75d24863
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php
@@ -0,0 +1,36 @@
+word = $word;
+ }
+
+ public function getWord(): string
+ {
+ return $this->word;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php
new file mode 100644
index 000000000..12b2ed5be
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php
@@ -0,0 +1,56 @@
+rulesets = array_merge([$ruleset], $rulesets);
+ }
+
+ public function inflect(string $word): string
+ {
+ if ($word === '') {
+ return '';
+ }
+
+ foreach ($this->rulesets as $ruleset) {
+ if ($ruleset->getUninflected()->matches($word)) {
+ return $word;
+ }
+
+ $inflected = $ruleset->getIrregular()->inflect($word);
+
+ if ($inflected !== $word) {
+ return $inflected;
+ }
+
+ $inflected = $ruleset->getRegular()->inflect($word);
+
+ if ($inflected !== $word) {
+ return $inflected;
+ }
+ }
+
+ return $word;
+ }
+}
diff --git a/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php
new file mode 100644
index 000000000..b88b1d696
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php
@@ -0,0 +1,10 @@
+getId(); // method exists through __call
+ */
+abstract class PersistentObject implements ObjectManagerAware
+{
+ /** @var ObjectManager|null */
+ private static $objectManager = null;
+
+ /** @var ClassMetadata|null */
+ private $cm = null;
+
+ /**
+ * Sets the object manager responsible for all persistent object base classes.
+ *
+ * @return void
+ */
+ public static function setObjectManager(?ObjectManager $objectManager = null)
+ {
+ self::$objectManager = $objectManager;
+ }
+
+ /**
+ * @return ObjectManager|null
+ */
+ public static function getObjectManager()
+ {
+ return self::$objectManager;
+ }
+
+ /**
+ * Injects the Doctrine Object Manager.
+ *
+ * @return void
+ *
+ * @throws RuntimeException
+ */
+ public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
+ {
+ if ($objectManager !== self::$objectManager) {
+ throw new RuntimeException('Trying to use PersistentObject with different ObjectManager instances. ' .
+ 'Was PersistentObject::setObjectManager() called?');
+ }
+
+ $this->cm = $classMetadata;
+ }
+
+ /**
+ * Sets a persistent fields value.
+ *
+ * @param string $field
+ * @param mixed[] $args
+ *
+ * @return void
+ *
+ * @throws BadMethodCallException When no persistent field exists by that name.
+ * @throws InvalidArgumentException When the wrong target object type is passed to an association.
+ */
+ private function set($field, $args)
+ {
+ if ($this->cm->hasField($field) && ! $this->cm->isIdentifier($field)) {
+ $this->$field = $args[0];
+ } elseif ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) {
+ $targetClass = $this->cm->getAssociationTargetClass($field);
+ if (! ($args[0] instanceof $targetClass) && $args[0] !== null) {
+ throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'");
+ }
+ $this->$field = $args[0];
+ $this->completeOwningSide($field, $targetClass, $args[0]);
+ } else {
+ throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'");
+ }
+ }
+
+ /**
+ * Gets a persistent field value.
+ *
+ * @param string $field
+ *
+ * @return mixed
+ *
+ * @throws BadMethodCallException When no persistent field exists by that name.
+ */
+ private function get($field)
+ {
+ if ($this->cm->hasField($field) || $this->cm->hasAssociation($field)) {
+ return $this->$field;
+ }
+
+ throw new BadMethodCallException("no field with name '" . $field . "' exists on '" . $this->cm->getName() . "'");
+ }
+
+ /**
+ * If this is an inverse side association, completes the owning side.
+ *
+ * @param string $field
+ * @param ClassMetadata $targetClass
+ * @param object $targetObject
+ *
+ * @return void
+ */
+ private function completeOwningSide($field, $targetClass, $targetObject)
+ {
+ // add this object on the owning side as well, for obvious infinite recursion
+ // reasons this is only done when called on the inverse side.
+ if (! $this->cm->isAssociationInverseSide($field)) {
+ return;
+ }
+
+ $mappedByField = $this->cm->getAssociationMappedByTargetField($field);
+ $targetMetadata = self::$objectManager->getClassMetadata($targetClass);
+
+ $setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? 'add' : 'set') . $mappedByField;
+ $targetObject->$setter($this);
+ }
+
+ /**
+ * Adds an object to a collection.
+ *
+ * @param string $field
+ * @param mixed[] $args
+ *
+ * @return void
+ *
+ * @throws BadMethodCallException
+ * @throws InvalidArgumentException
+ */
+ private function add($field, $args)
+ {
+ if (! $this->cm->hasAssociation($field) || ! $this->cm->isCollectionValuedAssociation($field)) {
+ throw new BadMethodCallException('There is no method add' . $field . '() on ' . $this->cm->getName());
+ }
+
+ $targetClass = $this->cm->getAssociationTargetClass($field);
+ if (! ($args[0] instanceof $targetClass)) {
+ throw new InvalidArgumentException("Expected persistent object of type '" . $targetClass . "'");
+ }
+ if (! ($this->$field instanceof Collection)) {
+ $this->$field = new ArrayCollection($this->$field ?: []);
+ }
+ $this->$field->add($args[0]);
+ $this->completeOwningSide($field, $targetClass, $args[0]);
+ }
+
+ /**
+ * Initializes Doctrine Metadata for this class.
+ *
+ * @return void
+ *
+ * @throws RuntimeException
+ */
+ private function initializeDoctrine()
+ {
+ if ($this->cm !== null) {
+ return;
+ }
+
+ if (! self::$objectManager) {
+ throw new RuntimeException('No runtime object manager set. Call PersistentObject#setObjectManager().');
+ }
+
+ $this->cm = self::$objectManager->getClassMetadata(static::class);
+ }
+
+ /**
+ * Magic methods.
+ *
+ * @param string $method
+ * @param mixed[] $args
+ *
+ * @return mixed
+ *
+ * @throws BadMethodCallException
+ */
+ public function __call($method, $args)
+ {
+ $this->initializeDoctrine();
+
+ $command = substr($method, 0, 3);
+ $field = lcfirst(substr($method, 3));
+ if ($command === 'set') {
+ $this->set($field, $args);
+ } elseif ($command === 'get') {
+ return $this->get($field);
+ } elseif ($command === 'add') {
+ $this->add($field, $args);
+ } else {
+ throw new BadMethodCallException('There is no method ' . $method . ' on ' . $this->cm->getName());
+ }
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\PersistentObject::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Proxy.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Proxy.php
new file mode 100644
index 000000000..c872c450e
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Proxy.php
@@ -0,0 +1,16 @@
+name = $name;
+ $this->connections = $connections;
+ $this->managers = $managers;
+ $this->defaultConnection = $defaultConnection;
+ $this->defaultManager = $defaultManager;
+ $this->proxyInterfaceName = $proxyInterfaceName;
+ }
+
+ /**
+ * Fetches/creates the given services.
+ *
+ * A service in this context is connection or a manager instance.
+ *
+ * @param string $name The name of the service.
+ *
+ * @return ObjectManager The instance of the given service.
+ */
+ abstract protected function getService($name);
+
+ /**
+ * Resets the given services.
+ *
+ * A service in this context is connection or a manager instance.
+ *
+ * @param string $name The name of the service.
+ *
+ * @return void
+ */
+ abstract protected function resetService($name);
+
+ /**
+ * Gets the name of the registry.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConnection($name = null)
+ {
+ if ($name === null) {
+ $name = $this->defaultConnection;
+ }
+
+ if (! isset($this->connections[$name])) {
+ throw new InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name));
+ }
+
+ return $this->getService($this->connections[$name]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConnectionNames()
+ {
+ return $this->connections;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConnections()
+ {
+ $connections = [];
+ foreach ($this->connections as $name => $id) {
+ $connections[$name] = $this->getService($id);
+ }
+
+ return $connections;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultConnectionName()
+ {
+ return $this->defaultConnection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultManagerName()
+ {
+ return $this->defaultManager;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws InvalidArgumentException
+ */
+ public function getManager($name = null)
+ {
+ if ($name === null) {
+ $name = $this->defaultManager;
+ }
+
+ if (! isset($this->managers[$name])) {
+ throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
+ }
+
+ return $this->getService($this->managers[$name]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getManagerForClass($class)
+ {
+ // Check for namespace alias
+ if (strpos($class, ':') !== false) {
+ [$namespaceAlias, $simpleClassName] = explode(':', $class, 2);
+ $class = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName;
+ }
+
+ $proxyClass = new ReflectionClass($class);
+
+ if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
+ $parentClass = $proxyClass->getParentClass();
+
+ if (! $parentClass) {
+ return null;
+ }
+
+ $class = $parentClass->getName();
+ }
+
+ foreach ($this->managers as $id) {
+ $manager = $this->getService($id);
+
+ if (! $manager->getMetadataFactory()->isTransient($class)) {
+ return $manager;
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getManagerNames()
+ {
+ return $this->managers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getManagers()
+ {
+ $dms = [];
+ foreach ($this->managers as $name => $id) {
+ $dms[$name] = $this->getService($id);
+ }
+
+ return $dms;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRepository($persistentObjectName, $persistentManagerName = null)
+ {
+ return $this
+ ->selectManager($persistentObjectName, $persistentManagerName)
+ ->getRepository($persistentObjectName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resetManager($name = null)
+ {
+ if ($name === null) {
+ $name = $this->defaultManager;
+ }
+
+ if (! isset($this->managers[$name])) {
+ throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
+ }
+
+ // force the creation of a new document manager
+ // if the current one is closed
+ $this->resetService($this->managers[$name]);
+
+ return $this->getManager($name);
+ }
+
+ private function selectManager(string $persistentObjectName, ?string $persistentManagerName = null) : ObjectManager
+ {
+ if ($persistentManagerName !== null) {
+ return $this->getManager($persistentManagerName);
+ }
+
+ return $this->getManagerForClass($persistentObjectName) ?? $this->getManager();
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\AbstractManagerRegistry::class);
+interface_exists(ObjectManager::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php
new file mode 100644
index 000000000..a822c7193
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ConnectionRegistry.php
@@ -0,0 +1,43 @@
+object = $object;
+ $this->objectManager = $objectManager;
+ }
+
+ /**
+ * Retrieves the associated entity.
+ *
+ * @deprecated
+ *
+ * @return object
+ */
+ public function getEntity()
+ {
+ return $this->object;
+ }
+
+ /**
+ * Retrieves the associated object.
+ *
+ * @return object
+ */
+ public function getObject()
+ {
+ return $this->object;
+ }
+
+ /**
+ * Retrieves the associated ObjectManager.
+ *
+ * @return ObjectManager
+ */
+ public function getObjectManager()
+ {
+ return $this->objectManager;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Event\LifecycleEventArgs::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php
new file mode 100644
index 000000000..31aae4a0d
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/LoadClassMetadataEventArgs.php
@@ -0,0 +1,48 @@
+classMetadata = $classMetadata;
+ $this->objectManager = $objectManager;
+ }
+
+ /**
+ * Retrieves the associated ClassMetadata.
+ *
+ * @return ClassMetadata
+ */
+ public function getClassMetadata()
+ {
+ return $this->classMetadata;
+ }
+
+ /**
+ * Retrieves the associated ObjectManager.
+ *
+ * @return ObjectManager
+ */
+ public function getObjectManager()
+ {
+ return $this->objectManager;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php
new file mode 100644
index 000000000..66dd90350
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/ManagerEventArgs.php
@@ -0,0 +1,33 @@
+objectManager = $objectManager;
+ }
+
+ /**
+ * Retrieves the associated ObjectManager.
+ *
+ * @return ObjectManager
+ */
+ public function getObjectManager()
+ {
+ return $this->objectManager;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Event\ManagerEventArgs::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php
new file mode 100644
index 000000000..cc263c133
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/OnClearEventArgs.php
@@ -0,0 +1,61 @@
+objectManager = $objectManager;
+ $this->entityClass = $entityClass;
+ }
+
+ /**
+ * Retrieves the associated ObjectManager.
+ *
+ * @return ObjectManager
+ */
+ public function getObjectManager()
+ {
+ return $this->objectManager;
+ }
+
+ /**
+ * Returns the name of the entity class that is cleared, or null if all are cleared.
+ *
+ * @return string|null
+ */
+ public function getEntityClass()
+ {
+ return $this->entityClass;
+ }
+
+ /**
+ * Returns whether this event clears all entities.
+ *
+ * @return bool
+ */
+ public function clearsAllEntities()
+ {
+ return $this->entityClass === null;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Event\OnClearEventArgs::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php
new file mode 100644
index 000000000..b9f837644
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Event/PreUpdateEventArgs.php
@@ -0,0 +1,116 @@
+entityChangeSet = &$changeSet;
+ }
+
+ /**
+ * Retrieves the entity changeset.
+ *
+ * @return mixed[][]
+ */
+ public function getEntityChangeSet()
+ {
+ return $this->entityChangeSet;
+ }
+
+ /**
+ * Checks if field has a changeset.
+ *
+ * @param string $field
+ *
+ * @return bool
+ */
+ public function hasChangedField($field)
+ {
+ return isset($this->entityChangeSet[$field]);
+ }
+
+ /**
+ * Gets the old value of the changeset of the changed field.
+ *
+ * @param string $field
+ *
+ * @return mixed
+ */
+ public function getOldValue($field)
+ {
+ $this->assertValidField($field);
+
+ return $this->entityChangeSet[$field][0];
+ }
+
+ /**
+ * Gets the new value of the changeset of the changed field.
+ *
+ * @param string $field
+ *
+ * @return mixed
+ */
+ public function getNewValue($field)
+ {
+ $this->assertValidField($field);
+
+ return $this->entityChangeSet[$field][1];
+ }
+
+ /**
+ * Sets the new value of this field.
+ *
+ * @param string $field
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function setNewValue($field, $value)
+ {
+ $this->assertValidField($field);
+
+ $this->entityChangeSet[$field][1] = $value;
+ }
+
+ /**
+ * Asserts the field exists in changeset.
+ *
+ * @param string $field
+ *
+ * @return void
+ *
+ * @throws InvalidArgumentException
+ */
+ private function assertValidField($field)
+ {
+ if (! isset($this->entityChangeSet[$field])) {
+ throw new InvalidArgumentException(sprintf(
+ 'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
+ $field,
+ get_class($this->getObject())
+ ));
+ }
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Event\PreUpdateEventArgs::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php
new file mode 100644
index 000000000..b28664ce4
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ManagerRegistry.php
@@ -0,0 +1,92 @@
+cacheDriver = $cacheDriver;
+ }
+
+ /**
+ * Gets the cache driver used by the factory to cache ClassMetadata instances.
+ *
+ * @return Cache|null
+ */
+ public function getCacheDriver()
+ {
+ return $this->cacheDriver;
+ }
+
+ /**
+ * Returns an array of all the loaded metadata currently in memory.
+ *
+ * @return ClassMetadata[]
+ */
+ public function getLoadedMetadata()
+ {
+ return $this->loadedMetadata;
+ }
+
+ /**
+ * Forces the factory to load the metadata of all classes known to the underlying
+ * mapping driver.
+ *
+ * @return ClassMetadata[] The ClassMetadata instances of all mapped classes.
+ */
+ public function getAllMetadata()
+ {
+ if (! $this->initialized) {
+ $this->initialize();
+ }
+
+ $driver = $this->getDriver();
+ $metadata = [];
+ foreach ($driver->getAllClassNames() as $className) {
+ $metadata[] = $this->getMetadataFor($className);
+ }
+
+ return $metadata;
+ }
+
+ /**
+ * Lazy initialization of this stuff, especially the metadata driver,
+ * since these are not needed at all when a metadata cache is active.
+ *
+ * @return void
+ */
+ abstract protected function initialize();
+
+ /**
+ * Gets the fully qualified class-name from the namespace alias.
+ *
+ * @param string $namespaceAlias
+ * @param string $simpleClassName
+ *
+ * @return string
+ */
+ abstract protected function getFqcnFromAlias($namespaceAlias, $simpleClassName);
+
+ /**
+ * Returns the mapping driver implementation.
+ *
+ * @return MappingDriver
+ */
+ abstract protected function getDriver();
+
+ /**
+ * Wakes up reflection after ClassMetadata gets unserialized from cache.
+ *
+ * @return void
+ */
+ abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService);
+
+ /**
+ * Initializes Reflection after ClassMetadata was constructed.
+ *
+ * @return void
+ */
+ abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService);
+
+ /**
+ * Checks whether the class metadata is an entity.
+ *
+ * This method should return false for mapped superclasses or embedded classes.
+ *
+ * @return bool
+ */
+ abstract protected function isEntity(ClassMetadata $class);
+
+ /**
+ * Gets the class metadata descriptor for a class.
+ *
+ * @param string $className The name of the class.
+ *
+ * @return ClassMetadata
+ *
+ * @throws ReflectionException
+ * @throws MappingException
+ */
+ public function getMetadataFor($className)
+ {
+ if (isset($this->loadedMetadata[$className])) {
+ return $this->loadedMetadata[$className];
+ }
+
+ // Check for namespace alias
+ if (strpos($className, ':') !== false) {
+ [$namespaceAlias, $simpleClassName] = explode(':', $className, 2);
+
+ $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName);
+ } else {
+ $realClassName = $this->getRealClass($className);
+ }
+
+ if (isset($this->loadedMetadata[$realClassName])) {
+ // We do not have the alias name in the map, include it
+ return $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+ }
+
+ $loadingException = null;
+
+ try {
+ if ($this->cacheDriver) {
+ $cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt);
+ if ($cached instanceof ClassMetadata) {
+ $this->loadedMetadata[$realClassName] = $cached;
+
+ $this->wakeupReflection($cached, $this->getReflectionService());
+ } else {
+ foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
+ $this->cacheDriver->save(
+ $loadedClassName . $this->cacheSalt,
+ $this->loadedMetadata[$loadedClassName]
+ );
+ }
+ }
+ } else {
+ $this->loadMetadata($realClassName);
+ }
+ } catch (MappingException $loadingException) {
+ $fallbackMetadataResponse = $this->onNotFoundMetadata($realClassName);
+
+ if (! $fallbackMetadataResponse) {
+ throw $loadingException;
+ }
+
+ $this->loadedMetadata[$realClassName] = $fallbackMetadataResponse;
+ }
+
+ if ($className !== $realClassName) {
+ // We do not have the alias name in the map, include it
+ $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+ }
+
+ return $this->loadedMetadata[$className];
+ }
+
+ /**
+ * Checks whether the factory has the metadata for a class loaded already.
+ *
+ * @param string $className
+ *
+ * @return bool TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
+ */
+ public function hasMetadataFor($className)
+ {
+ return isset($this->loadedMetadata[$className]);
+ }
+
+ /**
+ * Sets the metadata descriptor for a specific class.
+ *
+ * NOTE: This is only useful in very special cases, like when generating proxy classes.
+ *
+ * @param string $className
+ * @param ClassMetadata $class
+ *
+ * @return void
+ */
+ public function setMetadataFor($className, $class)
+ {
+ $this->loadedMetadata[$className] = $class;
+ }
+
+ /**
+ * Gets an array of parent classes for the given entity class.
+ *
+ * @param string $name
+ *
+ * @return string[]
+ */
+ protected function getParentClasses($name)
+ {
+ // Collect parent classes, ignoring transient (not-mapped) classes.
+ $parentClasses = [];
+
+ foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) {
+ if ($this->getDriver()->isTransient($parentClass)) {
+ continue;
+ }
+
+ $parentClasses[] = $parentClass;
+ }
+
+ return $parentClasses;
+ }
+
+ /**
+ * Loads the metadata of the class in question and all it's ancestors whose metadata
+ * is still not loaded.
+ *
+ * Important: The class $name does not necessarily exist at this point here.
+ * Scenarios in a code-generation setup might have access to XML/YAML
+ * Mapping files without the actual PHP code existing here. That is why the
+ * {@see Doctrine\Common\Persistence\Mapping\ReflectionService} interface
+ * should be used for reflection.
+ *
+ * @param string $name The name of the class for which the metadata should get loaded.
+ *
+ * @return string[]
+ */
+ protected function loadMetadata($name)
+ {
+ if (! $this->initialized) {
+ $this->initialize();
+ }
+
+ $loaded = [];
+
+ $parentClasses = $this->getParentClasses($name);
+ $parentClasses[] = $name;
+
+ // Move down the hierarchy of parent classes, starting from the topmost class
+ $parent = null;
+ $rootEntityFound = false;
+ $visited = [];
+ $reflService = $this->getReflectionService();
+ foreach ($parentClasses as $className) {
+ if (isset($this->loadedMetadata[$className])) {
+ $parent = $this->loadedMetadata[$className];
+ if ($this->isEntity($parent)) {
+ $rootEntityFound = true;
+ array_unshift($visited, $className);
+ }
+ continue;
+ }
+
+ $class = $this->newClassMetadataInstance($className);
+ $this->initializeReflection($class, $reflService);
+
+ $this->doLoadMetadata($class, $parent, $rootEntityFound, $visited);
+
+ $this->loadedMetadata[$className] = $class;
+
+ $parent = $class;
+
+ if ($this->isEntity($class)) {
+ $rootEntityFound = true;
+ array_unshift($visited, $className);
+ }
+
+ $this->wakeupReflection($class, $reflService);
+
+ $loaded[] = $className;
+ }
+
+ return $loaded;
+ }
+
+ /**
+ * Provides a fallback hook for loading metadata when loading failed due to reflection/mapping exceptions
+ *
+ * Override this method to implement a fallback strategy for failed metadata loading
+ *
+ * @param string $className
+ *
+ * @return ClassMetadata|null
+ */
+ protected function onNotFoundMetadata($className)
+ {
+ return null;
+ }
+
+ /**
+ * Actually loads the metadata from the underlying metadata.
+ *
+ * @param ClassMetadata $class
+ * @param ClassMetadata|null $parent
+ * @param bool $rootEntityFound
+ * @param string[] $nonSuperclassParents All parent class names
+ * that are not marked as mapped superclasses.
+ *
+ * @return void
+ */
+ abstract protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents);
+
+ /**
+ * Creates a new ClassMetadata instance for the given class name.
+ *
+ * @param string $className
+ *
+ * @return ClassMetadata
+ */
+ abstract protected function newClassMetadataInstance($className);
+
+ /**
+ * {@inheritDoc}
+ */
+ public function isTransient($class)
+ {
+ if (! $this->initialized) {
+ $this->initialize();
+ }
+
+ // Check for namespace alias
+ if (strpos($class, ':') !== false) {
+ [$namespaceAlias, $simpleClassName] = explode(':', $class, 2);
+ $class = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName);
+ }
+
+ return $this->getDriver()->isTransient($class);
+ }
+
+ /**
+ * Sets the reflectionService.
+ *
+ * @return void
+ */
+ public function setReflectionService(ReflectionService $reflectionService)
+ {
+ $this->reflectionService = $reflectionService;
+ }
+
+ /**
+ * Gets the reflection service associated with this metadata factory.
+ *
+ * @return ReflectionService
+ */
+ public function getReflectionService()
+ {
+ if ($this->reflectionService === null) {
+ $this->reflectionService = new RuntimeReflectionService();
+ }
+
+ return $this->reflectionService;
+ }
+
+ /**
+ * Gets the real class name of a class name that could be a proxy.
+ */
+ private function getRealClass(string $class) : string
+ {
+ $pos = strrpos($class, '\\' . Proxy::MARKER . '\\');
+
+ if ($pos === false) {
+ return $class;
+ }
+
+ return substr($class, $pos + Proxy::MARKER_LENGTH + 2);
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory::class);
+interface_exists(ClassMetadata::class);
+interface_exists(ReflectionService::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php
new file mode 100644
index 000000000..7b995d566
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/ClassMetadata.php
@@ -0,0 +1,157 @@
+reader = $reader;
+ if (! $paths) {
+ return;
+ }
+
+ $this->addPaths((array) $paths);
+ }
+
+ /**
+ * Appends lookup paths to metadata driver.
+ *
+ * @param string[] $paths
+ *
+ * @return void
+ */
+ public function addPaths(array $paths)
+ {
+ $this->paths = array_unique(array_merge($this->paths, $paths));
+ }
+
+ /**
+ * Retrieves the defined metadata lookup paths.
+ *
+ * @return string[]
+ */
+ public function getPaths()
+ {
+ return $this->paths;
+ }
+
+ /**
+ * Append exclude lookup paths to metadata driver.
+ *
+ * @param string[] $paths
+ */
+ public function addExcludePaths(array $paths)
+ {
+ $this->excludePaths = array_unique(array_merge($this->excludePaths, $paths));
+ }
+
+ /**
+ * Retrieve the defined metadata lookup exclude paths.
+ *
+ * @return string[]
+ */
+ public function getExcludePaths()
+ {
+ return $this->excludePaths;
+ }
+
+ /**
+ * Retrieve the current annotation reader
+ *
+ * @return Reader
+ */
+ public function getReader()
+ {
+ return $this->reader;
+ }
+
+ /**
+ * Gets the file extension used to look for mapping files under.
+ *
+ * @return string
+ */
+ public function getFileExtension()
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Sets the file extension used to look for mapping files under.
+ *
+ * @param string $fileExtension The file extension to set.
+ *
+ * @return void
+ */
+ public function setFileExtension($fileExtension)
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * Returns whether the class with the specified name is transient. Only non-transient
+ * classes, that is entities and mapped superclasses, should have their metadata loaded.
+ *
+ * A class is non-transient if it is annotated with an annotation
+ * from the {@see AnnotationDriver::entityAnnotationClasses}.
+ *
+ * @param string $className
+ *
+ * @return bool
+ */
+ public function isTransient($className)
+ {
+ $classAnnotations = $this->reader->getClassAnnotations(new ReflectionClass($className));
+
+ foreach ($classAnnotations as $annot) {
+ if (isset($this->entityAnnotationClasses[get_class($annot)])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAllClassNames()
+ {
+ if ($this->classNames !== null) {
+ return $this->classNames;
+ }
+
+ if (! $this->paths) {
+ throw MappingException::pathRequired();
+ }
+
+ $classes = [];
+ $includedFiles = [];
+
+ foreach ($this->paths as $path) {
+ if (! is_dir($path)) {
+ throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+ }
+
+ $iterator = new RegexIterator(
+ new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ ),
+ '/^.+' . preg_quote($this->fileExtension) . '$/i',
+ RecursiveRegexIterator::GET_MATCH
+ );
+
+ foreach ($iterator as $file) {
+ $sourceFile = $file[0];
+
+ if (! preg_match('(^phar:)i', $sourceFile)) {
+ $sourceFile = realpath($sourceFile);
+ }
+
+ foreach ($this->excludePaths as $excludePath) {
+ $exclude = str_replace('\\', '/', realpath($excludePath));
+ $current = str_replace('\\', '/', $sourceFile);
+
+ if (strpos($current, $exclude) !== false) {
+ continue 2;
+ }
+ }
+
+ require_once $sourceFile;
+
+ $includedFiles[] = $sourceFile;
+ }
+ }
+
+ $declared = get_declared_classes();
+
+ foreach ($declared as $className) {
+ $rc = new ReflectionClass($className);
+ $sourceFile = $rc->getFileName();
+ if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) {
+ continue;
+ }
+
+ $classes[] = $className;
+ }
+
+ $this->classNames = $classes;
+
+ return $classes;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php
new file mode 100644
index 000000000..4f49bc2df
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/DefaultFileLocator.php
@@ -0,0 +1,164 @@
+addPaths((array) $paths);
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * Appends lookup paths to metadata driver.
+ *
+ * @param string[] $paths
+ *
+ * @return void
+ */
+ public function addPaths(array $paths)
+ {
+ $this->paths = array_unique(array_merge($this->paths, $paths));
+ }
+
+ /**
+ * Retrieves the defined metadata lookup paths.
+ *
+ * @return string[]
+ */
+ public function getPaths()
+ {
+ return $this->paths;
+ }
+
+ /**
+ * Gets the file extension used to look for mapping files under.
+ *
+ * @return string|null
+ */
+ public function getFileExtension()
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Sets the file extension used to look for mapping files under.
+ *
+ * @param string|null $fileExtension The file extension to set.
+ *
+ * @return void
+ */
+ public function setFileExtension($fileExtension)
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findMappingFile($className)
+ {
+ $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
+
+ // Check whether file exists
+ foreach ($this->paths as $path) {
+ if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) {
+ return $path . DIRECTORY_SEPARATOR . $fileName;
+ }
+ }
+
+ throw MappingException::mappingFileNotFound($className, $fileName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAllClassNames($globalBasename)
+ {
+ $classes = [];
+
+ if ($this->paths) {
+ foreach ($this->paths as $path) {
+ if (! is_dir($path)) {
+ throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+ }
+
+ $iterator = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($path),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ );
+
+ foreach ($iterator as $file) {
+ $fileName = $file->getBasename($this->fileExtension);
+
+ if ($fileName === $file->getBasename() || $fileName === $globalBasename) {
+ continue;
+ }
+
+ // NOTE: All files found here means classes are not transient!
+ $classes[] = str_replace('.', '\\', $fileName);
+ }
+ }
+ }
+
+ return $classes;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function fileExists($className)
+ {
+ $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
+
+ // Check whether file exists
+ foreach ((array) $this->paths as $path) {
+ if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php
new file mode 100644
index 000000000..c8c783a6e
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileDriver.php
@@ -0,0 +1,199 @@
+locator = $locator;
+ } else {
+ $this->locator = new DefaultFileLocator((array) $locator, $fileExtension);
+ }
+ }
+
+ /**
+ * Sets the global basename.
+ *
+ * @param string $file
+ *
+ * @return void
+ */
+ public function setGlobalBasename($file)
+ {
+ $this->globalBasename = $file;
+ }
+
+ /**
+ * Retrieves the global basename.
+ *
+ * @return string|null
+ */
+ public function getGlobalBasename()
+ {
+ return $this->globalBasename;
+ }
+
+ /**
+ * Gets the element of schema meta data for the class from the mapping file.
+ * This will lazily load the mapping file if it is not loaded yet.
+ *
+ * @param string $className
+ *
+ * @return ClassMetadata The element of schema meta data.
+ *
+ * @throws MappingException
+ */
+ public function getElement($className)
+ {
+ if ($this->classCache === null) {
+ $this->initialize();
+ }
+
+ if (isset($this->classCache[$className])) {
+ return $this->classCache[$className];
+ }
+
+ $result = $this->loadMappingFile($this->locator->findMappingFile($className));
+ if (! isset($result[$className])) {
+ throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->locator->getFileExtension());
+ }
+
+ $this->classCache[$className] = $result[$className];
+
+ return $result[$className];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function isTransient($className)
+ {
+ if ($this->classCache === null) {
+ $this->initialize();
+ }
+
+ if (isset($this->classCache[$className])) {
+ return false;
+ }
+
+ return ! $this->locator->fileExists($className);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAllClassNames()
+ {
+ if ($this->classCache === null) {
+ $this->initialize();
+ }
+
+ if (! $this->classCache) {
+ return (array) $this->locator->getAllClassNames($this->globalBasename);
+ }
+
+ return array_unique(array_merge(
+ array_keys($this->classCache),
+ (array) $this->locator->getAllClassNames($this->globalBasename)
+ ));
+ }
+
+ /**
+ * Loads a mapping file with the given name and returns a map
+ * from class/entity names to their corresponding file driver elements.
+ *
+ * @param string $file The mapping file to load.
+ *
+ * @return ClassMetadata[]
+ */
+ abstract protected function loadMappingFile($file);
+
+ /**
+ * Initializes the class cache from all the global files.
+ *
+ * Using this feature adds a substantial performance hit to file drivers as
+ * more metadata has to be loaded into memory than might actually be
+ * necessary. This may not be relevant to scenarios where caching of
+ * metadata is in place, however hits very hard in scenarios where no
+ * caching is used.
+ *
+ * @return void
+ */
+ protected function initialize()
+ {
+ $this->classCache = [];
+ if ($this->globalBasename === null) {
+ return;
+ }
+
+ foreach ($this->locator->getPaths() as $path) {
+ $file = $path . '/' . $this->globalBasename . $this->locator->getFileExtension();
+ if (! is_file($file)) {
+ continue;
+ }
+
+ $this->classCache = array_merge(
+ $this->classCache,
+ $this->loadMappingFile($file)
+ );
+ }
+ }
+
+ /**
+ * Retrieves the locator used to discover mapping files by className.
+ *
+ * @return FileLocator
+ */
+ public function getLocator()
+ {
+ return $this->locator;
+ }
+
+ /**
+ * Sets the locator used to discover mapping files by className.
+ */
+ public function setLocator(FileLocator $locator)
+ {
+ $this->locator = $locator;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\FileDriver::class);
+interface_exists(FileLocator::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php
new file mode 100644
index 000000000..b14baf244
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/FileLocator.php
@@ -0,0 +1,57 @@
+defaultDriver;
+ }
+
+ /**
+ * Set the default driver.
+ *
+ * @return void
+ */
+ public function setDefaultDriver(MappingDriver $driver)
+ {
+ $this->defaultDriver = $driver;
+ }
+
+ /**
+ * Adds a nested driver.
+ *
+ * @param string $namespace
+ *
+ * @return void
+ */
+ public function addDriver(MappingDriver $nestedDriver, $namespace)
+ {
+ $this->drivers[$namespace] = $nestedDriver;
+ }
+
+ /**
+ * Gets the array of nested drivers.
+ *
+ * @return MappingDriver[] $drivers
+ */
+ public function getDrivers()
+ {
+ return $this->drivers;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function loadMetadataForClass($className, ClassMetadata $metadata)
+ {
+ /** @var MappingDriver $driver */
+ foreach ($this->drivers as $namespace => $driver) {
+ if (strpos($className, $namespace) === 0) {
+ $driver->loadMetadataForClass($className, $metadata);
+
+ return;
+ }
+ }
+
+ if ($this->defaultDriver !== null) {
+ $this->defaultDriver->loadMetadataForClass($className, $metadata);
+
+ return;
+ }
+
+ throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAllClassNames()
+ {
+ $classNames = [];
+ $driverClasses = [];
+
+ /** @var MappingDriver $driver */
+ foreach ($this->drivers as $namespace => $driver) {
+ $oid = spl_object_hash($driver);
+
+ if (! isset($driverClasses[$oid])) {
+ $driverClasses[$oid] = $driver->getAllClassNames();
+ }
+
+ foreach ($driverClasses[$oid] as $className) {
+ if (strpos($className, $namespace) !== 0) {
+ continue;
+ }
+
+ $classNames[$className] = true;
+ }
+ }
+
+ if ($this->defaultDriver !== null) {
+ foreach ($this->defaultDriver->getAllClassNames() as $className) {
+ $classNames[$className] = true;
+ }
+ }
+
+ return array_keys($classNames);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function isTransient($className)
+ {
+ /** @var MappingDriver $driver */
+ foreach ($this->drivers as $namespace => $driver) {
+ if (strpos($className, $namespace) === 0) {
+ return $driver->isTransient($className);
+ }
+ }
+
+ if ($this->defaultDriver !== null) {
+ return $this->defaultDriver->isTransient($className);
+ }
+
+ return true;
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain::class);
+interface_exists(ClassMetadata::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php
new file mode 100644
index 000000000..4f1d9488d
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/PHPDriver.php
@@ -0,0 +1,49 @@
+metadata = $metadata;
+
+ $this->loadMappingFile($this->locator->findMappingFile($className));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function loadMappingFile($file)
+ {
+ $metadata = $this->metadata;
+ include $file;
+
+ return [$metadata->getName() => $metadata];
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\PHPDriver::class);
+interface_exists(ClassMetadata::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php
new file mode 100644
index 000000000..848b3bd0a
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/StaticPHPDriver.php
@@ -0,0 +1,134 @@
+addPaths((array) $paths);
+ }
+
+ /**
+ * Adds paths.
+ *
+ * @param string[] $paths
+ *
+ * @return void
+ */
+ public function addPaths(array $paths)
+ {
+ $this->paths = array_unique(array_merge($this->paths, $paths));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadMetadataForClass($className, ClassMetadata $metadata)
+ {
+ $className::loadMetadata($metadata);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it?
+ */
+ public function getAllClassNames()
+ {
+ if ($this->classNames !== null) {
+ return $this->classNames;
+ }
+
+ if (! $this->paths) {
+ throw MappingException::pathRequired();
+ }
+
+ $classes = [];
+ $includedFiles = [];
+
+ foreach ($this->paths as $path) {
+ if (! is_dir($path)) {
+ throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+ }
+
+ $iterator = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($path),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ );
+
+ foreach ($iterator as $file) {
+ if ($file->getBasename('.php') === $file->getBasename()) {
+ continue;
+ }
+
+ $sourceFile = realpath($file->getPathName());
+ require_once $sourceFile;
+ $includedFiles[] = $sourceFile;
+ }
+ }
+
+ $declared = get_declared_classes();
+
+ foreach ($declared as $className) {
+ $rc = new ReflectionClass($className);
+ $sourceFile = $rc->getFileName();
+ if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) {
+ continue;
+ }
+
+ $classes[] = $className;
+ }
+
+ $this->classNames = $classes;
+
+ return $classes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isTransient($className)
+ {
+ return ! method_exists($className, 'loadMetadata');
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver::class);
+interface_exists(ClassMetadata::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php
new file mode 100644
index 000000000..3124c6662
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/SymfonyFileLocator.php
@@ -0,0 +1,233 @@
+addNamespacePrefixes($prefixes);
+ $this->fileExtension = $fileExtension;
+
+ if (empty($nsSeparator)) {
+ throw new InvalidArgumentException('Namespace separator should not be empty');
+ }
+
+ $this->nsSeparator = (string) $nsSeparator;
+ }
+
+ /**
+ * Adds Namespace Prefixes.
+ *
+ * @param string[] $prefixes
+ *
+ * @return void
+ */
+ public function addNamespacePrefixes(array $prefixes)
+ {
+ $this->prefixes = array_merge($this->prefixes, $prefixes);
+ $this->paths = array_merge($this->paths, array_keys($prefixes));
+ }
+
+ /**
+ * Gets Namespace Prefixes.
+ *
+ * @return string[]
+ */
+ public function getNamespacePrefixes()
+ {
+ return $this->prefixes;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getPaths()
+ {
+ return $this->paths;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getFileExtension()
+ {
+ return $this->fileExtension;
+ }
+
+ /**
+ * Sets the file extension used to look for mapping files under.
+ *
+ * @param string $fileExtension The file extension to set.
+ *
+ * @return void
+ */
+ public function setFileExtension($fileExtension)
+ {
+ $this->fileExtension = $fileExtension;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function fileExists($className)
+ {
+ $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
+ foreach ($this->paths as $path) {
+ if (! isset($this->prefixes[$path])) {
+ // global namespace class
+ if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
+ return true;
+ }
+
+ continue;
+ }
+
+ $prefix = $this->prefixes[$path];
+
+ if (strpos($className, $prefix . '\\') !== 0) {
+ continue;
+ }
+
+ $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
+ if (is_file($filename)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAllClassNames($globalBasename = null)
+ {
+ $classes = [];
+
+ if ($this->paths) {
+ foreach ((array) $this->paths as $path) {
+ if (! is_dir($path)) {
+ throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+ }
+
+ $iterator = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($path),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ );
+
+ foreach ($iterator as $file) {
+ $fileName = $file->getBasename($this->fileExtension);
+
+ if ($fileName === $file->getBasename() || $fileName === $globalBasename) {
+ continue;
+ }
+
+ // NOTE: All files found here means classes are not transient!
+ if (isset($this->prefixes[$path])) {
+ // Calculate namespace suffix for given prefix as a relative path from basepath to file path
+ $nsSuffix = strtr(
+ substr(realpath($file->getPath()), strlen(realpath($path))),
+ $this->nsSeparator,
+ '\\'
+ );
+
+ $classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName);
+ } else {
+ $classes[] = str_replace($this->nsSeparator, '\\', $fileName);
+ }
+ }
+ }
+ }
+
+ return $classes;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findMappingFile($className)
+ {
+ $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
+ foreach ($this->paths as $path) {
+ if (! isset($this->prefixes[$path])) {
+ if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
+ return $path . DIRECTORY_SEPARATOR . $defaultFileName;
+ }
+
+ continue;
+ }
+
+ $prefix = $this->prefixes[$path];
+
+ if (strpos($className, $prefix . '\\') !== 0) {
+ continue;
+ }
+
+ $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
+ if (is_file($filename)) {
+ return $filename;
+ }
+ }
+
+ throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1) . $this->fileExtension);
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php
new file mode 100644
index 000000000..9729e5f63
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/MappingException.php
@@ -0,0 +1,98 @@
+supportsTypedPropertiesWorkaround = version_compare((string) phpversion(), '7.4.0') >= 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getParentClasses($class)
+ {
+ if (! class_exists($class)) {
+ throw MappingException::nonExistingClass($class);
+ }
+
+ return class_parents($class);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getClassShortName($class)
+ {
+ $reflectionClass = new ReflectionClass($class);
+
+ return $reflectionClass->getShortName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getClassNamespace($class)
+ {
+ $reflectionClass = new ReflectionClass($class);
+
+ return $reflectionClass->getNamespaceName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getClass($class)
+ {
+ return new ReflectionClass($class);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAccessibleProperty($class, $property)
+ {
+ $reflectionProperty = new ReflectionProperty($class, $property);
+
+ if ($reflectionProperty->isPublic()) {
+ $reflectionProperty = new RuntimePublicReflectionProperty($class, $property);
+ } elseif ($this->supportsTypedPropertiesWorkaround && ! array_key_exists($property, $this->getClass($class)->getDefaultProperties())) {
+ $reflectionProperty = new TypedNoDefaultReflectionProperty($class, $property);
+ }
+
+ $reflectionProperty->setAccessible(true);
+
+ return $reflectionProperty;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function hasPublicMethod($class, $method)
+ {
+ try {
+ $reflectionMethod = new ReflectionMethod($class, $method);
+ } catch (ReflectionException $e) {
+ return false;
+ }
+
+ return $reflectionMethod->isPublic();
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\Mapping\RuntimeReflectionService::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php
new file mode 100644
index 000000000..ac24e4572
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/StaticReflectionService.php
@@ -0,0 +1,74 @@
+find($id).
+ *
+ * @param string $className The class name of the object to find.
+ * @param mixed $id The identity of the object to find.
+ *
+ * @return object|null The found object.
+ */
+ public function find($className, $id);
+
+ /**
+ * Tells the ObjectManager to make an instance managed and persistent.
+ *
+ * The object will be entered into the database as a result of the flush operation.
+ *
+ * NOTE: The persist operation always considers objects that are not yet known to
+ * this ObjectManager as NEW. Do not pass detached objects to the persist operation.
+ *
+ * @param object $object The instance to make managed and persistent.
+ *
+ * @return void
+ */
+ public function persist($object);
+
+ /**
+ * Removes an object instance.
+ *
+ * A removed object will be removed from the database as a result of the flush operation.
+ *
+ * @param object $object The object instance to remove.
+ *
+ * @return void
+ */
+ public function remove($object);
+
+ /**
+ * Merges the state of a detached object into the persistence context
+ * of this ObjectManager and returns the managed copy of the object.
+ * The object passed to merge will not become associated/managed with this ObjectManager.
+ *
+ * @deprecated Merge operation is deprecated and will be removed in Persistence 2.0.
+ * Merging should be part of the business domain of an application rather than
+ * a generic operation of ObjectManager.
+ *
+ * @param object $object
+ *
+ * @return object
+ */
+ public function merge($object);
+
+ /**
+ * Clears the ObjectManager. All objects that are currently managed
+ * by this ObjectManager become detached.
+ *
+ * @param string|null $objectName if given, only objects of this type will get detached.
+ *
+ * @return void
+ */
+ public function clear($objectName = null);
+
+ /**
+ * Detaches an object from the ObjectManager, causing a managed object to
+ * become detached. Unflushed changes made to the object if any
+ * (including removal of the object), will not be synchronized to the database.
+ * Objects which previously referenced the detached object will continue to
+ * reference it.
+ *
+ * @deprecated Detach operation is deprecated and will be removed in Persistence 2.0. Please use
+ * {@see ObjectManager::clear()} instead.
+ *
+ * @param object $object The object to detach.
+ *
+ * @return void
+ */
+ public function detach($object);
+
+ /**
+ * Refreshes the persistent state of an object from the database,
+ * overriding any local changes that have not yet been persisted.
+ *
+ * @param object $object The object to refresh.
+ *
+ * @return void
+ */
+ public function refresh($object);
+
+ /**
+ * Flushes all changes to objects that have been queued up to now to the database.
+ * This effectively synchronizes the in-memory state of managed objects with the
+ * database.
+ *
+ * @return void
+ */
+ public function flush();
+
+ /**
+ * Gets the repository for a class.
+ *
+ * @param string $className
+ *
+ * @return ObjectRepository
+ */
+ public function getRepository($className);
+
+ /**
+ * Returns the ClassMetadata descriptor for a class.
+ *
+ * The class name must be the fully-qualified class name without a leading backslash
+ * (as it is returned by get_class($obj)).
+ *
+ * @param string $className
+ *
+ * @return ClassMetadata
+ */
+ public function getClassMetadata($className);
+
+ /**
+ * Gets the metadata factory used to gather the metadata of classes.
+ *
+ * @return ClassMetadataFactory
+ */
+ public function getMetadataFactory();
+
+ /**
+ * Helper method to initialize a lazy loading proxy or persistent collection.
+ *
+ * This method is a no-op for other objects.
+ *
+ * @param object $obj
+ *
+ * @return void
+ */
+ public function initializeObject($obj);
+
+ /**
+ * Checks if the object is part of the current UnitOfWork and therefore managed.
+ *
+ * @param object $object
+ *
+ * @return bool
+ */
+ public function contains($object);
+}
+
+interface_exists(\Doctrine\Common\Persistence\ObjectManager::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php
new file mode 100644
index 000000000..2593b7c66
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectManagerAware.php
@@ -0,0 +1,34 @@
+wrapped->find($className, $id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function persist($object)
+ {
+ $this->wrapped->persist($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($object)
+ {
+ $this->wrapped->remove($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function merge($object)
+ {
+ return $this->wrapped->merge($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear($objectName = null)
+ {
+ $this->wrapped->clear($objectName);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function detach($object)
+ {
+ $this->wrapped->detach($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function refresh($object)
+ {
+ $this->wrapped->refresh($object);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function flush()
+ {
+ $this->wrapped->flush();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRepository($className)
+ {
+ return $this->wrapped->getRepository($className);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClassMetadata($className)
+ {
+ return $this->wrapped->getClassMetadata($className);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadataFactory()
+ {
+ return $this->wrapped->getMetadataFactory();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initializeObject($obj)
+ {
+ $this->wrapped->initializeObject($obj);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function contains($object)
+ {
+ return $this->wrapped->contains($object);
+ }
+}
+
+class_exists(\Doctrine\Common\Persistence\ObjectManagerDecorator::class);
diff --git a/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php
new file mode 100644
index 000000000..7661be20d
--- /dev/null
+++ b/frontend/drupal9/vendor/doctrine/persistence/lib/Doctrine/Persistence/ObjectRepository.php
@@ -0,0 +1,64 @@
+
+' . t('Render Facets in a single block.') . '
'; + return $output; + } +} + +/** + * Implements hook_theme(). + */ +function facets_block_theme($existing, $type, $theme, $path) { + return [ + 'facets_block' => [ + 'variables' => [ + 'show_title' => TRUE, + 'facets' => '', + ], + ], + ]; +} + +/** + * Implements hook_block_view_BASE_BLOCK_ID_alter(). + */ +function facets_block_block_view_facets_block_alter(array &$build, BlockPluginInterface $block) { + if (!empty($build['#configuration']['add_js_classes'])) { + $build['#pre_render'][] = '\Drupal\facets_block\AddJsClasses::preRender'; + } + + if (!empty($build['#configuration']['hide_empty_block'])) { + $build['#pre_render'][] = '\Drupal\facets_block\AddCssClasses::preRender'; + } +} diff --git a/frontend/drupal9/web/modules/contrib/facets_block/src/AddCssClasses.php b/frontend/drupal9/web/modules/contrib/facets_block/src/AddCssClasses.php new file mode 100644 index 000000000..c6d217e2f --- /dev/null +++ b/frontend/drupal9/web/modules/contrib/facets_block/src/AddCssClasses.php @@ -0,0 +1,36 @@ +facetsManager = $facets_manager; + $this->moduleHandler = $module_handler; + $this->pluginManagerBlock = $plugin_manager_block; + $this->currentUser = $current_user; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('facets.manager'), + $container->get('module_handler'), + $container->get('plugin.manager.block'), + $container->get('current_user') + ); + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + $form['block_settings'] = [ + '#type' => 'fieldset', + '#title' => 'Settings', + ]; + + $form['block_settings']['show_title'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Show Facet titles'), + '#default_value' => isset($this->configuration['show_title']) ? $this->configuration['show_title'] : TRUE, + ]; + + $form['block_settings']['exclude_empty_facets'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Exclude empty facets'), + '#default_value' => isset($this->configuration['exclude_empty_facets']) ? $this->configuration['exclude_empty_facets'] : TRUE, + ]; + + $form['block_settings']['hide_empty_block'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Hide empty block'), + '#description' => $this->t("Don't render the Facets Block if no facets are available (for instance when no search results are found)."), + '#default_value' => isset($this->configuration['hide_empty_block']) ? $this->configuration['hide_empty_block'] : FALSE, + ]; + + $form['block_settings']['add_js_classes'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Add JS classes for Facets block'), + '#default_value' => $this->configuration['add_js_classes'] ?? FALSE, + ]; + + $form['block_settings']['facets_to_include'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('Facets to include'), + '#default_value' => isset($this->configuration['facets_to_include']) ? $this->configuration['facets_to_include'] : [], + '#options' => $this->getAvailableFacets(), + ]; + + return $form; + } + + /** + * Returns a list of available facets. + * + * @return array + * An array of enabled facets. + */ + protected function getAvailableFacets() { + $enabled_facets = $this->facetsManager->getEnabledFacets(); + uasort($enabled_facets, [$this, 'sortFacetsByWeight']); + + $available_facets = []; + + if ($this->moduleHandler->moduleExists('facets_summary')) { + $available_facets['facets_summary_block:summary'] = $this->t('Summary'); + } + + foreach ($enabled_facets as $facet) { + /** @var \Drupal\facets\Entity\Facet $facet */ + $available_facets['facet_block:' . $facet->id()] = $facet->getName(); + } + + return $available_facets; + } + + /** + * Sorts array of objects by object weight property. + * + * @param \Drupal\facets\FacetInterface $a + * A facet. + * @param \Drupal\facets\FacetInterface $b + * A facet. + * + * @return int + * Sort value. + */ + protected function sortFacetsByWeight(FacetInterface $a, FacetInterface $b) { + $a_weight = $a->getWeight(); + $b_weight = $b->getWeight(); + + if ($a_weight == $b_weight) { + return 0; + } + + return ($a_weight < $b_weight) ? -1 : 1; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) { + $this->configuration['show_title'] = $form_state->getValue([ + 'block_settings', + 'show_title', + ]); + $this->configuration['exclude_empty_facets'] = $form_state->getValue([ + 'block_settings', + 'exclude_empty_facets', + ]); + $this->configuration['hide_empty_block'] = $form_state->getValue([ + 'block_settings', + 'hide_empty_block', + ]); + $this->configuration['facets_to_include'] = $form_state->getValue([ + 'block_settings', + 'facets_to_include', + ]); + $this->configuration['add_js_classes'] = $form_state->getValue([ + 'block_settings', + 'add_js_classes', + ]); + } + + /** + * Builds facets. + * + * @param array $facets_to_include + * A list of facets to display. + * + * @return array + * An array of facets. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + */ + protected function buildFacets(array $facets_to_include) { + $facets = []; + + $available_facets = $this->getAvailableFacets(); + + foreach ($available_facets as $plugin_id => $facet_title) { + if (isset($facets_to_include[$plugin_id]) && $facets_to_include[$plugin_id] === $plugin_id) { + $block_plugin = $this->pluginManagerBlock->createInstance($plugin_id, []); + + if ($block_plugin && $block_plugin->access($this->currentUser)) { + $build = $block_plugin->build(); + + $exclude_empty_facets = !isset($this->configuration['exclude_empty_facets']) ? TRUE : $this->configuration['exclude_empty_facets']; + + // Skip empty facets. + $is_empty = FALSE; + + if (!$build) { + $is_empty = TRUE; + } + elseif (isset($build[0]['#attributes']['class']) && in_array('facet-empty', $build[0]['#attributes']['class'])) { + $is_empty = TRUE; + } + // Check if Summary Facet is empty. + elseif (isset($build['#items']) && count($build['#items']) == 0) { + $is_empty = TRUE; + } + + if ($exclude_empty_facets && $is_empty) { + continue; + } + + if (empty($build['#attributes'])) { + $build['#attributes'] = []; + } + + $facets[] = [ + 'title' => $facet_title, + 'content' => $build, + 'attributes' => new Attribute($build['#attributes']), + ]; + } + } + } + + return $facets; + } + + /** + * {@inheritdoc} + */ + public function build() { + $show_title = !isset($this->configuration['show_title']) ? TRUE : $this->configuration['show_title']; + $facets_to_include = !isset($this->configuration['facets_to_include']) ? [] : $this->configuration['facets_to_include']; + $facets = $this->buildFacets($facets_to_include); + + // Allow other modules to alter the facets array. + $this->moduleHandler->alter('facets_block_facets', $facets); + + return [ + '#theme' => 'facets_block', + '#show_title' => $show_title, + '#facets' => $facets, + ]; + } + +} diff --git a/frontend/drupal9/web/modules/contrib/facets_block/templates/facets-block.html.twig b/frontend/drupal9/web/modules/contrib/facets_block/templates/facets-block.html.twig new file mode 100644 index 000000000..9d126bb00 --- /dev/null +++ b/frontend/drupal9/web/modules/contrib/facets_block/templates/facets-block.html.twig @@ -0,0 +1,8 @@ +{% for facet in facets %} +{{ facet.title }}
+ {% endif %} +' . $this->t('There are currently no XML sitemap contexts available.') . '
', + '#markup' => '' . $this->t('There are currently no XML Sitemap contexts available.') . '
', ]; } @@ -84,6 +84,8 @@ class XmlSitemapForm extends EntityForm { } catch (EntityStorageException $ex) { $this->messenger()->addError($this->t('There is another sitemap saved with the same context.')); + $form_state->setRedirect('entity.xmlsitemap.add_form'); + return; } $form_state->setRedirect('xmlsitemap.admin_search'); diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapLinkBundleSettingsForm.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapLinkBundleSettingsForm.php index 78ec13902..327714b88 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapLinkBundleSettingsForm.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapLinkBundleSettingsForm.php @@ -72,7 +72,7 @@ class XmlSitemapLinkBundleSettingsForm extends ConfigFormBase { $this->bundle_type = $bundle; $request = $this->getRequest(); - $form['#title'] = $this->t('@bundle XML sitemap settings', ['@bundle' => $bundle]); + $form['#title'] = $this->t('@bundle XML Sitemap settings', ['@bundle' => $bundle]); xmlsitemap_add_link_bundle_settings($form, $form_state, $entity, $bundle); $form['xmlsitemap']['#type'] = 'markup'; @@ -118,7 +118,7 @@ class XmlSitemapLinkBundleSettingsForm extends ConfigFormBase { $entity_info = $form['xmlsitemap']['#entity_info']; if (!empty($form['xmlsitemap']['#show_message'])) { - $this->messenger()->addStatus($this->t('XML sitemap settings for the %bundle have been saved.', ['%bundle' => $entity_info['bundles'][$bundle]['label']])); + $this->messenger()->addStatus($this->t('XML Sitemap settings for the %bundle have been saved.', ['%bundle' => $entity_info['bundles'][$bundle]['label']])); } // Unset the form values since we have already saved the bundle settings and diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapRebuildForm.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapRebuildForm.php index b32b6dba5..7ad3453aa 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapRebuildForm.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapRebuildForm.php @@ -70,7 +70,7 @@ class XmlSitemapRebuildForm extends ConfigFormBase { } else { $request->query->set('destination', 'admin/config/search/xmlsitemap'); - $this->messenger()->addWarning($this->t('A rebuild is not necessary. If you are just wanting to regenerate the XML sitemap files, you can run cron manually.', [ + $this->messenger()->addWarning($this->t('A rebuild is not necessary. If you are just wanting to regenerate the XML Sitemap files, you can run cron manually.', [ '@link-cron' => Url::fromRoute('system.run_cron', [], ['query' => $this->getDestinationArray()]), ])); $this->setRequest($request); diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapSettingsForm.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapSettingsForm.php index a3a5b8588..8c4fb4278 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapSettingsForm.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/Form/XmlSitemapSettingsForm.php @@ -130,7 +130,7 @@ class XmlSitemapSettingsForm extends ConfigFormBase { $form['xsl'] = [ '#type' => 'checkbox', '#title' => $this->t('Include a stylesheet in the sitemaps for humans.'), - '#description' => $this->t('When enabled, this will add formatting and tables with sorting to make it easier to view the XML sitemap data instead of viewing raw XML output. Search engines will ignore this.'), + '#description' => $this->t('When enabled, this will add formatting and tables with sorting to make it easier to view the XML Sitemap data instead of viewing raw XML output. Search engines will ignore this.'), '#default_value' => $config->get('xsl'), ]; $form['prefetch_aliases'] = [ @@ -196,7 +196,7 @@ class XmlSitemapSettingsForm extends ConfigFormBase { '#default_value' => $config->get('path'), '#size' => 30, '#maxlength' => 255, - '#description' => $this->t('Subdirectory where the sitemap data will be stored. This folder must not be shared with any other Drupal site or install using XML sitemap.'), + '#description' => $this->t('Subdirectory where the sitemap data will be stored. This folder must not be shared with any other Drupal site or install using XML Sitemap.'), '#field_prefix' => file_build_uri(''), '#required' => TRUE, ]; diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGenerator.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGenerator.php index 16fd9241a..9202c2588 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGenerator.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGenerator.php @@ -205,7 +205,7 @@ class XmlSitemapGenerator implements XmlSitemapGeneratorInterface { $this->setMemoryLimit(); if ($this->state->get('xmlsitemap_developer_mode')) { - $this->logger->notice('Starting XML sitemap generation. Memory usage: @memory-peak.', [ + $this->logger->notice('Starting XML Sitemap generation. Memory usage: @memory-peak.', [ '@memory-peak' => format_size(memory_get_peak_usage(TRUE)), ]); } @@ -318,7 +318,7 @@ class XmlSitemapGenerator implements XmlSitemapGeneratorInterface { // Ensure every link starts with a slash. // @see \Drupal\Core\Url::fromInternalUri() if ($link['loc'][0] !== '/') { - trigger_error("The XML sitemap link path {$link['loc']} for {$link['type']} {$link['id']} is invalid because it does not start with a slash.", E_USER_ERROR); + trigger_error("The XML Sitemap link path {$link['loc']} for {$link['type']} {$link['id']} is invalid because it does not start with a slash.", E_USER_ERROR); $link['loc'] = '/' . $link['loc']; } @@ -457,7 +457,7 @@ class XmlSitemapGenerator implements XmlSitemapGeneratorInterface { $context['sandbox']['max'] = $sitemap->getChunks(); $sitemap->setUpdated($this->time->getRequestTime()); xmlsitemap_sitemap_get_max_filesize($sitemap); - xmlsitemap_sitemap_save($sitemap); + $sitemap->saveState(); $context['finished'] = 1; return; @@ -496,7 +496,7 @@ class XmlSitemapGenerator implements XmlSitemapGeneratorInterface { $this->messenger->addStatus($this->t('The sitemaps were regenerated.')); // Show a watchdog message that the sitemap was regenerated. - $this->logger->notice('Finished XML sitemap generation in @elapsed. Memory usage: @memory-peak.', ['@elapsed' => $elapsed, '@memory-peak' => format_size(memory_get_peak_usage(TRUE))]); + $this->logger->notice('Finished XML Sitemap generation in @elapsed. Memory usage: @memory-peak.', ['@elapsed' => $elapsed, '@memory-peak' => format_size(memory_get_peak_usage(TRUE))]); } else { $this->messenger->addError($this->t('The sitemaps were not successfully regenerated.')); diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGeneratorInterface.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGeneratorInterface.php index 087bdb6ac..2ebeaacbd 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGeneratorInterface.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapGeneratorInterface.php @@ -61,7 +61,7 @@ interface XmlSitemapGeneratorInterface { * Generate one page (chunk) of the sitemap. * * @param XmlSitemapInterface $sitemap - * An unserialized data array for an XML sitemap. + * An unserialized data array for an XML Sitemap. * @param string $page * An integer of the specific page of the sitemap to generate. */ @@ -71,7 +71,7 @@ interface XmlSitemapGeneratorInterface { * Generates one chunk of the sitemap. * * @param \Drupal\xmlsitemap\XmlSitemapInterface $sitemap - * The XML sitemap config entity. + * The XML Sitemap config entity. * @param \Drupal\xmlsitemap\XmlSitemapWriter $writer * XML writer object. * @param int $chunk @@ -83,7 +83,7 @@ interface XmlSitemapGeneratorInterface { * Generate the index sitemap. * * @param \Drupal\xmlsitemap\XmlSitemapInterface $sitemap - * The XML sitemap config entity. + * The XML Sitemap config entity. * @param int|null $pages * The number of pages to write in the sitemap. Defaults to the value of * $sitemap->getChunks(). diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapInterface.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapInterface.php index 66b7e89ce..1d7ec50cd 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapInterface.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapInterface.php @@ -20,7 +20,7 @@ interface XmlSitemapInterface extends ConfigEntityInterface { /** * Returns the sitemap chunks number. * - * @return int + * @return int|null * The chunks number. */ public function getChunks(); @@ -28,7 +28,7 @@ interface XmlSitemapInterface extends ConfigEntityInterface { /** * Returns the sitemap links number. * - * @return int + * @return int|null * The links number. */ public function getLinks(); @@ -36,7 +36,7 @@ interface XmlSitemapInterface extends ConfigEntityInterface { /** * Returns the sitemap maximum file size. * - * @return int + * @return int|null * The maximum file size. */ public function getMaxFileSize(); @@ -50,10 +50,10 @@ interface XmlSitemapInterface extends ConfigEntityInterface { public function getContext(); /** - * Returns the sitemap context. + * Returns the timestamp of when the sitemap was last updated. * - * @return array - * The context. + * @return int|null + * The timestamp. */ public function getUpdated(); @@ -82,24 +82,24 @@ interface XmlSitemapInterface extends ConfigEntityInterface { /** * Sets the number of chunks. * - * @param string $chunks + * @param int $chunks * The number of chunks. * * @return \Drupal\xmlsitemap\XmlSitemapInterface * The class instance that this method is called on. */ - public function setChunks($chunks); + public function setChunks(int $chunks); /** * Sets the number of links. * - * @param string $links + * @param int $links * The number of links. * * @return \Drupal\xmlsitemap\XmlSitemapInterface * The class instance that this method is called on. */ - public function setLinks($links); + public function setLinks(int $links); /** * Sets the maximum file size of the sitemap. @@ -110,7 +110,7 @@ interface XmlSitemapInterface extends ConfigEntityInterface { * @return \Drupal\xmlsitemap\XmlSitemapInterface * The class instance that this method is called on. */ - public function setMaxFileSize($max_filesize); + public function setMaxFileSize(int $max_filesize); /** * Sets the context for the sitemap. @@ -124,21 +124,21 @@ interface XmlSitemapInterface extends ConfigEntityInterface { public function setContext($context); /** - * Sets if the sitemap was updated. + * Sets the timestamp of when the sitemap was updated. * - * @param bool $updated - * Check is sitemap was updated. + * @param int $updated + * The timestamp. * * @return \Drupal\xmlsitemap\XmlSitemapInterface * The class instance that this method is called on. */ - public function setUpdated($updated); + public function setUpdated(int $updated); /** * Returns the sitemap with the context specified as parameter. * * @param array $context - * An optional XML sitemap context array to use to find the correct XML + * An optional XML Sitemap context array to use to find the correct XML * sitemap. If not provided, the current site's context will be used. * * @return \Drupal\xmlsitemap\XmlSitemapInterface @@ -146,4 +146,9 @@ interface XmlSitemapInterface extends ConfigEntityInterface { */ public static function loadByContext(array $context = NULL); + /** + * Save the state information about the sitemap. + */ + public function saveState(): void; + } diff --git a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapLinkStorage.php b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapLinkStorage.php index 15c4f6b25..2a641c60d 100644 --- a/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapLinkStorage.php +++ b/frontend/drupal9/web/modules/contrib/xmlsitemap/src/XmlSitemapLinkStorage.php @@ -155,17 +155,17 @@ class XmlSitemapLinkStorage implements XmlSitemapLinkStorageInterface { // Temporary validation checks. // @todo Remove in final? if ($link['priority'] < 0 || $link['priority'] > 1) { - trigger_error("The XML sitemap link for {$link['type']} {$link['id']} has an invalid priority of {$link['priority']}.' . t('XML Sitemap automatically creates a sitemap that conforms to the sitemaps.org specification. This helps search engines keep their search results up to date.') . '
'; + $output .= '' . t("You can adjust the settings for your site's sitemap at admin/config/search/xmlsitemap. Your can view your site's sitemap at http://yoursite.com/sitemap.xml.") . '
'; + $output .= '' . t("When is necessary you can rebuild your sitemap at admin/config/search/xmlsitemap/rebuild.") . '
'; + $output .= '' . t("You can configure all Custom Entities Settings at admin/config/search/xmlsitemap/entities/settings") . '
'; + $output .= '' . t('It is highly recommended that you have clean URLs enabled for this project.') . '
'; + return $output; + case 'xmlsitemap.admin_rebuild': - $output .= '' . t("This action rebuilds your site's XML sitemap and regenerates the cached files, and may be a lengthy process. If you just installed XML sitemap, this can be helpful to import all your site's content into the sitemap. Otherwise, this should only be used in emergencies.") . '
'; + $output .= '' . t("This action rebuilds your site's XML Sitemap and regenerates the cached files, and may be a lengthy process. If you just installed XML Sitemap, this can be helpful to import all your site's content into the sitemap. Otherwise, this should only be used in emergencies.") . '
'; } $currentUser = \Drupal::currentUser(); @@ -290,20 +300,20 @@ function xmlsitemap_var($name, $default = NULL) { } /** - * @defgroup xmlsitemap_api XML sitemap API. + * @defgroup xmlsitemap_api XML Sitemap API. * @{ - * This is the XML sitemap API to be used by modules wishing to work with - * XML sitemap and/or link data. + * This is the XML Sitemap API to be used by modules wishing to work with + * XML Sitemap and/or link data. */ /** - * Load an XML sitemap array from the database. + * Load an XML Sitemap array from the database. * * @param mixed $smid - * An XML sitemap ID. + * An XML Sitemap ID. * * @return \Drupal\xmlsitemap\XmlSitemapInterface - * The XML sitemap object. + * The XML Sitemap object. */ function xmlsitemap_sitemap_load($smid) { $sitemap = xmlsitemap_sitemap_load_multiple([$smid]); @@ -311,15 +321,15 @@ function xmlsitemap_sitemap_load($smid) { } /** - * Load multiple XML sitemaps from the database. + * Load multiple XML Sitemaps from the database. * * @param array|bool $smids - * An array of XML sitemap IDs, or FALSE to load all XML sitemaps. + * An array of XML Sitemap IDs, or FALSE to load all XML Sitemaps. * @param array $conditions * An array of conditions in the form 'field' => $value. * * @return \Drupal\xmlsitemap\XmlSitemapInterface[] - * An array of XML sitemap objects. + * An array of XML Sitemap objects. */ function xmlsitemap_sitemap_load_multiple($smids = [], array $conditions = []) { if ($smids !== FALSE) { @@ -340,11 +350,11 @@ function xmlsitemap_sitemap_load_multiple($smids = [], array $conditions = []) { } /** - * Save changes to an XML sitemap or add a new XML sitemap. + * Save changes to an XML Sitemap or add a new XML Sitemap. * * @param Drupal\xmlsitemap\XmlSitemapInterface $sitemap - * The XML sitemap array to be saved. If $sitemap->smid is omitted, a new - * XML sitemap will be added. + * The XML Sitemap array to be saved. If $sitemap->smid is omitted, a new + * XML Sitemap will be added. * * @todo Save the sitemap's URL as a column? */ @@ -374,20 +384,20 @@ function xmlsitemap_sitemap_save(XmlSitemapInterface $sitemap) { } /** - * Delete an XML sitemap. + * Delete an XML Sitemap. * * @param string $smid - * An XML sitemap ID. + * An XML Sitemap ID. */ function xmlsitemap_sitemap_delete($smid) { xmlsitemap_sitemap_delete_multiple([$smid]); } /** - * Delete multiple XML sitemaps. + * Delete multiple XML Sitemaps. * * @param array $smids - * An array of XML sitemap IDs. + * An array of XML Sitemap IDs. */ function xmlsitemap_sitemap_delete_multiple(array $smids) { if (!empty($smids)) { @@ -418,7 +428,7 @@ function xmlsitemap_sitemap_get_file(XmlSitemapInterface $sitemap, $chunk = 'ind * Find the maximum file size of all a sitemap's XML files. * * @param \Drupal\xmlsitemap\XmlSitemapInterface $sitemap - * The XML sitemap object. + * The XML Sitemap object. * * @return int * Maximum file size in the directory. @@ -450,14 +460,14 @@ function xmlsitemap_sitemap_get_context_hash(array &$context) { } /** - * Returns the uri elements of an XML sitemap. + * Returns the uri elements of an XML Sitemap. * * @param \Drupal\xmlsitemap\XmlSitemapInterface $sitemap * The sitemap represented by and XmlSitemapInterface object. * * @return array * An array containing the 'path' and 'options' keys used to build the uri of - * the XML sitemap, and matching the signature of url(). + * the XML Sitemap, and matching the signature of url(). */ function xmlsitemap_sitemap_uri(XmlSitemapInterface $sitemap) { $uri['path'] = 'sitemap.xml'; @@ -623,7 +633,7 @@ function _xmlsitemap_delete_recursive($path, $delete_root = FALSE) { * Implements hook_entity_type_build(). */ function xmlsitemap_entity_type_build(array &$entity_types) { - // Mark some specific core entity types as not supported by XML sitemap. + // Mark some specific core entity types as not supported by XML Sitemap. // If a site wants to undo this, they may use hook_entity_type_alter(). $unsupported_types = [ // Custom blocks. @@ -648,7 +658,7 @@ function xmlsitemap_entity_type_build(array &$entity_types) { } /** - * Determines if an entity type can be listed in the XML sitemap as links. + * Determines if an entity type can be listed in the XML Sitemap as links. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. @@ -657,7 +667,7 @@ function xmlsitemap_entity_type_build(array &$entity_types) { * TRUE if the entity type can be used, or FALSE otherwise. */ function xmlsitemap_is_entity_type_supported(EntityTypeInterface $entity_type) { - // If the XML sitemap status in the entity type annotation has been set then + // If the XML Sitemap status in the entity type annotation has been set then // return that first. This will allow modules to bypass the logic below if // needed. $status = $entity_type->get('xmlsitemap'); @@ -1034,18 +1044,18 @@ function xmlsitemap_entity_bundle_delete($entity_type_id, $bundle) { * A string representing the update frequency according to the sitemaps.org * protocol. */ -function xmlsitemap_get_changefreq($interval) { +function xmlsitemap_get_changefreq($interval, bool $translated = TRUE) { if ($interval <= 0 || !is_numeric($interval)) { return FALSE; } foreach (xmlsitemap_get_changefreq_options() as $value => $frequency) { if ($interval <= $value) { - return $frequency; + return $translated ? $frequency : $frequency->getUntranslatedString(); } } - return 'never'; + return $translated ? t('never', [], ['context' => 'At no time']) : 'never'; } /** @@ -1169,7 +1179,7 @@ function xmlsitemap_form_submit_flag_regenerate(array $form, FormStateInterface } if ($stored_value != 'not_a_variable' && $stored_value != $value) { \Drupal::state()->set('xmlsitemap_regenerate_needed', TRUE); - \Drupal::messenger()->addWarning(t('XML sitemap settings have been modified and the files should be regenerated. You can run cron manually to regenerate the cached files.', [ + \Drupal::messenger()->addWarning(t('XML Sitemap settings have been modified and the files should be regenerated. You can run cron manually to regenerate the cached files.', [ '@run-cron' => Url::fromRoute('system.run_cron', [], ['query' => \Drupal::destination()->getAsArray()])->toString(), ]), FALSE); return; @@ -1178,7 +1188,7 @@ function xmlsitemap_form_submit_flag_regenerate(array $form, FormStateInterface } /** - * Add a link's XML sitemap options to the link's form. + * Add a link's XML Sitemap options to the link's form. * * @param array $form * Form array. @@ -1213,7 +1223,7 @@ function xmlsitemap_add_form_link_options(array &$form, $entity_type, $bundle, $ $form['xmlsitemap'] = [ '#type' => 'details', '#tree' => TRUE, - '#title' => t('XML sitemap'), + '#title' => t('XML Sitemap'), '#collapsible' => TRUE, '#collapsed' => !$link['status_override'] && !$link['priority_override'], '#access' => $currentUser->hasPermission('administer xmlsitemap') || ($admin_permission && $currentUser->hasPermission($admin_permission)), @@ -1340,7 +1350,7 @@ function xmlsitemap_link_bundle_settings_form_submit($form, &$form_state) { $entity_info = $form['xmlsitemap']['#entity_info']; if (!empty($form['xmlsitemap']['#show_message'])) { - \Drupal::messenger()->addStatus(t('XML sitemap settings for the @bundle-label %bundle have been saved.', ['@bundle-label' => mb_strtolower($entity_info['bundle label']), '%bundle' => $entity_info['bundles'][$bundle]['label']])); + \Drupal::messenger()->addStatus(t('XML Sitemap settings for the @bundle-label %bundle have been saved.', ['@bundle-label' => mb_strtolower($entity_info['bundle label']), '%bundle' => $entity_info['bundles'][$bundle]['label']])); } // Unset the form values since we have already saved the bundle settings and @@ -1352,20 +1362,17 @@ function xmlsitemap_link_bundle_settings_form_submit($form, &$form_state) { /** * Gets xmlsitemap frequency options. * - * @return array + * @return \Drupal\Core\StringTranslation\TranslatableMarkup[] * Frequency options. - * - * @todo Document this function. - * @todo Make these translatable */ function xmlsitemap_get_changefreq_options() { return [ - XMLSITEMAP_FREQUENCY_ALWAYS => 'always', - XMLSITEMAP_FREQUENCY_HOURLY => 'hourly', - XMLSITEMAP_FREQUENCY_DAILY => 'daily', - XMLSITEMAP_FREQUENCY_WEEKLY => 'weekly', - XMLSITEMAP_FREQUENCY_MONTHLY => 'monthly', - XMLSITEMAP_FREQUENCY_YEARLY => 'yearly', + XMLSITEMAP_FREQUENCY_ALWAYS => t('always', [], ['context' => 'At all times']), + XMLSITEMAP_FREQUENCY_HOURLY => t('hourly'), + XMLSITEMAP_FREQUENCY_DAILY => t('daily'), + XMLSITEMAP_FREQUENCY_WEEKLY => t('weekly'), + XMLSITEMAP_FREQUENCY_MONTHLY => t('monthly'), + XMLSITEMAP_FREQUENCY_YEARLY => t('yearly'), ]; } @@ -1392,7 +1399,7 @@ function xmlsitemap_language_load($language = LanguageInterface::LANGCODE_NOT_SP } /** - * @defgroup xmlsitemap_context_api XML sitemap API for sitemap contexts. + * @defgroup xmlsitemap_context_api XML Sitemap API for sitemap contexts. * @{ */ @@ -2009,7 +2016,7 @@ function xmlsitemap_xmlsitemap_sitemap_operations() { } /** - * XML sitemap link type settings callback for frontpage link entity. + * XML Sitemap link type settings callback for frontpage link entity. * * @param array $form * Form array. @@ -2037,10 +2044,10 @@ function xmlsitemap_link_frontpage_settings(array &$form) { } /** - * XML sitemap operation callback; regenerate sitemap files using the batch API. + * XML Sitemap operation callback; regenerate sitemap files using the batch API. * * @param array $smids - * An array of XML sitemap IDs. + * An array of XML Sitemap IDs. * * @see xmlsitemap_regenerate_batch() */ @@ -2122,7 +2129,7 @@ function xmlsitemap_add_form_entity_summary(array &$form, $entity, array $entity } /** - * Add the link type XML sitemap options to the link type's form. + * Add the link type XML Sitemap options to the link type's form. * * Caller is responsible for ensuring xmlsitemap_link_bundle_settings_save() * is called during submission. @@ -2143,7 +2150,7 @@ function xmlsitemap_add_link_bundle_settings(array &$form, FormStateInterface $f $form['xmlsitemap'] = [ '#type' => 'details', - '#title' => t('XML sitemap'), + '#title' => t('XML Sitemap'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#access' => \Drupal::currentUser()->hasPermission('administer xmlsitemap'), @@ -2352,7 +2359,7 @@ function _xmlsitemap_get_blurb($check_version = TRUE) { \Drupal::linkGenerator()->generate('Coupons Dealuxe', Url::fromUri('http://couponsdealuxe.com/', ['attributes' => ['target' => 'blank']])), ]; // Don't extract the following string for translation. - $blurb = 'Thank you for helping test the XML sitemap module rewrite. Please consider helping offset developer free time by donating or if your company is interested in sponsoring the rewrite or a specific feature, please contact the developer. Thank you to the following current sponsors: ' . implode(', ', $sponsors) . ', and all the individuals that have donated. This message will not be seen in the stable versions.
Thank you for helping test the XML Sitemap module rewrite. Please consider helping offset developer free time by donating or if your company is interested in sponsoring the rewrite or a specific feature, please contact the developer. Thank you to the following current sponsors: ' . implode(', ', $sponsors) . ', and all the individuals that have donated. This message will not be seen in the stable versions.