QBSDK iterator support in consolibyte - quickbooks

I have to fetch a large amount of data and so I want to use the iterator feature of QBSDK. I wanted to know if consolibyte library has any inherent support for it.

Several of the examples included with the lib use iterators:
https://github.com/consolibyte/quickbooks-php/blob/master/docs/web_connector/example_web_connector_import.php#L321
function _quickbooks_invoice_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
// Iterator support (break the result set into small chunks)
$attr_iteratorID = '';
$attr_iterator = ' iterator="Start" ';
if (empty($extra['iteratorID']))
{
// This is the first request in a new batch
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<InvoiceQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
...

Related

TCPDF how do I create several pdf's without opening a browser

I need to create like 350 pdf's at once. Now the browser opens a window for each pdf. I takes longer to open all the 350 windows than to create the pdf's. How do I create and save the pdf's without opening a browser windows? (In my pdf I use Header, body and footer all with variables)
Now I do a loop on php_page_1 which opens the pdf create file.
$sql = "SELECT id FROM shipping_id WHERE datum BETWEEN $date_range AND acc_id=$acc_id;";
$STH = $dbo->prepare( $sql );
$STH->execute();
$contains_files = 0;
$client_id='';
while ( $row = $STH->fetch( PDO::FETCH_ASSOC ) ) {
$contains_files++;
$link = "vb_print_1_no_screen.php?id=" . $row[ 'id' ] . "&nr=".$contains_files;
echo '<script>window.open("https://' . $website_admin . $link . '");</script>';
}
You can use curl to make the request to the URL instead of opening it directly in the browser or you can just include the file that generates the PDF. Try this code
$sql = "SELECT id FROM shipping_id WHERE datum BETWEEN $date_range AND acc_id=$acc_id;";
$STH = $dbo->prepare( $sql );
$STH->execute();
$contains_files = 0;
$client_id='';
while ( $row = $STH->fetch( PDO::FETCH_ASSOC ) ) {
$contains_files++;
$link = "vb_print_1_no_screen.php?id=" . $row[ 'id' ] . "&nr=".$contains_files;
// echo '<script>window.open("https://' . $website_admin . $link . '");</script>';
// method 1 using curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $website_admin . $link);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
curl_close($ch);
// method 2 include pdf generator script
$_GET['id'] = $row['id'];
$_GET['nr'] = $contains_files;
include "vb_print_1_no_screen.php";
}
Kindly make sure to use just one method.

XPATH - Multiple Url's

The code bellow, can count the number of times that the following words appearing on the URL consultor imobiliario , Consultora Imobil and Consultor Imobil repeats:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once dirname(__FILE__).'/../public_html/include/functions.php';
require_once dirname(__FILE__).'/phpQuery.php';
//header('Content-Type:application/json');
//Decisoes e Solucoes - Consultores
$current_page = 1;
$max_page = 999999999999;
$countTotalConsultores=0;
while($max_page >= $current_page){
$url = "https://decisoesesolucoes.com/agencias/albergaria/consultores?page=";
$url .= $current_page;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$res = curl_exec($ch);
curl_close($ch);
$dom = new DomDocument();
# $dom->loadHTML($res);
$xpath = new DOMXpath($dom);
$tables = $xpath->query("//*[text()[contains(normalize-space(), 'consultor imobiliario') or contains(normalize-space(),'Consultora Imobil') or contains(normalize-space(),'Consultor Imobil')]]");
$count = $tables->length;
$countTotalConsultores = $countTotalConsultores+$count;
echo " Página atual:" .$current_page . "No. of agents " . $countTotalConsultores;
$current_page = $current_page+1;
if ($count < 1){
break;
}
}
How can I add more than one URL for this Words searching count with this code?
I want to search in this following url's:
https://decisoesesolucoes.com/agencias/albergaria/consultores?page=
https://decisoesesolucoes.com/agencias/ABRANTES/consultores?page=
https://decisoesesolucoes.com/agencias/albufeira/consultores?page=
Can anyone help me please?
Thanks
Why don't you loop on those url ?
If you want to count you can use this XPATH query
count(//*[text()[contains(normalize-space(), 'consultor imobiliario') or contains(normalize-space(),'Consultora Imobil') or contains(normalize-space(),'Consultor Imobil')]])

Intuit QuickBooks web connector IteratorID not valid error

I have been trying to integrate a PHP based solution with QuickBooks Enterprise edition. I use QuickBooks PHP Dev Kit (http://consolibyte.com/quickbooks-open-source/) to connect the application to sync multiple modules bidirectionally.
The first module (QuickBooks to VtigerCRM) with multiple records are getting synced perfectly. When I try with my next module, only few records are getting synced and throws a error IteratorID is not valid. Then, I tried sending the params with new IteratorID in XML with no success.
20180821.05:13:03 UTC : QBWebConnector.SOAPWebService.do_receiveResponseXML() : hresult=""
20180821.05:13:03 UTC : QBWebConnector.SOAPWebService.do_receiveResponseXML() : message=""
20180821.05:13:03 UTC : QBWebConnector.SOAPWebService.do_receiveResponseXML() : Received from receiveResponseXML() following parameters:
20180821.05:13:03 UTC : QBWebConnector.SOAPWebService.do_receiveResponseXML() : more="-1">
20180821.05:13:03 UTC : QBWebConnector.SOAPWebService.do_getLastError() : * Calling getLastError() with following parameter:
20180821.05:13:03 UTC : QBWebConnector.SOAPWebService.do_getLastError() : wcTicket="403c7856-d600-c664-5187-3d9e2036c0cc"
20180821.05:13:04 UTC : QBWebConnector.SOAPWebService.do_getLastError() : Received from getLastError() following parameter:
20180821.05:13:04 UTC : QBWebConnector.SOAPWebService.do_getLastError() : errorMsg="3391: The iteratorID "{80c35df0-ae92-43a3-af49-946da1c306fb}" is not valid."
20180821.05:13:04 UTC : QBWebConnector.SOAPWebService.do_getLastError() : Received error from application: 3391: The iteratorID "{80c35df0-ae92-43a3-af49-946da1c306fb}" is not valid.
20180821.05:13:04 UTC : QBWebConnector.CompanyFileLock.Send_CompanyQueryRqXML() : XML dump follows: -
<?xml version="1.0"?><?qbxml version="13.0"?><QBXML><QBXMLMsgsRq onError="stopOnError"><CompanyQueryRq requestID="1"><OwnerID>{90A44FB7-33D9-4815-AC85-AC86A7E7D1EB}</OwnerID></CompanyQueryRq></QBXMLMsgsRq></QBXML>
I have added the code of the Helper.php
<?php
// Support URL
if (!empty($_GET['support']))
{
header('Location: http://www.consolibyte.com/');
exit;
}
// We need to make sure the correct timezone is set, or some PHP installations will complain
if (function_exists('date_default_timezone_set'))
{
// * MAKE SURE YOU SET THIS TO THE CORRECT TIMEZONE! *
// List of valid timezones is here: http://us3.php.net/manual/en/timezones.php
date_default_timezone_set('America/New_York');
}
// Require the framework
require_once 'QuickBooks.php';
require_once('config.inc.php');
global $dbconfig;
$user = 'quickbooks';
$pass = 'password';
define('QB_QUICKBOOKS_CONFIG_LAST', 'last');
define('QB_QUICKBOOKS_CONFIG_CURR', 'curr');
define('QB_QUICKBOOKS_MAX_RETURNED', 1);
define('QB_PRIORITY_PURCHASEORDER', 1);
define('QB_PRIORITY_ITEM', 6);
define('QB_PRIORITY_CUSTOMER', 5);
define('QB_PRIORITY_SALESORDER', 2);
/**
* Request priorities, invoices last...
*/
define('QB_PRIORITY_INVOICE', 3);
define('QB_PRIORITY_ESTIMATE',4);
define('QB_QUICKBOOKS_MAILTO', 'keith#consolibyte.com');
// Map QuickBooks actions to handler functions
$map = array(
QUICKBOOKS_IMPORT_CUSTOMER => array( '_quickbooks_customer_import_request', '_quickbooks_customer_import_response' ),
QUICKBOOKS_IMPORT_ITEM => array( '_quickbooks_item_import_request', '_quickbooks_item_import_response' ),
QUICKBOOKS_IMPORT_ESTIMATE =>array( '_quickbooks_quote_import_request', '_quickbooks_quote_import_response' ),
QUICKBOOKS_IMPORT_SALESORDER => array( '_quickbooks_salesorder_import_request', '_quickbooks_salesorder_import_response' ),
QUICKBOOKS_IMPORT_INVOICE => array( '_quickbooks_invoice_import_request', '_quickbooks_invoice_import_response' ),
QUICKBOOKS_IMPORT_PURCHASEORDER => array( '_quickbooks_purchaseorder_import_request', '_quickbooks_purchaseorder_import_response' ),
);
// Error handlers
$errmap = array(
500 => '_quickbooks_error_e500_notfound', // Catch errors caused by searching for things not present in QuickBooks
1 => '_quickbooks_error_e500_notfound',
'*' => '_quickbooks_error_catchall', // Catch any other errors that might occur
);
// An array of callback hooks
$hooks = array(
QuickBooks_WebConnector_Handlers::HOOK_LOGINSUCCESS => '_quickbooks_hook_loginsuccess', // call this whenever a successful login occurs
);
// Logging level
//$log_level = QUICKBOOKS_LOG_NORMAL;
//$log_level = QUICKBOOKS_LOG_VERBOSE;
//$log_level = QUICKBOOKS_LOG_DEBUG; // Use this level until you're sure everything works!!!
$log_level = QUICKBOOKS_LOG_DEVELOP;
// What SOAP server you're using
//$soapserver = QUICKBOOKS_SOAPSERVER_PHP; // The PHP SOAP extension, see: www.php.net/soap
$soapserver = QUICKBOOKS_SOAPSERVER_BUILTIN; // A pure-PHP SOAP server (no PHP ext/soap extension required, also makes debugging easier)
$soap_options = array( // See http://www.php.net/soap
);
$handler_options = array( // See the comments in the QuickBooks/Server/Handlers.php file
'deny_concurrent_logins' => false,
'deny_reallyfast_logins' => false,
);
$driver_options = array( // See the comments in the QuickBooks/Driver/<YOUR DRIVER HERE>.php file ( i.e. 'Mysql.php', etc. )
);
$callback_options = array(
);
$dsn = $dbconfig['db_type']."://".$dbconfig['db_username'].":".$dbconfig['db_password']."#".$dbconfig['db_server']."/".$dbconfig['db_name'];
//$dsn = 'mysql://root:smackcoders#localhost/vtiger2';
//$dsn = 'mysql://testuser:testpassword#localhost/testdatabase';
define('QB_QUICKBOOKS_DSN', $dsn);
// If we haven't done our one-time initialization yet, do it now!
if (!QuickBooks_Utilities::initialized($dsn))
{
// Create the example tables
$file = dirname(__FILE__) . '/example.sql';
if (file_exists($file))
{
$contents = file_get_contents($file);
foreach (explode(';', $contents) as $sql)
{
if (!trim($sql))
{
continue;
}
mysql_query($sql) or die(trigger_error(mysql_error()));
}
}
else
{
die('Could not locate "./example.sql" to create the demo SQL schema!');
}
// Create the database tables
QuickBooks_Utilities::initialize($dsn);
// Add the default authentication username/password
QuickBooks_Utilities::createUser($dsn, $user, $pass);
}
// Initialize the queue
QuickBooks_WebConnector_Queue_Singleton::initialize($dsn);
// Create a new server and tell it to handle the requests
$Server = new QuickBooks_WebConnector_Server($dsn, $map, $errmap, $hooks, $log_level, $soapserver, QUICKBOOKS_WSDL, $soap_options, $handler_options, $driver_options, $callback_options);
$response = $Server->handle(true, true);
/**
* Login success hook - perform an action when a user logs in via the Web Connector
*
*
*/
function _quickbooks_hook_loginsuccess($requestID, $user, $hook, &$err, $hook_data, $callback_config)
{
// For new users, we need to set up a few things
// Fetch the queue instance
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$date = date('Y-m-d H:i:s');
// Set up the invoice imports
if (!_quickbooks_get_last_run($user, QUICKBOOKS_IMPORT_INVOICE))
{
// And write the initial sync time
_quickbooks_set_last_run($user, QUICKBOOKS_IMPORT_INVOICE, $date);
}
// Do the same for customers
if (!_quickbooks_get_last_run($user, QUICKBOOKS_IMPORT_CUSTOMER))
{
_quickbooks_set_last_run($user, QUICKBOOKS_IMPORT_CUSTOMER, $date);
}
// ... and for sales orders
if (!_quickbooks_get_last_run($user, QUICKBOOKS_IMPORT_SALESORDER))
{
_quickbooks_set_last_run($user, QUICKBOOKS_IMPORT_SALESORDER, $date);
}
// ... and for items
if (!_quickbooks_get_last_run($user, QUICKBOOKS_IMPORT_ITEM))
{
_quickbooks_set_last_run($user, QUICKBOOKS_IMPORT_ITEM, $date);
}
// Make sure the requests get queued up
$Queue->enqueue(QUICKBOOKS_IMPORT_CUSTOMER, 1, QB_PRIORITY_CUSTOMER, null, $user);
$Queue->enqueue(QUICKBOOKS_IMPORT_ITEM, 1, QB_PRIORITY_ITEM, null, $user);
$Queue->enqueue(QUICKBOOKS_IMPORT_ESTIMATE, 1, QB_PRIORITY_ESTIMATE, null, $user);
$Queue->enqueue(QUICKBOOKS_IMPORT_SALESORDER, 1, QB_PRIORITY_SALESORDER, null, $user);
$Queue->enqueue(QUICKBOOKS_IMPORT_INVOICE, 1, QB_PRIORITY_INVOICE, null, $user);
$Queue->enqueue(QUICKBOOKS_IMPORT_PURCHASEORDER, 1, QB_PRIORITY_PURCHASEORDER, null, $user);
}
/**
* Get the last date/time the QuickBooks sync ran
*
* #param string $user The web connector username
* #return string A date/time in this format: "yyyy-mm-dd hh:ii:ss"
*/
function _quickbooks_get_last_run($user, $action)
{
$type = null;
$opts = null;
return QuickBooks_Utilities::configRead(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_LAST . '-' . $action, $type, $opts);
}
function _quickbooks_set_last_run($user, $action, $force = null)
{
$value = date('Y-m-d') . 'T' . date('H:i:s');
if ($force)
{
$value = date('Y-m-d', strtotime($force)) . 'T' . date('H:i:s', strtotime($force));
}
return QuickBooks_Utilities::configWrite(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_LAST . '-' . $action, $value);
}
/**
*
*
*/
function _quickbooks_get_current_run($user, $action)
{
$type = null;
$opts = null;
return QuickBooks_Utilities::configRead(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_CURR . '-' . $action, $type, $opts);
}
/**
*
*
*/
function _quickbooks_set_current_run($user, $action, $force = null)
{
$value = date('Y-m-d') . 'T' . date('H:i:s');
if ($force)
{
$value = date('Y-m-d', strtotime($force)) . 'T' . date('H:i:s', strtotime($force));
}
return QuickBooks_Utilities::configWrite(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_CURR . '-' . $action, $value);
}
/**
* Build a request to import invoices already in QuickBooks into our application
*/
function _quickbooks_invoice_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
// Iterator support (break the result set into small chunks)
$attr_iteratorID = '';
$attr_iterator = ' iterator="Start" ';
if (empty($extra['iteratorID']))
{
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
$extra['iteratorID'] = $saved_iterator_id; // From Table
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<InvoiceQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
<MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
<ModifiedDateRangeFilter>
<FromModifiedDate>' . $last . '</FromModifiedDate>
</ModifiedDateRangeFilter>
<IncludeLineItems>true</IncludeLineItems>
<OwnerID>0</OwnerID>
</InvoiceQueryRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
}
/**
* Handle a response from QuickBooks
*/
function _quickbooks_invoice_import_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_IMPORT_INVOICE, null, QB_PRIORITY_INVOICE, array( 'iteratorID' => $idents['iteratorID'] ), $user);
}else{
return true;
}
// This piece of the response from QuickBooks is now stored in $xml. You
// can process the qbXML response in $xml in any way you like. Save it to
// a file, stuff it in a database, parse it and stuff the records in a
// database, etc. etc. etc.
//
// The following example shows how to use the built-in XML parser to parse
// the response and stuff it into a database.
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/InvoiceQueryRs');
$smackHelper = new Quickbooks_vtigerHelper();
$smackHelper->addInvoice($List->children());
}
return true;
}
/**
* Build a request to import customers already in QuickBooks into our application
*/
function _quickbooks_customer_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
// Iterator support (break the result set into small chunks)
$attr_iteratorID = '';
$attr_iterator = ' iterator="Start" ';
if (empty($extra['iteratorID']))
{
// This is the first request in a new batch
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
$extra['iteratorID'] = $saved_iterator_id; // From Table
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CustomerQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
<MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
<FromModifiedDate>' . $last . '</FromModifiedDate>
<OwnerID>0</OwnerID>
</CustomerQueryRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
}
/**
* Handle a response from QuickBooks
*/
function _quickbooks_customer_import_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_IMPORT_CUSTOMER, null, QB_PRIORITY_CUSTOMER, array( 'iteratorID' => $idents['iteratorID'] ), $user);
}else{
return true;
}
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/CustomerQueryRs');
$smackHelper = new Quickbooks_vtigerHelper();
$smackHelper->addContacts($List->children());
}
return true;
}
function _quickbooks_quote_import_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_IMPORT_ESTIMATE, null, QB_PRIORITY_ESTIMATE, array( 'iteratorID' => $idents['iteratorID'] ), $user);
}else{
return true;
}
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/EstimateQueryRs');
$smackHelper = new Quickbooks_vtigerHelper();
$smackHelper->addQuotes($List->children());
}
return true;
}
function _quickbooks_quote_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
if (empty($extra['iteratorID']))
{
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
$attr_iterator = ' iterator="Start" ';
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
$extra['iteratorID'] = $saved_iterator_id; // From Table
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
//$last = '2015-08-18T01:03:41';
//$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<EstimateQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
<MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
<ModifiedDateRangeFilter>
<FromModifiedDate>' . $last . '</FromModifiedDate>
</ModifiedDateRangeFilter>
<IncludeLineItems>true</IncludeLineItems>
<OwnerID>0</OwnerID>
</EstimateQueryRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
}
function _quickbooks_salesorder_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
// Iterator support (break the result set into small chunks)
$attr_iteratorID = '';
$attr_iterator = ' iterator="Start" ';
if (empty($extra['iteratorID']))
{
// This is the first request in a new batch
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
$extra['iteratorID'] = $saved_iterator_id; // From Table
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<SalesOrderQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
<MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
<ModifiedDateRangeFilter>
<FromModifiedDate>' . $last . '</FromModifiedDate>
</ModifiedDateRangeFilter>
<IncludeLineItems>true</IncludeLineItems>
<OwnerID>0</OwnerID>
</SalesOrderQueryRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
}
/**
* Handle a response from QuickBooks
*/
function _quickbooks_salesorder_import_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_IMPORT_SALESORDER, null, QB_PRIORITY_SALESORDER, array( 'iteratorID' => $idents['iteratorID'] ), $user);
}else{
return true;
}
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/SalesOrderQueryRs');
$smackHelper = new Quickbooks_vtigerHelper();
$smackHelper->addSalesOrder($List->children());
}
return true;
}
/**
* Build a request to import customers already in QuickBooks into our application
*/
function _quickbooks_item_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
// Iterator support (break the result set into small chunks)
$attr_iteratorID = '';
$attr_iterator = ' iterator="Start" ';
if (empty($extra['iteratorID']))
{
// This is the first request in a new batch
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
$extra['iteratorID'] = $saved_iterator_id; // From Table
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<ItemQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
<MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
<FromModifiedDate>' . $last . '</FromModifiedDate>
<OwnerID>0</OwnerID>
</ItemQueryRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
}
/**
* Handle a response from QuickBooks
*/
function _quickbooks_item_import_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_IMPORT_ITEM, null, QB_PRIORITY_ITEM, array( 'iteratorID' => $idents['iteratorID'] ), $user);
}else{
return true;
}
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/ItemQueryRs');
$smackHelper = new Quickbooks_vtigerHelper();
$smackHelper->addProducts($List->children(),'Products');
}
return true;
}
/**
* Build a request to import invoices already in QuickBooks into our application
*/
function _quickbooks_purchaseorder_import_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{
// Iterator support (break the result set into small chunks)
$attr_iteratorID = '';
$attr_iterator = ' iterator="Start" ';
if (empty($extra['iteratorID']))
{
// This is the first request in a new batch
$last = _quickbooks_get_last_run($user, $action);
_quickbooks_set_last_run($user, $action); // Update the last run time to NOW()
// Set the current run to $last
_quickbooks_set_current_run($user, $action, $last);
}
else
{
$extra['iteratorID'] = $saved_iterator_id; // From Table
// This is a continuation of a batch
$attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
$attr_iterator = ' iterator="Continue" ';
$last = _quickbooks_get_current_run($user, $action);
}
// Build the request
$xml = '<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="' . $version . '"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<PurchaseOrderQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
<MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
<!--<ModifiedDateRangeFilter>
<FromModifiedDate>' . $last . '</FromModifiedDate>
</ModifiedDateRangeFilter>-->
<IncludeLineItems>true</IncludeLineItems>
<OwnerID>0</OwnerID>
</PurchaseOrderQueryRq>
</QBXMLMsgsRq>
</QBXML>';
return $xml;
}
/**
* Handle a response from QuickBooks
*/
function _quickbooks_purchaseorder_import_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{
if (!empty($idents['iteratorRemainingCount']))
{
// Queue up another request
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
$Queue->enqueue(QUICKBOOKS_IMPORT_PURCHASEORDER, null, QB_PRIORITY_PURCHASEORDER, array( 'iteratorID' => $idents['iteratorID'] ), $user);
}else{
return true;
}
// This piece of the response from QuickBooks is now stored in $xml. You
// can process the qbXML response in $xml in any way you like. Save it to
// a file, stuff it in a database, parse it and stuff the records in a
// database, etc. etc. etc.
//
// The following example shows how to use the built-in XML parser to parse
// the response and stuff it into a database.
// Import all of the records
$errnum = 0;
$errmsg = '';
$Parser = new QuickBooks_XML_Parser($xml);
if ($Doc = $Parser->parse($errnum, $errmsg))
{
$Root = $Doc->getRoot();
$List = $Root->getChildAt('QBXML/QBXMLMsgsRs/PurchaseOrderQueryRs');
// TODO
}
return true;
}
/**
* Handle a 500 not found error from QuickBooks
*
* Instead of returning empty result sets for queries that don't find any
* records, QuickBooks returns an error message. This handles those error
* messages, and acts on them by adding the missing item to QuickBooks.
*/
function _quickbooks_error_e500_notfound($requestID, $user, $action, $ID, $extra, &$err, $xml, $errnum, $errmsg)
{
$Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
if ($action == QUICKBOOKS_IMPORT_INVOICE)
{
return true;
}
else if ($action == QUICKBOOKS_IMPORT_CUSTOMER)
{
return true;
}
else if ($action == QUICKBOOKS_IMPORT_SALESORDER)
{
return true;
}
else if ($action == QUICKBOOKS_IMPORT_ITEM)
{
return true;
}
else if ($action == QUICKBOOKS_IMPORT_PURCHASEORDER)
{
return true;
}
return false;
}
function _quickbooks_error_catchall($requestID, $user, $action, $ID, $extra, &$err, $xml, $errnum, $errmsg)
{
$message = '';
$message .= 'Request ID: ' . $requestID . "\r\n";
$message .= 'User: ' . $user . "\r\n";
$message .= 'Action: ' . $action . "\r\n";
$message .= 'ID: ' . $ID . "\r\n";
$message .= 'Extra: ' . print_r($extra, true) . "\r\n";
//$message .= 'Error: ' . $err . "\r\n";
$message .= 'Error number: ' . $errnum . "\r\n";
$message .= 'Error message: ' . $errmsg . "\r\n";
mail(QB_QUICKBOOKS_MAILTO,
'QuickBooks error occured!',
$message);
}
So I see at least a few potential issues, and have some questions. First, some background --
Iterators in QuickBooks work just like a database cursor. Part of that means that you can't have two iterators open at once - you have to finish with one iterator before you start and/or continue another iterator. So if you do this, you'll get the error you're seeing:
Start iterator #1
Fetch some data from iterator #1
Start iterator #2
Try to fetch some data from iterator #1 again
That will fail because starting the second iterator has closed/killed the first iterator. This is probably what's happening to you.
What is this?
$extra['iteratorID'] = $saved_iterator_id; // From Table
That looks like an undefined variable to me. Did you check your PHP error logs?
Why are you saving this to a table, and what table are you saving it to? Where in the code are you pulling it back out of the table? I don't see any code that gets it from the table.

