【问题标题】:CustomerAddRq QuickBooks XML including files in ClientsController CakePHP3CustomerAddRq QuickBooks XML 包括 ClientsController CakePHP3 中的文件
【发布时间】:2017-03-15 04:35:45
【问题描述】:

我正在使用 consolibyte 的 php 开发工具包 (http://www.consolibyte.com/docs/index.php/PHP_DevKit_for_QuickBooks_-_Quick-Start / https://github.com/consolibyte/quickbooks-php) 将 QuickBooks Desktop 与 CakePHP 3.3 应用程序集成。我能够通过快速入门指南工作并从我的QuickbooksController.php 中添加一个客户(删除了该测试添加,现在通过 Web 连接器更新时收到“不需要数据交换”——这很好)。但现在我正试图将添加客户的队列移动到应该在的位置,ClientsController.php。我遇到了几个不同的错误,具体取决于我 require_once

第一个场景: 首先,我只是尝试复制QuickbooksController.php,所以我require_once'd 一切都和那里一样。这就是为什么有这么多注释掉的行。这导致尝试加载文件/.phprequire_once(/var/www/html/pivot/vendor/quickbooks-php-master/QuickBooks/Driver/.php): failed to open stream: No such file or directory [ROOT/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 56]

第二种情况 然后我想我应该只需要 Queue 类,所以这是我require_once'd 的唯一类。这导致了错误Class 'QuickBooks_Loader' not found

第三种情况 接下来我包括QuickBooks_Loader 以及队列。这导致了错误Notice (8): Use of undefined constant QUICKBOOKS_BASEDIR - assumed 'QUICKBOOKS_BASEDIR' [ROOT/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 56] require_once(QUICKBOOKS_BASEDIR/QuickBooks/Driver/Factory.php) [function.require-once]: failed to open stream: No such file or directory [ROOT/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 56] Fatal error: require_once() [function.require]: Failed opening required 'QUICKBOOKS_BASEDIR/QuickBooks/Driver/Factory.php' (include_path='.:/usr/share/php') in /var/www/html/pivot/vendor/quickbooks-php-master/QuickBooks/Loader.php on line 56

如果有用的话,我可以发布我的 QuickbooksController.php,但现在省略空间,因为在使用 Web 连接器更新时我没有收到任何错误。这是我的 [更新] 客户端控制器

ClientsController.php

<?php
namespace App\Controller;
require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks.php');

use App\Controller\AppController;
use Cake\I18n\Time;
use Cake\Utility\Text;
use Cake\Mailer\MailerAwareTrait;
use Cake\Log\Log;
use Cake\Core\Configure;
use QuickBooks;


/**
 * Clients Controller
 *
 * @property \App\Model\Table\ClientsTable $Clients
 */
class ClientsController extends AppController
{
    use MailerAwareTrait;
    //...skipping to add function
  /**
 * Add method
 *
 * @return void Redirects on successful add, renders view otherwise.
 */
    public function add()
    {
        $this->viewBuilder()->layout('dialog'); // we're gonna be opening in dialog
        $dsn = Configure::read('qbDsn');
        $client = $this->Clients->newEntity();
        if ($this->request->is('post')) {
            $newClientData = $this->request->data(); // transfer post data to $newClientData so we can manipulate further
            //data manipulation omitted
            $client = $this->Clients->patchEntity($client, $newClientData);
            if ($this->Clients->save($client)) {
                // incorrect - need to use global namespace not App\Controller
                //$queue = new QuickBooks_WebConnector_Queue($dsn);

                // Updated - confirmed correct
                $queue = new \QuickBooks_WebConnector_Queue($dsn)
                $queue->enqueue(QUICKBOOKS_ADD_CUSTOMER, $client->id);
                $this->Flash->success(__('The client has been saved.'));
                return $this->redirect(['action' => 'view', $client->id]); 
            } else {
                Log::write('debug', $client->errors());
                $this->Flash->error(__('The client could not be saved. Please, try again.'));
                //return $this->redirect(($this->referer()));
            }
        }
    }


完成 QuickBooksController.php

<?php
namespace App\Controller;
require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks.php');
require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks' . DS . 'Utilities.php');
require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks' . DS . 'WebConnector' . DS . 'Server.php');
//require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks' . DS . 'WebConnector' . DS . 'Queue.php');
require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks' . DS . 'WebConnector' . DS . 'Handlers.php');
//require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks' . DS . 'WebConnector' . DS . 'Functions.php');

use QuickBooks;

use App\Controller\AppController;
use Cake\Log\Log;
use QuickBooks_WebConnector_Server;
use QuickBooks_Utilities;
//use QuickBooks_WebConnector_Queue;
use QuickBooks_WebConnector_Handlers;
//use QuickBooks_WebConnector_Functions;

//use QuickBooks_WebConnector_QWC;

/**
* Quickbooks Controller
*
* @property \App\Model\Table\QuickbooksTable $Quickbooks
*/
class QuickbooksController extends AppController
{

    public function initialize()
    {
        parent::initialize();
        $this->Auth->allow();
        $dsn = 'mysqli://qb@192.168.16.243/pivot';
        $qbwc_user = 'quickbooks';
        $qbwc_pass = 'password';
        if(!QuickBooks_Utilities::initialized($dsn)) {
            QuickBooks_Utilities::initialize($dsn);
            QuickBooks_Utilities::createUser($dsn, $qbwc_user, $qbwc_pass);

        }
    }

    public function endpoint() 
    {
        $this->viewBuilder()->layout('qb');
        $this->response->type(['xml' => 'text/xml']);
        $this->response->type('xml');
        $map = array(
            //QuickBooks_WebConnector_Functions::QUICKBOOKS_ADD_CUSTOMER => array( '_quickbooks_customer_add_request', '_quickbooks_customer_add_response' ),
        QUICKBOOKS_ADD_CUSTOMER => array(array($this, '_quickbooks_customer_add_request'), array($this, '_quickbooks_customer_add_response' )),
        //QUICKBOOKS_ADD_SALESRECEIPT => array( '_quickbooks_salesreceipt_add_request', '_quickbooks_salesreceipt_add_response'     ), 
            //'*' => array( '_quickbooks_customer_add_request', '_quickbooks_customer_add_response' ), 
            // ... more action handlers here ...
            );
        // This is entirely optional, use it to trigger actions when an error is returned by QuickBooks
        $errmap = array(
            3070 => '_quickbooks_error_stringtoolong',              // Whenever a string is too long to fit in a field, call this function: _quickbooks_error_stringtolong()
                // 'CustomerAdd' => '_quickbooks_error_customeradd',    // Whenever an error occurs while trying to perform an 'AddCustomer' action, call this function: _quickbooks_error_customeradd()
                // '*' => '_quickbooks_error_catchall',                 // Using a key value of '*' will catch any errors which were not caught by another error handler
                // ... more error handlers here ...
                );

        // An array of callback hooks
        $hooks = array(
            // There are many hooks defined which allow you to run your own functions/methods when certain events happen within the framework
             QuickBooks_WebConnector_Handlers::HOOK_LOGINSUCCESS => '_quickbooks_hook_loginsuccess',    // Run this function whenever a successful login occurs
            );

        // Logging level
        //$log_level = QUICKBOOKS_LOG_NORMAL;
        //$log_level = QUICKBOOKS_LOG_VERBOSE;
        //$log_level = QUICKBOOKS_LOG_DEBUG;                
        $log_level = QUICKBOOKS_LOG_DEVELOP;        // Use this level until you're sure everything works!!!

        // 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(
            //'authenticate' => ' *** YOU DO NOT NEED TO PROVIDE THIS CONFIGURATION VARIABLE TO USE THE DEFAULT AUTHENTICATION METHOD FOR THE DRIVER YOU'RE USING (I.E.: MYSQL) *** '
            //'authenticate' => 'your_function_name_here', 
            //'authenticate' => array( 'YourClassName', 'YourStaticMethod' ),
            'deny_concurrent_logins' => false, 
            'deny_reallyfast_logins' => false, 
            );      // See the comments in the QuickBooks/Server/Handlers.php file
        $driver_options = array(        // See the comments in the QuickBooks/Driver/<YOUR DRIVER HERE>.php file ( i.e. 'Mysql.php', etc. )
            //'max_log_history' => 1024,    // Limit the number of quickbooks_log entries to 1024
            //'max_queue_history' => 64,    // Limit the number of *successfully processed* quickbooks_queue entries to 64
            );
        $callback_options = array();

        $dsn = 'mysqli://qb@192.168.16.243/pivot';
        //$queue = new QuickBooks_WebConnector_Queue($dsn);
        //$testKey = 25215;
        //$queue->enqueue(QUICKBOOKS_ADD_CUSTOMER, $testKey);

        $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);
    }

    function _quickbooks_customer_add_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
    {
        $this->loadModel('Clients');
        $client = $this->Clients->get($ID);

        // Create and return a qbXML request
        $qbxml = '<?xml version="1.0" encoding="utf-8"?>
        <?qbxml version="2.0"?>
        <QBXML>
            <QBXMLMsgsRq onError="stopOnError">
                <CustomerAddRq requestID="' . $requestID . '">
                    <CustomerAdd>
                        <Name>' . $client->company_name . '</Name>
                        <CompanyName>' . $client->company_name . '</CompanyName>
                        <BillAddress>
                            <Addr1>' . $client->address . '</Addr1>
                            <City>' . $client->city . '</City>
                            <State>' . $client->state . '</State>
                            <PostalCode>' . $client->zip . '</PostalCode>
                            <Country>' . $client->country . '</Country>
                        </BillAddress>';

        if (isset($client->mailing_address) && isset($client->mailing_city) && 
        isset($client->mailing_state) && isset($client->mailing_zip) &&
        isset($client->mailing_country)){
            $qbxml .= '<ShipAddress>
                    <Addr1>' . $client->mailing_address . '</Addr1>
                    <City>' . $client->mailing_city . '</City>
                    <State>' . $client->mailing_state . '</State>
                    <PostalCode>' . $client->mailing_zip . '</PostalCode>
                    <Country>' . $client->mailing_country . '</Country>
            </ShipAddress>';
        }
        if (isset($client->primary_phone)){
            $qbxml .= '<Phone>' . $client->primary_phone . '</Phone>';
        }
        if (isset($client->secondary_phone)){
            $qbxml .= '<AltPhone>' . $client->secondary_phone . '</AltPhone>';
        }
        if (isset($client->fax)){
            $qbxml .= '<Fax>' . $client->fax . '</Fax>';
        }        
        if (isset($client->email)){
            $qbxml .= '<Email>' . $client->email . '</Email>';
        }  
        $qbxml .= '</CustomerAdd></CustomerAddRq></QBXMLMsgsRq></QBXML>';

        return $qbxml;
    }

    function _quickbooks_customer_add_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
    {   
        $this->loadModel('Clients');
        $client = $this->Clients->get($ID);
        $data = [
            'qb_list_id' => $idents['ListID']
        ];
        $client = $this->Clients->patchEntity($client, $data);
        if (!$this->Clients->save($client)){
            Log::write('debug', 'failed updating client qb_list_id in qb response');
            Log::write('debug', $client->errors());
        }
    }

    public function isAuthorized($user)
    {
        return true;
    }

}
?>


