<?php
/**
* Copyright (c) 2008 Jerry Jalava <[email protected]>
* Licensed under the GPLv3 license
* http://www.gnu.org/licenses/gpl.html
*
* Version 1.2
* 08/05/2008:
* - Refactored to work better with more complex structures
* - Objects stay same in two way conversions
*/
class xmlObject {
public $root = 'root';
public $items = array();
}
class xmlObjectItem extends xmlObject
{
public $attributes = array();
}
class xmlObjectSet extends xmlObject
{
public $wrapper_id = 'object';
}
class xmlObjects
{
public static function clean_key($key)
{
return preg_replace('/[^a-z0-9\_]/i', '', $key);
}
public static function toXml(xmlObject $data, $root_name = null, $xml = null)
{
if (ini_get('zend.ze1_compatibility_mode') == 1) {
ini_set('zend.ze1_compatibility_mode', 0);
}
if (is_null($root_name)) {
$root_name = $data->root;
}
$root_name = xmlObjects::clean_key($root_name);
if ($xml == null) {
$xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$root_name/>");
}
if (get_class($data) == 'xmlObjectItem')
{
foreach ($data->items as $key => $value)
{
$key = xmlObjects::clean_key($key);
if (is_array($value))
{
$child = $xml->addChild($key);
if (isset($data->attributes[$key])) {
foreach ($data->attributes[$key] as $ak => $av) {
$child->addAttribute($ak, htmlentities($av));
}
}
xmlObjects::toXml($value, $root_name, $child);
}
else
{
if (get_class($value) == 'xmlObjectItem')
{
continue;
}
if (get_class($value) == 'xmlObjectSet')
{
$wrapper_id = preg_replace('/[^a-z0-9\_]/i', '', $value->wrapper_id);
$xml = $xml->addChild($key);
$object_node = $xml->addChild($wrapper_id);
foreach ($value->items as $item)
{
xmlObjects::toXml($item, '', $object_node);
}
}
else
{
$child = $xml->addChild($key, htmlentities($value));
if (isset($data->attributes[$key])) {
foreach ($data->attributes[$key] as $ak => $av) {
$child->addAttribute($ak, htmlentities($av));
}
}
}
}
}
}
elseif (get_class($data) == 'xmlObjectSet')
{
foreach ($data->items as $object)
{
//print_r($data);
$object_node = $xml->addChild($data->wrapper_id);
xmlObjects::toXml($object, $root_name, $object_node);
}
}
return $xml->asXML();
}
public static function fromXml($xml, &$data=null)
{
if (get_class($xml) != 'SimpleXMLElement') {
$xml = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
}
$root_name = $xml->getName();
$set = new xmlObjectSet();
$set->root = $root_name;
if (count($xml->children()) > 0)
{
$children = $xml->children();
$set->wrapper_id = $children[0]->getName();
foreach ($children as $child)
{
if (count($child->children()) == 0) {
$item = xmlObjects::itemFromXml($xml);
$item->root = $root_name;
return $item;
}
else
{
$set->items[] = xmlObjects::fromXml($child);
}
}
}
return $set;
}
public static function itemFromXml($xml)
{
$childData = array();
$childAttrs = array();
if (count($xml->children()) == 0) {
$childName = $xml->getName();
$childData[$childName] = (string) $xml;
if ($xml->attributes()) {
if (! isset($childAttrs[$childName])) {
$childAttrs[$childName] = array();
}
foreach ($xml->attributes() as $ak => $av) {
$childAttrs[$childName][$ak] = (string) $av;
}
}
}
else
{
foreach ($xml->children() as $child) {
$childName = $child->getName();
if ($child->attributes()) {
if (! isset($childAttrs[$childName])) {
$childAttrs[$childName] = array();
}
foreach ($child->attributes() as $ak => $av) {
$childAttrs[$childName][$ak] = (string) $av;
}
}
if (count($child->children()) == 0) {
$childData[$childName] = (string) $child;
}
else
{
if (! isset($childData[$childName])) {
$childData[$childName] = array();
}
$childData[$childName] = xmlObjects::fromXml($child);
}
}
}
$item = new xmlObjectItem();
$item->items = $childData;
$item->attributes = $childAttrs;
return $item;
}
}
/* Test data */
$single_client = new xmlObjectItem();
$single_client->items = array('id' => 1, 'name' => "Client 1", 'contact_id' => 2, 'team-leader' => null);
$single_client->attributes = array(
'contact_id' => array(
'is_assoc' => true,
'foreign_model' => 'person',
'foreign_key' => 'id'
)
);
$resource = new xmlObjectItem();
$resource->items = array(
'id' => 100,
'name' => "Jerry Jalava",
'person_id' => 1
);
$resource->attributes = array(
'person_id' => array(
'is_assoc' => true,
'foreign_model' => 'person',
'foreign_key' => 'id'
)
);
$resource_set = new xmlObjectSet();
$resource_set->wrapper_id = 'resource';
$resource_set->items[] = $resource;
$projects = array();
for ($i=1; $i <= 1; $i++)
{
$object = new xmlObjectItem();
$object->items = array(
'id' => $i,
'name' => "Project {$i}",
'manager_id' => $i+1,
'resources' => $resource_set
);
$projects[] = $object;
}
$project_set = new xmlObjectSet();
$project_set->wrapper_id = 'project';
$project_set->items = $projects;
$clients = array();
for ($i=1; $i <= 1; $i++)
{
$client = new xmlObjectItem();
$client->items = array(
'id' => $i,
'name' => "Client {$i}",
'contact_id' => $i+1,
'team-leader' => null,
'projects' => $project_set
);
$client->attributes = array(
'contact_id' => array(
'is_assoc' => true,
'foreign_model' => 'person',
'foreign_key' => 'id'
)
);
$clients[] = $client;
}
$client_set = new xmlObjectSet();
$client_set->wrapper_id = 'client';
$client_set->items = $clients;
echo "complex set:\n";
var_dump($client_set);
echo "simple item:\n";
var_dump($single_client);
echo "\n--------toXml---------\n";
$xmlSet_clients = xmlObjects::toXml($client_set, 'clients');
echo "complex:\n";
echo $xmlSet_clients;
echo "\n\n";
$xmlItem_client = xmlObjects::toXml($single_client, 'client');
echo "simple:\n";
echo $xmlItem_client;
echo "\n--------fromXml---------\n";
$client_set = xmlObjects::fromXml($xmlSet_clients);
echo "client_set root: {$client_set->root}\n";
var_dump($client_set);
echo "\n\n";
$single_client = xmlObjects::fromXml($xmlItem_client);
echo "single_client root: {$single_client->root}\n";
var_dump($single_client);
echo "\n--------back toXml---------\n";
$xmlSet_clients2 = xmlObjects::toXml($client_set);
echo "complex:\n";
echo $xmlSet_clients2;
if ($xmlSet_clients == $xmlSet_clients2) {
echo "\n\nVALID SET CONVERSION\n\n";
}
$xmlItem_client2 = xmlObjects::toXml($single_client);
echo "simple:\n";
echo $xmlItem_client2;
if ($xmlItem_client == $xmlItem_client2) {
echo "\n\nVALID ITEM CONVERSION\n\n";
}
?>