CustomerAddRq QuickBooks XML 包括 ClientsController CakePHP3 中的文件

CustomerAddRq QuickBooks XML including files in ClientsController CakePHP3

我正在使用 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 连接器更新时收到 'No Data Exchange Required' - 这很好)。但现在我正试图将添加客户的排队移动到它应该在的地方,在 ClientsController.php 中。我遇到了几个不同的错误,具体取决于我 require_once

第一个场景: 首先,我只是尝试复制 QuickbooksController.php,所以我 require_once 的所有内容都与那里的一样。这就是为什么有这么多注释掉的行。这导致尝试加载文件 /.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 class,所以那是我 require_once 唯一的 class。这导致错误 Class 'QuickBooks_Loader' not found

第三种情况 接下来,我包括 QuickBooks_Loader 以及 Queue。这导致错误 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

我可以 post 我的 QuickbooksController.php 如果它有用,但现在省略 space 因为我在使用 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;
    }

}
?>


Namespace 根据 Keith 的建议仅 require_once'ing QuickBooks.php 后出现错误(但未使用全局名称space)

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

任何正确方向的推动将不胜感激:)

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

require_once(ROOT . DS . 'vendor' . DS . 'quickbooks-php-master' . DS . 'QuickBooks.php');

在此代码中:

$queue = new QuickBooks_WebConnector_Queue($dsn);

您还没有定义 $dsn 变量。请定义它。

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

这告诉您您在命名空间中:

2016-11-02 09:50:16 Error: [Error] Class 'App\Controller\QuickBooks_WebConnector_Queue' not found

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

$queue = new \QuickBooks_WebConnector_Queue($dsn);

注意前导 \,它表示在搜索 class 时应使用全局命名空间。