本文整理汇总了PHP中Toolbox::unclean_html_cross_side_scripting_deep方法的典型用法代码示例。如果您正苦于以下问题:PHP Toolbox::unclean_html_cross_side_scripting_deep方法的具体用法?PHP Toolbox::unclean_html_cross_side_scripting_deep怎么用?PHP Toolbox::unclean_html_cross_side_scripting_deep使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Toolbox
的用法示例。
在下文中一共展示了Toolbox::unclean_html_cross_side_scripting_deep方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: function
<script type='text/javascript'>
window.onload = function() {
var input = document.getElementById("login_name").focus();
}
</script>
</head>
<body>
<div id="body2"></div>
<div class="login-container">
<div class="middle-login">
<div id='text-login'>
<?php
echo nl2br(Toolbox::unclean_html_cross_side_scripting_deep($CFG_GLPI['text_login']));
?>
</div>
<div class="block-web row-fluid">
<div class="head">
<h3 class="text-center"><img class="logo-img" src="pics/logo.png" alt="" style="left:50%;"></h3>
</div>
<div id="logo_big" style="border-right: 1px solid #ccc; width:220px;" >
<img src="pics/logo_big.png" alt="GLPI" class="logo2" />
</div>
<div id="auth" style="background:#fff;">
<form class="form-horizontal" style="margin-bottom: 0px !important;" action='front/login.php' method='post'>
示例2: showListForCentral
/**
* Show list for central view
*
* @param $personal boolean display rssfeeds created by me ? (true by default)
*
* @return Nothing (display function)
**/
static function showListForCentral($personal = true)
{
global $DB, $CFG_GLPI;
$users_id = Session::getLoginUserID();
$today = date('Y-m-d');
$now = date('Y-m-d H:i:s');
if ($personal) {
/// Personal notes only for central view
if ($_SESSION['glpiactiveprofile']['interface'] == 'helpdesk') {
return false;
}
$query = "SELECT `glpi_rssfeeds`.*\n FROM `glpi_rssfeeds`\n WHERE `glpi_rssfeeds`.`users_id` = '{$users_id}'\n AND `glpi_rssfeeds`.`is_active` = '1'\n ORDER BY `glpi_rssfeeds`.`name`";
$titre = "<a href='" . $CFG_GLPI["root_doc"] . "/front/rssfeed.php'>" . _n('Personal RSS feed', 'Personal RSS feeds', Session::getPluralNumber()) . "</a>";
} else {
// Show public rssfeeds / not mines : need to have access to public rssfeeds
if (!self::canView()) {
return false;
}
$restrict_user = '1';
// Only personal on central so do not keep it
if ($_SESSION['glpiactiveprofile']['interface'] == 'central') {
$restrict_user = "`glpi_rssfeeds`.`users_id` <> '{$users_id}'";
}
$query = "SELECT `glpi_rssfeeds`.*\n FROM `glpi_rssfeeds` " . self::addVisibilityJoins() . "\n WHERE {$restrict_user}\n AND " . self::addVisibilityRestrict() . "\n ORDER BY `glpi_rssfeeds`.`name`";
if ($_SESSION['glpiactiveprofile']['interface'] != 'helpdesk') {
$titre = "<a href=\"" . $CFG_GLPI["root_doc"] . "/front/rssfeed.php\">" . _n('Public RSS feed', 'Public RSS feeds', Session::getPluralNumber()) . "</a>";
} else {
$titre = _n('Public RSS feed', 'Public RSS feeds', Session::getPluralNumber());
}
}
$result = $DB->query($query);
$items = array();
$rssfeed = new self();
if ($nb = $DB->numrows($result)) {
while ($data = $DB->fetch_assoc($result)) {
if ($rssfeed->getFromDB($data['id'])) {
// Force fetching feeds
if ($feed = self::getRSSFeed($data['url'], $data['refresh_rate'])) {
// Store feeds in array of feeds
$items = array_merge($items, $feed->get_items(0, $data['max_items']));
$rssfeed->setError(false);
} else {
$rssfeed->setError(true);
}
}
}
}
echo "<br><table class='tab_cadrehov'>";
echo "<tr class='noHover'><th colspan='2'><div class='relative'><span>{$titre}</span>";
if ($personal && self::canCreate() || !$personal && Session::haveRight('rssfeed_public', CREATE)) {
echo "<span class='floatright'>";
echo "<a href='" . $CFG_GLPI["root_doc"] . "/front/rssfeed.form.php'>";
echo "<img src='" . $CFG_GLPI["root_doc"] . "/pics/plus.png' alt='" . __s('Add') . "' title=\"" . __s('Add') . "\"></a></span>";
}
echo "</div></th></tr>\n";
if ($nb) {
usort($items, array('SimplePie', 'sort_items'));
foreach ($items as $item) {
echo "<tr class='tab_bg_1'><td>";
echo HTML::convDateTime($item->get_date('Y-m-d H:i:s'));
echo "</td><td>";
$link = $item->feed->get_permalink();
if (empty($link)) {
echo $item->feed->get_title();
} else {
echo "<a target='_blank' href='{$link}'>" . $item->feed->get_title() . '</a>';
}
$link = $item->get_permalink();
// echo "<br>";
// echo $item->get_title();
// echo "</td><td>";
$rand = mt_rand();
echo "<div id='rssitem{$rand}' class='pointer rss'>";
if (!is_null($link)) {
echo "<a target='_blank' href='{$link}'>";
}
echo $item->get_title();
// echo Html::resume_text(Html::clean(Toolbox::unclean_cross_side_scripting_deep($item->get_content())), 300);
if (!is_null($link)) {
echo "</a>";
}
echo "</div>";
Html::showToolTip(Toolbox::unclean_html_cross_side_scripting_deep($item->get_content()), array('applyto' => "rssitem{$rand}", 'display' => true));
echo "</td></tr>";
}
}
echo "</table>\n";
}
示例3: showListForCentral
/**
* Show list for central view
*
* @param $personal boolean : display reminders created by me ? (true by default)
*
* @return Nothing (display function)
**/
static function showListForCentral($personal = true)
{
global $DB, $CFG_GLPI;
$users_id = Session::getLoginUserID();
$today = date('Y-m-d');
$now = date('Y-m-d H:i:s');
$restrict_visibility = " AND (`glpi_reminders`.`begin_view_date` IS NULL\n OR `glpi_reminders`.`begin_view_date` < '{$now}')\n AND (`glpi_reminders`.`end_view_date` IS NULL\n OR `glpi_reminders`.`end_view_date` > '{$now}') ";
if ($personal) {
/// Personal notes only for central view
if ($_SESSION['glpiactiveprofile']['interface'] == 'helpdesk') {
return false;
}
$query = "SELECT `glpi_reminders`.*\n FROM `glpi_reminders`\n WHERE `glpi_reminders`.`users_id` = '{$users_id}'\n AND (`glpi_reminders`.`end` >= '{$today}'\n OR `glpi_reminders`.`is_planned` = '0')\n {$restrict_visibility}\n ORDER BY `glpi_reminders`.`name`";
$titre = "<a href='" . $CFG_GLPI["root_doc"] . "/front/reminder.php'>" . _n('Personal reminder', 'Personal reminders', 2) . "</a>";
} else {
// Show public reminders / not mines : need to have access to public reminders
if (!Session::haveRight('reminder_public', 'r')) {
return false;
}
$restrict_user = '1';
// Only personal on central so do not keep it
if ($_SESSION['glpiactiveprofile']['interface'] == 'central') {
$restrict_user = "`glpi_reminders`.`users_id` <> '{$users_id}'";
}
$query = "SELECT `glpi_reminders`.*\n FROM `glpi_reminders` " . self::addVisibilityJoins() . "\n WHERE {$restrict_user}\n {$restrict_visibility}\n AND " . self::addVisibilityRestrict() . "\n ORDER BY `glpi_reminders`.`name`";
if ($_SESSION['glpiactiveprofile']['interface'] != 'helpdesk') {
$titre = "<a href=\"" . $CFG_GLPI["root_doc"] . "/front/reminder.php\">" . _n('Public reminder', 'Public reminders', 2) . "</a>";
} else {
$titre = _n('Public reminder', 'Public reminders', 2);
}
}
$result = $DB->query($query);
$nb = $DB->numrows($result);
echo "<br><table class='tab_cadrehov'>";
echo "<tr><th><div class='relative'><span>{$titre}</span>";
if (self::canCreate()) {
echo "<span class='reminder_right'>";
echo "<a href='" . $CFG_GLPI["root_doc"] . "/front/reminder.form.php'>";
echo "<img src='" . $CFG_GLPI["root_doc"] . "/pics/plus.png' alt='" . __s('Add') . "'\n title=\"" . __s('Add') . "\"></a></span>";
}
echo "</div></th></tr>\n";
if ($nb) {
$rand = mt_rand();
while ($data = $DB->fetch_assoc($result)) {
echo "<tr class='tab_bg_2'><td><div class='relative reminder_list'>";
$link = "<a id='content_reminder_" . $data["id"] . $rand . "'\n href='" . $CFG_GLPI["root_doc"] . "/front/reminder.form.php?id=" . $data["id"] . "'>" . $data["name"] . "</a>";
$tooltip = Html::showToolTip(Toolbox::unclean_html_cross_side_scripting_deep($data["text"]), array('applyto' => "content_reminder_" . $data["id"] . $rand, 'display' => false));
printf(__('%1$s %2$s'), $link, $tooltip);
if ($data["is_planned"]) {
$tab = explode(" ", $data["begin"]);
$date_url = $tab[0];
echo "<span class='reminder_right'>";
echo "<a href='" . $CFG_GLPI["root_doc"] . "/front/planning.php?date=" . $date_url . "&type=day'>";
echo "<img src='" . $CFG_GLPI["root_doc"] . "/pics/rdv.png' alt=\"" . __s('Planning') . "\" title=\"" . sprintf(__s('From %1$s to %2$s'), Html::convDateTime($data["begin"]), Html::convDateTime($data["end"])) . "\">";
echo "</a></span>";
}
echo "</div></td></tr>\n";
}
}
echo "</table>\n";
}
示例4: showFull
/**
* Print out (html) show item : question and answer
*
* @param $options array of options
*
* @return nothing (display item : question and answer)
**/
function showFull($options = array())
{
global $DB, $CFG_GLPI;
if (!$this->can($this->fields['id'], READ)) {
return false;
}
$linkusers_id = true;
// show item : question and answer
if (Session::getLoginUserID() === false && $CFG_GLPI["use_public_faq"] || $_SESSION["glpiactiveprofile"]["interface"] == "helpdesk" || !User::canView()) {
$linkusers_id = false;
}
$this->updateCounter();
$knowbaseitemcategories_id = $this->fields["knowbaseitemcategories_id"];
$fullcategoryname = getTreeValueCompleteName("glpi_knowbaseitemcategories", $knowbaseitemcategories_id);
$tmp = "<a href='" . $this->getSearchURL() . "?knowbaseitemcategories_id={$knowbaseitemcategories_id}'>" . $fullcategoryname . "</a>";
echo "<table class='tab_cadre_fixe'>";
echo "<tr><th colspan='4'>" . sprintf(__('%1$s: %2$s'), __('Category'), $tmp);
echo "</th></tr>";
echo "<tr><td class='left' colspan='4'><h2>" . __('Subject') . "</h2>";
if (KnowbaseItemTranslation::canBeTranslated($this)) {
echo KnowbaseItemTranslation::getTranslatedValue($this, 'name');
} else {
echo $this->fields["name"];
}
echo "</td></tr>";
echo "<tr><td class='left' colspan='4'><h2>" . __('Content') . "</h2>\n";
echo "<div id='kbanswer'>";
if (KnowbaseItemTranslation::canBeTranslated($this)) {
$answer = KnowbaseItemTranslation::getTranslatedValue($this, 'answer');
} else {
$answer = $this->fields["answer"];
}
echo Toolbox::unclean_html_cross_side_scripting_deep($answer);
echo "</div>";
echo "</td></tr>";
echo "<tr><th class='tdkb' colspan='2'>";
if ($this->fields["users_id"]) {
// Integer because true may be 2 and getUserName return array
if ($linkusers_id) {
$linkusers_id = 1;
} else {
$linkusers_id = 0;
}
printf(__('%1$s: %2$s'), __('Writer'), getUserName($this->fields["users_id"], $linkusers_id));
echo "<br>";
}
if ($this->fields["date"]) {
//TRANS: %s is the datetime of update
printf(__('Created on %s'), Html::convDateTime($this->fields["date"]));
echo "<br>";
}
if ($this->fields["date_mod"]) {
//TRANS: %s is the datetime of update
printf(__('Last update on %s'), Html::convDateTime($this->fields["date_mod"]));
}
echo "</th>";
echo "<th class='tdkb' colspan='2'>";
if ($this->countVisibilities() == 0) {
echo "<span class='red'>" . __('Unpublished') . "</span><br>";
}
printf(_n('%d view', '%d views', $this->fields["view"]), $this->fields["view"]);
echo "<br>";
if ($this->fields["is_faq"]) {
_e('This item is part of the FAQ');
} else {
_e('This item is not part of the FAQ');
}
echo "</th></tr>";
echo "</table>";
return true;
}
示例5: update084to0841
/**
* Update from 0.84 to 0.84.1
*
* @return bool for success (will die for most error)
**/
function update084to0841()
{
global $DB, $migration;
$updateresult = true;
$ADDTODISPLAYPREF = array();
//TRANS: %s is the number of new version
$migration->displayTitle(sprintf(__('Update to %s'), '0.84.1'));
$migration->setVersion('0.84.1');
$backup_tables = false;
$newtables = array();
foreach ($newtables as $new_table) {
// rename new tables if exists ?
if (TableExists($new_table)) {
$migration->dropTable("backup_{$new_table}");
$migration->displayWarning("{$new_table} table already exists. " . "A backup have been done to backup_{$new_table}.");
$backup_tables = true;
$query = $migration->renameTable("{$new_table}", "backup_{$new_table}");
}
}
if ($backup_tables) {
$migration->displayWarning("You can delete backup tables if you have no need of them.", true);
}
// Convert html fields from numeric encoding to raw encoding
$fields_to_clean = array('glpi_knowbaseitems' => 'answer', 'glpi_tickets' => 'solution', 'glpi_problems' => 'solution', 'glpi_reminders' => 'text', 'glpi_solutiontemplates' => 'content', 'glpi_notificationtemplatetranslations' => 'content_text');
foreach ($fields_to_clean as $table => $field) {
foreach ($DB->request($table) as $data) {
$text = Toolbox::unclean_html_cross_side_scripting_deep($data[$field]);
$text = html_entity_decode($text, ENT_NOQUOTES, 'UTF-8');
$text = addslashes($text);
$text = Toolbox::clean_cross_side_scripting_deep($text);
$query = "UPDATE `{$table}`\n SET `{$field}` = '{$text}'\n WHERE `id` = '" . $data['id'] . "';";
$DB->queryOrDie($query, "0.84.1 fix encoding of html field : {$table}.{$field}");
}
}
// Add date_mod to document_item
$migration->addField('glpi_documents_items', 'date_mod', 'datetime');
$migration->migrationOneTable('glpi_documents_items');
$query_doc_i = "UPDATE `glpi_documents_items` as `doc_i`\n INNER JOIN `glpi_documents` as `doc`\n ON `doc`.`id` = `doc_i`.`documents_id`\n SET `doc_i`.`date_mod` = `doc`.`date_mod`";
$DB->queryOrDie($query_doc_i, "0.84.1 update date_mod in glpi_documents_items");
// correct entities_id in documents_items
$query_doc_i = "UPDATE `glpi_documents_items` as `doc_i`\n INNER JOIN `glpi_documents` as `doc`\n ON `doc`.`id` = `doc_i`.`documents_id`\n SET `doc_i`.`entities_id` = `doc`.`entities_id`,\n `doc_i`.`is_recursive` = `doc`.`is_recursive`";
$DB->queryOrDie($query_doc_i, "0.84.1 change entities_id in documents_items");
// add delete_problem
$migration->addField('glpi_profiles', 'delete_problem', 'char', array('after' => 'edit_all_problem', 'update' => 'edit_all_problem'));
// ************ Keep it at the end **************
//TRANS: %s is the table or item to migrate
$migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_displaypreferences'));
foreach ($ADDTODISPLAYPREF as $type => $tab) {
$query = "SELECT DISTINCT `users_id`\n FROM `glpi_displaypreferences`\n WHERE `itemtype` = '{$type}'";
if ($result = $DB->query($query)) {
if ($DB->numrows($result) > 0) {
while ($data = $DB->fetch_assoc($result)) {
$query = "SELECT MAX(`rank`)\n FROM `glpi_displaypreferences`\n WHERE `users_id` = '" . $data['users_id'] . "'\n AND `itemtype` = '{$type}'";
$result = $DB->query($query);
$rank = $DB->result($result, 0, 0);
$rank++;
foreach ($tab as $newval) {
$query = "SELECT *\n FROM `glpi_displaypreferences`\n WHERE `users_id` = '" . $data['users_id'] . "'\n AND `num` = '{$newval}'\n AND `itemtype` = '{$type}'";
if ($result2 = $DB->query($query)) {
if ($DB->numrows($result2) == 0) {
$query = "INSERT INTO `glpi_displaypreferences`\n (`itemtype` ,`num` ,`rank` ,`users_id`)\n VALUES ('{$type}', '{$newval}', '" . $rank++ . "',\n '" . $data['users_id'] . "')";
$DB->query($query);
}
}
}
}
} else {
// Add for default user
$rank = 1;
foreach ($tab as $newval) {
$query = "INSERT INTO `glpi_displaypreferences`\n (`itemtype` ,`num` ,`rank` ,`users_id`)\n VALUES ('{$type}', '{$newval}', '" . $rank++ . "', '0')";
$DB->query($query);
}
}
}
}
// must always be at the end
$migration->executeMigration();
return $updateresult;
}
示例6: showFull
/**
* Print out (html) show item : question and answer
*
* @param $linkusers_id display users_id link (true by default)
* @param $options array of options
*
* @return nothing (display item : question and answer)
**/
function showFull($linkusers_id = true, $options = array())
{
global $DB, $CFG_GLPI;
if (!$this->can($this->fields['id'], 'r')) {
return false;
}
// show item : question and answer
if (!Session::haveRight("user", "r")) {
$linkusers_id = false;
}
$inpopup = strpos($_SERVER['PHP_SELF'], "popup.php");
$this->updateCounter();
$knowbaseitemcategories_id = $this->fields["knowbaseitemcategories_id"];
$fullcategoryname = getTreeValueCompleteName("glpi_knowbaseitemcategories", $knowbaseitemcategories_id);
if (!$inpopup) {
$this->showTabs($options);
}
$options['colspan'] = 2;
$options['canedit'] = 0;
// Hide the buttons
$this->showFormHeader($options);
$tmp = "<a href='" . $this->getSearchURL() . "?knowbaseitemcategories_id={$knowbaseitemcategories_id}'>" . $fullcategoryname . "</a>";
echo "<tr class='tab_bg_3'><th colspan='4'>" . sprintf(__('%1$s: %2$s'), __('Category'), $tmp);
echo "</th></tr>";
echo "<tr class='tab_bg_3'><td class='left' colspan='4'><h2>" . __('Subject') . "</h2>";
echo $this->fields["name"];
echo "</td></tr>";
echo "<tr class='tab_bg_3'><td class='left' colspan='4'><h2>" . __('Content') . "</h2>\n";
echo "<div id='kbanswer'>";
echo Toolbox::unclean_html_cross_side_scripting_deep($this->fields["answer"]);
echo "</div>";
echo "</td></tr>";
echo "<tr><th class='tdkb' colspan='2'>";
if ($this->fields["users_id"]) {
// Integer because true may be 2 and getUserName return array
if ($linkusers_id) {
$linkusers_id = 1;
} else {
$linkusers_id = 0;
}
printf(__('%1$s: %2$s'), __('Writer'), getUserName($this->fields["users_id"], $linkusers_id));
echo "<br>";
}
if ($this->fields["date"]) {
//TRANS: %s is the datetime of update
printf(__('Created on %s'), Html::convDateTime($this->fields["date"]));
}
if ($this->countVisibilities() == 0) {
echo "<br><span class='red'>" . __('Unpublished') . "</span>";
}
echo "</th>";
echo "<th class='tdkb' colspan='2'>";
if ($this->fields["date_mod"]) {
//TRANS: %s is the datetime of update
printf(__('Last update on %s'), Html::convDateTime($this->fields["date_mod"]));
echo "<br>";
}
echo sprintf(_n('%d view', '%d views', $this->fields["view"]), $this->fields["view"]) . "</th></tr>";
$this->showFormButtons($options);
if (!$inpopup) {
$this->addDivForTabs();
}
return true;
}
示例7: showTranslations
/**
* Display all translated field for an KnowbaseItem
*
* @param $item a KnowbaseItem item
*
* @return true;
**/
static function showTranslations(KnowbaseItem $item)
{
global $DB, $CFG_GLPI;
$canedit = $item->can($item->getID(), UPDATE);
$rand = mt_rand();
if ($canedit) {
echo "<div id='viewtranslation" . $item->getID() . "{$rand}'></div>\n";
echo "<script type='text/javascript' >\n";
echo "function addTranslation" . $item->getID() . "{$rand}() {\n";
$params = array('type' => __CLASS__, 'parenttype' => get_class($item), 'knowbaseitems_id' => $item->fields['id'], 'id' => -1);
Ajax::updateItemJsCode("viewtranslation" . $item->getID() . "{$rand}", $CFG_GLPI["root_doc"] . "/ajax/viewsubitem.php", $params);
echo "};";
echo "</script>\n";
echo "<div class='center'>" . "<a class='vsubmit' href='javascript:addTranslation" . $item->getID() . "{$rand}();'>" . __('Add a new translation') . "</a></div><br>";
}
$obj = new self();
$found = $obj->find("`knowbaseitems_id`='" . $item->getID() . "'", "`language` ASC");
if (count($found) > 0) {
if ($canedit) {
Html::openMassiveActionsForm('mass' . __CLASS__ . $rand);
$massiveactionparams = array('container' => 'mass' . __CLASS__ . $rand);
Html::showMassiveActions($massiveactionparams);
}
echo "<div class='center'>";
echo "<table class='tab_cadre_fixehov'><tr class='tab_bg_2'>";
echo "<th colspan='4'>" . __("List of translations") . "</th></tr>";
if ($canedit) {
echo "<th width='10'>";
Html::checkAllAsCheckbox('mass' . __CLASS__ . $rand);
echo "</th>";
}
echo "<th>" . __("Language") . "</th>";
echo "<th>" . __("Subject") . "</th>";
foreach ($found as $data) {
echo "<tr class='tab_bg_1' " . ($canedit ? "style='cursor:pointer'\n onClick=\"viewEditTranslation" . $data['id'] . "{$rand}();\"" : '') . ">";
if ($canedit) {
echo "<td class='center'>";
Html::showMassiveActionCheckBox(__CLASS__, $data["id"]);
echo "</td>";
}
echo "<td>";
if ($canedit) {
echo "\n<script type='text/javascript' >\n";
echo "function viewEditTranslation" . $data["id"] . "{$rand}() {\n";
$params = array('type' => __CLASS__, 'parenttype' => get_class($item), 'knowbaseitems_id' => $item->getID(), 'id' => $data["id"]);
Ajax::updateItemJsCode("viewtranslation" . $item->getID() . "{$rand}", $CFG_GLPI["root_doc"] . "/ajax/viewsubitem.php", $params);
echo "};";
echo "</script>\n";
}
echo Dropdown::getLanguageName($data['language']);
echo "</td><td>";
echo $data["name"];
if (isset($data['answer']) && !empty($data['answer'])) {
echo " ";
Html::showToolTip(Toolbox::unclean_html_cross_side_scripting_deep($data['answer']));
}
echo "</td></tr>";
}
echo "</table>";
if ($canedit) {
$massiveactionparams['ontop'] = false;
Html::showMassiveActions($massiveactionparams);
Html::closeForm();
}
} else {
echo "<table class='tab_cadre_fixe'><tr class='tab_bg_2'>";
echo "<th class='b'>" . __("No translation found") . "</th></tr></table>";
}
return true;
}
示例8: getAnswer
/**
* Get KB answer, with id on titles to set anchors
*
* @return string
*/
public function getAnswer()
{
if (KnowbaseItemTranslation::canBeTranslated($this)) {
$answer = KnowbaseItemTranslation::getTranslatedValue($this, 'answer');
} else {
$answer = $this->fields["answer"];
}
$answer = Toolbox::unclean_html_cross_side_scripting_deep($answer);
$callback = function ($matches) {
//1 => tag name, 2 => existing attributes, 3 => title contents
$tpl = '<%tag%attrs id="%slug"><a href="#%slug">%icon</a>%title</%tag>';
$title = str_replace(['%tag', '%attrs', '%slug', '%title', '%icon'], [$matches[1], $matches[2], Toolbox::slugify($matches[3]), $matches[3], '<svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"/></svg>'], $tpl);
return $title;
};
$pattern = '|<(h[1-6]{1})(.?[^>])?>(.+)</h[1-6]{1}>|';
$answer = preg_replace_callback($pattern, $callback, $answer);
return $answer;
}