Leyla
Leyla

Reputation: 103

CakePhp 3.x, TCPDF, htmlspecialchars

I´ve installed the plugin "CakePDF" following the documentation: https://github.com/FriendsOfCake/CakePdf

Now I want to build the first PDF and I´ve got the following error:

enter image description here

This is my configuration in the bootstrap.php:

Configure::write('CakePdf', [
    'engine' => 'CakePdf.Tcpdf',
    'margin' => [
        'bottom' => 15,
        'left' => 50,
        'right' => 30,
        'top' => 45
    ],
    'download' => true,
    'encoding' => 'UTF-8'
]);

The only code I´ve written is the following one in the template:

$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);

This is the code from line 68 in functions.php:

function h($text, $double = true, $charset = null)
    {
        if (is_string($text)) {
            //optimize for strings
        } elseif (is_array($text)) {
            $texts = [];
            foreach ($text as $k => $t) {
                $texts[$k] = h($t, $double, $charset);
            }
            return $texts;
        } elseif (is_object($text)) {
            if (method_exists($text, '__toString')) {
                $text = (string)$text;
            } else {
                $text = '(object)' . get_class($text);
            }
        } elseif (is_bool($text)) {
            return $text;
        }

        static $defaultCharset = false;
        if ($defaultCharset === false) {
            $defaultCharset = mb_internal_encoding();
            if ($defaultCharset === null) {
                $defaultCharset = 'UTF-8';
            }
        }
        if (is_string($double)) {
            $charset = $double;
        }
        return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, ($charset) ? $charset : $defaultCharset, $double);
    }

I´m absolutely confused and can´t find any solution. Has anyone an idea?

Upvotes: 6

Views: 4426

Answers (4)

Becheru Petru-Ioan
Becheru Petru-Ioan

Reputation: 331

put back de initial encoding, by extending the TCPDF class, and use the new class:

class TCPDF_repaired extends TCPDF{
    public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
        parent::__construct($orientation, $unit, $format, $unicode, $encoding, $diskcache, $pdfa);
        mb_internal_encoding($this->internal_encoding);
    }
};

Upvotes: 0

lorem monkey
lorem monkey

Reputation: 3992

After trying to find and debug the same error for over an hour, I just reset the value to UTF-8 after the usage of TCPDF - and everything works like before:

$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);

///...create, save, display your pdf

// Reset the encoding forced from tcpdf
mb_internal_encoding('UTF-8');

I also tried resetting it directly after the call of new TCPDF and everything was fine, too. I don't know what could go wrong with this reset :) My PDFs still look the same after this but emails get send again.

Upvotes: 10

ndm
ndm

Reputation: 60463

As you've figured, the problem is/was that the TCPDF class messes with mb_internal_encoding(), which is used in CakePHPs h() function to determine the apps default encoding, in case no explicit one is passed as an argument.

I'm no TCPDF expert, haven't used it in ages, but from a quick look at the current source, I'm having a hard time to understand why it fiddles with the internal encoding at all, since the only mb_* function the library uses, is mb_convert_encoding(), where both encoding arguments are passed, so the internal encoding isn't being used at all. That being said, I'd report this as a bug/issue to the TCPDF developer(s).

Anyways, you are only experiencing this problem because you are using CakePDF the wrong way. There is no need to manually create PDF engine instances, that's what CakePDF automatically does for you, which is pretty much the whole point of the plugin, it abstracts the PDF creation so that you just need to build the proper HTML in your view templates. That way you'll also avoid the encoding problems with TCPDF that you are currently experiencing, as the view template is being rendered before the PDF engine instance is being created.

tl;dr

Long story short, build only the HTML in your view template, and if you actually need to have access to a PDF engine instance because there's something you need to do that can only be achieved that way, then CakePDF is not the plugin you are looking for.

Upvotes: 0

Leyla
Leyla

Reputation: 103

I think, I´ve found the culprit. The constructor method of TCPDF sets the mb_internal_encoding to ASCII. (tcpdf.php line 1838)

I found a hint in the comments: Please note that this method sets the mb_internal_encoding to ASCII, so if you are using the mbstring module functions with TCPDF you need to correctly set/unset the mb_internal_encoding when needed.

But now I need an advice how to use tcpdf and mb_internal_encoding correctly (without issues with cake or tcpdf).

Sorry for asking, I´m an absolutely beginner. ;)

Upvotes: 0

Related Questions