diff --git a/inc/command/cleanticketscommand.class.php b/inc/command/cleanticketscommand.class.php index 660694145..92691844e 100644 --- a/inc/command/cleanticketscommand.class.php +++ b/inc/command/cleanticketscommand.class.php @@ -53,6 +53,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $this->fixBadForm_1($input, $output); $this->fixBadForm_2($input, $output); + $this->fixBadForm_3($input, $output); $output->writeln('Done.'); return 0; @@ -102,7 +103,7 @@ protected function fixBadForm_1(InputInterface $input, OutputInterface $output) return 0; } - $output->write("-> Found $count tickets to clean"); + $output->write("-> Found $count tickets to clean (double encoded < and > signs)"); $output->writeln(""); $output->write("-> Cleaning tickets..."); $output->writeln(""); @@ -130,7 +131,7 @@ protected function fixBadForm_1(InputInterface $input, OutputInterface $output) } /** - * remove HTML tag
+ * replace litteral HTML tag
with <br /> * * @param InputInterface $input * @param OutputInterface $output @@ -142,7 +143,7 @@ protected function fixBadForm_2(InputInterface $input, OutputInterface $output) // Search tickets having HTML tags
$itemTicketTable = Item_Ticket::getTable(); $ticketTable = Ticket::getTable(); - $pattern = 'br /'; + $pattern = '
'; $tickets = $DB->request([ 'SELECT' => [$ticketTable => [Ticket::getIndexName(), 'content']], 'FROM' => $ticketTable, @@ -158,7 +159,7 @@ protected function fixBadForm_2(InputInterface $input, OutputInterface $output) ], ], 'WHERE' => [ - "$ticketTable.content" => ['LIKE', '%' . $pattern . '%'], // Matches bad encoding for '<' + "$ticketTable.content" => ['LIKE', '%' . $pattern . '%'], // Matches bad encoding for 'br /' ], ]); @@ -169,7 +170,7 @@ protected function fixBadForm_2(InputInterface $input, OutputInterface $output) return 0; } - $output->write("-> Found $count tickets to clean"); + $output->write("-> Found $count tickets to clean (literal BR tag)"); $output->writeln(""); $output->write("-> Cleaning tickets..."); $output->writeln(""); @@ -177,9 +178,102 @@ protected function fixBadForm_2(InputInterface $input, OutputInterface $output) $pattern = [ '
', ]; - $replace = [ - '<br />', + // Determine if we must use legacy or new encoding + // @see Sanitizer::sanitize() + $replace = null; + if (strpos($row['content'], '<') !== false && strpos($row['content'], '#60;') === false) { + $replace = [ + '<br />', + ]; + } else if (strpos($row['content'], '#60') !== false && strpos($row['content'], '<') === false) { + $replace = [ + '<br />', + ]; + } + if ($replace === null) { + $output->write("-> Unable to determine the encoding type of ticket ID: " . $row['id']. ""); + continue; + } + $row['content'] = str_replace($pattern, $replace, $row['content']); + // Direct write to the table to avoid alteration of other fields + $DB->update( + $ticketTable, + [ + 'content' => $DB->escape($row['content']) + ], + [ + 'id' => $row['id'], + ] + ); + } + } + + /** + * replace litteral HTML tag > with #38; + * This may happen when a question gives the path to an item of a CommonTreeObject + * entities, locations, ... + * + * @param InputInterface $input + * @param OutputInterface $output + * @return void + */ + protected function fixBadForm_3(InputInterface $input, OutputInterface $output) { + global $DB; + + // Search tickets having HTML tags
+ $itemTicketTable = Item_Ticket::getTable(); + $ticketTable = Ticket::getTable(); + $pattern = ' > '; // greater than sign with a space before and after + $tickets = $DB->request([ + 'SELECT' => [$ticketTable => [Ticket::getIndexName(), 'content']], + 'FROM' => $ticketTable, + 'INNER JOIN' => [ + $itemTicketTable => [ + 'FKEY' => [ + $ticketTable => Ticket::getIndexName(), + $itemTicketTable => Ticket::getForeignKeyField(), + ], + 'AND' => [ + "$itemTicketTable.itemtype" => PluginFormcreatorFormAnswer::getType(), + ] + ], + ], + 'WHERE' => [ + "$ticketTable.content" => ['LIKE', '%' . $pattern . '%'], + ], + ]); + + $count = $tickets->count(); + if ($count < 1) { + $output->writeln('-> No ticket to fix.'); + $output->writeln(""); + return 0; + } + + $output->write("-> Found $count tickets to clean (litteral > sign)"); + $output->writeln(""); + $output->write("-> Cleaning tickets..."); + $output->writeln(""); + foreach ($tickets as $row) { + $pattern = [ + ' > ', ]; + // Determine if we must use legacy or new encoding + // @see Sanitizer::sanitize() + $replace = null; + if (strpos($row['content'], '<') !== false && strpos($row['content'], '#60;') === false) { + $replace = [ + ' > ', + ]; + } else if (strpos($row['content'], '#60') !== false && strpos($row['content'], '<') === false) { + $replace = [ + ' & ', + ]; + } + if ($replace === null) { + $output->write("-> Unable to determine the encoding type of ticket ID: " . $row['id']. ""); + continue; + } $row['content'] = str_replace($pattern, $replace, $row['content']); // Direct write to the table to avoid alteration of other fields $DB->update(