-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlibplist.php
More file actions
177 lines (141 loc) · 4.72 KB
/
libplist.php
File metadata and controls
177 lines (141 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
<?php
class Plist {
/**
* Default constructor
* TODO Determine if this is necessary
*/
public function __construct() {
}
/**
* Loads a file from the system and parses it as though it is a plist
*
* @param string $path Path to the file that should be loaded and parsed
* @return array The plist parsed into a native PHP array, or FALSE if the file could not be loaded / parsed.
*/
public function load_file($path = NULL) {
$str_plist = file_get_contents($path);
if ($str_plist !== FALSE) {
return $this->load_string($str_plist);
}
return $str_plist;
}
/**
* Parses a string containing XML plist data
*
* @param string $str_plist String containing XML plist data
* @return array The string parsed into a native PHP array, or FALSE if the string could not be parsed.
*/
public function load_string($str_plist = NULL) {
$pobject = new stdClass();
$pdoc = DOMDocument::loadXML($str_plist);
// Load the root plist element
$roots = $pdoc->getElementsByTagName('plist');
// There can not be more than one plist element in the document
if ($roots->length == 1) {
$root = $roots->item(0);
// Walk over the child nodes until we hit the root dict element
for ($i = 0; $i < $root->childNodes->length; $i++) {
if ($root->childNodes->item($i)->nodeType == XML_ELEMENT_NODE) {
return $this->process_value_element($root->childNodes->item($i));
}
}
}
return FALSE;
}
public function save_file($obj_data, $path) {
file_put_contents($path, $this->save_string(obj_data));
}
public function save_string($obj_data = NULL) {
$imp = new DOMImplementation();
$dtd = $imp->createDocumentType('plist', '-//Apple//DTD PLIST 1.0//EN', 'http://www.apple.com/DTDs/PropertyList-1.0.dtd');
$odoc = $imp->createDocument('', '', $dtd);
$p_root = $odoc->createElement('plist');
$odoc->appendChild($p_root);
if (is_array($obj_data)) {
}
else {
}
return $odoc->saveXML();
}
/**
* Processes a dict[tionary] DOMElement into a PHPObject, will recursively call other processing functions as required
* until the entire dictionary had been converted into a PHPObject.
*
* @param DOMElement $dict_node DOMElement representing the dict element to be processed
* @return stdClass The dictionary as a native PHP object
*/
public function process_dict_element(DOMElement $dict_node) {
/* Every dict element is key-value coded. First there is a <key> element which representing the key for the next element which,
is that key's value. Parsing will occur sequentially traversing the XML structure of the plist until the entire object is parsed
at which point the element which is being built will be returned. */
$arr_dict = array();
$key = NULL;
for ($i = 0; $i < $dict_node->childNodes->length; $i++) {
$child_node = $dict_node->childNodes->item($i);
if ($child_node->nodeType == XML_ELEMENT_NODE) {
if ($child_node->localName == 'key') {
$key = $child_node->textContent;
}
else {
$arr_dict[$key] = $this->process_value_element($child_node);
$key = NULL;
}
}
}
return $arr_dict;
}
/**
* Processes an array element returning it as a native PHP array
*
* @param DOMElement $array_node DOMElement containing an array node requiring processing
* @return array The node in a native PHP format
*/
public function process_array_element(DOMElement $array_node) {
$arr_node = array();
for ($i = 0; $i < $array_node->childNodes->length; $i++) {
$child_node = $array_node->childNodes->item($i);
if ($child_node->nodeType == XML_ELEMENT_NODE) {
$arr_node[] = $this->process_value_element($child_node);
}
}
return $arr_node;
}
/**
* Processes the given element into its appropriate type
*
* @param DOMElement $ele Element containing the value to be processed
* @return mixed The value in its native PHP type
*/
public function process_value_element(DOMElement $ele) {
switch ($ele->localName) {
case 'string':
return (string)$ele->textContent;
break;
case 'integer':
return (int)$ele->textContent;
break;
case 'real':
return (real)$ele->textContent;
break;
case 'true':
return TRUE;
break;
case 'false':
return FALSE;
break;
case 'data':
return bin2hex($ele->textContent);
break;
case 'date':
return date_parse($ele->textContent);
break;
case 'dict':
return $this->process_dict_element($ele);
break;
case 'array':
return $this->process_array_element($ele);
break;
}
}
}
?>