0

I'm getting this error when trying to send email from within my Laravel 5.1 application. This function was working quite well for a very long time, but I stopped using my application for about a year and now when I try to use it I'm getting this error. I don't think I've made any changes to anything related to emails, so I'm not sure what the cause could be.

Here is what my composer.json looks like:

    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.1.*",
        "barryvdh/laravel-ide-helper": "^2.1",
        "laravelcollective/html": "5.1.*",
        "nesbot/carbon": "1.39.*",
        "intervention/image": "^2.3",
        "fzaninotto/faker": "^1.7",
        "bugsnag/bugsnag-laravel": "^2.0",
        "silber/bouncer": " v1.0.0-rc.4",
        "doctrine/dbal": "v2.9",
        "spatie/laravel-medialibrary": "^4.0.0",
        "rap2hpoutre/laravel-log-viewer": "^2.2"
    },
    "require-dev": {
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~4.0",
        "phpspec/phpspec": "~2.1"
    },

EDIT:

Here is what the MailgunTransport.php file looks like:

<?php

namespace Illuminate\Mail\Transport;

use Swift_Mime_Message;
use GuzzleHttp\Post\PostFile;
use GuzzleHttp\ClientInterface;

class MailgunTransport extends Transport
{
    /**
     * Guzzle client instance.
     *
     * @var \GuzzleHttp\ClientInterface
     */
    protected $client;

    /**
     * The Mailgun API key.
     *
     * @var string
     */
    protected $key;

    /**
     * The Mailgun domain.
     *
     * @var string
     */
    protected $domain;

    /**
     * THe Mailgun API end-point.
     *
     * @var string
     */
    protected $url;

    /**
     * Create a new Mailgun transport instance.
     *
     * @param  \GuzzleHttp\ClientInterface  $client
     * @param  string  $key
     * @param  string  $domain
     * @return void
     */
    public function __construct(ClientInterface $client, $key, $domain)
    {
        $this->key = $key;
        $this->client = $client;
        $this->setDomain($domain);
    }

    /**
     * {@inheritdoc}
     */
    public function send(Swift_Mime_Message $message, &$failedRecipients = null)
    {
        $this->beforeSendPerformed($message);

        $options = ['auth' => ['api', $this->key]];

        $to = $this->getTo($message);

        $message->setBcc([]);

        if (version_compare(ClientInterface::VERSION, '6') === 1) {
            $options['multipart'] = [
                ['name' => 'to', 'contents' => $to],
                ['name' => 'message', 'contents' => $message->toString(), 'filename' => 'message.mime'],
            ];
        } else {
            $options['body'] = [
                'to' => $to,
                'message' => new PostFile('message', $message->toString()),
            ];
        }

        return $this->client->post($this->url, $options);
    }

    /**
     * Get the "to" payload field for the API request.
     *
     * @param  \Swift_Mime_Message  $message
     * @return array
     */
    protected function getTo(Swift_Mime_Message $message)
    {
        $formatted = [];

        $contacts = array_merge(
            (array) $message->getTo(), (array) $message->getCc(), (array) $message->getBcc()
        );

        foreach ($contacts as $address => $display) {
            $formatted[] = $display ? $display." <$address>" : $address;
        }

        return implode(',', $formatted);
    }

    /**
     * Get the API key being used by the transport.
     *
     * @return string
     */
    public function getKey()
    {
        return $this->key;
    }

    /**
     * Set the API key being used by the transport.
     *
     * @param  string  $key
     * @return string
     */
    public function setKey($key)
    {
        return $this->key = $key;
    }

    /**
     * Get the domain being used by the transport.
     *
     * @return string
     */
    public function getDomain()
    {
        return $this->domain;
    }

    /**
     * Set the domain being used by the transport.
     *
     * @param  string  $domain
     * @return void
     */
    public function setDomain($domain)
    {
        $this->url = 'https://api.mailgun.net/v3/'.$domain.'/messages.mime';

        return $this->domain = $domain;
    }
}

Please note that this file is generated from the Mailgun source code, nothing in that file was created by me.

Line 67 is this one:

if (version_compare(ClientInterface::VERSION, '6') === 1)

After running composer update as suggested in the replies, I get the following warnings:

Package anahkiasen/underscore-php is abandoned, you should avoid using it. No replacement was suggested.
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Package jakub-onderka/php-console-color is abandoned, you should avoid using it. Use php-parallel-lint/php-console-color instead.
Package jakub-onderka/php-console-highlighter is abandoned, you should avoid using it. Use php-parallel-lint/php-console-highlighter instead.
Package jeremeamia/superclosure is abandoned, you should avoid using it. Use opis/closure instead.
Package mtdowling/cron-expression is abandoned, you should avoid using it. Use dragonmantank/cron-expression instead.
Package patchwork/utf8 is abandoned, you should avoid using it. Use symfony/polyfill-mbstring or symfony/string instead.
Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
Package symfony/debug is abandoned, you should avoid using it. Use symfony/error-handler instead.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.

