diff --git a/.gitignore b/.gitignore index c7b6d033..862001b9 100644 --- a/.gitignore +++ b/.gitignore @@ -166,3 +166,10 @@ pip-log.txt # Mac crap .DS_Store + + +############# +## Composer +############# + +vendor/ diff --git a/QuickBooks/Driver/Sql.php b/QuickBooks/Driver/Sql.php index 74e400a1..9615c1a2 100755 --- a/QuickBooks/Driver/Sql.php +++ b/QuickBooks/Driver/Sql.php @@ -1111,7 +1111,7 @@ protected function _recurDequeue($user, $by_priority = false) if ($by_priority) { - $sql .= ' ORDER BY priority DESC '; + $sql .= ' ORDER BY priority DESC, enqueue_datetime ASC, quickbooks_recur_id ASC '; } if ($arr = $this->_fetch($this->_query($sql . ' ', $errnum, $errmsg, 0, 1))) @@ -1430,7 +1430,8 @@ protected function _queueDequeue($user, $by_priority = false) if ($by_priority) { - $sql .= ' ORDER BY priority DESC, ident ASC '; + // Run highest priority first, then preference older queue entries. In case datetime is the same use queue ID to infer earlier entry. + $sql .= ' ORDER BY priority DESC, enqueue_datetime ASC, quickbooks_queue_id ASC '; } return $this->_fetch($this->_query($sql, $errnum, $errmsg, 0, 1)); diff --git a/QuickBooks/Driver/Sql/Mysqli.php b/QuickBooks/Driver/Sql/Mysqli.php index fe856210..a9e6adb6 100644 --- a/QuickBooks/Driver/Sql/Mysqli.php +++ b/QuickBooks/Driver/Sql/Mysqli.php @@ -430,8 +430,9 @@ public function escape($str) */ protected function _escape($str) { - if (is_array($str)) - { + if ($str === null) { + $str = ''; + } elseif (is_array($str)) { error_log('Param passed to _escape($str) was an array: ' . print_r($str, true)); $str = ''; } diff --git a/QuickBooks/Payments.php b/QuickBooks/Payments.php index efa65495..ae44b26b 100755 --- a/QuickBooks/Payments.php +++ b/QuickBooks/Payments.php @@ -102,8 +102,9 @@ class Quickbooks_Payments protected $_last_errdetail; protected $_last_errtype; protected $_last_errinfolink; + private mixed $_last_intuittid; - public function __construct($oauth_consumer_key, $oauth_consumer_secret, $sandbox = false, $dsn = null, $log_level = QUICKBOOKS_LOG_NORMAL) + public function __construct($oauth_consumer_key, $oauth_consumer_secret, $sandbox = false, $dsn = null, $log_level = QUICKBOOKS_LOG_NORMAL) { $this->_oauth_consumer_key = $oauth_consumer_key; $this->_oauth_consumer_secret = $oauth_consumer_secret; diff --git a/QuickBooks/UnitTest.php b/QuickBooks/UnitTest.php index 74dc1a35..8dbe7c60 100755 --- a/QuickBooks/UnitTest.php +++ b/QuickBooks/UnitTest.php @@ -19,8 +19,9 @@ class QuickBooks_UnitTest protected $__lastMessage; protected $__lastActual; protected $__lastExpected; - - public function __construct() + private mixed $__lastError; + + public function __construct() { } diff --git a/QuickBooks/Utilities.php b/QuickBooks/Utilities.php index c90ece51..08c3bb4e 100755 --- a/QuickBooks/Utilities.php +++ b/QuickBooks/Utilities.php @@ -90,7 +90,12 @@ static public function mask($message) if (substr($key, 0, 1) == '<') { // It's an XML tag - $contents = QuickBooks_Utilities::_extractTagContents(trim($key, '<> '), $message); + $contents = QuickBooks_XML::extractTagContents(trim($key, '<> '), $message); + + // Clears type coercion warning in PHP 8+ + if (!$contents) { + $contents = ''; + } $masked = str_repeat('x', min(strlen($contents), 12)) . substr($contents, 12); @@ -101,15 +106,6 @@ static public function mask($message) return $message; } - /** - * @deprecated Use QuickBooks_XML::extractTagContents() instead - */ - static protected function _extractTagContents($tag, $data) - { - $tmp = QuickBooks_XML::extractTagContents($tag, $data); - return $tmp; - } - /** * Write a message to the log (via the back-end driver) * diff --git a/QuickBooks/WebConnector/Handlers.php b/QuickBooks/WebConnector/Handlers.php index 3348875d..7932a49b 100755 --- a/QuickBooks/WebConnector/Handlers.php +++ b/QuickBooks/WebConnector/Handlers.php @@ -320,6 +320,8 @@ protected function _defaults($config) 'deny_reallyfast_timeout' => 600, 'masking' => true, + + 'status_error_threshold' => 500, // the lowest status code considered an error ); $config = array_merge($defaults, $config); @@ -347,6 +349,8 @@ protected function _defaults($config) $config['deny_reallyfast_logins'] = (boolean) $config['deny_reallyfast_logins']; $config['deny_reallyfast_timeout'] = (int) max(1, $config['deny_reallyfast_timeout']); + $config['status_error_threshold'] = (int) max(1, $config['status_error_threshold']); + return $config; } @@ -518,14 +522,14 @@ public function authenticate($obj) } } - // Custom authentication backends - $override_dsn = $this->_config['authenticate']; - if (!empty($this->_config['authenticate_dsn'])) { // Backwards compat. $override_dsn = $this->_config['authenticate_dsn']; - } + } else { + // Custom authentication backends + $override_dsn = $this->_config['authenticate']; + } $auth = null; @@ -544,7 +548,7 @@ public function authenticate($obj) $customauth_wait_before_next_update = null; $customauth_min_run_every_n_seconds = null; - if (is_array($override_dsn) or strlen($override_dsn)) // Custom autj + if (is_array($override_dsn) or ($override_dsn !== null and strlen($override_dsn))) // Custom autj { //if ($auth->authenticate($obj->strUserName, $obj->strPassword, $customauth_company_file, $customauth_wait_before_next_update, $customauth_min_run_every_n_seconds) and @@ -1288,7 +1292,8 @@ public function receiveResponseXML($obj) // Check if we got a error message... if (strlen($obj->message) or - $this->_extractStatusCode($obj->response)) // or an error code + $this->_extractStatusCode($obj->response) + >= $this->_config['status_error_threshold']) // or an error code { //$this->_log('Extracted code[' . $this->_extractStatusCode($obj->response) . ']', $obj->ticket, QUICKBOOKS_LOG_DEBUG); diff --git a/QuickBooks/WebConnector/Queue.php b/QuickBooks/WebConnector/Queue.php index 3168d4f3..82e2f7f3 100755 --- a/QuickBooks/WebConnector/Queue.php +++ b/QuickBooks/WebConnector/Queue.php @@ -60,8 +60,13 @@ class QuickBooks_WebConnector_Queue * @var string */ protected $_user; - - /** + + /** + * @var object|null + */ + private $_driver; + + /** * Create a new QuickBooks queue instance * * @param mixed $dsn_or_conn A DSN-style connection string (i.e.: mysq://root:pass@locahost/database) or a database connection (if you wish to re-use an existing database connection) @@ -198,7 +203,7 @@ public function recurring($run_every, $action, $ident = null, $priority = 0, $ex * called. * * @param string $action An action to be performed within QuickBooks (see the qbXML and QuickBooks SDK documentation, i.e.: "CustomerAdd", "InvoiceAdd", "CustomerMod", etc.) - * @param mixed $ident A unique identifier (if required) for a record being operated on (i.e. if you're doing a "CustomerAdd", you'd probaly put a unique customer ID number here, so you're SOAP handler function knows which customer it is supposed to add) + * @param mixed $ident A unique identifier (if required) for a record being operated on (i.e. if you're doing a "CustomerAdd", you'd probably put a unique customer ID number here, so your SOAP handler function knows which customer it is supposed to add) * @param integer $priority The priority of the update (higher priority actions will be pushed to QuickBooks before lower priority actions) * @param array $extra If you need to make additional bits of data available to your request/response functions, you can pass an array of extra data here * @param string $user The username of the QuickBooks Web Connector user this item should be queued for @@ -207,7 +212,8 @@ public function recurring($run_every, $action, $ident = null, $priority = 0, $ex */ public function enqueue($action, $ident = null, $priority = 0, $extra = null, $user = null, $qbxml = null, $replace = true) { - if (!strlen($ident)) + // strlen(null) generates depreciation warning in PHP8 + if ($ident === null || !strlen($ident)) { // If they didn't provide an $ident, generate a random, unique one diff --git a/QuickBooks/XML.php b/QuickBooks/XML.php index b58ec3c5..a839acf5 100755 --- a/QuickBooks/XML.php +++ b/QuickBooks/XML.php @@ -214,7 +214,7 @@ class QuickBooks_XML * * @param string $tag The XML tag to extract the contents from * @param string $data The XML document - * @return string The contents of the tag + * @return string|null The contents of the tag */ static public function extractTagContents($tag, $data) { diff --git a/QuickBooks/XML/Backend/Builtin.php b/QuickBooks/XML/Backend/Builtin.php index 76849412..b4a829dd 100644 --- a/QuickBooks/XML/Backend/Builtin.php +++ b/QuickBooks/XML/Backend/Builtin.php @@ -364,6 +364,11 @@ protected function _parseHelper($xml, &$Root, &$errnum, &$errmsg, $indent = 0) $length = $node[3]; $payload = $node[4]; + // Force type coercion for PHP 8.1 warnings but also compatible with PHP 5.0 + if ($payload === null) { + $payload = ''; + } + $tmp = ''; $attributes = array(); $this->_extractAttributes($tag_w_attrs, $tmp, $attributes); @@ -371,6 +376,10 @@ protected function _parseHelper($xml, &$Root, &$errnum, &$errmsg, $indent = 0) $Node = new QuickBooks_XML_Node($tag); foreach ($attributes as $key => $value) { + // Force type coercion for PHP 8.1 warnings but also compatible with PHP 5.0 + if ($value === null) { + $value = ''; + } $value = QuickBooks_XML::decode($value, true); $Node->addAttribute($key, $value); diff --git a/composer.json b/composer.json index d7a21d8b..c4b14583 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": ">=5.0.0" + "php": "^5.0|^7.0|^8.0" }, "autoload": { diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..2ffd588c --- /dev/null +++ b/composer.lock @@ -0,0 +1,20 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "eac6704a48f10e32485644cf1c9bb943", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.0.0" + }, + "platform-dev": [], + "plugin-api-version": "2.0.0" +} diff --git a/docs/web_connector/example_codeigniter_web_connector/models/quickbooks.php b/docs/web_connector/example_codeigniter_web_connector/models/quickbooks.php index 627a76e5..ea1a7411 100644 --- a/docs/web_connector/example_codeigniter_web_connector/models/quickbooks.php +++ b/docs/web_connector/example_codeigniter_web_connector/models/quickbooks.php @@ -2,7 +2,9 @@ class Quickbooks extends CI_Model { - public function __construct() + private $_dsn; + + public function __construct() { parent::__construct(); } diff --git a/docs/web_connector/example_kohana_web_connector/application/classes/model/qbdata.php b/docs/web_connector/example_kohana_web_connector/application/classes/model/qbdata.php index 8a27816e..cfffbff7 100644 --- a/docs/web_connector/example_kohana_web_connector/application/classes/model/qbdata.php +++ b/docs/web_connector/example_kohana_web_connector/application/classes/model/qbdata.php @@ -12,7 +12,9 @@ */ class Model_Qbdata extends ORM { - public function __construct() + private $_db; + + public function __construct() { //link up this model to our qb_data database $this->_db = Database::instance('qb_data');