PageRenderTime 44ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/system/core/core.messages.php

https://github.com/danboy/Croissierd
PHP | 5494 lines | 4770 code | 404 blank | 320 comment | 215 complexity | 02e09200b7cfe6ae7e8fdcad36141dc1 MD5 | raw 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/docs/license.html
  13. =====================================================
  14. File: core.messages.php
  15. -----------------------------------------------------
  16. Purpose: Private Messages
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Messages {
  24. // URL Writing
  25. var $allegiance = 'cp'; // Side of the divide: cp or user
  26. var $CP = FALSE; // CP Object
  27. var $base_url = ''; // Base URL used throughout
  28. var $form_url = ''; // For CP Forms, since Rick was a doofus and changed how they work
  29. var $path = 'member/'; // User Side Path
  30. var $request = 'inbox'; // User Side Request
  31. var $cur_id = ''; // User Side ID, if any
  32. var $theme_class = 'profile_theme';
  33. var $images_folder = ''; // Location of Forum Images
  34. // Member Specific
  35. var $member_id = '';
  36. var $private_messages = '0'; // Number of unread private messages
  37. var $block_tracking = 'n'; // Block Sender Tracking
  38. // Member Group Specific
  39. var $allow_pm = 'y'; // Allowed to PM?
  40. var $attach_allowed = 'y'; // Attachments allowed?
  41. // Private Message Preferences
  42. var $storage_limit = 60; // Limit for messages to store per user (does not count deleted)
  43. var $send_limit = 20; // Limit for messages sent a day
  44. var $upload_path = ''; // Upload path for files
  45. var $attach_maxsize = 250; // Max size for attachments (KB)
  46. var $attach_total = 100; // Maximum amount for all PM attachments (MB)
  47. var $html_format = 'safe'; // HTML Formatting?
  48. var $auto_links = 'y'; // Auto convert URLs to links
  49. var $max_chars = 6000; // Maximum number of characters in a messages
  50. var $max_attachments = 1; // Maximum number of attachments per message
  51. // User Data Variables
  52. var $total_messages = ''; // Total Store Messages for User
  53. var $current_folder = '1'; // If any...
  54. var $folders = array(); // Folders for User
  55. var $hide_preview = FALSE; // Whether to show the Preview of Message
  56. var $attachments = array(); // Attachments for current message
  57. var $baddies = array(); // Blocked List; IDs only
  58. var $goodies = array(); // Buddies List; IDs only
  59. var $blocked = FALSE; // Blocked List
  60. var $buddies = FALSE; // Buddies List
  61. var $invalid_name = FALSE; // Invalid name submitted?
  62. // Menu Content
  63. var $menu_items = array(); // Abstracted data for creating menu
  64. var $menu = ''; // Menu fully formed
  65. // Processing and Returned Data
  66. var $title = ''; // Title of Page
  67. var $crumb = ''; // Crumb text for page
  68. var $return_data = ''; // Output data
  69. var $header_javascript = ''; // User Side Header JavaScript
  70. var $error = ''; // Submission Error
  71. var $single_parts = array(); // Parts of a page: text, form, images, content
  72. var $conditionals = array(); // Conditionals
  73. var $mimes = '';
  74. // Changeable Class Variables
  75. var $default_folders = array('Inbox', 'Sent');
  76. var $max_folders = 10; // Maximum number of folders per user
  77. var $per_page = 25; // Messages on a Folder's Page
  78. var $graph_width = '300'; // Width of Total Messages Graph
  79. var $emoticons_per_row = 5; // Number of Images Per Table Row
  80. var $delete_expiration = 30; // Erase deleted messages after X days
  81. var $disable_emoticons = 'n'; // Disable the showing of emoticons
  82. var $spellcheck_enabled = TRUE; // Enabled Spellcheck?
  83. /** -----------------------------------
  84. /** Constructor
  85. /** -----------------------------------*/
  86. function Messages()
  87. {
  88. global $IN, $LANG, $FNS, $PREFS, $SESS;
  89. /** -----------------------------------
  90. /** A Few Things to Define, Batman
  91. /** -----------------------------------*/
  92. $this->member_id = $SESS->userdata['member_id'];
  93. $this->allow_pm = ($SESS->userdata['group_id'] == '1') ? 'y' : $SESS->userdata['can_send_private_messages'];
  94. $this->allow_pm = ($this->allow_pm == 'y' && $SESS->userdata['accept_messages'] == 'y') ? 'y' : 'n';
  95. $this->attach_allowed = $SESS->userdata('can_attach_in_private_messages');
  96. $this->storage_limit = ($SESS->userdata['group_id'] == '1') ? 0 : $SESS->userdata['prv_msg_storage_limit'];
  97. $this->send_limit = $SESS->userdata['prv_msg_send_limit'];
  98. if ( ! defined('AMP')) define('AMP', '&amp;');
  99. if ( ! defined('BR')) define('BR', '<br />');
  100. if ( ! defined('NL')) define('NL', "\n");
  101. if ( ! defined('NBS')) define('NBS', "&nbsp;");
  102. $prefs = array( 'prv_msg_attach_maxsize',
  103. 'prv_msg_attach_total',
  104. 'prv_msg_html_format',
  105. 'prv_msg_auto_links',
  106. 'prv_msg_max_chars',
  107. 'prv_msg_max_attachments'
  108. );
  109. for($i=0, $t = sizeof($prefs); $i < $t; ++$i)
  110. {
  111. if (FALSE !== ($value = $PREFS->ini($prefs[$i])))
  112. {
  113. $name = str_replace('prv_msg_', '', $prefs[$i]);
  114. $this->{$name} = $value;
  115. }
  116. }
  117. $this->upload_path = $PREFS->ini('prv_msg_upload_path', TRUE);
  118. // -----------------------------------
  119. // Nearly every page requires this,
  120. // so just load it for all of them
  121. // -----------------------------------
  122. $LANG->fetch_language_file('messages');
  123. $this->title = $LANG->line('private_messages');
  124. $this->crumb = $LANG->line('private_messages');
  125. $this->images_folder = $PREFS->ini('theme_folder_url', TRUE).'cp_global_images/';
  126. $this->single_parts['path']['image_url'] = $this->images_folder;
  127. /** -----------------------------------
  128. /** Maintenance
  129. /** -----------------------------------*/
  130. srand(time());
  131. if ((rand() % 100) < 5)
  132. {
  133. $this->maintenance();
  134. }
  135. }
  136. /* END */
  137. /** -----------------------------------
  138. /** Determine request
  139. /** -----------------------------------*/
  140. function _determine_request()
  141. {
  142. global $IN;
  143. if ($this->allegiance == 'cp')
  144. {
  145. $this->base_url = BASE.AMP.'C=myaccount'.AMP.'M=messages'.AMP.'P=';
  146. $this->form_url = 'C=myaccount'.AMP.'M=messages'.AMP.'P=';
  147. $this->request = ($IN->GBL('P') !== FALSE) ? $IN->GBL('P') : 'inbox';
  148. }
  149. else
  150. {
  151. $this->form_url = $this->base_url;
  152. }
  153. }
  154. /* END */
  155. /** -----------------------------------
  156. /** Create Path
  157. /** -----------------------------------*/
  158. function _create_path($uri='', $hidden='')
  159. {
  160. if ($this->allegiance == 'user')
  161. {
  162. return $this->base_url.$uri.'/';
  163. }
  164. else
  165. {
  166. return $this->base_url.$uri.$hidden;
  167. }
  168. }
  169. /* END */
  170. // -----------------------------------
  171. // Process Page :
  172. // Convert and Template into Content
  173. // -----------------------------------
  174. function _process_template($template, $data = '')
  175. {
  176. global $LANG, $REGX;
  177. /** -------------------------------
  178. /** Process Conditionals
  179. /** -------------------------------*/
  180. if (sizeof($this->conditionals) > 0)
  181. {
  182. foreach($this->conditionals as $key => $value)
  183. {
  184. if ($value == 'y')
  185. {
  186. $template = preg_replace("/\{if\s+".$key."\}(.+?)\{\/if\}/si", "\\1", $template);
  187. $template = preg_replace("/\{if\s+not_".$key."\}(.+?)\{\/if\}/si", '', $template);
  188. }
  189. else
  190. {
  191. $template = preg_replace("/\{if\s+".$key."\}.+?\{\/if\}/si", '', $template);
  192. $template = preg_replace("/\{if\s+not_".$key."\}(.+?)\{\/if\}/si", "\\1", $template);
  193. }
  194. }
  195. }
  196. /** --------------------------
  197. /** Process any sent data
  198. /** --------------------------*/
  199. if (is_array($data) && sizeof($data) > 0)
  200. {
  201. foreach($data as $key => $value)
  202. {
  203. $template = str_replace(LD.$key.RD, $value, $template);
  204. }
  205. }
  206. /** -----------------------------
  207. /** Process any universal data
  208. /** -----------------------------*/
  209. if (sizeof($this->single_parts) > 0)
  210. {
  211. foreach($this->single_parts as $key => $value)
  212. {
  213. if (is_array($value) && sizeof($value) > 0)
  214. {
  215. foreach($value as $key2 => $value2)
  216. {
  217. if (is_array($value2) && sizeof($value2) > 0)
  218. {
  219. foreach($value2 as $key3 => $value3)
  220. {
  221. $template = str_replace(LD.$key.':'.$key2.':'.$key3.RD, $value3, $template);
  222. }
  223. }
  224. else
  225. {
  226. if ($key == 'input' && $key2 == 'body')
  227. {
  228. $value2 = $REGX->encode_ee_tags($value2, TRUE);
  229. }
  230. $template = str_replace(LD.$key.':'.$key2.RD,
  231. ($key == 'input' && $key2 != 'body' && $key2 != 'folder_name') ? htmlspecialchars($value2, ENT_QUOTES) : $value2,
  232. $template);
  233. }
  234. }
  235. }
  236. elseif( ! is_array($value))
  237. {
  238. if ($key != 'title' && ! stristr($value, '<option')) $value = htmlspecialchars($value, ENT_QUOTES); // {title} is link title for message menu
  239. $template = str_replace(LD.$key.RD, $value, $template);
  240. }
  241. }
  242. }
  243. /** -------------------------------------
  244. /** Finally, process all language text
  245. /** -------------------------------------*/
  246. if (isset($LANG->language) && is_array($LANG->language) && sizeof($LANG->language) > 0)
  247. {
  248. foreach($LANG->language as $key => $value)
  249. {
  250. $template = str_replace(LD.'lang:'.$key.RD, $value, $template);
  251. }
  252. }
  253. return $template;
  254. }
  255. /* END */
  256. /** -----------------------------------
  257. /** Manage Request
  258. /** -----------------------------------*/
  259. function manager()
  260. {
  261. global $PREFS;
  262. if ($this->allow_pm != 'y')
  263. {
  264. return;
  265. }
  266. $this->_determine_request();
  267. if (sizeof($this->folders) == 0)
  268. {
  269. $this->fetch_folders();
  270. }
  271. if ($this->disable_emoticons == 'y')
  272. {
  273. $PREFS->core_ini['enable_emoticons'] = 'n';
  274. }
  275. /** -----------------------------------
  276. /** Call request
  277. /** -----------------------------------*/
  278. if (method_exists($this, $this->request))
  279. {
  280. $this->{$this->request}();
  281. }
  282. else
  283. {
  284. $this->inbox();
  285. }
  286. /* -----------------------------------
  287. /* Member Module - Fixeroo
  288. /* - Rick has some legacy code in the member module that converts
  289. /* certain path variables automatically. We, however, do not want that
  290. /* in our most precious Private Messages, and so we do a bit of conversion
  291. /* -----------------------------------*/
  292. $this->return_data = preg_replace("/".LD."\s*path=(.*?)".RD."/", '&#123;path=\\1}', $this->return_data);
  293. $this->return_data = preg_replace("#".LD."\s*(profile_path\s*=.*?)".RD."#", '&#123;\\1}', $this->return_data);
  294. /** -----------------------------------
  295. /** Name to ID in Form Switch - Fixeroo
  296. /** -----------------------------------*/
  297. $this->return_data = str_replace('opener.document.submit_message.', "opener.document.getElementById('submit_message').", $this->return_data);
  298. }
  299. /* END */
  300. /** -----------------------------------
  301. /** Fetch Buddy and Block Lists
  302. /** -----------------------------------*/
  303. function fetch_lists($which='')
  304. {
  305. global $DB;
  306. if ($which == 'buddy')
  307. {
  308. $this->goodies = array();
  309. $this->buddies = array();
  310. }
  311. elseif($which == 'blocked')
  312. {
  313. $this->baddies = array();
  314. $this->blocked = array();
  315. }
  316. else
  317. {
  318. $this->goodies = array();
  319. $this->buddies = array();
  320. $this->baddies = array();
  321. $this->blocked = array();
  322. }
  323. $extra = ($which != '') ? "AND l.listed_type = '{$which}'" : '';
  324. $query = $DB->query("SELECT l.*, m.username, m.screen_name, m.member_id
  325. FROM exp_message_listed l, exp_members m
  326. WHERE l.listed_member = m.member_id
  327. AND l.member_id = '{$this->member_id}'
  328. $extra");
  329. if ($query->num_rows > 0)
  330. {
  331. foreach($query->result as $row)
  332. {
  333. if (empty($row['username']))
  334. {
  335. continue;
  336. }
  337. if ($row['listed_type'] == 'buddy')
  338. {
  339. $this->buddies[] = array($row['listed_member'], $row['username'], $row['screen_name'], $row['listed_description'], $row['listed_id'], $row['member_id']);
  340. $this->goodies[] = $row['listed_member'];
  341. }
  342. else
  343. {
  344. $this->blocked[] = array($row['listed_member'], $row['username'], $row['screen_name'], $row['listed_description'], $row['listed_id'], $row['member_id']);
  345. $this->baddies[] = $row['listed_member'];
  346. }
  347. }
  348. }
  349. }
  350. /* END */
  351. /** -----------------------------------
  352. /** Determine Folders for this User
  353. /** -----------------------------------*/
  354. function fetch_folders()
  355. {
  356. global $DB, $REGX;
  357. $this->folders = array();
  358. $query = $DB->query("SELECT * FROM exp_message_folders WHERE member_id = '{$this->member_id}'");
  359. if ($query->num_rows == 0)
  360. {
  361. $DB->query($DB->insert_string('exp_message_folders', array('member_id' => $this->member_id)));
  362. $this->folders['1'] = array($this->default_folders['0'], '0');
  363. $this->folders['2'] = array($this->default_folders['1'], '0');
  364. }
  365. else
  366. {
  367. $required = array('1' => array($query->row['folder1_name'], '0'), '2' => array($query->row['folder2_name'], '0'));
  368. for($i=3; $i <= $this->max_folders; $i++)
  369. {
  370. $this->folders[$i] = htmlspecialchars($query->row['folder'.$i.'_name'], ENT_QUOTES);
  371. }
  372. asort($this->folders);
  373. foreach($this->folders as $key => $value)
  374. {
  375. $this->folders[$key] = array($value, '0');
  376. }
  377. $this->folders = $required + $this->folders;
  378. $results = $DB->query("SELECT COUNT(*) AS count, message_folder FROM exp_message_copies
  379. WHERE recipient_id = '{$this->member_id}'
  380. AND message_deleted = 'n'
  381. GROUP BY message_folder");
  382. if ($results->num_rows > 0)
  383. {
  384. foreach($results->result as $row)
  385. {
  386. $this->folders[$row['message_folder']]['1'] = $row['count'];
  387. }
  388. }
  389. }
  390. }
  391. /* END */
  392. /** -----------------------------------
  393. /** Edit Folders
  394. /** -----------------------------------*/
  395. function folders()
  396. {
  397. global $LANG, $FNS;
  398. $template = $this->retrieve_template('message_edit_folders');
  399. $rows = $this->retrieve_template('message_edit_folders_row');
  400. $form_details = array('action' => $this->base_url.'edit_folders',
  401. 'id' => 'edit_folders',
  402. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  403. );
  404. $this->single_parts['form']['form_declaration']['edit_folders'] = $FNS->form_declaration($form_details);
  405. $this->single_parts['include']['current_folders'] = '';
  406. $this->single_parts['include']['new_folder'] = '';
  407. if ( ! isset($this->single_parts['include']['success_message']))
  408. {
  409. $this->single_parts['include']['success_message'] = '';
  410. }
  411. /** -----------------------------------------
  412. /** Create Folder Rows
  413. /** -----------------------------------------*/
  414. $t=1;
  415. foreach($this->folders as $key => $value)
  416. {
  417. if ($value['0'] == '')
  418. {
  419. continue;
  420. }
  421. $t++;
  422. $this->single_parts['lang']['required'] = ($key < 3) ? $LANG->line('folder_required') : '';
  423. $this->single_parts['input']['folder_name'] = $value['0'];
  424. $this->single_parts['input']['folder_id'] = $key;
  425. $this->single_parts['style'] = ($t % 2) ? 'tableCellOne' : 'tableCellTwo';
  426. $this->single_parts['include']['current_folders'] .= $this->_process_template($rows);
  427. }
  428. /** -----------------------------------------
  429. /** Create New Folder Row, If Allowed
  430. /** -----------------------------------------*/
  431. if ($t <= $this->max_folders)
  432. {
  433. $t++;
  434. $this->single_parts['lang']['required'] = '';
  435. $this->single_parts['input']['folder_name'] = '';
  436. $this->single_parts['input']['folder_id'] = 'new';
  437. $this->single_parts['style'] = ($t % 2) ? 'tableCellOne' : 'tableCellTwo';
  438. $this->single_parts['include']['new_folder'] = $this->_process_template($rows);
  439. }
  440. /** ----------------------------------------
  441. /** Return the Folder's Contents
  442. /** ----------------------------------------*/
  443. $this->title = $LANG->line('edit_folders');
  444. $this->crumb = $LANG->line('edit_folders');
  445. $this->return_data = $this->_process_template($template);
  446. }
  447. /* END */
  448. /** -----------------------------------
  449. /** Edit Folders
  450. /** -----------------------------------*/
  451. function edit_folders()
  452. {
  453. global $REGX, $DB, $LANG;
  454. /** -----------------------------------
  455. /** Check Required
  456. /** -----------------------------------*/
  457. if ( ! isset($_POST['folder_1']) OR ! isset($_POST['folder_2']) OR $_POST['folder_1'] == '' OR $_POST['folder_2'] == '')
  458. {
  459. return $this->_error_page('missing_required_field');
  460. }
  461. /** -----------------------------------
  462. /** Get Our Modified Data
  463. /** -----------------------------------*/
  464. for($i=1, $data = array(); $i <= $this->max_folders; $i++)
  465. {
  466. if ( ! isset($_POST['folder_'.$i]) OR $_POST['folder_'.$i] == '')
  467. {
  468. $data['folder'.$i.'_name'] = '';
  469. $DB->query("UPDATE exp_message_copies SET message_deleted = 'y'
  470. WHERE recipient_id = '{$this->member_id}' AND message_folder = '{$i}'");
  471. if ( ! isset($empty)) $empty = 'folder'.$i.'_name';
  472. }
  473. else
  474. {
  475. $data['folder'.$i.'_name'] = $REGX->xss_clean($_POST['folder_'.$i]);
  476. }
  477. }
  478. /** -----------------------------------
  479. /** Get Our New Folder
  480. /** -----------------------------------*/
  481. if (isset($_POST['folder_new']) && $_POST['folder_new'] != '' && isset($empty))
  482. {
  483. $data[$empty] = $REGX->xss_clean($_POST['folder_new']);
  484. }
  485. $DB->query($DB->update_string('exp_message_folders', $data, "member_id = '{$this->member_id}'"));
  486. $this->fetch_folders();
  487. /** -----------------------------------
  488. /** Success Message
  489. /** -----------------------------------*/
  490. $this->single_parts['lang']['message'] = $LANG->line('folders_updated');
  491. $this->single_parts['include']['success_message'] = $this->_process_template($this->retrieve_template('message_success'));
  492. /** ----------------------------------------
  493. /** Return us back to Oz
  494. /** ----------------------------------------*/
  495. return $this->folders();
  496. }
  497. /* END */
  498. /** -----------------------------------
  499. /** Abstracted Default Menu
  500. /** -----------------------------------*/
  501. function abstract_menu()
  502. {
  503. global $LANG, $DB, $SESS, $LOC;
  504. /** ------------------------------
  505. /** Bulletin Board
  506. /** ------------------------------*/
  507. $style = ($SESS->userdata['last_view_bulletins'] <= $SESS->userdata['last_bulletin_date']) ? 'defaultBold' : '';
  508. $this->menu_items['single_items']['bulletin_board'] = array('text' => $LANG->line('bulletin_board'),
  509. 'link' => $this->_create_path('bulletin_board'),
  510. 'image' => '',
  511. 'style' => $style);
  512. /** ------------------------
  513. /** Compose New Message
  514. /** ------------------------*/
  515. $this->menu_items['single_items']['compose_message'] = array('text' => $LANG->line('compose_message'),
  516. 'link' => $this->_create_path('compose'),
  517. 'image' => '',
  518. 'style' => 'defaultBold');
  519. /** ------------------------
  520. /** Drafts Folder
  521. /** ------------------------*/
  522. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_message_data
  523. WHERE sender_id = '{$this->member_id}'
  524. AND message_status = 'draft'");
  525. if ($query->row['count'] > 0)
  526. {
  527. $this->menu_items['repeat_items']['folders'][] = array('text' => $LANG->line('draft_messages') .' ('.$query->row['count'].')',
  528. 'link' => $this->_create_path('drafts'),
  529. 'image' => '',
  530. 'style' => '');
  531. }
  532. /** -------------------------------
  533. /** User Folders
  534. /** -------------------------------*/
  535. if (sizeof($this->folders) == 0)
  536. {
  537. $this->fetch_folders();
  538. }
  539. foreach($this->folders as $key => $value)
  540. {
  541. if ($value['0'] != '')
  542. {
  543. if ($this->allegiance == 'user')
  544. {
  545. $url = $this->base_url.'view_folder/'.$key.'/';
  546. }
  547. else
  548. {
  549. $url = $this->base_url.'view_folder'.AMP.'folder='.$key;
  550. }
  551. $this->menu_items['repeat_items']['folders'][] = array('text' => ' - '.$value['0'].' ('.$value['1'].')',
  552. 'link' => $url,
  553. 'image' => '',
  554. 'style' => '');
  555. }
  556. }
  557. /** ------------------------
  558. /** Deleted Folder
  559. /** ------------------------*/
  560. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_message_copies
  561. WHERE recipient_id = '{$this->member_id}'
  562. AND message_deleted = 'y'");
  563. $this->menu_items['repeat_items']['folders'][] = array('text' => $LANG->line('deleted_messages').' ('.$query->row['count'].')',
  564. 'link' => $this->_create_path('deleted'),
  565. 'image' => '',
  566. 'style' => '');
  567. /* ------------------------
  568. // Message Tracking
  569. // ------------------------
  570. $this->menu_items['single_items']['track_messages'] = array('text' => $LANG->line('track_messages'),
  571. 'link' => $this->_create_path('track'),
  572. 'image' => '',
  573. 'style' => '');
  574. */
  575. /** ------------------------
  576. /** Edit Message Folders
  577. /** ------------------------*/
  578. $this->menu_items['single_items']['edit_folders'] = array('text' => $LANG->line('edit_folders'),
  579. 'link' => $this->_create_path('folders'),
  580. 'image' => '',
  581. 'style' => '');
  582. /** ------------------------
  583. /** Buddy List
  584. /** ------------------------*/
  585. $this->menu_items['single_items']['buddy_list'] = array('text' => $LANG->line('buddy_list'),
  586. 'link' => $this->_create_path('buddies'),
  587. 'image' => '',
  588. 'style' => '');
  589. /** ------------------------
  590. /** Block List
  591. /** ------------------------*/
  592. $this->menu_items['single_items']['block_list'] = array('text' => $LANG->line('blocked_list'),
  593. 'link' => $this->_create_path('blocked'),
  594. 'image' => '',
  595. 'style' => '');
  596. }
  597. /* END */
  598. /** -----------------------------------
  599. /** Create Messages Menu
  600. /** -----------------------------------*/
  601. function create_menu()
  602. {
  603. global $DB, $DSP, $IN, $LANG;
  604. if ($this->allow_pm == 'n')
  605. {
  606. return;
  607. }
  608. $this->_determine_request();
  609. $this->abstract_menu();
  610. /** --------------------------------
  611. /** Open/Close JavaScript
  612. /** --------------------------------*/
  613. if ($IN->GBL('myaccount_messages', 'COOKIE') && $IN->GBL('myaccount_messages', 'COOKIE') == 'on')
  614. {
  615. $text = '[-]';
  616. $hidden_style = '';
  617. }
  618. else
  619. {
  620. $text = '[+]';
  621. $hidden_style = 'display: none; padding:0;';
  622. }
  623. $hidden_link = '<a href="javascript:void(0);" id="extLink1" class="altLinks" onclick="showHide(1,this);return false;">'.$text.'</a>';
  624. /** --------------------------------
  625. /** Create Menu
  626. /** --------------------------------*/
  627. $map = array('bulletin_board', 'compose_message', 'folders', 'edit_folders', 'buddy_list', 'block_list');
  628. if ($this->allegiance == 'cp')
  629. {
  630. /** --------------------------------
  631. /** Menu Section + JavaScript
  632. /** --------------------------------*/
  633. $expand = '<img src="'.PATH_CP_IMG.'expand.gif" border="0" width="10" height="10" alt="Expand" />&nbsp;&nbsp;';
  634. $collapse = '<img src="'.PATH_CP_IMG.'collapse.gif" border="0" width="10" height="10" alt="Collapse" />&nbsp;&nbsp;';
  635. $pm_state = ($IN->GBL('M') == 'messages') ? TRUE : FALSE;
  636. $this->menu .= '<div id="menu_pm_h" style="display: '.(($pm_state == TRUE) ? 'none' : 'block').'; padding:0; margin: 0;">';
  637. $js = ' onclick="showhide_menu(\'menu_pm\');return false;" onmouseover="navTabOn(\'pmx\', \'tableHeadingAlt\', \'tableHeadingAltHover\');" onmouseout="navTabOff(\'pmx\', \'tableHeadingAlt\', \'tableHeadingAltHover\');" ';
  638. $this->menu .= $DSP->div();
  639. $this->menu .= "<div class='tableHeadingAlt' id='pmx' ".$js.">";
  640. $this->menu .= $expand.$LANG->line('private_messages');
  641. $this->menu .= $DSP->div_c();
  642. $this->menu .= $DSP->div_c();
  643. $this->menu .= $DSP->div_c();
  644. $this->menu .= '<div id="menu_pm_b" style="display: '.(($pm_state == TRUE) ? 'block' : 'none').'; padding:0; margin: 0;">';
  645. $js = ' onclick="showhide_menu(\'menu_pm\');return false;" onmouseover="navTabOn(\'pmx2\', \'tableHeadingAlt\', \'tableHeadingAltHover\');" onmouseout="navTabOff(\'pmx2\', \'tableHeadingAlt\', \'tableHeadingAltHover\');" ';
  646. $this->menu .= $DSP->div();
  647. $this->menu .= "<div class='tableHeadingAlt' id='pmx2' ".$js.">";
  648. $this->menu .= $collapse.$LANG->line('private_messages');
  649. $this->menu .= $DSP->div_c();
  650. $this->menu .= $DSP->div('profileMenuInner');
  651. /** --------------------------------
  652. /** Create Menu Based on Item Map
  653. /** --------------------------------*/
  654. foreach($map as $item)
  655. {
  656. if (isset($this->menu_items['repeat_items'][$item]))
  657. {
  658. foreach($this->menu_items['repeat_items'][$item] as $item_member)
  659. {
  660. $this->create_item($item_member);
  661. }
  662. }
  663. else
  664. {
  665. $this->create_item($this->menu_items['single_items'][$item]);
  666. }
  667. }
  668. $this->menu .= $DSP->div_c().$DSP->div_c().$DSP->div_c();
  669. }
  670. else
  671. {
  672. $template = $this->retrieve_template('message_menu');
  673. $rows = $this->retrieve_template('message_menu_rows');
  674. $this->single_parts['include']['hide_menu_style'] = $hidden_style;
  675. $this->single_parts['include']['hide_menu_link'] = $hidden_link;
  676. $this->single_parts['include']['hide_menu_js'] = $this->showhide_js();
  677. $this->single_parts['include']['menu_items'] = '';
  678. foreach($map as $item)
  679. {
  680. if (isset($this->menu_items['repeat_items'][$item]))
  681. {
  682. foreach($this->menu_items['repeat_items'][$item] as $item_member)
  683. {
  684. $this->single_parts['title'] = $item_member['text'];
  685. $this->single_parts['link'] = $item_member['link'];
  686. $this->single_parts['include']['menu_items'] .= $this->_process_template($rows);
  687. }
  688. }
  689. else
  690. {
  691. $this->single_parts['title'] = $this->menu_items['single_items'][$item]['text'];
  692. $this->single_parts['link'] = $this->menu_items['single_items'][$item]['link'];
  693. $this->single_parts['include']['menu_items'] .= $this->_process_template($rows);
  694. }
  695. }
  696. $this->menu = $this->_process_template($template);
  697. }
  698. }
  699. /* END */
  700. /** -----------------------------------
  701. /** Create Menu Item
  702. /** -----------------------------------*/
  703. function create_item($data)
  704. {
  705. global $DB, $DSP;
  706. $this->menu .= $DSP->div(($data['style'] != '') ? $data['style'] : 'navPad').
  707. $DSP->anchor($data['link'], $data['text']).
  708. $DSP->div_c();
  709. }
  710. /* END */
  711. // -----------------------------------
  712. // Inbox
  713. // This function is kind of superfluous, but I find it comforting
  714. // to know that there is an inbox function for a messaging system.
  715. // Besides, it makes it a tad easier to understand certain parts
  716. // of the code to have this function called opposed to what is
  717. // really being calling. That is all, move along now...
  718. // -----------------------------------
  719. function inbox()
  720. {
  721. $this->view_folder('1');
  722. }
  723. /* END */
  724. /** -----------------------------------
  725. /** Deleted Messages
  726. /** -----------------------------------*/
  727. function deleted()
  728. {
  729. $this->view_folder('0');
  730. }
  731. /* END */
  732. /** -----------------------------------
  733. /** View Folder Contents
  734. /** -----------------------------------*/
  735. function drafts()
  736. {
  737. global $LANG, $DB, $OUT, $IN, $LOC, $PREFS;
  738. $row_count = 0; // How many rows shown this far (i.e. offset)
  739. if ($this->allegiance == 'user')
  740. {
  741. $row_count = $this->cur_id;
  742. }
  743. else
  744. {
  745. $row_count = ($IN->GBL('page', 'GP') === false) ? 0 : $IN->GBL('page', 'GP');
  746. }
  747. if ( ! is_numeric($row_count))
  748. {
  749. $row_count = 0;
  750. }
  751. $this->single_parts['lang']['folder_id'] = '1';
  752. $this->single_parts['lang']['folder_name'] = $LANG->line('draft_messages');
  753. $this->conditionals['paginate'] = 'n';
  754. $this->conditionals['drafts_folder'] = 'y';
  755. $this->conditionals['sent_folder'] = 'n';
  756. $this->conditionals['trash_folder'] = 'n';
  757. $this->conditionals['regular_folder'] = 'n';
  758. /** ---------------------------------------
  759. /** Retrieve Folder Contents Query
  760. /** ---------------------------------------*/
  761. $dql = "SELECT
  762. exp_message_data.sender_id,
  763. exp_message_data.message_date,
  764. exp_message_data.message_id,
  765. exp_message_data.message_subject,
  766. exp_message_data.message_recipients,
  767. exp_message_data.message_cc,
  768. exp_message_data.message_attachments,
  769. exp_members.screen_name as sender,
  770. exp_members.username as sender_username ";
  771. $sql = "FROM exp_message_data
  772. LEFT JOIN exp_members ON exp_members.member_id = exp_message_data.sender_id
  773. WHERE exp_message_data.message_status = 'draft'
  774. AND exp_message_data.sender_id = '{$this->member_id}'
  775. ORDER BY exp_message_data.message_date ";
  776. /** ----------------------------------------
  777. /** Run "count" query for pagination
  778. /** ----------------------------------------*/
  779. $query = $DB->query("SELECT COUNT(exp_message_data.message_id) AS count ".$sql);
  780. /** ----------------------------------------
  781. /** If No Messages, we say so.
  782. /** ----------------------------------------*/
  783. if ($query->row['count'] == 0)
  784. {
  785. $this->title = $LANG->line('draft_messages');
  786. $this->crumb = $LANG->line('draft_messages');
  787. $this->single_parts['include']['folder_rows'] = $this->retrieve_template('message_no_folder_rows');
  788. $this->single_parts['form']['form_declaration']['modify_messages'] = '';
  789. $this->return_data = $this->folder_wrapper(($folder_id == '0') ? 'n' : 'y');
  790. return;
  791. }
  792. /** ----------------------------------------
  793. /** Determine Current Page
  794. /** ----------------------------------------*/
  795. $current_page = ($row_count / $this->per_page) + 1;
  796. $total_pages = intval($query->row['count'] / $this->per_page);
  797. if ($query->row['count'] % $this->per_page)
  798. {
  799. $total_pages++;
  800. }
  801. $this->single_parts['include']['page_count'] = $LANG->line('folder_page').' '.$current_page.' '.$LANG->line('of').' '.$total_pages;
  802. /** -----------------------------
  803. /** Do we need pagination?
  804. /** -----------------------------*/
  805. $pager = '';
  806. if ($query->row['count'] > $this->per_page)
  807. {
  808. if ( ! class_exists('Paginate'))
  809. {
  810. require PATH_CORE.'core.paginate'.EXT;
  811. }
  812. $PGR = new Paginate();
  813. if ($this->allegiance == 'user')
  814. {
  815. $PGR->path = $this->_create_path('drafts');
  816. }
  817. else
  818. {
  819. $PGR->base_url = $this->_create_path('drafts');
  820. $PGR->qstr_var = 'page';
  821. }
  822. $PGR->total_count = $query->row['count'];
  823. $PGR->per_page = $this->per_page;
  824. $PGR->cur_page = $row_count;
  825. $this->single_parts['include']['pagination_link'] = $PGR->show_links();
  826. $this->conditionals['paginate'] = 'y';
  827. $sql .= " LIMIT ".$row_count.", ".$this->per_page;
  828. }
  829. /** ----------------------------------------
  830. /** Retrieve Folder Contents
  831. /** ----------------------------------------*/
  832. $folder_rows_template = $this->retrieve_template('message_folder_rows');
  833. $r = '';
  834. $i = 0;
  835. $censor = FALSE;
  836. if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '')
  837. {
  838. if ( ! class_exists('Typography'))
  839. {
  840. require PATH_CORE.'core.typography'.EXT;
  841. }
  842. $TYPE = new Typography(0);
  843. $censor = TRUE;
  844. }
  845. $query = $DB->query($dql.$sql);
  846. foreach($query->result as $row)
  847. {
  848. ++$i;
  849. $data = $row;
  850. $data['msg_id'] = 'd'.$row['message_id'];
  851. $data['message_date'] = $LOC->set_human_time($data['message_date']);
  852. $data['style'] = ($i % 2) ? 'tableCellTwo' : 'tableCellOne';
  853. $data['message_subject'] = ($censor === FALSE) ? $data['message_subject'] : $TYPE->filter_censored_words($data['message_subject']);
  854. if ($this->allegiance == 'user')
  855. {
  856. $data['message_url'] = $this->base_url.'compose/'.$row['message_id'].'/';
  857. }
  858. else
  859. {
  860. $data['message_url'] = $this->base_url.'compose'.AMP.'msg='.$row['message_id'];
  861. }
  862. $data['message_status'] = '';
  863. // This Requires Extra Queries and Processing
  864. // So We Only Do It When Those Variables Are Found
  865. if (stristr($folder_rows_template, '{recipients}') !== FALSE)
  866. {
  867. $data['recipients'] = htmlspecialchars($this->convert_recipients($row['message_recipients']), ENT_QUOTES);
  868. }
  869. if (stristr($folder_rows_template, '{cc}') !== FALSE)
  870. {
  871. $data['cc'] = htmlspecialchars($this->convert_recipients($row['message_cc']), ENT_QUOTES);
  872. }
  873. $r .= $this->_process_template($folder_rows_template, $data);
  874. }
  875. $this->single_parts['include']['folder_rows'] = $r;
  876. /** ----------------------------------------
  877. /** Return the Folder's Contents
  878. /** ----------------------------------------*/
  879. $this->title = $LANG->line('draft_messages');
  880. $this->crumb = $LANG->line('draft_messages');
  881. $this->return_data = $this->folder_wrapper('y', 'n', 'n');
  882. }
  883. /* END */
  884. /** -----------------------------------
  885. /** View Folder Contents
  886. /** -----------------------------------*/
  887. function view_folder($folder_id='')
  888. {
  889. global $LANG, $DB, $OUT, $IN, $LOC, $PREFS;
  890. // ---------------------------------
  891. // Find Requested Folder ID
  892. // $IN->QSTR - User
  893. // $IN->GBL('folder', 'GP') - CP
  894. // ---------------------------------
  895. $row_count = 0; // How many rows shown this far (i.e. offset)
  896. if ($folder_id == '')
  897. {
  898. if ($this->allegiance == 'user')
  899. {
  900. // Unknown, probably will have to do something similar to
  901. // the list of members where we have to create
  902. // a pseudo-query string in one of the URI segments
  903. // folder_pagenum : 1_1
  904. if ($this->cur_id == '')
  905. {
  906. $folder_id = 1;
  907. }
  908. else
  909. {
  910. $x = explode('_', $this->cur_id);
  911. $folder_id = ( ! is_numeric($x['0'])) ? 1 : $x['0'];
  912. $row_count = ( ! isset($x['1']) OR ! is_numeric($x['1'])) ? 0 : $x['1'];
  913. }
  914. }
  915. else
  916. {
  917. $folder_id = ($IN->GBL('folder', 'GP') === false) ? '1' : $IN->GBL('folder', 'GP');
  918. $row_count = ($IN->GBL('page', 'GP') === false) ? 0 : $IN->GBL('page', 'GP');
  919. }
  920. }
  921. if ( ! is_numeric($folder_id) OR $folder_id > $this->max_folders)
  922. {
  923. $folder_id = '1';
  924. }
  925. if ( ! is_numeric($row_count))
  926. {
  927. $row_count = 0;
  928. }
  929. /** ---------------------------------------
  930. /** Retrieve Folder Name for User
  931. /** ---------------------------------------*/
  932. if ($folder_id == '0')
  933. {
  934. $folder_name = $LANG->line('deleted_messages');
  935. }
  936. elseif ( ! isset($this->folders[$folder_id]['0']) OR $this->folders[$folder_id]['0'] == '')
  937. {
  938. if ($this->allegiance == 'cp')
  939. {
  940. return $DSP->no_access_message();
  941. }
  942. else
  943. {
  944. return $OUT->show_user_error('general', array($LANG->line('not_authorized')));
  945. }
  946. }
  947. else
  948. {
  949. $folder_name = $this->folders[$folder_id]['0'];
  950. }
  951. $this->single_parts['lang']['folder_name'] = $LANG->line('messages_folder').' - '.$folder_name;
  952. $this->single_parts['lang']['folder_id'] = $folder_id;
  953. $this->current_folder = $folder_id;
  954. $this->conditionals['paginate'] = 'n';
  955. /** -----------------------------------
  956. /** Folder Conditionals
  957. /** -----------------------------------*/
  958. $this->conditionals['drafts_folder'] = 'n';
  959. $this->conditionals['sent_folder'] = 'n';
  960. $this->conditionals['trash_folder'] = 'n';
  961. $this->conditionals['regular_folder'] = 'n';
  962. if ($folder_id == '0')
  963. {
  964. $this->conditionals['trash_folder'] = 'y';
  965. }
  966. elseif ($folder_id == '2')
  967. {
  968. $this->conditionals['sent_folder'] = 'y';
  969. }
  970. else
  971. {
  972. $this->conditionals['regular_folder'] = 'y';
  973. }
  974. /** ---------------------------------------
  975. /** Retrieve Folder Contents Query
  976. /** ---------------------------------------*/
  977. $dql = "SELECT
  978. exp_message_copies.message_status,
  979. exp_message_copies.message_id,
  980. exp_message_copies.message_read,
  981. exp_message_copies.copy_id as msg_id,
  982. exp_message_data.sender_id,
  983. exp_message_data.message_date,
  984. exp_message_data.message_subject,
  985. exp_message_data.message_recipients,
  986. exp_message_data.message_cc,
  987. exp_message_data.message_attachments,
  988. exp_members.screen_name as sender,
  989. exp_members.username as sender_username ";
  990. $sql = "FROM exp_message_copies
  991. LEFT JOIN exp_message_data ON exp_message_data.message_id = exp_message_copies.message_id
  992. LEFT JOIN exp_members ON exp_members.member_id = exp_message_copies.sender_id
  993. WHERE exp_message_copies.recipient_id = '{$this->member_id}' ";
  994. if ($folder_id == '0')
  995. {
  996. $sql .= "AND exp_message_copies.message_deleted = 'y' ";
  997. }
  998. else
  999. {
  1000. $sql .= "AND exp_message_copies.message_folder = '{$folder_id}'
  1001. AND exp_message_copies.message_deleted = 'n' ";
  1002. }
  1003. $sql .= "AND exp_message_data.message_status = 'sent'
  1004. ORDER BY exp_message_data.message_date desc";
  1005. /** ----------------------------------------
  1006. /** Run "count" query for pagination
  1007. /** ----------------------------------------*/
  1008. $query = $DB->query("SELECT COUNT(exp_message_copies.copy_id) AS count ".$sql);
  1009. /** ----------------------------------------
  1010. /** If No Messages, we say so.
  1011. /** ----------------------------------------*/
  1012. if ($query->row['count'] == 0)
  1013. {
  1014. $this->title = $folder_name;
  1015. $this->crumb = $folder_name;
  1016. $this->single_parts['include']['folder_rows'] = $this->retrieve_template('message_no_folder_rows');
  1017. $this->single_parts['form']['form_declaration']['modify_messages'] = '';
  1018. $this->return_data = $this->folder_wrapper(($folder_id == '0') ? 'n' : 'y');
  1019. return;
  1020. }
  1021. /** ----------------------------------------
  1022. /** Determine Current Page
  1023. /** ----------------------------------------*/
  1024. $current_page = ($row_count / $this->per_page) + 1;
  1025. $total_pages = intval($query->row['count'] / $this->per_page);
  1026. if ($query->row['count'] % $this->per_page)
  1027. {
  1028. $total_pages++;
  1029. }
  1030. $this->single_parts['include']['page_count'] = $LANG->line('folder_page').' '.$current_page.' '.$LANG->line('of').' '.$total_pages;
  1031. /** -----------------------------
  1032. /** Do we need pagination?
  1033. /** -----------------------------*/
  1034. $pager = '';
  1035. if ($query->row['count'] > $this->per_page)
  1036. {
  1037. if ( ! class_exists('Paginate'))
  1038. {
  1039. require PATH_CORE.'core.paginate'.EXT;
  1040. }
  1041. $PGR = new Paginate();
  1042. if ($this->allegiance == 'user')
  1043. {
  1044. $PGR->path = $this->base_url.'view_folder/'.$folder_id.'_';
  1045. }
  1046. else
  1047. {
  1048. $PGR->base_url = $this->base_url.'view_folder'.AMP.'folder='.$folder_id;
  1049. $PGR->qstr_var = 'page';
  1050. }
  1051. $PGR->total_count = $query->row['count'];
  1052. $PGR->per_page = $this->per_page;
  1053. $PGR->cur_page = $row_count;
  1054. $this->single_parts['include']['pagination_link'] = $PGR->show_links();
  1055. $this->conditionals['paginate'] = 'y';
  1056. $sql .= " LIMIT ".$row_count.", ".$this->per_page;
  1057. }
  1058. $censor = FALSE;
  1059. if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '')
  1060. {
  1061. $censor = TRUE;
  1062. if ( ! class_exists('Typography'))
  1063. {
  1064. require PATH_CORE.'core.typography'.EXT;
  1065. }
  1066. $TYPE = new Typography(0);
  1067. }
  1068. /** ----------------------------------------
  1069. /** Retrieve Folder Contents
  1070. /** ----------------------------------------*/
  1071. $message_ids = array();
  1072. $folder_rows_template = $this->retrieve_template('message_folder_rows');
  1073. $i = 0;
  1074. $r = '';
  1075. $query = $DB->query($dql.$sql);
  1076. foreach($query->result as $row)
  1077. {
  1078. $i++;
  1079. $data = $row;
  1080. $message_ids[] = $row['message_id'];
  1081. $data['msg_id'] = ($row['message_read'] == 'n') ? 'u'.$row['msg_id'] : $row['msg_id'];
  1082. $data['buddy_list_link'] = '';
  1083. $data['block_list_link'] = '';
  1084. $data['message_date'] = $LOC->set_human_time($data['message_date']);
  1085. $data['style'] = ($i % 2) ? 'tableCellTwo' : 'tableCellOne';
  1086. if ($censor == TRUE)
  1087. {
  1088. $data['message_subject'] = $TYPE->filter_censored_words($row['message_subject']);
  1089. }
  1090. if ($this->allegiance == 'user')
  1091. {
  1092. $data['message_url'] = $this->base_url.'view_message/'.$row['msg_id'].'/';
  1093. //$data['buddy_list_link'] = $this->_create_path('add_buddy').$row['sender_id'].'/';
  1094. //$data['block_list_link'] = $this->_create_path('add_block').$row['sender_id'].'/';
  1095. }
  1096. else
  1097. {
  1098. $data['message_url'] = $this->base_url.'view_message'.AMP.'msg='.$row['msg_id'];
  1099. //$data['buddy_list_link'] = $this->_create_path('add_buddy').AMP.'id='.$row['sender_id'];
  1100. //$data['block_list_link'] = $this->_create_path('add_block').AMP.'id='.$row['sender_id'];
  1101. }
  1102. // --------------------------------
  1103. // Message Status Entities:
  1104. // &bull; - unread
  1105. // &rarr; - forwarded
  1106. // &crarr; - Reply
  1107. // --------------------------------
  1108. if ($row['message_status'] == 'replied')
  1109. {
  1110. $data['message_status'] = '&crarr;';
  1111. }
  1112. elseif ($row['message_status'] == 'forwarded')
  1113. {
  1114. $data['message_status'] = '&rarr;';
  1115. }
  1116. elseif ($row['message_read'] == 'y')
  1117. {
  1118. $data['message_status'] = '';
  1119. }
  1120. elseif($row['message_read'] == 'n')
  1121. {
  1122. $data['message_status'] = '&bull;';
  1123. }
  1124. // This Requires Extra Queries and Processing
  1125. // So We Only Do It When Those Variables Are Found
  1126. if (stristr($folder_rows_template, '{recipients}') !== FALSE)
  1127. {
  1128. $data['recipients'] = htmlspecialchars($this->convert_recipients($row['message_recipients']), ENT_QUOTES);
  1129. }
  1130. if (stristr($folder_rows_template, '{cc}') !== FALSE)
  1131. {
  1132. $data['cc'] = htmlspecialchars($this->convert_recipients($row['message_cc']), ENT_QUOTES);
  1133. }
  1134. $r .= $this->_process_template($folder_rows_template, $data);
  1135. }
  1136. $this->single_parts['include']['folder_rows'] = $r;
  1137. /** ----------------------------------------
  1138. /** If Displayed, Messages are Received (not read)
  1139. /** ----------------------------------------*/
  1140. if (sizeof($message_ids) > 0 && $this->block_tracking == 'n')
  1141. {
  1142. $DB->query("UPDATE exp_message_copies SET message_received = 'y'
  1143. WHERE recipient_id = '{$this->member_id}'
  1144. AND message_id IN ('".implode("','",$message_ids)."')");
  1145. }
  1146. /** ----------------------------------------
  1147. /** Return the Folder's Contents
  1148. /** ----------------------------------------*/
  1149. $this->title = $folder_name;
  1150. $this->crumb = $folder_name;
  1151. $this->return_data = $this->folder_wrapper(($folder_id == '0') ? 'n' : 'y');
  1152. }
  1153. /* END */
  1154. /** ----------------------------------------
  1155. /** Wrapper for a Folder and its Contents
  1156. /** ----------------------------------------*/
  1157. function folder_wrapper($deleted='y', $moved='y', $copied = 'y')
  1158. {
  1159. global $FNS;
  1160. $folder_template = $this->retrieve_template('message_folder');
  1161. $this->folders_pulldown();
  1162. $this->single_parts['include']['hidden_js'] = $this->hidden_js();
  1163. $this->single_parts['include']['toggle_js'] = $this->toggle_js();
  1164. $this->single_parts['path']['compose_message'] = $this->_create_path('compose');
  1165. $this->single_parts['path']['erase_messages'] = $this->_create_path('erase');
  1166. $details = array('hidden_fields' => array('this_folder' => $this->single_parts['lang']['folder_id'], 'daction' => ''),
  1167. 'action' => $this->_create_path('modify_messages'),
  1168. 'id' => 'target',
  1169. 'enctype' => 'multi',
  1170. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  1171. );
  1172. $this->single_parts['form']['form_declaration']['modify_messages'] = $FNS->form_declaration($details);
  1173. /** ---------------------------------
  1174. /** Move, Copy, Delete Buttons
  1175. /** ---------------------------------*/
  1176. $this->_buttons($deleted, $moved, $copied);
  1177. /** -------------------------------
  1178. /** Storage Graph
  1179. /** -------------------------------*/
  1180. if ( ! isset($this->single_parts['image']['messages_graph']))
  1181. {
  1182. $this->storage_graph();
  1183. }
  1184. return $this->_process_template($folder_template);
  1185. }
  1186. /* END */
  1187. /** ----------------------------------------
  1188. /** Buttons for Various Pages
  1189. /** ----------------------------------------*/
  1190. function _buttons($deleted='y', $moved='y', $copied = 'y')
  1191. {
  1192. global $LANG;
  1193. $style = 'buttons';
  1194. /** ---------------------------------
  1195. /** Move, Copy, Delete Buttons
  1196. /** ---------------------------------*/
  1197. if ($deleted == 'n')
  1198. {
  1199. $this->single_parts['form']['delete_button'] = '';
  1200. }
  1201. else
  1202. {
  1203. $this->single_parts['form']['delete_button'] = "<button type='submit' id='delete' name='delete' value='delete' ".
  1204. "class='{$style}' title='{lang:delete_selected}' ".
  1205. "onclick='dynamic_action(\"delete\");'>".
  1206. "{lang:messages_delete}</button> ";
  1207. }
  1208. if ($moved == 'n')
  1209. {
  1210. $this->single_parts['form']['move_button'] = '';
  1211. }
  1212. else
  1213. {
  1214. $this->single_parts['form']['move_button'] = "<button type='submit' id='move' name='move' value='move' ".
  1215. "class='{$style}' title='{lang:move_selected}' ".
  1216. "onclick='dynamic_move();return false;'>".
  1217. "{lang:messages_move}</button>".NBS.NBS;
  1218. }
  1219. if ($copied == 'n')
  1220. {
  1221. $this->single_parts['form']['copy_button'] = '';
  1222. }
  1223. else
  1224. {
  1225. $this->single_parts['form']['copy_button'] = "<button type='submit' id='copy' name='copy' value='copy' ".
  1226. "class='{$style}' title='{lang:copy_selected}' ".
  1227. "onclick='dynamic_copy();return false;'>".
  1228. "{lang:messages_copy}</button>".NBS.NBS;
  1229. }
  1230. $this->single_parts['form']['forward_button'] = "<button type='submit' id='forward' name='forward' value='forward' ".
  1231. "class='{$style}' title='{lang:messages_forward}' ".
  1232. "onclick='dynamic_action(\"forward\");'>".
  1233. "{lang:messages_forward}</button>".NBS.NBS;
  1234. $this->single_parts['form']['reply_button'] = "<button type='submit' id='reply' name='reply' value='reply' ".
  1235. "class='{$style}' title='{lang:messages_reply}' ".
  1236. "onclick='dynamic_action(\"reply\");'>".
  1237. "{lang:messages_reply}</button>".NBS.NBS;
  1238. $this->single_parts['form']['reply_all_button'] = "<button type='submit' id='reply_all' name='reply_all' value='reply_all' ".
  1239. "class='{$style}' title='{lang:messages_reply_all}' ".
  1240. "onclick='dynamic_action(\"reply_all\");'>".
  1241. "{lang:messages_reply_all}</button>".NBS.NBS;
  1242. $this->single_parts['form']['add_button'] = $this->list_js().
  1243. "<button type='submit' id='add' name='add' value='add' ".
  1244. "class='{$style}' title='{lang:add_member}' ".
  1245. "onclick='list_addition();return false;'>".
  1246. "{lang:add_member}</button>".NBS.NBS;
  1247. }
  1248. /* END */
  1249. /** ----------------------------------------
  1250. /** Retrieve a Template for Processing
  1251. /** ----------------------------------------*/
  1252. function retrieve_template($which='')
  1253. {
  1254. global $PREFS, $FNS;
  1255. if ($which == '')
  1256. {
  1257. $which = 'message_folder';
  1258. }
  1259. /** ----------------------------------
  1260. /** CP Templates - Quick, Easy
  1261. /** ----------------------------------*/
  1262. if ($this->allegiance == 'cp')
  1263. {
  1264. if ( ! class_exists('Messages_CP'))
  1265. {
  1266. require PATH_CP.'cp.messages.php';
  1267. $this->CP = new Messages_CP();
  1268. }
  1269. $which = $which.'_cp';
  1270. return $this->CP->{$which}();
  1271. }
  1272. /** ----------------------------------
  1273. /** User Templates - Slow, Painful
  1274. /** ----------------------------------*/
  1275. if ( ! class_exists($this->theme_class))
  1276. {
  1277. if ($this->theme_path == '')
  1278. {
  1279. $theme = ($PREFS->ini('member_theme') == '') ? 'default' : $FNS->filename_security($PREFS->ini('member_theme'));
  1280. $this->theme_path = PATH_MBR_THEMES.$theme.'/profile_theme'.EXT;
  1281. }
  1282. include_once $this->theme_path;
  1283. }
  1284. if ( ! isset($MS) OR ! is_object($MS))
  1285. {
  1286. $MS = new $this->theme_class();
  1287. }
  1288. if ( ! method_exists($MS, $which))
  1289. {
  1290. global $OUT, $LANG, $PREFS;
  1291. // echo $which;
  1292. $data = array( 'title' => $LANG->line('error'),
  1293. 'heading' => $LANG->line('general_error'),
  1294. 'content' => $LANG->line('nonexistant_page'),
  1295. 'redirect' => '',
  1296. 'link' => array($PREFS->ini('site_url'), stripslashes($PREFS->ini('site_name')))
  1297. );
  1298. return $OUT->show_message($data, 0);
  1299. }
  1300. return trim($MS->$which());
  1301. }
  1302. /* END */
  1303. /** -----------------------------------
  1304. /** Folders Pulldown Menu
  1305. /** -----------------------------------*/
  1306. function folders_pulldown()
  1307. {
  1308. global $LANG;
  1309. $str=NL; $str2=NL;
  1310. foreach($this->folders as $key => $value)
  1311. {
  1312. if ($value['0'] != '')
  1313. {
  1314. if ($this->allegiance == 'user')
  1315. {
  1316. $url = $this->base_url.'view_folder/'.$key.'/';
  1317. }
  1318. else
  1319. {
  1320. $url = $this->base_url.'view_folder'.AMP.'folder='.$key;
  1321. }
  1322. $selected = ($key == $this->current_folder) ? ' selected="selected"' : '';
  1323. $str .= '<option value="'.$url.'"'.$selected.'>'.$value['0'].'</option>'.NL;
  1324. $str2 .= '<option value="'.$key.'"'.$selected.'>'.$value['0'].'</option>'.NL;
  1325. }
  1326. }
  1327. $str .= '</select>'.NL;
  1328. $str2 .= '</select>'.NL;
  1329. $yoffset = ($this->allegiance == 'cp') ? 30 : 20;
  1330. $move_js = <<<DOH
  1331. <script type="text/javascript">
  1332. //<![CDATA[
  1333. var movepopup = new PopupWindow("movemenu");
  1334. movepopup.offsetY={$yoffset};
  1335. movepopup.autoHide();
  1336. //]]>
  1337. </script>
  1338. DOH;
  1339. $copy_js = <<<DOH
  1340. <script type="text/javascript">
  1341. //<![CDATA[
  1342. var copypopup = new PopupWindow("copymenu");
  1343. copypopup.offsetY={$yoffset};
  1344. copypopup.autoHide();
  1345. //]]>
  1346. </script>
  1347. DOH;
  1348. $this->single_parts['include']['folder_pulldown']['change'] = '<select name="change_folder" class="select" onchange="location.href=this.value">'.$str;
  1349. $this->single_parts['include']['folder_pulldown']['move'] = '<div id="movemenu" class="tableCellOne" style="border: 1px solid #666; position:absolute;visibility:hidden;">'.
  1350. '<select name="moveto" class="select" onchange="this.form.submit();">'.
  1351. '<option value="none">'.$LANG->line('choose_folder').'</option>'.NL.
  1352. $str2.
  1353. '</div>'.NL.
  1354. $move_js;
  1355. $this->single_parts['include']['folder_pulldown']['copy'] = '<div id="copymenu" class="tableCellOne" style="border: 1px solid #666; position:absolute;visibility:hidden;">'.
  1356. '<select name="copyto" class="select" onchange="this.form.submit();">'.
  1357. '<option value="none">'.$LANG->line('choose_folder').'</option>'.NL.
  1358. $str2.
  1359. '</div>'.NL.
  1360. $copy_js;
  1361. }
  1362. /* END */
  1363. /** -----------------------------------
  1364. /** Member Search Popup
  1365. /** -----------------------------------*/
  1366. function member_search($message='')
  1367. {
  1368. global $LANG, $DB, $IN, $FNS, $PREFS;
  1369. $this->title = '';
  1370. $this->crumb = '';
  1371. if ($this->allegiance == 'cp')
  1372. {
  1373. $which_field = ( ! $IN->GBL('field')) ? 'recipients' : $IN->GBL('field');
  1374. }
  1375. else
  1376. {
  1377. $which_field = ($this->cur_id != '') ? $this->cur_id : 'recipients';
  1378. }
  1379. $form_details = array('hidden_fields' => array('which_field' => $which_field),
  1380. 'action' => $this->_create_path('do_member_search', AMP.'Z=1'),
  1381. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  1382. );
  1383. $this->single_parts['form']['form_declaration']['do_member_search'] = $FNS->form_declaration($form_details);
  1384. $this->single_parts['include']['message'] = $message;
  1385. $this->conditionals['message'] = ($message != '') ? 'y' : 'n';
  1386. // Member group select list
  1387. $this->single_parts['include']['member_group_options'] = '';
  1388. $query = $DB->query("SELECT group_id, group_title FROM exp_member_groups WHERE site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND include_in_memberlist = 'y' ORDER BY group_title");
  1389. foreach ($query->result as $row)
  1390. {
  1391. $this->single_parts['include']['member_group_options'] .= '<option value="'.$row['group_id'].'">'.$row['group_title'].'</option>';
  1392. }
  1393. $this->return_data = $this->_process_template($this->retrieve_template('search_members'));
  1394. if ($this->allegiance == 'cp')
  1395. {
  1396. global $DSP;
  1397. $DSP->title = $LANG->line('member_search');
  1398. $DSP->body = $this->return_data;
  1399. }
  1400. }
  1401. /* END */
  1402. /** -----------------------------
  1403. /** Perform Member search
  1404. /** -----------------------------*/
  1405. function do_member_search()
  1406. {
  1407. global $IN, $LANG, $FNS, $DB, $PREFS, $SESS;
  1408. $this->title = '';
  1409. $this->crumb = '';
  1410. $which_field = ( ! $IN->GBL('which_field')) ? 'recipients' : $IN->GBL('which_field');
  1411. if ($this->allegiance == 'cp')
  1412. {
  1413. $s = ($PREFS->ini('admin_session_type') != 'c') ? $SESS->userdata['session_id'] : 0;
  1414. $redirect_url = $PREFS->ini('cp_url', FALSE).'?S='.$s.
  1415. AMP.'C=myaccount'.
  1416. AMP.'M=messages'.
  1417. AMP.'P=member_search'.
  1418. AMP.'field='.$which_field.
  1419. AMP.'Z=1';
  1420. }
  1421. else
  1422. {
  1423. $redirect_url = $this->_create_path('member_search').$which_field.'/';
  1424. }
  1425. $this->single_parts['path']['new_search_url'] = $redirect_url;
  1426. $this->single_parts['which_field'] = $which_field;
  1427. /** --------------------------------
  1428. /** Parse the POST request
  1429. /** --------------------------------*/
  1430. if ($_POST['screen_name'] == '' &&
  1431. $_POST['email'] == ''
  1432. )
  1433. {
  1434. $FNS->redirect($redirect_url);
  1435. exit;
  1436. }
  1437. $search_query = array();
  1438. foreach ($_POST as $key => $val)
  1439. {
  1440. if ($key == 'which_field' OR $key == 'XID' OR $key == 'site_id')
  1441. {
  1442. continue;
  1443. }
  1444. if ($key == 'group_id')
  1445. {
  1446. if ($val != 'any')
  1447. {
  1448. $search_query[] = " exp_member_groups.group_id ='".$DB->escape_str($_POST['group_id'])."'";
  1449. }
  1450. }
  1451. else
  1452. {
  1453. if ($val != '')
  1454. {
  1455. $search_query[] = $key." LIKE '%".$DB->escape_like_str($val)."%'";
  1456. }
  1457. }
  1458. }
  1459. if (count($search_query) < 1)
  1460. {
  1461. $FNS->redirect($redirect_url);
  1462. exit;
  1463. }
  1464. $Q = implode(" AND ", $search_query);
  1465. $sql = "SELECT DISTINCT exp_members.screen_name FROM exp_members, exp_member_groups
  1466. WHERE exp_members.group_id = exp_member_groups.group_id
  1467. AND exp_member_groups.site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND include_in_memberlist = 'y'
  1468. AND ".$Q;
  1469. $query = $DB->query($sql);
  1470. $total_count = $query->num_rows;
  1471. if ($total_count == 0)
  1472. {
  1473. return $this->member_search($LANG->line('no_search_results'));
  1474. }
  1475. $this->single_parts['include']['search_results'] = '';
  1476. foreach($query->result as $row)
  1477. {
  1478. // Changed this from htmlentities to htmlspecialchars because of problems with foreign characters, specifically persian ones
  1479. $value = htmlspecialchars(str_replace(array('(', ')', "'", '"'), array('\(', '\)', "\'", '\"'), '<'.$row['screen_name']).'>', ENT_QUOTES);
  1480. $this->single_parts['include']['search_results'] .= $this->_process_template($this->retrieve_template('member_results_row'), array('item' => '<a href="#" onclick="insert_name(\''.$value.'\');return false;">'.$row['screen_name'].'</a>'));
  1481. }
  1482. $this->return_data = $this->_process_template($this->retrieve_template('member_results'));
  1483. if ($this->allegiance == 'cp')
  1484. {
  1485. global $DSP;
  1486. $DSP->title = $LANG->line('search_results');
  1487. $DSP->body = $this->return_data;
  1488. }
  1489. }
  1490. /* END */
  1491. /** -----------------------------------
  1492. /** Buddy Search Popup
  1493. /** -----------------------------------*/
  1494. function buddy_search($message='')
  1495. {
  1496. global $LANG, $DB, $IN, $FNS, $PREFS;
  1497. $this->title = '';
  1498. $this->crumb = '';
  1499. if ($this->allegiance == 'cp')
  1500. {
  1501. $which = ( ! $IN->GBL('which')) ? 'buddy' : $IN->GBL('which');
  1502. }
  1503. else
  1504. {
  1505. $which = ($this->cur_id != '') ? $this->cur_id : 'buddy';
  1506. }
  1507. $form_details = array('hidden_fields' => array('which' => $which),
  1508. 'action' => $this->_create_path('do_buddy_search', AMP.'Z=1'),
  1509. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  1510. );
  1511. $this->single_parts['form']['form_declaration']['do_member_search'] = $FNS->form_declaration($form_details);
  1512. $this->single_parts['include']['message'] = $message;
  1513. $this->conditionals['message'] = ($message != '') ? 'y' : 'n';
  1514. // Member group select list
  1515. $this->single_parts['include']['member_group_options'] = '';
  1516. $query = $DB->query("SELECT group_id, group_title FROM exp_member_groups WHERE site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND include_in_memberlist = 'y' ORDER BY group_title");
  1517. foreach ($query->result as $row)
  1518. {
  1519. $this->single_parts['include']['member_group_options'] .= '<option value="'.$row['group_id'].'">'.$row['group_title'].'</option>';
  1520. }
  1521. $this->return_data = $this->_process_template($this->retrieve_template('search_members'));
  1522. if ($this->allegiance == 'cp')
  1523. {
  1524. global $DSP;
  1525. $DSP->title = $LANG->line('member_search');
  1526. $DSP->body = $this->return_data;
  1527. }
  1528. }
  1529. /* END */
  1530. /** -----------------------------
  1531. /** Perform Buddy search
  1532. /** -----------------------------*/
  1533. function do_buddy_search()
  1534. {
  1535. global $IN, $LANG, $FNS, $DB, $PREFS, $SESS;
  1536. $this->title = '';
  1537. $this->crumb = '';
  1538. $which = ( ! $IN->GBL('which')) ? 'buddy' : $IN->GBL('which');
  1539. if ($this->allegiance == 'cp')
  1540. {
  1541. $s = ($PREFS->ini('admin_session_type') != 'c') ? $SESS->userdata['session_id'] : 0;
  1542. $redirect_url = $PREFS->ini('cp_url', FALSE).'?S='.$s.
  1543. AMP.'C=myaccount'.
  1544. AMP.'M=messages'.
  1545. AMP.'P=buddy_search'.
  1546. AMP.'which='.$which.
  1547. AMP.'Z=1';
  1548. }
  1549. else
  1550. {
  1551. $redirect_url = $this->_create_path('buddy_search').$which.'/';
  1552. }
  1553. $this->single_parts['path']['new_search_url'] = $redirect_url;
  1554. $this->single_parts['which_field'] = $which; // For the results
  1555. /** --------------------------------
  1556. /** Parse the POST request
  1557. /** --------------------------------*/
  1558. if ($_POST['screen_name'] == '' &&
  1559. $_POST['email'] == ''
  1560. )
  1561. {
  1562. $FNS->redirect($redirect_url);
  1563. exit;
  1564. }
  1565. $search_query = array();
  1566. foreach ($_POST as $key => $val)
  1567. {
  1568. if ($key == 'which' OR $key == 'XID' OR $key == 'site_id')
  1569. {
  1570. continue;
  1571. }
  1572. if ($key == 'group_id')
  1573. {
  1574. if ($val != 'any')
  1575. {
  1576. $search_query[] = " group_id ='".$DB->escape_str($_POST['group_id'])."'";
  1577. }
  1578. }
  1579. else
  1580. {
  1581. if ($val != '')
  1582. {
  1583. $search_query[] = $key." LIKE '%".$DB->escape_like_str($val)."%'";
  1584. }
  1585. }
  1586. }
  1587. if (count($search_query) < 1)
  1588. {
  1589. $FNS->redirect($redirect_url);
  1590. exit;
  1591. }
  1592. $Q = implode(" AND ", $search_query);
  1593. $sql = "SELECT DISTINCT exp_members.member_id, exp_members.screen_name FROM exp_members, exp_member_groups
  1594. WHERE exp_members.group_id = exp_member_groups.group_id
  1595. AND exp_member_groups.site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND include_in_memberlist = 'y'
  1596. AND ".$Q;
  1597. $query = $DB->query($sql);
  1598. $total_count = $query->num_rows;
  1599. if ($total_count == 0)
  1600. {
  1601. return $this->buddy_search($LANG->line('no_search_results'));
  1602. }
  1603. $r = '';
  1604. foreach($query->result as $row)
  1605. {
  1606. $link = ($which == 'blocked') ? $this->_create_path('add_block') : $this->_create_path('add_buddy');
  1607. $link .= ($this->allegiance == 'cp') ? '&mid='.$row['member_id'] : $row['member_id'].'/';
  1608. $r .= $this->_process_template($this->retrieve_template('member_results_row'), array('item' => '<a href="#" onclick="window.opener.location.href=\''.$link.'\';return false;">'.$row['screen_name'].'</a>'));
  1609. }
  1610. $this->single_parts['include']['search_results'] = $r;
  1611. $this->return_data = $this->_process_template($this->retrieve_template('member_results'));
  1612. if ($this->allegiance == 'cp')
  1613. {
  1614. global $DSP;
  1615. $DSP->title = $LANG->line('search_results');
  1616. $DSP->body = $this->return_data;
  1617. }
  1618. }
  1619. /* END */
  1620. /** -----------------------------------
  1621. /** Current Storage Usage
  1622. /** -----------------------------------*/
  1623. function storage_usage()
  1624. {
  1625. global $LANG, $DB;
  1626. $sql = "SELECT COUNT(exp_message_copies.copy_id) AS count
  1627. FROM exp_message_copies
  1628. WHERE exp_message_copies.recipient_id = '{$this->member_id}'
  1629. AND exp_message_copies.message_deleted = 'n'";
  1630. $tql = "SELECT COUNT(exp_message_data.message_id) AS count
  1631. FROM exp_message_data
  1632. WHERE exp_message_data.sender_id = '{$this->member_id}'
  1633. AND exp_message_data.message_status = 'draft'";
  1634. $query = $DB->query($sql);
  1635. $results = $DB->query($tql);
  1636. $this->total_messages = $query->row['count']; + $results->row['count'];
  1637. }
  1638. /* END */
  1639. /** -----------------------------------
  1640. /** Current Storage Graph
  1641. /** -----------------------------------*/
  1642. function storage_graph()
  1643. {
  1644. global $LANG, $DB, $SESS;
  1645. if ($this->total_messages == '')
  1646. {
  1647. $this->storage_usage();
  1648. }
  1649. /** ----------------------
  1650. /** Default
  1651. /** ----------------------*/
  1652. $this->single_parts['lang']['total_messages'] = $this->total_messages;
  1653. $this->single_parts['lang']['max_messages'] = ($this->storage_limit == '0') ? $LANG->line('unlimited_messages') : $this->storage_limit;
  1654. $this->single_parts['lang']['usage_percent'] = '0';
  1655. $this->single_parts['image']['messages_graph']['width'] = '1';
  1656. $this->single_parts['image']['messages_graph']['height'] = '11';
  1657. $this->single_parts['image']['messages_graph']['url'] = $this->images_folder.'bar.gif';
  1658. /** ----------------------
  1659. /** Calculate
  1660. /** ----------------------*/
  1661. if ($this->total_messages > 0 && $this->storage_limit > 0)
  1662. {
  1663. $this->single_parts['lang']['usage_percent'] = round(($this->total_messages / $this->storage_limit) * 100, 1);
  1664. $this->single_parts['image']['messages_graph']['width'] = ceil(($this->total_messages / $this->storage_limit) * $this->graph_width);
  1665. /* We are subtracting some pixels to take into account CSS padding (~6px) */
  1666. if ($this->single_parts['image']['messages_graph']['width'] > 7)
  1667. {
  1668. $this->single_parts['image']['messages_graph']['width'] -= 6;
  1669. }
  1670. if ($this->single_parts['image']['messages_graph']['width'] > $this->graph_width)
  1671. {
  1672. $this->single_parts['image']['messages_graph']['width'] = $this->graph_width;
  1673. }
  1674. }
  1675. $this->single_parts['lang']['storage_status'] = str_replace(array('%x', '%y'), array($this->single_parts['lang']['total_messages'], $this->single_parts['lang']['max_messages']), $LANG->line('storage_status'));
  1676. $this->single_parts['lang']['storage_percentage'] = str_replace('%x', $this->single_parts['lang']['usage_percent'], $LANG->line('storage_percentage'));
  1677. }
  1678. /* END */
  1679. /** -----------------------------------
  1680. /** Modify Messages Request
  1681. /** -----------------------------------*/
  1682. function modify_messages()
  1683. {
  1684. global $LANG, $DB, $IN, $FNS, $SESS;
  1685. if ( ! $IN->GBL('toggle', 'POST'))
  1686. {
  1687. $folder_id = ( ! $IN->GBL('this_folder')) ? 1 : $IN->GBL('this_folder');
  1688. return $this->view_folder($folder_id);
  1689. }
  1690. foreach ($_POST as $key => $val)
  1691. {
  1692. if (strstr($key, 'toggle') AND ! is_array($val))
  1693. {
  1694. $unread = FALSE;
  1695. if ($val != '' && $val[0] == 'u')
  1696. {
  1697. $unread = TRUE;
  1698. $val = substr($val, 1);
  1699. }
  1700. if ($IN->GBL('daction', 'POST') == 'delete')
  1701. {
  1702. if (substr($val, 0, 1) == 'd')
  1703. {
  1704. // We're deleting a draft
  1705. $DB->query("DELETE FROM exp_message_data
  1706. WHERE sender_id = '{$this->member_id}'
  1707. AND message_id = '".$DB->escape_str(substr($val, 1))."'
  1708. AND message_status = 'draft'");
  1709. }
  1710. else
  1711. {
  1712. $DB->query("UPDATE exp_message_copies SET message_deleted = 'y', message_read = 'y'
  1713. WHERE recipient_id = '{$this->member_id}'
  1714. AND copy_id = '".$DB->escape_str($val)."'");
  1715. /** ----------------------------------
  1716. /** Reduce exp_members.private_messages
  1717. /** ----------------------------------*/
  1718. // quick sanity check juuuuust in case
  1719. if ($SESS->userdata['private_messages'] > 0 && $unread === TRUE)
  1720. {
  1721. $DB->query("UPDATE exp_members SET private_messages = private_messages - 1
  1722. WHERE member_id = '{$this->member_id}'");
  1723. $SESS->userdata['private_messages']--;
  1724. }
  1725. }
  1726. }
  1727. elseif ($IN->GBL('daction', 'POST') == 'reply')
  1728. {
  1729. $this->hide_preview = TRUE;
  1730. return $this->compose($val);
  1731. }
  1732. elseif ($IN->GBL('daction', 'POST') == 'reply_all')
  1733. {
  1734. $this->hide_preview = TRUE;
  1735. return $this->compose($val);
  1736. }
  1737. elseif ($IN->GBL('daction', 'POST') == 'forward')
  1738. {
  1739. $this->hide_preview = TRUE;
  1740. return $this->compose($val);
  1741. }
  1742. elseif ($IN->GBL('moveto', 'POST') && $IN->GBL('moveto', 'POST') != 'none')
  1743. {
  1744. $folder_id = $IN->GBL('moveto', 'POST');
  1745. if (is_numeric($folder_id) && $folder_id <= $this->max_folders && isset($this->folders[$folder_id]))
  1746. {
  1747. $DB->query("UPDATE exp_message_copies
  1748. SET message_deleted = 'n',
  1749. message_folder = '".$DB->escape_str($folder_id)."'
  1750. WHERE recipient_id = '{$this->member_id}'
  1751. AND copy_id = '".$DB->escape_str($val)."'");
  1752. }
  1753. }
  1754. elseif ($IN->GBL('copyto', 'POST') && $IN->GBL('copyto', 'POST') != 'none')
  1755. {
  1756. $folder_id = $IN->GBL('copyto', 'POST');
  1757. if (is_numeric($folder_id) && $folder_id <= $this->max_folders && isset($this->folders[$folder_id]))
  1758. {
  1759. $query = $DB->query("SELECT * FROM exp_message_copies
  1760. WHERE recipient_id = '{$this->member_id}'
  1761. AND copy_id = '".$DB->escape_str($val)."'");
  1762. $query->row['copy_id'] = '';
  1763. $query->row['message_folder'] = $DB->escape_str($folder_id);
  1764. $query->row['message_deleted'] = 'n';
  1765. $DB->query($DB->insert_string('exp_message_copies', $query->row), TRUE);
  1766. }
  1767. }
  1768. }
  1769. }
  1770. $which = ($IN->GBL('this_folder', 'POST') === FALSE) ? '1' : $IN->GBL('this_folder', 'POST');
  1771. if ($this->allegiance == 'user')
  1772. {
  1773. $url = $this->base_url.'view_folder/'.$which.'/';
  1774. }
  1775. else
  1776. {
  1777. $url = $this->base_url.'view_folder'.AMP.'folder='.$which;
  1778. }
  1779. $FNS->redirect($url);
  1780. exit;
  1781. }
  1782. /* END */
  1783. /** -----------------------------------
  1784. /** Erase Messages
  1785. /** -----------------------------------*/
  1786. function erase($delete='')
  1787. {
  1788. global $FNS, $DB;
  1789. // -------------------------------------------
  1790. // If this is the last copy of a message,
  1791. // then perhaps we should erase the
  1792. // exp_message_data too, no?
  1793. // -------------------------------------------
  1794. if (is_array($delete) && sizeof($delete) > 0)
  1795. {
  1796. $query = $DB->query("SELECT message_id, copy_id FROM exp_message_copies
  1797. WHERE recipient_id = '{$this->member_id}'
  1798. AND copy_id IN ('".implode("','", $delete)."')");
  1799. }
  1800. else
  1801. {
  1802. $query = $DB->query("SELECT message_id, copy_id FROM exp_message_copies
  1803. WHERE recipient_id = '{$this->member_id}'
  1804. AND message_deleted = 'y'");
  1805. }
  1806. if ($query->num_rows > 0)
  1807. {
  1808. $copy_ids = array();
  1809. $message_ids = array();
  1810. foreach($query->result as $row)
  1811. {
  1812. $copy_ids[] = $row['copy_id'];
  1813. /* The reason we are using an implode on the $copy_ids array
  1814. is because there is a very small possibility that through
  1815. the copy and move commands that a single member might have
  1816. the last two remaining copies of a message and delete them
  1817. at the same time. Thus, a normal copy_id != $row['copy_id']
  1818. would not work effectively in this query to detemine if the
  1819. exp_message_data table should have this message removed.
  1820. */
  1821. $results = $DB->query("SELECT COUNT(*) AS count FROM exp_message_copies
  1822. WHERE message_id = '".$DB->escape_str($row['message_id'])."'
  1823. AND copy_id NOT IN ('".implode("','", $copy_ids)."')");
  1824. if ($results->row['count'] == 0)
  1825. {
  1826. $message_ids[] = $row['message_id'];
  1827. }
  1828. }
  1829. if (sizeof($message_ids) > 0)
  1830. {
  1831. $DB->query("DELETE FROM exp_message_data WHERE message_id IN ('".implode("','", $message_ids)."')");
  1832. // Remove any attachments as well
  1833. $query = $DB->query("SELECT attachment_location FROM exp_message_attachments WHERE message_id IN ('".implode("','", $message_ids)."')");
  1834. if ($query->num_rows > 0)
  1835. {
  1836. foreach ($query->result as $row)
  1837. {
  1838. @unlink($row['attachment_location']);
  1839. }
  1840. $DB->query("DELETE FROM exp_message_attachments WHERE message_id IN ('".implode("','", $message_ids)."')");
  1841. }
  1842. }
  1843. $DB->query("DELETE FROM exp_message_copies WHERE copy_id IN ('".implode("','", $copy_ids)."')");
  1844. }
  1845. /** ---------------------------------------
  1846. /** UPDATE Unread Message Count
  1847. /** ---------------------------------------*/
  1848. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_message_copies
  1849. WHERE recipient_id = '{$this->member_id}'
  1850. AND message_read = 'n'");
  1851. $results = $DB->query("UPDATE exp_members SET private_messages = '".$DB->escape_str($query->row['count'])."'
  1852. WHERE member_id = '{$this->member_id}'");
  1853. if (is_array($delete) && sizeof($delete) > 0)
  1854. {
  1855. return;
  1856. }
  1857. /** ----------------------------------------
  1858. /** Redirect Back to Inbox
  1859. /** ----------------------------------------*/
  1860. $FNS->redirect($this->_create_path('inbox'));
  1861. exit;
  1862. }
  1863. /* END */
  1864. /** -----------------------------------
  1865. /** Convert Recipients to Valid List
  1866. /** -----------------------------------*/
  1867. function convert_recipients($str, $type='string', $by='screen_name')
  1868. {
  1869. global $DB;
  1870. /** -------------------------------------
  1871. /** Retrieve Protected Names
  1872. /** -------------------------------------*/
  1873. $protected = array();
  1874. if (preg_match_all("/\<(.*?)\>/", $str, $matches))
  1875. {
  1876. for($i=0, $s=sizeof($matches['1']); $i < $s; ++$i)
  1877. {
  1878. $protected[] = $matches['1'][$i];
  1879. $str = str_replace($matches['0'][$i], '', $str);
  1880. }
  1881. }
  1882. /** -------------------------------------
  1883. /** Clean Up Remaining and Combine
  1884. /** -------------------------------------*/
  1885. $str = str_replace('|', ',', $str);
  1886. $str = str_replace(',,', ',', $str);
  1887. $str = preg_replace("/\s*,\s*/", ',', $str);
  1888. if (substr($str, -1) == ',')
  1889. {
  1890. $str = substr($str, 0, -1);
  1891. }
  1892. if (substr($str, 0, 1) == ',')
  1893. {
  1894. $str = substr($str, 1);
  1895. }
  1896. $temp_list = array_merge(explode(',', $str), $protected);
  1897. $list = array();
  1898. for($i=0, $s = sizeof($temp_list); $i < $s; ++$i)
  1899. {
  1900. if(trim($temp_list[$i]) != '')
  1901. {
  1902. $list[] = $DB->escape_str($temp_list[$i]);
  1903. }
  1904. }
  1905. if (sizeof($list) == 0)
  1906. {
  1907. if ($type == 'array')
  1908. {
  1909. return array();
  1910. }
  1911. else
  1912. {
  1913. $str = '';
  1914. return $str;
  1915. }
  1916. }
  1917. /** -------------------------------------
  1918. /** Check for matches in the database
  1919. /** -------------------------------------*/
  1920. if ( ! is_numeric($list['0']))
  1921. {
  1922. $query = $DB->query("SELECT {$by} FROM exp_members
  1923. WHERE screen_name IN ('".implode("','", $list)."')");
  1924. }
  1925. else
  1926. {
  1927. $query = $DB->query("SELECT {$by} FROM exp_members
  1928. WHERE member_id IN ('".implode("','", $list)."')");
  1929. if ($query->num_rows == 0)
  1930. {
  1931. $query = $DB->query("SELECT {$by} FROM exp_members
  1932. WHERE screen_name IN ('".implode("','", $list)."')");
  1933. }
  1934. }
  1935. $array = array();
  1936. if ($query->num_rows > 0)
  1937. {
  1938. foreach($query->result as $row)
  1939. {
  1940. $array[] = ($by == 'screen_name') ? '<'.$row[$by].'>' : $row[$by];
  1941. }
  1942. $array = array_unique($array);
  1943. sort($array);
  1944. }
  1945. // ----------------------------------
  1946. // Do we have as many returned as we had in our initial list?
  1947. // If not, we will be outputting an error in the send_message() function
  1948. // ----------------------------------
  1949. if (count($list) != count($array))
  1950. {
  1951. $this->invalid_name = TRUE;
  1952. }
  1953. if ($type == 'array')
  1954. {
  1955. return $array;
  1956. }
  1957. else
  1958. {
  1959. $str = implode(', ', $array);
  1960. return $str;
  1961. }
  1962. }
  1963. /* END */
  1964. /** -------------------------------------
  1965. /** Check if User is Over Storage Amount
  1966. /** -------------------------------------*/
  1967. function _check_overflow($id)
  1968. {
  1969. global $DB, $SESS, $PREFS;
  1970. /** ---------------------------------
  1971. /** Check Member Group Permissions
  1972. /** ---------------------------------*/
  1973. $sql = "SELECT exp_member_groups.group_id, exp_member_groups.can_send_private_messages, exp_member_groups.prv_msg_storage_limit, exp_members.accept_messages
  1974. FROM exp_members, exp_member_groups
  1975. WHERE exp_members.group_id = exp_member_groups.group_id
  1976. AND exp_member_groups.site_id = '".$DB->escape_str($PREFS->ini('site_id'))."'
  1977. AND exp_members.member_id = '".$DB->escape_str($id)."'";
  1978. $query = $DB->query($sql);
  1979. if ($query->num_rows > 0)
  1980. {
  1981. // Super Admins have ALL the fun
  1982. if ($query->row['group_id'] == 1 && $query->row['accept_messages'] == 'y')
  1983. {
  1984. return TRUE;
  1985. }
  1986. elseif ($query->row['can_send_private_messages'] != 'y' OR $query->row['accept_messages'] != 'y')
  1987. {
  1988. return FALSE;
  1989. }
  1990. }
  1991. else
  1992. {
  1993. return FALSE;
  1994. }
  1995. /** -------------------------------
  1996. /** Check Message Count
  1997. /** -------------------------------*/
  1998. $user_storage_limit = $query->row['prv_msg_storage_limit'];
  1999. if ($user_storage_limit == 0)
  2000. {
  2001. return TRUE;
  2002. }
  2003. $sql = "SELECT COUNT(exp_message_copies.copy_id) AS count
  2004. FROM exp_message_copies
  2005. WHERE exp_message_copies.recipient_id = '{$id}'
  2006. AND exp_message_copies.message_deleted = 'n'";
  2007. $query = $DB->query($sql);
  2008. if ($query->row['count'] >= $user_storage_limit)
  2009. {
  2010. return FALSE;
  2011. }
  2012. return TRUE;
  2013. }
  2014. /* END */
  2015. /** -----------------------------------
  2016. /** Compose to Member
  2017. /** -----------------------------------*/
  2018. function pm()
  2019. {
  2020. global $IN;
  2021. if ($this->allegiance == 'cp' && $IN->GBL('mid') !== FALSE && is_numeric($IN->GBL('mid')))
  2022. {
  2023. $_GET['recipients'] = $IN->GBL('mid');
  2024. }
  2025. elseif ($this->allegiance == 'user' && $this->cur_id != '' && is_numeric($this->cur_id))
  2026. {
  2027. $_GET['recipients'] = $this->cur_id;
  2028. $this->cur_id = '';
  2029. }
  2030. $this->compose();
  2031. }
  2032. /* END */
  2033. /** -----------------------------------
  2034. /** Compose New Message Form
  2035. /** -----------------------------------*/
  2036. function compose($id = '', $errors='')
  2037. {
  2038. global $LANG, $DB, $PREFS, $IN, $FNS;
  2039. if ($id == '')
  2040. {
  2041. if ($this->allegiance == 'cp' && $IN->GBL('msg') !== FALSE && is_numeric($IN->GBL('msg')))
  2042. {
  2043. $id = $IN->GBL('msg');
  2044. $this->hide_preview = TRUE;
  2045. }
  2046. elseif ($this->allegiance == 'user' && $this->cur_id != '' && is_numeric($this->cur_id))
  2047. {
  2048. $id = $this->cur_id;
  2049. $this->hide_preview = TRUE;
  2050. }
  2051. }
  2052. $template = $this->retrieve_template('message_compose');
  2053. /** --------------------------------
  2054. /** Form Declaration and Hidden Form Fields
  2055. /** --------------------------------*/
  2056. $hidden = array();
  2057. if ($id != '' && $IN->GBL('daction') != 'forward' && $IN->GBL('daction') != 'reply' && $IN->GBL('daction') != 'reply_all')
  2058. {
  2059. $hidden['message_id'] = $id;
  2060. }
  2061. if ($IN->GBL('daction') == 'forward')
  2062. {
  2063. $hidden['create_attach'] = 'y';
  2064. }
  2065. if ($IN->GBL('daction') == 'forward' OR $IN->GBL('forwarding') !== FALSE)
  2066. {
  2067. $hidden['forwarding'] = ($IN->GBL('daction') == 'forward') ? $id : $IN->GBL('forwarding');
  2068. }
  2069. if ($IN->GBL('daction') == 'reply_all' OR $IN->GBL('daction') == 'reply' OR $IN->GBL('replying') !== FALSE)
  2070. {
  2071. $hidden['replying'] = ($IN->GBL('daction') == 'reply' OR $IN->GBL('daction') == 'reply_all') ? $id : $IN->GBL('replying');
  2072. }
  2073. $details = array('action' => $this->_create_path('send_message'),
  2074. 'id' => 'submit_message',
  2075. 'enctype' => 'multi',
  2076. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  2077. );
  2078. /** -------------------------------------
  2079. /** Default Values for Form
  2080. /** -------------------------------------*/
  2081. $this->single_parts['include']['emoticons'] = $this->emoticons();
  2082. $this->single_parts['include']['hidden_js'] = $this->hidden_js();
  2083. $this->single_parts['image']['search_glass'] = '<img src="'.$this->images_folder.'search_glass.gif" style="border: 0px" width="12" height="12" alt="'.$LANG->line('search_glass').'" />';
  2084. $this->single_parts['include']['search']['recipients'] = '<a href="#" title="{lang:member_search}" onclick="perform_search(1); return false;">'.$this->single_parts['image']['search_glass'].'</a>';
  2085. $this->single_parts['include']['search']['cc'] = '<a href="#" title="{lang:member_search}" onclick="perform_search(2); return false;">'.$this->single_parts['image']['search_glass'].'</a>';
  2086. $this->single_parts['include']['search_js'] = $this->search_js();
  2087. $this->single_parts['include']['text_counter_js'] = $this->text_counter_js();
  2088. $this->conditionals['attachments_allowed'] = $this->attach_allowed;
  2089. $this->conditionals['attachments_exist'] = 'n';
  2090. $this->single_parts['include']['attachments'] = '';
  2091. $this->single_parts['lang']['max_file_size'] = $this->attach_maxsize;
  2092. $this->single_parts['lang']['max_chars'] = $this->max_chars;
  2093. $this->single_parts['input']['tracking_checked'] = "";
  2094. $this->single_parts['input']['sent_copy_checked'] = '';
  2095. $this->single_parts['input']['hide_cc_checked'] = '';
  2096. $this->single_parts['include']['compose_header_js'] = $this->compose_header_js();
  2097. $this->single_parts['include']['dynamic_address_book'] = $this->dynamic_address_book();
  2098. $this->single_parts['include']['submission_error'] = '';
  2099. $this->header_javascript .= $this->compose_header_js();
  2100. /** -------------------------------------
  2101. /** Spell Check Related Values
  2102. /** -------------------------------------*/
  2103. $this->single_parts['include']['spellcheck_js'] = ($this->spellcheck_enabled !== TRUE) ? '' : $this->spellcheck_js(); // goes first for enabled check
  2104. $this->single_parts['path']['spellcheck_iframe'] = ($this->spellcheck_enabled !== TRUE) ? '' : $this->_create_path('spellcheck_iframe');
  2105. $this->conditionals['spellcheck'] = ($this->spellcheck_enabled !== TRUE) ? 'n' : 'y';
  2106. /** -------------------------------------
  2107. /** Create the HTML formatting buttons
  2108. /** -------------------------------------*/
  2109. $this->single_parts['include']['html_formatting_buttons'] = '';
  2110. if ( ! class_exists('Html_buttons'))
  2111. {
  2112. if (include_once(PATH_LIB.'html_buttons'.EXT))
  2113. {
  2114. $BUTT = new Html_buttons();
  2115. $button_include = $BUTT->create_buttons();
  2116. if ($this->allegiance == 'cp')
  2117. {
  2118. $button_include = str_replace('htmlButtonOff', 'htmlButtonA', $button_include);
  2119. $button_include = str_replace('htmlButtonOn', 'htmlButtonB', $button_include);
  2120. }
  2121. /** -------------------------------
  2122. /** Fixes a small problem with single and double quotes
  2123. /** -------------------------------*/
  2124. $this->single_parts['include']['html_formatting_buttons'] = str_replace("document.getElementById('submit_post').",
  2125. "document.getElementById('submit_message').",
  2126. $button_include);
  2127. }
  2128. }
  2129. /** ----------------------------------------
  2130. /** Preview, Reply, Forward or New Entry?
  2131. /** ----------------------------------------*/
  2132. if ($id != '' && is_numeric($id))
  2133. {
  2134. if ($IN->GBL('daction') !== FALSE && ($IN->GBL('daction', 'POST') == 'reply' OR $IN->GBL('daction', 'POST') == 'reply_all' OR $IN->GBL('daction', 'POST') == 'forward'))
  2135. {
  2136. $data = $this->_message_data($id, '', $this->member_id);
  2137. if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '')
  2138. {
  2139. if ( ! class_exists('Typography'))
  2140. {
  2141. require PATH_CORE.'core.typography'.EXT;
  2142. }
  2143. $TYPE = new Typography(0);
  2144. $subject = ($data === FALSE) ? '' : $TYPE->filter_censored_words($data['subject']);
  2145. $body = ($data === FALSE) ? '' : $TYPE->filter_censored_words($data['body']);
  2146. }
  2147. else
  2148. {
  2149. $subject = ($data === FALSE) ? '' : $data['subject'];
  2150. $body = ($data === FALSE) ? '' : $data['body'];
  2151. }
  2152. $booger['hidden_fields'] = array('message_id' => $data['id'], 'forward' => 'y');
  2153. $prefix = ($IN->GBL('daction', 'POST') == 'forward') ? 'forward_prefix' : 'reply_prefix';
  2154. $prefix = (substr($data['subject'], 0, strlen($LANG->line($prefix))) == $LANG->line($prefix)) ? '' : '{lang:'.$prefix.'}';
  2155. $this->single_parts['input']['subject'] = ($data === FALSE) ? '' : $prefix.$subject;
  2156. $this->single_parts['input']['body'] = ($data === FALSE) ? '' : NL.NL.NL.'[quote]'.NL.$body.NL.'[/quote]';
  2157. $this->single_parts['input']['recipients'] = ($data === FALSE OR $IN->GBL('daction', 'POST') == 'forward') ? '' : $this->convert_recipients($data['sender_id']);
  2158. if ($data === FALSE OR $IN->GBL('daction', 'POST') != 'reply_all')
  2159. {
  2160. $this->single_parts['input']['cc'] = '';
  2161. }
  2162. else
  2163. {
  2164. $cc = $this->convert_recipients($data['recipients'].','.$data['cc']);
  2165. $x = explode(', ', $cc);
  2166. $y = explode(', ', $this->single_parts['input']['recipients']);
  2167. // Make sure CC does not contain members in Recipients
  2168. $cc = array_diff($x, $y);
  2169. $this->single_parts['input']['cc'] = implode(', ', $cc);
  2170. }
  2171. $this->single_parts['include']['preview_message'] = '';
  2172. if ($IN->GBL('daction', 'POST') == 'forward' && $data !== FALSE && sizeof($data['attachments']) > 0)
  2173. {
  2174. $this->conditionals['attachments_allowed'] = (sizeof($data['attachments']) >= $this->max_attachments) ? 'n' : 'y';
  2175. $this->conditionals['attachments_exist'] = 'y';
  2176. $this->single_parts['include']['attachments'] = $this->_display_attachments($data['attachments']);
  2177. $hidden['attach'] = implode('|', $data['attach']);
  2178. }
  2179. }
  2180. else
  2181. {
  2182. $data = $this->_message_data($id, $this->member_id);
  2183. if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '')
  2184. {
  2185. if ( ! class_exists('Typography'))
  2186. {
  2187. require PATH_CORE.'core.typography'.EXT;
  2188. }
  2189. $TYPE = new Typography(0);
  2190. $subject = ($data === FALSE) ? '' : $TYPE->filter_censored_words($data['subject']);
  2191. $body = ($data === FALSE) ? '' : $TYPE->filter_censored_words($data['body']);
  2192. }
  2193. else
  2194. {
  2195. $subject = ($data === FALSE) ? '' : $data['subject'];
  2196. $body = ($data === FALSE) ? '' : $data['body'];
  2197. }
  2198. $this->single_parts['input']['subject'] = $subject;
  2199. $this->single_parts['input']['body'] = $body;
  2200. $this->single_parts['input']['recipients'] = ($data === FALSE) ? '' : $this->convert_recipients($data['recipients']);
  2201. $this->single_parts['input']['cc'] = ($data === FALSE) ? '' : $this->convert_recipients($data['cc']);
  2202. $this->single_parts['include']['preview_message'] = ($data === FALSE OR $this->hide_preview === TRUE) ? '' : $data['preview'];
  2203. $this->single_parts['input']['tracking_checked'] = ($data === FALSE OR $data['tracking'] == 'n') ? '' : "checked='checked'";
  2204. $this->single_parts['input']['sent_copy_checked'] = ($data === FALSE OR $data['sent_copy'] == 'n') ? '' : "checked='checked'";;
  2205. $this->single_parts['input']['hide_cc_checked'] = ($data === FALSE OR $data['hide_cc'] == 'n') ? '' : "checked='checked'";
  2206. if ($data !== FALSE && sizeof($data['attachments']) > 0)
  2207. {
  2208. $this->conditionals['attachments_allowed'] = (sizeof($data['attachments']) >= $this->max_attachments) ? 'n' : 'y';
  2209. $this->conditionals['attachments_exist'] = 'y';
  2210. $this->single_parts['include']['attachments'] = $this->_display_attachments($data['attachments']);
  2211. $hidden['attach'] = implode('|', $data['attach']);
  2212. }
  2213. }
  2214. }
  2215. else
  2216. {
  2217. $this->single_parts['input']['subject'] = ( ! $IN->GBL('subject')) ? '' : $IN->GBL('subject');
  2218. $this->single_parts['input']['body'] = ( ! $IN->GBL('body')) ? '' : $IN->GBL('body');
  2219. $this->single_parts['input']['cc'] = '';
  2220. $this->single_parts['input']['recipients'] = ( ! $IN->GBL('recipients')) ? '' : $this->convert_recipients($IN->GBL('recipients'));
  2221. $this->single_parts['include']['preview_message'] = '';
  2222. }
  2223. $details['hidden_fields'] = $hidden;
  2224. $this->single_parts['form']['form_declaration']['messages'] = $FNS->form_declaration($details);
  2225. // --------------------------------------------
  2226. // If upload path is not specified we
  2227. // override all attachment related settings
  2228. // --------------------------------------------
  2229. if ($this->upload_path == '')
  2230. {
  2231. $this->conditionals['attachments_allowed'] = 'n';
  2232. $this->conditionals['attachments_exist'] = 'n';
  2233. $this->single_parts['include']['attachments'] = '';
  2234. }
  2235. /** ---------------------------------------
  2236. /** Error Message Displaying, if any
  2237. /** ---------------------------------------*/
  2238. if (is_array($errors) && sizeof($errors) > 0)
  2239. {
  2240. $this->single_parts['lang']['error_message'] = implode(BR, $errors);
  2241. $this->single_parts['include']['submission_error'] = $this->_process_template($this->retrieve_template('message_submission_error'));
  2242. }
  2243. /** ----------------------------------------
  2244. /** Return the Compose Form Contents
  2245. /** ----------------------------------------*/
  2246. $this->title = $LANG->line('compose_message');
  2247. $this->crumb = $LANG->line('compose_message');
  2248. $this->return_data = $this->_process_template($template);
  2249. }
  2250. /* END */
  2251. //----------------------------------------
  2252. // Fetch Message Data
  2253. // Massage that message data, si vous plait
  2254. //----------------------------------------
  2255. function _message_data($id, $sender='', $recipient='')
  2256. {
  2257. global $DB, $LOC;
  2258. $data = array();
  2259. // ------------------------------------------
  2260. // If $recipient is set, this is a message
  2261. // being viewed. So, $id is actually the copy_id
  2262. // in the exp_message_copies table.
  2263. // -----------------------------------------
  2264. if ($recipient != '' && is_numeric($recipient))
  2265. {
  2266. $query = $DB->query("SELECT message_id, message_folder, message_read FROM exp_message_copies
  2267. WHERE copy_id = '".$DB->escape_str($id)."'
  2268. AND recipient_id = '".$DB->escape_str($recipient)."'");
  2269. if ($query->num_rows == 0)
  2270. {
  2271. return FALSE;
  2272. }
  2273. $mid = $query->row['message_id'];
  2274. $data['folder_id'] = $query->row['message_folder'];
  2275. $data['message_read'] = $query->row['message_read'];
  2276. }
  2277. else
  2278. {
  2279. $mid = $id;
  2280. }
  2281. $sql = "SELECT * FROM exp_message_data WHERE message_id = '".$DB->escape_str($mid)."'";
  2282. if ($sender != '' && is_numeric($sender))
  2283. {
  2284. $sql .= " AND sender_id = '".$DB->escape_str($sender)."'";
  2285. }
  2286. $query = $DB->query($sql);
  2287. if ($query->num_rows == 0)
  2288. {
  2289. return FALSE;
  2290. }
  2291. /** ---------------------------------
  2292. /** Do a Little Data Work
  2293. /** ---------------------------------*/
  2294. foreach($query->row as $key => $value)
  2295. {
  2296. $data[str_replace('message_', '', $key)] = $value;
  2297. }
  2298. $data = str_replace('message_', '', $data);
  2299. $data['recipients'] = str_replace('|', ', ', $data['recipients']);
  2300. $data['cc'] = str_replace('|', ', ', $data['cc']);
  2301. $data['attachments'] = array();
  2302. $data['date'] = $LOC->set_human_time($data['date']);
  2303. $results = $DB->query("SELECT screen_name FROM exp_members WHERE member_id = '".$DB->escape_str($data['sender_id'])."'");
  2304. $data['sender'] = $results->row['screen_name'];
  2305. /** ---------------------------------
  2306. /** Create Preview of Message
  2307. /** ---------------------------------*/
  2308. if ( ! class_exists('Typography'))
  2309. {
  2310. require PATH_CORE.'core.typography'.EXT;
  2311. }
  2312. $TYPE = new Typography;
  2313. $TYPE->highlight_code = TRUE;
  2314. $this->single_parts['include']['parsed_message'] = $TYPE->parse_type(stripslashes($data['body']),
  2315. array(
  2316. 'text_format' => 'xhtml',
  2317. 'html_format' => $this->html_format,
  2318. 'auto_links' => $this->auto_links,
  2319. 'allow_img_url' => 'n'
  2320. ));
  2321. $data['preview'] = $this->_process_template($this->retrieve_template('preview_message'));
  2322. /** ---------------------------------
  2323. /** Fetch Attachment Information
  2324. /** ---------------------------------*/
  2325. if ($query->row['message_attachments'] == 'y')
  2326. {
  2327. $results = $DB->query("SELECT attachment_name, attachment_id, attachment_size, attachment_hash
  2328. FROM exp_message_attachments
  2329. WHERE message_id = '".$DB->escape_str($mid)."'");
  2330. if ($results->num_rows > 0)
  2331. {
  2332. $data['attach'] = array();
  2333. foreach($results->result as $row)
  2334. {
  2335. $data['attachments'][] = $row;
  2336. $data['attach'][] = $row['attachment_id'];
  2337. }
  2338. }
  2339. }
  2340. return $data;
  2341. }
  2342. /* END */
  2343. //----------------------------------------
  2344. // Output the displaying of attachments
  2345. // for the Compose Page
  2346. //----------------------------------------
  2347. function _display_attachments($data)
  2348. {
  2349. $main = $this->retrieve_template('message_attachments');
  2350. $rows = $this->retrieve_template('message_attachment_rows');
  2351. $this->single_parts['include']['attachment_rows'] = '';
  2352. for($i = 0, $l = sizeof($data); $i < $l; $i++)
  2353. {
  2354. foreach($data[$i] as $key => $value)
  2355. {
  2356. $this->single_parts['input'][$key] = $value;
  2357. }
  2358. $this->single_parts['include']['attachment_rows'] .= $this->_process_template($rows);
  2359. }
  2360. return $this->_process_template($main);
  2361. }
  2362. /* END */
  2363. //----------------------------------------
  2364. // Output the displaying of attachments
  2365. // for the viewing of a message
  2366. //----------------------------------------
  2367. function _attachment_links($data)
  2368. {
  2369. $rows = $this->retrieve_template('message_attachment_link');
  2370. if ($this->allegiance == 'user')
  2371. {
  2372. $url = $this->base_url.'attachment/';
  2373. }
  2374. else
  2375. {
  2376. $url = $this->base_url.'attachment'.AMP.'aid=';
  2377. }
  2378. $r = '';
  2379. for($i = 0, $l = sizeof($data); $i < $l; $i++)
  2380. {
  2381. foreach($data[$i] as $key => $value)
  2382. {
  2383. $this->single_parts['input'][$key] = $value;
  2384. }
  2385. $this->single_parts['path']['download_link'] = ($this->allegiance == 'user') ? $url.$data[$i]['attachment_hash'].'/' : $url.$data[$i]['attachment_hash'];
  2386. $r .= $this->_process_template($rows);
  2387. }
  2388. return $r;
  2389. }
  2390. /* END */
  2391. /** -----------------------------------
  2392. /** Send Message
  2393. /** -----------------------------------*/
  2394. function send_message()
  2395. {
  2396. if ( ! class_exists('Messages_send'))
  2397. {
  2398. require PATH_CORE.'core.messages_send.php';
  2399. }
  2400. $MS = new Messages_send();
  2401. foreach(get_object_vars($this) as $key => $value)
  2402. {
  2403. $MS->{$key} = $value;
  2404. }
  2405. $MS->send_message();
  2406. $this->return_data = $MS->return_data;
  2407. }
  2408. /* END */
  2409. /** -----------------------------------
  2410. /** View a Single Message
  2411. /** -----------------------------------*/
  2412. function view_message($copy_id = '')
  2413. {
  2414. global $LANG, $DB, $LOC, $IN, $FNS, $SESS, $REGX, $PREFS;
  2415. /** -----------------------------------
  2416. /** What Private Message?
  2417. /** -----------------------------------*/
  2418. if ($copy_id == '')
  2419. {
  2420. if ($this->allegiance == 'cp' && $IN->GBL('msg') !== FALSE && is_numeric($IN->GBL('msg')))
  2421. {
  2422. $copy_id = $IN->GBL('msg');
  2423. }
  2424. elseif ($this->allegiance == 'user' && $this->cur_id != '' && is_numeric($this->cur_id))
  2425. {
  2426. $copy_id = $this->cur_id;
  2427. }
  2428. }
  2429. /** -----------------------------------
  2430. /** Retrieve Data
  2431. /** -----------------------------------*/
  2432. $data = $this->_message_data($copy_id, '', $this->member_id);
  2433. if ($data === FALSE)
  2434. {
  2435. return $this->_error_page('invalid_message');
  2436. }
  2437. if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '')
  2438. {
  2439. if ( ! class_exists('Typography'))
  2440. {
  2441. require PATH_CORE.'core.typography'.EXT;
  2442. }
  2443. $TYPE = new Typography(0);
  2444. $data['subject'] = $TYPE->filter_censored_words($data['subject']);
  2445. $data['body'] = $TYPE->filter_censored_words($data['body']);
  2446. }
  2447. $this->single_parts['include']['subject'] = $data['subject'];
  2448. $this->single_parts['include']['body'] = $data['body'];
  2449. $this->single_parts['include']['recipients'] = $REGX->xml_convert($this->convert_recipients($data['recipients'], 'string', 'screen_name'));
  2450. $this->single_parts['include']['cc'] = ($data['cc'] == '') ? '' : $REGX->xml_convert($this->convert_recipients($data['cc'], 'string', 'screen_name'));
  2451. $this->single_parts['include']['sender'] = $data['sender'];
  2452. $this->single_parts['include']['date'] = $data['date'];
  2453. $this->conditionals['attachments_exist'] = 'n';
  2454. if ($data['sender'] == $SESS->userdata['screen_name'] && isset($data['folder_id']) && $data['folder_id'] == 2)
  2455. {
  2456. $this->conditionals['show_cc'] = 'y';
  2457. }
  2458. elseif(in_array($this->member_id, explode(', ',$data['cc'])))
  2459. {
  2460. $this->conditionals['show_cc'] = 'y';
  2461. $this->single_parts['include']['cc'] = $SESS->userdata['screen_name'];
  2462. }
  2463. elseif($data['hide_cc'] == 'y' OR $data['cc'] == '')
  2464. {
  2465. $this->conditionals['show_cc'] = 'n';
  2466. }
  2467. else
  2468. {
  2469. $this->conditionals['show_cc'] = 'y';
  2470. }
  2471. /** -----------------------------------
  2472. /** Prepare Attachments for Display
  2473. /** -----------------------------------*/
  2474. $this->conditionals['attachments_exist'] = (sizeof($data['attachments']) > 0) ? 'y' : 'n';
  2475. $this->single_parts['include']['attachment_links'] = (sizeof($data['attachments']) > 0) ? $this->_attachment_links($data['attachments']) : '';
  2476. // -----------------------------------
  2477. // Form Declaration
  2478. //
  2479. // NOTE: $data['id'] = $message_id
  2480. // -----------------------------------
  2481. $details = array('hidden_fields' => array('message_id' => $copy_id, 'toggle[]' => $copy_id, 'daction' => ''),
  2482. 'action' => $this->_create_path('modify_messages'),
  2483. 'id' => 'target',
  2484. 'enctype' => 'multi',
  2485. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  2486. );
  2487. $this->single_parts['form']['form_declaration']['view_message'] = $FNS->form_declaration($details);
  2488. /** -----------------------------------
  2489. /** Various Components
  2490. /** -----------------------------------*/
  2491. $this->current_folder = ( ! isset($data['folder_id'])) ? 'n' : $data['folder_id'];
  2492. $this->folders_pulldown();
  2493. $this->_buttons();
  2494. $this->single_parts['include']['hidden_js'] = $this->hidden_js();
  2495. /** ----------------------------------
  2496. /** Reduce exp_members.private_messages
  2497. /** ----------------------------------*/
  2498. if ($data['message_read'] == 'n' && $SESS->userdata['private_messages'] > 0)
  2499. {
  2500. $DB->query("UPDATE exp_members SET private_messages = private_messages - 1
  2501. WHERE member_id = '{$this->member_id}'");
  2502. $SESS->userdata['private_messages']--;
  2503. }
  2504. /** -----------------------------------
  2505. /** Tracking and Status
  2506. /** -----------------------------------*/
  2507. if ($data['message_read'] == 'n')
  2508. {
  2509. $udata = array('message_read' => 'y', 'message_time_read' => $LOC->now);
  2510. $DB->query($DB->update_string('exp_message_copies', $udata, "copy_id = {$copy_id}"));
  2511. }
  2512. /** ----------------------------------------
  2513. /** Return the Compose Form Contents
  2514. /** ----------------------------------------*/
  2515. $this->title = $LANG->line('private_message').' - '.$FNS->word_limiter($data['subject'], 10);
  2516. $this->crumb = $LANG->line('private_message');
  2517. $this->return_data = $this->_process_template($this->retrieve_template('view_message'));
  2518. }
  2519. /* END */
  2520. /** --------------------------------
  2521. /** Show Attachment
  2522. /** --------------------------------*/
  2523. function attachment()
  2524. {
  2525. global $IN, $DB, $LOC;
  2526. if ($this->allegiance == 'cp')
  2527. {
  2528. $attach_hash = $IN->GBL('aid');
  2529. }
  2530. else
  2531. {
  2532. $attach_hash = $this->cur_id;
  2533. }
  2534. /** ---------------------------
  2535. /** Valid ID?
  2536. /** ---------------------------*/
  2537. $query = $DB->query("SELECT attachment_location, attachment_name, attachment_extension, message_id
  2538. FROM exp_message_attachments WHERE attachment_hash = '".$DB->escape_str($attach_hash)."'");
  2539. if ($query->num_rows == 0)
  2540. {
  2541. exit;
  2542. }
  2543. /** ---------------------------
  2544. /** Attachment for User?
  2545. /** ---------------------------*/
  2546. $results = $DB->query("SELECT COUNT(*) AS count FROM exp_message_copies
  2547. WHERE message_id = '".$DB->escape_str($query->row['message_id'])."'
  2548. AND recipient_id = '{$this->member_id}'");
  2549. if ($results->row['count'] == 0)
  2550. {
  2551. exit;
  2552. }
  2553. $filepath = $query->row['attachment_location'];
  2554. $extension = strtolower(str_replace('.', '', $query->row['attachment_extension']));
  2555. if ($this->mimes == '')
  2556. {
  2557. include(PATH_LIB.'mimes.php');
  2558. $this->mimes = $mimes;
  2559. }
  2560. if ( ! file_exists($filepath) OR ! isset($this->mimes[$extension]))
  2561. {
  2562. exit;
  2563. }
  2564. $DB->query("UPDATE exp_message_copies SET attachment_downloaded = 'y'
  2565. WHERE message_id = '".$DB->escape_str($query->row['message_id'])."'
  2566. AND recipient_id = '{$this->member_id}'");
  2567. header('Content-Disposition: filename="'.$query->row['attachment_name'].'"');
  2568. header('Content-Type: '.$this->mimes[$extension]);
  2569. header('Content-Transfer-Encoding: binary');
  2570. header('Content-Length: '.filesize($filepath));
  2571. header('Last-Modified: '.gmdate('D, d M Y H:i:s', $LOC->now).' GMT');
  2572. if ( ! $fp = @fopen($filepath, 'rb'))
  2573. {
  2574. exit;
  2575. }
  2576. fpassthru($fp);
  2577. @fclose($fp);
  2578. exit;
  2579. }
  2580. /* END */
  2581. /** -----------------------------------
  2582. /** Buddies List
  2583. /** -----------------------------------*/
  2584. function buddies($message='')
  2585. {
  2586. global $LANG, $FNS, $DB;
  2587. $template = $this->retrieve_template('buddies_block_list');
  2588. $form_details = array('hidden_fields' => array('name' => '','description' => '', 'which' => 'buddy', 'daction' => ''),
  2589. 'action' => $this->_create_path('edit_list'),
  2590. 'id' => 'target',
  2591. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  2592. );
  2593. $this->single_parts['form']['form_declaration']['list'] = $FNS->form_declaration($form_details);
  2594. $this->single_parts['lang']['list_title'] = $LANG->line('buddy_list');
  2595. $this->single_parts['include']['toggle_js'] = $this->toggle_js();
  2596. $this->single_parts['include']['buddy_search_js'] = $this->buddy_search_js();
  2597. $this->single_parts['image']['search_glass'] = '<img src="'.$this->images_folder.'search_glass.gif" style="border: 0px" width="12" height="12" alt="'.$LANG->line('search_glass').'" />';
  2598. $this->single_parts['include']['member_search'] = '<a href="#" title="{lang:member_search}" onclick="buddy_search(1); return false;">'.$this->single_parts['image']['search_glass'].'</a>';
  2599. $this->single_parts['include']['list_rows'] = '';
  2600. $this->_buttons('y', 'n', 'n');
  2601. /** ----------------------------------------
  2602. /** Retrieve and Output List
  2603. /** ----------------------------------------*/
  2604. if ($this->buddies === FALSE)
  2605. {
  2606. $this->fetch_lists('buddy');
  2607. }
  2608. $list_size = sizeof($this->buddies);
  2609. if ($list_size == 0)
  2610. {
  2611. $this->single_parts['include']['list_rows'] .= $this->_process_template($this->retrieve_template('empty_list'));
  2612. }
  2613. else
  2614. {
  2615. $rows = $this->retrieve_template('buddies_block_row');
  2616. for($i=0; $i < $list_size; ++$i)
  2617. {
  2618. $this->single_parts['style'] = ($i % 2) ? 'tableCellOne' : 'tableCellTwo';
  2619. $this->single_parts['screen_name'] = $this->buddies[$i]['2'];
  2620. $this->single_parts['member_description'] = $this->buddies[$i]['3'];
  2621. $this->single_parts['listed_id'] = $this->buddies[$i]['4'];
  2622. if ($this->allegiance == 'user')
  2623. {
  2624. $this->single_parts['path']['send_pm'] = $this->_create_path('pm').$this->buddies[$i]['5'].'/';
  2625. }
  2626. else
  2627. {
  2628. $this->single_parts['path']['send_pm'] = $this->_create_path('pm').AMP.'mid='.$this->buddies[$i]['5'];
  2629. }
  2630. $this->single_parts['include']['list_rows'] .= $this->_process_template($rows);
  2631. }
  2632. }
  2633. /** ----------------------------------------
  2634. /** Return the Trackable Messages
  2635. /** ----------------------------------------*/
  2636. $this->title = $LANG->line('buddy_list');
  2637. $this->crumb = $LANG->line('buddy_list');
  2638. $this->return_data = $this->_process_template($template);
  2639. }
  2640. /* END */
  2641. /** -----------------------------------
  2642. /** Bulletin Board
  2643. /** -----------------------------------*/
  2644. function bulletin_board($message='')
  2645. {
  2646. global $LANG, $DB, $OUT, $IN, $LOC, $SESS, $PREFS;
  2647. $DB->query("UPDATE exp_members SET last_view_bulletins = '".$LOC->now."' WHERE member_id = '{$this->member_id}'");
  2648. $this->title = $LANG->line('bulletin_board');
  2649. $this->crumb = $LANG->line('bulletin_board');
  2650. $this->conditionals['bulletins'] = 'n';
  2651. $this->conditionals['no_bulletins'] = 'y';
  2652. $this->conditionals['paginate'] = 'n';
  2653. $this->conditionals['can_post_bulletin'] = ($SESS->userdata['can_send_bulletins'] == 'y') ? 'y' : 'n';
  2654. $this->single_parts['include']['message'] = $message;
  2655. $this->conditionals['message'] = ($message != '') ? 'y' : 'n';
  2656. $this->single_parts['path']['send_bulletin'] = $this->_create_path('send_bulletin');
  2657. /** ---------------------------------------
  2658. /** Retrieve Bulletins
  2659. /** ---------------------------------------*/
  2660. $dql = "SELECT m.screen_name, b.sender_id, b.bulletin_message, b.bulletin_date, b.bulletin_id ";
  2661. $sql = "FROM exp_member_bulletin_board b, exp_members m
  2662. WHERE b.sender_id = m.member_id
  2663. AND b.bulletin_group = ".$DB->escape_str($SESS->userdata['group_id'])."
  2664. AND bulletin_date < ".$LOC->now."
  2665. AND
  2666. (
  2667. b.bulletin_expires > ".$LOC->now."
  2668. OR
  2669. b.bulletin_expires = 0
  2670. )
  2671. ORDER BY b.bulletin_date DESC";
  2672. /** ----------------------------------------
  2673. /** Run "count" query for pagination
  2674. /** ----------------------------------------*/
  2675. $query = $DB->query("SELECT COUNT(b.bulletin_id) AS count ".$sql);
  2676. /** ----------------------------------------
  2677. /** If No Messages, we say so.
  2678. /** ----------------------------------------*/
  2679. if ($query->row['count'] == 0)
  2680. {
  2681. $this->single_parts['include']['bulletins'] = $LANG->line('message_no_bulletins');
  2682. $this->return_data = $this->_process_template($this->retrieve_template('bulletin_board'));
  2683. return;
  2684. }
  2685. /** ----------------------------------------
  2686. /** Determine Current Page
  2687. /** ----------------------------------------*/
  2688. $row_count = 0; // How many rows shown this far (i.e. offset)
  2689. if ($this->allegiance == 'user')
  2690. {
  2691. $row_count = $this->cur_id;
  2692. }
  2693. else
  2694. {
  2695. $row_count = ($IN->GBL('page', 'GP') === false) ? 0 : $IN->GBL('page', 'GP');
  2696. }
  2697. if ( ! is_numeric($row_count))
  2698. {
  2699. $row_count = 0;
  2700. }
  2701. $this->per_page = 5;
  2702. $current_page = ($row_count / $this->per_page) + 1;
  2703. $total_pages = intval($query->row['count'] / $this->per_page);
  2704. if ($query->row['count'] % $this->per_page)
  2705. {
  2706. $total_pages++;
  2707. }
  2708. $this->single_parts['include']['page_count'] = $current_page.' '.$LANG->line('of').' '.$total_pages;
  2709. /** -----------------------------
  2710. /** Do we need pagination?
  2711. /** -----------------------------*/
  2712. $pager = '';
  2713. if ($query->row['count'] > $this->per_page)
  2714. {
  2715. if ( ! class_exists('Paginate'))
  2716. {
  2717. require PATH_CORE.'core.paginate'.EXT;
  2718. }
  2719. $PGR = new Paginate();
  2720. if ($this->allegiance == 'user')
  2721. {
  2722. $PGR->path = $this->base_url.'bulletin_board/';
  2723. }
  2724. else
  2725. {
  2726. $PGR->base_url = $this->base_url.'bulletin_board';
  2727. $PGR->qstr_var = 'page';
  2728. }
  2729. $PGR->total_count = $query->row['count'];
  2730. $PGR->per_page = $this->per_page;
  2731. $PGR->cur_page = $row_count;
  2732. $this->single_parts['include']['pagination_link'] = $PGR->show_links();
  2733. $this->conditionals['paginate'] = 'y';
  2734. $sql .= " LIMIT ".$row_count.", ".$this->per_page;
  2735. }
  2736. /** ----------------------------------------
  2737. /** Create Bulletins
  2738. /** ----------------------------------------*/
  2739. $this->conditionals['bulletins'] = 'y';
  2740. $this->conditionals['no_bulletins'] = 'n';
  2741. $folder_rows_template = $this->retrieve_template('bulletin');
  2742. $i = 0;
  2743. $r = '';
  2744. $censor = FALSE;
  2745. if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '')
  2746. {
  2747. $censor = TRUE;
  2748. if ( ! class_exists('Typography'))
  2749. {
  2750. require PATH_CORE.'core.typography'.EXT;
  2751. }
  2752. $TYPE = new Typography(0);
  2753. }
  2754. $query = $DB->query($dql.$sql);
  2755. if ($query->row['bulletin_date'] != $SESS->userdata['last_bulletin_date'])
  2756. {
  2757. $DB->query($DB->update_string('exp_members', array('last_bulletin_date' => $query->row['bulletin_date']), "group_id = '".$DB->escape_str($SESS->userdata['group_id'])."'"));
  2758. }
  2759. foreach($query->result as $row)
  2760. {
  2761. ++$i;
  2762. $data = $row;
  2763. $this->conditionals['can_delete_bulletin'] = ($SESS->userdata['group_id'] == 1 OR $row['sender_id'] == $SESS->userdata['member_id']) ? 'y' : 'n';
  2764. if ($this->allegiance == 'cp')
  2765. {
  2766. $this->single_parts['path']['delete_bulletin'] = $this->_create_path('delete_bulletin', AMP.'bulletin_id='.$row['bulletin_id']);
  2767. }
  2768. else
  2769. {
  2770. $this->single_parts['path']['delete_bulletin'] = $this->_create_path('delete_bulletin').$row['bulletin_id'].'/';
  2771. }
  2772. $data['bulletin_message'] = ($censor === FALSE) ? $data['bulletin_message'] : $TYPE->filter_censored_words($data['bulletin_message']);
  2773. $data['bulletin_sender'] = $row['screen_name'];
  2774. $data['bulletin_date'] = $LOC->set_human_time($row['bulletin_date']);
  2775. $data['style'] = ($i % 2) ? 'tableCellTwo' : 'tableCellOne';
  2776. $r .= $this->_process_template($folder_rows_template, $data);
  2777. }
  2778. $this->single_parts['include']['bulletins'] = $r;
  2779. /** ----------------------------------------
  2780. /** Return the Folder's Contents
  2781. /** ----------------------------------------*/
  2782. $this->return_data = $this->_process_template($this->retrieve_template('bulletin_board'));
  2783. }
  2784. /* END */
  2785. /** -----------------------------------
  2786. /** Delete a Bulletin
  2787. /** -----------------------------------*/
  2788. function delete_bulletin()
  2789. {
  2790. global $LANG, $DB, $IN, $SESS;
  2791. if ($this->allegiance == 'cp')
  2792. {
  2793. if ($IN->GBL('bulletin_id') === FALSE)
  2794. {
  2795. return $this->bulletin_board();
  2796. }
  2797. $this->cur_id = $IN->GBL('bulletin_id');
  2798. }
  2799. $sql = "SELECT b.sender_id, b.bulletin_id, b.hash
  2800. FROM exp_member_bulletin_board b
  2801. WHERE b.bulletin_id = '".$DB->escape_str($this->cur_id)."'";
  2802. $query = $DB->query($sql);
  2803. if ($query->num_rows == 0)
  2804. {
  2805. return $this->bulletin_board();
  2806. }
  2807. elseif($SESS->userdata['group_id'] != 1 && $query->row['sender_id'] != $SESS->userdata['member_id'])
  2808. {
  2809. return $this->bulletin_board();
  2810. }
  2811. $DB->query("DELETE FROM exp_member_bulletin_board WHERE hash = '".$DB->escape_str($query->row['hash'])."'");
  2812. return $this->bulletin_board($LANG->line('bulletin_deleted'));
  2813. }
  2814. /* END */
  2815. /** -----------------------------------
  2816. /** Send a Bulletin Form for Admins
  2817. /** -----------------------------------*/
  2818. function send_bulletin($message='')
  2819. {
  2820. global $LANG, $DB, $OUT, $IN, $LOC, $SESS, $FNS, $PREFS;
  2821. /** -----------------------------------
  2822. /** Nasty Little Hobbits! No Sending!
  2823. /** -----------------------------------*/
  2824. if ($SESS->userdata['can_send_bulletins'] != 'y')
  2825. {
  2826. return FALSE;
  2827. }
  2828. $this->title = $LANG->line('send_bulletin');
  2829. $this->crumb = $LANG->line('send_bulletin');
  2830. /** ----------------------------------------
  2831. /** Some Form Data
  2832. /** ----------------------------------------*/
  2833. $form_details = array('action' => $this->base_url.'sending_bulletin',
  2834. 'id' => 'sending_bulletin',
  2835. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  2836. );
  2837. $this->single_parts['form']['form_declaration']['sending_bulletin'] = $FNS->form_declaration($form_details);
  2838. $this->single_parts['input']['bulletin_date'] = $LOC->set_human_time($LOC->now);
  2839. $this->single_parts['input']['bulletin_expires'] = $LOC->set_human_time($LOC->now + 30*24*60*60);
  2840. $this->single_parts['include']['message'] = $message;
  2841. $this->conditionals['message'] = ($message != '') ? 'y' : 'n';
  2842. // Member Group IDs
  2843. $english = array('Members', 'Super Admins');
  2844. $sql = "SELECT group_id, group_title FROM exp_member_groups WHERE site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND include_in_memberlist = 'y' AND group_id NOT IN ('2', '3', '4') ";
  2845. if ($SESS->userdata('group_id') != 1)
  2846. {
  2847. $sql .= "AND group_id != '1' ";
  2848. }
  2849. $sql .= " ORDER BY group_title";
  2850. $query = $DB->query($sql);
  2851. $menu = "<option value='0'>".$LANG->line('mbr_all_member_groups')."</option>\n";
  2852. foreach ($query->result as $row)
  2853. {
  2854. $group_title = $row['group_title'];
  2855. if (in_array($group_title, $english))
  2856. {
  2857. $group_title = $LANG->line(strtolower(str_replace(" ", "_", $group_title)));
  2858. }
  2859. $menu .= "<option value='".$row['group_id']."'>".$group_title."</option>\n";
  2860. }
  2861. $this->single_parts['group_id_options'] = $menu;
  2862. /** ----------------------------------------
  2863. /** Return the Parsed Template
  2864. /** ----------------------------------------*/
  2865. $this->return_data = $this->_process_template($this->retrieve_template('bulletin_form'));
  2866. }
  2867. /* END */
  2868. /** -----------------------------------
  2869. /** Send a Bulletin to Member Group
  2870. /** -----------------------------------*/
  2871. function sending_bulletin()
  2872. {
  2873. global $LANG, $DB, $LOC, $SESS, $FNS, $PREFS;
  2874. /** -----------------------------------
  2875. /** Nasty Little Hobbits! No Sending!
  2876. /** -----------------------------------*/
  2877. if ($SESS->userdata['can_send_bulletins'] != 'y')
  2878. {
  2879. return FALSE;
  2880. }
  2881. if ( ! isset($_POST['group_id']) OR ! is_numeric($_POST['group_id']))
  2882. {
  2883. return FALSE;
  2884. }
  2885. if ( ! isset($_POST['bulletin_message']) OR trim($_POST['bulletin_message']) == '')
  2886. {
  2887. return $this->send_bulletin();
  2888. }
  2889. /** ----------------------------------------
  2890. /** Valid Member Groups for User
  2891. /** ----------------------------------------*/
  2892. $sql = "SELECT group_id FROM exp_member_groups WHERE site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND include_in_memberlist = 'y' AND group_id NOT IN ('2', '3', '4') ";
  2893. if ($SESS->userdata('group_id') != 1)
  2894. {
  2895. $sql .= "AND group_id != '1' ";
  2896. }
  2897. $sql .= " ORDER BY group_title";
  2898. $query = $DB->query($sql);
  2899. $group = array();
  2900. foreach ($query->result as $row)
  2901. {
  2902. if ($_POST['group_id'] == '0' OR $_POST['group_id'] == $row['group_id'])
  2903. {
  2904. $groups[] = $row['group_id'];
  2905. }
  2906. }
  2907. /** ------------------------------
  2908. /** Suspicious use of non-valid group
  2909. /** ------------------------------*/
  2910. if (sizeof($groups) == 0)
  2911. {
  2912. return $this->send_bulletin();
  2913. }
  2914. $begins = $LOC->convert_human_date_to_gmt($_POST['bulletin_date']);
  2915. $expires = $LOC->convert_human_date_to_gmt($_POST['bulletin_expires']);
  2916. if ($begins == 0)
  2917. {
  2918. $begins = $LOC->now;
  2919. }
  2920. if ($expires == 0)
  2921. {
  2922. $expires = $LOC->now + 30*24*60*60;
  2923. }
  2924. $data = array( 'sender_id' => $this->member_id,
  2925. 'bulletin_date' => $begins,
  2926. 'hash' => $FNS->random('alpha', 10),
  2927. 'bulletin_expires' => $expires,
  2928. 'bulletin_message' => $_POST['bulletin_message']
  2929. );
  2930. foreach($groups as $group_id)
  2931. {
  2932. $data['bulletin_group'] = $group_id;
  2933. $DB->query($DB->insert_string('exp_member_bulletin_board', $data));
  2934. if ($LOC->now >= $begins)
  2935. {
  2936. $DB->query($DB->update_string('exp_members', array('last_bulletin_date' => $LOC->now), "group_id = '".$DB->escape_str($group_id)."'"));
  2937. }
  2938. }
  2939. /** ----------------------------------------
  2940. /** Return with Success Message
  2941. /** ----------------------------------------*/
  2942. $this->send_bulletin($LANG->line('bulletin_success'));
  2943. }
  2944. /* END */
  2945. /** -----------------------------------
  2946. /** Edit Buddies and Block Lists
  2947. /** -----------------------------------*/
  2948. function edit_list()
  2949. {
  2950. global $LANG, $IN, $FNS, $DB;
  2951. if ($IN->GBL('which') === FALSE OR $IN->GBL('which') == 'buddy')
  2952. {
  2953. $which = 'buddy';
  2954. }
  2955. else
  2956. {
  2957. $which = 'blocked';
  2958. }
  2959. /** -----------------------------------
  2960. /** Add to List
  2961. /** -----------------------------------*/
  2962. if ( ! $IN->GBL('toggle', 'POST'))
  2963. {
  2964. if ($IN->GBL('name') === FALSE OR $IN->GBL('description') === FALSE OR $IN->GBL('name') == '')
  2965. {
  2966. if ($which == 'blocked')
  2967. {
  2968. return $this->_error_page('missing_required_field');
  2969. }
  2970. else
  2971. {
  2972. return $this->_error_page('missing_required_field');
  2973. }
  2974. }
  2975. $person = $this->convert_recipients($IN->GBL('name'), 'array', 'member_id');
  2976. if (sizeof($person) == 0)
  2977. {
  2978. if ($which == 'blocked')
  2979. {
  2980. return $this->_error_page('invalid_username');
  2981. }
  2982. else
  2983. {
  2984. return $this->_error_page('invalid_username');
  2985. }
  2986. }
  2987. $data = array('member_id' => $this->member_id,
  2988. 'listed_description' => $FNS->char_limiter($_POST['description'], 50),
  2989. 'listed_type' => $which);
  2990. for ($i=0, $s = sizeof($person); $i < $s; ++$i)
  2991. {
  2992. if ($this->member_id == $person[$i])
  2993. {
  2994. return $this->_error_page('invalid_username');
  2995. }
  2996. elseif($which == 'buddy' && sizeof($this->goodies) > 0 && in_array($person[$i], $this->goodies))
  2997. {
  2998. return $this->_error_page('invalid_username');
  2999. }
  3000. elseif($which == 'blocked' && sizeof($this->baddies) > 0 && in_array($person[$i], $this->baddies))
  3001. {
  3002. return $this->_error_page('invalid_username');
  3003. }
  3004. $data['listed_member'] = $person[$i];
  3005. $DB->query($DB->insert_string('exp_message_listed', $data));
  3006. if ($which == 'blocked')
  3007. {
  3008. $DB->query("DELETE FROM exp_message_copies
  3009. WHERE sender_id = '".$DB->escape_str($person[$i])."'
  3010. AND recipient_id = '{$this->member_id}'");
  3011. }
  3012. }
  3013. $this->fetch_lists($which);
  3014. if ($which == 'blocked')
  3015. {
  3016. return $this->blocked();
  3017. }
  3018. else
  3019. {
  3020. return $this->buddies();
  3021. }
  3022. }
  3023. /** -----------------------------------
  3024. /** Delete From List
  3025. /** -----------------------------------*/
  3026. foreach ($_POST as $key => $val)
  3027. {
  3028. if (strstr($key, 'toggle') AND ! is_array($val))
  3029. {
  3030. if ($IN->GBL('daction', 'POST') == 'delete')
  3031. {
  3032. $DB->query("DELETE FROM exp_message_listed
  3033. WHERE member_id = '{$this->member_id}'
  3034. AND listed_id = '".$DB->escape_str($val)."'");
  3035. }
  3036. }
  3037. }
  3038. if ($which == 'blocked')
  3039. {
  3040. return $this->blocked();
  3041. }
  3042. else
  3043. {
  3044. return $this->buddies();
  3045. }
  3046. }
  3047. /* END */
  3048. /** -----------------------------------
  3049. /** Add Buddy
  3050. /** -----------------------------------*/
  3051. function add_buddy()
  3052. {
  3053. global $IN;
  3054. if ($this->buddies === FALSE)
  3055. {
  3056. $this->fetch_lists('buddy');
  3057. }
  3058. return $this->add_list_member('buddy', ($this->allegiance == 'user') ? $this->cur_id : $IN->GBL('mid'));
  3059. }
  3060. /* END */
  3061. /** -----------------------------------
  3062. /** Add Naughty, Poo-poo head
  3063. /** -----------------------------------*/
  3064. function add_block()
  3065. {
  3066. global $IN;
  3067. if ($this->blocked === FALSE)
  3068. {
  3069. $this->fetch_lists('blocked');
  3070. }
  3071. return $this->add_list_member('blocked', ($this->allegiance == 'user') ? $this->cur_id : $IN->GBL('mid'));
  3072. }
  3073. /* END */
  3074. /** -----------------------------------
  3075. /** Add to Buddy or Block List
  3076. /** -----------------------------------*/
  3077. function add_list_member($which='buddy', $id='')
  3078. {
  3079. global $DB;
  3080. /** -----------------------------------
  3081. /** Add to List
  3082. /** -----------------------------------*/
  3083. if (empty($id))
  3084. {
  3085. if ($which == 'blocked')
  3086. {
  3087. return $this->blocked();
  3088. }
  3089. else
  3090. {
  3091. return $this->buddies();
  3092. }
  3093. }
  3094. $person = $this->convert_recipients($id, 'array', 'member_id');
  3095. if (sizeof($person) == 0)
  3096. {
  3097. if ($which == 'blocked')
  3098. {
  3099. return $this->blocked();
  3100. }
  3101. else
  3102. {
  3103. return $this->buddies();
  3104. }
  3105. }
  3106. $data = array('member_id' => $this->member_id,
  3107. 'listed_description' => '',
  3108. 'listed_type' => $which);
  3109. for ($i=0, $s = sizeof($person); $i < $s; ++$i)
  3110. {
  3111. if ($this->member_id == $person[$i])
  3112. {
  3113. continue;
  3114. }
  3115. elseif($which == 'buddy' && sizeof($this->goodies) > 0 && in_array($person[$i], $this->goodies))
  3116. {
  3117. continue;
  3118. }
  3119. elseif($which == 'blocked' && sizeof($this->baddies) > 0 && in_array($person[$i], $this->baddies))
  3120. {
  3121. continue;
  3122. }
  3123. $data['listed_member'] = $person[$i];
  3124. $DB->query($DB->insert_string('exp_message_listed', $data));
  3125. if ($which == 'blocked')
  3126. {
  3127. $DB->query("DELETE FROM exp_message_copies
  3128. WHERE sender_id = '".$DB->escape_str($person[$i])."'
  3129. AND recipient_id = '{$this->member_id}'");
  3130. }
  3131. }
  3132. $this->fetch_lists($which);
  3133. if ($which == 'blocked')
  3134. {
  3135. return $this->blocked();
  3136. }
  3137. else
  3138. {
  3139. return $this->buddies();
  3140. }
  3141. }
  3142. /* END */
  3143. /** -----------------------------------
  3144. /** Edit Block List
  3145. /** -----------------------------------*/
  3146. function blocked()
  3147. {
  3148. global $LANG, $FNS, $DB;
  3149. $template = $this->retrieve_template('buddies_block_list');
  3150. $form_details = array('hidden_fields' => array('name' => '','description' => '', 'which' => 'blocked', 'daction' => ''),
  3151. 'action' => $this->_create_path('edit_list'),
  3152. 'id' => 'target',
  3153. 'secure' => ($this->allegiance == 'cp') ? FALSE : TRUE
  3154. );
  3155. $this->single_parts['form']['form_declaration']['list'] = $FNS->form_declaration($form_details);
  3156. $this->single_parts['lang']['list_title'] = $LANG->line('blocked_list');
  3157. $this->single_parts['include']['toggle_js'] = $this->toggle_js();
  3158. $this->single_parts['include']['buddy_search_js'] = $this->buddy_search_js();
  3159. $this->single_parts['image']['search_glass'] = '<img src="'.$this->images_folder.'search_glass.gif" style="border: 0px" width="12" height="12" alt="'.$LANG->line('search_glass').'" />';
  3160. $this->single_parts['include']['member_search'] = '<a href="#" title="{lang:member_search}" onclick="buddy_search(2); return false;">'.$this->single_parts['image']['search_glass'].'</a>';
  3161. $this->single_parts['include']['list_rows'] = '';
  3162. $this->_buttons('y', 'n', 'n');
  3163. /** ----------------------------------------
  3164. /** Retrieve and Output List
  3165. /** ----------------------------------------*/
  3166. if ($this->blocked === FALSE)
  3167. {
  3168. $this->fetch_lists('blocked');
  3169. }
  3170. $list_size = sizeof($this->blocked);
  3171. if ($list_size == 0)
  3172. {
  3173. $this->single_parts['include']['list_rows'] .= $this->_process_template($this->retrieve_template('empty_list'));
  3174. }
  3175. else
  3176. {
  3177. $rows = $this->retrieve_template('buddies_block_row');
  3178. for($i=0; $i < $list_size; ++$i)
  3179. {
  3180. $this->single_parts['style'] = ($i % 2) ? 'tableCellOne' : 'tableCellTwo';
  3181. $this->single_parts['screen_name'] = $this->blocked[$i]['2'];
  3182. $this->single_parts['member_description'] = $this->blocked[$i]['3'];
  3183. $this->single_parts['listed_id'] = $this->blocked[$i]['4'];
  3184. if ($this->allegiance == 'user')
  3185. {
  3186. $this->single_parts['path']['send_pm'] = $this->_create_path('pm').$this->buddies[$i]['5'].'/';
  3187. }
  3188. else
  3189. {
  3190. $this->single_parts['path']['send_pm'] = $this->_create_path('pm').AMP.'mid='.$this->buddies[$i]['5'];
  3191. }
  3192. $this->single_parts['include']['list_rows'] .= $this->_process_template($rows);
  3193. }
  3194. }
  3195. /** ----------------------------------------
  3196. /** Return the Trackable Messages
  3197. /** ----------------------------------------*/
  3198. $this->title = $LANG->line('blocked_list');
  3199. $this->crumb = $LANG->line('blocked_list');
  3200. $this->return_data = $this->_process_template($template);
  3201. }
  3202. /* END */
  3203. /** --------------------------------
  3204. /** Generate Error Page
  3205. /** --------------------------------*/
  3206. function _error_page($msg = 'not_authorized', $replace = array())
  3207. {
  3208. global $LANG;
  3209. $error = ( ! isset($LANG->language[$msg])) ? $msg : $LANG->line($msg);
  3210. if (sizeof($replace) > 0)
  3211. {
  3212. foreach($replace as $key => $value)
  3213. {
  3214. $error = str_replace($key, $value, $error);
  3215. }
  3216. }
  3217. $this->single_parts['lang']['heading'] = $LANG->line('error');
  3218. $this->single_parts['lang']['message'] = $error;
  3219. $this->title = $LANG->line('error');
  3220. $this->crumb = $LANG->line('error');
  3221. $this->return_data = $this->_process_template($this->retrieve_template('message_error'));
  3222. return;
  3223. }
  3224. /* END */
  3225. // -----------------------------------
  3226. // Maintenance
  3227. // This is where we do some automatic
  3228. // stuff such as erasing old and deleted messages
  3229. // -----------------------------------
  3230. function maintenance()
  3231. {
  3232. global $DB, $LOC;
  3233. $deletion_time = $LOC->now - ($this->delete_expiration*24*60*60);
  3234. // Erase old deleted messages
  3235. $query = $DB->query("SELECT copy_id FROM exp_message_copies
  3236. WHERE recipient_id = '{$this->member_id}'
  3237. AND message_deleted = 'y'
  3238. AND message_time_read < $deletion_time");
  3239. if ($query->num_rows > 0)
  3240. {
  3241. $delete = array();
  3242. foreach($query->result as $row)
  3243. {
  3244. $delete[] = $row['copy_id'];
  3245. }
  3246. $this->erase($delete);
  3247. }
  3248. // Erase old, unused sent messages
  3249. $query = $DB->query("SELECT d.message_id FROM exp_message_data d
  3250. LEFT JOIN exp_message_copies c ON (d.message_id = c.message_id)
  3251. WHERE d.sender_id = '{$this->member_id}'
  3252. AND d.message_status = 'sent'
  3253. AND d.message_date < $deletion_time
  3254. AND c.message_id IS NULL");;
  3255. if ($query->num_rows > 0)
  3256. {
  3257. $delete = array();
  3258. foreach($query->result as $row)
  3259. {
  3260. $delete[] = $row['message_id'];
  3261. }
  3262. if (sizeof($delete) > 0)
  3263. {
  3264. $DB->query("DELETE FROM exp_message_data WHERE message_id IN ('".implode("','", $delete)."')");
  3265. }
  3266. }
  3267. }
  3268. /* END */
  3269. /** -----------------------------------
  3270. /** JavaScript for Move Button
  3271. /** -----------------------------------*/
  3272. function hidden_js()
  3273. {
  3274. $str = <<<MRT
  3275. <script type="text/javascript">
  3276. //<![CDATA[
  3277. // ===================================================================
  3278. // Author: Matt Kruse <matt@mattkruse.com>
  3279. // WWW: http://www.mattkruse.com/
  3280. //
  3281. // NOTICE: You may use this code for any purpose, commercial or
  3282. // private, without any further permission from the author. You may
  3283. // remove this notice from your final code if you wish, however it is
  3284. // appreciated by the author if at least my web site address is kept.
  3285. //
  3286. // You may *NOT* re-distribute this code in any way except through its
  3287. // use. That means, you can include it in your product, or your web
  3288. // site, or any other form where the code is actually being used. You
  3289. // may not put the plain javascript up on your site for download or
  3290. // include it in your javascript libraries for download.
  3291. // If you wish to share this code with others, please just point them
  3292. // to the URL instead.
  3293. // Please DO NOT link directly to my .js files from your site. Copy
  3294. // the files to your server and use them there. Thank you.
  3295. // ===================================================================
  3296. /* SOURCE FILE: AnchorPosition.js */
  3297. /*
  3298. AnchorPosition.js
  3299. Author: Matt Kruse
  3300. Last modified: 10/11/02
  3301. DESCRIPTION: These functions find the position of an <A> tag in a document,
  3302. so other elements can be positioned relative to it.
  3303. COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small
  3304. positioning errors - usually with Window positioning - occur on the
  3305. Macintosh platform.
  3306. FUNCTIONS:
  3307. getAnchorPosition(anchorname)
  3308. Returns an Object() having .x and .y properties of the pixel coordinates
  3309. of the upper-left corner of the anchor. Position is relative to the PAGE.
  3310. getAnchorWindowPosition(anchorname)
  3311. Returns an Object() having .x and .y properties of the pixel coordinates
  3312. of the upper-left corner of the anchor, relative to the WHOLE SCREEN.
  3313. NOTES:
  3314. 1) For popping up separate browser windows, use getAnchorWindowPosition.
  3315. Otherwise, use getAnchorPosition
  3316. 2) Your anchor tag MUST contain both NAME and ID attributes which are the
  3317. same. For example:
  3318. <A NAME="test" ID="test"> </A>
  3319. 3) There must be at least a space between <A> </A> for IE5.5 to see the
  3320. anchor tag correctly. Do not do <A></A> with no space.
  3321. */
  3322. // getAnchorPosition(anchorname)
  3323. // This function returns an object having .x and .y properties which are the coordinates
  3324. // of the named anchor, relative to the page.
  3325. function getAnchorPosition(anchorname) {
  3326. // This function will return an Object with x and y properties
  3327. var useWindow=false;
  3328. var coordinates=new Object();
  3329. var x=0,y=0;
  3330. // Browser capability sniffing
  3331. var use_gebi=false, use_css=false, use_layers=false;
  3332. if (document.getElementById) { use_gebi=true; }
  3333. else if (document.all) { use_css=true; }
  3334. else if (document.layers) { use_layers=true; }
  3335. // Logic to find position
  3336. if (use_gebi && document.all) {
  3337. x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
  3338. y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
  3339. }
  3340. else if (use_gebi) {
  3341. var o=document.getElementById(anchorname);
  3342. x=AnchorPosition_getPageOffsetLeft(o);
  3343. y=AnchorPosition_getPageOffsetTop(o);
  3344. }
  3345. else if (use_css) {
  3346. x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
  3347. y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
  3348. }
  3349. else if (use_layers) {
  3350. var found=0;
  3351. for (var i=0; i<document.anchors.length; i++) {
  3352. if (document.anchors[i].name==anchorname) { found=1; break; }
  3353. }
  3354. if (found==0) {
  3355. coordinates.x=0; coordinates.y=0; return coordinates;
  3356. }
  3357. x=document.anchors[i].x;
  3358. y=document.anchors[i].y;
  3359. }
  3360. else {
  3361. coordinates.x=0; coordinates.y=0; return coordinates;
  3362. }
  3363. coordinates.x=x;
  3364. coordinates.y=y;
  3365. return coordinates;
  3366. }
  3367. // getAnchorWindowPosition(anchorname)
  3368. // This function returns an object having .x and .y properties which are the coordinates
  3369. // of the named anchor, relative to the window
  3370. function getAnchorWindowPosition(anchorname) {
  3371. var coordinates=getAnchorPosition(anchorname);
  3372. var x=0;
  3373. var y=0;
  3374. if (document.getElementById) {
  3375. if (isNaN(window.screenX)) {
  3376. x=coordinates.x-document.body.scrollLeft+window.screenLeft;
  3377. y=coordinates.y-document.body.scrollTop+window.screenTop;
  3378. }
  3379. else {
  3380. x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
  3381. y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
  3382. }
  3383. }
  3384. else if (document.all) {
  3385. x=coordinates.x-document.body.scrollLeft+window.screenLeft;
  3386. y=coordinates.y-document.body.scrollTop+window.screenTop;
  3387. }
  3388. else if (document.layers) {
  3389. x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
  3390. y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
  3391. }
  3392. coordinates.x=x;
  3393. coordinates.y=y;
  3394. return coordinates;
  3395. }
  3396. // Functions for IE to get position of an object
  3397. function AnchorPosition_getPageOffsetLeft (el) {
  3398. var ol=el.offsetLeft;
  3399. while ((el=el.offsetParent) != null) { ol += el.offsetLeft; }
  3400. return ol;
  3401. }
  3402. function AnchorPosition_getWindowOffsetLeft (el) {
  3403. return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
  3404. }
  3405. function AnchorPosition_getPageOffsetTop (el) {
  3406. var ot=el.offsetTop;
  3407. while((el=el.offsetParent) != null) { ot += el.offsetTop; }
  3408. return ot;
  3409. }
  3410. function AnchorPosition_getWindowOffsetTop (el) {
  3411. return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
  3412. }
  3413. /* SOURCE FILE: PopupWindow.js */
  3414. /*
  3415. PopupWindow.js
  3416. Author: Matt Kruse
  3417. Last modified: 02/16/04
  3418. DESCRIPTION: This object allows you to easily and quickly popup a window
  3419. in a certain place. The window can either be a DIV or a separate browser
  3420. window.
  3421. COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
  3422. positioning errors - usually with Window positioning - occur on the
  3423. Macintosh platform. Due to bugs in Netscape 4.x, populating the popup
  3424. window with <STYLE> tags may cause errors.
  3425. USAGE:
  3426. // Create an object for a WINDOW popup
  3427. var win = new PopupWindow();
  3428. // Create an object for a DIV window using the DIV named 'mydiv'
  3429. var win = new PopupWindow('mydiv');
  3430. // Set the window to automatically hide itself when the user clicks
  3431. // anywhere else on the page except the popup
  3432. win.autoHide();
  3433. // Show the window relative to the anchor name passed in
  3434. win.showPopup(anchorname);
  3435. // Hide the popup
  3436. win.hidePopup();
  3437. // Set the size of the popup window (only applies to WINDOW popups
  3438. win.setSize(width,height);
  3439. // Populate the contents of the popup window that will be shown. If you
  3440. // change the contents while it is displayed, you will need to refresh()
  3441. win.populate(string);
  3442. // set the URL of the window, rather than populating its contents
  3443. // manually
  3444. win.setUrl("http://www.site.com/");
  3445. // Refresh the contents of the popup
  3446. win.refresh();
  3447. // Specify how many pixels to the right of the anchor the popup will appear
  3448. win.offsetX = 50;
  3449. // Specify how many pixels below the anchor the popup will appear
  3450. win.offsetY = 100;
  3451. NOTES:
  3452. 1) Requires the functions in AnchorPosition.js
  3453. 2) Your anchor tag MUST contain both NAME and ID attributes which are the
  3454. same. For example:
  3455. <A NAME="test" ID="test"> </A>
  3456. 3) There must be at least a space between <A> </A> for IE5.5 to see the
  3457. anchor tag correctly. Do not do <A></A> with no space.
  3458. 4) When a PopupWindow object is created, a handler for 'onmouseup' is
  3459. attached to any event handler you may have already defined. Do NOT define
  3460. an event handler for 'onmouseup' after you define a PopupWindow object or
  3461. the autoHide() will not work correctly.
  3462. */
  3463. // Set the position of the popup window based on the anchor
  3464. function PopupWindow_getXYPosition(anchorname) {
  3465. var coordinates;
  3466. if (this.type == "WINDOW") {
  3467. coordinates = getAnchorWindowPosition(anchorname);
  3468. }
  3469. else {
  3470. coordinates = getAnchorPosition(anchorname);
  3471. }
  3472. this.x = coordinates.x;
  3473. this.y = coordinates.y;
  3474. }
  3475. // Set width/height of DIV/popup window
  3476. function PopupWindow_setSize(width,height) {
  3477. this.width = width;
  3478. this.height = height;
  3479. }
  3480. // Fill the window with contents
  3481. function PopupWindow_populate(contents) {
  3482. this.contents = contents;
  3483. this.populated = false;
  3484. }
  3485. // Set the URL to go to
  3486. function PopupWindow_setUrl(url) {
  3487. this.url = url;
  3488. }
  3489. // Set the window popup properties
  3490. function PopupWindow_setWindowProperties(props) {
  3491. this.windowProperties = props;
  3492. }
  3493. // Refresh the displayed contents of the popup
  3494. function PopupWindow_refresh() {
  3495. if (this.divName != null) {
  3496. // refresh the DIV object
  3497. if (this.use_gebi) {
  3498. document.getElementById(this.divName).innerHTML = this.contents;
  3499. }
  3500. else if (this.use_css) {
  3501. document.all[this.divName].innerHTML = this.contents;
  3502. }
  3503. else if (this.use_layers) {
  3504. var d = document.layers[this.divName];
  3505. d.document.open();
  3506. d.document.writeln(this.contents);
  3507. d.document.close();
  3508. }
  3509. }
  3510. else {
  3511. if (this.popupWindow != null && !this.popupWindow.closed) {
  3512. if (this.url!="") {
  3513. this.popupWindow.location.href=this.url;
  3514. }
  3515. else {
  3516. this.popupWindow.document.open();
  3517. this.popupWindow.document.writeln(this.contents);
  3518. this.popupWindow.document.close();
  3519. }
  3520. this.popupWindow.focus();
  3521. }
  3522. }
  3523. }
  3524. // Position and show the popup, relative to an anchor object
  3525. function PopupWindow_showPopup(anchorname) {
  3526. this.getXYPosition(anchorname);
  3527. this.x += this.offsetX;
  3528. this.y += this.offsetY;
  3529. if (!this.populated && (this.contents != "")) {
  3530. this.populated = true;
  3531. this.refresh();
  3532. }
  3533. if (this.divName != null) {
  3534. // Show the DIV object
  3535. if (this.use_gebi) {
  3536. document.getElementById(this.divName).style.left = this.x + "px";
  3537. document.getElementById(this.divName).style.top = this.y + "px";
  3538. document.getElementById(this.divName).style.visibility = "visible";
  3539. }
  3540. else if (this.use_css) {
  3541. document.all[this.divName].style.left = this.x;
  3542. document.all[this.divName].style.top = this.y;
  3543. document.all[this.divName].style.visibility = "visible";
  3544. }
  3545. else if (this.use_layers) {
  3546. document.layers[this.divName].left = this.x;
  3547. document.layers[this.divName].top = this.y;
  3548. document.layers[this.divName].visibility = "visible";
  3549. }
  3550. }
  3551. else {
  3552. if (this.popupWindow == null || this.popupWindow.closed) {
  3553. // If the popup window will go off-screen, move it so it doesn't
  3554. if (this.x<0) { this.x=0; }
  3555. if (this.y<0) { this.y=0; }
  3556. if (screen && screen.availHeight) {
  3557. if ((this.y + this.height) > screen.availHeight) {
  3558. this.y = screen.availHeight - this.height;
  3559. }
  3560. }
  3561. if (screen && screen.availWidth) {
  3562. if ((this.x + this.width) > screen.availWidth) {
  3563. this.x = screen.availWidth - this.width;
  3564. }
  3565. }
  3566. var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
  3567. this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
  3568. }
  3569. this.refresh();
  3570. }
  3571. }
  3572. // Hide the popup
  3573. function PopupWindow_hidePopup() {
  3574. if (this.divName != null) {
  3575. if (this.use_gebi) {
  3576. document.getElementById(this.divName).style.visibility = "hidden";
  3577. }
  3578. else if (this.use_css) {
  3579. document.all[this.divName].style.visibility = "hidden";
  3580. }
  3581. else if (this.use_layers) {
  3582. document.layers[this.divName].visibility = "hidden";
  3583. }
  3584. }
  3585. else {
  3586. if (this.popupWindow && !this.popupWindow.closed) {
  3587. this.popupWindow.close();
  3588. this.popupWindow = null;
  3589. }
  3590. }
  3591. }
  3592. // Pass an event and return whether or not it was the popup DIV that was clicked
  3593. function PopupWindow_isClicked(e) {
  3594. if (this.divName != null) {
  3595. if (this.use_layers) {
  3596. var clickX = e.pageX;
  3597. var clickY = e.pageY;
  3598. var t = document.layers[this.divName];
  3599. if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
  3600. return true;
  3601. }
  3602. else { return false; }
  3603. }
  3604. else if (document.all) { // Need to hard-code this to trap IE for error-handling
  3605. var t = window.event.srcElement;
  3606. while (t.parentElement != null) {
  3607. if (t.id==this.divName) {
  3608. return true;
  3609. }
  3610. t = t.parentElement;
  3611. }
  3612. return false;
  3613. }
  3614. else if (this.use_gebi && e) {
  3615. var t = e.originalTarget;
  3616. try {while (t.parentNode != null) {
  3617. if (t.id==this.divName) {
  3618. return true;
  3619. }
  3620. t = t.parentNode;
  3621. } } catch(g) {}
  3622. return false;
  3623. }
  3624. return false;
  3625. }
  3626. return false;
  3627. }
  3628. // Check an onmouseDown event to see if we should hide
  3629. function PopupWindow_hideIfNotClicked(e) {
  3630. if (this.autoHideEnabled && !this.isClicked(e)) {
  3631. this.hidePopup();
  3632. }
  3633. }
  3634. // Call this to make the DIV disable automatically when mouse is clicked outside it
  3635. function PopupWindow_autoHide() {
  3636. this.autoHideEnabled = true;
  3637. }
  3638. // This global function checks all PopupWindow objects onmouseup to see if they should be hidden
  3639. function PopupWindow_hidePopupWindows(e) {
  3640. for (var i=0; i<popupWindowObjects.length; i++) {
  3641. if (popupWindowObjects[i] != null) {
  3642. var p = popupWindowObjects[i];
  3643. p.hideIfNotClicked(e);
  3644. }
  3645. }
  3646. }
  3647. // Run this immediately to attach the event listener
  3648. function PopupWindow_attachListener() {
  3649. if (document.layers) {
  3650. document.captureEvents(Event.MOUSEUP);
  3651. }
  3652. window.popupWindowOldEventListener = document.onmouseup;
  3653. if (window.popupWindowOldEventListener != null) {
  3654. document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
  3655. }
  3656. else {
  3657. document.onmouseup = PopupWindow_hidePopupWindows;
  3658. }
  3659. }
  3660. // CONSTRUCTOR for the PopupWindow object
  3661. // Pass it a DIV name to use a DHTML popup, otherwise will default to window popup
  3662. function PopupWindow() {
  3663. if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }
  3664. if (!window.popupWindowObjects) { window.popupWindowObjects = new Array(); }
  3665. if (!window.listenerAttached) {
  3666. window.listenerAttached = true;
  3667. PopupWindow_attachListener();
  3668. }
  3669. this.index = popupWindowIndex++;
  3670. popupWindowObjects[this.index] = this;
  3671. this.divName = null;
  3672. this.popupWindow = null;
  3673. this.width=0;
  3674. this.height=0;
  3675. this.populated = false;
  3676. this.visible = false;
  3677. this.autoHideEnabled = false;
  3678. this.contents = "";
  3679. this.url="";
  3680. this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
  3681. if (arguments.length>0) {
  3682. this.type="DIV";
  3683. this.divName = arguments[0];
  3684. }
  3685. else {
  3686. this.type="WINDOW";
  3687. }
  3688. this.use_gebi = false;
  3689. this.use_css = false;
  3690. this.use_layers = false;
  3691. if (document.getElementById) { this.use_gebi = true; }
  3692. else if (document.all) { this.use_css = true; }
  3693. else if (document.layers) { this.use_layers = true; }
  3694. else { this.type = "WINDOW"; }
  3695. this.offsetX = 0;
  3696. this.offsetY = 0;
  3697. // Method mappings
  3698. this.getXYPosition = PopupWindow_getXYPosition;
  3699. this.populate = PopupWindow_populate;
  3700. this.setUrl = PopupWindow_setUrl;
  3701. this.setWindowProperties = PopupWindow_setWindowProperties;
  3702. this.refresh = PopupWindow_refresh;
  3703. this.showPopup = PopupWindow_showPopup;
  3704. this.hidePopup = PopupWindow_hidePopup;
  3705. this.setSize = PopupWindow_setSize;
  3706. this.isClicked = PopupWindow_isClicked;
  3707. this.autoHide = PopupWindow_autoHide;
  3708. this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
  3709. }
  3710. //]]>
  3711. </script>
  3712. <script type="text/javascript">
  3713. //<![CDATA[
  3714. var move_visible = 'n';
  3715. var copy_visible = 'n';
  3716. function dynamic_move()
  3717. {
  3718. if (move_visible == 'y')
  3719. {
  3720. move_visible = 'n';
  3721. movepopup.hidePopup();
  3722. }
  3723. else
  3724. {
  3725. copypopup.hidePopup();
  3726. copy_visible = 'n';
  3727. document.getElementById('target').copyto.options['0'].selected = 'none';
  3728. movepopup.showPopup('move');
  3729. move_visible = 'y';
  3730. }
  3731. dynamic_action('move');
  3732. }
  3733. function dynamic_copy()
  3734. {
  3735. if (copy_visible == 'y')
  3736. {
  3737. copy_visible = 'n';
  3738. copypopup.hidePopup();
  3739. }
  3740. else
  3741. {
  3742. movepopup.hidePopup();
  3743. move_visible = 'n';
  3744. document.getElementById('target').moveto.options['0'].selected = 'none';
  3745. copypopup.showPopup('copy');
  3746. copy_visible = 'y';
  3747. }
  3748. dynamic_action('copy');
  3749. }
  3750. function dynamic_action(which)
  3751. {
  3752. if (document.getElementById('target').daction)
  3753. {
  3754. document.getElementById('target').daction.value = which;
  3755. }
  3756. }
  3757. function dynamic_emoticons()
  3758. {
  3759. emoticonspopup.showPopup('emoticons');
  3760. }
  3761. //]]>
  3762. </script>
  3763. MRT;
  3764. return $str;
  3765. }
  3766. /* END */
  3767. /** -----------------------------------
  3768. /** Show Hide JS
  3769. /** -----------------------------------*/
  3770. function showhide_js()
  3771. {
  3772. global $PREFS;
  3773. $prefix = ( ! $PREFS->ini('cookie_prefix')) ? 'exp_' : $PREFS->ini('cookie_prefix').'_';
  3774. $path = ( ! $PREFS->ini('cookie_path')) ? '/' : $PREFS->ini('cookie_path');
  3775. $domain = ( ! $PREFS->ini('cookie_domain')) ? '' : $PREFS->ini('cookie_domain');
  3776. $domain = ($domain == '') ? '' : 'domain='.$domain;
  3777. $str = <<<EOT
  3778. <script type="text/javascript">
  3779. //<![CDATA[
  3780. function showHide(entryID, htmlObj)
  3781. {
  3782. extTextDivID = ('extText' + (entryID));
  3783. extLinkDivID = ('extLink' + (entryID));
  3784. if (document.getElementById(extTextDivID).style.display == 'none')
  3785. {
  3786. document.getElementById(extTextDivID).style.display = "block";
  3787. document.getElementById(extLinkDivID).innerHTML = "[-]";
  3788. document.cookie = "{$prefix}myaccount_messages=on;{$domain};path={$path};";
  3789. }
  3790. else
  3791. {
  3792. document.getElementById(extTextDivID).style.display = "none";
  3793. document.getElementById(extLinkDivID).innerHTML = "[+]";
  3794. document.cookie = "{$prefix}myaccount_messages=off;{$domain};path={$path};";
  3795. }
  3796. }
  3797. //]]>
  3798. </script>
  3799. EOT;
  3800. return $str;
  3801. }
  3802. /* END */
  3803. /** -----------------------------------------------------------
  3804. /** Emoticons
  3805. /** -----------------------------------------------------------*/
  3806. function emoticons()
  3807. {
  3808. global $PREFS;
  3809. $r = '';
  3810. if ( ! is_file(PATH_MOD.'emoticon/emoticons'.EXT))
  3811. {
  3812. return $r;
  3813. }
  3814. else
  3815. {
  3816. require PATH_MOD.'emoticon/emoticons'.EXT;
  3817. }
  3818. if ( ! is_array($smileys))
  3819. {
  3820. return $r;
  3821. }
  3822. $path = $PREFS->ini('emoticon_path', 1);
  3823. $i = 1;
  3824. $dups = array();
  3825. foreach ($smileys as $key => $val)
  3826. {
  3827. if ($i == 1 AND substr($r, -5) != "<tr>\n")
  3828. {
  3829. $r .= "<tr>\n";
  3830. }
  3831. if (in_array($smileys[$key]['0'], $dups))
  3832. {
  3833. continue;
  3834. }
  3835. $r .= "<td><a href=\"javascript:void(0);\" onclick=\"return add_smiley('".$key."');return false;\"><img src=\"".$path.$smileys[$key]['0']."\" width=\"".$smileys[$key]['1']."\" height=\"".$smileys[$key]['2']."\" alt=\"".$smileys[$key]['3']."\" style=\"border: 0px;\" /></a></td>\n";
  3836. $dups[] = $smileys[$key]['0'];
  3837. if ($i == $this->emoticons_per_row)
  3838. {
  3839. $r .= "</tr>\n";
  3840. $i = 1;
  3841. }
  3842. else
  3843. {
  3844. $i++;
  3845. }
  3846. }
  3847. $r = rtrim($r);
  3848. if (substr($r, -5) != "</tr>")
  3849. {
  3850. $r .= "</tr>\n";
  3851. }
  3852. return $r;
  3853. }
  3854. /* END */
  3855. /** -----------------------------------------
  3856. /** Base IFRAME for Spell Check
  3857. /** -----------------------------------------*/
  3858. function spellcheck_iframe()
  3859. {
  3860. if ( ! class_exists('Spellcheck'))
  3861. {
  3862. require PATH_CORE.'core.spellcheck'.EXT;
  3863. }
  3864. return Spellcheck::iframe();
  3865. }
  3866. /* END */
  3867. /** -----------------------------------------
  3868. /** Spell Check for Textareas
  3869. /** -----------------------------------------*/
  3870. function spellcheck()
  3871. {
  3872. if ( ! class_exists('Spellcheck'))
  3873. {
  3874. require PATH_CORE.'core.spellcheck'.EXT;
  3875. }
  3876. return Spellcheck::check();
  3877. }
  3878. /* END */
  3879. /** --------------------------------
  3880. /** SpellCheck - JS
  3881. /** --------------------------------*/
  3882. function spellcheck_js()
  3883. {
  3884. if ( ! class_exists('Spellcheck'))
  3885. {
  3886. require PATH_CORE.'core.spellcheck'.EXT;
  3887. }
  3888. $SPELL = new Spellcheck();
  3889. $this->spellcheck_enabled = $SPELL->enabled;
  3890. return $SPELL->JavaScript($this->_create_path('spellcheck'), TRUE);
  3891. }
  3892. /* END */
  3893. /** --------------------------------
  3894. /** Submit Member to List - JS
  3895. /** --------------------------------*/
  3896. function list_js()
  3897. {
  3898. return <<<EWOK
  3899. <script type="text/javascript">
  3900. //<![CDATA[
  3901. function list_addition()
  3902. {
  3903. var member_text = '{lang:member_usernames}';
  3904. var member_description = '{lang:member_description} {lang:description_charlimit}';
  3905. var Name = prompt(member_text, '');
  3906. if ( ! Name || Name == null)
  3907. {
  3908. return;
  3909. }
  3910. var Description = prompt(member_description, '');
  3911. if ( ! Name || Name == null)
  3912. {
  3913. return;
  3914. }
  3915. document.getElementById('target').name.value = Name;
  3916. document.getElementById('target').description.value = Description;
  3917. document.getElementById('target').submit();
  3918. }
  3919. function dynamic_action(which)
  3920. {
  3921. if (document.getElementById('target').daction)
  3922. {
  3923. document.getElementById('target').daction.value = which;
  3924. }
  3925. }
  3926. //]]>
  3927. </script>
  3928. EWOK;
  3929. }
  3930. /* END */
  3931. // -----------------------------------
  3932. // JavaScript for Recipients and
  3933. // CC Field Member Search for Composing
  3934. // -----------------------------------
  3935. function search_js()
  3936. {
  3937. global $LANG, $PREFS, $SESS;
  3938. if ($this->allegiance == 'cp')
  3939. {
  3940. $s = ($PREFS->ini('admin_session_type') != 'c') ? $SESS->userdata['session_id'] : 0;
  3941. $url = $PREFS->ini('cp_url', FALSE).'?S='.$s.'&C=myaccount&M=messages&P=member_search&Z=1';
  3942. $field = "&field='+which_field";
  3943. }
  3944. else
  3945. {
  3946. $url = $this->base_url.'member_search/';
  3947. $field = "'+which_field";
  3948. }
  3949. $str = <<<MRI
  3950. <script type="text/javascript">
  3951. //<![CDATA[
  3952. function perform_search(field)
  3953. {
  3954. if (field == 2)
  3955. {
  3956. var which_field = 'cc';
  3957. }
  3958. else
  3959. {
  3960. var which_field = 'recipients';
  3961. }
  3962. var popWin = window.open('{$url}{$field}, '_blank', 'width=700,height=460,scrollbars=yes,status=yes,screenx=0,screeny=0,resizable=yes');
  3963. }
  3964. //]]>
  3965. </script>
  3966. MRI;
  3967. return $str;
  3968. }
  3969. /* END */
  3970. // -----------------------------------
  3971. // JavaScript for Member Search for
  3972. // Buddy and Block Lists
  3973. // -----------------------------------
  3974. function buddy_search_js()
  3975. {
  3976. global $LANG, $PREFS, $SESS;
  3977. if ($this->allegiance == 'cp')
  3978. {
  3979. $s = ($PREFS->ini('admin_session_type') != 'c') ? $SESS->userdata['session_id'] : 0;
  3980. $url = $PREFS->ini('cp_url', FALSE).'?S='.$s.'&C=myaccount&M=messages&P=buddy_search&Z=1';
  3981. $which = "&which='+which";
  3982. }
  3983. else
  3984. {
  3985. $url = $this->base_url.'buddy_search/';
  3986. $which = "'+which";
  3987. }
  3988. $str = <<<MRI
  3989. <script type="text/javascript">
  3990. //<![CDATA[
  3991. function buddy_search(which)
  3992. {
  3993. if (which == 2)
  3994. {
  3995. var which = 'blocked';
  3996. }
  3997. else
  3998. {
  3999. var which = 'buddy';
  4000. }
  4001. var popWin = window.open('{$url}{$which}, '_blank', 'width=450,height=480,scrollbars=yes,status=yes,screenx=0,screeny=0,resizable=yes');
  4002. }
  4003. //]]>
  4004. </script>
  4005. MRI;
  4006. return $str;
  4007. }
  4008. /* END */
  4009. /** -----------------------------------
  4010. /** Counter for Counting Text, duh!
  4011. /** -----------------------------------*/
  4012. function text_counter_js()
  4013. {
  4014. $str = <<<MRI
  4015. <script type="text/javascript">
  4016. //<![CDATA[
  4017. function text_counter(field)
  4018. {
  4019. var max = {$this->max_chars};
  4020. var base = document.forms.submit_message;
  4021. var cur = base.body.value.length;
  4022. if (cur > max)
  4023. {
  4024. base.body.value = base.body.value.substring(0, max);
  4025. }
  4026. else
  4027. {
  4028. base.charsleft.value = max - cur
  4029. }
  4030. }
  4031. //]]>
  4032. </script>
  4033. MRI;
  4034. return $str;
  4035. }
  4036. /* END */
  4037. /** ----------------------------------------
  4038. /** Toggle JavaScript used everywhere!
  4039. /** ----------------------------------------*/
  4040. function toggle_js()
  4041. {
  4042. $str = <<<EOT
  4043. <script type="text/javascript">
  4044. //<![CDATA[
  4045. function toggle(thebutton)
  4046. {
  4047. if (thebutton.checked)
  4048. {
  4049. val = true;
  4050. }
  4051. else
  4052. {
  4053. val = false;
  4054. }
  4055. if (document.target)
  4056. {
  4057. var theForm = document.target;
  4058. }
  4059. else if (document.getElementById('target'))
  4060. {
  4061. var theForm = document.getElementById('target');
  4062. }
  4063. else
  4064. {
  4065. return false;
  4066. }
  4067. var len = theForm.elements.length;
  4068. for (var i = 0; i < len; i++)
  4069. {
  4070. var button = theForm.elements[i];
  4071. var name_array = button.name.split("[");
  4072. if (name_array[0] == "toggle")
  4073. {
  4074. button.checked = val;
  4075. }
  4076. }
  4077. theForm.toggleflag.checked = val;
  4078. }
  4079. //]]>
  4080. </script>
  4081. EOT;
  4082. return trim($str);
  4083. }
  4084. /* END */
  4085. // --------------------------------
  4086. // Headers for Compose Page
  4087. // Allows the Dynamic Address Book
  4088. // --------------------------------
  4089. function compose_header_js()
  4090. {
  4091. return <<<DOD
  4092. <script type="text/javascript">
  4093. //<![CDATA[
  4094. var buddy_div = 'address_book';
  4095. var agent = navigator.userAgent.toLowerCase();
  4096. var Opera = agent.indexOf("opera") != -1;
  4097. var MSIE = agent.indexOf("msie") != -1 && (document.all && !Opera);
  4098. var Konq = agent.indexOf("konqueror") != -1;
  4099. var Safari = agent.indexOf("safari") != -1 || Konq;
  4100. var Moz = !MSIE && (!Safari && (agent.indexOf("mozilla") != -1 || Opera));
  4101. var matches = new Array();
  4102. var current = 0;
  4103. function getChar(e) {
  4104. if (document.getElementById(buddy_div).innerHTML == '') return;
  4105. if (matches.length == 0) return;
  4106. if (window.event)
  4107. {
  4108. e = window.event;
  4109. }
  4110. // IE and Firefox
  4111. // tab => 9
  4112. // return => 13
  4113. // up => 38
  4114. // down => 40
  4115. var charCode = (!e.which || e.which == 0) ? e.keyCode : e.which;
  4116. var action = 'next';
  4117. switch(charCode)
  4118. {
  4119. case 38:
  4120. action = 'previous';
  4121. current--;
  4122. break;
  4123. case 40:
  4124. action = 'next';
  4125. current++;
  4126. break;
  4127. default:
  4128. return true;
  4129. }
  4130. if (current < 0) current = 0;
  4131. if (current > matches.length - 1) current = matches.length - 1;
  4132. for (var p=0, str=""; p < matches.length; p++)
  4133. {
  4134. if (p == current)
  4135. {
  4136. str += "<div style='padding: 3px; background-color:#aaffaa'><a href='#' onclick='add_email(this.innerHTML); return false;'>" + matches[p] + "<"+"/a></div>";
  4137. }
  4138. else
  4139. {
  4140. str += "<div style='padding: 3px;'><a href='#' onclick='add_email(this.innerHTML); return false;'>" + matches[p] + "<"+"/a></div>";
  4141. }
  4142. }
  4143. document.getElementById(buddy_div).innerHTML = str;
  4144. return false;
  4145. }
  4146. function getCharTab(e) {
  4147. if (document.getElementById(buddy_div).innerHTML == '') return;
  4148. if (matches.length == 0) return;
  4149. if (window.event)
  4150. {
  4151. e = window.event;
  4152. }
  4153. var charCode = (!e.which || e.which == 0) ? e.keyCode : e.which;
  4154. var action = 'next';
  4155. switch(charCode)
  4156. {
  4157. case 9:
  4158. action = 'insert';
  4159. break;
  4160. case 13:
  4161. action = 'insert';
  4162. break;
  4163. default:
  4164. return true;
  4165. }
  4166. setTimeout("add_email('"+matches[current]+"')", 0);
  4167. buddypopup.hidePopup();
  4168. document.getElementById(buddy_div).innerHTML = '';
  4169. current = 0;
  4170. matches = new Array();
  4171. return false;
  4172. }
  4173. document.onkeydown = getCharTab;
  4174. document.onkeyup = getChar;
  4175. //]]>
  4176. </script>
  4177. DOD;
  4178. }
  4179. /* END */
  4180. /** --------------------------------
  4181. /** Dynamic Address Book DIV & Javascript
  4182. /** --------------------------------*/
  4183. function dynamic_address_book()
  4184. {
  4185. if ($this->buddies === FALSE)
  4186. {
  4187. $this->fetch_lists('buddy');
  4188. }
  4189. $str = '';
  4190. for($i=0, $s = sizeof($this->buddies); $i < $s; $i++)
  4191. {
  4192. $str .= NL."\tbuddies_email[{$i}] = ['".htmlspecialchars($this->buddies[$i]['2'], ENT_QUOTES)."'];".NL;
  4193. }
  4194. return <<<DIRT
  4195. <div id="address_book" class="tableCellOne" style="border: 1px solid #666; padding: 1px;position:absolute;visibility:hidden;"></div>
  4196. <script type="text/javascript">
  4197. //<![CDATA[
  4198. if (document.getElementById(buddy_div))
  4199. {
  4200. var buddypopup = new PopupWindow(buddy_div);
  4201. buddypopup.offsetY=0;
  4202. buddypopup.offsetX=0;
  4203. buddypopup.autoHide();
  4204. }
  4205. var selectedField = 'recipients';
  4206. var lastString = '';
  4207. function buddy_list(which)
  4208. {
  4209. selectedField = which;
  4210. matches = new Array();
  4211. buddies_email = new Array();
  4212. {$str}
  4213. if (buddies_email.length == 0)
  4214. {
  4215. buddypopup.hidePopup();
  4216. document.getElementById(buddy_div).innerHTML = '';
  4217. return;
  4218. }
  4219. currentString = eval("document.getElementById('submit_message')." + which + ".value");
  4220. if (currentString == '')
  4221. {
  4222. buddypopup.hidePopup();
  4223. document.getElementById(buddy_div).innerHTML = '';
  4224. return;
  4225. }
  4226. if (lastString == currentString)
  4227. {
  4228. return;
  4229. }
  4230. splitString = currentString.split(',');
  4231. checkString = splitString[splitString.length - 1];
  4232. checkString = checkString.toLowerCase();
  4233. checkString = checkString.replace(/^\s*/, '').replace(/\s*$/, '');
  4234. if (checkString.length == 0)
  4235. {
  4236. buddypopup.hidePopup();
  4237. document.getElementById(buddy_div).innerHTML = '';
  4238. return;
  4239. }
  4240. compareString = eval("/^" + checkString + "/gi");
  4241. for(var i=0, email='', t=0; i < buddies_email.length; i++, name='', email='')
  4242. {
  4243. if (buddies_email[i][0].toLowerCase().substr('0',checkString.length).indexOf(checkString) > -1)
  4244. {
  4245. replaceString = buddies_email[i][0].slice(0, checkString.length);
  4246. email = buddies_email[i][0].replace(compareString, replaceString.bold());
  4247. }
  4248. if(email != '')
  4249. {
  4250. matches[t] = email; t++;
  4251. }
  4252. if(matches.length > 25)
  4253. {
  4254. break;
  4255. }
  4256. }
  4257. if (matches.length == 0)
  4258. {
  4259. buddypopup.hidePopup();
  4260. document.getElementById(buddy_div).innerHTML = '';
  4261. return;
  4262. }
  4263. for (var p=0, str=""; p < matches.length; p++)
  4264. {
  4265. if (p == 0)
  4266. {
  4267. str += "<div style='padding: 3px; background-color:#aaffaa'><a href='#' onclick='add_email(this.innerHTML); return false;'>" + matches[p] + "<"+"/a></div>";
  4268. }
  4269. else
  4270. {
  4271. str += "<div style='padding: 3px;'><a href='#' onclick='add_email(this.innerHTML); return false;'>" + matches[p] + "<"+"/a></div>";
  4272. }
  4273. }
  4274. buddypopup.showPopup(which+'_buddies');
  4275. document.getElementById(buddy_div).innerHTML = str;
  4276. }
  4277. function add_email(replaceString)
  4278. {
  4279. curField = eval("document.getElementById('submit_message')." + selectedField);
  4280. replaceString = replaceString.replace(/^ /,'').replace(/ $/,'');
  4281. replaceString = replaceString.replace(/<B>/gi,'').replace(/<\/B>/gi,'');
  4282. splitString = curField.value.split(',');
  4283. for (i=0, newText=''; i < (splitString.length - 1); i++)
  4284. {
  4285. newText += splitString[i].replace(/^ /,'').replace(/ $/,'') + ', ';
  4286. }
  4287. buddypopup.hidePopup();
  4288. newText += replaceString + ', ';
  4289. curField.value = newText;
  4290. curField.blur();
  4291. curField.focus();
  4292. }
  4293. //]]>
  4294. </script>
  4295. DIRT;
  4296. }
  4297. /* END */
  4298. /*
  4299. ,. '\'\ ,---.
  4300. Quiet, Paul, I'm pondering. | \\ l\\l_ // |
  4301. _ _ | \\/ `/ `.| | Err...right, Rick! Narf!
  4302. / \\ \ //\ | Y | | || Y |
  4303. | \\ \ // | | \| | |\ / | /
  4304. [ || || ] \ | o|o | > / /
  4305. ] || || [ \___\_--_ /_/__/
  4306. | \_|l,------.l|_/ | /.-\(____) /--.\
  4307. | >' `< | `--(______)----'
  4308. \ (/~'--____--'~\) / U// U / \
  4309. `-_>-__________-<_-' / \ / /|
  4310. /(_*(__)*_)\ ( .) / / ]
  4311. \___/__\___/ `.`' / [
  4312. /__`--'__\ |`-' |
  4313. /\(__,>-~~ __) | |__
  4314. /\//\\\ / _l |--:.
  4315. '\/ <^\ /^> | ` ( | \\
  4316. _\ >-__-< /_ ,-\ ,-~~->. \ `:.___,/
  4317. (___\ /___) (____/ (____) `---'
  4318. SRKmHWgK 6HP
  4319. WRWWQWm yQgX
  4320. zWQQqRRWT rqQqB
  4321. gqQqRtWR fbXn16hs XXRQq0
  4322. gXkQ8X pkSb b04 RQQXXK
  4323. QXXQkQ7 aDahC XSO RbXQQRQ
  4324. R88kXXQ PZFwX kkk bQkQkRQLt
  4325. QdXkkdXt rYOZ4Vt 4bd6 qXk8X8QR
  4326. gQQQd8kp G6TuTy 3khP tXQQQQRQa
  4327. Q888Xdb2 1TuL6 pkS Q RX8QQRQH
  4328. Kb88kSd8 YZZZ6yF6 4h zk888RQR
  4329. QQQ8bdbV ywyn k X8b8RRg
  4330. uQXb8Qb6 zFDD X4 XQbQXbQ
  4331. gRb8Qkh apX wQ t8QXQQW
  4332. bR8QbE hSF 1bA bQbR8W
  4333. zBXQRa zDDf2 KqQRqRbgy
  4334. tGEgQh aQRRqXXW
  4335. CmWQ KRRQgqQ
  4336. wqC HmQpYj
  4337. */
  4338. }
  4339. /* END */
  4340. ?>