V9: anyone tested email service yet?

I’m sending emails:

$mh->from($email_from, 'My Name');
$mh->replyto($email_from);

But the actual email ‘From’ header doesn’t have the email address, only the name:

Screenshot_20211113_201510

If I remove the string from the $mh->from($email_from); the header includes the email address. The replyTo does the same thing: it has an email only without the name.

Has anyone tried sending emails programmatically in v9 yet? That code worked in v8. Now I don’t get any emails although the log says they get sent.

Could anyone check the Mail Service function? I don’t understand how it works. Here’s the PHP online console: PHP Tryit Editor v1.2

The code is from concrete/src/Mail/Service.php
generateEmailStrings()

First it sets a ‘from’ property array with a string of email addresses and a name in
from($email, $name = null).

Second it sends email with sendMail() where it sets the
$fromStr = $this->generateEmailStrings([$this->from]);.

Third the generateEmailStrings makes up a string combining email+name. So I’ve pasted that code in the PHP console and it shows it does some weird stuff which I can’t understand. Hope I’m wrong. Hope you can prove or disprove that.

What I see in that function is the following:

See that line: $v = $arr[$i];

When $i is 0, i.e. $arr[0], the $v is the first array element, i.e. the email address. When $i is 1, i.e. $arr[1], the $v is the second array element, i.e. the name.

Now see the rest of the loop where it uses $v[0] and $v[1] - these are the 1st and 2nd letters of the email and name strings, NOT elements of the array.

So with $i = 0, $v[0] = ‘e’, $v[1] = ‘m’. With $i = 1, $v[0] = ‘M’, $v[1] = ‘y’.

Am I wrong or what?

I think I see where the issue might be. It’s not the loop, the loop and generateEmailStrings are actually fine. As long as the $attr is an array of array. But the $this-> from is a simple array. That’s why I think it breaks.

I think this:

public function from($email, $name = null)
{
      $this->from = [$email, $name];
}

should be changed for this:

public function from($email, $name = null)
{
    $this->from[] = [$email, $name];
}

