Projet

Général

Profil

Paste
Télécharger (6,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / node_export / formats / xml.inc @ 7fe061e8

1
<?php
2

    
3
/**
4
 * @file
5
 * The Node export XML format handler.
6
 *
7
 * Adds XML format to Node export.
8
 */
9

    
10
/**
11
 * Export callback.
12
 */
13
function node_export_xml_export($nodes, $format) {
14
  $xml_code = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
15
  $xml_code .= "<node_export created=\"" . date('r') . "\">\n";
16
  $xml_code .= node_export_xml_encode($nodes);
17
  $xml_code .= "</node_export>";
18
  return $xml_code;
19
}
20

    
21
/**
22
 * Import callback.
23
 */
24
function node_export_xml_import($code_string) {
25
  // Check for "<?xml" at the start.
26
  if (substr(ltrim($code_string), 0, 5) == "<?xml") {
27

    
28
    // Decode the XML.
29
    $xml_class = new NodeExportXmlDecoder();
30
    $result = $xml_class->decode($code_string);
31

    
32
    // Convert the nodes into objects.
33
    if (!isset($result['success'])) {
34
      foreach($result as $k => $v) {
35
        $result[$k] = (object)$v;
36
      }
37
    }
38

    
39
    return $result;
40
  }
41
}
42

    
43
/**
44
 * Build XML string recursively.
45
 */
46
function node_export_xml_encode($var, $iteration = 0) {
47
  $xml_code = "";
48
  $tab = '';
49
  for ($i = 0; $i <= $iteration; $i++) {
50
    $tab = $tab . "  ";
51
  }
52
  $iteration++;
53
  foreach ($var as $key => $value) {
54
    $attributes = array();
55
    if (is_bool($value)) {
56
      $attributes['type'] = 'boolean';
57
    }
58
    elseif (is_null($value)) {
59
      $attributes['type'] = 'NULL';
60
    }
61
    elseif (is_object($value)) {
62
      if ($iteration == 1 && isset($value->nid) && isset($value->type)) {
63
        // Assume first-level object with a nid and type is a stdClass node.
64
        $key = "node";
65
      }
66
      else {
67
        $attributes['class'] = get_class($value);
68
      }
69
      $value = (array)$value;
70
    }
71
    if (is_array($value) && array_values($value) === $value) {
72
      $attributes['_numeric_keys'] = "1";
73
    }
74
    $attr_string = "";
75
    foreach ($attributes as $attr_name => $attr_value) {
76
      $attr_string .= ' ' . $attr_name . '="' . $attr_value . '"';
77
    }
78

    
79
    if (is_numeric($key)) {
80
      $key = "n" . $key;
81
    }
82
    $xml_code .= $tab . "<" . $key . $attr_string . ">";
83

    
84
    if (is_array($value)) {
85
      if (!empty($value)) {
86
        $xml_code .= "\n";
87
        $xml_code .= node_export_xml_encode($value, $iteration);
88
        if (!is_numeric($key)) {
89
          $xml_code .= $tab;
90
        }
91
      }
92
    }
93
    elseif (is_numeric($value)) {
94
      $xml_code .= $value;
95
    }
96
    elseif (is_bool($value)) {
97
      $xml_code .= ($value ? 'TRUE' : 'FALSE');
98
    }
99
    elseif (is_string($value)) {
100
      $xml_code .= htmlspecialchars($value);
101
    }
102
    $xml_code .= "</" . $key . ">\n";
103
  }
104
  return $xml_code;
105
}
106

    
107
/**
108
 * Class for parsing Node export XML.
109
 */
110
class NodeExportXmlDecoder {
111
  var $stack;
112
  var $output;
113

    
114
  function decode($code_string) {
115
    $parser = xml_parser_create();
116
    xml_set_element_handler($parser, array(&$this, 'start_handler'), array(&$this, 'end_handler'));
117
    xml_set_character_data_handler($parser, array(&$this, 'data_handler'));
118
    $this->stack = array(
119
      array(
120
        'name' => 'node_export',
121
        'attributes' => array(),
122
        'children' => array(),
123
        'data' => '',
124
      )
125
    );
126
    if (!xml_parse($parser, $code_string)) {
127
      $errors[] = "Node export XML import was unsuccessful, error details follow.  No nodes imported.";
128
      $line = xml_get_current_line_number($parser);
129
      $column = xml_get_current_column_number($parser);
130
      $error = xml_error_string(xml_get_error_code($parser));
131
      $errors[] = "Line " . $line . ", Column " . $column .": ". $error;
132
      $lines = explode("\n", $code_string, $line + 1);
133
      $errors[] = "<pre>". htmlspecialchars($lines[$line - 1]) ."</pre>";
134
      xml_parser_free($parser);
135
      return array(
136
        'success' => FALSE,
137
        'output' => $errors,
138
      );
139
    }
140
    xml_parser_free($parser);
141

    
142
    $tmp = $this->build($this->stack[0]);
143
    if (count($tmp) == 1) {
144
      $this->output = array_pop($tmp);
145
    }
146
    else {
147
      $this->output = array();
148
    }
149
    unset($this->stack);
150
    return $this->output;
151
  }
152

    
153
  function build($stack) {
154
    $result = array();
155

    
156
    if (count($stack['children']) > 0) {
157
      $keycount = array();
158
      foreach ($stack['children'] as $child) {
159
        $keycount[] = $child['name'];
160
      }
161
      if (count(array_unique($keycount)) != count($keycount)) {
162
        // Enumerated array.
163
        $children = array();
164
        foreach ($stack['children'] as $child) {
165
          $children[] = $this->build($child);
166
        }
167
      }
168
      else {
169
        // Associative array.
170
        $children = array();
171
        foreach ($stack['children'] as $child) {
172
          if (!empty($stack['attributes']['_NUMERIC_KEYS'])) {
173
            $child['name'] = intval(substr($child['name'], 1));
174
          }
175
          $children[$child['name']] = $this->build($child);
176
        }
177
      }
178
      $result = array_merge($result, $children);
179
    }
180

    
181
    if (count($result) == 0) {
182
      // An atomic value.
183
      $return = trim($stack['data']);
184
      if (isset($stack['attributes']['TYPE'])) {
185
        if ($stack['attributes']['TYPE'] == 'boolean') {
186
          return (trim($stack['data']) == 'TRUE' ? TRUE : FALSE);
187
        }
188
        elseif ($stack['attributes']['TYPE'] == 'NULL') {
189
          return NULL;
190
        }
191
      }
192
      return htmlspecialchars_decode(trim($stack['data']));
193
    }
194
    else {
195
      // An array or object.
196
      if (isset($stack['attributes']['CLASS'])) {
197
        $object = new $stack['attributes']['CLASS']();
198
        foreach ($result as $k => $v) {
199
          $object->$k = $v;
200
        }
201
        $result = $object;
202
      }
203
      return $result;
204
    }
205
  }
206

    
207
  function start_handler($parser, $name, $attributes = array()) {
208
    $token = array();
209
    $token['name'] = strtolower($name);
210
    $token['attributes'] = $attributes;
211
    $token['data'] = '';
212
    $token['children'] = array();
213
    $this->stack[] = $token;
214
  }
215

    
216
  function end_handler($parser, $name, $attributes = array()) {
217
    $token = array_pop($this->stack);
218
    $this->stack[count($this->stack) - 1]['children'][] = $token;
219
  }
220

    
221
  function data_handler($parser, $data) {
222
    $this->stack[count($this->stack) - 1]['data'] .= $data;
223
  }
224

    
225
}
226

    
227
/**
228
 * Callback for actions.
229
 */
230
function node_export_xml_action_form($context, &$form_state) {
231
  return node_export_action_form($context, $form_state, 'xml');
232
}