/** * Return the XML object as an XML string * * @return string */ public function asXML($todo_for_empty_elements = true, $indent = "\t") { return $this->_root->asXML(); }
protected static function _ChildObjectsToXML($type, $action, $children, $parentPath = '') { $Driver = QuickBooks_Driver_Singleton::getInstance(); $nodes = array(); $file = '/QuickBooks/QBXML/Schema/Object/' . QuickBooks_Utilities::actionToRequest($action) . '.php'; $class = 'QuickBooks_QBXML_Schema_Object_' . QuickBooks_Utilities::actionToRequest($action); QuickBooks_Loader::load($file); $schema_object = new $class(); $usePath = ''; if ($parentPath != '') { $usePath .= $parentPath . ' '; } foreach ($children as $child) { // Figure out which LinkedTxn method should be used... if (strpos($child['table'], "linkedtxn") !== false) { if (stripos($action, "add") !== false) { $part = preg_replace("/add/i", "", $action); $part .= "LineAdd"; } else { if (stripos($action, 'mod') !== false) { $part = preg_replace("/mod/i", "", $action); $part .= "LineMod"; } } if ($schema_object->exists($usePath . 'LinkToTxnID')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($action . ' ' . $part . ' ' . 'LinkToTxn')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($usePath . 'LinkedTxn')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($action . ' ' . $part . ' ' . 'LinkedTxn')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($usePath . 'ApplyCheckToTxnAdd')) { $Node = new QuickBooks_XML_Node("ApplyCheckToTxnAdd"); $Node->setChildDataAt($Node->name() . ' ' . 'TxnID', $child['data']->get("ToTxnID")); $Node->setChildDataAt($Node->name() . ' ' . 'Amount', $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($usePath . 'ApplyCheckToTxnMod')) { $Node = new QuickBooks_XML_Node("ApplyCheckToTxnMod"); $Node->setChildDataAt($Node->name() . ' ' . 'TxnID', $child['data']->get("ToTxnID")); $Node->setChildDataAt($Node->name() . ' ' . 'Amount', $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { continue; } } } } } } } else { if (strpos($child['table'], "dataext") !== false) { continue; } } $map = ''; $others = array(); QuickBooks_SQL_Schema::mapToSchema($child['table'] . '.*', QUICKBOOKS_SQL_SCHEMA_MAP_TO_XML, $map, $others); $map = str_replace(' *', '', $map); $explode = explode(' ', $map); $first = trim(current($explode)); $map = trim(implode(' ', array_slice($explode, 1))); if (stripos($action, 'add') !== false) { $map = str_replace('Ret', 'Add', $map); } else { $map = str_replace('Ret', 'Mod', $map); } // Journal entries have an unusual JournalEntryMod syntax. Instead of // the typical CreditLineMod and DebitLineMod entries, they instead // have just a single combined entry, JournalLineMod. if ($action == QUICKBOOKS_MOD_JOURNALENTRY) { if ($child['table'] == 'journalentry_journaldebitline' or $child['table'] == 'journalentry_journalcreditline') { $map = 'JournalLineMod'; } } $Node = new QuickBooks_XML_Node($map); /* $retArr[$index]["table"] = $table; $retArr[$index]["data"] = QuickBooks_SQL_Object($table, null, $arr); $retArr[$index]["children"] */ foreach ($child['data']->asArray() as $field => $value) { $map = ''; $others = array(); QuickBooks_SQL_Schema::mapToSchema($child['table'] . '.' . $field, QUICKBOOKS_SQL_SCHEMA_MAP_TO_XML, $map, $others); if ($Driver->foldsToLower()) { $retpos = strpos($map, 'Ret '); $retval = substr($map, 0, $retpos + 4); $map = substr($map, $retpos + 4); if (stripos($action, 'add') !== false) { $map = str_replace('Ret ', 'Add ', $map); } else { $map = str_replace('Ret ', 'Mod ', $map); } //print('unfolding: {' . $map . '}' . "\n"); $map = $schema_object->unfold($map); //print(' unfolded to: [' . $map . ']' . "\n"); } //print($field . ' => ' . $value . "\n"); //print_r($map); //print("\n\n"); if (!$map or !strlen($value)) { continue; } // OK, the paths look like this: // CustomerRet FirstName // // We don't need the 'CustomerRet' part of it, that's actually incorrect, so we'll strip it off $explode = explode(' ', $map); $first = trim(current($explode)); $map = trim(implode(' ', array_slice($explode, 1))); if (stripos($action, "add") !== false) { $map = str_replace("Ret", "Add", $map); } else { $map = str_replace("Ret", "Mod", $map); } $map = preg_replace("/.*" . $Node->name() . " /", "", $map); /* if (strtolower($Node->name()) == "estimatelinemod" and strpos($map, 'TxnLineID') !== false ) { $value = -1; } */ if (false === strpos($map, ' ')) { if ($schema_object->exists($usePath . $Node->name() . ' ' . $map)) { $use_in_request = true; switch ($schema_object->dataType($usePath . $Node->name() . ' ' . $map)) { case 'AMTTYPE': $value = str_replace(',', '', number_format($value, 2)); break; case 'BOOLTYPE': if ($value == 1) { $value = 'true'; } else { if ($value == 0) { $value = 'false'; } else { $use_in_request = false; } } break; default: break; } if ($use_in_request) { $Child = new QuickBooks_XML_Node($map); $Child->setData($value); $Node->addChild($Child); } } else { // ignore it } } else { // Please see comments about JournalEntries above! if ($action == QUICKBOOKS_MOD_JOURNALENTRY) { $map = str_replace(array('JournalCreditLine ', 'JournalDebitLine '), '', $map); } if ($schema_object->exists($usePath . $Node->name() . ' ' . $map)) { $use_in_request = true; switch ($schema_object->dataType($usePath . $Node->name() . ' ' . $map)) { case 'AMTTYPE': $value = str_replace(',', '', number_format($value, 2)); break; case 'BOOLTYPE': if ($value == 1) { $value = 'true'; } else { if ($value == 0) { $value = 'false'; } else { $use_in_request = false; } } break; default: break; } if ($use_in_request) { $Node->setChildDataAt($Node->name() . ' ' . $map, $value, true); } } } } $tNodes = QuickBooks_Callbacks_SQL_Callbacks::_ChildObjectsToXML(strtolower($child['table']), $action, $child['children'], $usePath . $Node->name()); foreach ($tNodes as $tn) { $Node->addChild($tn); } $nodes[count($nodes)] = $Node; } return $nodes; }
/** * Helper function for converting to an array mapping paths to tag values * * @param QuickBooks_XML_Node $node * @param string $current * @param array $paths * @return void */ protected function _asArrayPathsHelper($node, $current, &$paths) { if ($node->hasChildNodes()) { foreach ($node->children() as $child) { $this->_asArrayPathsHelper($child, $current . ' ' . $node->name(), $paths); } } else { if ($node->hasData()) { $paths[trim($current . ' ' . $node->name())] = $node->data(); } } }
protected static function _ChildObjectsToXML($type, $action, $children, $parentPath = '') { $nodes = array(); $file = 'QuickBooks/QBXML/Schema/Object/' . QuickBooks_Utilities::actionToRequest($action) . '.php'; $class = 'QuickBooks_QBXML_Schema_Object_' . QuickBooks_Utilities::actionToRequest($action); require_once $file; $schema_object = new $class(); $usePath = ''; if ($parentPath != "") { $usePath .= $parentPath . ' '; } foreach ($children as $child) { // Figure out which LinkedTxn method should be used... if (strpos($child['table'], "linkedtxn") !== false) { if (stripos($action, "add") !== false) { $part = preg_replace("/add/i", "", $action); $part .= "LineAdd"; } else { if (stripos($action, "mod") !== false) { $part = preg_replace("/mod/i", "", $action); $part .= "LineMod"; } } if ($schema_object->exists($usePath . 'LinkToTxnID')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($action . ' ' . $part . ' ' . 'LinkToTxn')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($usePath . 'LinkedTxn')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($action . ' ' . $part . ' ' . 'LinkedTxn')) { $Node = new QuickBooks_XML_Node("LinkToTxnID", $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($usePath . 'ApplyCheckToTxnAdd')) { $Node = new QuickBooks_XML_Node("ApplyCheckToTxnAdd"); $Node->setChildDataAt($Node->name() . ' ' . 'TxnID', $child['data']->get("ToTxnID")); $Node->setChildDataAt($Node->name() . ' ' . 'Amount', $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { if ($schema_object->exists($usePath . 'ApplyCheckToTxnMod')) { $Node = new QuickBooks_XML_Node("ApplyCheckToTxnMod"); $Node->setChildDataAt($Node->name() . ' ' . 'TxnID', $child['data']->get("ToTxnID")); $Node->setChildDataAt($Node->name() . ' ' . 'Amount', $child['data']->get("ToTxnID")); $nodes[count($nodes)] = $Node; continue; } else { continue; } } } } } } } else { if (strpos($child['table'], "dataext") !== false) { continue; } } $map = ''; $others = array(); QuickBooks_SQL_Schema::mapToSchema($child['table'] . ".*", QUICKBOOKS_SQL_SCHEMA_MAP_TO_XML, $map, $others); $map = str_replace(" *", "", $map); $explode = explode(' ', $map); $first = trim(current($explode)); $map = trim(implode(' ', array_slice($explode, 1))); if (stripos($action, "add") !== false) { $map = str_replace("Ret", "Add", $map); } else { $map = str_replace("Ret", "Mod", $map); } $Node = new QuickBooks_XML_Node($map); /* $retArr[$index]["table"] = $table; $retArr[$index]["data"] = QuickBooks_SQL_Object($table, null, $arr); $retArr[$index]["children"] */ foreach ($child['data']->asArray() as $field => $value) { $map = ''; $others = array(); QuickBooks_SQL_Schema::mapToSchema($child['table'] . '.' . $field, QUICKBOOKS_SQL_SCHEMA_MAP_TO_XML, $map, $others); /* print($field . ' => ' . $value . "\n"); print_r($map); print("\n\n"); */ if (!$map or !strlen($value)) { continue; } // OK, the paths look like this: // CustomerRet FirstName // // We don't need the 'CustomerRet' part of it, that's actually incorrect, so we'll strip it off $explode = explode(' ', $map); $first = trim(current($explode)); $map = trim(implode(' ', array_slice($explode, 1))); if (stripos($action, "add") !== false) { $map = str_replace("Ret", "Add", $map); } else { $map = str_replace("Ret", "Mod", $map); } $map = preg_replace("/.*" . $Node->name() . " /", "", $map); if (strtolower($Node->name()) == "estimatelinemod" and strpos($map, 'TxnLineID') !== false) { $value = -1; } if (false === strpos($map, ' ')) { if ($schema_object->exists($usePath . $Node->name() . ' ' . $map)) { $use_in_request = true; switch ($schema_object->dataType($usePath . $Node->name() . ' ' . $map)) { case 'AMTTYPE': $value = str_replace(",", "", number_format($value, 2)); break; case 'BOOLTYPE': if ($value == 1) { $value = 'true'; } else { if ($value == 0) { $value = 'false'; } else { $use_in_request = false; } } break; default: break; } if ($use_in_request) { $Child = new QuickBooks_XML_Node($map); $Child->setData($value); $Node->addChild($Child); } } else { //ignore it } } else { if ($schema_object->exists($usePath . $Node->name() . ' ' . $map)) { $use_in_request = true; switch ($schema_object->dataType($usePath . $Node->name() . ' ' . $map)) { case 'AMTTYPE': $value = str_replace(",", "", number_format($value, 2)); break; case 'BOOLTYPE': if ($value == 1) { $value = 'true'; } else { if ($value == 0) { $value = 'false'; } else { $use_in_request = false; } } break; default: break; } if ($use_in_request) { $Node->setChildDataAt($Node->name() . ' ' . $map, $value, true); } } } } $tNodes = QuickBooks_Server_SQL_Callbacks::_ChildObjectsToXML(strtolower($child['table']), $action, $child['children'], $usePath . $Node->name()); foreach ($tNodes as $tn) { $Node->addChild($tn); } $nodes[count($nodes)] = $Node; } return $nodes; }
/** * XML parsing recursive helper function * * @param string $xml * @param QuickBooks_XML_Node $root * @return void */ protected function _parseHelper($xml, &$Root, &$errnum, &$errmsg, $indent = 0) { $errnum = QuickBooks_XML::ERROR_OK; $errmsg = ''; $arr = array(); $xml = trim($xml); if (!strlen($xml)) { return false; } $data = ''; $vstack = array(); $dstack = array(); // Remove comments while (false !== strpos($xml, '<!--')) { $start = strpos($xml, '<!--'); $end = strpos($xml, '-->', $start); if (false !== $start and false !== $end) { $xml = substr($xml, 0, $start) . substr($xml, $end + 3); } else { break; } } $raw = $xml; $current = 0; $last = ''; $i = 0; // Parse while (false !== strpos($xml, '<')) { /* print('now examinging:'); print('--------------'); print($xml); print('-----------'); print("\n\n\n"); */ $opentag_start = strpos($xml, '<'); $opentag_end = strpos($xml, '>'); // CDATA check if (substr($xml, $opentag_start, 3) == '<![') { // Find the end of the CDATA section $cdata_end = strpos($xml, ']]>'); $opentag_start = strpos($xml, '<', $cdata_end + 3); $opentag_end = strpos($xml, '>', $cdata_end + 3); } //print('opentag start/end (' . $opentag_start . ', ' . $opentag_end . ') puts us at: {{' . substr($xml, $opentag_start, $opentag_end - $opentag_start) . '}}' . "\n\n"); $tag_w_attrs = trim(substr($xml, $opentag_start + 1, $opentag_end - $opentag_start - 1)); $tag = ''; $attributes = array(); $this->_extractAttributes($tag_w_attrs, $tag, $attributes); if (substr($tag_w_attrs, 0, 1) == '?') { // ignore } else { if (substr($tag_w_attrs, 0, 1) == '!') { // ignore } else { if (substr($tag_w_attrs, -1, 1) == '/') { // ***DO NOT*** completely ignore, auto-closed because it has no children // Completely ignoring causes some SOAP errors for requests like <serverVersion xmlns="http://developer.intuit.com/" /> //print('TAG: [' . substr($tag_w_attrs, 0, -1 . ']' . "\n"); //print('TWA: [' . $tag . ']' . "\n"); //$tag_w_attrs = substr($tag_w_attrs, 0, -1); //$tag = substr($tag, 0, -1); $tag_w_attrs = rtrim($tag_w_attrs, '/'); $tag = rtrim($tag, '/'); // Shove the item on to the stack array_unshift($vstack, array($tag, $tag_w_attrs, $current + $opentag_end)); array_unshift($dstack, array($tag, $tag_w_attrs, $current + $opentag_end)); $key = key($vstack); $tmp = array_shift($vstack); $pop = $tag; $gnk = $tag_w_attrs; $pos = $current + $opentag_end; // there is no data, so empty data and the length is 0 $length = 0; $data = null; if (count($vstack)) { array_shift($dstack); } else { $dstack[$key] = array($pop, $gnk, $pos, $length, $data); } } else { if (substr($tag_w_attrs, 0, 1) == '/') { // NOTE: If you change the code here, you'll likely have to // change it in the above else () section as well, as that // section handles data-less tags like <serverVersion /> $tag = substr($tag, 1); $key = key($vstack); $tmp = array_shift($vstack); $pop = $tmp[0]; $gnk = $tmp[1]; $pos = $tmp[2]; if ($pop != $tag) { $errnum = QuickBooks_XML::ERROR_MISMATCH; $errmsg = 'Mismatched tags, found: ' . $tag . ', expected: ' . $pop; return false; } $data = substr($raw, $pos, $current + $opentag_start - $pos); // Handle <![CDATA[ ... ]]> sections if (substr($data, 0, 9) == '<![CDATA[') { $cdata_end = strpos($data, ']]>'); // Set the data to the CDATA section... $data = QuickBooks_XML::encode(substr($data, 9, $cdata_end - 9)); // ... and remove the CDATA from the remaining XML string //$current = $current + strlen($data) + 12; } if (count($vstack)) { array_shift($dstack); } else { $dstack[$key] = array($pop, $gnk, $pos, $current + $opentag_start - $pos, $data); } } else { array_unshift($vstack, array($tag, $tag_w_attrs, $current + $opentag_end + 1)); array_unshift($dstack, array($tag, $tag_w_attrs, $current + $opentag_end + 1)); } } } } //print('stacks' . "\n"); //print_r($vstack); //print_r($dstack); $xml = substr($xml, $opentag_end + 1); $current = $current + $opentag_end + 1; } if (strlen($xml)) { $errnum = QuickBooks_XML::ERROR_GARBAGE; $errmsg = 'Found this garbage data at end of stream: ' . $xml; return false; } if (count($vstack)) { $errnum = QuickBooks_XML::ERROR_DANGLING; $errmsg = 'XML stack still contains this after parsing: ' . var_export($vstack, true); return false; } //print_r($dstack); //exit; $dstack = array_reverse($dstack); $last = ''; foreach ($dstack as $node) { $tag = $node[0]; $tag_w_attrs = $node[1]; $start = $node[2]; if (count($node) < 5) { continue; } $length = $node[3]; $payload = $node[4]; $tmp = ''; $attributes = array(); $this->_extractAttributes($tag_w_attrs, $tmp, $attributes); $Node = new QuickBooks_XML_Node($tag); foreach ($attributes as $key => $value) { $value = QuickBooks_XML::decode($value, true); $Node->addAttribute($key, $value); } if (false !== strpos($payload, '<')) { // The tag contains child tags $tmp = $this->_parseHelper($payload, $Node, $errnum, $errmsg, $indent + 1); if (!$tmp) { return false; } } else { // This tag has no child tags contained inside it // Make sure we decode any entities $payload = QuickBooks_XML::decode($payload, true); $Node->setData($payload); } $Root->addChild($Node); $last = $tag; } return $Root; }
/** * Convert a QuickBooks_XML_Node object to a QuickBooks_Object_* object instance * * @param QuickBooks_XML_Node $XML * @param string $action_or_object * @return QuickBooks_Object */ public static function fromXML($XML, $action_or_object = null) { if (!$action_or_object or $action_or_object == QUICKBOOKS_QUERY_ITEM) { $action_or_object = $XML->name(); } $type = QuickBooks_Utilities::actionToObject($action_or_object); $exceptions = array(QUICKBOOKS_OBJECT_SERVICEITEM => 'ServiceItem', QUICKBOOKS_OBJECT_INVENTORYITEM => 'InventoryItem', QUICKBOOKS_OBJECT_NONINVENTORYITEM => 'NonInventoryItem', QUICKBOOKS_OBJECT_DISCOUNTITEM => 'DiscountItem', QUICKBOOKS_OBJECT_FIXEDASSETITEM => 'FixedAssetItem', QUICKBOOKS_OBJECT_GROUPITEM => 'GroupItem', QUICKBOOKS_OBJECT_OTHERCHARGEITEM => 'OtherChargeItem', QUICKBOOKS_OBJECT_SALESTAXITEM => 'SalesTaxItem', QUICKBOOKS_OBJECT_SALESTAXGROUPITEM => 'SalesTaxGroupItem', QUICKBOOKS_OBJECT_SUBTOTALITEM => 'SubtotalItem', QUICKBOOKS_OBJECT_INVENTORYASSEMBLYITEM => 'InventoryAssemblyItem'); if (isset($exceptions[$type])) { $type = $exceptions[$type]; } //print('trying to create type: {' . $type . '}' . "\n"); $class = 'QuickBooks_QBXML_Object_' . ucfirst(strtolower($type)); if (true) { $Object = QuickBooks_QBXML_Object::_fromXMLHelper($class, $XML); if (!is_object($Object)) { return false; } $children = array(); switch ($Object->object()) { case QUICKBOOKS_OBJECT_RECEIVEPAYMENT: $children = array('AppliedToTxnRet' => array('QuickBooks_QBXML_Object_ReceivePayment_AppliedToTxn', 'addAppliedToTxn')); break; case QUICKBOOKS_OBJECT_BILL: $children = array('ItemLineRet' => array('QuickBooks_QBXML_Object_Bill_ItemLine', 'addItemLine'), 'ExpenseLineRet' => array('QuickBooks_QBXML_Object_Bill_ExpenseLine', 'addExpenseLine')); break; case QUICKBOOKS_OBJECT_PURCHASEORDER: $children = array('PurchaseOrderLineRet' => array('QuickBooks_QBXML_Object_PurchaseOrder_PurchaseOrderLine', 'addPurchaseOrderLine')); break; case QUICKBOOKS_OBJECT_INVOICE: $children = array('InvoiceLineRet' => array('QuickBooks_QBXML_Object_Invoice_InvoiceLine', 'addInvoiceLine')); break; case QUICKBOOKS_OBJECT_ESTIMATE: $children = array('EstimateLineRet' => array('QuickBooks_QBXML_Object_Estimate_EstimateLine', 'addEstimateLine')); break; case QUICKBOOKS_OBJECT_SALESRECEIPT: $children = array('SalesReceiptLineRet' => array('QuickBooks_QBXML_Object_SalesReceipt_SalesReceiptLine', 'addSalesReceiptLine')); break; case QUICKBOOKS_OBJECT_JOURNALENTRY: $children = array('JournalCreditLineRet' => array('QuickBooks_QBXML_Object_JournalEntry_JournalCreditLine', 'addCreditLine'), 'JournalDebitLineRet' => array('QuickBooks_QBXML_Object_JournalEntry_JournalDebitLine', 'addDebitLine')); break; case QUICKBOOKS_OBJECT_SALESTAXGROUPITEM: $children = array('ItemSalesTaxRef' => array('QuickBooks_QBXML_Object_SalesTaxGroupItem_ItemSalesTaxRef', 'addItemSalesTaxRef')); break; case QUICKBOOKS_OBJECT_UNITOFMEASURESET: $children = array('RelatedUnit' => array('QuickBooks_QBXML_Object_UnitOfMeasureSet_RelatedUnit', 'addRelatedUnit'), 'DefaultUnit' => array('QuickBooks_QBXML_Object_UnitOfMeasureSet_DefaultUnit', 'addDefaultUnit')); break; } foreach ($children as $node => $tmp) { $childclass = $tmp[0]; $childmethod = $tmp[1]; if (class_exists($childclass)) { foreach ($XML->children() as $ChildXML) { if ($ChildXML->name() == $node) { $ChildObject = QuickBooks_QBXML_Object::_fromXMLHelper($childclass, $ChildXML); $Object->{$childmethod}($ChildObject); } } } else { print 'Missing class: ' . $childclass . "\n"; } } return $Object; } return false; }
/** * Transform an XML document into an SQL schema * * @param string $curpath * @param QuickBooks_XML_Node $node * @param array $tables * @return */ protected static function _transform($curpath, $node, &$tables) { //print("\n"); print '' . $curpath . ' node: ' . $node->name() . "\n"; //print(' node: ' . $node->name() . "\n"); //$tables = array(); $table = ''; $field = ''; //QuickBooks_SQL_Schema::mapPathToSQL($node->name(), $table, $field); // table name //print(' table for node: ' . $table . "\n"); //print(' field for node: ' . $field . "\n"); $this_sql = array(); $other_sql = array(); QuickBooks_SQL_Schema::mapToSchema($curpath . ' ' . $node->name(), QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $this_sql, $other_sql); //print('mapping: '); //print_r($this_sql); //print_r($other_sql); //print("\n\n\n"); //print_r($this_sql); foreach (array_merge(array($this_sql), $other_sql) as $sql) { $table = $sql[0]; $field = $sql[1]; if (!$sql[0] or !$sql[1]) { print ' table for node: ' . $sql[0] . "\n"; print ' field for node: ' . $sql[1] . "\n"; } else { print "\n"; } if ($table) { if (!isset($tables[$table])) { //print('trying to map key for: ' . $curpath . ' ' . $name); //$map = null; //QuickBooks_SQL_Schema::mapPrimaryKey($curpath . ' ' . $name, QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $map); //print_r($map); //exit; $tables[$table] = array(0 => $table, 1 => array(), 2 => null, 3 => array(), 4 => array()); } } if ($table and $field) { if (!isset($tables[$table][1][$field])) { $tables[$table][1][$field] = QuickBooks_SQL_Schema::mapFieldToSQLDefinition($table, $field, $node->data()); } } } if ($node->childCount()) { /* $sql = array(); $other_sql = array(); QuickBooks_SQL_Schema::mapToSchema($curpath . ' ' . $node->name(), QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $sql, $other_sql); foreach (array_merge($sql, $other_sql) as $sql) { $table = $sql[0]; $field = $sql[1]; } */ foreach ($node->children() as $child) { QuickBooks_SQL_Schema::_transform($curpath . ' ' . $node->name(), $child, $tables); } } /* print('tables: '); print_r($tables); exit; foreach ($tables as $table) { //print_r($table); exit; } */ }
/** * Convert a QuickBooks_XML_Node object to a QuickBooks_Object_* object instance * * @param QuickBooks_XML_Node $XML * @param string $action_or_object * @return QuickBooks_Object */ public static function fromXML($XML, $action_or_object = null) { if (!$action_or_object) { $action_or_object = $XML->name(); } $type = QuickBooks_Utilities::actionToObject($action_or_object); $class = 'QuickBooks_Object_' . ucfirst(strtolower($type)); if (class_exists($class)) { $Object = QuickBooks_Object::_fromXMLHelper($class, $XML); $children = array(); switch ($Object->object()) { case QUICKBOOKS_OBJECT_PURCHASEORDER: $children = array('PurchaseOrderLineRet' => array('QuickBooks_Object_PurchaseOrder_PurchaseOrderLine', 'addPurchaseOrderLine')); break; case QUICKBOOKS_OBJECT_INVOICE: $children = array('InvoiceLineRet' => array('QuickBooks_Object_Invoice_InvoiceLine', 'addInvoiceLine')); break; case QUICKBOOKS_OBJECT_ESTIMATE: $children = array('EstimateLineRet' => array('QuickBooks_Object_Estimate_EstimateLine', 'addEstimateLine')); break; case QUICKBOOKS_OBJECT_SALESRECEIPT: $children = array('SalesReceiptLineRet' => array('QuickBooks_Object_SalesReceipt_SalesReceiptLine', 'addSalesReceiptLine')); break; case QUICKBOOKS_OBJECT_JOURNALENTRY: $children = array('JournalCreditLine' => array('QuickBooks_Object_JournalEntry_JournalCreditLine', 'addCreditLine'), 'JournalDebitLine' => array('QuickBooks_Object_JournalEntry_JournalDebitLine', 'addDebitLine')); break; } foreach ($children as $node => $tmp) { $childclass = $tmp[0]; $childmethod = $tmp[1]; if (class_exists($childclass)) { foreach ($XML->children() as $ChildXML) { if ($ChildXML->name() == $node) { $ChildObject = QuickBooks_Object::_fromXMLHelper($childclass, $ChildXML); $Object->{$childmethod}($ChildObject); } } } } return $Object; } return false; }
protected function _parseIDS_v2($xml, $optype, $flavor, $version, &$xml_errnum, &$xml_errmsg, &$err_code, &$err_desc, &$err_db) { // Massage it... *sigh* $xml = $this->_massageQBOXML($xml, $optype); // Parse it $Parser = new QuickBooks_XML_Parser($xml); // Initial to success $xml_errnum = QuickBooks_XML::ERROR_OK; $err_code = QuickBooks_IPP::ERROR_OK; // Try to parse the XML IDS response $errnum = QuickBooks_XML::ERROR_OK; $errmsg = null; if ($Doc = $Parser->parse($errnum, $errmsg)) { $Root = $Doc->getRoot(); $List = current($Root->children()); switch ($optype) { case QuickBooks_IPP_IDS::OPTYPE_REPORT: // Parse a REPORT type response $Report = new QuickBooks_IPP_Object_Report('@todo Make sure we show the title of the report!'); foreach ($List->children() as $Child) { $class = 'QuickBooks_IPP_Object_' . $Child->name(); $Object = new $class(); foreach ($Child->children() as $Data) { $this->_push($Data, $Object); } $method = 'add' . $Child->name(); $Report->{$method}($Object); } return $Report; break; case QuickBooks_IPP_IDS::OPTYPE_QUERY: // Parse a QUERY type response // Parse a QUERY type response case QuickBooks_IPP_IDS::OPTYPE_FINDBYID: //print_r($List); //exit; //print_r($Root); //exit; // Stupid QuickBooks Online... *sigh* if ($optype == QuickBooks_IPP_IDS::OPTYPE_FINDBYID and $flavor == QuickBooks_IPP_IDS::FLAVOR_ONLINE) { $List = new QuickBooks_XML_Node(__CLASS__ . '__line_' . __LINE__); $List->addChild($Root); } //print_r($List); //exit; // Normal parsing of query results $list = array(); foreach ($List->children() as $Child) { $class = 'QuickBooks_IPP_Object_' . $Child->name(); $Object = new $class(); foreach ($Child->children() as $Data) { $this->_push($Data, $Object); } $list[] = $Object; } return $list; break; case QuickBooks_IPP_IDS::OPTYPE_ADD: // Parse an ADD type response // Parse an ADD type response case QuickBooks_IPP_IDS::OPTYPE_MOD: //print("\n\n\n" . 'response was: ' . $List->name() . "\n\n\n"); //print_r('list name [' . $List->name() . ']'); switch ($List->name()) { case 'Id': // This is what QuickBooks Online, IDS v2 does return QuickBooks_IPP_IDS::buildIDType($List->getAttribute('idDomain'), $List->data()); case 'Error': $err_code = $List->getChildDataAt('Error ErrorCode'); $err_desc = $List->getChildDataAt('Error ErrorDesc'); $err_db = $List->getChildDataAt('Error DBErrorCode'); return false; case 'Success': $checks = array('Success PartyRoleRef Id', 'Success PartyRoleRef PartyReferenceId', 'Success ObjectRef Id'); foreach ($checks as $xpath) { $IDNode = $List->getChildAt($xpath); if ($IDNode) { return QuickBooks_IPP_IDS::buildIDType($IDNode->getAttribute('idDomain'), $IDNode->data()); } } $err_code = QuickBooks_IPP::ERROR_INTERNAL; $err_desc = 'Could not locate unique ID in response: ' . $xml; $err_db = ''; return false; default: // This should never happen unless Keith neglected // to implement some part of the IPP/IDS spec $err_code = QuickBooks_IPP::ERROR_INTERNAL; $err_desc = 'The parseIDS() method could not understand node [' . $List->name() . '] in response: ' . $xml; $err_db = null; return false; } break; default: $err_code = QuickBooks_IPP::ERROR_INTERNAL; $err_desc = 'The parseIDS() method could not understand the specified optype: [' . $optype . ']'; $err_db = null; return false; } } else { $xml_errnum = $errnum; $xml_errmsg = $errmsg; return false; } }
/** * Transform an XML document into an SQL schema * * @param string $curpath * @param QuickBooks_XML_Node $node * @param array $tables * @return */ protected static function _transform($curpath, $node, &$tables) { print '' . $curpath . ' node: ' . $node->name() . "\n"; $table = ''; $field = ''; $this_sql = array(); $other_sql = array(); QuickBooks_SQL_Schema::mapToSchema($curpath . ' ' . $node->name(), QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $this_sql, $other_sql); foreach (array_merge(array($this_sql), $other_sql) as $sql) { $table = $sql[0]; $field = $sql[1]; /* if (!$sql[0] or !$sql[1]) { print(' table for node: ' . $sql[0] . "\n"); print(' field for node: ' . $sql[1] . "\n"); } else { print("\n"); } */ if ($table) { if (!isset($tables[$table])) { $tables[$table] = array(0 => $table, 1 => array(), 2 => null, 3 => array(), 4 => array()); } } if ($table and $field) { if (!isset($tables[$table][1][$field])) { $tables[$table][1][$field] = QuickBooks_SQL_Schema::mapFieldToSQLDefinition($table, $field, $node->data()); } } } if ($node->childCount()) { foreach ($node->children() as $child) { QuickBooks_SQL_Schema::_transform($curpath . ' ' . $node->name(), $child, $tables); } } return true; }