Fatal error from MessageFactory

Hello. When I attempt to do a findByField using this PHP (we have version 8.2) code:
$infusionsoft->data()->findByField(‘Job’, 1, 0, ‘_AmazonOrderNumber’, ‘123556’, [ ‘Id’, ‘ContactId’ ] );

And with further testing using other calls, I get the same error:

Fatal error: Uncaught LogicException:
You cannot use “Http\Message\MessageFactory\DiactorosMessageFactory” as the “php-http/message-factory” package is not installed. Try running “composer require php-http/message-factory”. Note that this package is deprecated, use “psr/http-factory” instead in /redacted-path/vendor/php-http/message/src/MessageFactory/DiactorosMessageFactory.php:13
Stack trace:
#0 /redacted-path/vendor/composer/ClassLoader.php(571): include()
#1 /redacted-path/vendor/composer/ClassLoader.php(428): Composer\Autoload\includeFile(‘/redacted-path…’)
#2 /redacted-path/vendor/infusionsoft/php-sdk/src/Infusionsoft/Http/GuzzleHttpClient.php(45): Composer\Autoload\ClassLoader->loadClass(‘Http\Message\Me…’)
#3 /redacted-path/vendor/infusionsoft/php-sdk/src/Infusionsoft/Http/InfusionsoftSerializer.php(26): Infusionsoft\Http\GuzzleHttpClient->getXmlRpcTransport()
#4 /redacted-path/vendor/infusionsoft/php-sdk/src/Infusionsoft/Infusionsoft.php(456): Infusionsoft\Http\InfusionsoftSerializer->request(‘DataService.fin…’, ‘https://api.inf…’, Array, Object(Infusionsoft\Http\GuzzleHttpClient))
#5 /redacted-path/vendor/infusionsoft/php-sdk/src/Infusionsoft/Api/DataService.php(60): Infusionsoft\Infusionsoft->request(‘DataService.fin…’, ‘Job’, 1, 0, ‘_AmazonOrderNum…’, ‘123556’, Array)
#6 /redacted-path/keap-auth.php(46): Infusionsoft\Api\DataService->findByField(‘Job’, 1, 0, ‘_AmazonOrderNum…’, ‘123556’, Array)
#7 {main} thrown in /redacted-path/vendor/php-http/message/src/MessageFactory/DiactorosMessageFactory.php on line 13

Both dependencies are present in the vendor folder. I’m not sure what to do to fix this. Help?

If it’s helpful, here is the directory structure of my vendor folder:

