Emo extra causing blank page together with archivist and german umlaut

I use ArchivistGrouper to sort and list resources by month. Now suddenly whenever I have a resource that is published in March, the whole page goes blank.

After checking the error log, I saw:

/core/components/emo/src/Emo.php : 261) PHP warning: foreach() argument must be of type array|object, bool given

So just for testing I disabled the emo plugin and the page loads again, but with one issue: This is a german site so the month March in german contains an “Umlaut”: März. Interestingly enough the month is now displayed like this: M�rz

I don’t have “Umlaut” issues anywhere else on the site, so I don’t think it’s a database collation issue which was my first thought here.

Also I’m not sure what exactly would have emo caused to interfere with the month here (if that’s even happening).

Any ideas?

MODX 2.8.4.-pl
PHP 8.0

The problem seems to be the function strftime that doesn’t return UTF-8.

Try adding utf8_encode() on the 3(!) lines in the snippet ArchivistGrouper, where the month name gets extracted from the date.

For example:

$resourceArray['month_name'] = utf8_encode(strftime('%B',$dateObj));

on this line:

1 Like

Thanks a lot, your solution works great to fix the broken “Umlaut”!

Why would the emo extra interfere with this though?

The emo plugin runs on every page, to search for email addresses and obfuscate them.
The wrong encoding seems to create an error in the emo code.

So actually emo still crashes the page, even though the encoding is now correct…

@jako maybe?

I can’t reproduce this.

I can see that the emo plugin fails if M�rz is wrong, but it works if the encoding is fixed.


The problem in the plugin is, that when preg_split on this line fails for some reason,

the plugin returns an empty string.

You could “fix” it by checking the return value $parts and returning the original content if an error occurred.

if ($parts === false){
	// An error happened in preg_split. Return the original content.
	// Potential email addresses are not obfuscated!!
	return $content;
}

But then potential email addresses on the page are not obfuscated.

Another way to fix this, is maybe to try to detect wrong encodings and converting them before preg_split is called.

Interesting… I can basically toggle the page by changing the date of the one resource to either march or anything else…

Anything else I can/should check on my end? Error log still creates the same error as mentioned above.

I think I will just skip on using emo for now. I tried excluding the resource through the selection_range system setting, which did nothing and also putting <!-- emo-exclude --> around my archivistGrouper tag didn’t help.

There still has to be some wrong/mixed encoding in the output from “ArchivistGrouper”.

I can’t reproduce this either.
It works when I set emo.selection_range to the resource ID and emo.selection_type to “exclude”.

Searching for these tags in the content, is exactly the part in the code where the error happens.

Not from the ArchivistGrouper but the general resource preview generated by pdoPage/pdoResources also contains a wrong encoding, where I put:

[[+publishedon:date=`%d. %B %Y`]]

in the tpl chunk. Where would I fix that?

That’s my bad, I didn’t get, that this is “2-part-system-setting”. Now it works.

The built-in output modifier date uses the PHP function strftime as well.

As the function strftime is deprecated (see also this thread), it’s probably a good idea to write a custom output modifier (similar to the one from this thread.)

For example a snippet “mydate” like this:

<?php
// snippet call [[+publishedon:mydate=`dd. MMMM y`]]
$input = !empty($input) ? strtotime($input) : '';
$pattern = !empty($options) ? $options : 'dd. MM. y';
$formatter = new IntlDateFormatter('de-DE', NULL, NULL);
$formatter->setPattern($pattern); 
$output = $formatter->format($input); 
return $output;
1 Like

Thank you for the example! I created the snippet but when I use it as stated in the commented section, I still only get a timestamp as an output: 1615895880.

Sorry, my bad.
I tested it with [[*publishedon]] (that is a formatted string) and not with the pdoResources placeholder [[+publishedon]] (that is a number).

So strtotime() has to be executed conditionally:

$input = !empty($input) ? $input : '';
$pattern = !empty($options) ? $options : 'dd. MM. y';

if (!is_numeric($input)) {
	$input = strtotime($input);
}

$formatter = new \IntlDateFormatter('de-DE', NULL, NULL);
$formatter->setPattern($pattern); 
$output = $formatter->format($input); 
return $output;

Also, if you use de_DE.UTF-8 for the locale instead of something like de_DE, it should resolve the whole encoding issue (and probably this entire thread).

2 Likes

You’re a legend! Everything looks perfect now, thank you very much!

I have added this info into the emo docs.

1 Like

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.