Ecodev / newsletter

TYPO3 extension to send newsletter
https://extensions.typo3.org/extension/newsletter/
25 stars 26 forks source link

No output of $content, $newsletter is not being created. Error: The newsletter could not be found :-( #148

Closed bucheggerOnline closed 5 years ago

bucheggerOnline commented 6 years ago

Typo3: 8.7.8 Newsletter: 3.2.0 PHP: 7.1.1 RealUrl disabled URL: /index.php?id=279&type=1342671779&tx_newsletter_p%5Baction%5D=show&tx_newsletter_p%5Bcontroller%5D=Email&pid=279&uidRecipientList=1&plainConverter=Ecodev%5CNewsletter%5CDomain%5CModel%5CPlainConverter%5CBuiltin&injectOpenSpy=1&injectLinksSpy=1&email=matthias%40buchegger.online

There is no output in the BE.plugin as in the sent mail. Error in the BE.plugin is "The newsletter could not be found :-("

I tried to debugg that (EmailController) and the $newsletter doesn't get set. the object is empty in the end. That's why there is no $content.

Before I found out that ['c'] is not in the $args array, which would be provided of $isPreview. That's because it's not given in the URL as argument, I did that manually, but didn't change anything for the output. Of course the $args['c'] is set now.

There is the $newsletter->setPid(@$args['pid']); but there is no function setPid in the NewsletterModel.

        $isPreview = empty($args['c']); // If we don't have an authentification code, we are in preview mode
        // If it's a preview, an email which was not sent yet, we will simulate it the best we can
        if ($isPreview) {
            // Create a fake newsletter and configure it with given parameters
            /** @var Newsletter $newsletter */
            $newsletter = $this->objectManager->get(\Ecodev\Newsletter\Domain\Model\Newsletter::class);
            $newsletter->setPid(@$args['pid']);
            $newsletter->setUidRecipientList(@$args['uidRecipientList']);

            if ($newsletter) {
                // Find the recipient
                $recipientList = $newsletter->getRecipientList();
                $recipientList->init();
                while ($record = $recipientList->getRecipient()) {
                    // Got him
                    if ($record['email'] == $args['email']) {
                        // Build a fake email
                        $email = $this->objectManager->get(\Ecodev\Newsletter\Domain\Model\Email::class);
                        $email->setRecipientAddress($record['email']);
                        $email->setRecipientData($record);
                    }
                }
            }
        } else {
            // Otherwise look for the original email which was already sent
            $email = $this->emailRepository->findByAuthcode($args['c']);
            if ($email) {
                $newsletter = $email->getNewsletter();

                // Here we need to ensure that we have real newsletter instance because of type hinting on \Ecodev\Newsletter\Tools::getConfiguredMailer()
                if ($newsletter instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
                    $newsletter = $newsletter->_loadRealInstance();
                }
            }
        }

Hope we can solve that.

Greetings, Matthias

bucheggerOnline commented 6 years ago

Ok, that wasn't really true. That the argument 'c' isn't there is wanted. $newsletter isn't empty. the problem seems to be the output of $mailer. There is no getHtml() given.

bucheggerOnline commented 6 years ago

Well...

The content would be created perfectly. But I cannot find out where it really should be built.

I'm now in the Validator.php:74 $this->content = $this->getURL($url); would work. But I cannot find where the function gets queried.

in the end $content = ''; is set. so nothing fills it.

    /**
     * Returns the content of the newsletter with validation messages. The content
     * is also "fixed" automatically when possible.
     * @param Newsletter $newsletter
     * @param string $language language of the content of the newsletter (the 'L' parameter in TYPO3 URL)
     * @return array
     */
    public function validate(Newsletter $newsletter, $language = null)
    {
        $this->initializeLang();

        // Reset stuff
        $this->newsletter = $newsletter;
        $this->content = '';
        $this->errors = [];
        $this->warnings = [];
        $this->infos = [];

        // We need to catch the exception if domain was not found/configured properly
        // or if we can't fetch the content (eg: because of improper SSL certificates)
        try {
            $url = $this->newsletter->getContentUrl($language);
            **$this->content = $this->getURL($url);**
        } catch (\Exception $e) {
            $this->errors[] = $e->getMessage();
            return $this->getResult();
        }

        $this->infos[] = sprintf($this->lang->getLL('validation_content_url'), '<a target="_blank" href="' . $url . '">' . $url . '</a>');

        $this->errorTooShort();
        $this->errorPhpWarnings();
        $this->errorPhpErrors();
        $this->errorPageBeingGenerated();
        $this->infoRelativeToAbsolute();
        $this->infoLinkedCss();
        $this->warningJavascript();
        $this->errorImageInCSS();
        $this->warningCssClasses();
        $this->warningCssProperties();
        $this->infoImageAlt();

        return $this->getResult();
    }
bucheggerOnline commented 6 years ago

Ok now I know where's the problem, but I can't see why...

try {
            $url = $this->newsletter->getContentUrl($language);
            $this->content = $this->getURL($url);
        } catch (\Exception $e) {
            $this->errors[] = $e->getMessage();
            return $this->getResult();
        }

Seems to work, but after that $this->content is empty. When I add...

        $url = $this->newsletter->getContentUrl($language);
        $this->content = $this->getURL($url);

after the try {} catch {} it works.

Debugging in the try also works perfect. Debugging in the catch doesn't generate an output, so everything seems to be great. There is no error, so the catch should be active.

Any Idea?

PowerKiKi commented 6 years ago

What does $this->getURL($url); return ? an empty value ? I think you should debug that method further. You will probably find out that your server somehow cannot get its own URL. If you configure TYPO3 to use cURL, then you start trying to see if curl on the command line from your server is able to reach itself.

bucheggerOnline commented 6 years ago

$this->getUrl($url) returns, in the try, the whole html of the wanted pid. But after the try/catch $this->content is empty.

PowerKiKi commented 6 years ago

So:

  1. line 99, $this->content is correct
  2. line 101, code does not go through catch block
  3. line 105, , $this->content is not correct anymore

That seems rather impossible... is that correct ?

bucheggerOnline commented 6 years ago

Yes! 😕 That seems also for me to be impossible, but it is like that. When I thy to debug the catch, there's no debug output, so it's not catching.

I really cannot understand why $this->content is empty after it. But there is the Problem. Of course there is no content in the end, when the variable is empty at that point.

PowerKiKi commented 6 years ago

Can you check all 3 assumptions at the same time, the same HTTP request, without editing the file in between ?

bucheggerOnline commented 6 years ago

Ok that's interesting... I think I debugged it to late. Directly after the try/catch it's working. The problem is $this->infoImageAlt(); . Before content is not empty, after that all content is gone. Screen debug

So I'll debug that now... ;)

bucheggerOnline commented 6 years ago

https://github.com/Ecodev/newsletter/blob/f0842b2351c5dab9c6b22ce30d7d7ae384edf6a1/Classes/Utility/Validator.php#L312

There it's getting lost. But I don't understand that code.

debug pic

From that position on $this->content is lost because $document doesn't get filled.

bucheggerOnline commented 6 years ago

Never used that, but , LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD is the problem. When I delete that $document gets filled and the page is generated.

PowerKiKi commented 6 years ago

Removing those parameters break unit tests. Can you find out if you can keep only one of those parameters ? Also does if removing the @ do you get error/warning messages when the two parameters are used ?

bucheggerOnline commented 6 years ago

I tried that now. Everything I tested is the same as with or without the @

removing one parameter doesn't change anything it's also not changing anything when I change this one parameter to the other. So so parameter is working as single.

it's just working when I remove everything after $prefix . $this->content As I wrote before... for this last version it doesn't change anything with or without the @

PowerKiKi commented 6 years ago

Would you be able to share a stripped down version of your content that will trigger the bug ? If so we could add it as a case for unit testing...

PowerKiKi commented 5 years ago

Closing for lack of feedback. Feel free to re-open with more information.