Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

Use quoted_printable_encode() if available for performance reasons #217

Merged
merged 2 commits into from Jul 1, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/including-the-files.rst
Expand Up @@ -28,3 +28,14 @@ To use Swift Mailer's autoloader:
require_once '/path/to/swift-mailer/lib/swift_required.php';

/* rest of code goes here */

For PHP versions starting with 5.3 it is recommended using the native quoted
printable encoder. It uses PHP’s native ``quoted_printable_encode()``-function
to achieve much better performance. To do so, edit ``lib/swift_init.php`` and
add the following line:

.. code-block:: php

Swift_DependencyContainer::getInstance()
->register('mime.qpcontentencoder')
->asAliasOf('mime.nativeqpcontentencoder');
58 changes: 58 additions & 0 deletions lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php
@@ -0,0 +1,58 @@
<?php

class Swift_Mime_ContentEncoder_NativeQpContentEncoder implements Swift_Mime_ContentEncoder
{
/**
* Notify this observer that the entity's charset has changed.
* @param string $charset
*/
public function charsetChanged($charset)
{
if ($charset !== 'utf-8') {
throw new RuntimeException(
sprintf('Charset "%s" not supported. NativeQpContentEncoder only supports "utf-8"', $charset));
}
}

/**
* Encode $in to $out.
* @param Swift_OutputByteStream $os to read from
* @param Swift_InputByteStream $is to write to
* @param int $firstLineOffset
* @param int $maxLineLength - 0 indicates the default length for this encoding
*/
public function encodeByteStream(
Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0,
$maxLineLength = 0)
{
$string = '';

while (false !== $bytes = $os->read(8192)) {
$string .= $bytes;
}

$is->write($this->encodeString($string));
}

/**
* Get the MIME name of this content encoding scheme.
* @return string
*/
public function getName()
{
return 'quoted-printable';
}

/**
* Encode a given string to produce an encoded string.
* @param string $string
* @param int $firstLineOffset if first line needs to be shorter
* @param int $maxLineLength - 0 indicates the default length for this encoding
* @return string
*/
public function encodeString($string, $firstLineOffset = 0,
$maxLineLength = 0)
{
return quoted_printable_encode($string);
}
}
5 changes: 4 additions & 1 deletion lib/dependency_maps/mime_deps.php
Expand Up @@ -82,6 +82,9 @@
-> register('mime.qpcontentencoder')
-> asNewInstanceOf('Swift_Mime_ContentEncoder_QpContentEncoder')
-> withDependencies(array('mime.charstream', 'mime.bytecanonicalizer'))

-> register('mime.nativeqpcontentencoder')
-> asNewInstanceOf('Swift_Mime_ContentEncoder_NativeQpContentEncoder')

-> register('mime.7bitcontentencoder')
-> asNewInstanceOf('Swift_Mime_ContentEncoder_PlainContentEncoder')
Expand All @@ -99,7 +102,7 @@
-> register('mime.rfc2231encoder')
-> asNewInstanceOf('Swift_Encoder_Rfc2231Encoder')
-> withDependencies(array('mime.charstream'))

;

unset($swift_mime_types);
@@ -0,0 +1,101 @@
<?php

require_once 'Swift/Tests/SwiftUnitTestCase.php';
require_once 'Swift/Mime/ContentEncoder/NativeQpContentEncoder.php';
require_once 'Swift/CharacterStream/ArrayCharacterStream.php';
require_once 'Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php';
require_once 'Swift/ByteStream/ArrayByteStream.php';

class Swift_Mime_ContentEncoder_NativeQpContentEncoderAcceptanceTest
extends Swift_Tests_SwiftUnitTestCase
{
/**
* @var Swift_Mime_ContentEncoder_NativeQpContentEncoder
*/
protected $_encoder;

public function setUp()
{
$this->_samplesDir = realpath(dirname(__FILE__) . '/../../../../_samples/charsets');
$this->_encoder = new Swift_Mime_ContentEncoder_NativeQpContentEncoder();
}

public function testEncodingAndDecodingSamples()
{
$sampleFp = opendir($this->_samplesDir);
while (false !== $encodingDir = readdir($sampleFp))
{
if (substr($encodingDir, 0, 1) == '.')
{
continue;
}

$sampleDir = $this->_samplesDir . '/' . $encodingDir;

if (is_dir($sampleDir))
{

$fileFp = opendir($sampleDir);
while (false !== $sampleFile = readdir($fileFp))
{
if (substr($sampleFile, 0, 1) == '.')
{
continue;
}

$text = file_get_contents($sampleDir . '/' . $sampleFile);

$os = new Swift_ByteStream_ArrayByteStream();
$os->write($text);

$is = new Swift_ByteStream_ArrayByteStream();
$this->_encoder->encodeByteStream($os, $is);

$encoded = '';
while (false !== $bytes = $is->read(8192))
{
$encoded .= $bytes;
}

$this->assertEqual(
quoted_printable_decode($encoded), $text,
'%s: Encoded string should decode back to original string for sample ' .
$sampleDir . '/' . $sampleFile
);
}
closedir($fileFp);
}

}
closedir($sampleFp);

}

public function testEncodingAndDecodingSamplesFromDiConfiguredInstance()
{
$encoder = $this->_createEncoderFromContainer();
$this->assertSame('=C3=A4=C3=B6=C3=BC=C3=9F', $encoder->encodeString('äöüß'));
}

public function testCharsetChangeNotImplemented()
{
$this->_encoder->charsetChanged('utf-8');
$this->expectException(new RuntimeException('Charset "charset" not supported. NativeQpContentEncoder only supports "utf-8"'));
$this->_encoder->charsetChanged('charset');
}

public function testGetName()
{
$this->assertSame('quoted-printable', $this->_encoder->getName());
}

// -- Private Methods

private function _createEncoderFromContainer()
{
return Swift_DependencyContainer::getInstance()
->lookup('mime.nativeqpcontentencoder')
;
}

}