Skip to content

Commit 929d5e5

Browse files
fillSchema() can remove specific nodes if $removeUselessNodes is false
Added ability to create several siblings of the same type when filling schemas Updated README.md
1 parent bda44b1 commit 929d5e5

File tree

2 files changed

+170
-8
lines changed

2 files changed

+170
-8
lines changed

README.md

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ Laravel 5 wrapper for Prestashop Web Service Library
66
Installation
77
------------
88

9+
Add these lines to your `composer.json` file at the end of the object:
10+
11+
```javascript
12+
"minimum-stability":"dev",
13+
"prefer-stable":"true"
14+
```
15+
The `"minimum-stability":"dev"` line is needed because the underlying Prestashop Web Service Library is not versioned so you must tell Composer to allow packages still in development.
16+
Adding `"prefer-stable":"true"` will tell Composer to provide stable packages if found over dev ones, this is not compulsory but suggested if you don'thave specific needs for your dependencies.
17+
918
Require this package with composer using the following command:
1019

1120
```shell
@@ -118,7 +127,25 @@ $response=Prestashop::add(['resource'=>'categories','postXml'=>$postXml->asXml()
118127

119128
```
120129

121-
#### Note for language value handling
130+
#### Preserving not filled nodes from removal
131+
132+
The default behaviour for the `fillSchema` method is to remove the nodes that are not filled. If you want to preserve those nodes (typical update situation) put the third parameter as `false`
133+
134+
```php
135+
$putXml=Prestashop::fillSchema($xmlSchema,$data,false);
136+
```
137+
138+
#### Removing specific nodes
139+
140+
When preserving unfilled nodes from removal you may specify some nodes to be removed as the fourth argument (this may be useful when updating a resource with some readonly nodes that would trigger error 400):
141+
142+
```php
143+
$putXml=Prestashop::fillSchema($xmlSchema,$data,false,['manufacturer_name','quantity']);
144+
//manufacturer_name and quantity only will be removed from the XML
145+
```
146+
147+
148+
#### Handling language values
122149

123150
If the node has a language child you may use a simple string for the value if your shop has only one language installed.
124151

