You are here

function cc::xml_to_array in Constant Contact 6.2

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

* This method will convert 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 1390

Class

cc
@file

Code

function xml_to_array($contents, $get_attributes = 1, $priority = 'tag') {
  if (!$contents) {
    return array();
  }
  if (!function_exists('xml_parser_create')) {
    $this->last_error = 'XML not supported';
    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)) {
    exit("Failed to create an instance of PHP's XML parser. " . "http://www.php.net/manual/en/ref.xml.php");
  }
  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;

  //Refference

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

  //Multiple tags with same name will be turned into an array
  foreach ($xml_values as $data) {
    unset($attributes, $value);

    //Remove existing values, or there will be trouble

    //This command will extract these variables into the foreach scope

    // tag(string), type(string), level(int), attributes(array).
    extract($data);

    //We could use the array by itself, but this cooler.
    $result = array();
    $attributes_data = array();
    if (isset($value)) {
      if ($priority == 'tag') {
        $result = $value;
      }
      else {
        $result['value'] = $value;
      }

      //Put the value in a assoc array if we are in the 'Attribute' mode
    }

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

        //Set all the attributes in a array called 'attr'
      }
    }

    //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;
}