PageRenderTime 66ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/html/AppCode/expressionengine/modules/wiki/mod.wiki.php

https://github.com/w3bg/www.hsifin.com
PHP | 6074 lines | 5015 code | 575 blank | 484 comment | 387 complexity | 7f10bbf7bb9ad73c18dd5b361923102e MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010, EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/user_guide/license.html
  13. =====================================================
  14. File: mod.wiki.php
  15. -----------------------------------------------------
  16. Purpose: Wiki class
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Wiki {
  24. var $version = '1.2';
  25. var $base_path = '';
  26. var $profile_path = '';
  27. var $base_url = '';
  28. var $seg_parts = array();
  29. var $admins = array('1');
  30. var $users = array('1', '5');
  31. var $conditionals = array();
  32. var $title = '';
  33. var $topic = '';
  34. var $revision_id = '';
  35. var $theme_path = '';
  36. var $theme_url = '';
  37. var $image_url = '';
  38. // Namespaces
  39. var $main_ns = 'Main';
  40. var $special_ns = 'Special'; // Deutsch: Spezial
  41. var $file_ns = 'File';
  42. var $category_ns = 'Category'; // Deutsch: Kategorie
  43. var $image_ns = 'Image';
  44. var $current_namespace = '';
  45. var $namespaces = array();
  46. // Settings
  47. var $wiki_id = 1;
  48. var $label_name = 'EE Wiki';
  49. var $use_captchas = 'n';
  50. var $text_format = 'xhtml';
  51. var $html_format = 'safe';
  52. var $auto_links = "n";
  53. var $upload_dir = '';
  54. var $valid_upload_dir = 'n';
  55. var $can_upload = 'n';
  56. var $moderation_emails = '';
  57. var $revision_limit = 100;
  58. var $author_limit = 75;
  59. var $min_length_keywords = 3;
  60. var $cats_separator = '::';
  61. var $cats_display_separator = ' -> ';
  62. var $cats_use_namespaces = 'n';
  63. var $cats_assign_parents = 'y';
  64. // Category Retrieval
  65. var $temp_array = array();
  66. var $cat_array = array();
  67. var $show_these = FALSE;
  68. var $cat_depth = 0;
  69. var $parent_cats = array();
  70. // Pagination variables
  71. var $paginate = FALSE;
  72. var $pagination_links = '';
  73. var $page_next = '';
  74. var $page_previous = '';
  75. var $current_page = 1;
  76. var $total_pages = 1;
  77. var $total_rows = 0;
  78. var $p_limit = '';
  79. var $p_page = '';
  80. var $pagination_sql = '';
  81. var $return_data = '';
  82. /** ----------------------------------------
  83. /** Constructor
  84. /** ----------------------------------------*/
  85. function Wiki($return = FALSE)
  86. {
  87. // Make a local reference to the ExpressionEngine super object
  88. $this->EE =& get_instance();
  89. if ($return === TRUE)
  90. {
  91. return;
  92. }
  93. $this->EE->lang->loadfile('wiki');
  94. /** ----------------------------------------
  95. /** Update Module Code
  96. /** ----------------------------------------*/
  97. if (isset($this->EE->TMPL->module_data['Wiki']['version']) && $this->version > $this->EE->TMPL->module_data['Wiki']['version'])
  98. {
  99. $this->update_module($this->EE->TMPL->module_data['Wiki']['version']);
  100. }
  101. /* ----------------------------------------
  102. /*
  103. /* There are five main kinds of pages in the ExpressionEngine Wiki:
  104. /*
  105. /* - Main/Index
  106. /* - Article Page (Including Namespaces)
  107. /* - Edit Topic Page
  108. /* - History Topic Page
  109. /* - Special Page (ex: Uploads, Search Results, Recent Changes)
  110. /*
  111. /* Now, the {exp:wiki} tag will be put into a template group
  112. /* and a template, which is set in base_path="" so that
  113. /* we can discover the structure of the URLs and what segments
  114. /* to read for what.
  115. /* ----------------------------------------*/
  116. if (($this->base_path = $this->EE->TMPL->fetch_param('base_path')) === FALSE)
  117. {
  118. return $this->return_data = $this->EE->lang->line('basepath_unset');
  119. }
  120. $this->base_path = rtrim($this->base_path, '/').'/';
  121. $this->base_url = $this->EE->functions->create_url($this->base_path).'/';
  122. /* ----------------------------------------
  123. Creating this array once is very useful and since I do my sanitization
  124. again here as well as in the Input class, I am sure that the
  125. segments are clean and ready to use on a page.
  126. /* ----------------------------------------*/
  127. $x = explode('/', $this->base_path);
  128. $this->seg_parts = explode('/', $this->EE->security->xss_clean(strip_tags(stripslashes($this->EE->uri->query_string))));
  129. /* ----------------------------------------
  130. Fixes a minor bug in ExpressionEngine where the QSTR variable
  131. has the template name included when there is no third segment
  132. on a non-index template - Paul
  133. /* ----------------------------------------*/
  134. if (isset($x['1']))
  135. {
  136. if ($this->seg_parts['0'] == $x['1'])
  137. {
  138. array_shift($this->seg_parts);
  139. }
  140. }
  141. /** ----------------------------------------
  142. /** Preferences and Language
  143. /** ----------------------------------------*/
  144. if ($this->EE->TMPL->fetch_param('wiki') !== FALSE)
  145. {
  146. $query = $this->EE->db->query("SELECT * FROM exp_wikis WHERE wiki_short_name = '".$this->EE->db->escape_str($this->EE->TMPL->fetch_param('wiki'))."'");
  147. }
  148. else
  149. {
  150. $query = $this->EE->db->query("SELECT * FROM exp_wikis WHERE wiki_short_name = 'default_wiki'");
  151. }
  152. if ($query->num_rows() == 0)
  153. {
  154. return $this->return_data = 'No Valid Wiki Specified';
  155. }
  156. foreach($query->row_array() as $field => $value)
  157. {
  158. if ($field != 'wiki_id')
  159. {
  160. $field = substr($field, 5);
  161. }
  162. if ($field == 'users' OR $field == 'admins')
  163. {
  164. $value = explode('|', $value);
  165. }
  166. $this->{$field} = $value;
  167. }
  168. /** ------------------------------------
  169. /** Retrieve Our Namespaces
  170. /** ------------------------------------*/
  171. $namespace_query = $this->EE->db->query("SELECT * FROM exp_wiki_namespaces WHERE wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."' ORDER BY namespace_name");
  172. if ($namespace_query->num_rows() > 0)
  173. {
  174. foreach($namespace_query->result_array() as $row)
  175. {
  176. $this->namespaces[strtolower($row['namespace_name'])] = array($row['namespace_name'], $row['namespace_label']);
  177. if (isset($this->seg_parts['0']) && strcasecmp($this->prep_title(substr($this->seg_parts['0'], 0, strlen($row['namespace_label'].':'))), $row['namespace_label'].':') == 0)
  178. {
  179. $this->admins = explode('|', $row['namespace_admins']);
  180. $this->users = explode('|', $row['namespace_users']);
  181. }
  182. }
  183. }
  184. if ($this->EE->TMPL->fetch_param('profile_path') !== FALSE)
  185. {
  186. $this->profile_path = $this->EE->functions->remove_double_slashes('/'.$this->EE->TMPL->fetch_param('profile_path').'/'.$this->EE->config->item('profile_trigger').'/');
  187. }
  188. else
  189. {
  190. $this->profile_path = $this->EE->functions->remove_double_slashes('/'.$this->EE->config->item('profile_trigger').'/');
  191. }
  192. /** ----------------------------------------
  193. /** Namespaces Localization
  194. /** ----------------------------------------*/
  195. $this->main_ns = (isset($this->EE->lang->language['main_ns'])) ? $this->EE->lang->line('main_ns') : $this->main_ns;
  196. $this->file_ns = (isset($this->EE->lang->language['file_ns'])) ? $this->EE->lang->line('file_ns') : $this->file_ns;
  197. $this->image_ns = (isset($this->EE->lang->language['image_ns'])) ? $this->EE->lang->line('image_ns') : $this->image_ns;
  198. $this->special_ns = (isset($this->EE->lang->language['special_ns'])) ? $this->EE->lang->line('special_ns') : $this->special_ns;
  199. $this->category_ns = (isset($this->EE->lang->language['category_ns'])) ? $this->EE->lang->line('category_ns') : $this->category_ns;
  200. /* ----------------------------------------
  201. /* Category namespace actually has articles so it is put into the
  202. /* namespaces array. However, instead of the localized name we use
  203. /* the relatively simple 'category' in the page_namespace field.
  204. /* ---------------------------------------*/
  205. $this->namespaces['category'] = array('category', $this->category_ns);
  206. /** ----------------------------------------
  207. /** Tag Settings
  208. /** ----------------------------------------*/
  209. if ( ! in_array('1', $this->admins)) $this->admins[] = "1";
  210. if ( ! in_array('1', $this->users)) $this->users[] = "1";
  211. foreach($this->admins as $key => $value)
  212. {
  213. if (in_array($value, array('2', '3', '4')))
  214. {
  215. unset($this->admins[$key]);
  216. }
  217. }
  218. foreach($this->users as $key => $value)
  219. {
  220. if (in_array($value, array('2', '3', '4')))
  221. {
  222. unset($this->users[$key]);
  223. }
  224. }
  225. /** ----------------------------------------
  226. /** Valid Upload Directory?
  227. /** ----------------------------------------*/
  228. if ( ! empty($this->upload_dir) && is_numeric($this->upload_dir))
  229. {
  230. $query = $this->EE->db->query("SELECT COUNT(*) AS count FROM exp_upload_prefs
  231. WHERE id = '".$this->EE->db->escape_str($this->upload_dir)."'");
  232. if ($query->row('count') > 0)
  233. {
  234. $this->valid_upload_dir = 'y';
  235. $this->can_upload = 'y';
  236. if (in_array($this->EE->session->userdata['group_id'], array(2, 3, 4)))
  237. {
  238. $this->can_upload = 'n';
  239. }
  240. elseif ($this->EE->session->userdata['group_id'] != 1)
  241. {
  242. $query = $this->EE->db->query("SELECT upload_id FROM exp_upload_no_access WHERE member_group = '".$this->EE->session->userdata['group_id']."'");
  243. if ($query->num_rows() > 0)
  244. {
  245. foreach($query->result_array() as $row)
  246. {
  247. if ($query->row('upload_id') == $this->upload_dir)
  248. {
  249. $this->can_upload = 'n';
  250. break;
  251. }
  252. }
  253. }
  254. }
  255. }
  256. }
  257. /** ----------------------------------------
  258. /** Set theme, load file helper
  259. /** ----------------------------------------*/
  260. $this->EE->load->helper('file');
  261. $this->theme_path = PATH_THEMES.'wiki_themes/default/';
  262. $this->image_url = $this->EE->config->slash_item('theme_folder_url').'wiki_themes/default/images/';
  263. $this->theme_url = $this->EE->config->slash_item('theme_folder_url').'wiki_themes/default/';
  264. if ($this->EE->TMPL->fetch_param('theme') !== FALSE && $this->EE->TMPL->fetch_param('theme') != '' && $this->EE->TMPL->fetch_param('theme') != 'default')
  265. {
  266. $theme = $this->EE->security->sanitize_filename($this->EE->TMPL->fetch_param('theme'));
  267. if (is_dir(PATH_THEMES.'/wiki_themes/'.$theme))
  268. {
  269. $this->theme_path = PATH_THEMES.'wiki_themes/'.$theme.'/';
  270. $this->image_url = $this->EE->config->slash_item('theme_folder_url').'wiki_themes/'.$theme.'/images/';
  271. $this->theme_url = $this->EE->config->slash_item('theme_folder_url').'wiki_themes/'.$theme.'/';
  272. }
  273. else
  274. {
  275. $this->EE->TMPL->log_item('Wiki module: theme not found - "'.htmlentities($theme).'"');
  276. }
  277. }
  278. /** ----------------------------------------
  279. /** Editing Article
  280. /** ----------------------------------------*/
  281. if ($this->EE->input->post('editing') == 'y' && $this->EE->input->post('preview') === FALSE)
  282. {
  283. return $this->edit_article();
  284. }
  285. /** ----------------------------------------
  286. /** Displaying Page
  287. /** ----------------------------------------*/
  288. $this->return_data = str_replace(array('{module_version}'), array($this->version), $this->_fetch_template('wiki_page.html'));
  289. $this->return_data = $this->active_members($this->return_data);
  290. /* -------------------------------------
  291. /* 'wiki_start' hook.
  292. /* - Allows page template to be modified prior to article processing
  293. /* - Added 1.6.0
  294. */
  295. if ($this->EE->extensions->active_hook('wiki_start') === TRUE)
  296. {
  297. $this->return_data = $this->EE->extensions->universal_call('wiki_start', $this);
  298. if ($this->EE->extensions->end_script === TRUE) return;
  299. }
  300. /*
  301. /* -------------------------------------*/
  302. /** ----------------------------------------
  303. /** Determine Page to Show
  304. /** ----------------------------------------*/
  305. // Index Page
  306. if (count($this->seg_parts) == 0 OR $this->EE->uri->query_string == '' OR $this->EE->uri->query_string == 'index')
  307. {
  308. $this->title = 'index';
  309. $this->article('index');
  310. }
  311. // File Page
  312. elseif (substr($this->seg_parts['0'], 0, strlen($this->file_ns.':')) == $this->file_ns.':')
  313. {
  314. $this->title = $this->seg_parts['0'];
  315. $this->current_namespace = $this->file_ns;
  316. $this->file(substr($this->seg_parts['0'], strlen($this->file_ns.':')));
  317. }
  318. // Image
  319. elseif (substr($this->seg_parts['0'], 0, strlen($this->image_ns.':')) == $this->image_ns.':')
  320. {
  321. $this->title = $this->seg_parts['0'];
  322. $this->current_namespace = $this->image_ns;
  323. $this->image(substr($this->seg_parts['0'], strlen($this->image_ns.':')));
  324. }
  325. // Special Page
  326. elseif (substr($this->seg_parts['0'], 0, strlen($this->special_ns.':')) == $this->special_ns.':')
  327. {
  328. $this->title = $this->seg_parts['0'];
  329. $this->current_namespace = $this->special_ns;
  330. $this->special(substr($this->seg_parts['0'], strlen($this->special_ns.':')));
  331. }
  332. // Download!
  333. elseif (isset($this->seg_parts['0']) && strlen($this->seg_parts['0']) == 32 && preg_match("/^[a-z0-9]+$/i", $this->seg_parts['0']))
  334. {
  335. $this->display_attachment();
  336. exit;
  337. }
  338. // Typical Boring Article. Yawn!
  339. else
  340. {
  341. if (in_array($this->seg_parts['0'], array('edit', 'history', 'revision', 'noredirect')))
  342. {
  343. $this->title = 'index';
  344. if ($this->seg_parts['0'] == 'noredirect')
  345. {
  346. $this->article('index');
  347. }
  348. else
  349. {
  350. $this->{$this->seg_parts['0']}('index');
  351. }
  352. }
  353. else
  354. {
  355. $this->title = $this->seg_parts['0'];
  356. if ($this->valid_title($this->title) != $this->title)
  357. {
  358. $this->redirect('', $this->title);
  359. }
  360. if (isset($this->seg_parts['1']) && $this->seg_parts['1'] == 'edit')
  361. {
  362. $this->edit($this->title);
  363. }
  364. elseif (isset($this->seg_parts['1']) && $this->seg_parts['1'] == 'history')
  365. {
  366. $this->history($this->title);
  367. }
  368. elseif (isset($this->seg_parts['1']) && $this->seg_parts['1'] == 'revision')
  369. {
  370. $this->revision($this->title);
  371. }
  372. else
  373. {
  374. $this->article($this->title);
  375. }
  376. }
  377. }
  378. if ($this->can_upload == 'y')
  379. {
  380. $this->return_data = $this->_allow_if('uploads', $this->return_data);
  381. }
  382. else
  383. {
  384. $this->return_data = $this->_deny_if('uploads', $this->return_data);
  385. }
  386. /** ----------------------------------------
  387. /** Global Tags
  388. /** ----------------------------------------*/
  389. if (preg_match_all("/\{wiki:custom_namespaces_list(.*?)\}(.*?)\{\/wiki:custom_namespaces_list\}/s", $this->return_data, $matches))
  390. {
  391. for($i = 0, $s = count($matches[0]); $i < $s; ++$i)
  392. {
  393. $output = '';
  394. if (count($this->namespaces) > 0)
  395. {
  396. foreach($this->namespaces as $name => $label)
  397. {
  398. $selected = (isset($this->seg_parts['1']) && strtolower($this->seg_parts['1']) == $name) ? 'selected="selected"' : '';
  399. $output .= str_replace(array('{namespace_short_name}', '{namespace_label}', '{namespace_selected}'), array($label['0'], $label['1'], $selected), $matches['2'][$i]);
  400. }
  401. }
  402. $this->return_data = str_replace($matches['0'][$i], $output, $this->return_data);
  403. }
  404. }
  405. if (preg_match("/\{wiki:categories_list(.*?)\}(.*?)\{\/wiki:categories_list\}/s", $this->return_data))
  406. {
  407. $this->categories_list();
  408. }
  409. /** ----------------------------------------
  410. /** Global Conditionals
  411. /** ----------------------------------------*/
  412. if ($this->EE->session->userdata('member_id') == 0)
  413. {
  414. $this->return_data = $this->_deny_if('logged_in', $this->return_data);
  415. $this->return_data = $this->_allow_if('logged_out', $this->return_data);
  416. }
  417. else
  418. {
  419. $this->return_data = $this->_allow_if('logged_in', $this->return_data);
  420. $this->return_data = $this->_deny_if('logged_out', $this->return_data);
  421. }
  422. if (in_array($this->EE->session->userdata['group_id'], $this->admins))
  423. {
  424. $this->return_data = $this->_deny_if('cannot_admin', $this->return_data);
  425. $this->return_data = $this->_allow_if('can_admin', $this->return_data);
  426. }
  427. else
  428. {
  429. $this->return_data = $this->_allow_if('cannot_admin', $this->return_data);
  430. $this->return_data = $this->_deny_if('can_admin', $this->return_data);
  431. }
  432. /** ----------------------------------------
  433. /** Global Variables
  434. /** ----------------------------------------*/
  435. $link = $this->create_url($this->current_namespace, $this->topic);
  436. // Load the XML Helper
  437. $this->EE->load->helper('xml');
  438. $data = array( '{charset}' => $this->EE->config->item('output_charset'),
  439. '{wiki_name}' => $this->label_name,
  440. '{title}' => xml_convert($this->prep_title($this->title)),
  441. '{url_title}' => xml_convert($this->valid_title($this->title)),
  442. '{topic}' => xml_convert($this->prep_title($this->topic)),
  443. '{namespace}' => xml_convert($this->current_namespace),
  444. '{special_namespace}' => xml_convert($this->special_ns),
  445. '{main_namespace}' => xml_convert($this->main_ns),
  446. '{file_namespace}' => xml_convert($this->file_ns),
  447. '{category_namespace}' => xml_convert($this->category_ns),
  448. '{image_namespace}' => xml_convert($this->image_ns),
  449. '{revision_id}' => $this->revision_id,
  450. '{screen_name}' => $this->prep_screen_name($this->EE->session->userdata('screen_name')),
  451. '{path:wiki_home}' => $this->EE->functions->create_url($this->base_path),
  452. '{path:wiki_base_url}' => $this->base_url,
  453. '{path:article_history}' => $link.'/history',
  454. '{path:view_article}' => $link,
  455. '{path:edit_article}' => $link.'/edit',
  456. '{path:logout}' => $this->EE->functions->fetch_site_index(0, 0).QUERY_MARKER.'ACT='.$this->EE->functions->fetch_action_id('Member', 'member_logout'),
  457. '{path:your_control_panel}' => $this->EE->functions->create_url($this->profile_path.'profile'),
  458. '{path:your_profile}' => $this->EE->functions->create_url($this->profile_path.$this->EE->session->userdata('member_id')),
  459. '{path:login}' => $this->EE->functions->create_url($this->profile_path.'login'),
  460. '{path:register}' => $this->EE->functions->create_url($this->profile_path.'register'),
  461. '{path:memberlist}' => $this->EE->functions->create_url($this->profile_path.'memberlist'),
  462. '{path:forgot}' => $this->EE->functions->create_url($this->profile_path.'forgot_password'),
  463. '{path:private_messages}' => $this->EE->functions->create_url($this->profile_path.'messages/view_folder/1'),
  464. '{path:image_url}' => $this->image_url,
  465. '{path:theme_url}' => $this->theme_url,
  466. '{text_format}' => ucwords(str_replace('_', ' ', $this->text_format))
  467. );
  468. /** -------------------------------------
  469. /** Parse URI segments
  470. /** -------------------------------------*/
  471. // This code lets admins fetch URI segments which become
  472. // available as: {segment_1} {segment_2}
  473. for ($i = 1; $i < 9; $i++)
  474. {
  475. $data[LD.'segment_'.$i.RD] = $this->EE->uri->segment($i);
  476. }
  477. /** -------------------------------------
  478. /** Parse Snippets
  479. /** -------------------------------------*/
  480. foreach ($this->EE->config->_global_vars as $key => $val)
  481. {
  482. $data[LD.$key.RD] = $val;
  483. }
  484. /** -------------------------------------
  485. /** Parse manual variables
  486. /** -------------------------------------*/
  487. if (count($this->EE->TMPL->global_vars) > 0)
  488. {
  489. foreach ($this->EE->TMPL->global_vars as $key => $val)
  490. {
  491. $data[LD.$key.RD] = $val;
  492. }
  493. }
  494. /* -------------------------------------
  495. /* We reset some of these because in $data we are converting them
  496. /* for display purposes and we would rather have the conditionals
  497. /* use the unmodified versions
  498. /* -------------------------------------*/
  499. $this->conditionals['title'] = $this->title;
  500. $this->conditionals['topic'] = $this->topic;
  501. $this->conditionals['namespace'] = $this->current_namespace;
  502. $this->return_data = $this->prep_conditionals($this->return_data, array_merge($data, $this->conditionals));
  503. $this->return_data = str_replace(array_keys($data), array_values($data), $this->return_data);
  504. /** ----------------------------------------
  505. /** Cleanup
  506. /** ----------------------------------------*/
  507. $this->return_data = $this->_deny_if('redirected', $this->return_data);
  508. $this->return_data = $this->_deny_if('redirect_page', $this->return_data);
  509. }
  510. // --------------------------------------------------------------------
  511. /**
  512. * Fetch Template
  513. *
  514. * Fetches a template fragment
  515. *
  516. * @access public
  517. * @param string
  518. * @return string
  519. */
  520. function _fetch_template($which)
  521. {
  522. return read_file($this->theme_path.$which);
  523. }
  524. // --------------------------------------------------------------------
  525. /** ----------------------------------------
  526. /** Redirect for the Wiki
  527. /** ----------------------------------------*/
  528. function redirect($namespace='', $title)
  529. {
  530. $this->EE->functions->redirect($this->create_url($namespace, $title));
  531. exit;
  532. }
  533. /** ----------------------------------------
  534. /** Creat URL for the Wiki
  535. /** ----------------------------------------*/
  536. function create_url($namespace='', $title)
  537. {
  538. if ($namespace == '' && stristr($title, ':') && count($this->namespaces) > 0)
  539. {
  540. foreach($this->namespaces as $possible)
  541. {
  542. if (substr($title, 0, strlen($possible['1'].':')) == $possible['1'].':')
  543. {
  544. $namespace = $possible['1'];
  545. $title = substr($title, strlen($possible['1'].':'));
  546. break;
  547. }
  548. }
  549. }
  550. if ($namespace != '')
  551. {
  552. /*
  553. Convert any colons back because of Category articles
  554. */
  555. $link = $this->EE->functions->create_url($this->base_path.
  556. urlencode($this->valid_title($namespace)).
  557. ':'.
  558. str_replace('%3A', ':', urlencode($this->valid_title($title))));
  559. }
  560. else
  561. {
  562. $link = $this->EE->functions->create_url($this->base_path.
  563. urlencode($this->valid_title($title)));
  564. }
  565. return $link;
  566. }
  567. /** ----------------------------------------
  568. /** Prep Screen Name for Display
  569. /** ----------------------------------------*/
  570. function prep_screen_name($str)
  571. {
  572. return str_replace(array('<', '>', '{', '}', '\'', '"', '?'), array('&lt;', '&gt;', '&#123;', '&#125;', '&#146;', '&quot;', '&#63;'), $str);
  573. }
  574. /** ----------------------------------------
  575. /** Prep Title Display
  576. /** ----------------------------------------*/
  577. function prep_title($str)
  578. {
  579. if ($this->EE->config->item('word_separator') == 'dash')
  580. {
  581. return str_replace(array('-', $this->cats_separator), array(' ', $this->cats_display_separator), $str);
  582. }
  583. else
  584. {
  585. return str_replace(array('_', $this->cats_separator), array(' ', $this->cats_display_separator), $str);
  586. }
  587. }
  588. /** ----------------------------------------
  589. /** Create Valid Topic Name
  590. /** ----------------------------------------*/
  591. function valid_title($str)
  592. {
  593. // Remove all numeric entities
  594. $str = preg_replace('/&#x([0-9a-f]{2,5});{0,1}|&#([0-9]{2,4});{0,1}/', '', $str);
  595. /*
  596. The PCRE_UTF8 ('u') modifier is not available until PHP 4.2.3 for Windows, so if it is not
  597. available, then for the time being we are not allowing those higher end characters. We
  598. will change this once the character library is finished and ready for prime time.
  599. UPDATE: Well, while the PHP documentation says the flag is "available", this does not seem
  600. to denote that it will actually "work". Seems with the myriad of problems with servers
  601. having the correct PCRE library *and* compiling PHP with it correctly (RedHat Enterprise 3, for example),
  602. we cannot realistically do this until a version of PHP greater than PHP 4.3.2. Sheesh...
  603. */
  604. $trans = array();
  605. if (is_php('4.3.2') === TRUE)
  606. {
  607. $trans["#[^a-z0-9\-\_@&\'\"!\.:\+\x{A1}-\x{44F}\s]#iu"] = '';
  608. }
  609. else
  610. {
  611. $trans["#[^a-z0-9\-\_@&\'\"!\.:\+\xA1-\xFF\s]#i"] = '';
  612. }
  613. // Use dash or underscore as separator
  614. $replace = ($this->EE->config->item('word_separator') == 'dash') ? '-' : '_';
  615. $trans = array_merge($trans, array(
  616. '/\s+/' => $replace,
  617. "/{$replace}+/" => $replace,
  618. "/{$replace}$/" => $replace,
  619. "/^{$replace}/" => $replace
  620. ));
  621. return preg_replace(array_keys($trans), array_values($trans), urldecode($str));
  622. }
  623. /** ----------------------------------------
  624. /** Take Namespace's Short Name and Convert to Label
  625. /** ----------------------------------------*/
  626. function namespace_label($short_name)
  627. {
  628. if ($short_name != '')
  629. {
  630. $short_name = strtolower($short_name);
  631. $short_name = (isset($this->namespaces[$short_name])) ? $this->namespaces[$short_name]['1'] : '';
  632. }
  633. return $short_name;
  634. }
  635. /** ----------------------------------------
  636. /** Encode EE Tags
  637. /** ----------------------------------------*/
  638. function encode_ee_tags($str)
  639. {
  640. return str_replace(array('{','}'), array('&#123;','&#125;'), $str);
  641. }
  642. /* ----------------------------------------
  643. /* Topic Request!
  644. /*
  645. /* - Title = Namespace:Topic
  646. /* - If no namespace, then Title and Topic are
  647. /* the same thing
  648. /* ----------------------------------------*/
  649. function topic_request($title)
  650. {
  651. $title = $this->valid_title($title);
  652. $xsql = " AND page_namespace = '' ";
  653. // In the beginning, these are the same thing
  654. $this->topic = $title;
  655. $this->title = $title;
  656. if (stristr($title, ':') && count($this->namespaces) > 0)
  657. {
  658. $parts = explode(':', $title, 2);
  659. /* In PHP 5.1 this loop was consistently faster than array_search() */
  660. foreach($this->namespaces as $name => $label)
  661. {
  662. if (strcasecmp($label['1'], $this->prep_title($parts['0'])) == 0)
  663. {
  664. $xsql = " AND LOWER(page_namespace) = '".$this->EE->db->escape_str($name)."' ";
  665. $this->topic = substr($this->topic, strlen($label['1'].':'));
  666. $this->current_namespace = $label['1'];
  667. $this->title = $this->current_namespace.':'.$this->topic;
  668. break;
  669. }
  670. }
  671. }
  672. return $this->EE->db->query("SELECT * FROM exp_wiki_page
  673. WHERE wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."'
  674. AND LOWER(page_name) = '".strtolower($this->EE->db->escape_str($this->topic))."'
  675. {$xsql}");
  676. }
  677. /** ----------------------------------------
  678. /** Load Image
  679. /** ----------------------------------------*/
  680. function image($topic, $return=FALSE)
  681. {
  682. if ($return === FALSE)
  683. {
  684. $this->title = $this->image_ns.':'.$topic;
  685. }
  686. /*
  687. No way to show the image if we do not have a valid upload directory
  688. because we need the URL for that directory.
  689. */
  690. if ($this->valid_upload_dir != 'y')
  691. {
  692. if ($return === TRUE) return FALSE;
  693. $this->redirect($this->file_ns, $topic);
  694. }
  695. /** ----------------------------------------
  696. /** Does File Exist? Is It An Image?
  697. /** ----------------------------------------*/
  698. $query = $this->EE->db->query("SELECT * FROM exp_wiki_uploads
  699. WHERE file_name = '".$this->EE->db->escape_str($topic)."'");
  700. if ($query->num_rows() == 0)
  701. {
  702. if ($return === TRUE) return FALSE;
  703. $this->redirect($this->file_ns, $topic);
  704. }
  705. $x = explode('/',$query->row('file_type') );
  706. if ($x['0'] != 'image')
  707. {
  708. if ($return === TRUE) return FALSE;
  709. $this->redirect($this->file_ns, $topic);
  710. }
  711. /** ----------------------------------------
  712. /** Create Our URL
  713. /** ----------------------------------------*/
  714. if ($return === TRUE)
  715. {
  716. $file_url = $this->base_url.$query->row('file_hash');
  717. }
  718. else
  719. {
  720. $results = $this->EE->db->query("SELECT url FROM exp_upload_prefs
  721. WHERE id = '".$this->EE->db->escape_str($this->upload_dir)."'");
  722. $file_url = (substr($results->row('url') , -1) == '/') ? $results->row('url') : $results->row('url') .'/';
  723. $file_url .= $query->row('file_name') ;
  724. }
  725. /* ----------------------------------------
  726. /* Display Our Image
  727. /* - Now in the future we might be clever and obfuscate the location
  728. /* - of images, if it is requested, by using fopen to get the image
  729. /* - data and displaying it instead of doing a redirect to the URL
  730. /* ----------------------------------------*/
  731. if ($return === TRUE)
  732. {
  733. return array('url' => $file_url,
  734. 'width' => $query->row('image_width') ,
  735. 'height' => $query->row('image_height') ,
  736. 'name' => $query->row('file_name') );
  737. }
  738. $this->EE->functions->redirect($file_url);
  739. exit;
  740. }
  741. /** ----------------------------------------
  742. /** File
  743. /** ----------------------------------------*/
  744. function file($topic)
  745. {
  746. $this->title = $this->file_ns.':'.$topic;
  747. $this->topic = $topic;
  748. /** ----------------------------------------
  749. /** Delete File? Admins Only!
  750. /** ----------------------------------------*/
  751. if (isset($this->seg_parts['1']) && strtolower($this->seg_parts['1']) == 'delete')
  752. {
  753. if ($this->can_upload == 'y' && in_array($this->EE->session->userdata['group_id'], $this->admins))
  754. {
  755. $query = $this->EE->db->query("SELECT COUNT(*) AS count FROM exp_wiki_uploads
  756. WHERE file_name = '".$this->EE->db->escape_str($topic)."'");
  757. if ($query->row('count') > 0)
  758. {
  759. $query = $this->EE->db->query("SELECT * FROM exp_upload_prefs
  760. WHERE id = '".$this->EE->db->escape_str($this->upload_dir)."'");
  761. $server_path = $query->row('server_path');
  762. if (substr($server_path , -1) != '/')
  763. {
  764. $server_path .= '/';
  765. }
  766. @unlink($server_path.$topic);
  767. $query = $this->EE->db->query("DELETE FROM exp_wiki_uploads
  768. WHERE file_name = '".$this->EE->db->escape_str($topic)."'");
  769. // Clear wiki cache
  770. $this->EE->functions->clear_caching('db');
  771. $this->redirect($this->special_ns, 'Files');
  772. }
  773. }
  774. }
  775. $this->return_data = $this->_deny_if('new_article', $this->return_data);
  776. $this->return_data = $this->_deny_if('article', $this->return_data);
  777. $this->return_data = $this->_deny_if('revision', $this->return_data);
  778. $this->return_data = $this->_deny_if('edit_article', $this->return_data);
  779. $this->return_data = $this->_deny_if('article_history', $this->return_data);
  780. $this->return_data = $this->_deny_if('special_page', $this->return_data);
  781. $this->return_data = $this->_allow_if('file_page', $this->return_data);
  782. $this->return_data = str_replace('{wiki:page}', $this->_fetch_template('wiki_file.html'), $this->return_data);
  783. $query = $this->EE->db->query("SELECT u.*, m.member_id, m.screen_name, m.email, m.url
  784. FROM exp_wiki_uploads u, exp_members m
  785. WHERE u.file_name = '".$this->EE->db->escape_str($topic)."'
  786. AND u.wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."'
  787. AND u.upload_author = m.member_id");
  788. /** ----------------------------------------
  789. /** Does File Exist? What Kind?
  790. /** ----------------------------------------*/
  791. if ($query->num_rows() == 0)
  792. {
  793. $this->return_data = $this->_deny_if('file_exists', $this->return_data);
  794. return;
  795. }
  796. else
  797. {
  798. $this->return_data = $this->_allow_if('file_exists', $this->return_data);
  799. }
  800. $x = explode('/',$query->row('file_type') );
  801. if ($x['0'] == 'image')
  802. {
  803. $this->return_data = $this->_allow_if('is_image', $this->return_data);
  804. }
  805. else
  806. {
  807. $this->return_data = $this->_deny_if('is_image', $this->return_data);
  808. }
  809. /** ----------------------------------------
  810. /** Date Formats
  811. /** ----------------------------------------*/
  812. if (preg_match_all("/".LD."(upload_date)\s+format=[\"'](.*?)[\"']".RD."/s", $this->return_data, $matches))
  813. {
  814. for ($j = 0; $j < count($matches['0']); $j++)
  815. {
  816. switch ($matches['1'][$j])
  817. {
  818. case 'upload_date' : $upload_date[$matches['0'][$j]] = array($matches['2'][$j], $this->EE->localize->fetch_date_params($matches['2'][$j]));
  819. break;
  820. }
  821. }
  822. foreach($upload_date as $key => $value)
  823. {
  824. $temp_date = $value['0'];
  825. foreach ($value['1'] as $dvar)
  826. {
  827. $temp_date = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $row['upload_date'], FALSE), $temp_date);
  828. }
  829. $this->return_data = str_replace($key, $temp_date, $this->return_data);
  830. }
  831. }
  832. /** ----------------------------------------
  833. /** Parse Variables
  834. /** ----------------------------------------*/
  835. $this->EE->load->library('typography');
  836. $this->EE->typography->initialize();
  837. $this->EE->typography->parse_images = FALSE;
  838. $this->EE->typography->parse_smileys = FALSE;
  839. $summary = $this->convert_curly_brackets($this->EE->typography->parse_type( $this->wiki_syntax($query->row('upload_summary') ),
  840. array(
  841. 'text_format' => $this->text_format,
  842. 'html_format' => $this->html_format,
  843. 'auto_links' => $this->auto_links,
  844. 'allow_img_url' => 'y'
  845. )
  846. ));
  847. $delete_url = '';
  848. if ($this->valid_upload_dir != 'y')
  849. {
  850. $file_url = $query->row('file_name') ;
  851. }
  852. else
  853. {
  854. $file_url = $this->base_url.$query->row('file_hash');
  855. if (in_array($this->EE->session->userdata['group_id'], $this->admins))
  856. {
  857. $delete_url = $this->base_url.$this->file_ns.':'.$query->row('file_name').'/delete';
  858. }
  859. }
  860. $this->conditionals['summary'] = $summary;
  861. $this->conditionals['delete_url'] = $delete_url;
  862. $this->conditionals = array_merge($this->conditionals, $query->row_array());
  863. /** ----------------------------------------
  864. /** Can User Edit File?
  865. /** ----------------------------------------*/
  866. if(in_array($this->EE->session->userdata['group_id'], $this->users) OR in_array($this->EE->session->userdata['group_id'], $this->admins))
  867. {
  868. $this->return_data = $this->_allow_if('can_edit', $this->return_data);
  869. $this->return_data = $this->_deny_if('cannot_edit', $this->return_data);
  870. }
  871. else
  872. {
  873. $this->return_data = $this->_deny_if('can_edit', $this->return_data);
  874. $this->return_data = $this->_allow_if('cannot_edit', $this->return_data);
  875. }
  876. $this->return_data = str_replace(array('{file_url}','{delete_url}','{file_name}','{summary}', '{image_width}', '{image_height}', '{file_type}'),
  877. array($file_url, $delete_url, $query->row('file_name') , $summary, $query->row('image_width') , $query->row('image_height') , $query->row('file_type') ),
  878. $this->return_data);
  879. }
  880. /** ----------------------------------------
  881. /** Special
  882. /** ----------------------------------------*/
  883. function special($topic)
  884. {
  885. $this->topic = $topic;
  886. $this->title = $this->special_ns.':'.$topic;
  887. $this->return_data = $this->_deny_if('new_article', $this->return_data);
  888. $this->return_data = $this->_deny_if('article', $this->return_data);
  889. $this->return_data = $this->_deny_if('revision', $this->return_data);
  890. $this->return_data = $this->_deny_if('edit_article', $this->return_data);
  891. $this->return_data = $this->_deny_if('article_history', $this->return_data);
  892. $this->return_data = $this->_allow_if('special_page', $this->return_data);
  893. /* -------------------------------------
  894. /* 'wiki_special_page' hook.
  895. /* - Allows complete takeover of special pages
  896. /* - Added 1.6.0
  897. */
  898. $edata = $this->EE->extensions->universal_call('wiki_special_page', $this, $topic);
  899. if ($this->EE->extensions->end_script === TRUE) return;
  900. /*
  901. /* -------------------------------------*/
  902. switch(strtolower($topic))
  903. {
  904. case 'recentchanges' :
  905. $this->recent_changes();
  906. break;
  907. case 'search_results' :
  908. $this->search_results();
  909. break;
  910. case 'random_page' :
  911. $this->random_page();
  912. break;
  913. case 'categories' :
  914. $this->categories();
  915. break;
  916. case 'files' :
  917. $this->files();
  918. break;
  919. case 'find_page' :
  920. $this->find_page();
  921. break;
  922. case 'uploads' :
  923. $this->upload_form();
  924. break;
  925. case 'recentchanges_rss' :
  926. $this->EE->output->out_type = 'feed';
  927. $this->EE->TMPL->template_type = 'feed';
  928. $this->return_data = $this->_fetch_template('wiki_special_rss.html');
  929. $this->recent_changes('rss');
  930. break;
  931. case 'recentchanges_atom' :
  932. $this->EE->output->out_type = 'feed';
  933. $this->EE->TMPL->template_type = 'feed';
  934. $this->return_data = $this->_fetch_template('wiki_special_atom.html');
  935. $this->recent_changes('atom');
  936. break;
  937. case 'titles' :
  938. $this->title_list();
  939. break;
  940. case 'associated_pages' :
  941. $this->associated_pages();
  942. break;
  943. case 'uncategorized' :
  944. $this->uncategorized_pages();
  945. break;
  946. case 'css' :
  947. $this->wiki_css();
  948. break;
  949. default:
  950. $this->return_data = str_replace('{wiki:page}', '', $this->return_data);
  951. break;
  952. }
  953. $this->return_data = $this->_deny_if('can_edit', $this->return_data);
  954. $this->return_data = $this->_allow_if('cannot_edit', $this->return_data);
  955. }
  956. // --------------------------------------------------------------------
  957. /**
  958. * Wiki CSS
  959. *
  960. * Outputs the default Wiki CSS theme file with proper headers
  961. *
  962. * @access public
  963. * @return void
  964. */
  965. function wiki_css()
  966. {
  967. // reset! We just want the CSS
  968. $this->return_data = $this->_fetch_template('wiki_style.css');
  969. if ($this->return_data === FALSE)
  970. {
  971. // no point
  972. exit;
  973. }
  974. // replace image paths
  975. $this->return_data = str_replace('{path:image_url}', $this->image_url, $this->return_data);
  976. $last_modified = filemtime($this->theme_path.'wiki_style.css');
  977. $this->EE->load->library('stylesheet');
  978. $this->EE->stylesheet->_send_css($this->return_data, $last_modified);
  979. }
  980. // --------------------------------------------------------------------
  981. /** ---------------------------------------
  982. /** Uncategorized Pages
  983. /** ---------------------------------------*/
  984. function uncategorized_pages()
  985. {
  986. return $this->title_list('uncategorized_pages');
  987. }
  988. /* END */
  989. /** ----------------------------------------
  990. /** Recent Changes Processing
  991. /** ----------------------------------------*/
  992. function title_list($type = '')
  993. {
  994. /** ---------------------------------------
  995. /** Initialize the correct template and do any
  996. /** prep work needed prior to our title query
  997. /** ---------------------------------------*/
  998. switch ($type)
  999. {
  1000. case 'uncategorized_pages' :
  1001. $this->return_data = str_replace('{wiki:page}', $this->_fetch_template('wiki_special_uncategorized_pages.html'), $this->return_data);
  1002. /** ---------------------------------------
  1003. /** Get categorized page ids
  1004. /** ---------------------------------------*/
  1005. $query = $this->EE->db->query("SELECT DISTINCT(exp_wiki_category_articles.page_id)
  1006. FROM exp_wiki_category_articles
  1007. LEFT JOIN exp_wiki_page ON exp_wiki_page.page_id = exp_wiki_category_articles.page_id
  1008. WHERE exp_wiki_page.wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."'");
  1009. if ($query->num_rows() > 0)
  1010. {
  1011. $page_ids = array();
  1012. foreach ($query->result() as $row)
  1013. {
  1014. $page_ids[] = $row->page_id;
  1015. }
  1016. $xsql = " AND p.page_id NOT IN (".implode(',', $page_ids).")
  1017. AND p.page_redirect = '' ";
  1018. }
  1019. break;
  1020. default :
  1021. $this->return_data = str_replace('{wiki:page}', $this->_fetch_template('wiki_special_titles.html'), $this->return_data);
  1022. break;
  1023. }
  1024. if ( ! preg_match("/\{wiki:title_list(.*?)\}(.*?)\{\/wiki:title_list\}/s", $this->return_data, $match))
  1025. {
  1026. return $this->return_data = '';
  1027. }
  1028. if ( ! preg_match("/\{articles\}(.*?)\{\/articles\}/s", $match['2'], $topics))
  1029. {
  1030. return $this->return_data = '';
  1031. }
  1032. /** ----------------------------------------
  1033. /** Parameters
  1034. /** ----------------------------------------*/
  1035. $columns = 3;
  1036. if (trim($match['1']) != '' && ($params = $this->EE->functions->assign_parameters($match['1'])) !== FALSE)
  1037. {
  1038. $columns = (isset($params['columns']) && is_numeric($params['columns'])) ? $params['columns'] : $limit;
  1039. }
  1040. /** ----------------------------------------
  1041. /** Date Formats
  1042. /** ----------------------------------------*/
  1043. $dates = $this->parse_dates($this->return_data);
  1044. /** ----------------------------------------
  1045. /** Our Query
  1046. /** ----------------------------------------*/
  1047. if ( ! isset($xsql))
  1048. {
  1049. $xsql = '';
  1050. }
  1051. if (isset($this->seg_parts['1']) && isset($this->namespaces[strtolower($this->seg_parts['1'])]))
  1052. {
  1053. $xsql = "AND LOWER(p.page_namespace) = '".$this->EE->db->escape_str(strtolower($this->seg_parts['1']))."'";
  1054. }
  1055. else
  1056. {
  1057. $xsql = "AND p.page_namespace = ''";
  1058. }
  1059. $results = $this->EE->db->query("SELECT r.*,
  1060. m.member_id, m.screen_name, m.email, m.url,
  1061. p.page_namespace, p.page_name AS topic
  1062. FROM exp_wiki_revisions r, exp_members m, exp_wiki_page p
  1063. WHERE p.last_updated = r.revision_date
  1064. {$xsql}
  1065. AND m.member_id = r.revision_author
  1066. AND r.page_id = p.page_id
  1067. AND r.revision_status = 'open'
  1068. AND r.wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."'
  1069. ORDER BY p.page_name");
  1070. if ($results->num_rows() == 0)
  1071. {
  1072. if (preg_match("|".LD."if\s+no_results".RD."(.*?)".LD."\/if".RD."|s",$match['2'], $block))
  1073. {
  1074. $this->return_data = str_replace($match['0'], $block['1'], $this->return_data);
  1075. }
  1076. else
  1077. {
  1078. $this->return_data = str_replace($match['0'], str_replace($topics['0'], '', $match['2']), $this->return_data);
  1079. }
  1080. return;
  1081. }
  1082. /** ----------------------------------------
  1083. /** Template Parts
  1084. /** ----------------------------------------*/
  1085. $our_template = $topics['1'];
  1086. $row_start = '';
  1087. $row_end = '';
  1088. $row_blank = '';
  1089. $row_column = '';
  1090. foreach(array('row_start', 'row_end', 'row_blank', 'row_column') as $val)
  1091. {
  1092. if (preg_match("/\{".preg_quote($val)."\}(.*?)\{\/".preg_quote($val)."\}/s", $our_template, $matching))
  1093. {
  1094. $$val = $matching['1'];
  1095. }
  1096. }
  1097. $template = $row_column;
  1098. /** ----------------------------------------
  1099. /** Parsing of the Recent Changes Tag Pair
  1100. /** ----------------------------------------*/
  1101. $parse_article = stristr($template, '{article}');
  1102. $this->EE->load->library('typography');
  1103. $this->EE->typography->initialize();
  1104. $this->EE->typography->parse_images = FALSE;
  1105. $this->EE->typography->parse_smileys = FALSE;
  1106. $titles = $row_start;
  1107. $i = 0;
  1108. $count = 0;
  1109. // added in 1.6 for {switch} variable and for future use
  1110. $vars = $this->EE->functions->assign_variables($template);
  1111. $this->EE->load->helper('url');
  1112. foreach($results->result_array() as $row)
  1113. {
  1114. $count++;
  1115. $titles .= ($i % $columns != 0) ? '' : $row_end.$row_start; ++$i;
  1116. $temp = $template;
  1117. if (isset($this->seg_parts['1']) && isset($this->namespaces[strtolower($this->seg_parts['1'])]))
  1118. {
  1119. $title = $row['topic'];
  1120. }
  1121. else
  1122. {
  1123. $title = ($row['page_namespace'] != '') ? $this->namespace_label($row['page_namespace']).':'.$row['topic'] : $row['topic'];
  1124. }
  1125. $link = $this->create_url($this->namespace_label($row['page_namespace']), $row['topic']);
  1126. $data = array( '{title}' => $this->prep_title($title),
  1127. '{revision_id}' => $row['revision_id'],
  1128. '{page_id}' => $row['page_id'],
  1129. '{author}' => $row['screen_name'],
  1130. '{path:author_profile}' => $this->EE->functions->create_url($this->profile_path.$row['member_id']),
  1131. '{path:member_profile}' => $this->EE->functions->create_url($this->profile_path.$row['member_id']),
  1132. '{email}' => $this->EE->typography->encode_email($row['email']),
  1133. '{url}' => prep_url($row['url']),
  1134. '{revision_notes}' => $row['revision_notes'],
  1135. '{path:view_article}' => $link,
  1136. '{content}' => $row['page_content'],
  1137. '{count}' => $count);
  1138. if ($parse_article !== FALSE)
  1139. {
  1140. $data['{article}'] = $this->convert_curly_brackets($this->EE->typography->parse_type( $this->wiki_syntax($row['page_content'], FALSE),
  1141. array(
  1142. 'text_format' => $this->text_format,
  1143. 'html_format' => $this->html_format,
  1144. 'auto_links' => $this->auto_links,
  1145. 'allow_img_url' => 'y'
  1146. )
  1147. ));
  1148. }
  1149. $temp = $this->prep_conditionals($temp, array_merge($data, $this->conditionals));
  1150. if (isset($dates['last_updated']))
  1151. {
  1152. foreach($dates['last_updated'] as $key => $value)
  1153. {
  1154. $temp_date = $value['0'];
  1155. // Do this once here, to save energy
  1156. $row['revision_date'] = $this->EE->localize->set_localized_time($row['revision_date']);
  1157. foreach ($value['1'] as $dvar)
  1158. {
  1159. $temp_date = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $row['revision_date'], FALSE), $temp_date);
  1160. }
  1161. $data[$key] = $temp_date;
  1162. }
  1163. }
  1164. foreach ($vars['var_single'] as $key => $val)
  1165. {
  1166. /** ----------------------------------------
  1167. /** parse {switch} variable
  1168. /** ----------------------------------------*/
  1169. if (preg_match("/^switch\s*=.+/i", $key))
  1170. {
  1171. $sparam = $this->EE->functions->assign_parameters($key);
  1172. $sw = '';
  1173. if (isset($sparam['switch']))
  1174. {
  1175. $sopt = explode("|", $sparam['switch']);
  1176. $sw = $sopt[($count-1 + count($sopt)) % count($sopt)];
  1177. }
  1178. $temp = $this->EE->TMPL->swap_var_single($key, $sw, $temp);
  1179. }
  1180. }
  1181. $titles .= str_replace(array_keys($data), array_values($data), $temp);
  1182. }
  1183. while($i % $columns != 0)
  1184. {
  1185. $titles .= $row_blank; ++$i;
  1186. }
  1187. $titles .= $row_end;
  1188. $this->return_data = str_replace($match['0'], str_replace($topics['0'], $titles, $match['2']), $this->return_data);
  1189. }
  1190. /** ----------------------------------------
  1191. /** Recent Changes Processing
  1192. /** ----------------------------------------*/
  1193. function recent_changes($type='')
  1194. {
  1195. /** ----------------------------------------
  1196. /** Load Template, Check for Valid Tag
  1197. /** ----------------------------------------*/
  1198. $this->return_data = str_replace('{wiki:page}', $this->_fetch_template('wiki_special_recent_changes.html'), $this->return_data);
  1199. if ( ! preg_match("/\{wiki:recent_changes(.*?)\}(.*?)\{\/wiki:recent_changes\}/s", $this->return_data, $match))
  1200. {
  1201. return $this->return_data = '';
  1202. }
  1203. /** ----------------------------------------
  1204. /** Parameters
  1205. /** ----------------------------------------*/
  1206. $parameters['limit'] = 10;
  1207. $parameters['paginate'] = 'bottom';
  1208. if (trim($match['1']) != '' && ($params = $this->EE->functions->assign_parameters($match['1'])) !== FALSE)
  1209. {
  1210. $parameters['limit'] = (isset($params['limit']) && is_numeric($params['limit'])) ? $params['limit'] : $parameters['limit'];
  1211. $parameters['paginate'] = (isset($params['paginate']) && is_numeric($params['paginate'])) ? $params['paginate'] : $parameters['paginate'];
  1212. }
  1213. /** ----------------------------------------
  1214. /** Date Formats
  1215. /** ----------------------------------------*/
  1216. $dates = $this->parse_dates($this->return_data);
  1217. /** ----------------------------------------
  1218. /** Our Query
  1219. /** ----------------------------------------*/
  1220. if (isset($this->seg_parts['1']) && $this->seg_parts['1'] != '' && ! preg_match("/^P[0-9]+$/", $this->seg_parts['1']))
  1221. {
  1222. $query = $this->topic_request($this->seg_parts['1']);
  1223. $sql = "FROM exp_wiki_revisions r, exp_members m, exp_wiki_page p
  1224. WHERE p.page_id = '".(($query->num_rows() > 0) ? $query->row('page_id') : '0')."'
  1225. AND r.page_id = p.page_id
  1226. AND r.revision_status = 'open'
  1227. AND r.wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."'
  1228. AND m.member_id = r.revision_author
  1229. ORDER BY r.revision_date DESC";
  1230. }
  1231. else
  1232. {
  1233. $sql = "FROM exp_wiki_revisions r, exp_members m, exp_wiki_page p
  1234. WHERE p.last_updated = r.revision_date
  1235. AND m.member_id = r.revision_author
  1236. AND r.page_id = p.page_id
  1237. AND r.revision_status = 'open'
  1238. AND r.wiki_id = '".$this->EE->db->escape_str($this->wiki_id)."'
  1239. ORDER BY p.last_updated DESC";
  1240. }
  1241. $results = $this->EE->db->query("SELECT COUNT(*) AS count ".$sql);
  1242. if ($results->row('count') == 0)
  1243. {
  1244. return $this->return_data = '';
  1245. }
  1246. $this->pagination($results->row('count') , $parameters['limit'], $this->base_url.$this->special_ns.':Recentchanges/');
  1247. // Pagination code removed, rerun template preg_match()
  1248. if ($this->paginate === TRUE)
  1249. {
  1250. preg_match("/\{wiki:recent_changes(.*?)\}(.*?)\{\/wiki:recent_changes\}/s", $this->return_data, $match);
  1251. }
  1252. else
  1253. {
  1254. $this->pagination_sql .= " LIMIT ".$parameters['limit'];
  1255. }
  1256. $results = $this->EE->db->query("SELECT r.*,
  1257. m.member_id, m.screen_name, m.email, m.url,
  1258. p.page_namespace, p.page_name AS topic ".
  1259. $sql.
  1260. $this->pagination_sql);
  1261. /** ----------------------------------------
  1262. /** Global Last Updated
  1263. /** ----------------------------------------*/
  1264. if (isset($dates['last_updated']))
  1265. {
  1266. foreach($dates['last_updated'] as $key => $value)
  1267. {
  1268. $temp_date = $value['0'];
  1269. foreach ($value['1'] as $dvar)
  1270. {
  1271. $temp_date = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $results->row('revision_date') , TRUE), $temp_date);
  1272. }
  1273. $this->return_data = str_replace($key, $temp_date, $this->return_data);
  1274. }
  1275. }
  1276. if (isset($dates['gmt_last_updated']))
  1277. {
  1278. foreach($dates['gmt_last_updated'] as $key => $value)
  1279. {
  1280. $temp_date = $value['0'];
  1281. foreach ($value['1'] as $dvar)
  1282. {
  1283. $temp_date = str_replace($dvar, $this->EE->localize->convert_timestamp($dvar, $results->row('revision_date') , FALSE), $temp_date);
  1284. }
  1285. $this->return_data = str_replace($key, $temp_date, $this->return_data);
  1286. }
  1287. }
  1288. /** -----------------------------------…

Large files files are truncated, but you can click here to view the full file