/** * Inline the CSS before an email is sent. * * @param \Swift_Events_SendEvent $evt */ public function beforeSendPerformed(\Swift_Events_SendEvent $evt) { $message = $evt->getMessage(); if ($message->getContentType() === 'text/html' || $message->getContentType() === 'multipart/alternative' && $message->getBody()) { $this->inliner->setHtml($message->getBody()); $message->setBody($this->inliner->emogrify()); } foreach ($message->getChildren() as $part) { if (strpos($part->getContentType(), 'text/html') === 0) { $this->inliner->setHtml($part->getBody()); $message->setBody($this->inliner->emogrify()); } } }
/** * @test */ public function emogrifierNotMapsCssToHtmlIfFeatureIsNotEnabled() { $css = 'img {float: right;}'; $this->subject->setHtml($this->html5DocumentType . '<html><body><img></body></html>'); $this->subject->setCss($css); $html = $this->subject->emogrify(); self::assertNotContains('<img align="right', $html); }
/** * @test * @param string $attribute the class attribute value * @dataProvider cssClassesWithWhitespaceDataProvider */ public function emogrifierMapsClassWithWiteSpaceInAttribute($attribute) { $css = '.test {color: red;}'; $this->subject->setHtml($this->html5DocumentType . '<html><body><div class="' . $attribute . '"></div></body></html>'); $this->subject->setCss($css); $html = $this->subject->emogrify(); self::assertContains('style="color: red;"', $html); }
/** * @test */ public function emptyMediaQueriesAreRemoved() { $emptyQuery = '@media all and (max-width: 500px) { }'; $this->subject->setCss($emptyQuery); $this->subject->setHtml($this->html5DocumentType . '<html><body><p></p></body></html>'); $result = $this->subject->emogrify(); self::assertNotContains($emptyQuery, $result); }
/** * @test * @param string $body The HTML * @param string $css The complete CSS * @param string $tagName The name of the tag that should be modified * @param string $attributes The attributes that are expected on the element * * @dataProvider cssToHtmlMappingDataProvider */ public function emogrifierMapsCssToHtml($body, $css, $tagName, $attributes) { $this->subject->setHtml($this->html5DocumentType . '<html><body>' . $body . '</body></html>'); $this->subject->setCss($css); $this->subject->enableCssToHtmlMapping(); $html = $this->subject->emogrify(); self::assertContains('<' . $tagName . ' ' . $attributes, $html); }
/** * @test */ public function emogrifierAddsCopyOfCssStylesAsStyleNode() { $this->subject->appendStylesToHead(); $this->subject->setCss('p { color: blue; }'); $this->subject->setHtml($this->html5DocumentType . '<html><body><style type="text/css">p { padding: 10px; }</style><p></p></body></html>'); $result = $this->subject->emogrify(); self::assertContains('p { color: blue; }', $result); self::assertContains('p { padding: 10px; }', $result); }
/** * @test * @param string $dataUriMediaType * @dataProvider dataUriMediaTypeDataProvider */ public function dataUrisAreConserved($dataUriMediaType) { $html = $this->html5DocumentType . '<html></html>'; $this->subject->setHtml($html); $styleRule = 'background-image: url(data:image/png' . $dataUriMediaType . ',iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAABUk' . 'lEQVQ4y81UsY6CQBCdWXBjYWFMjEgAE0piY8c38B9+iX+ksaHCgs5YWEhIrJCQYGJBomiC7lzhVcfqEa+5KXfey3s783bRdd00TR' . 'VFAQAAICJEhN/q8Xjoug7D4RA+qsFgwDjn9QYiTiaT+Xx+OByOx+NqtapjWq0WjEajekPTtCAIiIiIyrKMoqiOMQxDlVqyLMt1XQ' . 'A4nU6z2Wy9XkthEnK/3zdN8znC/X7v+36WZfJ7120vFos4joUQRHS5XDabzXK5bGrbtu1er/dtTFU1TWu3202VHceZTqe3242Itt' . 'ut53nj8bip8m6345wLIQCgKIowDIuikAoz6Wm3233mjHPe6XRe5UROJqImIWPwh/pvZMbYM2GKorx5oUw6m+v1miTJ+XzO8/x+v7' . '+UtizrM8+GYahVVSFik9/jxy6rqlJN02SM1cmI+GbbQghd178AAO2FXws6LwMAAAAASUVORK5CYII=);'; $this->subject->setCss('html {' . $styleRule . '}'); $result = $this->subject->emogrify(); self::assertContains('<html style="' . $styleRule . '">', $result); }
/** * @test */ public function ignoresWhitespaceAfterImportant() { $css = 'p { margin: 1px !important' . self::LF . ' ;}'; $html = $this->html5DocumentType . self::LF . '<html><head</head><body><p style="margin: 2px; ">some content</p></body></html>'; $expected = '<p style="margin: 1px !important;">'; $this->subject->setHtml($html); $this->subject->setCss($css); self::assertContains($expected, $this->subject->emogrify()); }
/** * @test */ public function emogrifyMergesCssWithMixedUnits() { $css = 'p { margin: 1px; padding-bottom:0;}'; $html = $this->html5DocumentType . self::LF . '<html><head><style>#topWrap p {margin:0;padding-bottom: 1px;}</style></head>' . '<body><div id="topWrap"><p style="text-align: center;">some content</p></div></body></html>'; $expected = '<p style="text-align: center; margin: 0; padding-bottom: 1px;">'; $this->subject->setHtml($html); $this->subject->setCss($css); $this->assertContains($expected, $this->subject->emogrify()); }
/** * @param array $data * * @throws \TijsVerkoyen\CssToInlineStyles\Exception */ protected function setHtml(array $data) { $html = view('emails.' . $this->template, ['user' => $this->user, 'data' => $data])->render(); $css = file_get_contents(asset('assets/css/bootstrap.css')); libxml_use_internal_errors(true); $emogrifier = new Emogrifier(); $emogrifier->setHtml($html); $emogrifier->setCss($css); $this->html = $emogrifier->emogrify(); }