public function getDBVar($Context, $varname, $udata = null) { $url = 'https://workplace.intuit.com/db/' . $this->_dbid; $action = QuickBooks_IPP::API_GETDBVAR; $xml = '<qdbapi> <ticket>' . $Context->ticket() . '</ticket> <apptoken>' . $Context->token() . '</apptoken> <varname>' . QuickBooks_XML::encode($varname) . '</varname>'; if ($udata) { $xml .= '<udata>' . $udata . '</udata>'; } $xml .= ' </qdbapi>'; return $this->_IPP($Context, $url, $action, $xml); }
<Type>Hen</Type> </Animal> <Animal id="3"> <Name>Wasabi</Name> <Type>Hen</Type> <Note>Wasabi & Yamaguchi are in *loooovvvveee*</Note> </Animal> </Animals>'; print "\n"; print 'List of animal names: ' . "\n"; $Parser->load($xml2); $errnum = 0; $errmsg = ''; if ($Parser->validate($errnum, $errmsg)) { $Doc = $Parser->parse($errnum, $errmsg); $Root = $Doc->getRoot(); $List = $Root->getChildAt('Animals'); foreach ($List->children() as $Animal) { $name = $Animal->getChildDataAt('Animal Name'); $note = $Animal->getChildDataAt('Animal Note'); print "\t" . $name . ' (' . $note . ')' . "\n"; } } print "\n"; print 'Error number: ' . $errnum . "\n"; print 'Error message: ' . $errmsg . "\n"; $value = 'Keith & Shannon went to the store!'; print "\n"; print 'Double encoded: ' . QuickBooks_XML::encode(QuickBooks_XML::encode($value)) . "\n"; print 'NOT double encoded: ' . QuickBooks_XML::encode(QuickBooks_XML::encode($value, true, false), true, false) . "\n"; print "\n";
/** * Get an IDS object by Name (i.e. get a customer by the QuickBooks Name field) * * @param QuickBooks_IPP_Context $Context * @param integer $realmID * @param string $resource * @param string $xml * @return QuickBooks_IPP_Object */ protected function _findByName($Context, $realmID, $resource, $name, $xml = '') { $IPP = $Context->IPP(); if ($IPP->flavor() == QuickBooks_IPP_IDS::FLAVOR_DESKTOP) { if (!$xml) { $xml = ''; $xml .= '<?xml version="1.0" encoding="UTF-8"?>' . QUICKBOOKS_CRLF; $xml .= '<' . $resource . 'Query xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.intuit.com/sb/cdm/' . $IPP->version() . '">' . QUICKBOOKS_CRLF; $xml .= ' <FirstLastInside>' . QuickBooks_XML::encode($name) . '</FirstLastInside>' . QUICKBOOKS_CRLF; $xml .= '</' . $resource . 'Query>'; } } else { $xml = http_build_query(array('Filter' => 'Name :EQUALS: ' . $name)); } $return = $IPP->IDS($Context, $realmID, $resource, QuickBooks_IPP_IDS::OPTYPE_QUERY, $xml); $this->_setLastRequestResponse($Context->lastRequest(), $Context->lastResponse()); $this->_setLastDebug($Context->lastDebug()); if (count($return)) { return $return[0]; } return null; }
/** * Resursive helper function for converting to XML * * @param QuickBooks_XML_Node $node * @param integer $tabs * @param boolean $empty A constant, one of: QUICKBOOKS_XML_XML_PRESERVE, QUICKBOOKS_XML_XML_DROP, QUICKBOOKS_XML_XML_COMPRESS * @param string $indent * @return string */ public function _asXMLHelper($node, $tabs, $empty, $indent) { $xml = ''; if ($node->childCount()) { $xml .= str_repeat($indent, $tabs) . '<' . $node->name(); foreach ($node->attributes() as $key => $value) { // Make sure double-encode is *off* //$xml .= ' ' . $key . '="' . QuickBooks_XML::encode($value, true, false) . '"'; $xml .= ' ' . $key . '="' . QuickBooks_XML::encode($value) . '"'; } $xml .= '>' . "\n"; foreach ($node->children() as $child) { $xml .= $this->_asXMLHelper($child, $tabs + 1, $empty, $indent); } $xml .= str_repeat($indent, $tabs) . '</' . $node->name() . '>' . "\n"; } else { if ($node->hasAttributes()) { $xml .= str_repeat($indent, $tabs) . '<' . $node->name(); foreach ($node->attributes() as $key => $value) { // Double-encode is *off* //$xml .= ' ' . $key . '="' . QuickBooks_XML::encode($value, true, false) . '"'; $xml .= ' ' . $key . '="' . QuickBooks_XML::encode($value) . '"'; } // Double-encode is *off* //$xml .= '>' . QuickBooks_XML::encode($node->data(), true, false) . '</' . $node->name() . '>' . "\n"; $xml .= '>' . QuickBooks_XML::encode($node->data()) . '</' . $node->name() . '>' . "\n"; } else { if ($node->hasData() or $empty == QUICKBOOKS_XML_XML_PRESERVE) { // Double-encode is *off* //$xml .= str_repeat($indent, $tabs) . '<' . $node->name() . '>' . QuickBooks_XML::encode($node->data(), true, false) . '</' . $node->name() . '>' . "\n"; $xml .= str_repeat($indent, $tabs) . '<' . $node->name() . '>' . QuickBooks_XML::encode($node->data()) . '</' . $node->name() . '>' . "\n"; } else { if ($empty == QUICKBOOKS_XML_XML_COMPRESS) { $xml .= str_repeat($indent, $tabs) . '<' . $node->name() . ' />' . "\n"; } else { if ($empty == QUICKBOOKS_XML_XML_DROP) { // do nothing, drop the empty element } } } } /* $xml .= str_repeat($indent, $tabs) . '<' . $node->name(); foreach ($node->attributes() as $key => $value) { $xml .= ' ' . $key . '="' . htmlentities($value, ENT_QUOTES) . '"'; } if ($node->data()) { $xml .= '>' . htmlentities($node->data()) . '</' . $node->name() . '>' . "\n"; } else if ($compress) { $xml .= ' />' . "\n"; } else { $xml .= '></' . $node->name() . '>' . "\n"; } */ } return $xml; }
/** * 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; }
public function asIDSXML($indent = 0, $parent = null, $optype = null, $flavor = null) { // We're not going to actually change the data, just change a copy of it $data = $this->_data; if (!$parent) { $parent = $this->resource(); } if ($optype == QuickBooks_IPP_IDS::OPTYPE_ADD or $optype == QuickBooks_IPP_IDS::OPTYPE_MOD) { if ($flavor == QuickBooks_IPP_IDS::FLAVOR_ONLINE) { $xml = str_repeat("\t", $indent) . '<' . $this->resource() . ' xmlns="http://www.intuit.com/sb/cdm/v2" xmlns:ns2="http://www.intuit.com/sb/cdm/qbopayroll/v1" xmlns:ns3="http://www.intuit.com/sb/cdm/qbo">' . QUICKBOOKS_CRLF; } else { $xml = str_repeat("\t", $indent) . '<Object xsi:type="' . $this->resource() . '">' . QUICKBOOKS_CRLF; } // Merge in the defaults for this object type $data = array_merge($this->_defaults(), $data); } else { if ($parent == 'CustomField') { $xml = str_repeat("\t", $indent) . '<' . $parent . ' xsi:type="StringTypeCustomField">' . QUICKBOOKS_CRLF; } else { $xml = str_repeat("\t", $indent) . '<' . $parent . '>' . QUICKBOOKS_CRLF; } } // Re-order is correctly $data = $this->_reorder($data); // Go through the data, creating XML out of it foreach ($data as $key => $value) { if (is_object($value)) { // If this causes problems, it can be commented out. It handles only situations where you are ->set(...)ing full objects, which can also be done by ->add(...)ing full objects instead $xml .= $value->asIDSXML($indent + 1, null, null, $flavor); } else { if (is_array($value)) { foreach ($value as $skey => $svalue) { //print('converting array: [' . $key . ' >> ' . $skey . ']'); if (is_object($svalue)) { $xml .= $svalue->asIDSXML($indent + 1, $key, null, $flavor); } else { if (substr($key, -2, 2) == 'Id') { $for_qbxml = false; $tmp = QuickBooks_IPP_IDS::parseIdType($svalue); if ($tmp[0]) { $xml .= str_repeat("\t", $indent + 1) . '<' . $key . ' idDomain="' . $tmp[0] . '">'; } else { $xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>'; } $xml .= QuickBooks_XML::encode($tmp[1], $for_qbxml); $xml .= '</' . $key . '>' . QUICKBOOKS_CRLF; } else { //$for_qbxml = false; // //$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>'; //$xml .= QuickBooks_XML::encode($value, $for_qbxml); //$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF; $xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>' . QuickBooks_XML::encode($svalue, false) . '</' . $key . '>' . QUICKBOOKS_CRLF; } } } } else { if (substr($key, -2, 2) == 'Id') { $for_qbxml = false; $tmp = QuickBooks_IPP_IDS::parseIdType($value); if ($tmp[0]) { $xml .= str_repeat("\t", $indent + 1) . '<' . $key . ' idDomain="' . $tmp[0] . '">'; } else { $xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>'; } $xml .= QuickBooks_XML::encode($tmp[1], $for_qbxml); $xml .= '</' . $key . '>' . QUICKBOOKS_CRLF; } else { $for_qbxml = false; $xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>'; $xml .= QuickBooks_XML::encode($value, $for_qbxml); $xml .= '</' . $key . '>' . QUICKBOOKS_CRLF; } } } } if ($optype == QuickBooks_IPP_IDS::OPTYPE_ADD or $optype == QuickBooks_IPP_IDS::OPTYPE_MOD) { if ($flavor == QuickBooks_IPP_IDS::FLAVOR_ONLINE) { $xml .= str_repeat("\t", $indent) . '</' . $this->resource() . '>' . QUICKBOOKS_CRLF; } else { $xml .= str_repeat("\t", $indent) . '</Object>' . QUICKBOOKS_CRLF; } } else { $xml .= str_repeat("\t", $indent) . '</' . $parent . '>' . QUICKBOOKS_CRLF; } return $xml; }
/** * @deprecated See QuickBooksXML::encode() instead */ public static function htmlspecialchars($string, $quote_style = ENT_COMPAT, $charset = 'ISO-8859-1', $double_encode = true) { /* if (!$charset) { $charset = 'ISO-8859-1'; } if (version_compare(PHP_VERSION, '5.2.3', '>=')) { return htmlspecialchars($string, $quote_style, $charset, $double_encode); } else { $string = htmlspecialchars($string, $quote_style, $charset); $fix = array( '&amp;' => '&', '&quot;' => '"', ); return str_replace(array_keys($fix), array_values($fix), $string); } */ return QuickBooks_XML::encode($str, true, $double_encode); }
/** * * * */ public function voidOrRefund($Transaction, $amount = null, $salestax = null, $comment = null, $force_new_transaction = true) { $this->_setError(QuickBooks_MerchantService::ERROR_OK); $this->_log('voidOrRefund()', QUICKBOOKS_LOG_VERBOSE); if (!$this->isSignedOn()) { $this->signOn(); if ($this->errorNumber()) { return false; } } // Error checking if (!$Transaction instanceof QuickBooks_MerchantService_Transaction) { $this->_setError(QuickBooks_MerchantService::ERROR_PARAM, 'voidOrRefund() expects first parameter to be a Transaction object, got: ' . print_r($Transaction, true)); return false; } if (!is_numeric($amount)) { $this->_setError(QuickBooks_MerchantService::ERROR_PARAM, 'voidOrRefund() expects second parameter to be a float, got: ' . print_r($amount, true)); return false; } $transRequestID = $this->_transRequestID(QuickBooks_MerchantService::TYPE_VOIDORREFUND, $Transaction, $amount, $force_new_transaction); $xml = ''; $xml .= '<?xml version="1.0" encoding="utf-8"?>' . QUICKBOOKS_CRLF; $xml .= '<?qbmsxml version="4.1"?>' . QUICKBOOKS_CRLF; $xml .= '<QBMSXML>' . QUICKBOOKS_CRLF; $xml .= $this->_createSessionXML(); $xml .= ' <QBMSXMLMsgsRq>' . QUICKBOOKS_CRLF; $xml .= ' <CustomerCreditCardTxnVoidOrRefundRq>' . QUICKBOOKS_CRLF; $xml .= ' <TransRequestID>' . $transRequestID . '</TransRequestID>' . QUICKBOOKS_CRLF; $xml .= ' <CreditCardTransID>' . $Transaction->getTransactionID() . '</CreditCardTransID>' . QUICKBOOKS_CRLF; if ((double) $amount) { $xml .= ' <Amount>' . sprintf('%01.2f', (double) $amount) . '</Amount>' . QUICKBOOKS_CRLF; } if (!is_null($salestax) and (double) $salestax) { $xml .= ' <SalesTaxAmount>' . sprintf('%01.2f', (double) $salestax) . '</SalesTaxAmount>' . QUICKBOOKS_CRLF; } //<BatchID >STRTYPE</BatchID> <!-- optional --> if ($comment) { $xml .= ' <Comment>' . substr(QuickBooks_XML::encode($comment), 0, 500) . '</Comment>' . QUICKBOOKS_CRLF; } $xml .= ' </CustomerCreditCardTxnVoidOrRefundRq>' . QUICKBOOKS_CRLF; $xml .= ' </QBMSXMLMsgsRq>' . QUICKBOOKS_CRLF; $xml .= '</QBMSXML>' . QUICKBOOKS_CRLF; return $this->_doQBMS(QuickBooks_MerchantService::TYPE_VOIDORREFUND, 'QBMSXML/QBMSXMLMsgsRs/CustomerCreditCardTxnVoidOrRefundRs', $xml); }