You are here

function cc::xml_to_array in Constant Contact 7.3

Same name and namespace in other branches
  1. 6.3 class.cc.php \cc::xml_to_array()
  2. 6.2 class.cc.php \cc::xml_to_array()

Converts a string comtaining XML into a nicely formatted PHP array.

@access private

1 call to cc::xml_to_array()
cc::load_url in ./class.cc.php
Loads a specific URL, this method is used by the user friendly methods.

File

./class.cc.php, line 1541
Constant Contact PHP Class

Class

cc
@file Constant Contact PHP Class

Code

function xml_to_array($contents, $get_attributes = 1, $priority = 'tag') {
  if (!$contents) {
    return array();
  }
  if (!function_exists('xml_parser_create')) {
    trigger_error("XML not supported: " . "http://www.php.net/manual/en/ref.xml.php", E_USER_ERROR);
    return array();
  }
  $output_encoding = 'ISO-8859-1';
  $input_encoding = NULL;
  $detect_encoding = TRUE;
  list($parser, $source) = $this
    ->xml_create_parser($contents, $output_encoding, $input_encoding, $detect_encoding);
  if (!is_resource($parser)) {
    trigger_error("Failed to create an instance of PHP's XML parser. " . "http://www.php.net/manual/en/ref.xml.php", E_USER_ERROR);
  }
  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  xml_parse_into_struct($parser, trim($contents), $xml_values);
  xml_parser_free($parser);
  if (!$xml_values) {
    return;
  }

  //Hmm...

  //Initializations.
  $xml_array = array();
  $parents = array();
  $opened_tags = array();
  $arr = array();
  $current =& $xml_array;

  // Go through the tags.
  $repeated_tag_index = array();

  // Multiple tags with same name will be turned into an array.
  foreach ($xml_values as $data) {

    // Remove existing values, or there will be trouble.
    unset($attributes, $value);

    // Extract these variables into the foreach scope
    // tag(string), type(string), level(int), attributes(array).
    extract($data);
    $result = array();
    $attributes_data = array();
    if (isset($value)) {
      if ($priority == 'tag') {
        $result = $value;
      }
      else {

        // Put the value in a assoc array if we are in the 'Attribute' mode
        $result['value'] = $value;
      }
    }

    // Set the attributes too.
    if (isset($attributes) and $get_attributes) {
      foreach ($attributes as $attr => $val) {
        if ($priority == 'tag') {
          $attributes_data[$attr] = $val;
        }
        else {

          // Set all the attributes in an array called 'attr'.
          $result['attr'][$attr] = $val;
        }
      }
    }

    // See tag status and do the needed.
    if ($type == "open") {

      // The starting of the tag '<tag>'
      $parent[$level - 1] =& $current;
      if (!is_array($current) or !in_array($tag, array_keys($current))) {

        //Insert New tag
        $current[$tag] = $result;
        if ($attributes_data) {
          $current[$tag . '_attr'] = $attributes_data;
        }
        $repeated_tag_index[$tag . '_' . $level] = 1;
        $current =& $current[$tag];
      }
      else {

        // There was another element with the same tag name.
        if (isset($current[$tag][0])) {

          //If there is a 0th element it is already an array
          $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
          $repeated_tag_index[$tag . '_' . $level]++;
        }
        else {

          // This section will make the value an array if multiple tags with
          // the same name appear together.
          $current[$tag] = array(
            $current[$tag],
            $result,
          );

          // This will combine the existing item and the new item together to
          // make an array
          $repeated_tag_index[$tag . '_' . $level] = 2;
          if (isset($current[$tag . '_attr'])) {

            // The attribute of the last(0th) tag must be moved as well.
            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
            unset($current[$tag . '_attr']);
          }
        }
        $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
        $current =& $current[$tag][$last_item_index];
      }
    }
    elseif ($type == "complete") {

      //Tags that ends in 1 line '<tag />'

      //See if the key is already taken.
      if (!isset($current[$tag])) {

        //New Key
        $current[$tag] = $result;
        $repeated_tag_index[$tag . '_' . $level] = 1;
        if ($priority == 'tag' and $attributes_data) {
          $current[$tag . '_attr'] = $attributes_data;
        }
      }
      else {

        // If taken, put all things inside a list(array).
        if (isset($current[$tag][0]) and is_array($current[$tag])) {

          // If it is already an array push the new element into that array.
          $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
          if ($priority == 'tag' and $get_attributes and $attributes_data) {
            $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
          }
          $repeated_tag_index[$tag . '_' . $level]++;
        }
        else {

          // If it is not an array.
          $current[$tag] = array(
            $current[$tag],
            $result,
          );

          // Make it an array using using the existing value and the new value.
          $repeated_tag_index[$tag . '_' . $level] = 1;
          if ($priority == 'tag' and $get_attributes) {
            if (isset($current[$tag . '_attr'])) {

              // The attribute of the last(0th) tag must be moved as well.
              $current[$tag]['0_attr'] = $current[$tag . '_attr'];
              unset($current[$tag . '_attr']);
            }
            if ($attributes_data) {
              $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
            }
          }
          $repeated_tag_index[$tag . '_' . $level]++;

          //0 and 1 index is already taken
        }
      }
    }
    elseif ($type == 'close') {

      //End of tag '</tag>'
      $current =& $parent[$level - 1];
    }
  }
  return $xml_array;
}