PageRenderTime 41ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/system/expressionengine/libraries/Messages.php

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