I'm wondering if maybe the swiftmailer is causing the issue...I'm not sure how to get it to use symfony mailer as recommended.

Andrew Fox
  • 794
  • 4
  • 13
  • 30
  • 1
    Where does MailgunTransport.php come from? I see nothing in your composer.json related to Mailgun. – Olivier Sep 14 '22 at 07:21
  • It’s built into the Laravel framework. I only included the composer file to show what versions of PHP and Laravel (etc.) that I’m using. – Andrew Fox Sep 14 '22 at 15:36
  • We need MailgunTransport.php or at minimum line 65-69 of it along with any definitions of VERSION in that file or others. – James Risner Sep 14 '22 at 19:02
  • @JamesRisner I’m not sure what you mean – Andrew Fox Sep 15 '22 at 01:26
  • 2
    Your title: FatalThrowableError in MailgunTransport.php line 67: Undefined class constant 'VERSION' --- Indicates an issue on line 67 of MailgunTransport.php. We would need to see at minimum line 67. Preferably most if not all. – James Risner Sep 15 '22 at 01:41
  • 3
    We need more information like what you have already tried and what's in `MailgunTransport.php` file. – Myo Win Sep 16 '22 at 16:22
  • Very sorry for the delay, I've added the `MailgunTransport.php` file contents as requested. – Andrew Fox Sep 21 '22 at 05:39

1 Answers1

2

Because you said it was fine before, seems like you just need to update dependencies to their minor updates.

  1. Firstly, backup your composer.json file and run composer update and see it helps.
  2. If it doesn't help, you might need to install Guzzle. According to laravel doc,
    • you need to add "guzzlehttp/guzzle": "~5.3|~6.0" to your composer.json

    • delete composer.lock file

    • and run composer install

With composer.lock file presence, composer install will only look into that file and install versions defined in there.

enter image description here

  1. If it still not help, just replace the backed-up composer.json back and run composer install to rollback your dependencies. Then show me MailgunTransport.php file for further investigation.
Myo Win
  • 483
  • 1
  • 6
  • 17
  • Running composer update did not help, although it did give me some error messages (added to my question) and now I wonder if swiftmailer isn't the issue, it says it's abandoned and to use symfony mailer instead. Also, I think Guzzle is installed with Laravel, because it does exist in the vendor file but it isn't in the composer.json file. Currently it's showing version 7.4.5 installed. – Andrew Fox Sep 21 '22 at 05:44
  • There you go! The doc suggested version of guzzle is `"guzzlehttp/guzzle": "~5.3|~6.0"` but you said you have `7.4.5` installed. Downgrade the guzzle by adding `"guzzlehttp/guzzle": "~5.3|~6.0"` to your `composer.json` and run `composer install` to install the defined version. Since the doc mentioned `~`, guzzlehttp version should not be larger than 5.4 or 6.1. Read more about the versions here https://stackoverflow.com/a/22345808/2218290 – Myo Win Sep 21 '22 at 08:30
  • I did as you suggested but I get the same error. My vendor folder is also showing the same version as before, is there a way to confirm which version is installed? – Andrew Fox Sep 21 '22 at 15:21
  • Also, do you know how my version would go up to 7.4.5? Since I didn't have it in my composer file previously, I thought it was part of the Laravel package, which I assumed would control which versions of the dependencies would be installed, no? – Andrew Fox Sep 21 '22 at 15:22
  • 1
    You can use `composer show -i | grep guzzlehttp/guzzle` command to see the installed guzzle version. "which I assumed would control which versions of the dependencies would be installed, no?" Yes, your app's dependencies can have their own dependencies with their defined `composer.json` files. You can find them in packages' folder. – Myo Win Sep 21 '22 at 15:30
  • 1
    @AndrewFox As you can see [here](https://github.com/guzzle/guzzle/blob/a52f0440530b54fa079ce76e8c5d196a42cad981/src/ClientInterface.php#L13), `ClientInterface::VERSION` was deprecated in version 6 and removed in 7. – Olivier Sep 21 '22 at 19:22
  • I understand what you're saying, thank you for taking the time to reply. I'm not sure how I can force the version of Guzzle to be less than 7.4.5. After I added the specific version needed in my composer.json and installed everything, it was still that newer version. I assume that's because something else is controlling which version gets installed. – Andrew Fox Sep 22 '22 at 05:17
  • I just tried adding the version to my composer.json file again, and then running `composer update`, and it's now working! THANK YOU!!! Bounty coming your way tomorrow – Andrew Fox Sep 22 '22 at 05:46
  • 1
    Glad to hear! I realized what happened. `composer.lock` file must be deleted before running `composer install`. I will add it in the answer. – Myo Win Sep 22 '22 at 06:46