array( 'title' => t('Quickbooks'), 'page callback' => 'drupal_get_form', 'page arguments' => array('qb_settings'), 'access arguments' => array('administer quickbooks'), 'file' => 'qb.inc', 'type' => MENU_NORMAL_ITEM, ), ); } function qb_perm() { return array('administer quickbooks'); } function qb_qbxml($elements, $root = array('QBXML')) { $qbxml = $xml = new DOMDocument('1.0'); // Make sure the root is an array so _qb_qbxml_node can process it properly if (!is_array($root)) { $root = array($root => array()); } // Attach the base/common root of the document $start = _qb_qbxml_node($qbxml, key($root), current($root), $xml); // Attach the rest of the document foreach ((array)$elements as $key => $element) { _qb_qbxml_node($qbxml, $key, $element, $start); } return $qbxml->saveXML(); } function _qb_qbxml_node(&$doc, $name, $value, &$parent) { // Store the elements in the order they were added to the doc static $added; if (is_scalar($value)) { $element = $doc->createElement($name, $value); $parent->appendChild($element); } if (is_array($value)) { if (is_numeric(key($value))) { for ($k=0;$v=$value[$k];$k++) { _qb_qbxml_node($doc, $name, $v, $parent); } } else { $element = $doc->createElement($name); foreach ($value as $k => $v) { // Denote attributes as starting with a _ if (is_scalar($v) && strpos($k, '_') === 0) { $k = drupal_substr($k, 1); $attr = $doc->createAttribute($k); $attr->appendChild($doc->createTextNode($v)); $element->appendChild($attr); } // Denote processing instructions with a ? else if (is_scalar($v) && strpos($k, '?') === 0) { $k = drupal_substr($k, 1); $doc->appendChild($doc->createProcessingInstruction($k, $v)); } else { _qb_qbxml_node($doc, $k, $v, $element); } } $added[] = $parent->appendChild($element); } } // Try and return the last added element (first in the array because of recursion) to help have a more complex "root" as specified in qb_qbxml return reset($added); }