1<?php
2/**
3 * AutoLink 4 DokuWiki plugin
4 *
5 * @license    MIT
6 * @author     Eli Fenton
7 */
8if(!defined('DOKU_INC')) die();
9require_once(DOKU_PLUGIN.'autolink4/consts.php');
10
11class helper_plugin_autolink4 extends DokuWiki_Plugin {
12	use autotooltip4_consts;
13	const CONFIG_FILE = DOKU_CONF . 'autolink4.conf';
14
15	static $didInit = false;
16	static $subs = [];
17	static $regexSubs = [];
18	static $simpleSubs = [];
19
20
21	public function getSubs() {
22		return self::$subs; //TODO: Remove this later?
23	}
24	public function getRegexSubs() {
25		return self::$regexSubs;
26	}
27	public function getSimpleSubs() {
28		return self::$simpleSubs;
29	}
30
31	/**
32	 * Saves the config file
33	 *
34	 * @param string $config the raw text for the config
35	 * @return bool
36	 */
37	public function saveConfigFile($config) {
38		return io_saveFile(self::CONFIG_FILE, cleanText($config));
39	}
40
41
42	/**
43	 * Load the config file
44	 */
45	public function loadConfigFile() {
46		if (file_exists(self::CONFIG_FILE)) {
47			return io_readFile(self::CONFIG_FILE);
48		}
49	}
50
51
52	/**
53	 * Load the config file
54	 */
55	public function loadAndProcessConfigFile() {
56		// Only load once, so we don't re-process with things like plugin:include.
57		if (self::$didInit) {
58			return;
59		}
60		self::$didInit = true;
61
62		if (file_exists(self::CONFIG_FILE)) {
63			$cfg = io_readFile(self::CONFIG_FILE);
64
65			// Convert the config into usable data.
66			$lines = preg_split('/[\n\r]+/', $cfg);
67			foreach ($lines as $line) {
68				$line = trim($line);
69				if (strlen($line)) {
70					$data = str_getcsv($line);
71					if (strlen($data[self::$ORIG]) && strlen($data[self::$TO])) {
72						$orig = trim($data[self::$ORIG]);
73
74						// utf-8 codes don't work with addSpecialPattern().
75						// https://github.com/splitbrain/dokuwiki/issues/856
76						// This fix to hex-escape byte codes does not help:
77						//if (strlen($orig) != mb_strlen($orig, 'UTF8')) {
78						//	$orig = '\\x' . implode('\\x', str_split(implode('', unpack('H*', $orig)), 2));
79						//}
80						$s = [];
81						$s[self::$ORIG] = $orig;
82						$s[self::$TO] = trim($data[self::$TO]);
83						$s[self::$IN] = isset($data[self::$IN]) ? trim($data[self::$IN]) : null;
84						$s[self::$FLAGS] = isset($data[self::$FLAGS]) ? trim($data[self::$FLAGS]) : null;
85						$s[self::$TOOLTIP] = isset($data[self::$FLAGS]) ? strstr($data[self::$FLAGS], 'tt') !== FALSE : false;
86						$s[self::$ONCE] = isset($data[self::$FLAGS]) ? strstr($data[self::$FLAGS], 'once') !== FALSE : false;
87						$s[self::$INWORD] = isset($data[self::$FLAGS]) ? strstr($data[self::$FLAGS], 'inword') !== FALSE : false;
88
89						// Add word breaks, and collapse one space (allows newlines).
90						if ($s[self::$INWORD]) {
91							$s[self::$MATCH] = preg_replace('/ /', '\s', $orig);
92						}
93						else {
94							$s[self::$MATCH] = '\b' . preg_replace('/ /', '\s', $orig) . '\b';
95						}
96
97						self::$subs[] = $s;
98
99						if (preg_match('/[\\\[?.+*^$]/', $orig)) {
100							self::$regexSubs[] = $s;
101						}
102						else {
103							// If the search string is not a regex, cache it right away, so we don't have to loop
104							// through regexes later.
105							self::$simpleSubs[$orig] = $s;
106							self::$simpleSubs[$orig][self::$TEXT] = $orig;
107						}
108					}
109				}
110			}
111		}
112	}
113}
114