The generateEmailStrings() expects a 2 dim array (even though it doesn’t make sense IMHO for From and Reply-To.

It’s been that way since at least 8.5.4 (the oldest copy I have available).

The simple solution is to add the array (which if you dig in the code you will see that happen):

$mh->from( [ $email_from, 'My Name' ] );
$mh->replyto( [ $email_from ] );

The tiny un-resizable reply text box is way too short - it’s a real pain when trying to scroll/select code blocks.

Maybe this’ll catch someone who can do something about it…

#discuss #forum #concrete_CMS

No, it throws an error:

“Exception Occurred: /srv/www/htdocs/c9/concrete/src/Mail/Service.php:485 strpos() expects parameter 1 to be string, array given (2)”

Oops, replyto() takes 2 strings ($email, $name = null)

From is handled very weirdly:

Snipped and commented from sendMail(): 553
$fromStr = $this->generateEmailStrings([$this->from]); // wrapped array
$replyStr = $this->generateEmailStrings($this->replyto); // not wrapped

I think either the documentation (Working with the Mail-Service) is correct but the code is wrong. Or the documentation is wrong AND the code doesn’t work.

I haven’t looked at the doc, but my sites are all delivering mail with correct From and Reply-To headers set properly.

So, the code is (and has been working) fine for me on 8.5.4 through 8.5.7.

Did you try just passing 2 strings to mh->replyto() - your error didn’t complain about wrapping $mh->from() …

The API reference is definitely confused about from and replyto :frowning:

https://documentation.concretecms.org/api/8.5.7/Concrete/Core/Mail/Service.html

It doesn’t help the code. Regardless of the documentation I just can’t figure out how it could work given my test at the very top. And even sending the array instead of function parameters doesn’t work.

Ok, I created a test (and believe I found a bug in the process). I have tested this with my own email addresses and Gmail (names have been changed…)

$ms = Core::make('mail');
// $ms->setTesting(true);
$ms->setSubject('Testing email.');
$ms->setBody('This is some mail.');
$ms->setBodyHTML('<p>This is some HTML mail.</p>');

// Bug: passing in [email, name] here causes an exception in concrete/vendor/zendframework/zend-mail/src/Address.php :41
// adding $email to the exception message, shows that the constructor think $name is an email address !!!
$ms->from(['j@j.com']);  // do NOT pass a name

$ms->replyto('j@gmail.com', 'Website Reply');
$ms->to('s@s.com', 'Somebody S.');
$ms->to('a@a.com, b@b.com');
try {
    $ms->sendMail();
}
catch (exception $e) {
    echo $e->getMessage();
}

if (!isset($e)) {
    echo 'Mail sent.';
} else {
    echo 'Mail NOT sent!';
}

Are you testing it on v8? Because I think ZendFramework is removed from v9. I’m testing it on v9 and the email doesn’t work with that setup.

If I do:

$mh->to($email_to);
$mh->from($email_from);
$mh->replyto($email_from);

I get the following email headers (in the Log):

To: xxx@email.com
From: yyy@email.com
Reply-To: Reply-To: =?UTF-8?Q?User=20Name?=

If I do this:

$mh->to($email_to);
$mh->from([$email_from]);
$mh->replyto($email_from, $name);

I get the following email headers (in the Log):

To: xxx@email.com
From: Array
Reply-To: “User Name”

Something’s really stuffed in the Mail Service in v9.

It only works with using only these two:

$mh->to($email_to);
$mh->from($email_from);

Has anyone else tried sending emails programmatically in v9 through the Mail Service?

Sorry Alex,

I didn’t see your v9 reference (my bad). I originally saw it on github issues.

The 5.8+ bug seems to be real, but I haven’t tried v9 with so many bugs still being reported on git.

I normally don’t try new releases for this very reason.

Ignored notices/warnings slow PHP down too much, but not as bad as the massive SQL joins.

I’m following this thread, and hope you find an answer!

Thank you, John, for confirming that. At least on this occasion I was not insane (as opposed to my blunder with the ajax checkbox the other day :grinning: )

You’re welcome Alex. I saw that, but at least you owned it.

“Been there, done that.”

You might be insane, but I have no proof of that. :stuck_out_tongue_winking_eye:

:+1: :grinning: :grinning: :grinning:

Every time when the error feels the most stupid it’s 99% chance it is

Hehe. Just FYI, $fromStr is used in the default concrete logs, not the actual $from email address.

I’m not sure why, but it might be some kind of “security” by obfuscation.

I think I’d add my own logging of the actual headers/body while trying to debug this…

There seems to be some confusion in this thread, hopefully this will help.

  1. The mail service works in v9. We have active production sites running v9. If emails didn’t work we’d hear about it.
  2. I just tested the mail service by running a “forgot password” on my local develop branch site. I received an email just fine.
  3. Perhaps there’s something a bit strange with the email logging functionality – LOGGING being the keyword. When you say something about emails not working people are going to be a bit more concerned than when you say the LOGGING functionality isn’t working.
  4. In these cases it’s always good to test using something that you’re pretty sure works, rather than any custom code you’ve developed (which you might be less sure about, since you just wrote it.) We have a “Test Mail Settings” Dashboard page in the System and Settings section of the Dashboard that can be very useful for testing your SMTP settings, and other email related functionality (logging, etc…)
  5. That being said, I see no indication that email logging isn’t working. My forgot password test works just fine and appears in the logs. There is a bit of work being done in the logging to log any email parts that you have, so I’m not exactly sure why from email address appears as just the string in the plain text portion, but I don’t think it’s indicative of anything not working the way it’s supposed to.
  6. When looking at the docs, I think you might be getting confused between the from method and from property. Ignore the property. The property is not what you want. The method is what you want. The method takes a string for the from email address, and an option name to go along with it.

The array approach for things like to() and replyto() is for a very simple reason – you can have multiple recipients of an email and multiple people on the replyto, but you can only have a single “from” email/name on an email. So. don’t use an email when setting the from().

So this?

$mail->from('andrew@concretecms.com', 'Andrew');

Good. This?

$mail->from(['andrew@concretecms.com', 'Andrew']);

Bad. Email can only be “from” one person, so it doesn’t take an array.

I hope this helps. Again, it’s very possible that a bug exists somewhere, but I don’t think this is a result of a bug.