Back end for iOS app with relational databases

I am currently trying to build an ios application that will need to be able to retrieve and store data in a remote relational database. I have investigated using RestKit for the front end, which seems adequate. I have experience developing with both mysql and php, though I am not sure where to start in getting a web server to send information that is not html. (php enhanced html, that is)
I would appreciate any input on where I might get started. Thanks in advance!
I use PHP to query a mySQL database on my server and format the response as XML which I then parse in the app.
Here is a PHP example from my server....This also sends a size response to allow the App to track the download completion percentage and a file name response too. Also, if the database is empty, it will send a dummy record.
<?php
header("Content-type: text/text");
//get the values from the url query string
$user = $_GET['user'];
$pass = $_GET['password'];
$db = $_GET['database'];
$dbhost = 'localhost';
//create connection to mysql or tell user something has gone wrong
$connection = mysql_connect( $dbhost, $user, $pass ) or die('Could not connect to MySQL');
//select database or tell user something has gone wrong
mysql_select_db( $db ) or die('Could not select database');
// Construct and run query.
$sql = 'SELECT * FROM itemInfo WHERE itemStatus = "active" ORDER BY itemSortKey ASC';
//echo $sql;
$result = mysql_query($sql) or die('<result>fail</result>');
$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "<bodyimage>\n";
while($record = mysql_fetch_assoc($result)) {
$xml_output .= "\t<storeitems>\n";
$xml_output .= "\t\t<itemSortKey>" . $record['itemSortKey'] . "</itemSortKey>\n";
$xml_output .= "\t\t<itemDesc>" . $record['itemDesc'] . "</itemDesc>\n";
$xml_output .= "\t\t<itemPrice>" . $record['itemPrice'] . "</itemPrice>\n";
$xml_output .= "\t\t<productID>" . $record['productID'] . "</productID>\n";
$xml_output .= "\t\t<field1>" . $record['field1'] . "</field1>\n";
$xml_output .= "\t\t<field2>" . $record['field2'] . "</field2>\n";
$xml_output .= "\t\t<field3>" . $record['field3'] . "</field3>\n";
$xml_output .= "\t\t<field4>" . $record['field4'] . "</field4>\n";
$xml_output .= "\t\t<dateCreated>" . $record['dateCreated'] . "</dateCreated>\n";
$xml_output .= "\t\t<dateModified>" . $record['dateModified'] . "</dateModified>\n";
// Escaping illegal characters
//$row['text'] = str_replace("&", "&", $row['text']);
//$row['text'] = str_replace("<", "<", $row['text']);
//$row['text'] = str_replace(">", ">", $row['text']);
//$row['text'] = str_replace("\"", """, $row['text']);
//$xml_output .= "\t\t<text>" . $row['text'] . "</text>\n";
$xml_output .= "\t</storeitems>\n";
//add this record to the output
//$output = '|facilityname|' .$record['facilityname'] . '|/facilityname||customername|' . $record['customername'] . '|/customername||imageurl|' . $record['imageurl'] . '|/imageurl|';
//print $output;
}
$xml_output .= "</bodyimage>";
header("HTTP/1.0 200 OK");
header('Content-type: text/xml');
header('Content-Disposition: attachment; filename="storeitems.xml"');
header("Content-Length: ".strlen ( $xml_output ));
// redundent.....$xml_output .= "</bmrcontrol>";
//echo strlen( $xml_output );
//the next statement relates if there are NO lines in the table - it sends a message
if ( strlen( $xml_output ) == 61 ) {
$xml_output = "<?xml version=\"1.0\"?>\n";
$xml_output .= "<bodyimage>\n";
$xml_output .= "\t<storeitems>\n";
$xml_output .= "\t\t<itemSortKey>aaaa</itemSortKey>\n";
$xml_output .= "\t\t<itemDesc>Store Items Missing</itemDesc>\n";
$xml_output .= "\t\t<itemPrice>0.0</itemPrice>\n";
$xml_output .= "\t\t<productID>blank</productID>\n";
$xml_output .= "\t\t<field1>.</field1>\n";
$xml_output .= "\t\t<field2>.</field2>\n";
$xml_output .= "\t\t<field3>.</field3>\n";
$xml_output .= "\t\t<field4>.</field4>\n";
$xml_output .= "\t\t<dateCreated>2012-02-13 09:03:49</dateCreated>\n";
$xml_output .= "\t\t<dateModified>2012-02-13 09:03:49</dateModified>\n";
// Escaping illegal characters
//$row['text'] = str_replace("&", "&", $row['text']);
//$row['text'] = str_replace("<", "<", $row['text']);
//$row['text'] = str_replace(">", ">", $row['text']);
//$row['text'] = str_replace("\"", """, $row['text']);
//$xml_output .= "\t\t<text>" . $row['text'] . "</text>\n";
$xml_output .= "\t</storeitems>\n";
$xml_output .= "</bodyimage>";
}
echo $xml_output;
if(mysql_num_rows($result)) {
//mysql_close($connection);
}
else
die('<result>fail</result>');
//mysql_close($connection);
?>