根据 Keith 的建议,仅在 require_once'ing QuickBooks.php 之后出现命名空间错误(但不使用全局命名空间)

2016-11-02 09:50:16 Error: [Error] Class 'App\Controller\QuickBooks_WebConnector_Queue' not found
Request URL: /clients/add.json
Referer URL: http://pivotstaging.efs.net/landings/admin
Client IP: 192.168.16.172
Stack Trace:
#0 [internal function]: App\Controller\ClientsController->add()
#1 /var/www/html/pivot/vendor/cakephp/cakephp/src/Controller/Controller.php(435): call_user_func_array(Array, Array)
#2 /var/www/html/pivot/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php(122): Cake\Controller\Controller->invokeAction()
#3 /var/www/html/pivot/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php(96): Cake\Http\ActionDispatcher->_invoke(Object(App\Controller\ClientsController))
#4 /var/www/html/pivot/vendor/cakephp/cakephp/src/Routing/Dispatcher.php(60): Cake\Http\ActionDispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#5 /var/www/html/pivot/webroot/index.php(36): Cake\Routing\Dispatcher->dispatch(Object(Cake\Network\Request), Object(Cake\Network\Response))
#6 {main}

最近的错误

2016-11-03 07:47:39 Warning: Warning (2): require_once(/var/www/html/pivot/vendor/quickbooks-php-master/QuickBooks/Driver/.php): failed to open stream: No such file or directory in [/var/www/html/pivot/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 56]
Request URL: /clients/add.json
Referer URL: http://pivotstaging.efs.net/landings/admin
Client IP: 192.168.16.172
Trace:
Cake\Error\BaseErrorHandler::handleError() - CORE/src/Error/BaseErrorHandler.php, line 146
require_once - ROOT/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 56
QuickBooks_Loader::load() - ROOT/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 56
QuickBooks_Loader::__autoload() - ROOT/vendor/quickbooks-php-master/QuickBooks/Loader.php, line 104
spl_autoload_call - [internal], line ??
class_exists - [internal], line ??
QuickBooks_Driver_Factory::create() - ROOT/vendor/quickbooks-php-master/QuickBooks/Driver/Factory.php, line 95
QuickBooks_WebConnector_Queue::__construct() - ROOT/vendor/quickbooks-php-master/QuickBooks/WebConnector/Queue.php, line 73
App\Controller\ClientsController::add() - APP/Controller/ClientsController.php, line 271
Cake\Controller\Controller::invokeAction() - CORE/src/Controller/Controller.php, line 435
Cake\Http\ActionDispatcher::_invoke() - CORE/src/Http/ActionDispatcher.php, line 122
Cake\Http\ActionDispatcher::dispatch() - CORE/src/Http/ActionDispatcher.php, line 96
Cake\Routing\Dispatcher::dispatch() - CORE/src/Routing/Dispatcher.php, line 60
[main] - ROOT/webroot/index.php, line 36

