This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * gwikiPage.php - class to access wiki page data |
||
4 | * |
||
5 | * This file is part of gwiki - geekwright wiki |
||
6 | */ |
||
7 | |||
8 | // defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined'); |
||
9 | |||
10 | define('_WIKI_CAMELCASE_REGEX', '(([A-Z]{1,}[a-z\x80-\xff0-9\:]+){2,}\d*)'); |
||
11 | define('_WIKI_KEYWORD_REGEX', '([A-Za-z\x80-\xff0-9.\:-]{1,})'); |
||
12 | |||
13 | /** |
||
14 | * gwikiPage.php - class to access wiki page data |
||
15 | * |
||
16 | * |
||
17 | * @category Class |
||
18 | * @package Gwiki |
||
19 | * @author Richard Griffith <[email protected]> |
||
20 | * @copyright 2013-2015 geekwright, LLC. All rights reserved. |
||
21 | * @license gwiki/docs/license.txt GNU General Public License (GPL) |
||
22 | */ |
||
23 | class GwikiPage |
||
24 | { |
||
25 | //------------------------------------------------------------ |
||
26 | // Properties - public, protected, and private |
||
27 | //------------------------------------------------------------ |
||
28 | |||
29 | protected $currentid; |
||
30 | protected $currentkeyword; |
||
31 | public $gwiki_id; |
||
32 | public $keyword; |
||
33 | public $display_keyword; |
||
34 | public $title; |
||
35 | public $body; |
||
36 | public $parent_page; |
||
37 | public $page_set_home; |
||
38 | public $page_set_order; |
||
39 | public $meta_description; |
||
40 | public $meta_keywords; |
||
41 | public $lastmodified; |
||
42 | public $uid; |
||
43 | public $admin_lock; |
||
44 | public $active; |
||
45 | public $search_body; |
||
46 | public $toc_cache; |
||
47 | public $show_in_index; |
||
48 | public $gwiki_version; |
||
49 | |||
50 | public $page_id; // an integer id for the keyword |
||
51 | public $wikiHomePage; // the home page |
||
52 | public $currentprefix; // Prefix of current keyword, if any |
||
53 | public $currentprefixid; // id of current Prefix |
||
54 | public $currenttemplateid; // template for current Prefix (0=use default) |
||
55 | public $attachments; |
||
56 | |||
57 | public $renderedPage; |
||
58 | |||
59 | private $numberOfRecentItems = 10; |
||
60 | // $wikiLinkURL is a sprintf format string, with keyword as only arg. Better link establised in __construct() |
||
61 | private $wikiLinkURL = 'index.php?page=%s'; |
||
62 | public $dateFormat; |
||
63 | public $defaultThumbSize; |
||
64 | private $tocIdPrefix = 'toc'; |
||
65 | private $tocAnchorFmt = '#%s'; |
||
66 | private $imageLib = array(); |
||
67 | private $useCamelCase; |
||
68 | private $autoNameFormat; |
||
69 | |||
70 | private $module_id; |
||
71 | |||
72 | private $wikiDir; // dirname of the gwiki module |
||
73 | private $gwikiVersion = 1; // wiki syntax version for future backward compatibility |
||
74 | |||
75 | private $highlightArg; |
||
76 | |||
77 | private $noWikiQueue = array(); // hold no wiki content during rendering |
||
78 | private $noWikiIndex = 0; |
||
79 | |||
80 | private $tocQueue = array(); // track headers for toc |
||
81 | private $tocIndex = 0; |
||
82 | |||
83 | private $refQueue = array(); // track reference |
||
84 | private $refIndex = 0; |
||
85 | private $refShown = false; |
||
86 | |||
87 | private $wikiPageLinks = array(); // link in current page |
||
88 | |||
89 | // Out Of Bounds data - not cleared with resetPage |
||
90 | private $pageIndexPrefix = ''; // current prefix for the pageindex |
||
91 | |||
92 | //------------------------------------------------------------ |
||
93 | // Methods |
||
94 | //------------------------------------------------------------ |
||
95 | |||
96 | /** |
||
97 | * class constructor |
||
98 | */ |
||
99 | public function __construct() |
||
100 | { |
||
101 | $this->resetPage(); |
||
102 | $dir = basename(dirname(__DIR__)); |
||
103 | $this->wikiDir = $dir; |
||
104 | |||
105 | $moduleHelper = Xmf\Module\Helper::getHelper($dir); |
||
106 | |||
107 | $this->wikiLinkURL = $moduleHelper->getConfig('wikilink_template'); |
||
108 | $this->wikiHomePage = $moduleHelper->getConfig('wiki_home_page'); |
||
109 | $this->dateFormat = $moduleHelper->getConfig('date_format'); |
||
110 | $this->imageLib = explode(',', $moduleHelper->getConfig('imagelib_pages')); |
||
111 | $this->useCamelCase = $moduleHelper->getConfig('allow_camelcase'); |
||
112 | $this->defaultThumbSize = $moduleHelper->getConfig('default_thumb_size'); |
||
113 | $this->autoNameFormat = $moduleHelper->getConfig('auto_name_format'); |
||
114 | $this->module_id = $moduleHelper->getModule()->getVar('mid'); |
||
115 | |||
116 | if (!defined('_MI_GWIKI_WIKIHOME')) { |
||
117 | $this->loadLanguage('modinfo', $dir); |
||
118 | } |
||
119 | if (!defined('_MD_GWIKI_PAGE_PERM_EDIT_ANY_NUM')) { |
||
120 | $this->loadLanguage('main', $dir); |
||
121 | } |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * load language resources |
||
126 | * |
||
127 | * @param string $name language file name (main, modinfo, etc.) |
||
128 | * @param string $domain domain/module |
||
129 | * @param null $language language |
||
130 | * |
||
131 | * @return void |
||
132 | */ |
||
133 | View Code Duplication | private function loadLanguage($name, $domain = '', $language = null) |
|
0 ignored issues
–
show
|
|||
134 | { |
||
135 | global $xoopsConfig; |
||
136 | if (!@include_once XOOPS_ROOT_PATH . "/modules/{$domain}/language/" . $xoopsConfig['language'] . "/{$name}.php") { |
||
137 | include_once XOOPS_ROOT_PATH . "/modules/{$domain}/language/english/{$name}.php"; |
||
138 | } |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Reset all page properties |
||
143 | * |
||
144 | * @return void |
||
145 | */ |
||
146 | protected function resetPage() |
||
147 | { |
||
148 | $this->gwiki_id = null; |
||
149 | $this->keyword = ''; |
||
150 | $this->display_keyword = ''; |
||
151 | $this->title = ''; |
||
152 | $this->body = ''; |
||
153 | $this->parent_page = ''; |
||
154 | $this->page_set_home = ''; |
||
155 | $this->page_set_order = ''; |
||
156 | $this->meta_description = ''; |
||
157 | $this->meta_keywords = ''; |
||
158 | $this->lastmodified = 0; |
||
159 | $this->uid = 0; |
||
160 | $this->admin_lock = 0; |
||
161 | $this->active = 0; |
||
162 | $this->search_body = ''; |
||
163 | $this->toc_cache = ''; |
||
164 | $this->show_in_index = 1; |
||
165 | $this->gwiki_version = $this->gwikiVersion; |
||
166 | |||
167 | $this->page_id = 0; |
||
168 | $this->created = 0; |
||
0 ignored issues
–
show
The property
created does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
169 | $this->renderedPage = ''; |
||
170 | $this->currentprefix = ''; |
||
171 | $this->currentprefixid = ''; |
||
172 | $this->currenttemplateid = 0; |
||
173 | $this->attachments = array(); |
||
174 | $this->tocQueue = array(); |
||
175 | $this->tocIndex = 0; |
||
176 | $this->refQueue = array(); |
||
177 | $this->refIndex = 0; |
||
178 | $this->refShown = false; |
||
179 | $this->wikiPageLinks = array(); |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * escape a string to be "safe" for use in database |
||
184 | * |
||
185 | * @param string $value string to be escaped |
||
186 | * |
||
187 | * @return string |
||
188 | */ |
||
189 | public function escapeForDB($value) |
||
190 | { |
||
191 | global $xoopsDB; |
||
192 | |||
193 | return $value = $xoopsDB->escape($value); |
||
0 ignored issues
–
show
$value is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
194 | } |
||
195 | |||
196 | /** |
||
197 | * set the count for recent item list |
||
198 | * |
||
199 | * @param int $count item count |
||
200 | * |
||
201 | * @return void |
||
202 | */ |
||
203 | public function setRecentCount($count) |
||
204 | { |
||
205 | $count = (int)$count; |
||
206 | if ($count > 1 && $count < 1000) { |
||
207 | $this->numberOfRecentItems = $count; |
||
208 | } |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * Set the URL pattern for wiki links |
||
213 | * |
||
214 | * @param string $url sprintf pattern for URL. Will get page name as parameter. |
||
215 | * |
||
216 | * @return void |
||
217 | */ |
||
218 | public function setWikiLinkURL($url) |
||
219 | { |
||
220 | $this->wikiLinkURL = $url; |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * Get the URL pattern for wiki links |
||
225 | * |
||
226 | * @return string |
||
227 | */ |
||
228 | public function getWikiLinkURL() |
||
229 | { |
||
230 | return $this->wikiLinkURL; |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * git the wiki directory (dirname) |
||
235 | * |
||
236 | * @return string |
||
237 | */ |
||
238 | public function getWikiDir() |
||
239 | { |
||
240 | return $this->wikiDir; |
||
241 | } |
||
242 | |||
243 | /** |
||
244 | * get max upload size from ini |
||
245 | * |
||
246 | * @return int|string |
||
247 | */ |
||
248 | public function getMaxUploadSize() |
||
249 | { |
||
250 | $val = trim(ini_get('upload_max_filesize')); |
||
251 | $last = strtolower($val[strlen($val) - 1]); |
||
252 | switch ($last) { |
||
253 | // The 'G' modifier is available since PHP 5.1.0 |
||
254 | case 'g': |
||
255 | $val *= 1024; |
||
256 | // no break |
||
257 | case 'm': |
||
258 | $val *= 1024; |
||
259 | // no break |
||
260 | case 'k': |
||
261 | $val *= 1024; |
||
262 | // no break |
||
263 | } |
||
264 | |||
265 | return $val; |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * set format for TOC links |
||
270 | * |
||
271 | * @param string $prefix prefix |
||
272 | * @param string $linkformat anchor |
||
273 | * |
||
274 | * @return void |
||
275 | */ |
||
276 | public function setTocFormat($prefix, $linkformat) |
||
277 | { |
||
278 | $this->tocIdPrefix = $prefix; |
||
279 | $this->tocAnchorFmt = $linkformat; |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Make sure that keyword obeys formatting rules or switch to illegal name |
||
284 | * |
||
285 | * @param mixed $keyword - wiki page name |
||
286 | * |
||
287 | * @return string |
||
288 | */ |
||
289 | public function makeKeyword($keyword) |
||
290 | { |
||
291 | if (!preg_match('#^' . _WIKI_KEYWORD_REGEX . '$#', $keyword)) { |
||
292 | $keyword = _MI_GWIKI_WIKI404; |
||
293 | } else { // check for undefined prefix |
||
294 | $prefix = $this->getPrefix($keyword); |
||
295 | if ($prefix && !$prefix['defined']) { |
||
296 | $keyword = _MI_GWIKI_WIKI404; |
||
297 | } |
||
298 | } |
||
299 | |||
300 | return $keyword; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * add namespace prefix to a wiki word |
||
305 | * |
||
306 | * @param int $nsid namespace (prefix) id |
||
307 | * @param string $page keyword |
||
308 | * |
||
309 | * @return bool|string |
||
310 | */ |
||
311 | public function makeKeywordFromPrefix($nsid, $page) |
||
312 | { |
||
313 | if ($nsid >= 0) { |
||
314 | $pfx = $this->getPrefixFromId($nsid); |
||
315 | if (empty($page)) { |
||
316 | if ($pfx['prefix_auto_name']) { |
||
317 | $page = date($this->autoNameFormat); |
||
318 | } else { |
||
319 | $page = $pfx['prefix_home']; |
||
320 | } |
||
321 | } |
||
322 | $page = $pfx['prefix'] . ':' . $page; |
||
323 | } |
||
324 | |||
325 | return $page; |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * Capture out of bounds data traveling with keyword. Such data is sent |
||
330 | * in keyword(oob) construct. This function processes any oob data and |
||
331 | * returns a clean keyword. |
||
332 | * oob data is used this way to pass page specific data in any url |
||
333 | * |
||
334 | * Only call this if you will NOT be calling normalizeKeyword or the |
||
335 | * OOB data will be lost. |
||
336 | * |
||
337 | * @param mixed $keyword - wiki page name possibily containing OOB data |
||
338 | * |
||
339 | * @return string - keyword with no OOB data |
||
340 | */ |
||
341 | public function getOOBFromKeyword($keyword) |
||
342 | { |
||
343 | $oob = null; |
||
344 | if (substr($keyword, -1) === ')') { |
||
345 | $lparen = strpos($keyword, '('); |
||
346 | if ($lparen !== false) { |
||
347 | $inparen = substr($keyword, $lparen); |
||
348 | $inparen = substr($inparen, 1, -2); |
||
349 | $keyword = substr($keyword, 0, $lparen); |
||
350 | $oob = $inparen; |
||
351 | } |
||
352 | } |
||
353 | // currently this is the only use |
||
354 | $this->pageIndexPrefix = strtolower($oob); |
||
355 | |||
356 | return $keyword; |
||
357 | } |
||
358 | |||
359 | /** |
||
360 | * If page exists, fix case of page name to that specified in database |
||
361 | * |
||
362 | * @param string $keyword - wiki page name |
||
363 | * |
||
364 | * @return string normalized keyword |
||
365 | */ |
||
366 | public function normalizeKeyword($keyword) |
||
367 | { |
||
368 | global $xoopsDB; |
||
369 | |||
370 | $keyword = $this->getOOBFromKeyword($keyword); |
||
371 | $keyword = $this->escapeForDB($keyword); |
||
372 | $sql = 'SELECT keyword FROM ' . $xoopsDB->prefix('gwiki_pages') . " WHERE keyword='{$keyword}' AND active=1 "; |
||
373 | $result = $xoopsDB->query($sql); |
||
374 | if ($content = $xoopsDB->fetchArray($result)) { |
||
375 | $keyword = $content['keyword']; |
||
376 | } else { |
||
377 | $keyword = $this->makeKeyword($keyword); |
||
378 | } |
||
379 | |||
380 | return $keyword; |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * Get the gwiki_id of the active page for the keyword |
||
385 | * |
||
386 | * @param mixed $keyword - wiki page name |
||
387 | * |
||
388 | * @return int - id of page |
||
389 | */ |
||
390 | public function getCurrentId($keyword) |
||
391 | { |
||
392 | global $xoopsDB; |
||
393 | |||
394 | $sql = 'SELECT gwiki_id FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
395 | $sql .= " WHERE keyword='{$keyword}' AND active = 1 ORDER BY gwiki_id DESC LIMIT 1"; |
||
396 | $result = $xoopsDB->query($sql); |
||
397 | list($id) = $xoopsDB->fetchRow($result); |
||
398 | |||
399 | return (int)$id; |
||
400 | } |
||
401 | |||
402 | /** |
||
403 | * Add current page as a new revision |
||
404 | * |
||
405 | * @param bool $leave_inactive true to save page as inactive |
||
406 | * |
||
407 | * @return mixed |
||
408 | */ |
||
409 | public function addRevision($leave_inactive = false) |
||
410 | { |
||
411 | global $xoopsDB; |
||
412 | |||
413 | $page = $this->escapeForDB($this->keyword); |
||
414 | if (empty($this->display_keyword)) { |
||
415 | $this->display_keyword = $page; |
||
416 | } |
||
417 | $this->tocQueue = array(); |
||
418 | $this->tocIndex = 0; |
||
419 | $this->refQueue = array(); |
||
420 | $this->refIndex = 0; |
||
421 | $this->wikiPageLinks = array(); |
||
422 | |||
423 | // eliminate things we don't want in search page because they |
||
424 | // are misleading and/or change outside of the page itself |
||
425 | $search[] = "#{(PageIndex|RecentChanges)([^\"<\n]+?)?}#si"; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$search was never initialized. Although not strictly required by PHP, it is generally a good practice to add $search = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
426 | $replace[] = ''; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$replace was never initialized. Although not strictly required by PHP, it is generally a good practice to add $replace = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
427 | $search[] = "#\{toc\}#i"; |
||
428 | $replace[] = ''; |
||
429 | $search[] = "#\{pagesettoc\}#i"; |
||
430 | $replace[] = ''; |
||
431 | $tempbody = preg_replace($search, $replace, $this->body) . "\n\n"; |
||
432 | |||
433 | $this->search_body = strip_tags($this->renderPage($tempbody)); |
||
434 | $this->toc_cache = serialize($this->tocQueue); |
||
435 | $this->gwiki_version = $this->gwikiVersion; // new revisions always for current engine |
||
436 | |||
437 | // if we are adding to a page set, auto increment the order if none specified |
||
438 | if (!empty($this->page_set_home) && $this->page_set_order === '') { |
||
439 | $this->page_set_order = $this->getNextPageSetOrder($this->page_set_home); |
||
440 | } |
||
441 | |||
442 | // this will usually fail (duplicate) |
||
443 | $sql = 'INSERT INTO ' . $xoopsDB->prefix('gwiki_pageids') . " (keyword, created) VALUES('{$page}', UNIX_TIMESTAMP())"; |
||
444 | $result = $xoopsDB->query($sql); |
||
445 | if ($result) { |
||
446 | $page_id = $xoopsDB->getInsertId(); |
||
447 | $this->page_id = $page_id; |
||
448 | } |
||
449 | if ($leave_inactive) { |
||
450 | // allow a save that is not activated (for conflict management, and maybe more) |
||
451 | $this->active = 0; |
||
452 | $sql = 'INSERT INTO ' . $xoopsDB->prefix('gwiki_pages'); |
||
453 | $sql .= ' (keyword, display_keyword, title, body, parent_page, page_set_home, page_set_order'; |
||
454 | $sql .= ', meta_description, meta_keywords'; |
||
455 | $sql .= ', lastmodified, uid, admin_lock, active, search_body, toc_cache, show_in_index, gwiki_version)'; |
||
456 | $sql .= ' VALUES ('; |
||
457 | $sql .= '\'' . $page . '\' ,'; |
||
458 | $sql .= '\'' . $this->escapeForDB($this->display_keyword) . '\' ,'; |
||
459 | $sql .= '\'' . $this->escapeForDB($this->title) . '\' ,'; |
||
460 | $sql .= '\'' . $this->escapeForDB($this->body) . '\' ,'; |
||
461 | $sql .= '\'' . $this->escapeForDB($this->parent_page) . '\' ,'; |
||
462 | $sql .= '\'' . $this->escapeForDB($this->page_set_home) . '\' ,'; |
||
463 | $sql .= '\'' . $this->escapeForDB($this->page_set_order) . '\' ,'; |
||
464 | $sql .= '\'' . $this->escapeForDB($this->meta_description) . '\' ,'; |
||
465 | $sql .= '\'' . $this->escapeForDB($this->meta_keywords) . '\' ,'; |
||
466 | $sql .= 'UNIX_TIMESTAMP() ,'; |
||
467 | $sql .= '\'' . $this->escapeForDB($this->uid) . '\' ,'; |
||
468 | $sql .= '\'' . $this->escapeForDB($this->admin_lock) . '\' ,'; |
||
469 | $sql .= '\'' . $this->escapeForDB($this->active) . '\' ,'; |
||
470 | $sql .= '\'' . $this->escapeForDB($this->search_body) . '\' ,'; |
||
471 | $sql .= '\'' . $this->escapeForDB($this->toc_cache) . '\' ,'; |
||
472 | $sql .= '\'' . $this->escapeForDB($this->show_in_index) . '\' ,'; |
||
0 ignored issues
–
show
$this->show_in_index is of type integer|boolean , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
473 | $sql .= '\'' . $this->escapeForDB($this->gwiki_version) . '\' )'; |
||
474 | $result = $xoopsDB->query($sql); |
||
475 | if ($result) { |
||
476 | $result = $xoopsDB->getInsertId(); |
||
477 | $this->gwiki_id = $result; |
||
478 | } |
||
479 | } else { |
||
480 | $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET active = 0 WHERE keyword='{$page}' and active = 1 "; |
||
481 | $result = $xoopsDB->query($sql); |
||
482 | if ($result) { |
||
483 | $previous_rows = $xoopsDB->getAffectedRows(); |
||
484 | $this->active = 1; |
||
485 | $sql = 'INSERT INTO ' . $xoopsDB->prefix('gwiki_pages'); |
||
486 | $sql .= ' (keyword, display_keyword, title, body, parent_page, page_set_home, page_set_order'; |
||
487 | $sql .= ', meta_description, meta_keywords, lastmodified'; |
||
488 | $sql .= ', uid, admin_lock, active, search_body, toc_cache, show_in_index, gwiki_version)'; |
||
489 | $sql .= ' VALUES ('; |
||
490 | $sql .= '\'' . $page . '\' ,'; |
||
491 | $sql .= '\'' . $this->escapeForDB($this->display_keyword) . '\' ,'; |
||
492 | $sql .= '\'' . $this->escapeForDB($this->title) . '\' ,'; |
||
493 | $sql .= '\'' . $this->escapeForDB($this->body) . '\' ,'; |
||
494 | $sql .= '\'' . $this->escapeForDB($this->parent_page) . '\' ,'; |
||
495 | $sql .= '\'' . $this->escapeForDB($this->page_set_home) . '\' ,'; |
||
496 | $sql .= '\'' . $this->escapeForDB($this->page_set_order) . '\' ,'; |
||
497 | $sql .= '\'' . $this->escapeForDB($this->meta_description) . '\' ,'; |
||
498 | $sql .= '\'' . $this->escapeForDB($this->meta_keywords) . '\' ,'; |
||
499 | $sql .= 'UNIX_TIMESTAMP() ,'; |
||
500 | $sql .= '\'' . $this->escapeForDB($this->uid) . '\' ,'; |
||
501 | $sql .= '\'' . $this->escapeForDB($this->admin_lock) . '\' ,'; |
||
502 | $sql .= '\'' . $this->escapeForDB($this->active) . '\' ,'; |
||
503 | $sql .= '\'' . $this->escapeForDB($this->search_body) . '\' ,'; |
||
504 | $sql .= '\'' . $this->escapeForDB($this->toc_cache) . '\' ,'; |
||
505 | $sql .= '\'' . $this->escapeForDB($this->show_in_index) . '\' ,'; |
||
0 ignored issues
–
show
$this->show_in_index is of type integer|boolean , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
506 | $sql .= '\'' . $this->escapeForDB($this->gwiki_version) . '\' )'; |
||
507 | $result = $xoopsDB->query($sql); |
||
508 | if ($result) { |
||
509 | $result = $xoopsDB->getInsertId(); |
||
510 | $this->gwiki_id = $result; |
||
511 | |||
512 | $this->updatePageLinks(); |
||
513 | |||
514 | $notificationHandler = xoops_getHandler('notification'); |
||
515 | $tags['PAGE_NAME'] = $page; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$tags was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tags = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
516 | $tags['PAGE_TITLE'] = $this->title; |
||
517 | if (empty($tags['PAGE_TITLE'])) { |
||
518 | $tags['PAGE_TITLE'] = $this->display_keyword; |
||
519 | } |
||
520 | if (empty($tags['PAGE_TITLE'])) { |
||
521 | $tags['PAGE_TITLE'] = $page; |
||
522 | } |
||
523 | $tags['PAGE_LINK'] = sprintf($this->wikiLinkURL, $page); |
||
524 | $tags['NAMESPACE'] = $this->currentprefix; |
||
525 | |||
526 | if ($previous_rows < 1) { |
||
527 | // only for new |
||
528 | $notificationHandler->triggerEvent('global', 0, 'new_page', $tags, array(), $this->module_id); |
||
529 | if ($this->currentprefixid) { // have namespace |
||
530 | $notificationHandler->triggerEvent('namespace', $this->currentprefixid, 'new_ns_page', $tags, array(), $this->module_id); |
||
531 | } |
||
532 | } |
||
533 | // for all cases (new is also an update) |
||
534 | $notificationHandler->triggerEvent('page', $this->page_id, 'page_watch', $tags, array(), $this->module_id); |
||
535 | $notificationHandler->triggerEvent('global', 0, 'upd_page', $tags, array(), $this->module_id); |
||
536 | if ($this->currentprefixid) { // have namespace |
||
537 | $notificationHandler->triggerEvent('namespace', $this->currentprefixid, 'upd_ns_page', $tags, array(), $this->module_id); |
||
538 | } |
||
539 | } |
||
540 | } |
||
541 | } |
||
542 | |||
543 | return $result; |
||
544 | } |
||
545 | |||
546 | /** |
||
547 | * update gwiki_pagelinks table - expects $page to be current |
||
548 | * |
||
549 | * @param bool $render do a fresh page render before updating |
||
550 | * |
||
551 | * @return void |
||
552 | */ |
||
553 | private function updatePageLinks($render = false) |
||
554 | { |
||
555 | global $xoopsDB; |
||
556 | |||
557 | if ($render) { |
||
558 | // eliminate things we don't want in search page because they |
||
559 | // are misleading and/or change outside of the page itself |
||
560 | $search[] = "#{(PageIndex|RecentChanges)([^\"<\n]+?)?}#si"; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$search was never initialized. Although not strictly required by PHP, it is generally a good practice to add $search = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
561 | $replace[] = ''; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$replace was never initialized. Although not strictly required by PHP, it is generally a good practice to add $replace = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
562 | $search[] = "#\{toc\}#i"; |
||
563 | $replace[] = ''; |
||
564 | $search[] = "#\{pagesettoc\}#i"; |
||
565 | $replace[] = ''; |
||
566 | $tempbody = preg_replace($search, $replace, $this->body) . "\n\n"; |
||
567 | |||
568 | $this->renderPage($tempbody); |
||
569 | } |
||
570 | $page = $this->escapeForDB($this->keyword); |
||
571 | |||
572 | $sql = 'DELETE FROM ' . $xoopsDB->prefix('gwiki_pagelinks'); |
||
573 | $sql .= ' WHERE from_keyword = \'' . $page . '\''; |
||
574 | $result = $xoopsDB->query($sql); |
||
0 ignored issues
–
show
$result is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
575 | |||
576 | if (!empty($this->wikiPageLinks)) { |
||
577 | $sql = 'INSERT INTO ' . $xoopsDB->prefix('gwiki_pagelinks') . ' (from_keyword, to_keyword) VALUES '; |
||
578 | $values = ''; |
||
579 | foreach ($this->wikiPageLinks as $i => $v) { |
||
580 | if (!empty($values)) { |
||
581 | $values .= ', '; |
||
582 | } |
||
583 | $values .= '(\'' . $page . '\', \'' . $this->escapeForDB($i) . '\')'; |
||
584 | } |
||
585 | $sql .= $values; |
||
586 | $result = $xoopsDB->query($sql); |
||
0 ignored issues
–
show
$result is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
587 | } |
||
588 | |||
589 | return; |
||
590 | } |
||
591 | |||
592 | /** |
||
593 | * get the next higher unused page_set_order for a given page_set_home |
||
594 | * |
||
595 | * @param string $page_set_home keyword of page set home |
||
596 | * |
||
597 | * @return int |
||
598 | */ |
||
599 | View Code Duplication | private function getNextPageSetOrder($page_set_home) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
600 | { |
||
601 | global $xoopsDB; |
||
602 | |||
603 | $page_set_order = 1; |
||
604 | |||
605 | $keyword = $this->escapeForDB($page_set_home); |
||
606 | |||
607 | $sql = 'SELECT MAX(page_set_order) FROM ' . $xoopsDB->prefix('gwiki_pages') . " WHERE active = 1 and page_set_home = '{$keyword}' "; |
||
608 | $result = $xoopsDB->query($sql); |
||
609 | if ($result) { |
||
610 | $myrow = $xoopsDB->fetchRow($result); |
||
611 | $page_set_order = $myrow[0] + 1; |
||
612 | } |
||
613 | |||
614 | return $page_set_order; |
||
615 | } |
||
616 | |||
617 | /** |
||
618 | * Check if the current user may edit the current page |
||
619 | * Since the class can be used outside the module where permissions are assigned, we have to work at this a bit |
||
620 | * |
||
621 | * @return boolean mayEdit |
||
622 | */ |
||
623 | public function checkEdit() |
||
624 | { |
||
625 | global $xoopsUser, $xoopsDB; |
||
626 | |||
627 | $mayEdit = false; |
||
628 | $keyword = $this->keyword; |
||
629 | |||
630 | $module_id = $this->module_id; |
||
631 | $groups = XOOPS_GROUP_ANONYMOUS; |
||
632 | if (is_object($xoopsUser)) { |
||
633 | $groups = $xoopsUser->getGroups(); |
||
634 | } |
||
635 | |||
636 | $gpermHandler = xoops_getHandler('groupperm'); |
||
637 | |||
638 | $edit_any = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_EDIT_ANY_NUM, $groups, $module_id); |
||
639 | $edit_pfx = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_EDIT_PFX_NUM, $groups, $module_id); |
||
640 | $create_any = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_CREATE_ANY_NUM, $groups, $module_id); |
||
641 | $create_pfx = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_CREATE_PFX_NUM, $groups, $module_id); |
||
642 | |||
643 | // check for namespace prefix |
||
644 | $prefix = $this->getPrefix($keyword); |
||
645 | if ($prefix) { |
||
646 | if ($prefix['defined']) { |
||
647 | View Code Duplication | if (is_array($groups)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
648 | $groupwhere = ' IN (' . implode(', ', $groups) . ') '; |
||
649 | } else { |
||
650 | $groupwhere = " = '" . $groups . "'"; |
||
651 | } |
||
652 | $sql = 'SELECT group_prefix_id FROM ' . $xoopsDB->prefix('gwiki_group_prefix') . ' WHERE prefix_id = \'' . $prefix['prefix_id'] . '\' AND group_id ' . $groupwhere; |
||
653 | $result = $xoopsDB->query($sql); |
||
654 | $rows = $xoopsDB->getRowsNum($result); |
||
655 | $xoopsDB->freeRecordSet($result); |
||
656 | if ($rows) { // prefix is assigned to one or more of user's groups |
||
657 | if (($edit_pfx || $create_pfx) && $this->gwiki_id) { |
||
658 | $mayEdit = true; |
||
659 | } |
||
660 | if ($create_pfx && !$this->gwiki_id) { |
||
661 | $mayEdit = true; |
||
662 | } |
||
663 | } |
||
664 | if (($edit_any || $create_any) && $this->gwiki_id) { |
||
665 | $mayEdit = true; |
||
666 | } |
||
667 | if ($create_any && !$this->gwiki_id) { |
||
668 | $mayEdit = true; |
||
669 | } |
||
670 | } else { // allow edit, but no create if prefix is undefined |
||
671 | if ($edit_any && $this->gwiki_id) { |
||
672 | $mayEdit = true; |
||
673 | } |
||
674 | } |
||
675 | } else { |
||
676 | if (($edit_any || $create_any) && $this->gwiki_id) { |
||
677 | $mayEdit = true; |
||
678 | } |
||
679 | if ($create_any && !$this->gwiki_id) { |
||
680 | $mayEdit = true; |
||
681 | } |
||
682 | } |
||
683 | |||
684 | return $mayEdit; |
||
685 | } |
||
686 | |||
687 | /** |
||
688 | * get user name based on id |
||
689 | * |
||
690 | * @param int $uid user id |
||
691 | * |
||
692 | * @return string |
||
693 | */ |
||
694 | View Code Duplication | public function getUserName($uid) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
695 | { |
||
696 | global $xoopsConfig; |
||
697 | |||
698 | $uid = (int)$uid; |
||
699 | |||
700 | if ($uid > 0) { |
||
701 | $memberHandler = xoops_getHandler('member'); |
||
702 | $user = $memberHandler->getUser($uid); |
||
703 | if (is_object($user)) { |
||
704 | return "<a href=\"" . XOOPS_URL . "/userinfo.php?uid=$uid\">" . htmlspecialchars($user->getVar('uname'), ENT_QUOTES) . '</a>'; |
||
705 | } |
||
706 | } |
||
707 | |||
708 | return $xoopsConfig['anonymous']; |
||
709 | } |
||
710 | |||
711 | /** |
||
712 | * get array of prefixes user can edit |
||
713 | * |
||
714 | * @param boolean $createonly true to show only prefixes with create permission |
||
715 | * |
||
716 | * @return string[]|false |
||
717 | */ |
||
718 | public function getUserNamespaces($createonly = false) |
||
719 | { |
||
720 | global $xoopsUser, $xoopsDB; |
||
721 | |||
722 | $module_id = $this->module_id; |
||
723 | |||
724 | $groups = XOOPS_GROUP_ANONYMOUS; |
||
725 | if (is_object($xoopsUser)) { |
||
726 | $groups = $xoopsUser->getGroups(); |
||
727 | } |
||
728 | |||
729 | $gpermHandler = xoops_getHandler('groupperm'); |
||
730 | |||
731 | $edit_any = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_EDIT_ANY_NUM, $groups, $module_id); |
||
732 | $edit_pfx = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_EDIT_PFX_NUM, $groups, $module_id); |
||
733 | $create_any = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_CREATE_ANY_NUM, $groups, $module_id); |
||
734 | $create_pfx = $gpermHandler->checkRight('wiki_authority', _MD_GWIKI_PAGE_PERM_CREATE_PFX_NUM, $groups, $module_id); |
||
735 | |||
736 | View Code Duplication | if (is_array($groups)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
737 | $groupwhere = ' IN (' . implode(', ', $groups) . ') '; |
||
738 | } else { |
||
739 | $groupwhere = " = '" . $groups . "'"; |
||
740 | } |
||
741 | |||
742 | $sql = 'SELECT distinct p.prefix_id, prefix FROM '; |
||
743 | $sql .= $xoopsDB->prefix('gwiki_prefix') . ' p, '; |
||
744 | $sql .= $xoopsDB->prefix('gwiki_group_prefix') . ' g '; |
||
745 | $sql .= ' WHERE group_id ' . $groupwhere; |
||
746 | $sql .= ' AND p.prefix_id = g.prefix_id'; |
||
747 | $sql .= ' ORDER BY prefix '; |
||
748 | $prefixes = array(); |
||
749 | $result = $xoopsDB->query($sql); |
||
750 | if ($create_any) { |
||
751 | $prefixes[] = array('prefix_id' => -1, 'prefix' => ' '); |
||
752 | } |
||
753 | while ($myrow = $xoopsDB->fetchArray($result)) { |
||
754 | $prefixes[] = $myrow; |
||
755 | } |
||
756 | |||
757 | // make sure we have some edit/create permission. We need full keyword to be certain, so let edit sort it out. |
||
758 | $mayEdit = ($edit_any || $create_any || $edit_pfx || $create_pfx); |
||
759 | if ($createonly) { |
||
760 | $mayEdit = ($create_any || $create_pfx); |
||
761 | } |
||
762 | if ($mayEdit) { |
||
763 | return $prefixes; |
||
764 | } |
||
765 | |||
766 | return false; |
||
767 | } |
||
768 | |||
769 | /** |
||
770 | * Get keyword for an id |
||
771 | * |
||
772 | * @param int $page_id id |
||
773 | * |
||
774 | * @return string|null wiki keyword (page) |
||
775 | */ |
||
776 | public function getKeywordById($page_id) |
||
777 | { |
||
778 | global $xoopsDB; |
||
779 | |||
780 | $keyword = null; |
||
781 | |||
782 | $sql = 'SELECT keyword FROM ' . $xoopsDB->prefix('gwiki_pageids') . " WHERE page_id = '{$page_id}' "; |
||
783 | $result = $xoopsDB->query($sql); |
||
784 | if ($result) { |
||
785 | $myrow = $xoopsDB->fetchRow($result); |
||
786 | $keyword = $myrow[0]; |
||
787 | } |
||
788 | |||
789 | return $keyword; |
||
790 | } |
||
791 | |||
792 | /** |
||
793 | * lookup id for a keyword |
||
794 | * |
||
795 | * @param string $keyword keyword |
||
796 | * |
||
797 | * @return int |
||
798 | */ |
||
799 | View Code Duplication | public function getPageId($keyword) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
800 | { |
||
801 | global $xoopsDB; |
||
802 | |||
803 | $page_id = 0; |
||
804 | |||
805 | $keyword = $this->escapeForDB($keyword); |
||
806 | |||
807 | $sql = 'SELECT page_id FROM ' . $xoopsDB->prefix('gwiki_pageids') . " WHERE keyword = '{$keyword}' "; |
||
808 | $result = $xoopsDB->query($sql); |
||
809 | if ($result) { |
||
810 | $myrow = $xoopsDB->fetchRow($result); |
||
811 | $page_id = $myrow[0]; |
||
812 | } |
||
813 | |||
814 | return $page_id; |
||
815 | } |
||
816 | |||
817 | /** |
||
818 | * record a page hit for a keyword |
||
819 | * |
||
820 | * @param string $keyword keyword |
||
821 | * |
||
822 | * @return int count of rows updated |
||
823 | */ |
||
824 | public function registerHit($keyword) |
||
825 | { |
||
826 | global $xoopsDB; |
||
827 | |||
828 | $keyword = $this->escapeForDB($keyword); |
||
829 | |||
830 | $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pageids') . " SET hit_count = hit_count + 1 WHERE keyword = '{$keyword}' "; |
||
831 | $result = $xoopsDB->queryF($sql); |
||
0 ignored issues
–
show
$result is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
832 | |||
833 | // nothing to do if it fails |
||
834 | return $xoopsDB->getAffectedRows(); |
||
835 | } |
||
836 | |||
837 | /** |
||
838 | * set a specific revison as active for a keyword |
||
839 | * |
||
840 | * @param string $keyword wiki keyword |
||
841 | * @param int $id id of revision to activate |
||
842 | * |
||
843 | * @return mixed |
||
844 | */ |
||
845 | public function setRevision($keyword, $id) |
||
846 | { |
||
847 | global $xoopsDB; |
||
848 | |||
849 | $keyword = $this->escapeForDB($keyword); |
||
850 | $id = (int)$id; |
||
851 | |||
852 | $page = $this->getPage($keyword, $id); |
||
853 | if (!$page) { |
||
854 | return false; |
||
855 | } |
||
856 | |||
857 | $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET active = 0 WHERE keyword='{$keyword}' and active = 1 "; |
||
858 | $result = $xoopsDB->query($sql); |
||
0 ignored issues
–
show
$result is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
859 | |||
860 | $sql = 'UPDATE ' . $xoopsDB->prefix('gwiki_pages') . " SET active = 1 WHERE keyword='{$keyword}' AND gwiki_id='{$id}'"; |
||
861 | $result = $xoopsDB->query($sql); |
||
862 | |||
863 | $this->updatePageLinks(true); |
||
864 | |||
865 | return $result; |
||
866 | } |
||
867 | |||
868 | /** |
||
869 | * load a page with optional revision id |
||
870 | * |
||
871 | * @param string $keyword keyword |
||
872 | * @param int|null $id optional page id |
||
873 | * |
||
874 | * @return bool |
||
875 | */ |
||
876 | public function getPage($keyword, $id = null) |
||
877 | { |
||
878 | global $xoopsDB; |
||
879 | |||
880 | $this->resetPage(); |
||
881 | $this->keyword = $keyword; |
||
882 | $prefix = $this->getPrefix($keyword); |
||
883 | if ($prefix && $prefix['defined']) { |
||
884 | $this->currentprefix = $prefix['prefix']; |
||
885 | $this->currentprefixid = $prefix['prefix_id']; |
||
886 | $this->currenttemplateid = $prefix['prefix_template_id']; |
||
887 | } |
||
888 | |||
889 | $keyword = $this->escapeForDB($keyword); |
||
890 | |||
891 | $this->page_id = $this->getPageId($keyword); |
||
892 | |||
893 | if (empty($id)) { |
||
894 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_pages') . ' natural left join ' . $xoopsDB->prefix('gwiki_pageids') . " WHERE keyword='{$keyword}' and active = 1 "; |
||
895 | } else { |
||
896 | $id = (int)$id; |
||
897 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_pages') . ' natural left join ' . $xoopsDB->prefix('gwiki_pageids') . " WHERE keyword='{$keyword}' and gwiki_id = {$id} "; |
||
898 | } |
||
899 | $result = $xoopsDB->query($sql); |
||
900 | $page = false; |
||
901 | $rows = $xoopsDB->getRowsNum($result); |
||
902 | if ($rows > 0) { |
||
903 | $page = $xoopsDB->fetchArray($result); |
||
904 | |||
905 | $this->gwiki_id = $page['gwiki_id']; |
||
906 | $this->keyword = $page['keyword']; |
||
907 | $this->display_keyword = $page['display_keyword']; |
||
908 | $this->title = $page['title']; |
||
909 | $this->body = $page['body']; |
||
910 | $this->parent_page = $page['parent_page']; |
||
911 | |||
912 | $this->page_set_home = $page['page_set_home']; |
||
913 | $this->page_set_order = $page['page_set_order']; |
||
914 | |||
915 | $this->meta_description = $page['meta_description']; |
||
916 | $this->meta_keywords = $page['meta_keywords']; |
||
917 | $this->lastmodified = $page['lastmodified']; |
||
918 | $this->uid = $page['uid']; |
||
919 | $this->admin_lock = $page['admin_lock']; |
||
920 | $this->active = $page['active']; |
||
921 | $this->search_body = $page['search_body']; |
||
922 | $this->toc_cache = $page['toc_cache']; |
||
923 | $this->show_in_index = $page['show_in_index']; |
||
924 | |||
925 | $this->gwiki_version = $page['gwiki_version']; |
||
926 | $this->page_id = $page['page_id']; |
||
927 | $this->created = $page['created']; |
||
928 | |||
929 | $page['author'] = $this->getUserName($page['uid']); |
||
930 | $page['revisiontime'] = date($this->dateFormat, $page['lastmodified']); |
||
931 | $page['createdtime'] = date($this->dateFormat, $page['created']); |
||
932 | $page['createdmonth'] = date('M', $page['created']); |
||
933 | $page['createdday'] = date('d', $page['created']); |
||
934 | $page['createdyear'] = date('Y', $page['created']); |
||
935 | |||
936 | $temp = $this->renderPageSetNav($keyword); |
||
937 | if ($temp) { |
||
938 | $page['pageset'] = $temp; |
||
939 | } |
||
940 | } |
||
941 | |||
942 | return $page; |
||
943 | } |
||
944 | |||
945 | /** |
||
946 | * Check for a prefix (namespace) |
||
947 | * |
||
948 | * @param mixed $keyword - wiki page name |
||
949 | * |
||
950 | * @return bool |
||
951 | */ |
||
952 | public function getPrefix($keyword) |
||
953 | { |
||
954 | /* |
||
955 | gwiki_prefix columns |
||
956 | prefix_id |
||
957 | prefix |
||
958 | prefix_home |
||
959 | prefix_template_id |
||
960 | prefix_is_external |
||
961 | prefix_external_url < sprintf template for page in external namespace |
||
962 | */ |
||
963 | global $xoopsDB; |
||
964 | |||
965 | $prefix = false; |
||
966 | $keyword = $this->escapeForDB($keyword); |
||
967 | |||
968 | $pos = strpos($keyword, ':'); |
||
969 | // split namespace and page reference on first colon |
||
970 | if ($pos !== false && $pos > 0) { |
||
971 | $pre = substr($keyword, 0, $pos); |
||
972 | $page = substr($keyword, $pos + 1); |
||
973 | $q_pre = $this->escapeForDB($pre); |
||
974 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_prefix') . " WHERE prefix='{$q_pre}' "; |
||
975 | $result = $xoopsDB->query($sql); |
||
976 | $rows = $xoopsDB->getRowsNum($result); |
||
977 | if ($rows > 0) { |
||
978 | $prefix = $xoopsDB->fetchArray($result); |
||
979 | if ($page === '') { |
||
980 | $page = $prefix['prefix_home']; |
||
981 | } // supply home page if empty |
||
982 | $prefix['defined'] = true; |
||
983 | // external namespace |
||
984 | if ($prefix['prefix_is_external']) { |
||
985 | $prefix['actual_page'] = sprintf($prefix['prefix_external_url'], $page); |
||
986 | } else { // local namespace |
||
987 | $prefix['actual_page'] = $prefix['prefix'] . ':' . $page; |
||
988 | } |
||
989 | } else { // we have an undefined prefix |
||
990 | $prefix['defined'] = false; |
||
991 | } |
||
992 | } |
||
993 | |||
994 | return $prefix; |
||
995 | } |
||
996 | |||
997 | /** |
||
998 | * get prefix string for an id |
||
999 | * |
||
1000 | * @param int $pid prefix id |
||
1001 | * |
||
1002 | * @return string namespace prefix, or empty string |
||
1003 | */ |
||
1004 | public function getPrefixFromId($pid) |
||
1005 | { |
||
1006 | global $xoopsDB; |
||
1007 | |||
1008 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_prefix') . ' WHERE prefix_id =' . $pid; |
||
1009 | $result = $xoopsDB->query($sql); |
||
1010 | while ($myrow = $xoopsDB->fetchArray($result)) { |
||
1011 | return $myrow; |
||
1012 | } |
||
1013 | |||
1014 | return ''; |
||
1015 | } |
||
1016 | |||
1017 | /** |
||
1018 | * get template for the current page |
||
1019 | * |
||
1020 | * @return string template name |
||
1021 | */ |
||
1022 | public function getTemplateName() |
||
1023 | { |
||
1024 | $template = 'gwiki_view.tpl'; |
||
1025 | if ($this->currenttemplateid) { |
||
1026 | $template = $this->wikiDir . '_prefix_' . $this->currentprefixid . '.tpl'; |
||
1027 | } |
||
1028 | |||
1029 | return $template; |
||
1030 | } |
||
1031 | |||
1032 | /** |
||
1033 | * get attachment info associated with a page |
||
1034 | * |
||
1035 | * @param string $page keyword |
||
1036 | * |
||
1037 | * @return array |
||
1038 | */ |
||
1039 | public function getAttachments($page) |
||
1040 | { |
||
1041 | global $xoopsDB; |
||
1042 | |||
1043 | $this->attachments = array(); |
||
1044 | $q_keyword = $this->escapeForDB($page); |
||
1045 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_page_files') . " WHERE keyword='{$q_keyword}' "; |
||
1046 | $result = $xoopsDB->query($sql); |
||
1047 | $rows = $xoopsDB->getRowsNum($result); |
||
0 ignored issues
–
show
$rows is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
1048 | while ($row = $xoopsDB->fetchArray($result)) { |
||
1049 | $row['iconlink'] = XOOPS_URL . '/modules/' . $this->wikiDir . '/assets/icons/48px/' . $row['file_icon'] . '.png'; |
||
1050 | $row['userlink'] = $this->getUserName($row['file_uid']); |
||
1051 | $row['size'] = number_format($row['file_size']); |
||
1052 | $row['date'] = date($this->dateFormat, $row['file_upload_date']); |
||
1053 | $this->attachments[] = $row; |
||
1054 | } |
||
1055 | |||
1056 | return $this->attachments; |
||
1057 | } |
||
1058 | |||
1059 | /** |
||
1060 | * Make a link from a wiki keyword |
||
1061 | * |
||
1062 | * @param mixed $keyword - wiki page name |
||
1063 | * @param mixed $altkey - alternate text for link. If empty, display_keyword will be used. |
||
1064 | * |
||
1065 | * @return string |
||
1066 | */ |
||
1067 | public function wikiLink($keyword, $altkey = null) |
||
1068 | { |
||
1069 | global $xoopsDB; |
||
1070 | |||
1071 | // HACK - get rid of spaces in page |
||
1072 | // WikiCreole site is filled with page references such as [[Creole 1.0 Poll]] which resolve as |
||
1073 | // hrefs like http://wikicreole.org/wiki/Creole1.0Poll |
||
1074 | // |
||
1075 | // will assume this is considered normal wikiish behavior, and try to emulate. |
||
1076 | // Also seems to capitalize each portion, ie 'Ab and Cd' yields 'AbAndCd' - emulate this, too. |
||
1077 | $org_keyword = $keyword; |
||
1078 | if (strpos(trim($keyword), ' ')) { |
||
1079 | $keys = explode(' ', $keyword); |
||
1080 | foreach ($keys as $i => $k) { |
||
1081 | $keys[$i] = ucfirst($k); |
||
1082 | } |
||
1083 | $keyword = implode('', $keys); |
||
1084 | } |
||
1085 | // $keyword=str_replace (' ', '', $keyword); |
||
1086 | |||
1087 | // check for namespace prefix |
||
1088 | $prefix = $this->getPrefix($keyword); |
||
1089 | if ($prefix && $prefix['defined']) { |
||
1090 | $link = $prefix['actual_page']; |
||
1091 | // external namespace |
||
1092 | if ($prefix['prefix_is_external']) { |
||
1093 | $linktext = $org_keyword; |
||
1094 | if ($altkey) { |
||
1095 | $linktext = $altkey; |
||
1096 | } |
||
1097 | $linktext = stripslashes($linktext); |
||
1098 | $ret = '<a href="' . $link . '" target="_blank" title="' . _MD_GWIKI_PAGE_EXT_LINK_TT . '">' . $linktext . '<span class="wikiextlink"> </span></a>'; |
||
1099 | |||
1100 | return $ret; |
||
1101 | } else { // interal namespace |
||
1102 | $keyword = $link; // we may have modified the keyword |
||
1103 | } |
||
1104 | } |
||
1105 | |||
1106 | $sql = 'SELECT keyword, display_keyword, title FROM ' . $xoopsDB->prefix('gwiki_pages') . " WHERE keyword='{$keyword}' and active = 1 "; |
||
1107 | $result = $xoopsDB->query($sql); |
||
1108 | $rows = $xoopsDB->getRowsNum($result); |
||
1109 | if ($rows) { // existing page |
||
1110 | list($keyword, $display_keyword, $title) = $xoopsDB->fetchRow($result); |
||
1111 | $display_keyword = htmlentities($display_keyword, ENT_QUOTES); |
||
1112 | if (empty($display_keyword)) { |
||
1113 | $display_keyword = $org_keyword; |
||
1114 | } |
||
1115 | $keyword = strtolower($keyword); |
||
1116 | $newpage = ''; |
||
1117 | } else { // new page link |
||
1118 | $display_keyword = $org_keyword; |
||
1119 | $newpage = '<span class="wikinewpage"> </span>'; |
||
1120 | $title = sprintf(_MD_GWIKI_PAGE_CREATE_TT, $keyword); |
||
1121 | } |
||
1122 | if (!empty($altkey)) { |
||
1123 | $display_keyword = $altkey; |
||
1124 | } |
||
1125 | $title = htmlspecialchars($title); |
||
1126 | $display_keyword = stripslashes($display_keyword); |
||
1127 | |||
1128 | // track where this page links |
||
1129 | if (isset($this->wikiPageLinks[$keyword])) { |
||
1130 | ++$this->wikiPageLinks[$keyword]; |
||
1131 | } else { |
||
1132 | $this->wikiPageLinks[$keyword] = 1; |
||
1133 | } |
||
1134 | |||
1135 | $url = sprintf($this->wikiLinkURL, $keyword); |
||
1136 | |||
1137 | return sprintf('<a href="%s" title="%s">%s%s</a>', $url, $title, $display_keyword, $newpage); |
||
1138 | } |
||
1139 | |||
1140 | /** |
||
1141 | * callback |
||
1142 | * |
||
1143 | * @param string[] $matches preg_replace_callback matches |
||
1144 | * |
||
1145 | * @return string |
||
1146 | */ |
||
1147 | private function wikiCCLink($matches) |
||
1148 | { |
||
1149 | return $this->wikiLink($matches[1]); |
||
1150 | } |
||
1151 | |||
1152 | /** |
||
1153 | * get tabbed page index |
||
1154 | * |
||
1155 | * @return array |
||
1156 | */ |
||
1157 | private function getIndexTabs() |
||
1158 | { |
||
1159 | global $xoopsDB; |
||
1160 | |||
1161 | $tabs = array(); |
||
1162 | |||
1163 | $sql = 'SELECT SUBSTRING(display_keyword,1,1) as letter, count(*) as count '; |
||
1164 | $sql .= ' FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
1165 | $sql .= ' WHERE active=1 AND show_in_index=1 '; |
||
1166 | $sql .= ' GROUP BY letter '; |
||
1167 | |||
1168 | $result = $xoopsDB->query($sql); |
||
1169 | |||
1170 | $currentset = false; |
||
1171 | $rows = $xoopsDB->getRowsNum($result); |
||
1172 | if ($rows) { |
||
1173 | while ($row = $xoopsDB->fetchArray($result)) { |
||
1174 | $row['letter'] = strtolower($row['letter']); |
||
1175 | if ($this->pageIndexPrefix === $row['letter']) { |
||
1176 | $row['current'] = true; |
||
1177 | $currentset = true; |
||
1178 | } else { |
||
1179 | $row['current'] = false; |
||
1180 | } |
||
1181 | $tabs[] = $row; |
||
1182 | } |
||
1183 | } |
||
1184 | $xoopsDB->freeRecordSet($result); |
||
1185 | |||
1186 | if (!$currentset) { |
||
1187 | $this->pageIndexPrefix = $tabs[0]['letter']; |
||
1188 | $tabs[0]['current'] = true; |
||
1189 | } |
||
1190 | |||
1191 | return $tabs; |
||
1192 | } |
||
1193 | |||
1194 | /** |
||
1195 | * get a page index |
||
1196 | * |
||
1197 | * @param string|null $prefix if not null, limit index to a prefix |
||
1198 | * |
||
1199 | * @return string rendered index |
||
1200 | * |
||
1201 | */ |
||
1202 | private function pageIndex($prefix = null) |
||
1203 | { |
||
1204 | global $xoopsDB; |
||
1205 | $simplelayout = false; |
||
1206 | $tablayout = false; |
||
1207 | |||
1208 | $body = ''; |
||
1209 | |||
1210 | $pageselect = 'active=1 AND show_in_index=1 '; |
||
1211 | |||
1212 | if (!empty($prefix)) { |
||
1213 | $pageselect .= ' AND keyword LIKE "' . $prefix . '%" '; |
||
1214 | } else { |
||
1215 | $sql = 'SELECT count(*) as count FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
1216 | $sql .= ' WHERE ' . $pageselect; |
||
1217 | $result = $xoopsDB->query($sql); |
||
1218 | $row = $xoopsDB->fetchArray($result); |
||
1219 | $cnt = $row['count']; |
||
1220 | $xoopsDB->freeRecordSet($result); |
||
1221 | if ($cnt > 500) { |
||
1222 | $tablayout = true; |
||
1223 | $simplelayout = true; // tablayout is already grouped by first character |
||
1224 | $tabs = $this->getIndexTabs(); |
||
1225 | $pageselect .= ' AND display_keyword LIKE "' . $this->pageIndexPrefix . '%" '; |
||
1226 | } |
||
1227 | } |
||
1228 | |||
1229 | $sql = 'SELECT keyword, display_keyword, title'; |
||
1230 | $sql .= ' FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
1231 | $sql .= ' WHERE ' . $pageselect; |
||
1232 | $sql .= ' ORDER BY display_keyword '; |
||
1233 | // $sql.=' ORDER BY active, show_in_index, display_keyword '; |
||
1234 | |||
1235 | $result = $xoopsDB->query($sql); |
||
1236 | $rowcnt = $xoopsDB->getRowsNum($result); |
||
1237 | |||
1238 | if ($rowcnt < 50) { |
||
1239 | $simplelayout = true; |
||
1240 | } // skip the fancy by letter breakout if this is a small index |
||
1241 | |||
1242 | if ($tablayout) { |
||
1243 | $body .= '<div class="wikiindex"><div class="wikiindextabs"><ul>'; |
||
1244 | |||
1245 | foreach ($tabs as $tab) { |
||
0 ignored issues
–
show
The variable
$tabs does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
1246 | $class = ''; |
||
1247 | if ($tab['current']) { |
||
1248 | $class = ' id="wikiindextabactive"'; |
||
1249 | } |
||
1250 | $url = sprintf($this->wikiLinkURL, strtolower($this->keyword . '(\\' . $tab['letter'] . ')')); |
||
1251 | $letter = strtoupper($tab['letter']); |
||
1252 | $body .= "\n<li{$class}><a href=\"{$url}\">{$letter}</a></li>"; |
||
1253 | } |
||
1254 | $body .= '</ul></div><div class="wikiindexbody">'; |
||
1255 | } |
||
1256 | |||
1257 | $lastletter = ''; |
||
1258 | if ($simplelayout) { |
||
1259 | $body .= '<ul>'; |
||
1260 | } |
||
1261 | while ($content = $xoopsDB->fetchArray($result)) { |
||
1262 | $display_keyword = $content['display_keyword']; |
||
1263 | if (empty($display_keyword)) { |
||
1264 | $display_keyword = $content['keyword']; |
||
1265 | } |
||
1266 | if (!$simplelayout) { |
||
1267 | if (function_exists('mb_substr')) { |
||
1268 | $testletter = mb_strtoupper(mb_substr($display_keyword, 0, 1, 'UTF-8'), 'UTF-8'); |
||
1269 | } else { |
||
1270 | $testletter = strtoupper(substr($display_keyword, 0, 1)); |
||
1271 | } |
||
1272 | if ($lastletter === '') { |
||
1273 | $lastletter = $testletter; |
||
1274 | $body .= "<h3>{$lastletter}</h3><ul>"; |
||
1275 | } |
||
1276 | if ($lastletter !== $testletter) { |
||
1277 | $lastletter = $testletter; |
||
1278 | $body .= "</ul><h3>{$lastletter}</h3><ul>"; |
||
1279 | } |
||
1280 | } |
||
1281 | $title = htmlspecialchars($content['title']); |
||
1282 | $display_keyword = htmlspecialchars($display_keyword); |
||
1283 | $url = sprintf($this->wikiLinkURL, strtolower($content['keyword'])); |
||
1284 | $link = sprintf('<a href="%s" title="%s">%s%s</a>', $url, $title, $display_keyword, ''); |
||
1285 | $body .= '<li>' . $link . ' : ' . $title . '</li>'; |
||
1286 | } |
||
1287 | $xoopsDB->freeRecordSet($result); |
||
1288 | if ($tablayout) { |
||
1289 | $body .= '</ul></div></div>'; |
||
1290 | } elseif ($body != '') { |
||
1291 | $body .= '</ul>'; |
||
1292 | } |
||
1293 | |||
1294 | return $body . "\n\n"; |
||
1295 | } |
||
1296 | |||
1297 | /** |
||
1298 | * get a recently modfied page index |
||
1299 | * |
||
1300 | * @param string|null $prefix if not null, limit index to a prefix |
||
1301 | * |
||
1302 | * @return string rendered index |
||
1303 | * |
||
1304 | */ |
||
1305 | private function recentIndex($prefix = null) |
||
1306 | { |
||
1307 | global $xoopsDB; |
||
1308 | |||
1309 | // only show active pages |
||
1310 | $pageselect = 'active=1 AND show_in_index=1 '; |
||
1311 | if (!empty($prefix)) { |
||
1312 | $pageselect .= ' AND keyword LIKE "' . $prefix . '%" '; |
||
1313 | } |
||
1314 | |||
1315 | $body = ''; |
||
1316 | |||
1317 | $sql = 'SELECT keyword, display_keyword, title, lastmodified'; |
||
1318 | $sql .= ', FROM_UNIXTIME(lastmodified) as fmtlastmodified, uid'; |
||
1319 | $sql .= ' FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
1320 | $sql .= ' WHERE ' . $pageselect; |
||
1321 | $sql .= ' ORDER BY lastmodified DESC LIMIT ' . $this->numberOfRecentItems; |
||
1322 | |||
1323 | $result = $xoopsDB->query($sql); |
||
1324 | |||
1325 | $lastdate = ''; |
||
1326 | while ($content = $xoopsDB->fetchArray($result)) { |
||
1327 | $testdate = substr($content['fmtlastmodified'], 0, 10); |
||
1328 | if ($lastdate === '') { |
||
1329 | $lastdate = $testdate; |
||
1330 | $body .= "<h3>{$lastdate}</h3><ul>"; |
||
1331 | } |
||
1332 | if ($lastdate !== $testdate) { |
||
1333 | $lastdate = $testdate; |
||
1334 | $body .= "</ul><h3>{$lastdate}</h3><ul>"; |
||
1335 | } |
||
1336 | |||
1337 | $title = htmlspecialchars($content['title']); |
||
1338 | $display_keyword = htmlspecialchars($content['display_keyword']); |
||
1339 | $url = sprintf($this->wikiLinkURL, strtolower($content['keyword'])); |
||
1340 | $link = sprintf('<a href="%s" title="%s">%s%s</a>', $url, $title, $display_keyword, ''); |
||
1341 | $body .= '<li>' . $link . ' : ' . $title . '</li>'; |
||
1342 | } |
||
1343 | $xoopsDB->freeRecordSet($result); |
||
1344 | if ($body !== '') { |
||
1345 | $body .= '</ul>'; |
||
1346 | } |
||
1347 | |||
1348 | return $body . "\n\n"; |
||
1349 | } |
||
1350 | |||
1351 | /** |
||
1352 | * callback render match specified index |
||
1353 | * |
||
1354 | * @param string[] $matches preg_replace_callback matches |
||
1355 | * |
||
1356 | * @return bool|string |
||
1357 | */ |
||
1358 | private function renderIndex($matches) |
||
1359 | { |
||
1360 | $type = $matches[1]; |
||
1361 | $parms = ''; |
||
1362 | if (isset($matches[2])) { |
||
1363 | $parms = trim($matches[2]); |
||
1364 | } |
||
1365 | if (strcasecmp($type, 'RecentChanges') === 0) { |
||
1366 | return $this->recentIndex($parms); |
||
1367 | } |
||
1368 | if (strcasecmp($type, 'PageIndex') === 0) { |
||
1369 | return $this->pageIndex($parms); |
||
1370 | } |
||
1371 | |||
1372 | return false; |
||
1373 | } |
||
1374 | |||
1375 | /** |
||
1376 | * highlight search terms |
||
1377 | * adapted from: http://stack:overflow.com/questions/2591046/highlight-text-except-html-tags |
||
1378 | * |
||
1379 | * @param string[] $capture matches |
||
1380 | * |
||
1381 | * @return string |
||
1382 | */ |
||
1383 | private function mon_rplc_callback($capture) |
||
1384 | { |
||
1385 | $haystack = $capture[1]; |
||
1386 | $p1 = stripos($haystack, $this->highlightArg['needle']); |
||
1387 | $l1 = strlen($this->highlightArg['needle']); |
||
1388 | $ret = ''; |
||
1389 | while ($p1 !== false) { |
||
1390 | $ret .= substr($haystack, 0, $p1) . $this->highlightArg['pre'] . substr($haystack, $p1, $l1) . $this->highlightArg['post']; |
||
1391 | $haystack = substr($haystack, $p1 + $l1); |
||
1392 | $p1 = stripos($haystack, $this->highlightArg['needle']); |
||
1393 | } |
||
1394 | $ret .= $haystack . $capture[2]; |
||
1395 | |||
1396 | return $ret; |
||
1397 | } |
||
1398 | |||
1399 | /** |
||
1400 | * split string aware of html tags |
||
1401 | * |
||
1402 | * @param string $needle string to find |
||
1403 | * @param string $pre string to include before each match |
||
1404 | * @param string $post string to include after each match |
||
1405 | * @param string $txt text to search |
||
1406 | * |
||
1407 | * @return string |
||
1408 | */ |
||
1409 | private function split_on_tag($needle, $pre, $post, $txt) |
||
1410 | { |
||
1411 | $this->highlightArg = compact('needle', 'pre', 'post'); |
||
1412 | |||
1413 | return preg_replace_callback('#((?:(?!<[/a-z]).)*)([^>]*>|$)#si', array($this, 'mon_rplc_callback'), $txt); |
||
1414 | } |
||
1415 | |||
1416 | /** |
||
1417 | * highlight words in page |
||
1418 | * |
||
1419 | * @param string $words space separated words to match |
||
1420 | * |
||
1421 | * @return string rendered page with words highlighted |
||
1422 | */ |
||
1423 | public function highlightWords($words) |
||
1424 | { |
||
1425 | $words = str_replace(' ', ' ', $words); |
||
1426 | $words = explode(' ', $words); |
||
1427 | $body = $this->renderedPage; |
||
1428 | foreach ($words as $word) { |
||
1429 | $body = $this->split_on_tag($word, '<span class="wiki_search_term">', '</span>', $body); |
||
1430 | } |
||
1431 | |||
1432 | return $body; |
||
1433 | } |
||
1434 | |||
1435 | /** |
||
1436 | * Hold content not to be processed for wiki markup, generate a unique tag to locate later |
||
1437 | * |
||
1438 | * @param string $type type of nowiki invocation (block, wcinline or inline) |
||
1439 | * @param string $source content to hold |
||
1440 | * |
||
1441 | * @return string generated tag for held content |
||
1442 | */ |
||
1443 | private function noWikiHold($type, $source) |
||
1444 | { |
||
1445 | ++$this->noWikiIndex; |
||
1446 | switch ($type) { |
||
1447 | case 'block': |
||
1448 | $this->noWikiQueue[$this->noWikiIndex] = "<pre>\n{$source}\n</pre>"; |
||
1449 | break; |
||
1450 | case 'wcinline': |
||
1451 | $this->noWikiQueue[$this->noWikiIndex] = '<span class="wikinoinline">' . $source . '</span>'; |
||
1452 | break; |
||
1453 | case 'inline': |
||
1454 | default: |
||
1455 | $this->noWikiQueue[$this->noWikiIndex] = $source; |
||
1456 | break; |
||
1457 | } |
||
1458 | |||
1459 | $ret = "{PdNlNw:{$this->noWikiIndex}}"; |
||
1460 | |||
1461 | return $ret; |
||
1462 | } |
||
1463 | |||
1464 | /** |
||
1465 | * no wiki block callback |
||
1466 | * |
||
1467 | * @param string[] $matches preg_replace_callback matches |
||
1468 | * |
||
1469 | * @return string |
||
1470 | */ |
||
1471 | private function noWikiHoldBlock($matches) |
||
1472 | { |
||
1473 | return $this->noWikiHold('block', $matches[1]); |
||
1474 | } |
||
1475 | |||
1476 | /** |
||
1477 | * no wiki inline callback |
||
1478 | * |
||
1479 | * @param string[] $matches preg_replace_callback matches |
||
1480 | * |
||
1481 | * @return string |
||
1482 | */ |
||
1483 | private function noWikiHoldInline($matches) |
||
1484 | { |
||
1485 | return $this->noWikiHold('inline', $matches[1]); |
||
1486 | } |
||
1487 | |||
1488 | /** |
||
1489 | * no wiki inline (WikiCreole style) callback |
||
1490 | * |
||
1491 | * @param string[] $matches preg_replace_callback matches |
||
1492 | * |
||
1493 | * @return string |
||
1494 | */ |
||
1495 | private function noWikiHoldWCInline($matches) |
||
1496 | { |
||
1497 | return $this->noWikiHold('wcinline', $matches[1]); |
||
1498 | } |
||
1499 | |||
1500 | /** |
||
1501 | * no wiki for code block callback |
||
1502 | * |
||
1503 | * @param string[] $matches preg_replace_callback matches |
||
1504 | * |
||
1505 | * @return string |
||
1506 | */ |
||
1507 | private function noWikiHoldCode($matches) |
||
1508 | { |
||
1509 | return $matches[1] . $this->noWikiHold('block', $matches[2]) . $matches[3]; |
||
1510 | } |
||
1511 | |||
1512 | /** |
||
1513 | * emit save nowiki content callback |
||
1514 | * |
||
1515 | * @param string[] $matches preg_replace_callback matches |
||
1516 | * |
||
1517 | * @return string |
||
1518 | */ |
||
1519 | private function noWikiEmit($matches) |
||
1520 | { |
||
1521 | $index = $matches[1]; |
||
1522 | |||
1523 | return $this->noWikiQueue[$index]; |
||
1524 | } |
||
1525 | |||
1526 | /** |
||
1527 | * table support callback |
||
1528 | * |
||
1529 | * @param string[] $matches preg_replace_callback matches |
||
1530 | * |
||
1531 | * @return string |
||
1532 | */ |
||
1533 | private function renderTables($matches) |
||
1534 | { |
||
1535 | $source = $matches[0]; |
||
1536 | $rowcnt = 0; |
||
1537 | $table = "<table class=\"wikitable\">\n"; |
||
1538 | $rows = explode("\n", $source); |
||
1539 | foreach ($rows as $i => $row) { |
||
1540 | $row = trim($row); |
||
1541 | if (!empty($row)) { |
||
1542 | if ($row[0] === '|') { |
||
1543 | $row = substr($row, 1); |
||
1544 | } |
||
1545 | if (substr($row, -1) === '|') { |
||
1546 | $row = substr($row, 0, -1); |
||
1547 | } |
||
1548 | $cols = explode('|', $row); |
||
1549 | $table .= '<tr' . (($rowcnt % 2) ? ' class="even"' : ' class="odd"') . '>'; |
||
1550 | ++$rowcnt; |
||
1551 | foreach ($cols as $col) { |
||
1552 | if (empty($col)) { |
||
1553 | $table .= '<td> </td>'; |
||
1554 | View Code Duplication | } elseif ($col[0] === '=') { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1555 | $table .= '<th>' . substr($col, 1) . '</th>'; |
||
1556 | } elseif ($col[0] === '>') { |
||
1557 | $table .= '<td class="right">' . substr($col, 1) . '</td>'; |
||
1558 | View Code Duplication | } elseif ($col[0] === '+') { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1559 | $table .= '<td class="center">' . substr($col, 1) . '</td>'; |
||
1560 | } elseif (substr($col, 0, 4) === '<') { |
||
1561 | $table .= '<td class="left">' . substr($col, 4) . '</td>'; |
||
1562 | } elseif (preg_match('/^\s*[0-9.$+\-]+\s*$/', $col)) { |
||
1563 | $class = 'number'; |
||
1564 | if ((float)preg_replace("/[^-0-9\.]/", '', $col) < 0) { |
||
1565 | $class = 'number negative'; |
||
1566 | } |
||
1567 | $table .= '<td class="' . $class . '">' . trim($col) . '</td>'; |
||
1568 | } else { |
||
1569 | $table .= '<td>' . $col . '</td>'; |
||
1570 | } |
||
1571 | } |
||
1572 | $table .= "</tr>\n"; |
||
1573 | } |
||
1574 | } |
||
1575 | $table .= "</table>\n"; |
||
1576 | |||
1577 | return $table; |
||
1578 | } |
||
1579 | |||
1580 | /** |
||
1581 | * link support callback |
||
1582 | * |
||
1583 | * @param string[] $matches preg_replace_callback matches |
||
1584 | * |
||
1585 | * @return string |
||
1586 | */ |
||
1587 | private function renderLink($matches) |
||
1588 | { |
||
1589 | $source = trim($matches[1]); |
||
1590 | $pos = strpos($source, '|'); |
||
1591 | |||
1592 | if ($pos === false) { // no delimter - whole thing is the link |
||
1593 | $link = $source; |
||
1594 | $linktext = ''; |
||
1595 | // handle the pathological case of a possesive of a person page. |
||
1596 | // Creole test includes "[[Ward Cunningham's]]" which leads to a |
||
1597 | // wiki page WardCunningham. Included in spirit of compatibility. |
||
1598 | if (substr($link, -2) === "'s") { |
||
1599 | $templink = substr($link, 0, -3); // quote is slashed |
||
1600 | // only if a wiki page |
||
1601 | if (preg_match('/^([A-Za-z\x80-\xff0-9.:\- ]){2,}$/', $templink)) { |
||
1602 | $linktext = $link; |
||
1603 | $link = $templink; |
||
1604 | } |
||
1605 | } |
||
1606 | } else { |
||
1607 | $link = trim(substr($source, 0, $pos)); |
||
1608 | $linktext = trim(substr($source, $pos + 1)); |
||
1609 | } |
||
1610 | |||
1611 | if (preg_match('/^([A-Za-z\x80-\xff0-9.:\- ]){2,}$/', $link)) { |
||
1612 | //$link=str_replace (' ', '', $link); |
||
1613 | if (empty($linktext)) { |
||
1614 | $ret = $this->wikiLink($link); |
||
1615 | } else { |
||
1616 | $ret = $this->wikiLink($link, stripslashes($linktext)); |
||
1617 | } |
||
1618 | } else { |
||
1619 | $ext = true; |
||
1620 | if (strncasecmp($link, XOOPS_URL, strlen(XOOPS_URL)) === 0) { |
||
1621 | $ext = false; |
||
1622 | } // matches our site |
||
1623 | View Code Duplication | if (strcasecmp('siteurl:', substr($link, 0, 8)) === 0) { // explicit reference to our site |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1624 | $link = XOOPS_URL . substr($link, 8); |
||
1625 | $ext = false; |
||
1626 | } |
||
1627 | if (strpos($link, ':') === false) { |
||
1628 | $ext = false; |
||
1629 | } // no protocol, assume relative url |
||
1630 | if ($linktext === '') { |
||
1631 | $linktext = $link; |
||
1632 | } |
||
1633 | $linktext = stripslashes($linktext); |
||
1634 | // $linktext=$this->noWikiHold('inline',stripslashes($linktext)); |
||
1635 | $ret = "<a href=\"{$link}\" title=\"{$linktext}\">{$linktext}</a>"; |
||
1636 | if ($ext) { |
||
1637 | $ret = '<a href="' . $link . '" target="_blank" title="' . _MD_GWIKI_PAGE_EXT_LINK_TT . '">' . $linktext . '<span class="wikiextlink"> </span></a>'; |
||
1638 | } |
||
1639 | } |
||
1640 | |||
1641 | return $ret; |
||
1642 | } |
||
1643 | |||
1644 | /** |
||
1645 | * header support callback |
||
1646 | * |
||
1647 | * @param string[] $matches preg_replace_callback matches |
||
1648 | * |
||
1649 | * @return string |
||
1650 | */ |
||
1651 | private function renderHeader($matches) |
||
1652 | { |
||
1653 | $source = $matches[3]; |
||
1654 | $level = $matches[2]; |
||
1655 | $level = strlen($level) + 1; |
||
1656 | $this->tocQueue[$this->tocIndex] = array('level' => $level, 'name' => $source); |
||
1657 | $toc = "\n<h" . $level . ' id="' . $this->tocIdPrefix . $this->tocIndex . '" >' . $source . '</h' . $level . ">\n"; |
||
1658 | ++$this->tocIndex; |
||
1659 | |||
1660 | return $toc; |
||
1661 | } |
||
1662 | |||
1663 | /** |
||
1664 | * indent support callback |
||
1665 | * |
||
1666 | * @param string[] $matches preg_replace_callback matches |
||
1667 | * |
||
1668 | * @return string |
||
1669 | */ |
||
1670 | private function renderIndent($matches) |
||
1671 | { |
||
1672 | $source = $matches[2]; |
||
1673 | $level = $matches[1]; |
||
1674 | $level = strlen($level); |
||
1675 | $ret = "\n<div class=\"wikiindent{$level}\">\n{$source}\n</div>"; |
||
1676 | |||
1677 | return $ret; |
||
1678 | } |
||
1679 | |||
1680 | /** |
||
1681 | * table of contents support callback |
||
1682 | * |
||
1683 | * @param string[] $matches preg_replace_callback matches |
||
1684 | * |
||
1685 | * @return string |
||
1686 | */ |
||
1687 | private function renderToc($matches) |
||
0 ignored issues
–
show
|
|||
1688 | { |
||
1689 | $tocq = $this->tocQueue; |
||
1690 | $toc = ''; |
||
1691 | foreach ($tocq as $i => $v) { |
||
1692 | $toc .= '<li class="wikitoclevel' . $v['level'] . '"><a href="' . sprintf($this->tocAnchorFmt, $this->tocIdPrefix . $i) . '">' . strip_tags($v['name']) . '</a></li>'; |
||
1693 | } |
||
1694 | if (!empty($toc)) { |
||
1695 | $toc = '<div class="wikitoc"><div class="wikitocheader">' . _MD_GWIKI_TOC . '</div><ul class="wikitoclist">' . $toc . '</ul></div>'; |
||
1696 | } |
||
1697 | |||
1698 | return $toc; |
||
1699 | } |
||
1700 | |||
1701 | /** |
||
1702 | * fetch table of contents for a page |
||
1703 | * |
||
1704 | * @param string $page keyword |
||
1705 | * |
||
1706 | * @return array|bool |
||
1707 | */ |
||
1708 | public function fetchPageSetToc(&$page) |
||
1709 | { |
||
1710 | global $xoopsDB; |
||
1711 | $toc = false; |
||
1712 | |||
1713 | $q_page = $this->escapeForDB($page); |
||
1714 | |||
1715 | $sql = 'SELECT gwiki_id, keyword, display_keyword, page_set_home, page_set_order, toc_cache '; |
||
1716 | $sql .= ' FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
1717 | $sql .= " WHERE active=1 and keyword='{$q_page}' "; |
||
1718 | |||
1719 | $result = $xoopsDB->query($sql); |
||
1720 | |||
1721 | $rows = $xoopsDB->getRowsNum($result); |
||
1722 | if ($rows) { |
||
1723 | $row = $xoopsDB->fetchArray($result); |
||
1724 | if (!empty($row['page_set_home'])) { |
||
1725 | $page = $row['page_set_home']; // this is passed back up to caller! |
||
1726 | $q_page = $this->escapeForDB($row['page_set_home']); |
||
1727 | $xoopsDB->freeRecordSet($result); |
||
1728 | $sql = 'SELECT gwiki_id, keyword, display_keyword, page_set_home, page_set_order, toc_cache '; |
||
1729 | $sql .= ' FROM ' . $xoopsDB->prefix('gwiki_pages'); |
||
1730 | $sql .= " WHERE active=1 and page_set_home='{$q_page}' "; |
||
1731 | $sql .= ' ORDER BY page_set_order, keyword '; |
||
1732 | |||
1733 | $result = $xoopsDB->query($sql); |
||
1734 | while ($row = $xoopsDB->fetchArray($result)) { |
||
1735 | $row['display_keyword'] = strip_tags($row['display_keyword']); |
||
1736 | if (!empty($row['toc_cache'])) { |
||
1737 | $tmp = unserialize($row['toc_cache']); |
||
1738 | foreach ($tmp as $i => $v) { |
||
1739 | $tmp[$i]['name'] = strip_tags($tmp[$i]['name']); |
||
1740 | } |
||
1741 | $row['toc'] = $tmp; |
||
1742 | |||
1743 | $toc[] = $row; |
||
1744 | } |
||
1745 | } |
||
1746 | } |
||
1747 | } |
||
1748 | $xoopsDB->freeRecordSet($result); |
||
1749 | |||
1750 | return $toc; |
||
1751 | } |
||
1752 | |||
1753 | /** |
||
1754 | * page set toc support callback |
||
1755 | * |
||
1756 | * @param string[] $matches preg_replace_callback matches |
||
1757 | * |
||
1758 | * @return string |
||
1759 | */ |
||
1760 | public function renderPageSetTocWrapper($matches) |
||
0 ignored issues
–
show
|
|||
1761 | { |
||
1762 | return $this->renderPageSetToc($this->keyword, 6); |
||
1763 | } |
||
1764 | |||
1765 | /** |
||
1766 | * render a table of contents |
||
1767 | * |
||
1768 | * @param string $page keyword |
||
1769 | * @param integer $level level limit |
||
1770 | * @param string $tocclass base class for toc. Current level will be appended |
||
1771 | * |
||
1772 | * @return bool|string |
||
1773 | */ |
||
1774 | public function renderPageSetToc(&$page, $level, $tocclass = 'wikitocpage') |
||
1775 | { |
||
1776 | $toc = $this->fetchPageSetToc($page); |
||
1777 | if (!$toc) { |
||
1778 | return false; |
||
1779 | } |
||
1780 | $tocout = ''; |
||
1781 | foreach ($toc as $ti => $tv) { |
||
0 ignored issues
–
show
The expression
$toc of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
1782 | //$link=sprintf($this->getWikiLinkURL(),$tv['keyword']); |
||
1783 | foreach ($tv['toc'] as $i => $v) { |
||
1784 | if ((int)$v['level'] <= $level) { |
||
1785 | $tocout .= '<li class="wikitoclevel' . $v['level'] . '"><a href="' . sprintf($this->getWikiLinkURL(), $tv['keyword'] . sprintf($this->tocAnchorFmt, $this->tocIdPrefix . $i)) . '">' |
||
1786 | . $v['name'] . '</a></li>'; |
||
1787 | } |
||
1788 | } |
||
1789 | } |
||
1790 | if (!empty($tocout)) { |
||
1791 | $tocout = '<div class="' . $tocclass . '"><ul class="wikitoclist">' . $tocout . '</ul></div>'; |
||
1792 | } |
||
1793 | |||
1794 | return $tocout; |
||
1795 | } |
||
1796 | |||
1797 | /** |
||
1798 | * render navigation for a page set |
||
1799 | * @param $page |
||
1800 | * |
||
1801 | * @return mixed |
||
1802 | */ |
||
1803 | public function renderPageSetNav($page) |
||
1804 | { |
||
1805 | $sethome = $page; |
||
1806 | $toc = $this->fetchPageSetToc($sethome); // this will set home |
||
1807 | if (!$toc) { |
||
1808 | return false; |
||
1809 | } |
||
1810 | $home = -1; |
||
1811 | $current = -1; |
||
1812 | $prev = -1; |
||
1813 | $next = -1; |
||
1814 | foreach ($toc as $i => $v) { |
||
0 ignored issues
–
show
The expression
$toc of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
1815 | if (strcasecmp($toc[$i]['keyword'], $page) === 0) { |
||
1816 | $current = $i; |
||
1817 | } |
||
1818 | if (strcasecmp($toc[$i]['keyword'], $sethome) === 0) { |
||
1819 | $home = $i; |
||
1820 | } |
||
1821 | } |
||
1822 | |||
1823 | if ($current > -1) { |
||
1824 | $prev = $current - 1; |
||
1825 | $next = $current + 1; |
||
1826 | } |
||
1827 | |||
1828 | $first = 0; |
||
1829 | $last = count($toc) - 1; |
||
1830 | |||
1831 | // should these wrap instead? |
||
1832 | if ($next > $last) { |
||
1833 | $next = $last; |
||
1834 | } |
||
1835 | if ($prev < 0) { |
||
1836 | $prev = 0; |
||
1837 | } |
||
1838 | if ($home < 0) { |
||
1839 | $home = 0; |
||
1840 | } |
||
1841 | |||
1842 | $pageset['first'] = array( |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$pageset was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pageset = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
1843 | 'link' => sprintf($this->getWikiLinkURL(), $toc[$first]['keyword']), |
||
1844 | 'text' => htmlentities($toc[$first]['display_keyword'], ENT_QUOTES), |
||
1845 | 'desc' => _MD_GWIKI_PAGENAV_FIRST |
||
1846 | ); |
||
1847 | |||
1848 | $pageset['prev'] = array( |
||
1849 | 'link' => sprintf($this->getWikiLinkURL(), $toc[$prev]['keyword']), |
||
1850 | 'text' => htmlentities($toc[$prev]['display_keyword'], ENT_QUOTES), |
||
1851 | 'desc' => _MD_GWIKI_PAGENAV_PREV |
||
1852 | ); |
||
1853 | |||
1854 | $pageset['home'] = array( |
||
1855 | 'link' => sprintf($this->getWikiLinkURL(), $toc[$home]['keyword']), |
||
1856 | 'text' => htmlentities($toc[$home]['display_keyword'], ENT_QUOTES), |
||
1857 | 'desc' => _MD_GWIKI_PAGENAV_TOP |
||
1858 | ); |
||
1859 | |||
1860 | $pageset['next'] = array( |
||
1861 | 'link' => sprintf($this->getWikiLinkURL(), $toc[$next]['keyword']), |
||
1862 | 'text' => htmlentities($toc[$next]['display_keyword'], ENT_QUOTES), |
||
1863 | 'desc' => _MD_GWIKI_PAGENAV_NEXT |
||
1864 | ); |
||
1865 | |||
1866 | $pageset['last'] = array( |
||
1867 | 'link' => sprintf($this->getWikiLinkURL(), $toc[$last]['keyword']), |
||
1868 | 'text' => htmlentities($toc[$last]['display_keyword'], ENT_QUOTES), |
||
1869 | 'desc' => _MD_GWIKI_PAGENAV_LAST |
||
1870 | ); |
||
1871 | |||
1872 | View Code Duplication | if (strcasecmp($toc[$first]['keyword'], $page) === 0) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1873 | $pageset['first']['link'] = 'javascript:void(0)'; |
||
1874 | } |
||
1875 | View Code Duplication | if (strcasecmp($toc[$prev]['keyword'], $page) === 0) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1876 | $pageset['prev']['link'] = 'javascript:void(0)'; |
||
1877 | } |
||
1878 | View Code Duplication | if (strcasecmp($toc[$home]['keyword'], $page) === 0) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1879 | $pageset['home']['link'] = 'javascript:void(0)'; |
||
1880 | } |
||
1881 | View Code Duplication | if (strcasecmp($toc[$next]['keyword'], $page) === 0) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1882 | $pageset['next']['link'] = 'javascript:void(0)'; |
||
1883 | } |
||
1884 | View Code Duplication | if (strcasecmp($toc[$last]['keyword'], $page) === 0) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1885 | $pageset['last']['link'] = 'javascript:void(0)'; |
||
1886 | } |
||
1887 | |||
1888 | return $pageset; |
||
1889 | } |
||
1890 | |||
1891 | /** |
||
1892 | * get image libraries for a page |
||
1893 | * |
||
1894 | * @param string $keyword keyword of page |
||
1895 | * |
||
1896 | * @return string[] |
||
1897 | */ |
||
1898 | public function getImageLib($keyword) |
||
1899 | { |
||
1900 | $lib = $this->imageLib; |
||
1901 | array_unshift($lib, $keyword); |
||
1902 | |||
1903 | return array_unique($lib); |
||
1904 | } |
||
1905 | |||
1906 | /** |
||
1907 | * get an image relative to specified page |
||
1908 | * |
||
1909 | * return array includes: |
||
1910 | * image_id |
||
1911 | * keyword |
||
1912 | * image_name |
||
1913 | * image_alt_text |
||
1914 | * image_file |
||
1915 | * |
||
1916 | * @param string $keyword keyword of page |
||
1917 | * @param string $name image name |
||
1918 | * |
||
1919 | * @return array|bool image data or false if invalid or not found |
||
1920 | */ |
||
1921 | public function getPageImage($keyword, $name) |
||
1922 | { |
||
1923 | global $xoopsDB; |
||
1924 | |||
1925 | if (strncasecmp($name, 'http://', 7) === 0 || strncasecmp($name, 'https://', 8) === 0) { |
||
1926 | return false; |
||
1927 | } |
||
1928 | $lib = $this->imageLib; |
||
1929 | array_unshift($lib, $keyword); |
||
1930 | foreach ($lib as $page) { |
||
1931 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_page_images') . ' WHERE keyword=\'' . $this->escapeForDB($page) . '\' '; |
||
1932 | $sql .= ' AND image_name=\'' . $this->escapeForDB($name) . '\' '; |
||
1933 | $result = $xoopsDB->query($sql); |
||
1934 | if ($image = $xoopsDB->fetchArray($result)) { |
||
1935 | return $image; |
||
1936 | } |
||
1937 | } |
||
1938 | |||
1939 | return false; |
||
1940 | } |
||
1941 | |||
1942 | /** |
||
1943 | * render image support callback |
||
1944 | * |
||
1945 | * @param string[] $matches preg_replace_callback matches |
||
1946 | * |
||
1947 | * @return string |
||
1948 | */ |
||
1949 | private function renderImage($matches) |
||
1950 | { |
||
1951 | $source = trim($matches[1]); |
||
1952 | $pos = strpos($source, '|'); |
||
1953 | //if($pos===false) $pos=strpos($source,' '); |
||
1954 | if ($pos === false) { // no delimter - whole thing is the image url |
||
1955 | $link = $source; |
||
1956 | $parms = array(); |
||
1957 | } else { |
||
1958 | $link = trim(substr($source, 0, $pos)); |
||
1959 | $parms = explode('|', trim(substr($source, $pos + 1))); |
||
1960 | foreach ($parms as $i => $parm) { |
||
1961 | $parms[$i] = trim($parm); |
||
1962 | } |
||
1963 | } |
||
1964 | View Code Duplication | if (strcasecmp('siteurl:', substr($link, 0, 8)) === 0) { // explicit reference to our site |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1965 | $link = XOOPS_URL . substr($link, 8); |
||
1966 | } |
||
1967 | $showthumb = false; |
||
1968 | $showthumblink = false; |
||
1969 | if (strcasecmp('thumb:', substr($link, 0, 6)) === 0) { // explicit request for thumbnail, links to full image |
||
1970 | $revertlink = $link; |
||
1971 | $link = substr($link, 6); |
||
1972 | $showthumblink = true; |
||
1973 | } |
||
1974 | $alttext = empty($parms[0]) ? '' : $parms[0]; |
||
1975 | $align = empty($parms[1]) ? '' : $parms[1]; |
||
0 ignored issues
–
show
$align is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
1976 | $maxpx = empty($parms[2]) ? '' : (int)$parms[2]; |
||
1977 | |||
1978 | // align must be left, right, center or empty |
||
1979 | $align = ''; |
||
1980 | if (strcasecmp($align, 'left') === 0) { |
||
1981 | $align = 'left'; |
||
1982 | } elseif (strcasecmp($align, 'right') === 0) { |
||
1983 | $align = 'right'; |
||
1984 | } elseif (strcasecmp($align, 'center') === 0) { |
||
1985 | $align = 'center'; |
||
1986 | } |
||
1987 | |||
1988 | $alignparm = ''; |
||
1989 | if ($align === 'left' || $align === 'right' || $align === 'center') { |
||
1990 | $alignparm = ', ' . $align; |
||
1991 | } |
||
1992 | |||
1993 | // look up link in page_images table, if found use that, otherwise just pass on link as is |
||
1994 | $image = $this->getPageImage($this->keyword, $link); |
||
1995 | if ($image) { |
||
1996 | // image array includes: |
||
1997 | // image_id |
||
1998 | // keyword |
||
1999 | // image_name |
||
2000 | // image_alt_text |
||
2001 | // image_file |
||
2002 | // use_to_represent |
||
2003 | $link = XOOPS_URL . '/uploads/' . $this->wikiDir . '/' . $image['image_file']; |
||
2004 | if (empty($alttext)) { |
||
2005 | $alttext = $image['image_alt_text']; |
||
2006 | } |
||
2007 | } else { |
||
2008 | // thumbs don't apply, so put everything back the way it was |
||
2009 | if ($showthumblink) { |
||
2010 | $link = $revertlink; |
||
0 ignored issues
–
show
The variable
$revertlink does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
2011 | $showthumblink = false; |
||
2012 | } |
||
2013 | } |
||
2014 | |||
2015 | $alt = ''; |
||
2016 | // $alttext=htmlspecialchars($alttext); |
||
2017 | if (!empty($alttext)) { |
||
2018 | $alt = " alt=\"{$alttext}\" title=\"{$alttext}\" "; |
||
2019 | } |
||
2020 | |||
2021 | $maxpxstyle = ''; |
||
2022 | if (!empty($maxpx)) { |
||
2023 | $maxpxstyle = " style=\"max-width:{$maxpx}px; max-height:{$maxpx}px; width:auto; height:auto;\" "; |
||
2024 | $showthumb = true; // trigger automatic thumbnail use |
||
2025 | } |
||
2026 | |||
2027 | if ($showthumb) { |
||
2028 | $thumbsize = $this->defaultThumbSize; |
||
2029 | if (!empty($maxpx)) { |
||
2030 | $thumbsize = $maxpx; |
||
2031 | } |
||
2032 | $link = XOOPS_URL . '/modules/' . $this->wikiDir . '/getthumb.php?page=' . $image['keyword'] . '&name=' . urlencode($image['image_name']) . '&size=' . $thumbsize; |
||
2033 | } |
||
2034 | |||
2035 | if ($showthumblink) { |
||
2036 | $ret = ''; |
||
2037 | $thumbsize = $this->defaultThumbSize; |
||
2038 | if (!empty($maxpx)) { |
||
2039 | $thumbsize = $maxpx; |
||
2040 | } |
||
2041 | $thumb = XOOPS_URL . '/modules/' . $this->wikiDir . '/getthumb.php?page=' . $image['keyword'] . '&name=' . urlencode($image['image_name']) . '&size=' . $thumbsize; |
||
2042 | $img = XOOPS_URL . '/uploads/' . $this->wikiDir . '/' . $image['image_file']; |
||
2043 | $ret .= '<a href="' . $img . '" ' . $alt . '><img src="' . $thumb . '"' . $alt . $maxpxstyle . '/></a>'; |
||
2044 | } else { |
||
2045 | $ret = "<img class=\"wikiimage{$alignparm}\" src=\"{$link}\" {$alt}{$maxpxstyle} />"; |
||
2046 | } |
||
2047 | |||
2048 | if ($align === 'center') { |
||
2049 | $ret = '<div style="margin: 0 auto; text-align: center;">' . $ret . '</div>'; |
||
2050 | } |
||
2051 | |||
2052 | return $ret; |
||
2053 | } |
||
2054 | |||
2055 | /** |
||
2056 | * gallery support callback |
||
2057 | * |
||
2058 | * @param string[] $matches preg_replace_callback matches |
||
2059 | * |
||
2060 | * @return string |
||
2061 | */ |
||
2062 | private function renderGallery($matches) |
||
2063 | { |
||
2064 | global $xoopsDB; |
||
2065 | |||
2066 | $source = ''; |
||
2067 | if (isset($matches[1])) { |
||
2068 | $source = $matches[1]; |
||
2069 | } |
||
2070 | $maxpx = (int)trim($source); |
||
2071 | if ($maxpx < 10) { |
||
2072 | $maxpx = $this->defaultThumbSize; |
||
2073 | } |
||
2074 | $page = $this->keyword; |
||
2075 | |||
2076 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_page_images') . ' WHERE keyword = \'' . $page . '\' ' . ' ORDER BY image_name '; |
||
2077 | $result = $xoopsDB->query($sql); |
||
2078 | |||
2079 | $dir = $this->wikiDir; |
||
2080 | $body = '<div class="wikigallery"><ul class="wikigalleryimg">'; |
||
2081 | |||
2082 | for ($i = 0, $iMax = $xoopsDB->getRowsNum($result); $i < $iMax; ++$i) { |
||
2083 | $image = $xoopsDB->fetchArray($result); |
||
2084 | $img = XOOPS_URL . '/uploads/' . $dir . '/' . $image['image_file']; |
||
2085 | $thumb = XOOPS_URL . '/modules/' . $dir . '/getthumb.php?page=' . $image['keyword'] . '&name=' . urlencode($image['image_name']) . '&size=' . $maxpx; |
||
2086 | $alt = htmlentities($image['image_alt_text'], ENT_QUOTES); |
||
2087 | $name = htmlentities($image['image_name'], ENT_QUOTES); |
||
2088 | if (empty($alt)) { |
||
2089 | $alt = $name; |
||
2090 | } |
||
2091 | $body .= '<li><a href="' . $img . '" title="' . $name . '"><img src="' . $thumb . '" alt="' . $alt . '" title="' . $alt . '" /></a></li>' . "\n"; |
||
2092 | } |
||
2093 | |||
2094 | $body .= '</ul><br style="clear:both;" /></div>'; |
||
2095 | |||
2096 | return $body; |
||
2097 | } |
||
2098 | |||
2099 | /** |
||
2100 | * list support callback |
||
2101 | * |
||
2102 | * @param string[] $matches preg_replace_callback matches |
||
2103 | * |
||
2104 | * @return string |
||
2105 | */ |
||
2106 | private function renderLists($matches) |
||
2107 | { |
||
2108 | $lines = explode("\n", $matches[0]); |
||
2109 | $last = ''; |
||
2110 | foreach ($lines as $i => $line) { |
||
2111 | $line = ltrim($line); |
||
2112 | if (!empty($line)) { |
||
2113 | $list = ''; |
||
2114 | $p = strpos($line, ' '); |
||
2115 | $current = substr($line, 0, $p); |
||
2116 | $x = 0; |
||
2117 | while (!empty($last[$x]) && !empty($current[$x]) && $last[$x] === $current[$x]) { |
||
2118 | ++$x; |
||
2119 | } |
||
2120 | // $x is where the last and current list prefixes differ |
||
2121 | // close anything from $x to end in last |
||
2122 | $close = strrev(substr($last, $x)); |
||
2123 | $y = 0; |
||
2124 | View Code Duplication | while (!empty($close[$y])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2125 | if ($close[$y] === '*') { |
||
2126 | $list .= '</li></ul>'; |
||
2127 | } //.($x>0?'</li>':''); |
||
2128 | if ($close[$y] === '#') { |
||
2129 | $list .= '</li></ol>'; |
||
2130 | } //.($x>0?'</li>':''); |
||
2131 | ++$y; |
||
2132 | } |
||
2133 | // open anything from $x to end in |
||
2134 | $open = substr($current, $x); |
||
2135 | $y = 0; |
||
2136 | View Code Duplication | while (!empty($open[$y])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2137 | if ($open[$y] === '*') { |
||
2138 | $list .= '<ul class="wikiulist">'; |
||
2139 | } |
||
2140 | if ($open[$y] === '#') { |
||
2141 | $list .= '<ol class="wikiolist">'; |
||
2142 | } |
||
2143 | ++$y; |
||
2144 | } |
||
2145 | $endli = ($last === $current) ? '</li>' : ''; |
||
2146 | $last = $current; |
||
2147 | $lines[$i] = $list . $endli . "\n<li> " . substr($line, $p + 1); |
||
2148 | } |
||
2149 | } |
||
2150 | |||
2151 | // put list back together |
||
2152 | $list = "\n"; |
||
2153 | foreach ($lines as $line) { |
||
2154 | if (!empty($line)) { |
||
2155 | $list .= $line; |
||
2156 | } |
||
2157 | } |
||
2158 | // close anything left open |
||
2159 | $close = strrev($last); |
||
2160 | $y = 0; |
||
2161 | View Code Duplication | while (!empty($close[$y])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2162 | if ($close[$y] === '*') { |
||
2163 | $list .= "</li></ul>\n"; |
||
2164 | } |
||
2165 | if ($close[$y] === '#') { |
||
2166 | $list .= "</li></ol>\n"; |
||
2167 | } |
||
2168 | ++$y; |
||
2169 | } |
||
2170 | |||
2171 | return $list; |
||
2172 | } |
||
2173 | |||
2174 | /** |
||
2175 | * reference support callback |
||
2176 | * |
||
2177 | * @param string[] $matches preg_replace_callback matches |
||
2178 | * |
||
2179 | * @return string |
||
2180 | */ |
||
2181 | private function renderRef($matches) |
||
2182 | { |
||
2183 | $refinfo = $matches[1]; |
||
2184 | $source = $matches[2]; |
||
2185 | $first_ref = false; |
||
2186 | $refs = explode('|', trim($refinfo) . '|||'); |
||
2187 | $rq['id'] = $refs[0]; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$rq was never initialized. Although not strictly required by PHP, it is generally a good practice to add $rq = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
2188 | $rq['first'] = $refs[1]; |
||
2189 | $rq['repeat'] = $refs[2]; |
||
2190 | $rq['source'] = $source; |
||
2191 | $refid = (-1); |
||
2192 | if (!empty($rq['id'])) { |
||
2193 | foreach ($this->refQueue as $i => $v) { |
||
2194 | if ($v['id'] === $rq['id']) { |
||
2195 | $refid = $i; |
||
2196 | } |
||
2197 | } |
||
2198 | } |
||
2199 | if ($refid === (-1)) { |
||
2200 | $refid = $this->refIndex; |
||
2201 | $first_ref = true; |
||
2202 | $this->refQueue[$this->refIndex] = $rq; |
||
2203 | ++$this->refIndex; |
||
2204 | } |
||
2205 | $paren_ref = false; |
||
2206 | if (!empty($this->refQueue[$refid]['first'])) { |
||
2207 | $paren_ref = true; |
||
2208 | } |
||
2209 | if ($paren_ref) { |
||
2210 | $ref_text = $this->refQueue[$refid]['first']; |
||
2211 | if (!$first_ref) { |
||
2212 | if (!empty($this->refQueue[$refid]['repeat'])) { |
||
2213 | $ref_text = $this->refQueue[$refid]['repeat']; |
||
2214 | } |
||
2215 | } |
||
2216 | $r = '<span class="wikiparenref"><a href="#ref' . $refid . '">(' . $ref_text . ')</a></span>'; |
||
2217 | } else { |
||
2218 | $r = '<span class="wikinumref"><a href="#ref' . $refid . '">' . ($refid + 1) . '</a></span>'; |
||
2219 | } |
||
2220 | |||
2221 | return $r; |
||
2222 | } |
||
2223 | |||
2224 | /** |
||
2225 | * reference list support callback |
||
2226 | * |
||
2227 | * @param string[] $matches preg_replace_callback matches |
||
2228 | * |
||
2229 | * @return string |
||
2230 | */ |
||
2231 | private function renderRefList($matches) |
||
0 ignored issues
–
show
|
|||
2232 | { |
||
2233 | $this->refShown = true; |
||
2234 | $r = '<div class="wikicitelist">'; |
||
2235 | |||
2236 | foreach ($this->refQueue as $i => $v) { |
||
2237 | $refid = $i; |
||
2238 | if (empty($v['first'])) { |
||
2239 | $r .= '<div class="wikicitenumitem" id="ref' . $refid . '"><span class="wikicitenum">' . ($refid + 1) . '. </span>' . $v['source'] . "</div>\n"; |
||
2240 | } else { |
||
2241 | $r .= '<div class="wikiciteparenitem" id="ref' . $refid . '">' . $v['source'] . "</div>\n"; |
||
2242 | } |
||
2243 | } |
||
2244 | |||
2245 | $r .= '</div>'; |
||
2246 | |||
2247 | return $r; |
||
2248 | } |
||
2249 | |||
2250 | /** |
||
2251 | * box support callback |
||
2252 | * |
||
2253 | * @param string[] $matches preg_replace_callback matches |
||
2254 | * |
||
2255 | * @return string |
||
2256 | */ |
||
2257 | private function renderBox($matches) |
||
2258 | { |
||
2259 | $type = $matches[1]; |
||
2260 | $title = $matches[2]; |
||
2261 | $body = $matches[3]; |
||
2262 | // make sure we have a valid type |
||
2263 | $type = strtolower($type); |
||
2264 | if (!($type === 'code' || $type === 'info' || $type === 'note' || $type === 'tip' || $type === 'warn' |
||
2265 | || $type === 'folded') |
||
2266 | ) { |
||
2267 | $type = 'info'; |
||
2268 | } |
||
2269 | |||
2270 | // $title may include options ( title | align ) : |
||
2271 | // align: adds additonal class 'left' or 'right' to box so css can alter float, size, etc. |
||
2272 | $title = trim($title); |
||
2273 | $eclass = ''; |
||
2274 | $ejs = ''; |
||
2275 | $etooltip = ''; |
||
2276 | $pos = strpos($title, '|'); |
||
2277 | if ($pos !== false) { // if no delimiter - whole thing is the title |
||
2278 | $parms = explode('|', $title); |
||
2279 | $title = $parms[0]; |
||
2280 | if (!empty($parms[1]) && ($parms[1] === 'left' || $parms[1] === 'right')) { |
||
2281 | $eclass = ' ' . $parms[1]; |
||
2282 | } |
||
2283 | } |
||
2284 | if ($type === 'folded') { |
||
2285 | $foldclass = 'wikifolded' . $eclass; |
||
2286 | $unfoldclass = 'wikiunfolded' . $eclass; |
||
2287 | $ejs = ' onclick="var c=this.className; if(c==\'' . $foldclass . '\') this.className=\'' . $unfoldclass . '\'; else this.className=\'' . $foldclass . '\';"'; |
||
2288 | $etooltip = '<span>' . _MD_GWIKI_FOLDED_TT . '</span>'; |
||
2289 | } |
||
2290 | |||
2291 | $ret = '<div class="wiki' . $type . $eclass . '"' . $ejs . '><div class="wiki' . $type . 'icon"></div><div class="wiki' . $type . 'title">' . $title . $etooltip . '</div><div class="wiki' |
||
2292 | . $type . 'inner">' . $body . '<br clear="all" /></div></div>' . "\n\n"; |
||
2293 | |||
2294 | return $ret; |
||
2295 | } |
||
2296 | |||
2297 | /** |
||
2298 | * Convert entities |
||
2299 | * |
||
2300 | * @param string $body wiki text to process |
||
2301 | * |
||
2302 | * @return string |
||
2303 | */ |
||
2304 | private function convertEntities($body) |
||
2305 | { |
||
2306 | // convert some entites |
||
2307 | $sym = array(); |
||
2308 | $ent = array(); |
||
2309 | $sym[] = '{cent}'; |
||
2310 | $ent[] = '¢'; |
||
2311 | $sym[] = '{pound}'; |
||
2312 | $ent[] = '£'; |
||
2313 | $sym[] = '{yen}'; |
||
2314 | $ent[] = '¥'; |
||
2315 | $sym[] = '{euro}'; |
||
2316 | $ent[] = '€'; |
||
2317 | $sym[] = '{c}'; |
||
2318 | $ent[] = '©'; |
||
2319 | $sym[] = '(c)'; |
||
2320 | $ent[] = '©'; |
||
2321 | $sym[] = '{r}'; |
||
2322 | $ent[] = '®'; |
||
2323 | $sym[] = '(r)'; |
||
2324 | $ent[] = '®'; |
||
2325 | $sym[] = '{tm}'; |
||
2326 | $ent[] = '™'; |
||
2327 | $sym[] = '(tm)'; |
||
2328 | $ent[] = '™'; |
||
2329 | $sym[] = '{sm}'; |
||
2330 | // very poor font support for unicode code point for service mark, fake with markup |
||
2331 | $ent[] = '<span style="font-size: 50%; vertical-align: super;">SM</span>'; |
||
2332 | $sym[] = '{nbsp}'; |
||
2333 | $ent[] = ' '; |
||
2334 | |||
2335 | $body = str_ireplace($sym, $ent, $body); |
||
2336 | |||
2337 | return $body; |
||
2338 | } |
||
2339 | |||
2340 | /** |
||
2341 | * Render a teaser section. If page includes a {more} tag, teaser will be text that preceeds it. |
||
2342 | * Otherwise try to break semantically at about 400 characters. |
||
2343 | * |
||
2344 | * @param string|null $body text to process, defaults to current page body |
||
2345 | * @param string|null $title title to use |
||
2346 | * |
||
2347 | * @return string |
||
2348 | */ |
||
2349 | public function renderTeaser($body = null, $title = null) |
||
2350 | { |
||
2351 | // chop body at more tag if it is set |
||
2352 | $splitsize = 400; // arbitrary size to use when no {more} tag |
||
2353 | if (empty($body)) { |
||
2354 | $body = $this->body; |
||
2355 | } |
||
2356 | $pos = stripos($body, '{more}'); |
||
2357 | if ($pos === false && strlen($body) > $splitsize) { |
||
2358 | $search = "#\r\n?#"; |
||
2359 | $replace = "\n"; |
||
2360 | $body = preg_replace($search, $replace, $body); |
||
2361 | $pos = stripos($body, "\n\n", $splitsize); // hopefully the end of a paragraph |
||
2362 | } |
||
2363 | if ($pos !== false) { |
||
2364 | $body = substr($body, 0, $pos); |
||
2365 | $url = sprintf($this->wikiLinkURL, $this->keyword); |
||
2366 | } |
||
2367 | |||
2368 | $body = str_ireplace('{toc}', '', $body); |
||
2369 | $body = $this->renderPage($body, $title); |
||
2370 | if ($pos !== false) { |
||
2371 | $body .= '<a href="' . $url . '#more"><span class="wikimore">' . _MD_GWIKI_MORE . '</span></a>'; |
||
0 ignored issues
–
show
The variable
$url does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
2372 | } |
||
2373 | |||
2374 | return $body; |
||
2375 | } |
||
2376 | |||
2377 | /** |
||
2378 | * block quote support callback |
||
2379 | * |
||
2380 | * @param string[] $matches preg_replace_callback matches |
||
2381 | * |
||
2382 | * @return string |
||
2383 | */ |
||
2384 | private function renderBlockquote($matches) |
||
2385 | { |
||
2386 | $src = str_replace("\n", ' ', preg_replace('#^> #m', '', $matches[0])); |
||
2387 | |||
2388 | return '<blockquote class=\"wikiquote\">' . $src . "</blockquote>\n"; |
||
2389 | } |
||
2390 | |||
2391 | /** |
||
2392 | * preformatted support callback |
||
2393 | * |
||
2394 | * @param string[] $matches preg_replace_callback matches |
||
2395 | * |
||
2396 | * @return string |
||
2397 | */ |
||
2398 | private function renderPreformat($matches) |
||
2399 | { |
||
2400 | $src = preg_replace('#^. #m', '', $matches[0]); |
||
2401 | |||
2402 | return '<pre>' . $src . "</pre>\n"; |
||
2403 | } |
||
2404 | |||
2405 | /** |
||
2406 | * Render a page |
||
2407 | * |
||
2408 | * @param string|null $body text to process, defaults to current page body |
||
2409 | * @param string|null $title title to use, defaults to current page title |
||
2410 | * |
||
2411 | * @return string |
||
2412 | */ |
||
2413 | public function renderPage($body = null, $title = null) |
||
2414 | { |
||
2415 | if (empty($body)) { |
||
2416 | $body = $this->body; |
||
2417 | } |
||
2418 | $this->renderedPage = ''; |
||
2419 | $this->noWikiQueue = array(); |
||
2420 | $this->noWikiIndex = 0; |
||
2421 | $this->refShown = false; |
||
2422 | |||
2423 | if (empty($title)) { |
||
2424 | $title = $this->title; |
||
2425 | } |
||
2426 | // do first because title should always be #toc0 - set in template |
||
2427 | $this->renderHeader(array('', '', '', $title)); |
||
2428 | |||
2429 | $body .= "\n"; |
||
2430 | |||
2431 | // eliminate double line endings |
||
2432 | $search = "#\r\n?#"; |
||
2433 | $replace = "\n"; |
||
2434 | $body = preg_replace($search, $replace, $body); |
||
2435 | |||
2436 | // neuter html tags |
||
2437 | $search = '#<#'; |
||
2438 | $replace = '<'; |
||
2439 | $body = preg_replace($search, $replace, $body); |
||
2440 | |||
2441 | // neuter single quotes |
||
2442 | $search = "#'#"; |
||
2443 | $replace = "\\'"; |
||
2444 | $body = preg_replace($search, $replace, $body); |
||
2445 | |||
2446 | // nowiki - tilde escape |
||
2447 | $search = "#~([^ \t\r\n\v\f])#U"; |
||
2448 | $replace = array($this, 'noWikiHoldInline'); |
||
2449 | $body = preg_replace_callback($search, $replace, $body); |
||
2450 | |||
2451 | // nowiki content gwiki style |
||
2452 | $search = '#{nowiki}(.*){endnowiki}#Umsi'; |
||
2453 | $replace = array($this, 'noWikiHoldInline'); |
||
2454 | $body = preg_replace_callback($search, $replace, $body); |
||
2455 | |||
2456 | // nowiki content block creole style (a nowiki that forces a style, how odd.) |
||
2457 | $search = "#^{{{\n(.*)^}}}\n#Umsi"; |
||
2458 | $replace = array($this, 'noWikiHoldBlock'); |
||
2459 | $body = preg_replace_callback($search, $replace, $body); |
||
2460 | |||
2461 | // nowiki content inline creole style |
||
2462 | $search = '#{{{(.*)}}}#U'; |
||
2463 | $replace = array($this, 'noWikiHoldWCInline'); |
||
2464 | $body = preg_replace_callback($search, $replace, $body); |
||
2465 | |||
2466 | // automatically nowiki content of code box - {code title}xxx{endcode} |
||
2467 | $search = "#({code [^\"<\n]+?})(.*?)({endcode})#si"; |
||
2468 | $replace = array($this, 'noWikiHoldCode'); |
||
2469 | $body = preg_replace_callback($search, $replace, $body); |
||
2470 | |||
2471 | // center ++ xxx |
||
2472 | $search = "#^(\+{2})(.*)(?=\n\n|\Z)#Usm"; |
||
2473 | $replace = "<div style=\"text-align: center;\" class=\"wikicenter\">\n\\2\n</div>\n"; |
||
2474 | $body = preg_replace($search, $replace, $body); |
||
2475 | |||
2476 | // : indent up to 5 levels |
||
2477 | $search = "#^(\:{1,5})\s(.*)(?=\n\n|\Z)#Usm"; |
||
2478 | $replace = array($this, 'renderIndent'); |
||
2479 | $body = preg_replace_callback($search, $replace, $body); |
||
2480 | |||
2481 | // lists |
||
2482 | $search = "#^( *[*\#]{1,} (.*)\n)+#m"; |
||
2483 | $replace = array($this, 'renderLists'); |
||
2484 | $body = preg_replace_callback($search, $replace, $body); |
||
2485 | |||
2486 | // bold **xxx** |
||
2487 | $search = "#\*{2}(.*?)(\*{2}|(?=\n\n))#s"; |
||
2488 | $replace = "<strong class=\"wikistrong\">\\1</strong>"; |
||
2489 | $body = preg_replace($search, $replace, $body); |
||
2490 | |||
2491 | // italic //xxx// |
||
2492 | $search = "#(?<![:])/{2}(.*?[^:])(/{2}|(?=\n\n))#s"; |
||
2493 | $replace = "<em class=\"wikiem\">\\1</em>"; |
||
2494 | $body = preg_replace($search, $replace, $body); |
||
2495 | |||
2496 | // horizontal rule ---- (not an empty strikethru; creole says 4 or more so this needs to go first) |
||
2497 | $search = "#^-{4,}$#m"; |
||
2498 | $replace = "\n<hr class=\"wikihr\"/>\n"; |
||
2499 | $body = preg_replace($search, $replace, $body); |
||
2500 | |||
2501 | // strikethru --xxx-- (this does NOT cross lines, as '--' is a common typographic convention |
||
2502 | $search = "#-{2}([^\s]{1}.*?)(-{2})#"; |
||
2503 | $replace = "<del class=\"wikidel\">\\1</del>"; |
||
2504 | $body = preg_replace($search, $replace, $body); |
||
2505 | |||
2506 | // underline __xxx__ |
||
2507 | $search = "#(?<=\s)_{2}(.*?)(_{2}|(?=\n\n))#s"; |
||
2508 | $replace = "<span class=\"wikiu\">\\1</span>"; |
||
2509 | $body = preg_replace($search, $replace, $body); |
||
2510 | |||
2511 | // superscript ^^xxx^^ |
||
2512 | $search = "#\^{2}(.*?)(\^{2}|(?=\n\n))#s"; |
||
2513 | $replace = "<sup class=\"wikisup\">\\1</sup>"; |
||
2514 | $body = preg_replace($search, $replace, $body); |
||
2515 | |||
2516 | // subscript ,,xxx,, |
||
2517 | $search = "#,{2}(.*?)(,{2}|(?=\n\n))#s"; |
||
2518 | $replace = "<sub class=\"wikisub\">\\1</sub>"; |
||
2519 | $body = preg_replace($search, $replace, $body); |
||
2520 | |||
2521 | // monospace ##xxx## |
||
2522 | $search = "#\#{2}(.*?)(\#{2}|(?=\n\n))#s"; |
||
2523 | $replace = "<span class=\"wikitt\">\\1</span>"; |
||
2524 | $body = preg_replace($search, $replace, $body); |
||
2525 | |||
2526 | // color !!color:xxx!! |
||
2527 | $search = "#!{2}(\#{0,1}[0-9A-Za-z]*):(.*?)(!{2}|(?=\n\n))#s"; |
||
2528 | $replace = "<span style=\"color:\\1;\">\\2</span>"; |
||
2529 | $body = preg_replace($search, $replace, $body); |
||
2530 | |||
2531 | // color !!color,background:xxx!! |
||
2532 | $search = "#!{2}(\#{0,1}[0-9A-Za-z]*),(\#{0,1}[0-9A-Za-z]*):(.*?)(!{2}|(?=\n\n))#s"; |
||
2533 | $replace = "<span style=\"color:\\1; background-color:\\2;\">\\3</span>"; |
||
2534 | $body = preg_replace($search, $replace, $body); |
||
2535 | |||
2536 | // forced line break creole style \\, just a bare break tag |
||
2537 | $search = "#(\\\{2})#i"; |
||
2538 | $replace = '<br>'; |
||
2539 | $body = preg_replace($search, $replace, $body); |
||
2540 | |||
2541 | // forced line break blog [[br]] or gwiki {break} styles, themed - by default clear all |
||
2542 | $search = "#(\[\[BR\]\]|{break})#i"; |
||
2543 | $replace = '<br class="wikibreak" />'; |
||
2544 | $body = preg_replace($search, $replace, $body); |
||
2545 | |||
2546 | // image {{image url|alt text|align|max width in pixels}} |
||
2547 | $search = "#\{{2}(.*)\}{2}#Um"; |
||
2548 | $replace = array($this, 'renderImage'); |
||
2549 | $body = preg_replace_callback($search, $replace, $body); |
||
2550 | |||
2551 | // info box {info title}xxx{endinfo} |
||
2552 | $search = "#{(info) ([^\"<\n]+?)?}(.*?){endinfo}#si"; |
||
2553 | $replace = array($this, 'renderBox'); |
||
2554 | $body = preg_replace_callback($search, $replace, $body); |
||
2555 | |||
2556 | // note box {note title}xxx{endnote} |
||
2557 | $search = "#{(note) ([^\"<\n]+?)?}(.*?){endnote}#si"; |
||
2558 | $replace = array($this, 'renderBox'); |
||
2559 | $body = preg_replace_callback($search, $replace, $body); |
||
2560 | |||
2561 | // tip box {tip title}xxx{endtip} |
||
2562 | $search = "#{(tip) ([^\"<\n]+?)?}(.*?){endtip}#si"; |
||
2563 | $replace = array($this, 'renderBox'); |
||
2564 | $body = preg_replace_callback($search, $replace, $body); |
||
2565 | |||
2566 | // warning box {warning title}xxx{endwarning} |
||
2567 | $search = "#{(warn)ing ([^\"<\n]+?)?}(.*?){endwarning}#si"; |
||
2568 | $replace = array($this, 'renderBox'); |
||
2569 | $body = preg_replace_callback($search, $replace, $body); |
||
2570 | |||
2571 | // code (preformatted) box {code title}xxx{endcode} |
||
2572 | $search = "#{(code) ([^\"<\n]+?)?}(.*?){endcode}#si"; |
||
2573 | $replace = array($this, 'renderBox'); |
||
2574 | $body = preg_replace_callback($search, $replace, $body); |
||
2575 | |||
2576 | // folded box {folded title}xxx{endfolded} |
||
2577 | $search = "#{(folded) ([^\"<\n]+?)?}(.*?){endfolded}#si"; |
||
2578 | $replace = array($this, 'renderBox'); |
||
2579 | $body = preg_replace_callback($search, $replace, $body); |
||
2580 | |||
2581 | // urls - smells like a link |
||
2582 | $search = "#(?<=\s)((http|https|ftp|ftps)://.{2,}\..*)(?=[,.?!:;]{0,1}\s)#Ui"; |
||
2583 | $replace = array($this, 'renderLink'); |
||
2584 | $body = preg_replace_callback($search, $replace, $body); |
||
2585 | |||
2586 | // link [[link|linktext]] |
||
2587 | $search = "#\[{2}(.*)\]{2}#Um"; |
||
2588 | $replace = array($this, 'renderLink'); |
||
2589 | $body = preg_replace_callback($search, $replace, $body); |
||
2590 | |||
2591 | // email [email protected] |
||
2592 | $search = "#(?<=\s)([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})(?=\s)#i"; |
||
2593 | $replace = '<a href="mailto:\\1">\\1</a>'; |
||
2594 | $body = preg_replace($search, $replace, $body); |
||
2595 | |||
2596 | // CamelCase wiki link "#^([A-Z][a-z\:]+){2,}\d*$#" |
||
2597 | // Could be between whitespace on either end or between > on start and/or < on end |
||
2598 | if ($this->useCamelCase) { |
||
2599 | $search = "#(?<=\s|>)" . _WIKI_CAMELCASE_REGEX . "(?=\s|</l|</t)#"; |
||
2600 | $replace = array($this, 'wikiCCLink'); |
||
2601 | $body = preg_replace_callback($search, $replace, $body); |
||
2602 | } |
||
2603 | |||
2604 | // =====headings up to 5 levels |
||
2605 | $search = "#(^\s{0,})(={1,5})([^=].*[^=])(={0,5})\s*$#Um"; |
||
2606 | $replace = array($this, 'renderHeader'); |
||
2607 | $body = preg_replace_callback($search, $replace, $body); |
||
2608 | |||
2609 | // blockquote > xxx |
||
2610 | $search = "#^(> .*\n)+#m"; |
||
2611 | $replace = array($this, 'renderBlockquote'); |
||
2612 | $body = preg_replace_callback($search, $replace, $body); |
||
2613 | |||
2614 | // preformated .xxx |
||
2615 | $search = "#^(\. .*\n)+#m"; |
||
2616 | $replace = array($this, 'renderPreformat'); |
||
2617 | $body = preg_replace_callback($search, $replace, $body); |
||
2618 | |||
2619 | // reference {ref id|first-ref}source{endref} |
||
2620 | $search = "#{ref( [^\"<\n]+?)?}(.*?){endref}#si"; |
||
2621 | $replace = array($this, 'renderRef'); |
||
2622 | $body = preg_replace_callback($search, $replace, $body); |
||
2623 | |||
2624 | // forced line break blog [[br]] or gwiki {break} styles, themed - by default clear all |
||
2625 | $search = '#({reflist})#i'; |
||
2626 | $replace = array($this, 'renderRefList'); |
||
2627 | $body = preg_replace_callback($search, $replace, $body); |
||
2628 | |||
2629 | // index or change list {pageindex prefix} |
||
2630 | $search = "#{(PageIndex|RecentChanges)([^\"<\n]+?)?}#si"; |
||
2631 | $replace = array($this, 'renderIndex'); |
||
2632 | $body = preg_replace_callback($search, $replace, $body); |
||
2633 | |||
2634 | // table of contents |
||
2635 | $search = "#\{toc\}#i"; |
||
2636 | $replace = array($this, 'renderToc'); |
||
2637 | $body = preg_replace_callback($search, $replace, $body); |
||
2638 | |||
2639 | // page set table of contents |
||
2640 | $search = "#\{pagesettoc\}#i"; |
||
2641 | $replace = array($this, 'renderPageSetTocWrapper'); |
||
2642 | $body = preg_replace_callback($search, $replace, $body); |
||
2643 | |||
2644 | // image gallery {gallery size} |
||
2645 | $search = "#{gallery([^\"<\n]+?)?}#si"; |
||
2646 | $replace = array($this, 'renderGallery'); |
||
2647 | $body = preg_replace_callback($search, $replace, $body); |
||
2648 | |||
2649 | // more anchor - indicates end of teaser/summary |
||
2650 | $search = "#\{more\}#i"; |
||
2651 | $replace = '<span id="more"></span>'; |
||
2652 | $body = preg_replace($search, $replace, $body); |
||
2653 | |||
2654 | // tables |
||
2655 | $search = "#^( *\|((.*)\|){1,}\s*\n)+#m"; |
||
2656 | $replace = array($this, 'renderTables'); |
||
2657 | $body = preg_replace_callback($search, $replace, $body); |
||
2658 | |||
2659 | // paragraph on 2 consecutive newlines |
||
2660 | $search = "#\n{2}#"; |
||
2661 | $replace = "\n<p>"; |
||
2662 | $body = preg_replace($search, $replace, $body); |
||
2663 | |||
2664 | // restore cached nowiki content, all styles |
||
2665 | // (if you need to use {PdNlNw:#} in your page, put it in a nowiki tag) |
||
2666 | $search = '#{PdNlNw:([0-9]{1,})}#'; |
||
2667 | $replace = array($this, 'noWikiEmit'); |
||
2668 | $body = preg_replace_callback($search, $replace, $body); |
||
2669 | |||
2670 | if ($this->refShown === false && $this->refIndex > 0) { |
||
2671 | $body .= $this->renderRefList(null); |
||
0 ignored issues
–
show
null is of type null , but the function expects a array<integer,string> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
2672 | } |
||
2673 | $body = stripslashes($this->convertEntities($body)); |
||
2674 | |||
2675 | $this->renderedPage = $body; |
||
2676 | |||
2677 | return $this->renderedPage; |
||
2678 | } |
||
2679 | } |
||
2680 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.