2013-11-24, 04:09:58
Hello guys.
Lately I've been working on a project where I had to write, save, edit, etc multiple items in xml files and found that there was not much possibilities to do this in the base GetSimple so I made a few new functions to handle the data and thought to share it if anyone needs also to get your suggestions how it could be improved.
First "issue" was with GetSimple getXML() since its always setting node cdata as text when you add or edit an item in the xml all the other cdata (except the one you add/edit) becomes simple text and this raised some problems for me.
So heres my modified code for that:
Note: The $file variable is the file you want to save in (Same like in GetSimple. ex: GSDATAOTHERPATH.'myfile.xml').
The $nocdata variable by default is true (to act the same way as the original function) but later if editing a file or adding a new element then it must be false so all the other/existing data is written back as it was, without changing cdata into text.
Then I needed a function to save the xml based on the passed variables, an identifier for each item and with another node for sorting.
Here is the code i came up with:
Note: The $file variable is the file you want to save in (ex: /absolute/path/to/your/file.xml).
The $values variable must be an array containing all the elements you want to add as keys and their values (ex: array('title'=>'This is the title','content'=>'This is the content')).
The $slug variable I use to redirect the user to a page if the xml was saved successfully.
Then I needed a function to edit/save the data.
Here is what i came up with:
Note: The $file variable same like in the function above.
The $values variable same like in the function above except that it needs an extra key/value, the identifier of the element you want to edit (ex: array('id'=>'1','title'=>'This is the title','content'=>'This is the content')).
The $keep variable is optional. If the variable is passed then it must be an array containing the elements of which you want to keep the old values (ex: array('content') -> this way all the other passed $values will be updated except the 'content').
The $slug variable same like in the function above.
After this i needed a function to delete data.
Note: The $file variable same like in the function above.
The $values variable is different from the other functions. Here it must be an array containing only the identifier of the element you want to delete (ex: array('id'=>'1')).
The $slug variable same like in the function above.
And then for editing the 'sort' I made different things.
First is to edit only the sort element of the data.
Note: The $file variable same like in the function above.
The $values variable is different from the other functions. Here it must be an array containing only the identifier of the element and the new sort value (ex: array('id'=>'1','sort'=>'8')).
The $slug variable same like in the function above.
And here the last one that I use often when working with xml files:
Note: The $object variable must be an object.
So if you guys have any suggestions on how this code could be improved, extended or if you think its totally useless please let me know by leaving a post.
Lately I've been working on a project where I had to write, save, edit, etc multiple items in xml files and found that there was not much possibilities to do this in the base GetSimple so I made a few new functions to handle the data and thought to share it if anyone needs also to get your suggestions how it could be improved.
First "issue" was with GetSimple getXML() since its always setting node cdata as text when you add or edit an item in the xml all the other cdata (except the one you add/edit) becomes simple text and this raised some problems for me.
So heres my modified code for that:
Note: The $file variable is the file you want to save in (Same like in GetSimple. ex: GSDATAOTHERPATH.'myfile.xml').
The $nocdata variable by default is true (to act the same way as the original function) but later if editing a file or adding a new element then it must be false so all the other/existing data is written back as it was, without changing cdata into text.
PHP Code:
function custom_getXML($file, $nocdata = true) {
$xml = @file_get_contents($file);
if ($xml) {
if ($nocdata) {
$data = simplexml_load_string($xml, 'SimpleXMLExtended', LIBXML_NOCDATA);
} else {
$data = simplexml_load_string($xml, 'SimpleXMLExtended');
}
return $data;
}
}
Then I needed a function to save the xml based on the passed variables, an identifier for each item and with another node for sorting.
Here is the code i came up with:
Note: The $file variable is the file you want to save in (ex: /absolute/path/to/your/file.xml).
The $values variable must be an array containing all the elements you want to add as keys and their values (ex: array('title'=>'This is the title','content'=>'This is the content')).
The $slug variable I use to redirect the user to a page if the xml was saved successfully.
PHP Code:
function custom_save_xml($file,$values,$slug) {
if (!file_exists($file)) {
$xml = new SimpleXMLExtended('<items></items>');
$item = $xml->addChild('item');
$item->addAttribute('id','1');
foreach ($values as $key => $value) {
$base = $item->addChild($key);
$base->addCData($value);
}
$item->addChild('sort','1');
} else {
$max_id = array();
$max_sort = array();
$xml = custom_getXML($file,false);
foreach ($xml->item as $item) {
$max_id[] = (int)$item['id'];
$max_sort[] = (int)$item->sort;
}
$id = max($max_id)+1;
$sort_id = max($max_sort)+1;
$item = $xml->addChild('item');
$item->addAttribute('id',$id);
foreach ($values as $key => $value) {
$base = $item->addChild($key);
$base->addCData($value);
}
$item->addChild('sort',$sort_id);
}
if (!XMLsave($xml, $file)) {
//redirect user to error page
} else {
//redirect user to $slug
}
}
Then I needed a function to edit/save the data.
Here is what i came up with:
Note: The $file variable same like in the function above.
The $values variable same like in the function above except that it needs an extra key/value, the identifier of the element you want to edit (ex: array('id'=>'1','title'=>'This is the title','content'=>'This is the content')).
The $keep variable is optional. If the variable is passed then it must be an array containing the elements of which you want to keep the old values (ex: array('content') -> this way all the other passed $values will be updated except the 'content').
The $slug variable same like in the function above.
PHP Code:
function custom_save_edit_xml($file,$values,$slug,$keep=null) {
if (!file_exists($file)) {
//redirect user to error page
} else {
$xml = custom_getXML($file,false);
foreach($xml->item as $item) {
if($item['id'] == $values['id']) {
$old = array();
$old_data = array();
if (!is_null($keep) && is_array($keep)) {
foreach ($keep as $stuff) {
$old[] = $stuff;
}
if (count($old)>0) {
foreach ($old as $other) {
$old_data[$other] = (string)$item->$stuff;
}
}
}
$oldsort = $item->sort;
$dom=dom_import_simplexml($item);
$dom->parentNode->removeChild($dom);
$newitem = $xml->addChild('item');
$newitem->addAttribute('id',$values['id']);
unset($values['id']);
foreach ($values as $key => $value) {
$base = $newitem->addChild($key);
$base->addCData($value);
}
if (count($old_data)>0) {
foreach ($old_data as $id=>$data) {
$extra = $newitem->addChild($id);
$extra->addCData($data);
}
}
$newitem->addChild('sort',$oldsort);
}
}
}
if (!XMLsave($xml, $file)) {
//redirect user to error page
} else {
//redirect user to $slug
}
}
After this i needed a function to delete data.
Note: The $file variable same like in the function above.
The $values variable is different from the other functions. Here it must be an array containing only the identifier of the element you want to delete (ex: array('id'=>'1')).
The $slug variable same like in the function above.
PHP Code:
function custom_delete_xml($file,$values,$slug) {
if (!file_exists($file)) {
//redirect user to error page
} else {
$xml = custom_getXML($file);
foreach($xml->item as $item) {
if($item['id'] == $values['id']) {
$dom=dom_import_simplexml($item);
$dom->parentNode->removeChild($dom);
}
}
}
if (!XMLsave($xml, $file)) {
//redirect user to error page
} else {
//redirect user to $slug
}
}
And then for editing the 'sort' I made different things.
First is to edit only the sort element of the data.
Note: The $file variable same like in the function above.
The $values variable is different from the other functions. Here it must be an array containing only the identifier of the element and the new sort value (ex: array('id'=>'1','sort'=>'8')).
The $slug variable same like in the function above.
PHP Code:
function custom_sort_xml($file,$values,$slug) {
if (!file_exists($file)) {
//redirect user to error page
} else {
$xml = custom_getXML($file,false);
foreach($xml->item as $item) {
if($item['id'] == $values['id']) {
$oldentries = array();
foreach ($item as $key => $value) {
$oldentries[$key] = (string)$value;
}
unset($oldentries['@attributes'],$oldentries['id'],$oldentries['sort']);
$dom=dom_import_simplexml($item);
$dom->parentNode->removeChild($dom);
$item = $xml->addChild('item');
$item->addAttribute('id',$values['id']);
foreach ($oldentries as $key => $value) {
$base = $item->addChild($key);
$base->addCData($value);
}
$item->addChild('sort',$values['sort']);
}
}
}
if (!XMLsave($xml, $file)) {
//redirect user to error page
} else {
//redirect user to $slug
}
}
And here the last one that I use often when working with xml files:
Note: The $object variable must be an object.
PHP Code:
function custom_object_to_array($object) {
$array_object = is_object($object) ? get_object_vars($object) : $object;
$array = array();
foreach ($array_object as $key => $val) {
$val = (is_array($val) || is_object($val)) ? custom_object_to_array($val) : $val;
$array[$key] = $val;
}
return $array;
}
So if you guys have any suggestions on how this code could be improved, extended or if you think its totally useless please let me know by leaving a post.