solspace / craft-freeform

Freeform for Craft: The most reliable form builder that's ready for wherever your project takes you.
https://docs.solspace.com/craft/freeform/v5/
Other
47 stars 59 forks source link

5.5.5 Breaks custom integration #1463

Closed mofman closed 1 month ago

mofman commented 1 month ago

What happened?

An issue has been introduced in 5.5.5 whereby a custom integration which was working in 5.5.4 no longer works.

Reverting to 5.5.4 fixes the problem for us...

Errors and Stack Trace (if available)

`ReflectionException: Class "eyekiller\craftfreeformextensions\Integrations\CRM\Capsule\CapsuleCRMIntegration" does not exist in /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Bundles/Integrations/Providers/IntegrationTypeProvider.php:18
Stack trace:
#0 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Bundles/Integrations/Providers/IntegrationTypeProvider.php(18): ReflectionClass->__construct('eyekiller\\craft...')
#1 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Events/Integrations/RegisterIntegrationTypesEvent.php(42): Solspace\Freeform\Bundles\Integrations\Providers\IntegrationTypeProvider->getTypeDefinition('eyekiller\\craft...')
#2 /Users/andrew/Sites/mahlatini/vendor/eyekiller/craft-freeform-extensions/src/FreeformExtensions.php(41): Solspace\Freeform\Events\Integrations\RegisterIntegrationTypesEvent->addType('eyekiller\\craft...')
#3 [internal function]: eyekiller\craftfreeformextensions\FreeformExtensions->eyekiller\craftfreeformextensions\{closure}(Object(Solspace\Freeform\Events\Integrations\RegisterIntegrationTypesEvent))
#4 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/base/Event.php(312): call_user_func(Object(Closure), Object(Solspace\Freeform\Events\Integrations\RegisterIntegrationTypesEvent))
#5 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Services/Integrations/IntegrationsService.php(63): yii\base\Event::trigger('Solspace\\Freefo...', 'register-integr...', Object(Solspace\Freeform\Events\Integrations\RegisterIntegrationTypesEvent))
#6 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Services/Integrations/IntegrationsService.php(101): Solspace\Freeform\Services\Integrations\IntegrationsService->getAllIntegrationTypes()
#7 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Services/Integrations/IntegrationsService.php(399): Solspace\Freeform\Services\Integrations\IntegrationsService->getAllIntegrations('single')
#8 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Bundles/Integrations/Providers/FormIntegrationsProvider.php(52): Solspace\Freeform\Services\Integrations\IntegrationsService->getForForm(Object(Solspace\Freeform\Form\Types\Regular), 'single', true, NULL)
#9 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Bundles/Integrations/Providers/FormIntegrationsProvider.php(80): Solspace\Freeform\Bundles\Integrations\Providers\FormIntegrationsProvider->getForForm(Object(Solspace\Freeform\Form\Types\Regular), 'single')
#10 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Integrations/Single/JavascriptTest/EventListeners/JavascriptTestBundle.php(189): Solspace\Freeform\Bundles\Integrations\Providers\FormIntegrationsProvider->getSingleton(Object(Solspace\Freeform\Form\Types\Regular), 'Solspace\\Freefo...')
#11 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Integrations/Single/JavascriptTest/EventListeners/JavascriptTestBundle.php(77): Solspace\Freeform\Integrations\Single\JavascriptTest\EventListeners\JavascriptTestBundle->getIntegration(Object(Solspace\Freeform\Form\Types\Regular))
#12 [internal function]: Solspace\Freeform\Integrations\Single\JavascriptTest\EventListeners\JavascriptTestBundle->addJsTestToJson(Object(Solspace\Freeform\Events\Forms\OutputAsJsonEvent))
#13 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/base/Event.php(312): call_user_func(Array, Object(Solspace\Freeform\Events\Forms\OutputAsJsonEvent))
#14 /Users/andrew/Sites/mahlatini/vendor/solspace/craft-freeform/packages/plugin/src/Form/Form.php(824): yii\base\Event::trigger('Solspace\\Freefo...', 'output-as-json', Object(Solspace\Freeform\Events\Forms\OutputAsJsonEvent))
#15 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/helpers/BaseJson.php(179): Solspace\Freeform\Form\Form->jsonSerialize()
#16 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/helpers/BaseJson.php(75): yii\helpers\BaseJson::processData(Object(Solspace\Freeform\Form\Types\Regular), Array, '66b4d46d434a11....')
#17 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/helpers/Json.php(39): yii\helpers\BaseJson::encode(Object(Solspace\Freeform\Form\Types\Regular), 0)
#18 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/web/twig/Extension.php(683): craft\helpers\Json::encode(Object(Solspace\Freeform\Form\Types\Regular), 0)
#19 /Users/andrew/Sites/mahlatini/storage/runtime/compiled_templates/67/6797a9026e8eaa79cf218827af4f65e8.php(57): craft\web\twig\Extension->jsonEncodeFilter(Object(Solspace\Freeform\Form\Types\Regular))
#20 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(394): __TwigTemplate_d4872fec3f342003f435f7541c02af17->doDisplay(Array, Array)
#21 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#22 /Users/andrew/Sites/mahlatini/storage/runtime/compiled_templates/3e/3e7f50bde47f783b4f065fc77801de3f.php(311): Twig\Template->display(Array)
#23 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(394): __TwigTemplate_9c8d89b64b629b5a130062675934e23c->doDisplay(Array, Array)
#24 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#25 /Users/andrew/Sites/mahlatini/storage/runtime/compiled_templates/f7/f7279dbc3ac242228f3c40f91ac81955.php(48): Twig\Template->display(Array, Array)
#26 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(394): __TwigTemplate_33f40e23100a9421293b80cc516e773f->doDisplay(Array, Array)
#27 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#28 /Users/andrew/Sites/mahlatini/storage/runtime/compiled_templates/e9/e943107416ff6014044a3395ae794627.php(48): Twig\Template->display(Array, Array)
#29 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(394): __TwigTemplate_102383a679f20d1b899e83dbd1175521->doDisplay(Array, Array)
#30 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#31 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Template.php(379): Twig\Template->display(Array)
#32 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\Template->render(Array)
#33 /Users/andrew/Sites/mahlatini/vendor/twig/twig/src/Environment.php(280): Twig\TemplateWrapper->render(Array)
#34 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/web/View.php(495): Twig\Environment->render('index', Array)
#35 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/web/View.php(548): craft\web\View->renderTemplate('index', Array)
#36 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/web/TemplateResponseFormatter.php(57): craft\web\View->renderPageTemplate('index', Array, 'site')
#37 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/web/Response.php(1109): craft\web\TemplateResponseFormatter->format(Object(craft\web\Response))
#38 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/web/Response.php(338): yii\web\Response->prepare()
#39 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/web/Response.php(340): craft\web\Response->prepare()
#40 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/web/ErrorHandler.php(136): yii\web\Response->send()
#41 /Users/andrew/Sites/mahlatini/vendor/craftcms/cms/src/web/ErrorHandler.php(192): yii\web\ErrorHandler->renderException(Object(yii\base\ErrorException))
#42 /Users/andrew/Sites/mahlatini/vendor/yiisoft/yii2/base/ErrorHandler.php(323): craft\web\ErrorHandler->renderException(Object(yii\base\ErrorException))
#43 [internal function]: yii\base\ErrorHandler->handleFatalError()
#44 {main}`

