@@ -662,7 +662,9 @@ private function syncNode($uuid, $path, $type, $isNewNode, $props = array(), $pr
662
662
'namespace ' => $ namespace ,
663
663
'parent ' => PathHelper::getParentPath ($ path ),
664
664
'workspace_name ' => $ this ->workspaceName ,
665
- 'props ' => $ propsData ['dom ' ]->saveXML (),
665
+ 'props ' => $ propsData ['stringDom ' ] ? $ propsData ['stringDom ' ]->saveXML () : null ,
666
+ 'long_props ' => $ propsData ['longDom ' ] ? $ propsData ['longDom ' ]->saveXML () : null ,
667
+ 'decimal_props ' => $ propsData ['decimalDom ' ] ? $ propsData ['decimalDom ' ]->saveXML () : null ,
666
668
'depth ' => PathHelper::getPathDepth ($ path ),
667
669
'parent_a ' => PathHelper::getParentPath ($ path ),
668
670
));
@@ -684,7 +686,13 @@ private function syncNode($uuid, $path, $type, $isNewNode, $props = array(), $pr
684
686
if (!$ nodeId ) {
685
687
throw new RepositoryException ("nodeId for $ path not found " );
686
688
}
687
- $ this ->conn ->update ('phpcr_nodes ' , array ('props ' => $ propsData ['dom ' ]->saveXML ()), array ('id ' => $ nodeId ));
689
+ $ this ->conn ->update ('phpcr_nodes ' , array (
690
+ 'props ' => $ propsData ['stringDom ' ] ? $ propsData ['stringDom ' ]->saveXML () : null ,
691
+ 'long_props ' => $ propsData ['longDom ' ] ? $ propsData ['longDom ' ]->saveXML () : null ,
692
+ 'decimal_props ' => $ propsData ['decimalDom ' ] ? $ propsData ['decimalDom ' ]->saveXML () : null ,
693
+ ),
694
+ array ('id ' => $ nodeId )
695
+ );
688
696
}
689
697
690
698
$ this ->nodeIdentifiers [$ path ] = $ uuid ;
@@ -837,70 +845,85 @@ private function syncReferences()
837
845
}
838
846
}
839
847
840
- public static function xmlToProps ($ xml , ValueConverter $ valueConverter , $ filter = null )
848
+ public static function xmlToProps ($ xmlData , ValueConverter $ valueConverter , $ filter = null )
841
849
{
842
850
$ data = new \stdClass ();
843
851
844
- $ dom = new \DOMDocument ('1.0 ' , 'UTF-8 ' );
845
- $ dom ->loadXML ($ xml );
852
+ $ xmlFields = array ();
846
853
847
- foreach ($ dom ->getElementsByTagNameNS ('http://www.jcp.org/jcr/sv/1.0 ' , 'property ' ) as $ propertyNode ) {
848
- $ name = $ propertyNode ->getAttribute ('sv:name ' );
854
+ if (!empty ($ xmlData ['props ' ])) {
855
+ $ xmlFields [] = $ xmlData ['props ' ];
856
+ }
857
+ if (!empty ($ xmlData ['long_props ' ])) {
858
+ $ xmlFields [] = $ xmlData ['long_props ' ];
859
+ }
860
+ if (!empty ($ xmlData ['decimal_props ' ])) {
861
+ $ xmlFields [] = $ xmlData ['decimal_props ' ];
862
+ }
849
863
850
- // only return the properties that pass through the filter callback
851
- if (null !== $ filter && is_callable ($ filter ) && false === $ filter ($ name )) {
852
- continue ;
853
- }
864
+ foreach ($ xmlFields as $ xml ) {
865
+
866
+ $ dom = new \DOMDocument ('1.0 ' , 'UTF-8 ' );
867
+ $ dom ->loadXML ($ xml );
868
+
869
+ foreach ($ dom ->getElementsByTagNameNS ('http://www.jcp.org/jcr/sv/1.0 ' , 'property ' ) as $ propertyNode ) {
870
+ $ name = $ propertyNode ->getAttribute ('sv:name ' );
871
+
872
+ // only return the properties that pass through the filter callback
873
+ if (null !== $ filter && is_callable ($ filter ) && false === $ filter ($ name )) {
874
+ continue ;
875
+ }
876
+
877
+ $ values = array ();
878
+ $ type = PropertyType::valueFromName ($ propertyNode ->getAttribute ('sv:type ' ));
879
+ foreach ($ propertyNode ->childNodes as $ valueNode ) {
880
+ switch ($ type ) {
881
+ case PropertyType::NAME :
882
+ case PropertyType::URI :
883
+ case PropertyType::WEAKREFERENCE :
884
+ case PropertyType::REFERENCE :
885
+ case PropertyType::PATH :
886
+ case PropertyType::DECIMAL :
887
+ case PropertyType::STRING :
888
+ $ values [] = $ valueNode ->nodeValue ;
889
+ break ;
890
+ case PropertyType::BOOLEAN :
891
+ $ values [] = (bool ) $ valueNode ->nodeValue ;
892
+ break ;
893
+ case PropertyType::LONG :
894
+ $ values [] = (int ) $ valueNode ->nodeValue ;
895
+ break ;
896
+ case PropertyType::BINARY :
897
+ $ values [] = (int ) $ valueNode ->nodeValue ;
898
+ break ;
899
+ case PropertyType::DATE :
900
+ $ date = $ valueNode ->nodeValue ;
901
+ if ($ date ) {
902
+ $ date = new \DateTime ($ date );
903
+ $ date ->setTimezone (new \DateTimeZone (date_default_timezone_get ()));
904
+ // Jackalope expects a string, might make sense to refactor to allow \DateTime instances too
905
+ $ date = $ valueConverter ->convertType ($ date , PropertyType::STRING );
906
+ }
907
+ $ values [] = $ date ;
908
+ break ;
909
+ case PropertyType::DOUBLE :
910
+ $ values [] = (double ) $ valueNode ->nodeValue ;
911
+ break ;
912
+ default :
913
+ throw new \InvalidArgumentException ("Type with constant $ type not found. " );
914
+ }
915
+ }
854
916
855
- $ values = array ();
856
- $ type = PropertyType::valueFromName ($ propertyNode ->getAttribute ('sv:type ' ));
857
- foreach ($ propertyNode ->childNodes as $ valueNode ) {
858
917
switch ($ type ) {
859
- case PropertyType::NAME :
860
- case PropertyType::URI :
861
- case PropertyType::WEAKREFERENCE :
862
- case PropertyType::REFERENCE :
863
- case PropertyType::PATH :
864
- case PropertyType::DECIMAL :
865
- case PropertyType::STRING :
866
- $ values [] = $ valueNode ->nodeValue ;
867
- break ;
868
- case PropertyType::BOOLEAN :
869
- $ values [] = (bool ) $ valueNode ->nodeValue ;
870
- break ;
871
- case PropertyType::LONG :
872
- $ values [] = (int ) $ valueNode ->nodeValue ;
873
- break ;
874
918
case PropertyType::BINARY :
875
- $ values [] = (int ) $ valueNode ->nodeValue ;
876
- break ;
877
- case PropertyType::DATE :
878
- $ date = $ valueNode ->nodeValue ;
879
- if ($ date ) {
880
- $ date = new \DateTime ($ date );
881
- $ date ->setTimezone (new \DateTimeZone (date_default_timezone_get ()));
882
- // Jackalope expects a string, might make sense to refactor to allow \DateTime instances too
883
- $ date = $ valueConverter ->convertType ($ date , PropertyType::STRING );
884
- }
885
- $ values [] = $ date ;
886
- break ;
887
- case PropertyType::DOUBLE :
888
- $ values [] = (double ) $ valueNode ->nodeValue ;
919
+ $ data ->{': ' . $ name } = $ propertyNode ->getAttribute ('sv:multi-valued ' ) ? $ values : $ values [0 ];
889
920
break ;
890
921
default :
891
- throw new \InvalidArgumentException ("Type with constant $ type not found. " );
922
+ $ data ->{$ name } = $ propertyNode ->getAttribute ('sv:multi-valued ' ) ? $ values : $ values [0 ];
923
+ $ data ->{': ' . $ name } = $ type ;
924
+ break ;
892
925
}
893
926
}
894
-
895
- switch ($ type ) {
896
- case PropertyType::BINARY :
897
- $ data ->{': ' . $ name } = $ propertyNode ->getAttribute ('sv:multi-valued ' ) ? $ values : $ values [0 ];
898
- break ;
899
- default :
900
- $ data ->{$ name } = $ propertyNode ->getAttribute ('sv:multi-valued ' ) ? $ values : $ values [0 ];
901
- $ data ->{': ' . $ name } = $ type ;
902
- break ;
903
- }
904
927
}
905
928
906
929
return $ data ;
@@ -912,7 +935,11 @@ public static function xmlToProps($xml, ValueConverter $valueConverter, $filter
912
935
* @param array $properties
913
936
* @param boolean $inlineBinaries
914
937
*
915
- * @return array ('dom' => $dom, 'binaryData' => streams, 'references' => array('type' => INT, 'values' => array(UUIDs)))
938
+ * @return array (
939
+ * 'stringDom' => $stringDom,
940
+ * 'integerDom' => $integerDom',
941
+ * 'binaryData' => streams,
942
+ * 'references' => array('type' => INT, 'values' => array(UUIDs)))
916
943
*/
917
944
private function propsToXML ($ properties , $ inlineBinaries = false )
918
945
{
@@ -925,20 +952,17 @@ private function propsToXML($properties, $inlineBinaries = false)
925
952
'rep ' => "internal " ,
926
953
);
927
954
928
- $ dom = new \DOMDocument ('1.0 ' , 'UTF-8 ' );
929
- $ rootNode = $ dom ->createElement ('sv:node ' );
930
- foreach ($ namespaces as $ namespace => $ uri ) {
931
- $ rootNode ->setAttribute ('xmlns: ' . $ namespace , $ uri );
932
- }
933
- $ dom ->appendChild ($ rootNode );
955
+ $ propertyMap = array (
956
+ 'longDom ' => array (),
957
+ 'stringDom ' => array (),
958
+ 'decimalDom ' => array (),
959
+ );
934
960
935
961
$ binaryData = $ references = array ();
962
+
936
963
foreach ($ properties as $ property ) {
937
- /* @var $property Property */
938
- $ propertyNode = $ dom ->createElement ('sv:property ' );
939
- $ propertyNode ->setAttribute ('sv:name ' , $ property ->getName ());
940
- $ propertyNode ->setAttribute ('sv:type ' , PropertyType::nameFromValue ($ property ->getType ()));
941
- $ propertyNode ->setAttribute ('sv:multi-valued ' , $ property ->isMultiple () ? '1 ' : '0 ' );
964
+
965
+ $ column = 'stringDom ' ;
942
966
943
967
switch ($ property ->getType ()) {
944
968
case PropertyType::WEAKREFERENCE :
@@ -955,12 +979,14 @@ private function propsToXML($properties, $inlineBinaries = false)
955
979
break ;
956
980
case PropertyType::DECIMAL :
957
981
$ values = $ property ->getDecimal ();
982
+ $ column = 'decimalDom ' ;
958
983
break ;
959
984
case PropertyType::BOOLEAN :
960
985
$ values = array_map ('intval ' , (array ) $ property ->getBoolean ());
961
986
break ;
962
987
case PropertyType::LONG :
963
988
$ values = $ property ->getLong ();
989
+ $ column = 'longDom ' ;
964
990
break ;
965
991
case PropertyType::BINARY :
966
992
if ($ property ->isNew () || $ property ->isModified ()) {
@@ -998,26 +1024,65 @@ private function propsToXML($properties, $inlineBinaries = false)
998
1024
break ;
999
1025
case PropertyType::DOUBLE :
1000
1026
$ values = $ property ->getDouble ();
1027
+ $ column = 'decimalDom ' ;
1001
1028
break ;
1002
1029
default :
1003
1030
throw new RepositoryException ('unknown type ' .$ property ->getType ());
1004
1031
}
1005
1032
1006
- $ lengths = (array ) $ property ->getLength ();
1007
- foreach ((array ) $ values as $ key => $ value ) {
1008
- $ element = $ propertyNode ->appendChild ($ dom ->createElement ('sv:value ' ));
1009
- $ element ->appendChild ($ dom ->createTextNode ($ value ));
1010
- if (isset ($ lengths [$ key ])) {
1011
- $ lengthAttribute = $ dom ->createAttribute ('length ' );
1012
- $ lengthAttribute ->value = $ lengths [$ key ];
1013
- $ element ->appendChild ($ lengthAttribute );
1033
+ $ propertyMap [$ column ][] = array (
1034
+ 'name ' => $ property ->getName (),
1035
+ 'type ' => PropertyType::nameFromValue ($ property ->getType ()),
1036
+ 'multiple ' => $ property ->isMultiple (),
1037
+ 'lengths ' => (array ) $ property ->getLength (),
1038
+ 'values ' => $ values ,
1039
+ );
1040
+ }
1041
+
1042
+ $ ret = array (
1043
+ 'stringDom ' => null ,
1044
+ 'longDom ' => null ,
1045
+ 'decimalDom ' => null ,
1046
+ 'binaryData ' => $ binaryData ,
1047
+ 'references ' => $ references
1048
+ );
1049
+
1050
+ foreach ($ propertyMap as $ column => $ properties ) {
1051
+
1052
+ $ dom = new \DOMDocument ('1.0 ' , 'UTF-8 ' );
1053
+ $ rootNode = $ dom ->createElement ('sv:node ' );
1054
+ foreach ($ namespaces as $ namespace => $ uri ) {
1055
+ $ rootNode ->setAttribute ('xmlns: ' . $ namespace , $ uri );
1056
+ }
1057
+ $ dom ->appendChild ($ rootNode );
1058
+
1059
+ foreach ($ properties as $ property ) {
1060
+
1061
+ /* @var $property Property */
1062
+ $ propertyNode = $ dom ->createElement ('sv:property ' );
1063
+ $ propertyNode ->setAttribute ('sv:name ' , $ property ['name ' ]);
1064
+ $ propertyNode ->setAttribute ('sv:type ' , $ property ['type ' ]);
1065
+ $ propertyNode ->setAttribute ('sv:multi-valued ' , $ property ['multiple ' ] ? '1 ' : '0 ' );
1066
+ $ lengths = (array ) $ property ['lengths ' ];
1067
+ foreach ((array ) $ values as $ key => $ value ) {
1068
+ $ element = $ propertyNode ->appendChild ($ dom ->createElement ('sv:value ' ));
1069
+ $ element ->appendChild ($ dom ->createTextNode ($ value ));
1070
+ if (isset ($ lengths [$ key ])) {
1071
+ $ lengthAttribute = $ dom ->createAttribute ('length ' );
1072
+ $ lengthAttribute ->value = $ lengths [$ key ];
1073
+ $ element ->appendChild ($ lengthAttribute );
1074
+ }
1014
1075
}
1076
+
1077
+ $ rootNode ->appendChild ($ propertyNode );
1015
1078
}
1016
1079
1017
- $ rootNode ->appendChild ($ propertyNode );
1080
+ if (count ($ properties )) {
1081
+ $ ret [$ column ] = $ dom ;
1082
+ }
1018
1083
}
1019
1084
1020
- return array ( ' dom ' => $ dom , ' binaryData ' => $ binaryData , ' references ' => $ references ) ;
1085
+ return $ ret ;
1021
1086
}
1022
1087
1023
1088
/**
@@ -1123,7 +1188,7 @@ private function getNodesData($rows)
1123
1188
1124
1189
foreach ($ rows as $ row ) {
1125
1190
$ this ->nodeIdentifiers [$ row ['path ' ]] = $ row ['identifier ' ];
1126
- $ data [$ row ['path ' ]] = self ::xmlToProps ($ row[ ' props ' ] , $ this ->valueConverter );
1191
+ $ data [$ row ['path ' ]] = self ::xmlToProps ($ row , $ this ->valueConverter );
1127
1192
$ data [$ row ['path ' ]]->{'jcr:primaryType ' } = $ row ['type ' ];
1128
1193
$ paths [] = $ row ['path ' ];
1129
1194
}
@@ -1190,7 +1255,7 @@ public function getNodes($paths)
1190
1255
$ params [':fetchDepth ' ] = $ this ->fetchDepth ;
1191
1256
1192
1257
$ query = '
1193
- SELECT path AS arraykey, id, path, parent, local_name, namespace, workspace_name, identifier, type, props, depth, sort_order
1258
+ SELECT path AS arraykey, id, path, parent, local_name, namespace, workspace_name, identifier, type, props, long_props, decimal_props, depth, sort_order
1194
1259
FROM phpcr_nodes
1195
1260
WHERE workspace_name = :workspace
1196
1261
AND ( ' ;
@@ -1204,7 +1269,7 @@ public function getNodes($paths)
1204
1269
$ i ++;
1205
1270
}
1206
1271
} else {
1207
- $ query = 'SELECT path AS arraykey, id, path, parent, local_name, namespace, workspace_name, identifier, type, props, depth, sort_order
1272
+ $ query = 'SELECT path AS arraykey, id, path, parent, local_name, namespace, workspace_name, identifier, type, props, long_props, decimal_props, depth, sort_order
1208
1273
FROM phpcr_nodes WHERE workspace_name = :workspace AND ( ' ;
1209
1274
1210
1275
$ i = 0 ;
@@ -1278,7 +1343,7 @@ public function getNodesByIdentifier($identifiers)
1278
1343
return array ();
1279
1344
}
1280
1345
1281
- $ query = 'SELECT id, path, parent, local_name, namespace, workspace_name, identifier, type, props, depth, sort_order
1346
+ $ query = 'SELECT id, path, parent, local_name, namespace, workspace_name, identifier, type, props, long_props, decimal_props, depth, sort_order
1282
1347
FROM phpcr_nodes WHERE workspace_name = ? AND identifier IN (?) ' ;
1283
1348
if ($ this ->conn ->getDatabasePlatform () instanceof SqlitePlatform) {
1284
1349
$ all = array ();
@@ -2178,6 +2243,7 @@ public function query(Query $query)
2178
2243
2179
2244
$ primarySource = reset ($ selectors );
2180
2245
$ primaryType = $ primarySource ->getSelectorName () ?: $ primarySource ->getNodeTypeName ();
2246
+ error_log ($ sql );
2181
2247
$ data = $ this ->conn ->fetchAll ($ sql , array ($ this ->workspaceName ));
2182
2248
2183
2249
$ results = $ properties = $ standardColumns = array ();
@@ -2202,7 +2268,11 @@ public function query(Query $query)
2202
2268
2203
2269
if (isset ($ row [$ columnPrefix . 'props ' ])) {
2204
2270
$ properties [$ selectorName ] = (array ) static ::xmlToProps (
2205
- $ row [$ columnPrefix . 'props ' ],
2271
+ array (
2272
+ 'props ' => $ row [$ columnPrefix . 'props ' ],
2273
+ 'decimal_props ' => $ row [$ columnPrefix . 'decimal_props ' ],
2274
+ 'long_props ' => $ row [$ columnPrefix . 'long_props ' ],
2275
+ ),
2206
2276
$ this ->valueConverter
2207
2277
);
2208
2278
} else {
@@ -2223,6 +2293,11 @@ public function query(Query $query)
2223
2293
$ columnName = $ column ->getPropertyName ();
2224
2294
$ columnPrefix = isset ($ selectorAliases [$ selectorName ]) ? $ selectorAliases [$ selectorName ] . '_ ' : $ selectorAliases ['' ] . '_ ' ;
2225
2295
2296
+ // do not overwrite jcr:path and jcr:score
2297
+ if (in_array ($ columnName , array ('jcr:path ' , 'jcr:score ' ))) {
2298
+ continue ;
2299
+ }
2300
+
2226
2301
$ dcrValue = 'jcr:uuid ' === $ columnName
2227
2302
? $ row [$ columnPrefix . 'identifier ' ]
2228
2303
: (isset ($ properties [$ selectorName ][$ columnName ]) ? $ properties [$ selectorName ][$ columnName ] : '' )
0 commit comments