任何朝着正确方向的轻推将不胜感激:)

【问题讨论】:

    标签: php cakephp integration quickbooks


    【解决方案1】:

    这是您应该包括的唯一内容:

    require_once(ROOT . DS . '供应商' . DS . 'quickbooks-php-master' . DS . 'QuickBooks.php');

    在这段代码中:

    $queue = new QuickBooks_WebConnector_Queue($dsn);

    您尚未定义$dsn 变量。请定义它。

    就命名空间问题而言......

    这告诉你你在一个命名空间中:

    2016-11-02 09:50:16 错误:[错误] 类 'App\Controller\QuickBooks_WebConnector_Queue' 未找到

    但是您要查找的类与您不在同一个命名空间中。您使用的 PHP 库没有命名空间,因此您需要将其置于全局命名空间之外 (https://secure.php.net/manual/en/language.namespaces.global.php):

    $queue = 新 \QuickBooks_WebConnector_Queue($dsn);

    注意前面的\,它表示在搜索类时应该使用全局命名空间。

    【讨论】:

    • 基思,感谢您的快速回复。当只包括你提到的 QuickBooks.php 时,我收到一个错误,它找不到 Queue 类。在浏览了更多 QuickBooks.php 之后,它应该从那里包含,对吗?如果if (QUICKBOOKS_FRAMEWORKS &amp; QUICKBOOKS_FRAMEWORK_QUEUE or QUICKBOOKS_FRAMEWORKS &amp; QUICKBOOKS_FRAMEWORK_WEBCONNECTOR) 为真。抱歉 - 我忘了添加 $dsn - 它在 add 函数中进一步定义 - $dsn = Configure::read('qbDsn');
    • 然后发布您的实际完整代码,以便我们实际看到您在做什么。如果我不能告诉你在这里真正做什么,我将无法提供帮助。另外,发布实际的错误消息怎么样,这样我就不必猜测实际的错误是什么?
    • 用更多代码和整个(最近的)错误更新了问题。感谢您的宝贵时间!
    • 编辑了我的答案以反映您发布的新代码/错误。
    • 多哈。多么简单的修复。谢谢你。这解决了命名空间错误,但是我现在回到场景#1,加载程序试图要求一个文件“.php”......我更新了我的代码并发布了错误。非常感谢您的帮助!
    猜你喜欢
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    相关资源
    最近更新 更多