diff --git a/inc/command/cleanticketscommand.class.php b/inc/command/cleanticketscommand.class.php new file mode 100644 index 000000000..65080a896 --- /dev/null +++ b/inc/command/cleanticketscommand.class.php @@ -0,0 +1,196 @@ +. + * --------------------------------------------------------------------- + * @copyright Copyright © 2011 - 2021 Teclib' + * @license http://www.gnu.org/licenses/gpl.txt GPLv3+ + * @link https://github.com/pluginsGLPI/formcreator/ + * @link https://pluginsglpi.github.io/formcreator/ + * @link http://plugins.glpi-project.org/#/plugin/formcreator + * --------------------------------------------------------------------- + */ + +namespace GlpiPlugin\Formcreator\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Ticket; +use Item_Ticket; +use PluginFormcreatorFormAnswer; +use Glpi\Toolbox\Sanitizer; + +class CleanTicketsCommand extends Command +{ + protected function configure() { + $this + ->setName('glpi:plugins:formcreator:clean_tickets') + ->setDescription("Clean Tickets having visible HTML tags in their content"); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $output->write("-> Search tickets to clean..."); + $output->writeln(""); + + $this->fixBadForm_1($input, $output); + $this->fixBadForm_2($input, $output); + + $output->writeln('Done.'); + return 0; + } + + /** + * fix HTML tags double encoded + *

=> <p> => &lt;p&gt; + * + * @param InputInterface $input + * @param OutputInterface $output + * @return void + */ + protected function fixBadForm_1(InputInterface $input, OutputInterface $output) { + global $DB; + + // Search tickets having HTML tags in content in the following form + // &lt;p&gt;Hello world&lt;/p&gt; + // Hello world is between

and

, but with wrong escaping + $itemTicketTable = Item_Ticket::getTable(); + $ticketTable = Ticket::getTable(); + $pattern = '&lt;'; + // $pattern = str_replace(';', '\\;', $pattern); + $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 . '%'], // Matches bad encoding for '<' + ], + ]); + + $count = $tickets->count(); + if ($count < 1) { + $output->writeln('-> No ticket to fix.'); + $output->writeln(""); + return 0; + } + + $output->write("-> Found $count tickets to clean"); + $output->writeln(""); + $output->write("-> Cleaning tickets..."); + $output->writeln(""); + foreach ($tickets as $row) { + $pattern = [ + '/&lt;([a-z0-9]+?)&gt;/', + '/&lt;(\/[a-z0-9]+?)&gt;/', + ]; + $replace = [ + '<$1>', + '<$1>', + ]; + $row['content'] = preg_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'], + ] + ); + } + } + + /** + * remove HTML tag
+ * + * @param InputInterface $input + * @param OutputInterface $output + * @return void + */ + protected function fixBadForm_2(InputInterface $input, OutputInterface $output) { + global $DB; + + // Search tickets having HTML tags
+ $itemTicketTable = Item_Ticket::getTable(); + $ticketTable = Ticket::getTable(); + $pattern = 'br /'; + $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 . '%'], // Matches bad encoding for '<' + ], + ]); + + $count = $tickets->count(); + if ($count < 1) { + $output->writeln('-> No ticket to fix.'); + $output->writeln(""); + return 0; + } + + $output->write("-> Found $count tickets to clean"); + $output->writeln(""); + $output->write("-> Cleaning tickets..."); + $output->writeln(""); + foreach ($tickets as $row) { + $pattern = [ + '
', + ]; + $replace = [ + '<div></div>', + ]; + $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'], + ] + ); + } + } +}