How can we reproduce this?

a

Freeform Edition

Pro

Freeform Version

5.5.5

Craft Version

4.11.1

When did this issue start?

After upgrading from older Freeform version

Previous Freeform Version

5.5.4

mofman commented 1 month ago

Seems to be CRMIntegration which are specifically affected

`

<?php

namespace eyekiller\craftfreeformextensions\Integrations\CRM\Capsule;

use Craft;
use DateTime;
use Exception;
use GuzzleHttp\Client;
use Solspace\Freeform\Attributes\Integration\Type;
use Solspace\Freeform\Attributes\Property\Flag;
use Solspace\Freeform\Attributes\Property\Input;
use Solspace\Freeform\Attributes\Property\Input\Special\Properties\FieldMappingTransformer;
use Solspace\Freeform\Attributes\Property\Implementations\FieldMapping\FieldMapItem;
use Solspace\Freeform\Attributes\Property\Implementations\FieldMapping\FieldMapping;
use Solspace\Freeform\Attributes\Property\ValueTransformer;
use Solspace\Freeform\Attributes\Property\VisibilityFilter;
use Solspace\Freeform\Form\Form;
use Solspace\Freeform\Library\Integrations\Types\CRM\CRMIntegration;
use Solspace\Freeform\Library\Exceptions\Integrations\IntegrationException;
use Solspace\Freeform\Library\Integrations\DataObjects\FieldObject;
use Solspace\Freeform\Library\Helpers\IsolatedTwig;

#[Type(
    name: 'Capsule CRM',
    type: Type::TYPE_CRM,
    version: 'v2',
    readme: __DIR__.'/README.md',
    iconPath: __DIR__.'/icon.svg',
)]

class CapsuleCRMIntegration extends CRMIntegration

`

kjmartens commented 1 month ago

Sorry about this @mofman,

We'll check into this shortly. 🙂

gustavs-gutmanis commented 1 month ago

Hi @mofman,

I tried reproducing this issue but for me it all works. I created a new custom integration and registered it via a custom module in the craft installation. It loads and works fine.

I see that the error you get is because the composer autoloader is incapable of finding the class in question. Is it at all possible that the namespace doesn't conform to PSR-4 standards? This could happen if you have a folder that uses different caps letters than your namespace.

Could you please send me a screenshot of the directory structure where the CapsuleCRMIntegration is residing in? And a the code for registering it, maybe it's missing something? The integration loading part was not changed since v5.5.4.

mofman commented 1 month ago

https://www.loom.com/share/7b65dc0a3e824dab9e769bec4d2ea8fd

