sendgrid / sendgrid-php

The Official Twilio SendGrid PHP API Library
https://sendgrid.com
MIT License
1.49k stars 623 forks source link

include plugin as library to 3rd party plugin #1005

Closed loretoparisi closed 4 years ago

loretoparisi commented 4 years ago

Issue Summary

When included sendgrid-php plugin within another plugin as a library, a Cannot declare class error comes out.

Steps to Reproduce

  1. Install the sendgrid-php plugin
  2. Include the plugin in a new plugin folder and upload zip to WordPress

Code Snippet

To avoid the error, I'm currently using this check:

// include sendgrid sdk
if( class_exists('\\SendGrid\\Email') === false ) {
    // when used globally \\SendGrid\\Email
    // when importing with "use" Sendgrid
    require_once dirname(__FILE__) . "/sendgrid-php/sendgrid-php.php";
}

Exception/Log

Fatal error: Cannot declare class SendGrid\Email, because the name is already in use in /home/loretoparisi/staging/3/wp-content/plugins/sendgrid-email-delivery-simplified/vendor/sendgrid-php/SendGrid/Email.php on line 5
There has been a critical error on your website. Please check your site admin email inbox for instructions.

Technical details:

I have posted more details on SF here.

loretoparisi commented 4 years ago

[UPDATE] I have successfully renamed the SendGrid class and namespace to SendGridSDK, thus the "external" (i.e. directly installed from Wordpress) plugin works fine. The problem is the "internal" (ie. the one used as a library in my plugin) has an error, related to Composer I assume. Let's consider that I have already installed of Composer requirements locally, so my directory looks like:

.
├── lib
│   ├── SendGridSDK.php
│   └── helpers
│       └── mail
│           ├── Mail.php
│           └── README.md
├── sendgrid-php.php
└── vendor
    ├── autoload.php
    ├── bin
    ├── composer
    │   ├── ClassLoader.php
    │   ├── LICENSE
    │   ├── autoload_classmap.php
    │   ├── autoload_files.php
    │   ├── autoload_namespaces.php
    │   ├── autoload_psr4.php
    │   ├── autoload_real.php
    │   ├── autoload_static.php
    │   └── installed.json
    └── sendgrid
        └── php-http-client
            ├── CHANGELOG.md
            ├── CONTRIBUTING.md
            ├── LICENSE.txt
            ├── README.md
            ├── examples
            │   └── example.php
            └── lib
                ├── Client.php
                └── Response.php

The error is Fatal error: Uncaught Error: Class 'SendGridSDK\Client' not found in thrown in /home/loretoparisi/staging/2/wp-content/plugins/loretoparisi_admin/sendgrid-php/lib/SendGridSDK.php on line 53, where the Client is called:

    $this->client = new \SendGridSDK\Client($host, $headers, '/v3', null, $curlOptions);

I have also refactored the class Client and Response to match the right namespace:

namespace SendGridSDK;

/**
  * Quickly and easily access any REST or REST-like API.
  */
class Client
{
...

Also for the Composer auto loader classes:

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'SendGridSDK\\' => array($vendorDir . '/sendgrid/php-http-client/lib'),
);

So, since I have all files locally, why The ClassLoader cannot import the class SendGridSDK\Client?

childish-sambino commented 4 years ago

Recommend upgrading to a later, supported version of this library which may resolve the issue you're seeing. Latest is 7.8.3.

loretoparisi commented 4 years ago

@childish-sambino thank you. By the way, in the meantime I have fixed the old one just removing Composer and including libraries manually:

.
├── Wrapper
│   ├── Php.php
│   ├── Wordpress.php
│   └── WordpressCli.php
├── sendgrid-php
│   ├── lib
│   │   ├── Client.php
│   │   ├── Mail.php
│   │   ├── Response.php
│   │   └── SendGridSDK.php
│   └── sendgrid-php.php
├── test.php

where sendgrid-php.php looks like:

<?php
require __DIR__ ."/lib/Client.php";
require __DIR__ ."/lib/Response.php";
require __DIR__ ."/lib/Mail.php";
require __DIR__ ."/lib/SendGridSDK.php";
?>