@@ -131,7 +158,7 @@ If the node has a language child you may use a simple string for the value if yo
131158
</name>
132159
...
133160
*/
134-
$data= ['name'=>Clothes'];
161+
$data= ['name'=>'Clothes'];
135162
```
136163

137164
If your shops has more than one language installed you may pass the node value as an array where the key is the language ID.
@@ -149,8 +176,85 @@ If your shops has more than one language installed you may pass the node value a
149176
$data= [
150177
'name'=>[
151178
1 => 'Clothes',
152-
2 => 'Abbigliamento
179+
2 => 'Abbigliamento'
153180
]
154181
];
155182
```
156-
_Please note that if you don't provide an array of values keyed by the language ID all language values will have the same value._
183+
_Please note that if you don't provide an array of values keyed by the language ID all language values will have the same value._
184+
185+
#### Handling associations with several siblings
186+
187+
Provided you got a node with several associations like category association for products or similar as from this extract of product schema:
188+
189+
```xml
190+
...
191+
<associations>
192+
<categories>
193+
<category>
194+
<id/>
195+
</category>
196+
</categories>
197+
<product_features>
198+
<product_feature>
199+
<id/>
200+
<id_feature_value/>
201+
</product_feature>
202+
</product_features>
203+
...
204+
```
205+
You can prepare the array data map for the `fillSchema` method in this way:
206+
207+
```php
208+
$data => [
209+
...
210+
'associations' => [
211+
'categories' =>[
212+
[ 'category' => ['id' => 4] ],
213+
[ 'category' => ['id' => 5] ],
214+
[ 'category' => ['id' => 11] ],
215+
],
216+
'product_features' => [
217+
[
218+
'product_feature' => [
219+
'id' => 5,
220+
'id_feature_value' => 94
221+
]
222+
],
223+
[
224+
'product_feature' => [
225+
'id' => 1,
226+
'id_feature_value' => 2
227+
]
228+
]
229+
]
230+
]
231+
]
232+
```
233+
The result will be this as expected:
234+
235+
```xml
236+
...
237+
<associations>
238+
<categories>
239+
<category>
240+
<id>4</id>
241+
</category>
242+
<category>
243+
<id>5</id>
244+
</category>
245+
<category>
246+
<id>11</id>
247+
</category>
248+
</categories>
249+
<product_features>
250+
<product_feature>
251+
<id>5</id>
252+
<id_feature_value>94</id_feature_value>
253+
</product_feature>
254+
<product_feature>
255+
<id>1</id>
256+
<id_feature_value>2</id_feature_value>
257+
</product_feature>
258+
</product_features>
259+
...
260+
```

src/PrestashopWebService.php

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,20 @@ public function getSchema($resource)
2626
* @param SimpleXMLElement $xmlSchema
2727
* @param array $data
2828
* @param bool $removeUselessNodes set true if you want to remove nodes that are not present in the data array
29+
* @param array $removeSpecificNodes If $removeUselessNodes is false you may add here the first level nodes that you want to remove
2930
* @return SimpleXMLElement
3031
*/
31-
public function fillSchema(SimpleXMLElement $xmlSchema, $data, $removeUselessNodes = true)
32+
public function fillSchema(SimpleXMLElement $xmlSchema, $data, $removeUselessNodes = true, $removeSpecificNodes=array())
3233
{
3334
$resource = $xmlSchema->children()->children();
3435
foreach ($data as $key => $value) {
3536
$this->processNode($resource, $key, $value);
3637
}
3738
if ($removeUselessNodes) {
38-
$this->checkForUselessNode($resource, $data);
39+
$this->checkForUselessNodes($resource, $data);
40+
}
41+
else{
42+
$this->removeSpecificNodes($resource,$removeSpecificNodes);
3943
}
4044
return $xmlSchema;
4145
}
@@ -76,7 +80,13 @@ private function fillLanguageNode($node, $data)
7680
*/
7781
private function processNode(SimpleXMLElement $node, $dataKey, $dataValue)
7882
{
79-
if (property_exists($node->$dataKey, 'language')) {
83+
if(is_int($dataKey)){
84+
if($dataKey===0){
85+
$this->emptyNode($node);
86+
}
87+
$this->createNode($node,$dataValue);
88+
}
89+
elseif (property_exists($node->$dataKey, 'language')) {
8090
$this->fillLanguageNode($node->$dataKey, $dataValue);
8191
} elseif (is_array($dataValue)) {
8292
foreach ($dataValue as $key => $value) {
@@ -92,7 +102,7 @@ private function processNode(SimpleXMLElement $node, $dataKey, $dataValue)
92102
* @param SimpleXMLElement $resource
93103
* @param $data
94104
*/
95-
private function checkForUselessNode(SimpleXMLElement $resource, $data)
105+
private function checkForUselessNodes(SimpleXMLElement $resource, $data)
96106
{
97107
$uselessNodes = [];
98108
foreach ($resource as $key => $value) {
@@ -104,4 +114,52 @@ private function checkForUselessNode(SimpleXMLElement $resource, $data)
104114
unset($resource->$key);
105115
}
106116
}
117+
118+
/**
119+
* Remove the given nodes from the resource
120+
* @param $resource
121+
* @param $removeSpecificNodes
122+
*/
123+
private function removeSpecificNodes($resource, $removeSpecificNodes)
124+
{
125+
foreach ($removeSpecificNodes as $node) {
126+
unset($resource->$node);
127+
}
128+
}
129+
130+
/**
131+
* @param SimpleXMLElement $node
132+
* @param array $dataValue
133+
*/
134+
private function createNode(SimpleXMLElement $node, $dataValue)
135+
{
136+
foreach ($dataValue as $key => $value) {
137+
if(is_array($value)){
138+
if(is_int($key)){
139+
$this->createNode($node,$value);
140+
}
141+
else{
142+
$childNode=$node->addChild($key);
143+
$this->createNode($childNode,$value);
144+
}
145+
}
146+
else{
147+
$node->addChild($key,$value);
148+
}
149+
}
150+
}
151+
152+
/**
153+
* @param SimpleXMLElement $node
154+
*/
155+
private function emptyNode(SimpleXMLElement $node)
156+
{
157+
$nodeNames = array();
158+
foreach ($node->children() as $key => $value) {
159+
$nodeNames[]=$key;
160+
}
161+
foreach ($nodeNames as $nodeName) {
162+
unset($node->$nodeName);
163+
}
164+
}
107165
}

0 commit comments

Comments
 (0)