Screenshot 2024-08-09 at 09 47 32

`

<?php

namespace eyekiller\craftfreeformextensions;

use Craft;
use craft\base\Plugin;
use Solspace\Freeform\Events\Integrations\RegisterIntegrationTypesEvent;
use Solspace\Freeform\Library\Bundles\BundleLoader;
use Solspace\Freeform\Services\Integrations\IntegrationsService;
use eyekiller\craftfreeformextensions\Integrations\CRM\Capsule\CapsuleCRMIntegration;
use eyekiller\craftfreeformextensions\Integrations\Captchas\CloudflareTurnstile\CloudflareTurnstile;
use eyekiller\craftfreeformextensions\Integrations\Captchas\CloudflareTurnstile\CloudflareTurnstileBundle;
use eyekiller\craftfreeformextensions\Integrations\EmailMarketing\ConvertKit\ConvertKitIntegration;
use yii\base\Event;

class FreeformExtensions extends Plugin
{
    public string $schemaVersion = '1.0.0';

    public function init()
    {
        parent::init();

        Event::on(
            IntegrationsService::class,
            IntegrationsService::EVENT_REGISTER_INTEGRATION_TYPES,
            function (RegisterIntegrationTypesEvent $event) {

                // CRM
                $event->addType(CapsuleCRMIntegration::class);

            }
        );

    }

}

`

`

<?php

namespace eyekiller\craftfreeformextensions\Integrations\CRM\Capsule;

use Craft;
use DateTime;
use Exception;
use GuzzleHttp\Client;
use Solspace\Freeform\Attributes\Integration\Type;
use Solspace\Freeform\Attributes\Property\Flag;
use Solspace\Freeform\Attributes\Property\Input;
use Solspace\Freeform\Attributes\Property\Input\Special\Properties\FieldMappingTransformer;
use Solspace\Freeform\Attributes\Property\Implementations\FieldMapping\FieldMapItem;
use Solspace\Freeform\Attributes\Property\Implementations\FieldMapping\FieldMapping;
use Solspace\Freeform\Attributes\Property\ValueTransformer;
use Solspace\Freeform\Attributes\Property\VisibilityFilter;
use Solspace\Freeform\Form\Form;
use Solspace\Freeform\Library\Integrations\Types\CRM\CRMIntegration;
use Solspace\Freeform\Library\Exceptions\Integrations\IntegrationException;
use Solspace\Freeform\Library\Integrations\DataObjects\FieldObject;
use Solspace\Freeform\Library\Helpers\IsolatedTwig;

class CapsuleCRMIntegration extends CRMIntegration
{

}

`

gustavs-gutmanis commented 1 month ago

Very mystical. If you roll back to 5.5.4 it works? I'm not sure this would be the case, but maybe the order in which the plugins are loaded changed? That shouldn't be an issue though, because all of the plugin autoload paths should be pre-built already. Could you try running composer dump-autoload in your craft project directory?

mofman commented 1 month ago

Yes if i role back to 5.5.4 it works.

composer dump-autoload doesnt make any difference, I should also mention this is happening on multiple environments.

I attached a loom to show the breakdown https://www.loom.com/share/7b65dc0a3e824dab9e769bec4d2ea8fd

gustavs-gutmanis commented 1 month ago

Thanks a lot for the loom. Could you show me what your PSR-4 entry is in the composer.json for the extras plugin?

Would it be possible to make a yii module rather than a plugin, to see if there's some race condition?

mofman commented 1 month ago

craft-freeform-extensions.zip

I've attached a skeleton of our plugin, if you wanted to try installing? Notably there is no issues loading the captcha or the email marketing integrations.

gustavs-gutmanis commented 1 month ago

Interesting, I ran into the very same issue. But when I implemented all of the missing methods of the CapsuleCRMIntegration, it started running fine.


    public function checkConnection(Client $client): bool
    {
        return true;
    }

    public function getApiRootUrl(): string
    {
        return '';
    }

    public function fetchFields(string $category, Client $client): array
    {
        return [];
    }

    public function push(Form $form, Client $client): void
    {
        // TODO: Implement push() method.
    }

I implemented these four methods, could you check if any one of them is missing in your class definition? And if it is - please let me know, I might have changed something that should have been backwards compatible.

gustavs-gutmanis commented 1 month ago

I'm very sorry, yes the ::push() method definition has changed from

public function push(Form $form, Client $client): bool;

to

public function push(Form $form, Client $client): void;

Change its return type to void please, this has been a bad oversight on my part.

mofman commented 1 month ago

Yes indeed changing the return type to void and removing any return statements fixes this for me.

gustavs-gutmanis commented 1 month ago

Sorry for the inconvenience, we won't be making breaking changes in minor versions in the future.

mofman commented 1 month ago

No problem, should the exception not be alot more descriptive than it currently is, in this scenario, the current one is very misleading?

gustavs-gutmanis commented 1 month ago

It is strangely misleading, yes, I'll see if that can be improved.