|
16 | 16 | use Gedmo\Exception\InvalidArgumentException;
|
17 | 17 | use Gedmo\Exception\RuntimeException;
|
18 | 18 | use Gedmo\Exception\UnexpectedValueException;
|
| 19 | +use Gedmo\Tool\ORM\Repository\EntityRepositoryCompat; |
19 | 20 | use Gedmo\Tool\Wrapper\EntityWrapper;
|
20 | 21 | use Gedmo\Tree\Node;
|
21 | 22 | use Gedmo\Tree\Strategy;
|
|
43 | 44 | */
|
44 | 45 | class NestedTreeRepository extends AbstractTreeRepository
|
45 | 46 | {
|
46 |
| - /** |
47 |
| - * Allows the following 'virtual' methods: |
48 |
| - * - persistAsFirstChild($node) |
49 |
| - * - persistAsFirstChildOf($node, $parent) |
50 |
| - * - persistAsLastChild($node) |
51 |
| - * - persistAsLastChildOf($node, $parent) |
52 |
| - * - persistAsNextSibling($node) |
53 |
| - * - persistAsNextSiblingOf($node, $sibling) |
54 |
| - * - persistAsPrevSibling($node) |
55 |
| - * - persistAsPrevSiblingOf($node, $sibling) |
56 |
| - * Inherited virtual methods: |
57 |
| - * - find* |
58 |
| - * |
59 |
| - * @see \Doctrine\ORM\EntityRepository |
60 |
| - * |
61 |
| - * @throws InvalidArgumentException If arguments are invalid |
62 |
| - * @throws \BadMethodCallException If the method called is an invalid find* or persistAs* method |
63 |
| - * or no find* either persistAs* method at all and therefore an invalid method call |
64 |
| - * |
65 |
| - * @return mixed TreeNestedRepository if persistAs* is called |
66 |
| - */ |
67 |
| - public function __call($method, $args) |
68 |
| - { |
69 |
| - if ('persistAs' === substr($method, 0, 9)) { |
70 |
| - if (!isset($args[0])) { |
71 |
| - throw new InvalidArgumentException('Node to persist must be available as first argument.'); |
72 |
| - } |
73 |
| - $node = $args[0]; |
74 |
| - $wrapped = new EntityWrapper($node, $this->getEntityManager()); |
75 |
| - $meta = $this->getClassMetadata(); |
76 |
| - $config = $this->listener->getConfiguration($this->getEntityManager(), $meta->getName()); |
77 |
| - $position = substr($method, 9); |
78 |
| - if ('Of' === substr($method, -2)) { |
79 |
| - if (!isset($args[1])) { |
80 |
| - throw new InvalidArgumentException('If "Of" is specified you must provide parent or sibling as the second argument.'); |
81 |
| - } |
82 |
| - $parentOrSibling = $args[1]; |
83 |
| - if (strstr($method, 'Sibling')) { |
84 |
| - $wrappedParentOrSibling = new EntityWrapper($parentOrSibling, $this->getEntityManager()); |
85 |
| - $newParent = $wrappedParentOrSibling->getPropertyValue($config['parent']); |
86 |
| - if (null === $newParent && isset($config['root'])) { |
87 |
| - throw new UnexpectedValueException('Cannot persist sibling for a root node, tree operation is not possible'); |
88 |
| - } |
89 |
| - |
90 |
| - if (!$node instanceof Node) { |
91 |
| - @trigger_error(\sprintf( |
92 |
| - 'Not implementing the "%s" interface from node "%s" is deprecated since gedmo/doctrine-extensions' |
93 |
| - .' 3.13 and will throw a "%s" error in version 4.0.', |
94 |
| - Node::class, |
95 |
| - \get_class($node), |
96 |
| - \TypeError::class |
97 |
| - ), \E_USER_DEPRECATED); |
98 |
| - } |
99 |
| - |
100 |
| - // @todo: In the next major release, remove the previous condition and uncomment the following one. |
101 |
| - |
102 |
| - // if (!$node instanceof Node) { |
103 |
| - // throw new \TypeError(\sprintf( |
104 |
| - // 'Node MUST implement "%s" interface.', |
105 |
| - // Node::class |
106 |
| - // )); |
107 |
| - // } |
108 |
| - |
109 |
| - // @todo: In the next major release, remove the `method_exists()` condition and left the `else` branch. |
110 |
| - if (!method_exists($node, 'setSibling')) { |
111 |
| - $node->sibling = $parentOrSibling; |
112 |
| - } else { |
113 |
| - $node->setSibling($parentOrSibling); |
114 |
| - } |
115 |
| - $parentOrSibling = $newParent; |
116 |
| - } |
117 |
| - $wrapped->setPropertyValue($config['parent'], $parentOrSibling); |
118 |
| - $position = substr($position, 0, -2); |
119 |
| - } |
120 |
| - $wrapped->setPropertyValue($config['left'], 0); // simulate changeset |
121 |
| - $oid = spl_object_id($node); |
122 |
| - $this->listener |
123 |
| - ->getStrategy($this->getEntityManager(), $meta->getName()) |
124 |
| - ->setNodePosition($oid, $position) |
125 |
| - ; |
126 |
| - |
127 |
| - $this->getEntityManager()->persist($node); |
128 |
| - |
129 |
| - return $this; |
130 |
| - } |
131 |
| - |
132 |
| - return parent::__call($method, $args); |
133 |
| - } |
| 47 | + use EntityRepositoryCompat; |
134 | 48 |
|
135 | 49 | public function getRootNodesQueryBuilder($sortByField = null, $direction = 'asc')
|
136 | 50 | {
|
@@ -1169,6 +1083,100 @@ public function getNodesHierarchy($node = null, $direct = false, array $options
|
1169 | 1083 | return $this->getNodesHierarchyQuery($node, $direct, $options, $includeNode)->getArrayResult();
|
1170 | 1084 | }
|
1171 | 1085 |
|
| 1086 | + /** |
| 1087 | + * Allows the following 'virtual' methods: |
| 1088 | + * - persistAsFirstChild($node) |
| 1089 | + * - persistAsFirstChildOf($node, $parent) |
| 1090 | + * - persistAsLastChild($node) |
| 1091 | + * - persistAsLastChildOf($node, $parent) |
| 1092 | + * - persistAsNextSibling($node) |
| 1093 | + * - persistAsNextSiblingOf($node, $sibling) |
| 1094 | + * - persistAsPrevSibling($node) |
| 1095 | + * - persistAsPrevSiblingOf($node, $sibling) |
| 1096 | + * Inherited virtual methods: |
| 1097 | + * - find* |
| 1098 | + * |
| 1099 | + * @param string $method |
| 1100 | + * @param array $args |
| 1101 | + * |
| 1102 | + * @phpstan-param list<mixed> $args |
| 1103 | + * |
| 1104 | + * @throws \BadMethodCallException If the method called is an invalid find* or persistAs* method |
| 1105 | + * or no find* either persistAs* method at all and therefore an invalid method call |
| 1106 | + * @throws InvalidArgumentException If arguments are invalid |
| 1107 | + * |
| 1108 | + * @return mixed TreeNestedRepository if persistAs* is called |
| 1109 | + * |
| 1110 | + * @see \Doctrine\ORM\EntityRepository |
| 1111 | + */ |
| 1112 | + protected function doCallWithCompat($method, $args) |
| 1113 | + { |
| 1114 | + if ('persistAs' === substr($method, 0, 9)) { |
| 1115 | + if (!isset($args[0])) { |
| 1116 | + throw new InvalidArgumentException('Node to persist must be available as first argument.'); |
| 1117 | + } |
| 1118 | + $node = $args[0]; |
| 1119 | + $wrapped = new EntityWrapper($node, $this->getEntityManager()); |
| 1120 | + $meta = $this->getClassMetadata(); |
| 1121 | + $config = $this->listener->getConfiguration($this->getEntityManager(), $meta->getName()); |
| 1122 | + $position = substr($method, 9); |
| 1123 | + if ('Of' === substr($method, -2)) { |
| 1124 | + if (!isset($args[1])) { |
| 1125 | + throw new InvalidArgumentException('If "Of" is specified you must provide parent or sibling as the second argument.'); |
| 1126 | + } |
| 1127 | + $parentOrSibling = $args[1]; |
| 1128 | + if (strstr($method, 'Sibling')) { |
| 1129 | + $wrappedParentOrSibling = new EntityWrapper($parentOrSibling, $this->getEntityManager()); |
| 1130 | + $newParent = $wrappedParentOrSibling->getPropertyValue($config['parent']); |
| 1131 | + if (null === $newParent && isset($config['root'])) { |
| 1132 | + throw new UnexpectedValueException('Cannot persist sibling for a root node, tree operation is not possible'); |
| 1133 | + } |
| 1134 | + |
| 1135 | + if (!$node instanceof Node) { |
| 1136 | + @trigger_error(\sprintf( |
| 1137 | + 'Not implementing the "%s" interface from node "%s" is deprecated since gedmo/doctrine-extensions' |
| 1138 | + .' 3.13 and will throw a "%s" error in version 4.0.', |
| 1139 | + Node::class, |
| 1140 | + \get_class($node), |
| 1141 | + \TypeError::class |
| 1142 | + ), \E_USER_DEPRECATED); |
| 1143 | + } |
| 1144 | + |
| 1145 | + // @todo: In the next major release, remove the previous condition and uncomment the following one. |
| 1146 | + |
| 1147 | + // if (!$node instanceof Node) { |
| 1148 | + // throw new \TypeError(\sprintf( |
| 1149 | + // 'Node MUST implement "%s" interface.', |
| 1150 | + // Node::class |
| 1151 | + // )); |
| 1152 | + // } |
| 1153 | + |
| 1154 | + // @todo: In the next major release, remove the `method_exists()` condition and left the `else` branch. |
| 1155 | + if (!method_exists($node, 'setSibling')) { |
| 1156 | + $node->sibling = $parentOrSibling; |
| 1157 | + } else { |
| 1158 | + $node->setSibling($parentOrSibling); |
| 1159 | + } |
| 1160 | + $parentOrSibling = $newParent; |
| 1161 | + } |
| 1162 | + $wrapped->setPropertyValue($config['parent'], $parentOrSibling); |
| 1163 | + $position = substr($position, 0, -2); |
| 1164 | + } |
| 1165 | + $wrapped->setPropertyValue($config['left'], 0); // simulate changeset |
| 1166 | + $oid = spl_object_id($node); |
| 1167 | + $this->listener |
| 1168 | + ->getStrategy($this->getEntityManager(), $meta->getName()) |
| 1169 | + ->setNodePosition($oid, $position) |
| 1170 | + ; |
| 1171 | + |
| 1172 | + $this->getEntityManager()->persist($node); |
| 1173 | + |
| 1174 | + return $this; |
| 1175 | + } |
| 1176 | + |
| 1177 | + return parent::__call($method, $args); |
| 1178 | + } |
| 1179 | + |
1172 | 1180 | protected function validate()
|
1173 | 1181 | {
|
1174 | 1182 | return Strategy::NESTED === $this->listener->getStrategy($this->getEntityManager(), $this->getClassMetadata()->name)->getName();
|
|
0 commit comments