28 ./laminas/laminas-diactoros/src/ServerRequestFilter
44 ./laminas/laminas-diactoros/src/Response
68 ./laminas/laminas-diactoros/src/Exception
72 ./laminas/laminas-diactoros/src/functions
16 ./laminas/laminas-diactoros/src/Request
384 ./laminas/laminas-diactoros/src
408 ./laminas/laminas-diactoros
412 ./laminas
28 ./php-http/discovery/src/Strategy
28 ./php-http/discovery/src/Exception
24 ./php-http/discovery/src/Composer
144 ./php-http/discovery/src
176 ./php-http/discovery
8 ./php-http/guzzle7-adapter/src/Exception
20 ./php-http/guzzle7-adapter/src
52 ./php-http/guzzle7-adapter
16 ./php-http/promise/src
36 ./php-http/promise
12 ./php-http/httplug/src/Promise
24 ./php-http/httplug/src/Exception
52 ./php-http/httplug/src
80 ./php-http/httplug
16 ./php-http/message/src/Formatter
8 ./php-http/message/src/Builder
40 ./php-http/message/src/Authentication
16 ./php-http/message/src/RequestMatcher
16 ./php-http/message/src/StreamFactory
16 ./php-http/message/src/UriFactory
8 ./php-http/message/src/Exception
8 ./php-http/message/src/Encoding/Filter
52 ./php-http/message/src/Encoding
20 ./php-http/message/src/Decorator
12 ./php-http/message/src/Stream
16 ./php-http/message/src/MessageFactory
268 ./php-http/message/src
312 ./php-http/message
660 ./php-http
8 ./infusionsoft/php-sdk/src/Infusionsoft/FrameworkSupport/Lumen
8 ./infusionsoft/php-sdk/src/Infusionsoft/FrameworkSupport/Laravel/config
20 ./infusionsoft/php-sdk/src/Infusionsoft/FrameworkSupport/Laravel
32 ./infusionsoft/php-sdk/src/Infusionsoft/FrameworkSupport
28 ./infusionsoft/php-sdk/src/Infusionsoft/Http
36 ./infusionsoft/php-sdk/src/Infusionsoft/Api/Rest/Traits
140 ./infusionsoft/php-sdk/src/Infusionsoft/Api/Rest
220 ./infusionsoft/php-sdk/src/Infusionsoft/Api
320 ./infusionsoft/php-sdk/src/Infusionsoft
572 ./infusionsoft/php-sdk/src
20 ./infusionsoft/php-sdk/tests/Infusionsoft
28 ./infusionsoft/php-sdk/tests
8 ./infusionsoft/php-sdk/docker-nginx-config
20 ./infusionsoft/php-sdk/samples
796 ./infusionsoft/php-sdk
800 ./infusionsoft
24 ./clue/stream-filter/src
8 ./clue/stream-filter/.github
60 ./clue/stream-filter
64 ./clue
8 ./guzzlehttp/psr7/src/Exception
288 ./guzzlehttp/psr7/src
344 ./guzzlehttp/psr7
44 ./guzzlehttp/guzzle/src/Exception
44 ./guzzlehttp/guzzle/src/Cookie
92 ./guzzlehttp/guzzle/src/Handler
332 ./guzzlehttp/guzzle/src
496 ./guzzlehttp/guzzle
92 ./guzzlehttp/promises/src
128 ./guzzlehttp/promises
972 ./guzzlehttp
136 ./composer
12 ./lstrojny/fxmlrpc/src/fXmlRpc/Value
20 ./lstrojny/fxmlrpc/src/fXmlRpc/Transport
20 ./lstrojny/fxmlrpc/src/fXmlRpc/Serializer
44 ./lstrojny/fxmlrpc/src/fXmlRpc/Exception
36 ./lstrojny/fxmlrpc/src/fXmlRpc/Parser
32 ./lstrojny/fxmlrpc/src/fXmlRpc/Timing
12 ./lstrojny/fxmlrpc/src/fXmlRpc/CodeGenerator
220 ./lstrojny/fxmlrpc/src/fXmlRpc
224 ./lstrojny/fxmlrpc/src
8 ./lstrojny/fxmlrpc/.github/workflows
12 ./lstrojny/fxmlrpc/.github
4 ./lstrojny/fxmlrpc/vendor
260 ./lstrojny/fxmlrpc
264 ./lstrojny
24 ./symfony/deprecation-contracts
28 ./symfony
28 ./psr/http-factory/src
44 ./psr/http-factory
68 ./psr/http-message/src
24 ./psr/http-message/docs
112 ./psr/http-message
36 ./psr/log/src
52 ./psr/log
20 ./psr/http-client/src
40 ./psr/http-client
252 ./psr
8 ./ralouphie/getallheaders/src
24 ./ralouphie/getallheaders
28 ./ralouphie

I have a seeing that the Keap’s PHP SDK is not being kept up-to-date with the latest versions of PHP.
Only just recently they approved an issue that tackles PHP v8.1 Support - Upgrade to php 8.1 and psr/log 3 by mfadul24 · Pull Request #297 · infusionsoft/infusionsoft-php · GitHub

If you can downgrade your PHP to v8.1, then maybe the SDK will work. Otherwise, if you attempt to upgrade the libraries to the latest versions that support PHP v8.2 you may run into other complications.

@TomScott - You need to regularly update Keap’s PHP SDK when newer versions of PHP come out. It is surprising that just recently you approved a Pull Request to handle PHP v8.1. PHP is currently on v8.2, and in a few months time PHP v8.3 will be released. Further changes will be needed to support those versions.

I tried to go down to 8.1 and it still didn’t work. The composer I used was built with 8.2. I guess I’ll try to downgrade!! Thank you.

On a related note, there are some other messages that pop up when using PHP 8.2. These are not all of the messages, just the unique ones.

Deprecated: Return type of Infusionsoft\Api\Rest\RestModel::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in vendor/infusionsoft/php-sdk/src/Infusionsoft/Api/Rest/RestModel.php on line 985

