@@ -123,8 +123,18 @@ class Builder extends BaseBuilder
123
123
*/
124
124
public $ options = [];
125
125
126
+ public const TRANSFORM_QUERY_DATE = 1 << 0 ;
127
+ public const TRANSFORM_RESULT_DATE = 1 << 1 ;
128
+ public const TRANSFORM_RENAME_QUERY_ROOT_ID = 1 << 2 ;
129
+ public const TRANSFORM_RENAME_RESULT_ROOT_ID = 1 << 3 ;
130
+ public const TRANSFORM_RENAME_QUERY_EMBED_ID = 1 << 4 ;
131
+ public const TRANSFORM_RENAME_RESULT_EMBED_ID = 1 << 5 ;
132
+
133
+ /** @var int-mask-of<self::TRANSFORM_* */
134
+ private int $ transformations = -1 ;
135
+
126
136
/**
127
- * All of the available clause operators.
137
+ * All the available clause operators.
128
138
*
129
139
* @var array
130
140
*/
@@ -575,6 +585,27 @@ public function generateCacheKey()
575
585
return md5 (serialize (array_values ($ key )));
576
586
}
577
587
588
+ public function disableDateTransformation (): static
589
+ {
590
+ $ this ->transformations &= ~self ::TRANSFORM_QUERY_DATE & ~self ::TRANSFORM_RESULT_DATE ;
591
+
592
+ return $ this ;
593
+ }
594
+
595
+ public function disableRootIdTransformation (): static
596
+ {
597
+ $ this ->transformations &= ~self ::TRANSFORM_RENAME_QUERY_ROOT_ID & ~self ::TRANSFORM_RENAME_RESULT_ROOT_ID ;
598
+
599
+ return $ this ;
600
+ }
601
+
602
+ public function disableEmbedIdTransformation (): static
603
+ {
604
+ $ this ->transformations &= ~self ::TRANSFORM_RENAME_QUERY_EMBED_ID & ~self ::TRANSFORM_RENAME_RESULT_EMBED_ID ;
605
+
606
+ return $ this ;
607
+ }
608
+
578
609
/** @return ($function is null ? AggregationBuilder : mixed) */
579
610
public function aggregate ($ function = null , $ columns = ['* ' ])
580
611
{
@@ -1763,9 +1794,12 @@ public function orWhereIntegerNotInRaw($column, $values, $boolean = 'and')
1763
1794
throw new BadMethodCallException ('This method is not supported by MongoDB ' );
1764
1795
}
1765
1796
1766
- private function aliasIdForQuery (array $ values ): array
1797
+ private function aliasIdForQuery (array $ values, bool $ root = true ): array
1767
1798
{
1768
- if (array_key_exists ('id ' , $ values )) {
1799
+ if (
1800
+ ($ root && $ this ->transformations & self ::TRANSFORM_RENAME_QUERY_ROOT_ID || ! $ root && $ this ->transformations & self ::TRANSFORM_RENAME_QUERY_EMBED_ID )
1801
+ && array_key_exists ('id ' , $ values )
1802
+ ) {
1769
1803
if (array_key_exists ('_id ' , $ values ) && $ values ['id ' ] !== $ values ['_id ' ]) {
1770
1804
throw new InvalidArgumentException ('Cannot have both "id" and "_id" fields. ' );
1771
1805
}
@@ -1792,7 +1826,10 @@ private function aliasIdForQuery(array $values): array
1792
1826
}
1793
1827
1794
1828
// ".id" subfield are alias for "._id"
1795
- if (str_ends_with ($ key , '.id ' )) {
1829
+ if (
1830
+ $ this ->transformations & self ::TRANSFORM_RENAME_QUERY_EMBED_ID
1831
+ && str_ends_with ($ key , '.id ' )
1832
+ ) {
1796
1833
$ newkey = substr ($ key , 0 , -3 ) . '._id ' ;
1797
1834
if (array_key_exists ($ newkey , $ values ) && $ value !== $ values [$ newkey ]) {
1798
1835
throw new InvalidArgumentException (sprintf ('Cannot have both "%s" and "%s" fields. ' , $ key , $ newkey ));
@@ -1805,8 +1842,8 @@ private function aliasIdForQuery(array $values): array
1805
1842
1806
1843
foreach ($ values as &$ value ) {
1807
1844
if (is_array ($ value )) {
1808
- $ value = $ this ->aliasIdForQuery ($ value );
1809
- } elseif ($ value instanceof DateTimeInterface) {
1845
+ $ value = $ this ->aliasIdForQuery ($ value, false );
1846
+ } elseif ($ this -> transformations & self :: TRANSFORM_QUERY_DATE && $ value instanceof DateTimeInterface) {
1810
1847
$ value = new UTCDateTime ($ value );
1811
1848
}
1812
1849
}
@@ -1817,42 +1854,49 @@ private function aliasIdForQuery(array $values): array
1817
1854
/**
1818
1855
* @internal
1819
1856
*
1857
+ * @param bool $embed True when applied to a sub-document
1820
1858
* @psalm-param T $values
1821
1859
*
1822
1860
* @psalm-return T
1823
1861
*
1824
1862
* @template T of array|object
1825
1863
*/
1826
- public function aliasIdForResult (array |object $ values ): array |object
1864
+ public function aliasIdForResult (array |object $ values, bool $ root = false ): array |object
1827
1865
{
1828
1866
if (is_array ($ values )) {
1829
- if (array_key_exists ('_id ' , $ values ) && ! array_key_exists ('id ' , $ values )) {
1867
+ if (
1868
+ ($ root && $ this ->transformations & self ::TRANSFORM_RENAME_RESULT_ROOT_ID || ! $ root && $ this ->transformations & self ::TRANSFORM_RENAME_QUERY_EMBED_ID )
1869
+ && array_key_exists ('_id ' , $ values ) && ! array_key_exists ('id ' , $ values )
1870
+ ) {
1830
1871
$ values ['id ' ] = $ values ['_id ' ];
1831
1872
unset($ values ['_id ' ]);
1832
1873
}
1833
1874
1834
1875
foreach ($ values as $ key => $ value ) {
1835
- if ($ value instanceof UTCDateTime) {
1876
+ if ($ this -> transformations & self :: TRANSFORM_RESULT_DATE && $ value instanceof UTCDateTime) {
1836
1877
$ values [$ key ] = Date::instance ($ value ->toDateTime ())
1837
1878
->setTimezone (new DateTimeZone (date_default_timezone_get ()));
1838
1879
} elseif (is_array ($ value ) || is_object ($ value )) {
1839
- $ values [$ key ] = $ this ->aliasIdForResult ($ value );
1880
+ $ values [$ key ] = $ this ->aliasIdForResult ($ value, true );
1840
1881
}
1841
1882
}
1842
1883
}
1843
1884
1844
1885
if ($ values instanceof stdClass) {
1845
- if (property_exists ($ values , '_id ' ) && ! property_exists ($ values , 'id ' )) {
1886
+ if (
1887
+ ($ root && $ this ->transformations & self ::TRANSFORM_RENAME_RESULT_ROOT_ID || ! $ root && $ this ->transformations & self ::TRANSFORM_RENAME_QUERY_EMBED_ID )
1888
+ && property_exists ($ values , '_id ' ) && ! property_exists ($ values , 'id ' )
1889
+ ) {
1846
1890
$ values ->id = $ values ->_id ;
1847
1891
unset($ values ->_id );
1848
1892
}
1849
1893
1850
1894
foreach (get_object_vars ($ values ) as $ key => $ value ) {
1851
- if ($ value instanceof UTCDateTime) {
1895
+ if ($ this -> transformations & self :: TRANSFORM_RESULT_DATE && $ value instanceof UTCDateTime) {
1852
1896
$ values ->{$ key } = Date::instance ($ value ->toDateTime ())
1853
1897
->setTimezone (new DateTimeZone (date_default_timezone_get ()));
1854
1898
} elseif (is_array ($ value ) || is_object ($ value )) {
1855
- $ values ->{$ key } = $ this ->aliasIdForResult ($ value );
1899
+ $ values ->{$ key } = $ this ->aliasIdForResult ($ value, true );
1856
1900
}
1857
1901
}
1858
1902
}
0 commit comments