Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2023-03-26 15:31:06 +02:00
commit d2649ef5e7
2 changed files with 435 additions and 32 deletions

View File

@ -18,6 +18,7 @@ class OdfException extends Exception
* @copyright 2010-2015 - Laurent Destailleur - eldy@users.sourceforge.net
* @copyright 2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com
* @copyright 2012 - Stephen Larroque - lrq3000@gmail.com
* @copyright 2023 - Thomas Negre - contact@open-dsi.fr
* @license https://www.gnu.org/copyleft/gpl.html GPL License
* @version 1.5.0
*/
@ -46,6 +47,9 @@ class Odf
public $userdefined=array();
const PIXEL_TO_CM = 0.026458333;
const FIND_TAGS_REGEX = '/<([A-Za-z0-9]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/';
const FIND_ENCODED_TAGS_REGEX = '/&lt;([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/&gt;)|(?:&gt;(.*)&lt;\/\1&gt;))/';
/**
* Class constructor
@ -161,12 +165,16 @@ class Odf
*/
public function convertVarToOdf($value, $encode = true, $charset = 'ISO-8859')
{
$value = $encode ? htmlspecialchars($value) : $value;
$value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
$value = html_entity_decode($value, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
// fix breaklines.
$value = preg_replace('/<br\s*\/?>/', "<br />", $value);
$convertedValue = $value;
// Check if the value includes html tags
if ($this->_hasHtmlTag($value) === true) {
$value = strip_tags($value, '<br><strong><b><i><em><u><s><sub><sup><span>');
// Default styles for strong/b, i/em, u, s, sub & sup
$automaticStyles = array(
'<style:style style:name="boldText" style:family="text"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>',
@ -180,7 +188,7 @@ class Odf
$customStyles = array();
$fontDeclarations = array();
$convertedValue = $this->_replaceHtmlWithOdtTag($this->_getDataFromHtml($value), $customStyles, $fontDeclarations);
$convertedValue = $this->_replaceHtmlWithOdtTag($this->_getDataFromHtml($value), $customStyles, $fontDeclarations, $encode, $charset);
foreach ($customStyles as $key => $val) {
array_push($automaticStyles, '<style:style style:name="customStyle' . $key . '" style:family="text">' . $val . '</style:style>');
@ -204,21 +212,23 @@ class Odf
}
$this->contentXml = str_replace('</office:font-face-decls>', $fonts . '</office:font-face-decls>', $this->contentXml);
} else {
$convertedValue = preg_replace('/(\r\n|\r|\n)/i', "<text:line-break/>", $value);
$convertedValue = $this->encode_chars($convertedValue, $encode, $charset);
$convertedValue = preg_replace('/(\r\n|\r|\n)/i', "<text:line-break/>", $convertedValue);
}
return $convertedValue;
}
/**
* Replaces html tags in with odt tags and returns an odt string
*
* @param array $tags An array with html tags generated by the getDataFromHtml() function
* @param array $customStyles An array of style defenitions that should be included inside the odt file
* @param array $fontDeclarations An array of font declarations that should be included inside the odt file
* @return string
*/
private function _replaceHtmlWithOdtTag($tags, &$customStyles, &$fontDeclarations)
* Replaces html tags in with odt tags and returns an odt string. Encodes and converts inner text.
* @param array $tags An array with html tags generated by the getDataFromHtml() function
* @param array $customStyles An array of style defenitions that should be included inside the odt file
* @param array $fontDeclarations An array of font declarations that should be included inside the odt file
* @param bool $encode If true, special XML characters are encoded
* @param string $charset Charset. See encode_chars()
* @return string
*/
private function _replaceHtmlWithOdtTag($tags, &$customStyles, &$fontDeclarations, $encode = false, $charset = '')
{
if ($customStyles == null) $customStyles = array();
if ($fontDeclarations == null) $fontDeclarations = array();
@ -228,7 +238,8 @@ class Odf
foreach ((array) $tags as $tag) {
// Check if the current item is a tag or just plain text
if (isset($tag['text'])) {
$odtResult .= $tag['text'];
$text = $this->encode_chars($tag['text'], $encode, $charset);
$odtResult .= $text;
} elseif (isset($tag['name'])) {
switch ($tag['name']) {
case 'br':
@ -236,23 +247,23 @@ class Odf
break;
case 'strong':
case 'b':
$odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'i':
case 'em':
$odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'u':
$odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 's':
$odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'sub':
$odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'sup':
$odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'span':
if (isset($tag['attributes']['style'])) {
@ -287,9 +298,9 @@ class Odf
}
if (strlen($odtStyles) > 0) {
// Generate a unique id for the style (using microtime and random because some CPUs are really fast...)
$key = floatval(str_replace('.', '', microtime(true)))+rand(0, 10);
$key = floatval(str_replace('.', '', microtime(true))) + rand(0, 10);
$customStyles[$key] = $odtStyles;
$odtResult .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
}
}
break;
@ -303,15 +314,30 @@ class Odf
}
/**
* Checks if the given text is a html string
* @param string $text The text to check
* @return bool
* Correctly encode chars
* @param string $text The text to encode or not
* @param bool $encode If true, special XML characters are encoded
* @param string $charset Charset
* @return string The converted text
* @see self::convertVarToOdf()
*/
private function _isHtmlTag($text)
private function encode_chars($text, $encode = false, $charset = '')
{
return preg_match('/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/', $text);
$newtext = $encode ? htmlspecialchars($text, ENT_QUOTES | ENT_XML1) : $text;
$newtext = ($charset == 'ISO-8859') ? utf8_encode($newtext) : $newtext;
return $newtext;
}
/**
* Checks if the given text is a html string
* @param string $text The text to check
* @return bool
*/
private function _isHtmlTag($text)
{
return preg_match(self::FIND_TAGS_REGEX, $text);
}
/**
* Checks if the given text includes a html string
* @param string $text The text to check
@ -319,7 +345,7 @@ class Odf
*/
private function _hasHtmlTag($text)
{
$result = preg_match_all('/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/', $text);
$result = preg_match_all(self::FIND_TAGS_REGEX, $text);
return is_numeric($result) && $result > 0;
}
@ -334,9 +360,8 @@ class Odf
$tempHtml = $html;
while (strlen($tempHtml) > 0) {
$matches = array();
// Check if the string includes a html tag
if (preg_match_all('/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/', $tempHtml, $matches)) {
if (preg_match_all(self::FIND_TAGS_REGEX, $tempHtml, $matches)) {
$tagOffset = strpos($tempHtml, $matches[0][0]);
// Check if the string starts with the html tag
if ($tagOffset > 0) {
@ -348,13 +373,12 @@ class Odf
$tempHtml = substr($tempHtml, $tagOffset);
}
// Extract the attribute data from the html tag
$explodedAttributes = array();
preg_match_all('/([0-9A-Za-z]+(?:="[0-9A-Za-z\:\-\s\,\;\#]*")?)+/', $matches[2][0], $explodedAttributes);
$explodedAttributes = array_filter($explodedAttributes[0]);
$attributes = array();
// Store each attribute with its name in the $attributes array
$explodedAttributesCount = count($explodedAttributes);
for ($i=0; $i<$explodedAttributesCount; $i++) {
for ($i = 0; $i < $explodedAttributesCount; $i++) {
$attribute = trim($explodedAttributes[$i]);
// Check if the attribute has a value (like style="") or has no value (like required)
if (strpos($attribute, '=') !== false) {
@ -368,7 +392,7 @@ class Odf
// Split the style properties and store them in an array
$explodedStyles = explode(';', $attrValue);
$explodedStylesCount = count($explodedStyles);
for ($n=0; $n<$explodedStylesCount; $n++) {
for ($n = 0; $n < $explodedStylesCount; $n++) {
$splitStyle = explode(':', $explodedStyles[$n]);
$attributes[$attrName][trim($splitStyle[0])] = trim($splitStyle[1]);
}

379
test/phpunit/ODFTest.php Normal file
View File

@ -0,0 +1,379 @@
<?php
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2023 - Thomas Negre - contact@open-dsi.fr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file test/unit/ODFTest.php
* \ingroup odf
* \brief PHPUnit test for odf class.
*/
global $conf,$user,$langs,$db;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
require_once dirname(__FILE__).'/../../htdocs/includes/odtphp/odf.php';
if (empty($user->id)) {
print "Load permissions for admin user nb 1\n";
$user->fetch(1);
$user->getrights();
}
$conf->global->MAIN_DISABLE_ALL_MAILS=1;
$langs->load("main");
/**
* Class for PHPUnit tests
*
* @backupGlobals disabled
* @backupStaticAttributes enabled
* @remarks backupGlobals must be disabled to have db,conf,user and lang not erased.
*/
class ODFTest extends PHPUnit\Framework\TestCase
{
protected $savconf;
protected $savuser;
protected $savlangs;
protected $savdb;
/**
* Constructor
* We save global variables into local variables
*
* @return BOMTest
*/
public function __construct()
{
parent::__construct();
//$this->sharedFixture
global $conf,$user,$langs,$db;
$this->savconf=$conf;
$this->savuser=$user;
$this->savlangs=$langs;
$this->savdb=$db;
print __METHOD__." db->type=".$db->type." user->id=".$user->id;
//print " - db ".$db->db;
print "\n";
}
/**
* setUpBeforeClass
*
* @return void
*/
public static function setUpBeforeClass()
{
global $conf,$user,$langs,$db;
$db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
print __METHOD__."\n";
}
/**
* tearDownAfterClass
*
* @return void
*/
public static function tearDownAfterClass()
{
global $conf,$user,$langs,$db;
$db->rollback();
print __METHOD__."\n";
}
/**
* Init phpunit tests
*
* @return void
*/
protected function setUp()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
print __METHOD__."\n";
}
/**
* End phpunit tests
*
* @return void
*/
protected function tearDown()
{
print __METHOD__."\n";
}
/**
* test ODF convertVarToOdf
*
* @return int
*/
public function testODFconvertVarToOdf()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
// we test using template_invoice, it does not matter, we just need a valid odt.
$filename = '../../htdocs/install/doctemplates/invoices/template_invoice.odt';
$config = [
'PATH_TO_TMP' => "/tmp",
'ZIP_PROXY' => "PclZipProxy",
'DELIMITER_LEFT' => "{",
'DELIMITER_RIGHT' => "}",
];
$to_test = [
/** No HTML **/
// Simple strings
1 => [
'to_convert' => 'Simple string',
'encode' => true,
'charset' => null,
'expected' => 'Simple string',
],
2 => [
'to_convert' => 'Simple string',
'encode' => false,
'charset' => null,
'expected' => 'Simple string',
],
3 => [
'to_convert' => "Simple string\nwith line break",
'encode' => true,
'charset' => null,
'expected' => "Simple string<text:line-break/>with line break",
],
4 => [
'to_convert' => "Simple string\nwith line break",
'encode' => false,
'charset' => null,
'expected' => "Simple string<text:line-break/>with line break",
],
// Special chars
5 => [
'to_convert' => 'One&two',
'encode' => true,
'charset' => null,
'expected' => 'One&amp;two',
],
6 => [
'to_convert' => 'One&two',
'encode' => false,
'charset' => null,
'expected' => 'One&two',
],
7 => [
'to_convert' => "/a&él'èàüöç€Ğ~<>",
'encode' => true,
'charset' => null,
'expected' => utf8_encode("/a&amp;él&apos;èàüöç€Ğ~&lt;&gt;"),
],
8 => [
'to_convert' => "/a&él'èàüöç€Ğ~<>",
'encode' => false,
'charset' => null,
'expected' => utf8_encode("/a&él'èàüöç€Ğ~<>"),
],
// special chars with non-default charset
9 => [
'to_convert' => "/a&él'èàüöç€Ğ~<>",
'encode' => true,
'charset' => 'UTF-16',
'expected' => "/a&amp;él&apos;èàüöç€Ğ~&lt;&gt;",
],
10 => [
'to_convert' => "/a&él'èàüöç€Ğ~<>",
'encode' => false,
'charset' => 'UTF-16', // When the charset differs from ISO-8859 string is not converted.
'expected' => "/a&él'èàüöç€Ğ~<>",
],
11 => [
'to_convert' => "Greater > than",
'encode' => true,
'charset' => null,
'expected' => utf8_encode("Greater &gt; than"),
],
12 => [
'to_convert' => "Greater > than",
'encode' => false,
'charset' => null,
'expected' => utf8_encode("Greater > than"),
],
13 => [
'to_convert' => "Smaller < than",
'encode' => true,
'charset' => null,
'expected' => utf8_encode("Smaller &lt; than"),
],
14 => [
'to_convert' => "Smaller < than",
'encode' => false,
'charset' => null,
'expected' => utf8_encode("Smaller < than"),
],
/** HTML **/
// break lines
15 => [
'to_convert' => "Break<br>line",
'encode' => true,
'charset' => null,
'expected' => utf8_encode("Break<text:line-break/>line"),
],
16 => [
'to_convert' => "Break<br>line",
'encode' => false,
'charset' => null,
'expected' => utf8_encode("Break<text:line-break/>line"),
],
17 => [
'to_convert' => "Break<br />line",
'encode' => true,
'charset' => null,
'expected' => utf8_encode("Break<text:line-break/>line"),
],
18 => [
'to_convert' => "Break<br />line",
'encode' => false,
'charset' => null,
'expected' => utf8_encode("Break<text:line-break/>line"),
],
// HTML tags
19 => [
'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>",
'encode' => false,
'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>',
],
20 => [
'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>",
'encode' => true,
'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&amp;ciàlchärs éè l&apos;</text:span>',
],
21 => [
'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>",
'encode' => false,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>'),
],
22 => [
'to_convert' => "text with <strong>strong, </strong><em>emphasis</em> and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>",
'encode' => true,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&amp;ciàlchärs éè l&apos;</text:span>'),
],
23 => [
'to_convert' => "text with <strong>intricated<u>tags</u></strong>",
'encode' => true,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">intricated<text:span text:style-name="underlineText">tags</text:span></text:span>'),
],
// One can also pass html-encoded string to the method
24 => [
'to_convert' => 'One&amp;two',
'encode' => true,
'charset' => null,
'expected' => 'One&amp;two',
],
25 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => false,
'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>',
],
26 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => true,
'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&amp;ciàlchärs éè l&apos;</text:span>',
],
27 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => false,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>'),
],
28 => [
'to_convert' => "text with &lt;strong&gt;strong, &lt;/strong&gt;&lt;em&gt;emphasis&lt;/em&gt; and &lt;u&gt;underlined&lt;/u&gt; words with &lt;i&gt;it@lic sp&amp;ciàlchärs éè l'&lt;/i&gt;",
'encode' => true,
'charset' => null,
'expected' => utf8_encode('text with <text:span text:style-name="boldText">strong, </text:span><text:span text:style-name="italicText">emphasis</text:span> and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&amp;ciàlchärs éè l&apos;</text:span>'),
],
// // TODO custom styles are not tested for now : the custom style have a custom ID based on time. Not random, but hard to mock or predict. generated in _replaceHtmlWithOdtTag() case 'span'.
// [
// 'to_convert' => '123 <span style="color:#e74c3c">trucmachin > truc < troc > trac</span>bla bla',
// 'encode' => true,
// 'charset' => 'UTF-8',
// 'expected' => "123 <text:span text:style-name="customStyle1668592427018">trucmachin &gt; truc &lt; troc &gt; trac</text:span>bla bla'",
// ],
/* Tests that can evolve */
// Following tests reflect the current behavior. They may evolve if the method behavior changes.
// The method removes hyperlinks and tags that are not dealt with.
29 => [
'to_convert' => '123 <a href="/test.php">trucmachin > truc < troc > trac</a>bla bla',
'encode' => true,
'charset' => null,
'expected' => "123 trucmachin &gt; truc &lt; troc &gt; tracbla bla",
],
30 => [
'to_convert' => '123 <h3>Title</h3> bla',
'encode' => true,
'charset' => null,
'expected' => "123 Title bla",
],
// HTML should not take \n into account, but only <br />.
31 => [
'to_convert' => "text with <strong>strong text </strong>, a line\nbreak and <u>underlined</u> words with <i>it@lic sp&ciàlchärs éè l'</i>",
'encode' => false,
'charset' => 'UTF-8',
'expected' => 'text with <text:span text:style-name="boldText">strong text </text:span>, a line'."\n".'break and <text:span text:style-name="underlineText">underlined</text:span> words with <text:span text:style-name="italicText">it@lic sp&ciàlchärs éè l\'</text:span>',
],
];
$odf=new Odf($filename, array());
if (is_object($odf)) $result = 1; // Just to test
foreach ($to_test as $case) {
if ($case['charset'] !== null) {
$res = $odf->convertVarToOdf($case['to_convert'], $case['encode'], $case['charset']);
} else {
$res = $odf->convertVarToOdf($case['to_convert'], $case['encode']);
}
$this->assertEquals($res, $case['expected']);
}
print __METHOD__." result=".$result."\n";
return $result;
}
}