Deprecated: Return type of Infusionsoft\Api\Rest\RestModel::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in vendor/infusionsoft/php-sdk/src/Infusionsoft/Api/Rest/RestModel.php on line 574

Deprecated: Return type of Infusionsoft\InfusionsoftCollection::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in vendor/infusionsoft/php-sdk/src/Infusionsoft/InfusionsoftCollection.php on line 136

Deprecated: Creation of dynamic property Infusionsoft\Api\ContactService::$client is deprecated in vendor/infusionsoft/php-sdk/src/Infusionsoft/Api/AbstractApi.php on line 11

So, I have tried using PHP 8.2, 8.1, 8.0, and 7.4. Can’t use 7.4 because dependencies require 8 or above. When I use any version of 8 I’m back to the same error.

What do I do now??

I used a different server which has composer installed. I set the PHP version, then ran composer, and copied the files to my vendor folder. Is that the correct procedure?

Is my problem with my SDK or with my code?

Hello. Any ideas here? I’m getting rather desperate for solutions. Thank you.

You will find below a PHP Script that uses the raw XML to query the Orders for your specific field.
It is a single use script which uses cURL (Querying) and SimpleXMLElement (Results Parsing).

The “$app” and “$key” variables need to set your Application Name and Legacy API Encrypted Key.

The Amazon Order Number has been specified as a variable “$amazon_order_number”, which is set to a String Type.

It will just return the “Id” and “ContactId” fields in the result.

https://developer.keap.com/docs/xml-rpc/#data-query-a-data-table

<?php

    // Example PHP script to update the Contact Job Title field via the XML-RPC using the Legacy API Encrypted Key.

    ini_set("display_errors", 1);
    ini_set("display_startup_errors", 1);
    error_reporting(E_ALL);

    // API Connection.
    $app = "XXXXX";    // Your Keap Account Name.
    $key = "XXXXX";    // Your API Encrypted Key.

    // Amazon Order Number.
    $amazon_order_number = "123";

    // API Request.
    $request = "<?xml version='1.0' encoding='UTF-8'?>
<methodCall>
  <methodName>DataService.query</methodName>
  <params>
    <param>
      <value><string>{$key}</string></value>
    </param>
    <param>
      <value><string>Job</string></value>
    </param>
    <param>
      <value><int>100</int></value>
    </param>
    <param>
      <value><int>0</int></value>
    </param>
    <param>
      <value><struct>
        <member><name>_AmazonOrderNumber</name>
          <value><string>{$amazon_order_number}</string></value>
        </member>
      </struct></value>
    </param>
    <param>
      <value><array>
        <data>
          <value><string>Id</string></value>
          <value><string>ContactId</string></value>
        </data>
      </array></value>
    </param>
    <param>
      <value><string>Id</string></value>
    </param>
    <param>
      <value><boolean>0</boolean></value>
    </param>
  </params>
</methodCall>";

    $url       = "https://{$app}.infusionsoft.com:443/api/xmlrpc";
    $headers   = [ "Content-Type: text/xml", "Accept-Charset: UTF-8,ISO-8859-1,US-ASCII", "Expect:" ];
    $useragent = "XML-RPC Example";

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSLVERSION, 0);

    $output = curl_exec($ch);

    curl_close($ch);

    // print_r($output);

    $xml = new SimpleXMLElement($output); 

    print_r($xml->params->param->value->array->data);

    // Loop through the Orders.
    foreach($xml->params->param->value->array->data->value as $order)
    {        
        // Loop through the Order Fields.
        foreach($order->struct->member as $field)
        {
            echo $field->name . ' - ' . $field->value->i4 . PHP_EOL;
        }
    }

The SDK would take away a lot of the API complexity here. Unfortunately due to the complexity of incorporating third party libraries they have created a house of cards for it.

Hope the script helps you out.

I think this will help a lot. Where do I obtain the Legacy API Encrypted Key? I tried the one from the developer portal and it’s telling me Invalid Key. I also tried the Service Key and that didn’t seem to work, either.

I sense a breakthrough coming on!!

UPDATE!!! IT WORKED! I FOUND THE KEY AND I GOT IT TO DO A THING!!! Hopefully I can move on from here.