How to get the total number of tweets, retweets and replies on a particular tag or account, in Twitter using its API?

I have a requirement to get the total no.of tweets, retweets and replies on a particular tag or user account. How to get these numbers efficiently? The numbers should be exact and not like 100+.
I also need to get the total no.of direct messages.
Using this site as a starting point I've been trying the same thing:
Pull Twitter feed into your site
<?php
require_once 'db-functions.inc.php' ; //custom database functions
function saveTweets($screen_name) {
global $link;
$screen_name = dbEscape(strtolower(trim($screen_name)));
if (!$screen_name) { echo "<p><strong>Error: No screen name declared.</strong></p>\n"; return false; }
$row = dbGetRow("SELECT `id` FROM `retweet` WHERE `screen_name`='$screen_name' ORDER BY `id` DESC LIMIT 1");
$last_id = $row['id'];
$url = "http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=$screen_name&count=1500&include_rts=true" ;
if ($last_id) { $url .= "&since_id=$last_id" ; }
$ch = curl_init($url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
$xml = curl_exec ($ch);
curl_close ($ch);
$affected = 0;
$twelement = new SimpleXMLElement($xml);
foreach ($twelement->status as $status) {
$text = dbEscape(trim($status->text));
$time = strtotime($status->created_at);
$id = $status->id;
$retweet_count = $status->retweet_count;
dbQuery("INSERT INTO `twit` (`id`,`screen_name`,`time`,`text`,`hidden`,`retweet_count`) VALUES ('$id','$screen_name','$time','$text','n','$retweet_count')");
$affected = $affected + dbAffectedRows();
}
return "<p>".number_format($affected)." new tweets from $screen_name saved.</p>\n" ;
}
echo saveTweets('stackoverflow');
echo saveTweets('Apple');
echo saveTweets('Android');
echo saveTweets('Google');
?>
<h3>Stackoverflow</h3>
<?php
require_once 'databaseconnection.php' ; //database connection function
$result = dbQuery("SELECT * FROM `retweet` WHERE `hidden` != 'y' ORDER BY `retweet_count` DESC");
while ($row = mysql_fetch_array($result)) {
echo $row[0];
echo "<br>";
echo date("l, M j, Y, G:i a",$row[3]);
echo " : ";
echo stripslashes($row[2]);
echo "<br>";
echo stripslashes($row[4]);
echo "<br>Retweet: ";
echo stripslashes($row[6]);
echo "<br>";
echo "<br>";
}
?>
At the present time this doesn't have an "UPDATE" clause in it to take into account the retweet_count increasing, and you can remove:
return "<p>".number_format($affected)." new tweets from $screen_name saved.</p>\n" ;
If you don't need to see what has been updated.
Hope that helps

Resources