Depuis la 1.0.0, il y a effectivement peu de changements fonctionnels, mais il y en a un important dans listener.php.
Modifications fonctionnelles
Dans
event/listener.php, j'ai ajouté un nouvel événement phpBB :
Cet événement permet d'intervenir sur l'écran de rédaction/prévisualisation. phpBB documente bien cet événement comme permettant de modifier les variables du template de l'écran de publication.
J'ai ensuite ajouté la fonction :
public function edit_preview($event)
Elle :
- vérifie que $event['preview'] est actif ;
- récupère le message_parser ;
- reformate le message avec format_display() ;
- récupère ainsi le HTML réellement généré pour la prévisualisation ;
- passe ce HTML dans replace_links() ;
- réinjecte le résultat dans PREVIEW_MESSAGE.
L'objectif est donc bien de faire :
Prévisualisation :
Le dossier config
→
Titre du sujet
sans modifier le contenu de la zone de saisie.
Autre petite modification
J'ai légèrement amélioré la regex de replace_links() :
1.0.0 :
href="..."
1.0.1 :
href="..."
ou
href='...'
Donc elle accepte maintenant les deux types de guillemets autour de href.
Voici le fichier
listener.php
Code: Tout sélectionner
<?php
/**
*
* @package phpBB Extension - Smart Links
* @copyright (c) 2026 Fred Rimbert
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
namespace caforum\smartlinks\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class listener implements EventSubscriberInterface
{
/** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\template\template */
protected $template;
public function __construct(
\phpbb\db\driver\driver_interface $db,
\phpbb\template\template $template
)
{
$this->db = $db;
$this->template = $template;
}
public static function getSubscribedEvents()
{
return [
'core.viewtopic_modify_post_row' => 'edit_postrow',
'core.posting_modify_template_vars' => 'edit_preview',
];
}
/**
* Returns the topic title from a topic_id or a post_id.
*/
protected function get_topic_title($id, $type = 't')
{
if ($type === 'p')
{
$sql = 'SELECT t.topic_title
FROM ' . POSTS_TABLE . ' p
INNER JOIN ' . TOPICS_TABLE . ' t
ON t.topic_id = p.topic_id
WHERE p.post_id = ' . (int) $id;
}
else
{
$sql = 'SELECT topic_title
FROM ' . TOPICS_TABLE . '
WHERE topic_id = ' . (int) $id;
}
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
return ($row) ? $row['topic_title'] : '';
}
/**
* Replaces internal phpBB link text with the corresponding topic title.
* The HTML is already rendered here, so this works for both published
* posts and the formatted preview.
*/
protected function replace_links($message)
{
$pattern = '#<a([^>]+href=(?:"|\')([^"\']*viewtopic\.php\?[^"\']*)(?:"|\')[^>]*)>(.*?)</a>#is';
return preg_replace_callback($pattern, function ($matches)
{
$url = html_entity_decode($matches[2], ENT_QUOTES);
$title = '';
if (preg_match('/(?:\?|&)t=(\d+)/', $url, $m))
{
$title = $this->get_topic_title((int) $m[1], 't');
}
elseif (preg_match('/(?:\?|&)p=(\d+)/', $url, $m))
{
$title = $this->get_topic_title((int) $m[1], 'p');
}
if (!$title)
{
return $matches[0];
}
return '<a' . $matches[1] . '>' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>';
}, $message);
}
/**
* Replace internal link text in the formatted posting preview.
*
* The normal posting page keeps MESSAGE as BBCode for the textarea.
* The actual preview is stored separately in PREVIEW_MESSAGE, so it must
* be modified directly without touching MESSAGE.
*/
public function edit_preview($event)
{
if (!$event['preview'])
{
return;
}
$message_parser = $event['message_parser'];
$preview_message = $message_parser->format_display(
$event['post_data']['enable_bbcode'],
$event['post_data']['enable_urls'],
$event['post_data']['enable_smilies'],
false
);
$this->template->assign_var('PREVIEW_MESSAGE', $this->replace_links($preview_message));
}
public function edit_postrow($event)
{
$post_row = $event['post_row'];
if (!empty($post_row['MESSAGE']))
{
$post_row['MESSAGE'] = $this->replace_links($post_row['MESSAGE']);
}
if (!empty($post_row['SIGNATURE']))
{
$post_row['SIGNATURE'] = $this->replace_links($post_row['SIGNATURE']);
}
$event['post_row'] = $post_row;
}
}