xref: /plugin/avatar/syntax.php (revision 37ab823292c3801ac452b277fd13384ef1ff18b8)
1401a61e7Swikidesign<?php
2401a61e7Swikidesign/**
3*37ab8232Snerun * DokuWiki Avatar Plugin: displays avatar images with syntax, see:
4*37ab8232Snerun * <https://www.dokuwiki.org/plugin:avatar>.
5401a61e7Swikidesign *
6*37ab8232Snerun * Copyright (C) 2005-2007 by Esther Brunner <wikidesign@gmail.com>
7*37ab8232Snerun * Copyright (C) 2008-2009 by Gina Häußge, Michael Klier <dokuwiki@chimeric.de>
8*37ab8232Snerun * Copyright (C) 2013 by Michael Hamann <michael@content-space.de>
9*37ab8232Snerun * Copyright (C) 2023 by Daniel Dias Rodrigues <danieldiasr@gmail.com>
10401a61e7Swikidesign *
11*37ab8232Snerun * This program is free software; you can redistribute it and/or modify
12*37ab8232Snerun * it under the terms of the GNU General Public License as published by
13*37ab8232Snerun * the Free Software Foundation; either version 2 of the License, or
14*37ab8232Snerun * (at your option) any later version.
15*37ab8232Snerun *
16*37ab8232Snerun * This program is distributed in the hope that it will be useful,
17*37ab8232Snerun * but WITHOUT ANY WARRANTY; without even the implied warranty of
18*37ab8232Snerun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19*37ab8232Snerun * GNU General Public License for more details.
20*37ab8232Snerun *
21*37ab8232Snerun * You should have received a copy of the GNU General Public License along
22*37ab8232Snerun * with this program; if not, see <https://www.gnu.org/licenses/>.
23401a61e7Swikidesign */
24401a61e7Swikidesign
25401a61e7Swikidesignif(!defined('DOKU_INC')) die();
26401a61e7Swikidesign
27401a61e7Swikidesignclass syntax_plugin_avatar extends DokuWiki_Syntax_Plugin {
28401a61e7Swikidesign
2923415f0dSnerun    const SIZE_SMALL = 20;
3023415f0dSnerun    const SIZE_MEDIUM = 40;
3123415f0dSnerun    const SIZE_LARGE = 80;
3223415f0dSnerun    const SIZE_XLARGE = 120;
33401a61e7Swikidesign
3423415f0dSnerun    public function getType(): string { return 'substition'; }
3523415f0dSnerun    public function getSort(): int { return 315; }
3623415f0dSnerun
3723415f0dSnerun    public function connectTo($mode): void {
38401a61e7Swikidesign        $this->Lexer->addSpecialPattern("{{(?:gr|)avatar>.+?}}", $mode, 'plugin_avatar');
39401a61e7Swikidesign    }
40401a61e7Swikidesign
41f994dce8Snerun    public function handle($match, $state, $pos, Doku_Handler $handler): ?array {
42f994dce8Snerun        $parts = explode('>', substr($match, 2, -2), 2);
43197ce240Snerun
44f994dce8Snerun        if (count($parts) !== 2) {
45f994dce8Snerun            return null; // Malformed input → discards and interrupts handle()
46401a61e7Swikidesign        }
47401a61e7Swikidesign
48f994dce8Snerun        $match = $parts[1]; //  $parts[0] = 'avatar' or 'gravatar'
49f994dce8Snerun
50f874a7c6Snerun        if (!preg_match('/^([^?|]+)(?:\?([^|]*))?(?:\|(.*))?$/', $match, $matches)) {
513c4ea843Snerun            return null;
52f994dce8Snerun        }
53f994dce8Snerun
54e656ef4bSnerun        $user = $matches[1];
55f994dce8Snerun
56f994dce8Snerun        /* Final check:
57f994dce8Snerun         * Even if something strange slipped through the first regex, here the
58f994dce8Snerun         * string is checked in isolation. This ensures that the renderer will
59f994dce8Snerun         * only receive a clean username or a valid email, preventing parsing
60f994dce8Snerun         * problems, CSS errors, HTML injection, etc.
61f994dce8Snerun         */
62e656ef4bSnerun        if (filter_var($user, FILTER_VALIDATE_EMAIL) === false &&
63e656ef4bSnerun            !preg_match('/^\s*[a-zA-Z0-9._-]+\s*$/', $user)) {
64f994dce8Snerun            return null;
65f994dce8Snerun        }
66f994dce8Snerun
6723415f0dSnerun        $param = isset($matches[2]) ? trim(strtolower($matches[2])) : '';
6823415f0dSnerun        $title = isset($matches[3]) ? trim($matches[3]) : '';
6923415f0dSnerun
7023415f0dSnerun        // Determine alignment
7123415f0dSnerun        $align = null;
72f994dce8Snerun        if ($user !== ltrim($user)) $align = 'right';
73f994dce8Snerun        if ($user !== rtrim($user)) $align = $align ? 'center' : 'left';
7423415f0dSnerun        $user = trim($user);
7523415f0dSnerun
7623415f0dSnerun        // Determine size
7723415f0dSnerun        switch ($param) {
7823415f0dSnerun            case 's':  $size = self::SIZE_SMALL; break;
7923415f0dSnerun            case 'm':  $size = self::SIZE_MEDIUM; break;
8023415f0dSnerun            case 'l':  $size = self::SIZE_LARGE; break;
8123415f0dSnerun            case 'xl': $size = self::SIZE_XLARGE; break;
824cc391acSnerun            default:
834cc391acSnerun                $size = max(1, (int) $this->getConf('size')) ?: self::SIZE_MEDIUM;
844cc391acSnerun                break;
8523415f0dSnerun        }
8623415f0dSnerun
8723415f0dSnerun        return [$user, $title, $align, $size];
8823415f0dSnerun    }
8923415f0dSnerun
9023415f0dSnerun    public function render($mode, Doku_Renderer $renderer, $data): bool {
9123415f0dSnerun        if ($mode !== 'xhtml') return false;
9223415f0dSnerun
93f994dce8Snerun        if ($data === null) {
94f994dce8Snerun            $renderer->doc .= '<span style="color:red;font-family:monospace;' .
95f994dce8Snerun                              'font-weight:bold;">' .
96f994dce8Snerun                              'Error: Avatar plugin: Invalid username or' .
97f994dce8Snerun                              ' email</span>';
98f994dce8Snerun            return true;
99f994dce8Snerun        }
100f994dce8Snerun
10123415f0dSnerun        if ($my = plugin_load('helper', 'avatar')) {
1022f05229bSwikidesign            $renderer->doc .= '<span class="vcard">' .
103986bb475Snerun                $my->renderXhtml($data[0], $data[1], $data[2], $data[3]) .
1042f05229bSwikidesign                '</span>';
10523415f0dSnerun        }
106401a61e7Swikidesign        return true;
107401a61e7Swikidesign    }
108401a61e7Swikidesign}
109