Advertisement
Guest User

Untitled

a guest
Nov 8th, 2016
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 106.79 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * <pre>
  5. * Invision Power Services
  6. * IP.Board v3.4.9
  7. * Core user control panel plugin
  8. * Last Updated: $Date: 2015-05-03 10:31:01 -0400 (Sun, 03 May 2015) $
  9. * </pre>
  10. *
  11. * @author $Author: stuarts $
  12. * @copyright (c) 2001 - 2009 Invision Power Services, Inc.
  13. * @license http://www.invisionpower.com/company/standards.php#license
  14. * @package IP.Board
  15. * @subpackage Core
  16. * @link http://www.invisionpower.com
  17. * @since 20th February 2002
  18. * @version $Rev: 12633 $
  19. *
  20. */
  21.  
  22. if ( ! defined( 'IN_IPB' ) )
  23. {
  24. print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
  25. exit();
  26. }
  27.  
  28. class usercpForms_core extends public_core_usercp_manualResolver implements interface_usercp
  29. {
  30. /**
  31. * Tab name
  32. * This can be left blank and the application title will
  33. * be used
  34. *
  35. * @var string
  36. */
  37. public $tab_name = "Settings";
  38.  
  39. /**
  40. * Default area code
  41. *
  42. * @var string
  43. */
  44. public $defaultAreaCode = 'profileinfo';
  45.  
  46. /**
  47. * OK Message
  48. * This is an optional message to return back to the framework
  49. * to replace the standard 'Settings saved' message
  50. *
  51. * @var string
  52. */
  53. public $ok_message = '';
  54.  
  55. /**
  56. * Hide 'save' button and form elements
  57. * Useful if you have custom output that doesn't
  58. * need to use it
  59. *
  60. * @var bool
  61. */
  62. public $hide_form_and_save_button = false;
  63.  
  64. /**
  65. * If you wish to allow uploads, set a value for this
  66. *
  67. * @var integer
  68. */
  69. public $uploadFormMax = 0;
  70.  
  71. /**
  72. * Flag to indicate that the user is a facebook logged in user doozer
  73. *
  74. * @var boolean
  75. */
  76. protected $_isFBUser = false;
  77.  
  78. /**
  79. * Flag to indicate compatibility
  80. *
  81. * @var int
  82. */
  83. public $version = 32;
  84.  
  85. /**
  86. * Initiate this module
  87. *
  88. * @return @e void
  89. */
  90. public function init( )
  91. {
  92. $this->tab_name = ipsRegistry::getClass('class_localization')->words['tab__core'];
  93.  
  94. /* Facebook? */
  95. if ( IPSLib::fbc_enabled() === TRUE AND $this->memberData['fb_uid'] )
  96. {
  97. $this->_isFBUser = true;
  98. }
  99.  
  100. if( !$this->memberData['g_edit_profile'] )
  101. {
  102. $this->defaultAreaCode = 'email';
  103. }
  104. }
  105.  
  106. /**
  107. * Return links for this tab
  108. * You may return an empty array or FALSE to not have
  109. * any links show in the tab.
  110. *
  111. * The links must have 'area=xxxxx'. The rest of the URL
  112. * is added automatically.
  113. * 'area' can only be a-z A-Z 0-9 - _
  114. *
  115. * @author Matt Mecham
  116. * @return array Links
  117. */
  118. public function getLinks()
  119. {
  120. ipsRegistry::instance()->getClass('class_localization')->loadLanguageFile( array( 'public_usercp' ), 'core' );
  121.  
  122. $array = array();
  123.  
  124. if( $this->memberData['g_edit_profile'] )
  125. {
  126. $array[] = array( 'url' => 'area=profileinfo',
  127. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['change_settings'],
  128. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'profileinfo' ? 1 : 0,
  129. 'area' => 'profileinfo'
  130. );
  131. }
  132.  
  133. if ( $this->memberData['gbw_allow_customization'] AND ! $this->memberData['bw_disable_customization'] )
  134. {
  135. $array[] = array( 'url' => 'area=customize',
  136. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_customize'],
  137. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'customize' ? 1 : 0,
  138. 'area' => 'customize'
  139. );
  140. }
  141.  
  142. $array[] = array( 'url' => 'area=email',
  143. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_email_pass_change'],
  144. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'email' ? 1 : 0,
  145. 'area' => 'email'
  146. );
  147.  
  148. if ( $this->settings['auth_allow_dnames'] == 1 AND $this->memberData['g_dname_changes'] != 0 )
  149. {
  150. $array[] = array( 'url' => 'area=displayname',
  151. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['ucp_change_name'],
  152. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'displayname' ? 1 : 0,
  153. 'area' => 'displayname'
  154. );
  155. }
  156.  
  157. $sig_restrictions = explode( ':', $this->memberData['g_signature_limits'] );
  158.  
  159. if ( ( ! $sig_restrictions[0] OR ( $sig_restrictions[0] AND $this->memberData['g_sig_unit'] ) ) AND $this->memberData['g_edit_profile'] )
  160. {
  161. $array[] = array( 'url' => 'area=signature',
  162. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_sig_info'],
  163. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'signature' ? 1 : 0,
  164. 'area' => 'signature'
  165. );
  166. }
  167.  
  168. $array[] = array( 'url' => 'area=ignoredusers',
  169. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_ignore_users'],
  170. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'ignoredusers' ? 1 : 0,
  171. 'area' => 'ignoredusers'
  172. );
  173.  
  174. if ( IPSLib::fbc_enabled() === TRUE )
  175. {
  176. $array[] = array( 'url' => 'area=facebook',
  177. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_facebook'],
  178. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'facebook' ? 1 : 0,
  179. 'area' => 'facebook'
  180. );
  181. }
  182.  
  183. if ( IPSLib::twitter_enabled() === TRUE )
  184. {
  185. $array[] = array( 'url' => 'area=twitter',
  186. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_twitter'],
  187. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'twitter' ? 1 : 0,
  188. 'area' => 'twitter'
  189. );
  190. }
  191.  
  192. if ( $this->memberData['g_attach_max'] != -1 )
  193. {
  194. $array[] = array(
  195. 'url' => 'area=attachments',
  196. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_attach'],
  197. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'attachments' ? 1 : 0,
  198. 'area' => 'attachments'
  199. );
  200. }
  201.  
  202. $array[] = array( 'url' => 'area=notifications',
  203. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_notifications'],
  204. 'active' => $this->request['tab'] == 'core' && $this->request['area'] == 'notifications' ? 1 : 0,
  205. 'area' => 'notifications'
  206. );
  207.  
  208. $array[] = array( 'url' => 'area=notificationlog',
  209. 'title' => ipsRegistry::instance()->getClass('class_localization')->words['m_arch_notify'],
  210. 'active' => ( in_array( $this->request['area'], array( 'notificationlog', 'viewNotification', 'removeNotifications' ) ) ) ? 1 : 0,
  211. 'area' => 'notificationlog'
  212. );
  213.  
  214. return $array;
  215. }
  216.  
  217.  
  218. /**
  219. * Run custom event
  220. *
  221. * If you pass a 'do' in the URL / post form that is not either:
  222. * save / save_form or show / show_form then this function is loaded
  223. * instead. You can return a HTML chunk to be used in the UserCP (the
  224. * tabs and footer are auto loaded) or redirect to a link.
  225. *
  226. * If you are returning HTML, you can use $this->hide_form_and_save_button = 1;
  227. * to remove the form and save button that is automatically placed there.
  228. *
  229. * @author Matt Mecham
  230. * @param string Current area
  231. * @return mixed html or void
  232. */
  233. public function runCustomEvent( $currentArea )
  234. {
  235. //-----------------------------------------
  236. // INIT
  237. //-----------------------------------------
  238.  
  239. $html = '';
  240.  
  241. //-----------------------------------------
  242. // What to do?
  243. //-----------------------------------------
  244.  
  245. switch( $currentArea )
  246. {
  247. case 'removeIgnoredUser':
  248. return $this->customEvent_removeIgnoredUser();
  249. break;
  250. case 'toggleIgnoredUser':
  251. return $this->customEvent_toggleIgnoredUser();
  252. break;
  253. case 'facebookSync':
  254. $html = $this->customEvent_facebookSync();
  255. break;
  256. case 'facebookRemove':
  257. $html = $this->customEvent_facebookRemove();
  258. break;
  259. case 'twitterRemove':
  260. $html = $this->customEvent_twitterRemove();
  261. break;
  262. case 'facebookLink':
  263. $html = $this->customEvent_facebookLink();
  264. break;
  265. case 'updateAttachments':
  266. return $this->customEvent_updateAttachments();
  267. break;
  268.  
  269. case 'viewNotification':
  270. $html = $this->customEvent_viewNotification();
  271. break;
  272.  
  273. case 'markNotification':
  274. return $this->customEvent_markNotification();
  275. break;
  276.  
  277. case 'removeNotifications':
  278. return $this->customEvent_removeNotifications();
  279. break;
  280. }
  281.  
  282. //-----------------------------------------
  283. // Turn off save button
  284. //-----------------------------------------
  285.  
  286. $this->hide_form_and_save_button = 1;
  287.  
  288. //-----------------------------------------
  289. // Return
  290. //-----------------------------------------
  291.  
  292. return $html;
  293. }
  294.  
  295. /**
  296. * Delete attachments
  297. *
  298. * @author Matt Mecham
  299. * @return string Processed HTML
  300. */
  301. public function customEvent_updateAttachments()
  302. {
  303. //-----------------------------------------
  304. // Secure Key
  305. //-----------------------------------------
  306.  
  307. $this->request['secure_key'] = $this->request['secure_key'] ? $this->request['secure_key'] : $this->request['authKey'];
  308.  
  309. if( $this->request['secure_key'] != $this->member->form_hash )
  310. {
  311. $this->registry->output->showError( 'warn_bad_key', '1021523.1' );
  312. }
  313.  
  314. //-----------------------------------------
  315. // Get the ID's to delete
  316. //-----------------------------------------
  317.  
  318. $finalIDs = array();
  319.  
  320. //-----------------------------------------
  321. // Grab post IDs
  322. //-----------------------------------------
  323.  
  324. if ( is_array( $_POST['attach'] ) and count( $_POST['attach'] ) )
  325. {
  326. foreach( $_POST['attach'] as $id => $value )
  327. {
  328. $finalIDs[ $id ] = intval( $id );
  329. }
  330. }
  331.  
  332. if ( count($finalIDs) > 0 )
  333. {
  334. $this->DB->build( array( 'select' => 'a.*',
  335. 'from' => array( 'attachments' => 'a' ),
  336. 'where' => "a.attach_id IN (" . implode( ",", $finalIDs ) .") AND a.attach_rel_module IN( 'post', 'msg' ) AND attach_member_id=" . $this->memberData['member_id'],
  337. 'add_join' => array(
  338. array( 'select' => 'p.topic_id, p.pid',
  339. 'from' => array( 'posts' => 'p' ),
  340. 'where' => "p.pid=a.attach_rel_id AND a.attach_rel_module='post'",
  341. 'type' => 'left'
  342. ),
  343. array( 'select' => 'mt.msg_id, mt.msg_topic_id',
  344. 'from' => array( 'message_posts' => 'mt' ),
  345. 'where' => "mt.msg_id=a.attach_rel_id AND a.attach_rel_module='msg'",
  346. 'type' => 'left'
  347. ),
  348. )
  349. ) );
  350.  
  351. $o = $this->DB->execute();
  352.  
  353. while ( $killmeh = $this->DB->fetch( $o ) )
  354. {
  355. if ( $killmeh['attach_location'] )
  356. {
  357. @unlink( $this->settings['upload_dir']."/".$killmeh['attach_location'] );
  358. }
  359. if ( $killmeh['attach_thumb_location'] )
  360. {
  361. @unlink( $this->settings['upload_dir']."/".$killmeh['attach_thumb_location'] );
  362. }
  363.  
  364. if ( $killmeh['topic_id'] )
  365. {
  366. $this->DB->update( 'topics', 'topic_hasattach=topic_hasattach-1', 'tid='.$killmeh['topic_id'], true, true );
  367. }
  368. else if( $killmeh['msg_id'] )
  369. {
  370. $this->DB->update( 'message_topics', 'mt_hasattach=mt_hasattach-1', 'mt_id='.$killmeh['msg_topic_id'], true, true );
  371. }
  372. }
  373.  
  374. $this->DB->delete( 'attachments', 'attach_id IN ('.implode(",",$finalIDs).') and attach_member_id='.$this->memberData['member_id'] );
  375. }
  376.  
  377. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&amp;module=usercp&amp;tab=core&amp;area=attachments&amp;do=show" );
  378. }
  379.  
  380. /**
  381. * UserCP handle our notifications
  382. *
  383. * @return boolean Successful
  384. */
  385. public function customEvent_removeNotifications()
  386. {
  387. //-----------------------------------------
  388. // Check form hash
  389. //-----------------------------------------
  390.  
  391. $this->request['secure_key'] = $this->request['secure_key'] ? $this->request['secure_key'] : $this->request['authKey'];
  392.  
  393. if( $this->request['secure_key'] != $this->member->form_hash )
  394. {
  395. $this->registry->output->showError( 'warn_bad_key', 1021523 );
  396. }
  397.  
  398. //-----------------------------------------
  399. // Notifications library
  400. //-----------------------------------------
  401.  
  402. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' );
  403. $notifyLibrary = new $classToLoad( $this->registry );
  404. $notifyLibrary->setMember( $this->memberData );
  405.  
  406. //-----------------------------------------
  407. // Delete the notifications
  408. //-----------------------------------------
  409.  
  410. $_toDelete = IPSLib::cleanIntArray( $this->request['notifications'] );
  411.  
  412. if( !count($_toDelete) )
  413. {
  414. return $this->showInlineNotifications( $this->lang->words['no_notify_del'] );
  415. }
  416.  
  417. $this->DB->delete( 'inline_notifications', "notify_id IN(" . implode( ',', $_toDelete ) . ") AND notify_to_id=" . $this->memberData['member_id'] );
  418.  
  419. //-----------------------------------------
  420. // If member has 'unread' count, rebuild count
  421. //-----------------------------------------
  422.  
  423. if( $this->memberData['notification_cnt'] )
  424. {
  425. $notifyLibrary->rebuildUnreadCount();
  426. }
  427.  
  428. //-----------------------------------------
  429. // Redirect
  430. //-----------------------------------------
  431.  
  432. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&amp;module=usercp&amp;tab=core&amp;area=notificationlog&amp;confirm=1" );
  433. }
  434.  
  435. /**
  436. * Mark a notification
  437. *
  438. * @return string HTML
  439. */
  440. public function customEvent_markNotification()
  441. {
  442. //-----------------------------------------
  443. // CSRF Check
  444. //-----------------------------------------
  445. if ( $this->request['k'] != $this->member->form_hash )
  446. {
  447. $this->registry->getClass('output')->showError( 'no_permission', 1021523 );
  448. }
  449.  
  450. //-----------------------------------------
  451. // Notifications library
  452. //-----------------------------------------
  453.  
  454. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' );
  455. $notifyLibrary = new $classToLoad( $this->registry );
  456. $notifyLibrary->setMember( $this->memberData );
  457.  
  458. //-----------------------------------------
  459. // Get notification
  460. //-----------------------------------------
  461.  
  462. /* Marking them all as read? */
  463. if ( $this->request['mark'] == 'all' )
  464. {
  465. $this->DB->update( 'inline_notifications', array( 'notify_read' => time() ), 'notify_to_id=' . $this->memberData['member_id'] );
  466. }
  467. else
  468. {
  469. $id = intval($this->request['mark']);
  470. $notification = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'inline_notifications', 'where' => 'notify_id=' . $id ) );
  471.  
  472. //-----------------------------------------
  473. // Error checking
  474. //-----------------------------------------
  475.  
  476. if( !$notification['notify_id'] )
  477. {
  478. if( $this->request['ajax'] )
  479. {
  480. print 'ok';
  481. exit;
  482. }
  483. else
  484. {
  485. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url'] . "app=core&amp;module=usercp&amp;tab=core&amp;area=notificationlog" );
  486. }
  487. }
  488.  
  489. if( $notification['notify_to_id'] != $this->memberData['member_id'] )
  490. {
  491. if( $this->request['ajax'] )
  492. {
  493. print 'ok';
  494. exit;
  495. }
  496. else
  497. {
  498. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url'] . "app=core&amp;module=usercp&amp;tab=core&amp;area=notificationlog" );
  499. }
  500. }
  501.  
  502. //-----------------------------------------
  503. // Update read timestamp
  504. //-----------------------------------------
  505.  
  506. $this->DB->update( 'inline_notifications', array( 'notify_read' => time() ), 'notify_id=' . $id );
  507. }
  508.  
  509. //-----------------------------------------
  510. // If member has 'unread' count, rebuild count
  511. //-----------------------------------------
  512.  
  513. if( $this->memberData['notification_cnt'] )
  514. {
  515. $notifyLibrary->rebuildUnreadCount();
  516. }
  517.  
  518. if( $this->request['ajax'] )
  519. {
  520. print 'ok';
  521. exit;
  522. }
  523. else
  524. {
  525. $this->registry->output->silentRedirect( $this->settings['base_url'] . "app=core&amp;module=usercp&amp;tab=core&amp;area=notificationlog" );
  526. }
  527. }
  528.  
  529. /**
  530. * View a notification
  531. *
  532. * @return string HTML
  533. */
  534. public function customEvent_viewNotification()
  535. {
  536. //-----------------------------------------
  537. // Notifications library
  538. //-----------------------------------------
  539.  
  540. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' );
  541. $notifyLibrary = new $classToLoad( $this->registry );
  542. $notifyLibrary->setMember( $this->memberData );
  543.  
  544. //-----------------------------------------
  545. // Get notification
  546. //-----------------------------------------
  547.  
  548. $id = intval($this->request['view']);
  549. $notification = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'inline_notifications', 'where' => 'notify_id=' . $id ) );
  550.  
  551. //-----------------------------------------
  552. // Error checking
  553. //-----------------------------------------
  554.  
  555. if( !$notification['notify_id'] )
  556. {
  557. $this->registry->output->showError( 'bad_notify_id', 10191 );
  558. }
  559.  
  560. if( $notification['notify_to_id'] != $this->memberData['member_id'] )
  561. {
  562. $this->registry->output->showError( 'bad_notify_id', 10192 );
  563. }
  564.  
  565. //-----------------------------------------
  566. // Update read timestamp
  567. //-----------------------------------------
  568.  
  569. $this->DB->update( 'inline_notifications', array( 'notify_read' => time() ), 'notify_id=' . $id );
  570.  
  571. //-----------------------------------------
  572. // If member has 'unread' count, rebuild count
  573. //-----------------------------------------
  574.  
  575. if( $this->memberData['notification_cnt'] )
  576. {
  577. $notifyLibrary->rebuildUnreadCount();
  578. }
  579.  
  580. //-----------------------------------------
  581. // Parse for display
  582. //-----------------------------------------
  583.  
  584. /* As the email template parser makes an attempt to reparse 'safe' HTML, we need to make it safe here */
  585. $notification['notify_text'] = IPSText::htmlspecialchars( $notification['notify_text'] );
  586.  
  587. IPSText::getTextClass('bbcode')->parse_smilies = 1;
  588. IPSText::getTextClass('bbcode')->parse_nl2br = 1;
  589. IPSText::getTextClass('bbcode')->parse_html = 0;
  590. IPSText::getTextClass('bbcode')->parse_bbcode = 1;
  591. IPSText::getTextClass('bbcode')->parsing_section = 'global';
  592.  
  593. $notification['notify_text'] = IPSText::getTextClass('bbcode')->preDisplayParse( nl2br( $notification['notify_text'] ) );
  594.  
  595. //-----------------------------------------
  596. // Show notification
  597. //-----------------------------------------
  598.  
  599. $this->_nav[] = array( $this->lang->words['m_arch_notify'], 'app=core&amp;module=usercp&amp;tab=core&amp;area=notificationlog' );
  600. return $this->registry->getClass('output')->getTemplate('ucp')->showNotification( $notification );
  601. }
  602.  
  603. /**
  604. * Custom Event: Remove Twitter link
  605. *
  606. * @return @e void
  607. */
  608. public function customEvent_twitterRemove()
  609. {
  610. //-----------------------------------------
  611. // Check secure hash...
  612. //-----------------------------------------
  613.  
  614. if ( $this->request['secure_key'] != $this->member->form_hash )
  615. {
  616. $this->registry->output->showError( 'authorization_error', 100, true, null, 403 );
  617. }
  618.  
  619. //-----------------------------------------
  620. // Okay...
  621. //-----------------------------------------
  622.  
  623. if ( $this->memberData['twitter_id'] )
  624. {
  625. /* Remove the link */
  626. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'twitter_id' => 0, 'twitter_token' => '', 'twitter_secret' => '' ) ) );
  627. }
  628.  
  629. /* Log the user out */
  630. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&module=global&section=login&do=logout&k=" . $this->member->form_hash );
  631. }
  632.  
  633. /**
  634. * Custom Event: Create facebook link
  635. *
  636. * @return @e void
  637. */
  638. public function customEvent_facebookLink()
  639. {
  640. //-----------------------------------------
  641. // Check secure hash...
  642. //-----------------------------------------
  643.  
  644. if ( $this->request['secure_key'] != $this->member->form_hash )
  645. {
  646. $this->registry->output->showError( 'authorization_error', 100, true, null, 403 );
  647. }
  648.  
  649. /* Load application */
  650. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/facebook/connect.php', 'facebook_connect' );
  651. $facebook = new $classToLoad( $this->registry );
  652.  
  653. try
  654. {
  655. $facebook->linkMember( $this->memberData['member_id'] );
  656. }
  657. catch( Exception $error )
  658. {
  659. $msg = $error->getMessage();
  660.  
  661. switch( $msg )
  662. {
  663. default:
  664. case 'NO_FACEBOOK_USER_LOGGED_IN':
  665. case 'ALREADY_LINKED':
  666. $this->registry->getClass('output')->showError( 'fbc_authorization_screwup', 1005.99, null, null, 403 );
  667. break;
  668. }
  669. }
  670.  
  671. //-----------------------------------------
  672. // Return
  673. //-----------------------------------------
  674.  
  675. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&amp;module=usercp&amp;tab=core&amp;area=facebook&amp;do=show" );
  676. }
  677.  
  678. /**
  679. * Custom Event: Remove facebook link
  680. *
  681. * @return @e void
  682. */
  683. public function customEvent_facebookRemove()
  684. {
  685. //-----------------------------------------
  686. // Check secure hash...
  687. //-----------------------------------------
  688.  
  689. if ( $this->request['secure_key'] != $this->member->form_hash )
  690. {
  691. $this->registry->output->showError( 'authorization_error', 100, true, null, 403 );
  692. }
  693.  
  694. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/facebook/connect.php', 'facebook_connect' );
  695. $facebook = new $classToLoad( $this->registry );
  696.  
  697. //-----------------------------------------
  698. // Okay...
  699. //-----------------------------------------
  700.  
  701. if ( $this->memberData['fb_uid'] )
  702. {
  703. /* Unauthorize application */
  704. $facebook->revokeAuthorization();
  705.  
  706. /* Remove the link */
  707. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'fb_uid' => 0, 'fb_emailhash' => '', 'fb_token' => '', 'fb_lastsync' => 0 ) ) );
  708. }
  709.  
  710. /* Log the user out */
  711. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&module=global&section=login&do=logout&k=" . $this->member->form_hash );
  712. }
  713.  
  714. /**
  715. * Custom Event: Sync up facebook
  716. * NO LONGER USED. LEFT FOR FIX CONFIRMATION
  717. *
  718. * @return @e void
  719. */
  720. public function customEvent_facebookSync()
  721. {
  722. if ( IPSLib::fbc_enabled() === TRUE )
  723. {
  724. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/facebook/connect.php', 'facebook_connect' );
  725. $facebook = new $classToLoad( $this->registry );
  726.  
  727. try
  728. {
  729. $facebook->syncMember( $this->memberData );
  730. }
  731. catch( Exception $error )
  732. {
  733. $msg = $error->getMessage();
  734.  
  735. switch( $msg )
  736. {
  737. case 'NOT_LINKED':
  738. case 'NO_MEMBER':
  739. default:
  740. $this->registry->getClass('output')->showError( 'fbc_authorization_screwup', 1005, null, null, 403 );
  741. break;
  742. }
  743. }
  744.  
  745. //-----------------------------------------
  746. // Return
  747. //-----------------------------------------
  748.  
  749. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&amp;module=usercp&amp;tab=core&amp;area=facebook&amp;do=show" );
  750. }
  751. }
  752.  
  753. /**
  754. * Custom Event: Run the find user tool
  755. *
  756. * @return @e void
  757. */
  758. public function customEvent_toggleIgnoredUser()
  759. {
  760. //-----------------------------------------
  761. // Secure Key
  762. //-----------------------------------------
  763.  
  764. $this->request['secure_key'] = $this->request['secure_key'] ? $this->request['secure_key'] : $this->request['authKey'];
  765.  
  766. if( $this->request['secure_key'] != $this->member->form_hash )
  767. {
  768. $this->registry->output->showError( 'warn_bad_key', '1021523.2' );
  769. }
  770.  
  771. //-----------------------------------------
  772. // INIT
  773. //-----------------------------------------
  774.  
  775. $member_id = intval( $this->request['id'] );
  776. $field = $this->request['field'];
  777. $update = array();
  778.  
  779. //-----------------------------------------
  780. // Grab user
  781. //-----------------------------------------
  782.  
  783. $ignoredUser = $this->DB->buildAndFetch( array( 'select' => '*',
  784. 'from' => 'ignored_users',
  785. 'where' => 'ignore_ignore_id=' . $member_id . ' AND ignore_owner_id=' . $this->memberData['member_id'] ) );
  786.  
  787. if ( $ignoredUser['ignore_id'] )
  788. {
  789. switch( $field )
  790. {
  791. default:
  792. case 'topics':
  793. $update = array( 'ignore_topics' => ( $ignoredUser['ignore_topics'] == 1 ) ? 0 : 1 );
  794. break;
  795. case 'messages':
  796. $update = array( 'ignore_messages' => ( $ignoredUser['ignore_messages'] == 1 ) ? 0 : 1 );
  797. break;
  798. case 'signatures':
  799. $update = array( 'ignore_signatures' => ( $ignoredUser['ignore_signatures'] == 1 ) ? 0 : 1 );
  800. break;
  801. case 'chats':
  802. $update = array( 'ignore_chats' => ( $ignoredUser['ignore_chats'] == 1 ) ? 0 : 1 );
  803. break;
  804. }
  805.  
  806. //-----------------------------------------
  807. // Update
  808. //-----------------------------------------
  809.  
  810. $this->DB->update( 'ignored_users', $update, 'ignore_id=' . $ignoredUser['ignore_id'] );
  811.  
  812. /* Rebuild cache */
  813. IPSMember::rebuildIgnoredUsersCache( $this->memberData );
  814. }
  815.  
  816. //-----------------------------------------
  817. // Return
  818. //-----------------------------------------
  819.  
  820. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&amp;module=usercp&amp;tab=core&amp;area=ignoredusers&amp;do=show&amp;st={$this->request['st']}" );
  821. }
  822.  
  823. /**
  824. * Custom event: Remove ignored user
  825. *
  826. * @author Matt Mecham
  827. * @return string Processed HTML
  828. */
  829. public function customEvent_removeIgnoredUser()
  830. {
  831. //-----------------------------------------
  832. // Secure Key
  833. //-----------------------------------------
  834.  
  835. $this->request['secure_key'] = $this->request['secure_key'] ? $this->request['secure_key'] : $this->request['authKey'];
  836.  
  837. if( $this->request['secure_key'] != $this->member->form_hash )
  838. {
  839. $this->registry->output->showError( 'warn_bad_key', '1021523.3' );
  840. }
  841.  
  842. //-----------------------------------------
  843. // INIT
  844. //-----------------------------------------
  845.  
  846. $removeID = intval( $this->request['id'] );
  847.  
  848. $this->DB->delete( 'ignored_users', 'ignore_owner_id=' . $this->memberData['member_id'] . ' AND ignore_ignore_id=' . $removeID );
  849.  
  850. /* Rebuild cache */
  851. IPSMember::rebuildIgnoredUsersCache( $this->memberData );
  852.  
  853. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url']."app=core&amp;module=usercp&amp;tab=core&amp;area=ignoredusers&amp;do=show" );
  854. }
  855.  
  856. /**
  857. * UserCP Form Show
  858. *
  859. * @author Matt Mecham
  860. * @param string Current area as defined by 'get_links'
  861. * @param array Array of errors
  862. * @return string Processed HTML
  863. */
  864. public function showForm( $current_area, $errors=array() )
  865. {
  866. //-----------------------------------------
  867. // Where to go, what to see?
  868. //-----------------------------------------
  869.  
  870. if( !$current_area AND !$this->memberData['g_edit_profile'] )
  871. {
  872. $current_area = 'email';
  873. }
  874.  
  875. switch( $current_area )
  876. {
  877. default:
  878. case 'profileinfo':
  879. return $this->formProfileInfo();
  880. break;
  881. case 'signature':
  882. return $this->formSignature();
  883. break;
  884. case 'photo':
  885. return $this->formPhoto();
  886. break;
  887. case 'ignoredusers':
  888. return $this->formIgnoredUsers();
  889. break;
  890. case 'facebook':
  891. return $this->formFacebook();
  892. break;
  893. case 'twitter':
  894. return $this->formTwitter();
  895. break;
  896. case 'customize':
  897. return $this->formCustomize();
  898. break;
  899. case 'email':
  900. return $this->showFormEmailPassword();
  901. break;
  902. case 'displayname':
  903. return $this->showFormDisplayname();
  904. break;
  905. case 'attachments':
  906. return $this->showFormAttachments();
  907. break;
  908. case 'notifications':
  909. return $this->showFormNotifications();
  910. break;
  911. case 'notificationlog':
  912. return $this->showInlineNotifications();
  913. break;
  914. }
  915. }
  916.  
  917. /**
  918. * Show the customization form
  919. *
  920. * @author Matt Mecham
  921. * @param string Any inline message to show
  922. * @return string Processed HTML
  923. */
  924. public function formCustomize( $inlineMsg='' )
  925. {
  926. /* Allow uploads */
  927. $this->uploadFormMax = 10000 * 1024;
  928.  
  929. if ( ! $this->memberData['gbw_allow_customization'] OR $this->memberData['bw_disable_customization'] )
  930. {
  931. $this->registry->getClass('output')->showError( 'no_permission', 1005.5 );
  932. }
  933.  
  934. /* Grab current options */
  935. $options = IPSLib::safeUnserialize( $this->memberData['pp_customization'] );
  936. $options = is_array( $options ) ? $options : array();
  937.  
  938. /* Build input */
  939. foreach( $options as $k => $v )
  940. {
  941. $input[ $k ] = ( $this->request[ $k ] ) ? $this->request[ $k ] : $v;
  942. }
  943.  
  944. /* Figure out preview URL */
  945. if ( $options['type'] == 'url' AND $options['bg_url'] )
  946. {
  947. $input['_preview'] = $options['bg_url'];
  948. }
  949. else if ( $options['type'] == 'upload' AND $options['bg_url'] )
  950. {
  951. $input['_preview'] = $this->settings['upload_url'] . '/' . $options['bg_url'];
  952. $input['bg_url'] = '';
  953. }
  954.  
  955. /* Show form */
  956. return $this->registry->getClass('output')->getTemplate('ucp')->membersProfileCustomize( $options, $input, $inlineMsg );
  957. }
  958.  
  959. /**
  960. * Show the twitter form
  961. *
  962. * @author Matt Mecham
  963. * @param string Any inline message to show
  964. * @return string Processed HTML
  965. */
  966. public function formTwitter( $inlineMsg='' )
  967. {
  968. //-----------------------------------------
  969. // INIT
  970. //-----------------------------------------
  971.  
  972. if( !IPSLib::twitter_enabled() )
  973. {
  974. $this->registry->getClass('output')->showError( 'twitter_disabled', 1005.1 );
  975. }
  976.  
  977. //-----------------------------------------
  978. // Twitter user logged in?
  979. //-----------------------------------------
  980.  
  981. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/twitter/connect.php', 'twitter_connect' );
  982. $twitter = new $classToLoad( $this->registry, $this->memberData['twitter_token'], $this->memberData['twitter_secret'] );
  983.  
  984. //-----------------------------------------
  985. // Thaw bitfield options
  986. //-----------------------------------------
  987.  
  988. $bwOptions = IPSBWOptions::thaw( $this->memberData['tc_bwoptions'], 'twitter' );
  989.  
  990. //-----------------------------------------
  991. // Merge..
  992. //-----------------------------------------
  993.  
  994. if ( is_array( $bwOptions ) )
  995. {
  996. foreach( $bwOptions as $k => $v )
  997. {
  998. $this->memberData[ $k ] = $v;
  999. }
  1000. }
  1001.  
  1002. if( ! $twitter->isConnected() )
  1003. {
  1004. $this->hide_form_and_save_button = 1;
  1005. }
  1006.  
  1007. $userData = $twitter->fetchUserData();
  1008.  
  1009. if ( isset( $userData['status']['text'] ) )
  1010. {
  1011. if ( IPS_DOC_CHAR_SET != 'UTF-8' )
  1012. {
  1013. $userData['status']['text'] = IPSText::utf8ToEntities( $userData['status']['text'] );
  1014. }
  1015.  
  1016. /* Make safe */
  1017. $userData['status']['text'] = str_replace( array( '<', '>' ), array( '&lt;', '&gt;' ), $userData['status']['text'] );
  1018. }
  1019.  
  1020. return $this->registry->getClass('output')->getTemplate('ucp')->membersTwitterConnect( $twitter->isConnected(), $userData );
  1021. }
  1022.  
  1023.  
  1024. /**
  1025. * Show the member form
  1026. *
  1027. * @author Matt Mecham
  1028. * @param string Any inline message to show
  1029. * @return string Processed HTML
  1030. */
  1031. public function formFacebook( $inlineMsg='' )
  1032. {
  1033. //-----------------------------------------
  1034. // INIT
  1035. //-----------------------------------------
  1036.  
  1037. if( !IPSLib::fbc_enabled() )
  1038. {
  1039. $this->registry->getClass('output')->showError( 'fbc_disabled', 1005.2 );
  1040. }
  1041.  
  1042. //-----------------------------------------
  1043. // Shut off save button if not associated yet
  1044. //-----------------------------------------
  1045.  
  1046. if( !$this->memberData['fb_uid'] )
  1047. {
  1048. $this->hide_form_and_save_button = true;
  1049. $userData = array();
  1050. $linkedMemberData = array();
  1051. $perms = array();
  1052. }
  1053. else
  1054. {
  1055. //-----------------------------------------
  1056. // FB user logged in?
  1057. //-----------------------------------------
  1058.  
  1059. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/facebook/connect.php', 'facebook_connect' );
  1060. $facebook = new $classToLoad( $this->registry );
  1061.  
  1062. /* Now get the linked user */
  1063. $linkedMemberData = IPSMember::load( intval($this->memberData['fb_uid']), 'all', 'fb_uid' );
  1064.  
  1065. $userData = $facebook->fetchUserData();
  1066.  
  1067. /* Email */
  1068. $perms['email'] = $facebook->fetchHasAppPermission( 'email' );
  1069.  
  1070. /* Publish Stream */
  1071. $perms['publish_actions'] = $facebook->fetchHasAppPermission( 'publish_actions' );
  1072.  
  1073. /* Read stream */
  1074. $perms['user_status'] = $facebook->fetchHasAppPermission( 'user_status' );
  1075.  
  1076. //var_dump( $perms ); exit;
  1077.  
  1078. /* Check our perms and see if any aren't allowed */
  1079. $missingPerms = FALSE;
  1080. foreach( $perms AS $k => $perm )
  1081. {
  1082. if ( $perm['data'][0]['status'] != 'granted' )
  1083. {
  1084. $missingPerms = TRUE;
  1085. break;
  1086. }
  1087. }
  1088.  
  1089. //-----------------------------------------
  1090. // Thaw bitfield options
  1091. //-----------------------------------------
  1092.  
  1093. $bwOptions = IPSBWOptions::thaw( $this->memberData['fb_bwoptions'], 'facebook' );
  1094.  
  1095. //-----------------------------------------
  1096. // Merge..
  1097. //-----------------------------------------
  1098.  
  1099. if ( is_array( $bwOptions ) )
  1100. {
  1101. foreach( $bwOptions as $k => $v )
  1102. {
  1103. $this->memberData[ $k ] = $v;
  1104. }
  1105. }
  1106.  
  1107. //-----------------------------------------
  1108. // Able to update status?
  1109. //-----------------------------------------
  1110.  
  1111. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/member/status.php', 'memberStatus' );
  1112. $this->registry->setClass( 'memberStatus', new $classToLoad( $this->registry ) );
  1113.  
  1114. $this->registry->memberStatus->setAuthor( $this->memberData );
  1115. $this->memberData['can_updated_status'] = $this->registry->memberStatus->canCreate();
  1116.  
  1117. $_updates = $facebook->fetchUserTimeline( $userData['id'], 0, true );
  1118.  
  1119. /* Got any? */
  1120. if ( count( $_updates ) )
  1121. {
  1122. $update = array_shift( $_updates );
  1123.  
  1124. if ( count( $update ) AND is_array( $update ) )
  1125. {
  1126. $userData['status'] = $update;
  1127. }
  1128. }
  1129.  
  1130. if ( is_array( $userData ) AND $userData['status']['message'] AND IPS_DOC_CHAR_SET != 'UTF-8' )
  1131. {
  1132. $userData['status']['message'] = IPSText::utf8ToEntities( $userData['status']['message'] );
  1133. }
  1134.  
  1135. /* Make safe */
  1136. $userData['status']['message'] = str_replace( array( '<', '>' ), array( '&lt;', '&gt;' ), $userData['status']['message'] );
  1137. }
  1138.  
  1139. return $this->registry->getClass('output')->getTemplate('ucp')->membersFacebookConnect( trim($this->memberData['fb_uid']), $userData, $linkedMemberData, $perms, $missingPerms );
  1140. }
  1141.  
  1142. /**
  1143. * Show the ignored users
  1144. *
  1145. * @author Matt Mecham
  1146. * @return string Processed HTML
  1147. */
  1148. public function formIgnoredUsers()
  1149. {
  1150. //-----------------------------------------
  1151. // INIT
  1152. //-----------------------------------------
  1153.  
  1154. $final_users = array();
  1155. $temp_users = array();
  1156. $uid = intval( $this->request['uid'] );
  1157. $ignoredUsers = array();
  1158.  
  1159. //-----------------------------------------
  1160. // Do we have incoming?
  1161. //-----------------------------------------
  1162.  
  1163. if ( $uid )
  1164. {
  1165. $newmem = IPSMember::load( $uid );
  1166.  
  1167. $this->request['newbox_1'] = $newmem['members_display_name'];
  1168. }
  1169.  
  1170. //-----------------------------------------
  1171. // Get ignored users
  1172. //-----------------------------------------
  1173.  
  1174. $perPage = 25;
  1175.  
  1176. /* Count */
  1177. $count = $this->DB->buildAndFetch( array( 'select' => 'count(*) as dracula', 'from' => 'ignored_users', 'where' => 'ignore_owner_id=' . $this->memberData['member_id'] ) );
  1178.  
  1179. /* Sort out pagination */
  1180. $st = intval($this->request['st']) >=0 ? intval($this->request['st']) : 0;
  1181. $pagination = $this->registry->output->generatePagination( array(
  1182. 'totalItems' => $count['dracula'],
  1183. 'itemsPerPage' => $perPage,
  1184. 'currentStartValue' => $st,
  1185. 'baseUrl' => 'app=core&module=usercp&tab=core&area=ignoredusers',
  1186. ) );
  1187.  
  1188. /* Get em */
  1189. $this->DB->build( array( 'select' => '*', 'from' => 'ignored_users', 'where' => 'ignore_owner_id=' . $this->memberData['member_id'], 'limit' => array( $st, $perPage ) ) );
  1190. $this->DB->execute();
  1191.  
  1192. while( $row = $this->DB->fetch() )
  1193. {
  1194. $ignoredUsers[ $row['ignore_ignore_id'] ] = $row;
  1195. }
  1196.  
  1197. //-----------------------------------------
  1198. // Get members and check to see if they've
  1199. // since been moved into a group that cannot
  1200. // be ignored
  1201. //-----------------------------------------
  1202.  
  1203. foreach( $ignoredUsers as $_id => $data )
  1204. {
  1205. if ( intval($_id) )
  1206. {
  1207. $temp_users[] = $_id;
  1208. }
  1209. }
  1210.  
  1211. if ( count($temp_users) )
  1212. {
  1213. $members = IPSMember::load( $temp_users, 'all' );
  1214.  
  1215. foreach( $members as $m )
  1216. {
  1217. $m['g_title'] = IPSMember::makeNameFormatted( $this->caches['group_cache'][ $m['member_group_id'] ]['g_title'], $m['member_group_id'] );
  1218.  
  1219. $final_users[ $m['member_id'] ] = IPSMember::buildDisplayData( $m );
  1220. $final_users[ $m['member_id'] ]['ignoreData'] = $ignoredUsers[ $m['member_id'] ];
  1221. }
  1222. }
  1223.  
  1224. $this->request['newbox_1'] = $this->request['newbox_1'] ? $this->request['newbox_1'] : '';
  1225.  
  1226. $result = $this->registry->getClass('output')->getTemplate('ucp')->membersIgnoredUsersForm( $final_users, $pagination );
  1227. $result = str_replace( "area=toggleIgnoredUser", "area=toggleIgnoredUser&amp;authKey=" . $this->member->form_hash, $result );
  1228. $result = str_replace( "area=removeIgnoredUser", "area=removeIgnoredUser&amp;authKey=" . $this->member->form_hash, $result );
  1229. return $result;
  1230. }
  1231.  
  1232.  
  1233. /**
  1234. * Show the signature page
  1235. *
  1236. * @author Matt Mecham
  1237. * @return string Processed HTML
  1238. */
  1239. public function formSignature()
  1240. {
  1241. /* Load editor stuff */
  1242. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite' );
  1243. $this->editor = new $classToLoad();
  1244.  
  1245. /* HTML checkbox language strings */
  1246. $this->registry->getClass('class_localization')->loadLanguageFile( array( 'public_post' ), 'forums' );
  1247.  
  1248. //-----------------------------------------
  1249. // Check to make sure that we can edit profiles..
  1250. //-----------------------------------------
  1251.  
  1252. $sig_restrictions = explode( ':', $this->memberData['g_signature_limits'] );
  1253.  
  1254. if ( ! $this->memberData['g_edit_profile'] OR ( $sig_restrictions[0] AND ! $this->memberData['g_sig_unit'] ) )
  1255. {
  1256. $this->registry->getClass('output')->showError( 'members_profile_disabled', 1024, null, null, 403 );
  1257. }
  1258.  
  1259. /* Signature Limits */
  1260. if ( $sig_restrictions[0] AND $this->memberData['g_sig_unit'] )
  1261. {
  1262. if ( $this->memberData['gbw_sig_unit_type'] )
  1263. {
  1264. /* days */
  1265. if ( $this->memberData['joined'] > ( time() - ( 86400 * $this->memberData['g_sig_unit'] ) ) )
  1266. {
  1267. $this->hide_form_and_save_button = 1;
  1268. $form['_noPerm'] = sprintf( $this->lang->words['sig_group_restrict_date'], $this->lang->getDate( $this->memberData['joined'] + ( 86400 * $this->memberData['g_sig_unit'] ), 'long' ) );
  1269. }
  1270. }
  1271. else
  1272. {
  1273. /* Posts */
  1274. if ( $this->memberData['posts'] < $this->memberData['g_sig_unit'] )
  1275. {
  1276. $this->hide_form_and_save_button = 1;
  1277. $form['_noPerm'] = sprintf( $this->lang->words['sig_group_restrict_posts'], $this->memberData['g_sig_unit'] - $this->memberData['posts'] );
  1278. }
  1279. }
  1280.  
  1281. if( $form['_noPerm'] )
  1282. {
  1283. return $this->registry->getClass('output')->getTemplate('ucp')->membersSignatureFormError( $form );
  1284. }
  1285. }
  1286.  
  1287. //-----------------------------------------
  1288. // Set max length
  1289. //-----------------------------------------
  1290.  
  1291. $current_sig = '';
  1292. $t_sig = '';
  1293.  
  1294. /* Set content in editor */
  1295. $this->editor->setLegacyMode(false);
  1296. $this->editor->setAllowBbcode( true );
  1297. $this->editor->setAllowSmilies( true );
  1298. $this->editor->setAllowHtml( $this->memberData['g_dohtml'] );
  1299. $this->editor->setIsHtml( $this->memberData['bw_html_sig'] );
  1300. $this->editor->setBbcodeSection('signatures');
  1301. $this->editor->setContent( $this->memberData['signature'] );
  1302.  
  1303. /* Load parser */
  1304. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/text/parser.php', 'classes_text_parser' );
  1305. $parser = new $classToLoad();
  1306.  
  1307. $parser->set( array( 'memberData' => $this->memberData,
  1308. 'parseBBCode' => 1,
  1309. 'parseHtml' => ( $this->memberData['g_dohtml'] && $this->memberData['bw_html_sig'] ),
  1310. 'parseArea' => 'signatures',
  1311. 'parseEmoticons' => 1 ) );
  1312.  
  1313. $signature = $parser->display( $this->memberData['signature'] );
  1314.  
  1315. return $this->registry->getClass('output')->getTemplate('ucp')->membersSignatureForm( $this->editor->show( 'Post', array( 'noSmilies' => false ) ), $sig_restrictions, $signature );
  1316. }
  1317.  
  1318.  
  1319. /**
  1320. * Show the profile information
  1321. *
  1322. * @author Matt Mecham
  1323. * @return string Processed HTML
  1324. */
  1325. public function formProfileInfo()
  1326. {
  1327. /* Load Lang File */
  1328. $this->registry->class_localization->loadLanguageFile( array( 'public_profile' ), 'members' );
  1329.  
  1330. /* Load editor stuff */
  1331. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite' );
  1332. $this->editor = new $classToLoad();
  1333.  
  1334. /* INIT */
  1335. $required_output = "";
  1336. $optional_output = "";
  1337.  
  1338. /* Permission Check */
  1339. if( ! $this->memberData['g_edit_profile'] )
  1340. {
  1341. $this->registry->getClass('output')->showError( 'members_profile_disabled', 1026, null, null, 403 );
  1342. }
  1343.  
  1344. /* Format the birthday drop boxes.. */
  1345. $date = getdate();
  1346.  
  1347. $day = array();
  1348. $mon = array();
  1349. $year = array();
  1350. $times = array();
  1351.  
  1352. /* Build the day options */
  1353. $day[] = array( '0', '--' );
  1354. for ( $i = 1 ; $i < 32 ; $i++ )
  1355. {
  1356. $day[] = array( $i, $i );
  1357. }
  1358.  
  1359. /* Build the month options */
  1360. $mon[] = array( '0', '--' );
  1361. for( $i = 1 ; $i < 13 ; $i++ )
  1362. {
  1363. $mon[] = array( $i, $this->lang->words['M_' . $i ] );
  1364. }
  1365.  
  1366. /* Build the years options */
  1367. $i = $date['year'] - 1;
  1368. $j = $date['year'] - 100;
  1369.  
  1370. $year[] = array( '0', '--' );
  1371. for( $i ; $j < $i ; $i-- )
  1372. {
  1373. $year[] = array( $i, $i );
  1374. }
  1375.  
  1376. /* Custom Fields */
  1377. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/customfields/profileFields.php', 'customProfileFields' );
  1378. $fields = new $classToLoad();
  1379.  
  1380. $fields->member_data = $this->member->fetchMemberData();
  1381. $fields->initData( 'edit' );
  1382. $fields->parseToEdit();
  1383.  
  1384. $field_output = array();
  1385.  
  1386. if ( count( $fields->out_fields ) )
  1387. {
  1388. foreach( $fields->out_fields as $id => $element )
  1389. {
  1390. $data = $fields->cache_data[ $id ];
  1391. $field_output[ $data['pf_group_key'] ][ $id ] = array(
  1392. 'field' => $this->registry->getClass('output')->getTemplate('ucp')->field_entry( $fields->field_names[ $id ], $fields->field_desc[ $id ], $fields->out_fields[ $id ], $id ),
  1393. 'required' => $data['pf_not_null']
  1394. );
  1395. }
  1396.  
  1397. /*foreach( $fields->out_fields as $id => $data )
  1398. {
  1399. if ( $fields->cache_data[ $id ]['pf_not_null'] == 1 )
  1400. {
  1401. $ftype = 'required_output';
  1402. }
  1403. else
  1404. {
  1405. $ftype = 'optional_output';
  1406. }
  1407.  
  1408. ${$ftype} .= $this->registry->getClass('output')->getTemplate('ucp')->field_entry( $fields->field_names[ $id ], $fields->field_desc[ $id ], $data, $id );
  1409. }*/
  1410. }
  1411.  
  1412. /* About me */
  1413. $this->editor->setContent( $this->memberData['pp_about_me'] );
  1414.  
  1415. $amEditor = $this->editor->show( 'Post', array( 'delayInit' => 1 ) );
  1416.  
  1417. /* Times */
  1418. foreach ( $this->lang->words as $k => $v )
  1419. {
  1420. if ( strpos( $k, "time_" ) === 0 )
  1421. {
  1422. $k = str_replace( "time_", '', $k );
  1423.  
  1424. if( preg_match( '/^[\-\d\.]+$/', $k ) )
  1425. {
  1426. $times[ $k ] = $v;
  1427. }
  1428. }
  1429. }
  1430.  
  1431. ksort( $times );
  1432.  
  1433. /* Build and return the form */
  1434. $template = $this->registry->getClass('output')->getTemplate('ucp')->membersProfileForm( $field_output, $fields->fetchGroupTitles(), $day, $mon, $year, $amEditor, $times );
  1435.  
  1436. return $template;
  1437. }
  1438.  
  1439. /**
  1440. * Show the logged inline notifications
  1441. *
  1442. * @author Brandon Farber
  1443. * @param string Error message
  1444. * @return string Processed HTML
  1445. */
  1446. public function showInlineNotifications( $error='' )
  1447. {
  1448. /* Init */
  1449. $start = intval( $this->request['st'] );
  1450. $perPage = 50;
  1451.  
  1452. //-----------------------------------------
  1453. // Get class
  1454. //-----------------------------------------
  1455.  
  1456. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' );
  1457. $notifyLibrary = new $classToLoad( $this->registry );
  1458. $notifyLibrary->setMember( $this->memberData );
  1459.  
  1460. /* Clear them? - used in mobile skin */
  1461. if ( isset($this->request['clear']) && trim($this->request['clear']) == 'true' AND $this->request['k'] == $this->member->form_hash )
  1462. {
  1463. $this->DB->update( 'inline_notifications', array( 'notify_read' => 1 ), 'notify_to_id=' . $this->memberData['member_id'] );
  1464.  
  1465. $notifyLibrary->rebuildUnreadCount();
  1466. }
  1467.  
  1468. //-----------------------------------------
  1469. // Turn off normal form
  1470. //-----------------------------------------
  1471.  
  1472. $this->hide_form_and_save_button = 1;
  1473.  
  1474. //-----------------------------------------
  1475. // Get notifications
  1476. //-----------------------------------------
  1477.  
  1478. $_notifications = array();
  1479. $mids = array();
  1480.  
  1481. $count = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as er',
  1482. 'from' => 'inline_notifications',
  1483. 'where' => 'notify_to_id=' . $this->memberData['member_id'] ) );
  1484.  
  1485. if ( $count['er'] )
  1486. {
  1487. $this->DB->build( array( 'select' => '*',
  1488. 'from' => 'inline_notifications',
  1489. 'where' => 'notify_to_id=' . $this->memberData['member_id'],
  1490. 'limit' => array( $start, $perPage ),
  1491. 'order' => 'notify_sent DESC' ) );
  1492. $outer = $this->DB->execute();
  1493.  
  1494. while( $r = $this->DB->fetch($outer) )
  1495. {
  1496. $r['notify_icon'] = $notifyLibrary->getNotificationIcon( $r['notify_type_key'] );
  1497.  
  1498. $_notifications[] = $r;
  1499.  
  1500. $mids[ $r['notify_from_id'] ] = $r['notify_from_id'];
  1501. }
  1502.  
  1503. /* Get members */
  1504. if ( count( $mids ) )
  1505. {
  1506. $members = IPSMember::load( array_keys( $mids ), 'all' );
  1507.  
  1508. if ( count( $members ) )
  1509. {
  1510. foreach( $_notifications as $key => $data )
  1511. {
  1512. if ( isset($members[ $data['notify_from_id'] ]) )
  1513. {
  1514. $_notifications[ $key ]['member'] = IPSMember::buildProfilePhoto( $members[ $data['notify_from_id'] ] );
  1515. }
  1516. }
  1517. }
  1518. }
  1519. }
  1520.  
  1521. $pages = $this->registry->getClass('output')->generatePagination( array( 'totalItems' => $count['er'],
  1522. 'itemsPerPage' => $perPage,
  1523. 'currentStartValue' => $start,
  1524. 'baseUrl' => "app=core&amp;module=usercp&amp;tab=core&amp;area=notificationlog"
  1525. ) );
  1526.  
  1527. //-----------------------------------------
  1528. // Send to template
  1529. //-----------------------------------------
  1530.  
  1531. return $this->registry->getClass('output')->getTemplate('ucp')->notificationsLog( $_notifications, $error, $pages );
  1532. }
  1533.  
  1534. /**
  1535. * Show notification configuration form
  1536. *
  1537. * @author Brandon Farber
  1538. * @return string Processed HTML
  1539. *
  1540. * @note Updating this function update also mobileApiRequest::_handleNotificationTypes()
  1541. */
  1542. public function showFormNotifications()
  1543. {
  1544. //-----------------------------------------
  1545. // Notifications library
  1546. //-----------------------------------------
  1547.  
  1548. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' );
  1549. $notifyLibrary = new $classToLoad( $this->registry );
  1550. $notifyLibrary->setMember( $this->memberData );
  1551.  
  1552. //-----------------------------------------
  1553. // Show the form
  1554. //-----------------------------------------
  1555.  
  1556. $_basicOptions = array( array( 'email', $this->lang->words['notopt__email'] ), array( 'inline', $this->lang->words['notopt__inline'] ), array( 'mobile', $this->lang->words['notopt__mobile'] ) );
  1557. $_configOptions = $notifyLibrary->getNotificationData( TRUE );
  1558. $_notifyConfig = $notifyLibrary->getMemberNotificationConfig( $this->memberData );
  1559. $_defaultConfig = $notifyLibrary->getDefaultNotificationConfig();
  1560. $_formOptions = array();
  1561.  
  1562. foreach( $_configOptions as $option )
  1563. {
  1564. $_thisConfig = isset($_notifyConfig[ $option['key'] ]) ? $_notifyConfig[ $option['key'] ] : $_defaultConfig[ $option['key'] ];
  1565.  
  1566. //-----------------------------------------
  1567. // Determine available options
  1568. //-----------------------------------------
  1569.  
  1570. $_available = array();
  1571.  
  1572. foreach( $_basicOptions as $_bo ) // ewwww :P
  1573. {
  1574. if( !is_array($_defaultConfig[ $option['key'] ]['disabled']) OR !in_array( $_bo[0], $_defaultConfig[ $option['key'] ]['disabled'] ) )
  1575. {
  1576. $_available[] = $_bo;
  1577. }
  1578. }
  1579.  
  1580. //-----------------------------------------
  1581. // If none available, at least give inline
  1582. //-----------------------------------------
  1583.  
  1584. if( !count($_available) )
  1585. {
  1586. $_available[] = array( 'inline', $this->lang->words['notify__inline'] );
  1587. }
  1588.  
  1589. //-----------------------------------------
  1590. // Start setting data to pass to form
  1591. //-----------------------------------------
  1592.  
  1593. $_formOptions[ $option['key'] ] = array();
  1594. $_formOptions[ $option['key'] ]['key'] = $option['key'];
  1595. $_formOptions[ $option['key'] ]['app'] = $option['app'];
  1596.  
  1597. //-----------------------------------------
  1598. // Rikki asked for this...
  1599. //-----------------------------------------
  1600.  
  1601. foreach( $_available as $_availOption )
  1602. {
  1603. $_formOptions[ $option['key'] ]['options'][ $_availOption[0] ] = $_availOption;
  1604. }
  1605.  
  1606. //$_formOptions[ $option['key'] ]['options'] = $_available;
  1607.  
  1608. $_formOptions[ $option['key'] ]['defaults'] = is_array($_thisConfig['selected']) ? $_thisConfig['selected'] : array();
  1609. $_formOptions[ $option['key'] ]['disabled'] = 0;
  1610.  
  1611. //-----------------------------------------
  1612. // Don't allow member to configure
  1613. // Still show, but disable on form
  1614. //-----------------------------------------
  1615.  
  1616. if( $_defaultConfig[ $option['key'] ]['disable_override'] )
  1617. {
  1618. $_formOptions[ $option['key'] ]['disabled'] = 1;
  1619. $_formOptions[ $option['key'] ]['defaults'] = is_array($_defaultConfig[ $option['key'] ]['selected']) ? $_defaultConfig[ $option['key'] ]['selected'] : array();
  1620. }
  1621. }
  1622.  
  1623. //-----------------------------------------
  1624. // Other settings
  1625. //-----------------------------------------
  1626.  
  1627. $_emailData = array();
  1628.  
  1629. //-----------------------------------------
  1630. // Email settings...
  1631. //-----------------------------------------
  1632.  
  1633. $_emailData['auto_track'] = $this->memberData['auto_track'] ? 'checked="checked"' : '';
  1634.  
  1635. foreach( array( 'none', 'immediate', 'offline', 'daily', 'weekly' ) as $_opt )
  1636. {
  1637. $_emailData['trackOption'][ $_opt ] = ( $this->memberData['auto_track'] == $_opt ) ? 'selected="selected"' : '';
  1638. }
  1639.  
  1640. return $this->registry->getClass('output')->getTemplate('ucp')->notificationsForm( $_formOptions, $_emailData );
  1641. }
  1642.  
  1643. /**
  1644. * Show the attachments form
  1645. *
  1646. * @author Matt Mecham
  1647. * @return string Processed HTML
  1648. */
  1649. public function showFormAttachments()
  1650. {
  1651. //-----------------------------------------
  1652. // INIT
  1653. //-----------------------------------------
  1654.  
  1655. $info = array();
  1656. $start = intval( $this->request['st'] );
  1657. $perpage = 15;
  1658. $sort_key = "";
  1659. $attachments = array();
  1660.  
  1661. $this->hide_form_and_save_button = 1;
  1662.  
  1663. //-----------------------------------------
  1664. // Sort it
  1665. //-----------------------------------------
  1666.  
  1667. switch ( $this->request['sort'] )
  1668. {
  1669. case 'date':
  1670. $sort_key = 'a.attach_date ASC';
  1671. $info['date_order'] = 'rdate';
  1672. $info['size_order'] = 'size';
  1673. break;
  1674. case 'rdate':
  1675. $sort_key = 'a.attach_date DESC';
  1676. $info['date_order'] = 'date';
  1677. $info['size_order'] = 'size';
  1678. break;
  1679. case 'size':
  1680. $sort_key = 'a.attach_filesize DESC';
  1681. $info['date_order'] = 'date';
  1682. $info['size_order'] = 'rsize';
  1683. break;
  1684. case 'rsize':
  1685. $sort_key = 'a.attach_filesize ASC';
  1686. $info['date_order'] = 'date';
  1687. $info['size_order'] = 'size';
  1688. break;
  1689. default:
  1690. $sort_key = 'a.attach_date DESC';
  1691. $info['date_order'] = 'date';
  1692. $info['size_order'] = 'size';
  1693. break;
  1694. }
  1695.  
  1696. //-----------------------------------------
  1697. // Get some stats...
  1698. //-----------------------------------------
  1699.  
  1700. $maxspace = intval($this->memberData['g_attach_max']);
  1701.  
  1702. if ( $this->memberData['g_attach_max'] == -1 )
  1703. {
  1704. $this->registry->getClass('output')->showError( 'no_permission_to_attach', 1010 );
  1705. }
  1706.  
  1707. //-----------------------------------------
  1708. // Limit by forums
  1709. //-----------------------------------------
  1710.  
  1711. $stats = $this->DB->buildAndFetch( array( 'select' => 'count(*) as count, ' . $this->DB->buildCoalesce( array( 'sum(attach_filesize)', 0 ) ) . ' as sum',
  1712. 'from' => 'attachments',
  1713. 'where' => 'attach_member_id=' . $this->memberData['member_id'] . " AND attach_rel_module IN( 'post', 'msg' )" ) );
  1714.  
  1715.  
  1716. if ( $maxspace > 0 )
  1717. {
  1718. //-----------------------------------------
  1719. // Figure out percentage used
  1720. //-----------------------------------------
  1721.  
  1722. $info['has_limit'] = 1;
  1723. $info['full_percent'] = $stats['sum'] ? sprintf( "%.0f", ( ( $stats['sum'] / ($maxspace * 1024) ) * 100) ) : 0;
  1724.  
  1725. if ( $info['full_percent'] > 100 )
  1726. {
  1727. $info['full_percent'] = 100;
  1728. }
  1729. else if ( $info['full_percent'] < 1 AND $stats['count'] > 0 )
  1730. {
  1731. $info['full_percent'] = 1;
  1732. }
  1733.  
  1734. $info['attach_space_count'] = sprintf( $this->lang->words['attach_space_count'], intval($stats['count']), intval($info['full_percent']) );
  1735. $info['attach_space_used'] = sprintf( $this->lang->words['attach_space_used'] , IPSLib::sizeFormat($stats['sum']), IPSLib::sizeFormat($maxspace * 1024) );
  1736. }
  1737. else
  1738. {
  1739. $info['has_limit'] = 0;
  1740. $info['attach_space_used'] = sprintf( $this->lang->words['attach_space_unl'] , IPSLib::sizeFormat($stats['sum']) );
  1741. }
  1742.  
  1743. //-----------------------------------------
  1744. // Pages
  1745. //-----------------------------------------
  1746.  
  1747. $pages = $this->registry->getClass('output')->generatePagination( array( 'totalItems' => $stats['count'],
  1748. 'itemsPerPage' => $perpage,
  1749. 'currentStartValue' => $start,
  1750. 'baseUrl' => "app=core&amp;module=usercp&amp;tab=core&amp;area=attachments&amp;sort=" . $this->request['sort'] . "",
  1751. ) );
  1752.  
  1753. //-----------------------------------------
  1754. // Get attachments...
  1755. //-----------------------------------------
  1756.  
  1757. if( $stats['count'] )
  1758. {
  1759. $this->DB->build( array( 'select' => 'a.*',
  1760. 'from' => array( 'attachments' => 'a' ),
  1761. 'where' => "a.attach_member_id=" . $this->memberData['member_id'] . " AND a.attach_rel_module IN( 'post', 'msg' )",
  1762. 'order' => $sort_key,
  1763. 'limit' => array( $start, $perpage ),
  1764. 'add_join' => array(
  1765. array( 'select' => 'p.topic_id',
  1766. 'from' => array( 'posts' => 'p' ),
  1767. 'where' => 'p.pid=a.attach_rel_id',
  1768. 'type' => 'left'
  1769. ),
  1770. array( 'select' => 't.*',
  1771. 'from' => array( 'topics' => 't' ),
  1772. 'where' => 't.tid=p.topic_id',
  1773. 'type' => 'left'
  1774. ) )
  1775. ) );
  1776. $outer = $this->DB->execute();
  1777.  
  1778. $this->registry->getClass( 'class_localization')->loadLanguageFile( array( 'public_topic' ), 'forums' );
  1779.  
  1780. $cache = $this->cache->getCache('attachtypes');
  1781.  
  1782. /* Load topic class */
  1783. if ( ! $this->registry->isClassLoaded('topics') )
  1784. {
  1785. $classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . "/sources/classes/topics.php", 'app_forums_classes_topics', 'forums' );
  1786. $this->registry->setClass( 'topics', new $classToLoad( $this->registry ) );
  1787. }
  1788.  
  1789. while ( $row = $this->DB->fetch( $outer ) )
  1790. {
  1791. $row['_link'] = true;
  1792.  
  1793. if ( ! $this->registry->topics->canView( $row ) )
  1794. {
  1795. $row['title'] = $this->lang->words['attach_topicmoved'];
  1796. $row['_link'] = false;
  1797. }
  1798.  
  1799. //-----------------------------------------
  1800. // Full attachment thingy
  1801. //-----------------------------------------
  1802.  
  1803. if ( $row['attach_rel_module'] == 'post' )
  1804. {
  1805. $row['_type'] = 'post';
  1806. }
  1807. else if ( $row['attach_rel_module'] == 'msg' )
  1808. {
  1809. $row['_type'] = 'msg';
  1810. $row['title'] = $this->lang->words['attach_inpm'];
  1811. }
  1812.  
  1813. /* IPB 2.x conversion */
  1814. $row['image'] = str_replace( 'folder_mime_types', 'mime_types', $cache[ $row['attach_ext'] ]['atype_img'] );
  1815. $row['short_name'] = IPSText::truncate( $row['attach_file'], 30 );
  1816. $row['attach_date'] = $this->registry->getClass( 'class_localization')->getDate( $row['attach_date'], 'SHORT' );
  1817. $row['real_size'] = IPSLib::sizeFormat( $row['attach_filesize'] );
  1818.  
  1819. $attachments[] = $row;
  1820. }
  1821. }
  1822.  
  1823. return $this->registry->getClass('output')->getTemplate('ucp')->coreAttachments( $info, $pages, $attachments );
  1824. }
  1825.  
  1826. /**
  1827. * Show the Email & Password form
  1828. *
  1829. * @author Matt Mecham
  1830. * @param string Returned error message (if any)
  1831. * @return string Processed HTML
  1832. */
  1833. public function showFormEmailPassword( $_message='' )
  1834. {
  1835. //-----------------------------------------
  1836. // Do not allow validating members to change
  1837. // email when admin validation is on
  1838. // @see http://community.invisionpower.com/tracker/issue-19964-loophole-in-registration-procedure/
  1839. //-----------------------------------------
  1840.  
  1841. if( $this->memberData['member_group_id'] == $this->settings['auth_group'] AND in_array( $this->settings['reg_auth_type'], array( 'admin', 'admin_user' ) ) )
  1842. {
  1843. $this->registry->output->showError( $this->lang->words['admin_val_no_email_chg'], 10189 );
  1844. }
  1845.  
  1846. //-----------------------------------------
  1847. // Do we have another URL for email resets?
  1848. //-----------------------------------------
  1849.  
  1850. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/handlers/han_login.php', 'han_login' );
  1851. $this->han_login = new $classToLoad( $this->registry );
  1852. $this->han_login->init();
  1853. $this->han_login->checkMaintenanceRedirect();
  1854.  
  1855. //$txt = $this->lang->words['ce_current'] . $this->memberData['email'];
  1856.  
  1857. if ( $this->settings['reg_auth_type'])
  1858. {
  1859. $txt .= $this->lang->words['ce_auth'];
  1860. }
  1861.  
  1862. $_message = $_message ? $this->lang->words[$_message] : '';
  1863.  
  1864. if( $this->memberData['g_access_cp'] )
  1865. {
  1866. $this->hide_form_and_save_button = true;
  1867. }
  1868.  
  1869. return $this->registry->getClass('output')->getTemplate('ucp')->emailPasswordChangeForm( $txt, $_message, $this->_isFBUser );
  1870. }
  1871.  
  1872. /**
  1873. * Show the display name form
  1874. *
  1875. * @author Matt Mecham
  1876. * @param string Error message (if any)
  1877. * @return string Processed HTML
  1878. */
  1879. public function showFormDisplayname( $error="" )
  1880. {
  1881. //-----------------------------------------
  1882. // INIT
  1883. //-----------------------------------------
  1884.  
  1885. $form = array();
  1886.  
  1887. //-----------------------------------------
  1888. // CHECK (please)
  1889. //-----------------------------------------
  1890.  
  1891. if ( ! $this->settings['auth_allow_dnames'] OR $this->memberData['g_dname_changes'] == 0 OR $this->memberData['g_dname_date'] == 0 )
  1892. {
  1893. $this->registry->getClass('output')->showError( 'no_permission_for_display_names', 1011 );
  1894. }
  1895.  
  1896. $this->request['display_name'] = $this->request['display_name'] ? $this->request['display_name'] : '';
  1897.  
  1898. $this->settings['username_errormsg'] = str_replace( '{chars}', $this->settings['username_characters'], $this->settings['username_errormsg'] );
  1899.  
  1900. //-----------------------------------------
  1901. // Grab # changes > 24 hours
  1902. //-----------------------------------------
  1903.  
  1904. $time_check = time() - 86400 * $this->memberData['g_dname_date'];
  1905.  
  1906. if( $time_check < $this->memberData['joined'] )
  1907. {
  1908. $time_check = $this->memberData['joined'];
  1909. }
  1910.  
  1911. $name_count = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as count, MIN(dname_date) as min_date', 'from' => 'dnames_change', 'where' => "dname_member_id=" . $this->memberData['member_id'] . " AND dname_date > $time_check AND dname_discount=0" ) );
  1912.  
  1913. $name_count['count'] = intval( $name_count['count'] );
  1914. $name_count['min_date'] = intval( $name_count['min_date'] ) ? intval( $name_count['min_date'] ) : $time_check;
  1915.  
  1916. //-----------------------------------------
  1917. // Calculate # left
  1918. //-----------------------------------------
  1919.  
  1920. /* Check new permissions */
  1921. $_g = $this->caches['group_cache'][ $this->memberData['member_group_id'] ];
  1922.  
  1923. if ( $_g['g_displayname_unit'] )
  1924. {
  1925. if ( $_g['gbw_displayname_unit_type'] )
  1926. {
  1927. /* days */
  1928. if ( $this->memberData['joined'] > ( time() - ( 86400 * $_g['g_displayname_unit'] ) ) )
  1929. {
  1930. $this->hide_form_and_save_button = 1;
  1931. $form['_noPerm'] = sprintf( $this->lang->words['dname_group_restrict_date'], $this->lang->getDate( $this->memberData['joined'] + ( 86400 * $_g['g_displayname_unit'] ), 'long' ) );
  1932. }
  1933. }
  1934. else
  1935. {
  1936. /* Posts */
  1937. if ( $this->memberData['posts'] < $_g['g_displayname_unit'] )
  1938. {
  1939. $this->hide_form_and_save_button = 1;
  1940. $form['_noPerm'] = sprintf( $this->lang->words['dname_group_restrict_posts'], $_g['g_displayname_unit'] - $this->memberData['posts'] );
  1941. }
  1942. }
  1943. }
  1944.  
  1945. if( !$form['_noPerm'] )
  1946. {
  1947. if ( $this->memberData['g_dname_changes'] == -1 )
  1948. {
  1949. $form['_lang_string'] = $this->lang->words['dname_string2'];
  1950. }
  1951. else
  1952. {
  1953. $form['_changes_left'] = $this->memberData['g_dname_changes'] - $name_count['count'];
  1954. $form['_changes_done'] = $name_count['count'];
  1955.  
  1956. # Make sure changes done isn't larger than allowed
  1957. # This happens when changing via ACP
  1958.  
  1959. if ( $form['_changes_done'] > $this->memberData['g_dname_changes'] )
  1960. {
  1961. $form['_changes_done'] = $this->memberData['g_dname_changes'];
  1962. }
  1963.  
  1964. $form['_first_change'] = $this->registry->getClass( 'class_localization')->getDate( $name_count['min_date'], 'date', 1 );
  1965. $form['_lang_string'] = sprintf( $this->lang->words['dname_string'],
  1966. $form['_changes_done'], $this->memberData['g_dname_changes'],
  1967. $form['_first_change'], $this->memberData['g_dname_changes'],
  1968. $this->memberData['g_dname_date'] ) . $this->lang->words['dname_string2'];
  1969. }
  1970. }
  1971.  
  1972. //-----------------------------------------
  1973. // Print
  1974. //-----------------------------------------
  1975.  
  1976. $this->_pageTitle = $this->lang->words['m_dname_change'];
  1977.  
  1978. return $this->registry->getClass('output')->getTemplate('ucp')->displayNameForm( $form, $error, '', $this->_isFBUser );
  1979. }
  1980.  
  1981. /**
  1982. * UserCP Form Check
  1983. *
  1984. * @author Matt Mecham
  1985. * @param string Current area as defined by 'get_links'
  1986. * @return string Processed HTML
  1987. */
  1988. public function saveForm( $current_area )
  1989. {
  1990. //-----------------------------------------
  1991. // Where to go, what to see?
  1992. //-----------------------------------------
  1993.  
  1994. switch( $current_area )
  1995. {
  1996. default:
  1997. case 'profileinfo':
  1998. return $this->saveProfileInfo();
  1999. break;
  2000. case 'signature':
  2001. return $this->saveSignature();
  2002. break;
  2003. case 'photo':
  2004. return $this->savePhoto();
  2005. break;
  2006. case 'ignoredusers':
  2007. return $this->saveIgnoredUsers();
  2008. break;
  2009. case 'facebook':
  2010. return $this->saveFacebook();
  2011. break;
  2012. case 'twitter':
  2013. return $this->saveTwitter();
  2014. break;
  2015. case 'customize':
  2016. return $this->saveCustomize();
  2017. break;
  2018. case 'email':
  2019. return $this->saveFormEmailPassword();
  2020. break;
  2021. case 'password':
  2022. return $this->saveFormPassword();
  2023. break;
  2024. case 'displayname':
  2025. return $this->saveFormDisplayname();
  2026. break;
  2027. case 'notifications':
  2028. return $this->saveFormNotifications();
  2029. break;
  2030. }
  2031. }
  2032.  
  2033. /**
  2034. * UserCP Save Form: Customize
  2035. *
  2036. * @return array Errors
  2037. */
  2038. public function saveCustomize()
  2039. {
  2040. /* Init */
  2041. $errors = array();
  2042. $custom = array();
  2043. $bg_nix = trim( $this->request['bg_nix'] );
  2044. $bg_url = trim( $this->request['bg_url'] );
  2045. $bg_tile = intval( $this->request['bg_tile'] );
  2046. $bg_color = trim( str_replace( '#', '', $this->request['bg_color'] ) );
  2047.  
  2048. /* reset custom */
  2049. $custom = IPSLib::safeUnserialize( $this->memberData['pp_customization'] );
  2050.  
  2051. /* Bug #21578 */
  2052. if( ! $bg_color && $custom['bg_color'] )
  2053. {
  2054. $bg_color = $custom['bg_color'];
  2055. }
  2056.  
  2057. /* Delete all? */
  2058. if ( $bg_nix )
  2059. {
  2060. /* reset array */
  2061. $custom = array( 'bg_url' => '', 'type' => '', 'bg_color' => '', 'bg_tile' => '' );
  2062.  
  2063. /* remove bg images */
  2064. IPSMember::getFunction()->removeUploadedBackgroundImages( $this->memberData['member_id'] );
  2065. }
  2066. else
  2067. {
  2068. if ( $bg_url AND $this->memberData['gbw_allow_url_bgimage'] )
  2069. {
  2070. /* Check */
  2071. if ( ! stristr( $bg_url, 'http://' ) OR preg_match( '#\(\*#', $bg_url ) )
  2072. {
  2073. return array( 0 => $this->lang->words['pp_bgimg_url_bad'] );
  2074. }
  2075.  
  2076. $image_extension = strtolower( pathinfo( $bg_url, PATHINFO_EXTENSION ) );
  2077.  
  2078. if( ! in_array( $image_extension, array( 'png', 'jpg', 'gif', 'jpeg' ) ) )
  2079. {
  2080. return array( 0 => $this->lang->words['pp_bgimg_ext_bad'] );
  2081. }
  2082.  
  2083. $custom['bg_url'] = $bg_url;
  2084. $custom['type'] = 'url';
  2085. }
  2086. else if ( $this->memberData['gbw_allow_upload_bgimage'] )
  2087. {
  2088. /* Load more lang strings */
  2089. $this->registry->class_localization->loadLanguageFile( array( 'public_profile' ), 'members' );
  2090.  
  2091. /* Upload img */
  2092. $img = IPSMember::getFunction()->uploadBackgroundImage();
  2093.  
  2094. if ( $img['status'] == 'fail' )
  2095. {
  2096. return array( 0 => sprintf( $this->lang->words[ 'pp_' . $img['error'] ], $img['maxSize'] ) );
  2097. }
  2098. else if ( $img['final_location'] )
  2099. {
  2100. $custom['bg_url'] = $img['final_location'];
  2101. $custom['type'] = 'upload';
  2102. }
  2103. }
  2104. }
  2105.  
  2106. /* BG color */
  2107. $custom['bg_color'] = $bg_nix ? '' : IPSText::alphanumericalClean( $bg_color );
  2108.  
  2109. /* Tile */
  2110. $custom['bg_tile'] = $bg_nix ? '' : $bg_tile;
  2111.  
  2112. /* Save it */
  2113. if ( ! $this->memberData['bw_disable_customization'] AND $this->memberData['gbw_allow_customization'] )
  2114. {
  2115. IPSMember::save( $this->memberData['member_id'], array( 'extendedProfile' => array( 'pp_profile_update' => IPS_UNIX_TIME_NOW, 'pp_customization' => serialize( $custom ) ) ) );
  2116. }
  2117.  
  2118. return TRUE;
  2119. }
  2120.  
  2121. /**
  2122. * UserCP Save Form: Twitter
  2123. *
  2124. * @return array Errors
  2125. */
  2126. public function saveTwitter()
  2127. {
  2128. if( !IPSLib::twitter_enabled() )
  2129. {
  2130. $this->registry->getClass('output')->showError( 'twitter_disabled', 1005.2 );
  2131. }
  2132.  
  2133. //-----------------------------------------
  2134. // Data
  2135. //-----------------------------------------
  2136.  
  2137. $toSave = IPSBWOptions::thaw( $this->memberData['tc_bwoptions'], 'twitter' );
  2138.  
  2139. //-----------------------------------------
  2140. // Loop and save... simple
  2141. //-----------------------------------------
  2142.  
  2143. foreach( array( 'tc_s_pic', 'tc_s_status', 'tc_s_aboutme', 'tc_s_bgimg', 'tc_si_status' ) as $field )
  2144. {
  2145. $toSave[ $field ] = intval( $this->request[ $field ] );
  2146. }
  2147.  
  2148. $this->memberData['tc_bwoptions'] = IPSBWOptions::freeze( $toSave, 'twitter' );
  2149. $return = IPSMember::save( $this->memberData['member_id'], array( 'extendedProfile' => array( 'tc_bwoptions' => $this->memberData['tc_bwoptions'] ) ) );
  2150.  
  2151. //-----------------------------------------
  2152. // Now sync
  2153. //-----------------------------------------
  2154.  
  2155. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/twitter/connect.php', 'twitter_connect' );
  2156. $twitter = new $classToLoad( $this->registry, $this->memberData['twitter_token'], $this->memberData['twitter_secret'] );
  2157.  
  2158. try
  2159. {
  2160. $twitter->syncMember( $this->memberData );
  2161. }
  2162. catch( Exception $error )
  2163. {
  2164. $msg = $error->getMessage();
  2165.  
  2166. switch( $msg )
  2167. {
  2168. case 'NOT_LINKED':
  2169. case 'NO_MEMBER':
  2170. break;
  2171. }
  2172. }
  2173.  
  2174. return TRUE;
  2175. }
  2176.  
  2177. /**
  2178. * UserCP Save Form: Facebook
  2179. *
  2180. * @return array Errors
  2181. */
  2182. public function saveFacebook()
  2183. {
  2184. if( !IPSLib::fbc_enabled() )
  2185. {
  2186. $this->registry->getClass('output')->showError( 'fbc_disabled', 1005 );
  2187. }
  2188.  
  2189. //-----------------------------------------
  2190. // Data
  2191. //-----------------------------------------
  2192.  
  2193. $toSave = IPSBWOptions::thaw( $this->memberData['members_bitoptions'], 'members' );
  2194.  
  2195. //-----------------------------------------
  2196. // Loop and save... simple
  2197. //-----------------------------------------
  2198.  
  2199. foreach( array( 'fbc_s_pic', 'fbc_s_status', 'fbc_s_aboutme', 'fbc_si_status' ) as $field )
  2200. {
  2201. $toSave[ $field ] = intval( $this->request[ $field ] );
  2202. }
  2203.  
  2204. $this->memberData['fb_bwoptions'] = IPSBWOptions::freeze( $toSave, 'facebook' );
  2205. IPSMember::save( $this->memberData['member_id'], array( 'extendedProfile' => array( 'fb_bwoptions' => $this->memberData['fb_bwoptions'] ) ) );
  2206.  
  2207. //-----------------------------------------
  2208. // Now sync
  2209. //-----------------------------------------
  2210.  
  2211. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/facebook/connect.php', 'facebook_connect' );
  2212. $facebook = new $classToLoad( $this->registry );
  2213.  
  2214. try
  2215. {
  2216. $facebook->syncMember( $this->memberData );
  2217. }
  2218. catch( Exception $error )
  2219. {
  2220. $msg = $error->getMessage();
  2221.  
  2222. switch( $msg )
  2223. {
  2224. case 'NOT_LINKED':
  2225. case 'NO_MEMBER':
  2226. break;
  2227. }
  2228. }
  2229.  
  2230. return TRUE;
  2231. }
  2232.  
  2233. /**
  2234. * UserCP Save Form: Ignore Users
  2235. *
  2236. * @return array Errors
  2237. */
  2238. public function saveIgnoredUsers()
  2239. {
  2240. //-----------------------------------------
  2241. // INIT
  2242. //-----------------------------------------
  2243.  
  2244. $newName = $this->request['newbox_1'];
  2245. $dnvs = intval( $this->request['donot_view_sigs'] );
  2246.  
  2247. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'view_sigs' => ( $dnvs ) ? 0 : 1 ) ) );
  2248.  
  2249. if ( trim( $newName ) && $_POST['newbox_1'] != $this->lang->words['ucp_members_name'] )
  2250. {
  2251. //-----------------------------------------
  2252. // Load
  2253. //-----------------------------------------
  2254.  
  2255. $member = IPSMember::load( $newName, 'core', 'displayname' );
  2256.  
  2257. if ( ! $member['member_id'] )
  2258. {
  2259. return array( 0 => $this->lang->words['ignoreuser_nomem'] );
  2260. }
  2261.  
  2262. if ( $member['member_id'] == $this->memberData['member_id'] )
  2263. {
  2264. return array( 0 => $this->lang->words['ignoreuser_cannot'] );
  2265. }
  2266.  
  2267. //-----------------------------------------
  2268. // Already ignoring?
  2269. //-----------------------------------------
  2270.  
  2271. $ignoreMe = $this->DB->buildAndFetch( array(
  2272. 'select' => '*',
  2273. 'from' => 'ignored_users',
  2274. 'where' => 'ignore_owner_id=' . $this->memberData['member_id'] . ' AND ignore_ignore_id=' . $member['member_id']
  2275. ) );
  2276.  
  2277. if ( $ignoreMe['ignore_id'] )
  2278. {
  2279. return array( 0 => $this->lang->words['ignoreuser_already'] );
  2280. }
  2281.  
  2282. //-----------------------------------------
  2283. // Can we ignore them?
  2284. //-----------------------------------------
  2285.  
  2286. if ( $member['_canBeIgnored'] !== TRUE )
  2287. {
  2288. return array( 0 => $this->lang->words['ignoreuser_cannot'] );
  2289. }
  2290.  
  2291. //-----------------------------------------
  2292. // Add it
  2293. //-----------------------------------------
  2294.  
  2295. $this->DB->insert( 'ignored_users', array(
  2296. 'ignore_owner_id' => $this->memberData['member_id'],
  2297. 'ignore_ignore_id' => $member['member_id'],
  2298. 'ignore_messages' => !empty( $this->request['ignore_messages'] ) ? 1 : 0,
  2299. 'ignore_topics' => !empty( $this->request['ignore_topics'] ) ? 1 : 0,
  2300. 'ignore_signatures' => !empty( $this->request['ignore_signatures'] ) ? 1 : 0,
  2301. 'ignore_chats' => !empty( $this->request['ignore_chats'] ) ? 1 : 0,
  2302. )
  2303. );
  2304.  
  2305. /* Rebuild cache */
  2306. IPSMember::rebuildIgnoredUsersCache( $this->memberData );
  2307. }
  2308.  
  2309. return TRUE;
  2310. }
  2311.  
  2312.  
  2313. /**
  2314. * UserCP Save Form: Signature
  2315. *
  2316. * @return array Errors
  2317. */
  2318. public function saveSignature()
  2319. {
  2320. /* Load editor stuff */
  2321. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite' );
  2322. $this->editor = new $classToLoad();
  2323. $this->editor->setLegacyMode(false);
  2324.  
  2325. $isHtml = intval( $this->request['sig_htmlstatus'] );
  2326.  
  2327. //-----------------------------------------
  2328. // Check to make sure that we can edit profiles..
  2329. //-----------------------------------------
  2330.  
  2331. $sig_restrictions = explode( ':', $this->memberData['g_signature_limits'] );
  2332.  
  2333. if ( ! $this->memberData['g_edit_profile'] OR ( $sig_restrictions[0] AND ! $this->memberData['g_sig_unit'] ) )
  2334. {
  2335. $this->registry->getClass('output')->showError( 'members_profile_disabled', 1028, null, null, 403 );
  2336. }
  2337.  
  2338. //-----------------------------------------
  2339. // Post process the editor
  2340. // Now we have safe HTML and bbcode
  2341. //-----------------------------------------
  2342.  
  2343. /* Set content in editor */
  2344. $this->editor->setAllowBbcode( true );
  2345. $this->editor->setAllowSmilies( true );
  2346. $this->editor->setIsHtml( $this->memberData['g_dohtml'] && $isHtml );
  2347. $this->editor->setBbcodeSection('signatures');
  2348. $this->editor->setContent( $this->memberData['signature'] );
  2349.  
  2350. $signature = $this->editor->process( $_POST['Post'] );
  2351.  
  2352. //-----------------------------------------
  2353. // Parse post
  2354. //-----------------------------------------
  2355.  
  2356. /* Load parser */
  2357. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/text/parser.php', 'classes_text_parser' );
  2358. $parser = new $classToLoad();
  2359.  
  2360. $parser->testForParsingLimits( $signature, array( 'quote', 'emoticons', 'urls' ) );
  2361.  
  2362. if ( is_array( $parser->getErrors() ) && count( $parser->getErrors() ) )
  2363. {
  2364. $this->lang->loadLanguageFile( array( 'public_post' ), 'forums' );
  2365.  
  2366. $_errors = $parser->getErrors();
  2367. $_error = array_pop( $_errors );
  2368. $this->registry->getClass('output')->showError( $_error, 10210 );
  2369. }
  2370.  
  2371. //-----------------------------------------
  2372. // Signature restrictions...
  2373. //-----------------------------------------
  2374.  
  2375. $sig_errors = array();
  2376.  
  2377. //-----------------------------------------
  2378. // Max number of images...
  2379. //-----------------------------------------
  2380.  
  2381. if( isset($sig_restrictions[1]) and $sig_restrictions[1] !== '' )
  2382. {
  2383. if( $parser->getImageCount( $signature ) > $sig_restrictions[1] )
  2384. {
  2385. $sig_errors[] = sprintf( $this->lang->words['sig_toomanyimages'], $sig_restrictions[1] );
  2386. }
  2387. }
  2388.  
  2389. //-----------------------------------------
  2390. // Max number of urls...
  2391. //-----------------------------------------
  2392.  
  2393. if( isset($sig_restrictions[4]) and $sig_restrictions[4] !== '' )
  2394. {
  2395. if( $parser->getUrlCount( $signature ) > $sig_restrictions[4] )
  2396. {
  2397. $sig_errors[] = sprintf( $this->lang->words['sig_toomanyurls'], $sig_restrictions[4] );
  2398. }
  2399. else
  2400. {
  2401. preg_match_all( '#(^|\s|>)((http|https|news|ftp)://\w+[^\s\[\]\<]+)#is', $signature, $matches );
  2402.  
  2403. if( count($matches[1]) > $sig_restrictions[4] )
  2404. {
  2405. $sig_errors[] = sprintf( $this->lang->words['sig_toomanyurls'], $sig_restrictions[4] );
  2406. }
  2407. }
  2408. }
  2409.  
  2410. $this->settings['signature_line_length'] = $this->settings['signature_line_length'] > 0 ? $this->settings['signature_line_length'] : 200;
  2411.  
  2412. /* You can't wordwrap on HTML http://community.invisionpower.com/resources/bugs.html/_/ip-board/signature-url-bbcode-r41254 */
  2413. //$signature = wordwrap( $signature, $this->settings['signature_line_length'], '</p>', true );
  2414.  
  2415. // http://community.invisionpower.com/tracker/issue-35105-signature-restriction-minor-bug
  2416. $signature = preg_replace( '#^\s*(</p>)+#i', '', $signature );
  2417. $signature = preg_replace( '#(</p>)+?\s*$#i', '', $signature );
  2418.  
  2419. //-----------------------------------------
  2420. // Max number of lines of text...
  2421. //-----------------------------------------
  2422.  
  2423. if( isset($sig_restrictions[5]) and $sig_restrictions[5] !== '' )
  2424. {
  2425. $lineCount = substr_count( $signature, "</p>" ) + substr_count( $signature, "br>" );
  2426.  
  2427. if( $lineCount >= $sig_restrictions[5] )
  2428. {
  2429. $sig_errors[] = sprintf( $this->lang->words['sig_toomanylines'], $sig_restrictions[5] );
  2430. }
  2431. }
  2432.  
  2433. //-----------------------------------------
  2434. // Now the crappy part..
  2435. //-----------------------------------------
  2436.  
  2437. if( isset($sig_restrictions[2]) and $sig_restrictions[2] !== '' AND isset($sig_restrictions[3]) and $sig_restrictions[3] !== '' )
  2438. {
  2439. preg_match_all( '/\<img([^>]+?)>/i', $signature, $allImages );
  2440.  
  2441. if( count($allImages[1]) )
  2442. {
  2443. foreach( $allImages[1] as $foundImage )
  2444. {
  2445. preg_match( '#src=[\'"]([^\'"]+?)[\'"]#i', $foundImage, $url );
  2446. $imageProperties = @getimagesize( $url[1] );
  2447.  
  2448. if( is_array($imageProperties) AND count($imageProperties) )
  2449. {
  2450. if( $imageProperties[0] > $sig_restrictions[2] OR $imageProperties[1] > $sig_restrictions[3] )
  2451. {
  2452. $sig_errors[] = sprintf( $this->lang->words['sig_imagetoobig'], $url[1], $sig_restrictions[2], $sig_restrictions[3] );
  2453. }
  2454. }
  2455. else
  2456. {
  2457. $sig_errors[] = $this->lang->words['sig_imagenotretrievable'];
  2458. }
  2459. }
  2460. }
  2461. }
  2462.  
  2463. if( count($sig_errors) )
  2464. {
  2465. $this->registry->getClass('output')->showError( implode( '<br />', $sig_errors ), 10211 );
  2466. }
  2467.  
  2468. /* Save HTML status */
  2469. $members_bitoptions = IPSBWOptions::thaw( $this->memberData['members_bitoptions'], 'members', 'global' );
  2470. $members_bitoptions['bw_html_sig'] = $isHtml;
  2471.  
  2472. //-----------------------------------------
  2473. // Write it to the DB.
  2474. //-----------------------------------------
  2475.  
  2476. IPSMember::save( $this->memberData['member_id'], array( 'members' => $members_bitoptions, 'extendedProfile' => array( 'signature' => $signature ) ) );
  2477.  
  2478. /* Update cache */
  2479. IPSContentCache::update( $this->memberData['member_id'], 'sig', $parser->display( $signature ) );
  2480.  
  2481. return TRUE;
  2482. }
  2483.  
  2484.  
  2485. /**
  2486. * UserCP Save Form: Profile Info
  2487. *
  2488. * @return array Errors
  2489. */
  2490. public function saveProfileInfo()
  2491. {
  2492. /* Load editor stuff */
  2493. if( $this->request['updateAboutMe'] )
  2494. {
  2495. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite' );
  2496. $this->editor = new $classToLoad();
  2497. $this->editor->setLegacyMode(false);
  2498. }
  2499.  
  2500. //-----------------------------------------
  2501. // INIT
  2502. //-----------------------------------------
  2503.  
  2504. $pp_setting_moderate_comments = intval( $this->request['pp_setting_moderate_comments'] );
  2505. $pp_setting_moderate_friends = intval( $this->request['pp_setting_moderate_friends'] );
  2506. $pp_setting_count_visitors = intval( $this->request['pp_setting_count_visitors'] );
  2507. $pp_setting_count_comments = intval( $this->request['pp_setting_count_comments'] );
  2508. $pp_setting_count_friends = intval( $this->request['pp_setting_count_friends'] );
  2509.  
  2510. //-----------------------------------------
  2511. // Check to make sure that we can edit profiles..
  2512. //-----------------------------------------
  2513.  
  2514. if ( ! $this->memberData['g_edit_profile'] )
  2515. {
  2516. $this->registry->getClass('output')->showError( 'members_profile_disabled', 10214, null, null, 403 );
  2517. }
  2518.  
  2519. //-----------------------------------------
  2520. // make sure that either we entered
  2521. // all calendar fields, or we left them
  2522. // all blank
  2523. //-----------------------------------------
  2524.  
  2525. $c_cnt = 0;
  2526.  
  2527. foreach ( array('day','month','year') as $v )
  2528. {
  2529. if ( $this->request[ $v ] )
  2530. {
  2531. $c_cnt++;
  2532. }
  2533. }
  2534.  
  2535. if( $c_cnt > 0 && $c_cnt < 2 )
  2536. {
  2537. $this->registry->getClass('output')->showError( 'member_bad_birthday', 10215 );
  2538. }
  2539. else if( $c_cnt > 0 )
  2540. {
  2541. //-----------------------------------------
  2542. // Make sure it's a legal date
  2543. //-----------------------------------------
  2544.  
  2545. $_year = $this->request['year'] ? $this->request['year'] : 2000;
  2546.  
  2547. if ( ! checkdate( $this->request['month'], $this->request['day'], $_year ) )
  2548. {
  2549. $this->registry->getClass('output')->showError( 'member_bad_birthday', 10216 );
  2550. }
  2551. }
  2552.  
  2553. //-----------------------------------------
  2554. // Start off our array
  2555. //-----------------------------------------
  2556.  
  2557. $core = array( 'bday_day' => $this->request['day'],
  2558. 'bday_month' => $this->request['month'],
  2559. 'bday_year' => $this->request['year'],
  2560. );
  2561.  
  2562. $extendedProfile = array( 'pp_setting_moderate_comments' => $pp_setting_moderate_comments,
  2563. 'pp_setting_moderate_friends' => $pp_setting_moderate_friends,
  2564. 'pp_setting_count_visitors' => $pp_setting_count_visitors,
  2565. 'pp_setting_count_comments' => $pp_setting_count_comments,
  2566. 'pp_setting_count_friends' => $pp_setting_count_friends );
  2567.  
  2568. //-----------------------------------------
  2569. // check to see if we can enter a member title
  2570. // and if one is entered, update it.
  2571. //-----------------------------------------
  2572.  
  2573. if( isset( $this->request['member_title'] ) and ( $this->settings['post_titlechange'] == -1 or ( $this->settings['post_titlechange'] and $this->memberData['posts'] >= $this->settings['post_titlechange'] ) ) )
  2574. {
  2575. $core['title'] = IPSText::getTextClass('bbcode')->stripBadWords( $this->request['member_title'] );
  2576. }
  2577.  
  2578. //-----------------------------------------
  2579. // Custom profile field stuff
  2580. //-----------------------------------------
  2581.  
  2582. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/customfields/profileFields.php', 'customProfileFields' );
  2583. $fields = new $classToLoad();
  2584.  
  2585. $fields->member_data = $this->member->fetchMemberData();
  2586. $fields->initData( 'edit' );
  2587. /* Use $_POST and not ipsRegistry::$request as the custom profile field kernel class has its own cleaning routines for saving and showing
  2588. which means we end up with double & -> &amp; conversion (&amp;lt;, etc) */
  2589. $fields->parseToSave( $_POST );
  2590.  
  2591. if( $fields->error_messages )
  2592. {
  2593. return $fields->error_messages;
  2594. }
  2595.  
  2596. /* Check the website url field */
  2597. $website_field = $fields->getFieldIDByKey( 'website' );
  2598.  
  2599. if( $website_field && $fields->out_fields[ 'field_' . $website_field ] )
  2600. {
  2601. if( stristr( $fields->out_fields[ 'field_' . $website_field ], 'http://' ) === FALSE && stristr( $fields->out_fields[ 'field_' . $website_field ], 'https://' ) === FALSE )
  2602. {
  2603. $fields->out_fields[ 'field_' . $website_field ] = 'http://' . $fields->out_fields[ 'field_' . $website_field ];
  2604. }
  2605.  
  2606. if ( IPSText::xssCheckUrl( $fields->out_fields[ 'field_' . $website_field ] ) === FALSE )
  2607. {
  2608. $fields->error_fields['invalid'][] = $fields->cache_data[ $website_field ];
  2609. $fields->out_fields[ 'field_' . $website_field ] = '';
  2610. }
  2611. }
  2612.  
  2613. //-----------------------------------------
  2614. // Check...
  2615. //-----------------------------------------
  2616.  
  2617. if ( count( $fields->error_fields['empty'] ) )
  2618. {
  2619. $this->registry->getClass('output')->showError( array( 'customfields_empty', $fields->error_fields['empty'][0]['pf_title'] ), 10217 );
  2620. }
  2621.  
  2622. if ( count( $fields->error_fields['invalid'] ) )
  2623. {
  2624. $this->registry->getClass('output')->showError( array( 'customfields_invalid', $fields->error_fields['invalid'][0]['pf_title'] ), 10218 );
  2625. }
  2626.  
  2627. if ( count( $fields->error_fields['toobig'] ) )
  2628. {
  2629. $this->registry->getClass('output')->showError( array( 'customfields_toobig', $fields->error_fields['toobig'][0]['pf_title'] ), 10219 );
  2630. }
  2631.  
  2632. /* About me */
  2633. if( $this->request['updateAboutMe'] )
  2634. {
  2635. $extendedProfile['pp_about_me'] = $this->editor->process( $_POST['Post'] );
  2636. }
  2637.  
  2638. /* Open ID & times*/
  2639. $timeZone = IPSText::alphanumericalClean( $this->request['timeZone'], '+.' );
  2640. $dst_correct = intval( $this->request['dst_correct'] );
  2641.  
  2642. /* Add into array */
  2643. $core['time_offset'] = $timeZone;
  2644.  
  2645. /* http://community.invisionpower.com/resources/bugs.html/_/ip-board/cannot-uncheck-my-timezone-is-currently-in-dst-checkbox-in-profile-r41510 */
  2646. //$core['dst_in_use'] = $this->settings['time_dst_auto_correction'] ? ( ( $this->request['dstOption'] AND intval($this->request['dstCheck']) == 0 ) ? intval($this->request['dstOption']) : 0 ) : $this->memberData['dst_in_use'];
  2647. $core['dst_in_use'] = $this->settings['time_dst_auto_correction'] ? ( ( $this->request['dstOption'] AND intval($this->request['dstCheck']) == 0 ) ? intval($this->request['dstOption']) : 0 ) : intval($this->request['dstOption']);
  2648.  
  2649. $core['members_auto_dst'] = $this->settings['time_dst_auto_correction'] ? intval($this->request['dstCheck']) : $this->memberData['members_auto_dst'];
  2650.  
  2651. //-----------------------------------------
  2652. // Update the DB
  2653. //-----------------------------------------
  2654.  
  2655. IPSMember::save( $this->memberData['member_id'], array( 'core' => $core,
  2656. 'customFields' => $fields->out_fields,
  2657. 'extendedProfile' => $extendedProfile ) );
  2658.  
  2659. //-----------------------------------------
  2660. // Update birthdays cache if user set to today
  2661. // or if birthday was today but isn't now
  2662. //-----------------------------------------
  2663.  
  2664. if( $core['bday_month'] == date('m') AND $core['bday_day'] == date('d') )
  2665. {
  2666. $this->cache->rebuildCache( 'birthdays', 'calendar' );
  2667. }
  2668. else if( $this->memberData['bday_month'] == date('m') AND $this->memberData['bday_day'] == date('d') AND ( $core['bday_month'] != date('m') OR $core['bday_day'] != date('d') ) )
  2669. {
  2670. $this->cache->rebuildCache( 'birthdays', 'calendar' );
  2671. }
  2672.  
  2673. return TRUE;
  2674. }
  2675.  
  2676. /**
  2677. * UserCP Save Form: Notifications config
  2678. *
  2679. * @return boolean Successful
  2680. */
  2681. public function saveFormNotifications()
  2682. {
  2683. //-----------------------------------------
  2684. // Notifications library
  2685. //-----------------------------------------
  2686.  
  2687. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . '/sources/classes/member/notifications.php', 'notifications' );
  2688. $notifyLibrary = new $classToLoad( $this->registry );
  2689. $notifyLibrary->setMember( $this->memberData );
  2690.  
  2691. //-----------------------------------------
  2692. // Show the form
  2693. //-----------------------------------------
  2694.  
  2695. $_basicOptions = array( array( 'email', $this->lang->words['notopt__email'] ), array( 'inline', $this->lang->words['notopt__inline'] ), array( 'mobile' => $this->lang->words['notopt__mobile'] ) );
  2696. $_configOptions = $notifyLibrary->getNotificationData();
  2697. $_notifyConfig = $notifyLibrary->getMemberNotificationConfig( $this->memberData );
  2698. $_defaultConfig = $notifyLibrary->getDefaultNotificationConfig();
  2699. $_saveConfig = array();
  2700.  
  2701. foreach( $_configOptions as $option )
  2702. {
  2703. $_saveConfig[ $option['key'] ] = array();
  2704. $_saveConfig[ $option['key'] ]['selected'] = array();
  2705.  
  2706. //-----------------------------------------
  2707. // Loop through and mark what we selected.
  2708. // Do not allow changing of stuff from disable_override
  2709. // and disabled, however
  2710. //-----------------------------------------
  2711.  
  2712. if( is_array($this->request['config_' . $option['key'] ]) AND count($this->request['config_' . $option['key'] ]) )
  2713. {
  2714. foreach( $this->request['config_' . $option['key'] ] as $_selected )
  2715. {
  2716. if( !is_array($_defaultConfig[ $option['key'] ]['disabled']) OR !in_array( $_selected, $_defaultConfig[ $option['key'] ]['disabled'] ) )
  2717. {
  2718. $_saveConfig[ $option['key'] ]['selected'][] = $_selected;
  2719. }
  2720. }
  2721. }
  2722.  
  2723. if( $_defaultConfig[ $option['key'] ]['disable_override'] )
  2724. {
  2725. $_saveConfig[ $option['key'] ]['selected'] = $_defaultConfig[ $option['key'] ]['selected'];
  2726. }
  2727. }
  2728.  
  2729. //-----------------------------------------
  2730. // Save
  2731. //-----------------------------------------
  2732.  
  2733. IPSMember::packMemberCache( $this->memberData['member_id'], array( 'notifications' => $_saveConfig, 'show_notification_popup' => intval($this->request['show_notification_popup']) ), $this->memberData['members_cache'] );
  2734.  
  2735. //-----------------------------------------
  2736. // Topic preferences
  2737. //-----------------------------------------
  2738.  
  2739. $_trackChoice = '';
  2740.  
  2741. if ( $this->request['auto_track'] )
  2742. {
  2743. if ( in_array( $this->request['trackchoice'], array( 'none', 'immediate', 'offline', 'daily', 'weekly' ) ) )
  2744. {
  2745. $_trackChoice = $this->request['trackchoice'];
  2746. }
  2747. }
  2748.  
  2749. //-----------------------------------------
  2750. // Profile preferences
  2751. //-----------------------------------------
  2752.  
  2753. IPSMember::save( $this->memberData['member_id'], array( 'core' => array(
  2754. 'allow_admin_mails' => intval( $this->request['admin_send'] ),
  2755. 'auto_track' => $_trackChoice
  2756. ) ) );
  2757.  
  2758. return TRUE;
  2759. }
  2760. /**
  2761. * UserCP Save Form: Password
  2762. *
  2763. * @param array Array of member / core_sys_login information (if we're editing)
  2764. * @return mixed Array of errors / boolean true
  2765. */
  2766. public function saveFormPassword( $member=array() )
  2767. {
  2768. //-----------------------------------------
  2769. // INIT
  2770. //-----------------------------------------
  2771.  
  2772. $cur_pass = trim($this->request['current_pass']);
  2773. $new_pass = trim($this->request['new_pass_1']);
  2774. $chk_pass = trim($this->request['new_pass_2']);
  2775. $isRemote = ( ! $this->memberData['bw_local_password_set'] AND $this->memberData['members_created_remote'] ) ? true : false;
  2776.  
  2777. //-----------------------------------------
  2778. // Checks...
  2779. //-----------------------------------------
  2780.  
  2781. if( $this->memberData['g_access_cp'] )
  2782. {
  2783. return array( 0 => $this->lang->words['admin_emailpassword'] );
  2784. }
  2785.  
  2786. if ( $isRemote === false AND ( ! $_POST['current_pass'] OR ( empty($new_pass) ) or ( empty($chk_pass) ) ) )
  2787. {
  2788. return array( 0 => $this->lang->words['complete_entire_form'] );
  2789. }
  2790.  
  2791. //-----------------------------------------
  2792. // Do the passwords actually match?
  2793. //-----------------------------------------
  2794.  
  2795. if ( $new_pass != $chk_pass )
  2796. {
  2797. return array( 0 => $this->lang->words['passwords_not_matchy'] );
  2798. }
  2799.  
  2800. //-----------------------------------------
  2801. // Check password...
  2802. //-----------------------------------------
  2803.  
  2804. if ( $isRemote === false )
  2805. {
  2806. if ( $this->_checkPassword( $cur_pass ) !== TRUE )
  2807. {
  2808. return array( 0 => $this->lang->words['current_pw_bad'] );
  2809. }
  2810. }
  2811. else
  2812. {
  2813. /* This is INIT in _checkPassword */
  2814. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/handlers/han_login.php', 'han_login' );
  2815. $this->han_login = new $classToLoad( $this->registry );
  2816. $this->han_login->init();
  2817. }
  2818.  
  2819. //-----------------------------------------
  2820. // Create new password...
  2821. //-----------------------------------------
  2822.  
  2823. $md5_pass = md5($new_pass);
  2824.  
  2825. //-----------------------------------------
  2826. // han_login was loaded during check_password
  2827. //-----------------------------------------
  2828.  
  2829. $this->han_login->changePass( $this->memberData['email'], $md5_pass, $new_pass, $this->memberData );
  2830.  
  2831. if ( $this->han_login->return_code AND $this->han_login->return_code != 'METHOD_NOT_DEFINED' AND $this->han_login->return_code != 'SUCCESS' )
  2832. {
  2833. return array( 0 => $this->lang->words['hanlogin_pw_failed'] );
  2834. }
  2835.  
  2836. //-----------------------------------------
  2837. // Update the DB
  2838. //-----------------------------------------
  2839.  
  2840. IPSMember::updatePassword( $this->memberData['member_id'], $md5_pass );
  2841.  
  2842. IPSLib::runMemberSync( 'onPassChange', $this->memberData['member_id'], $new_pass );
  2843.  
  2844. //-----------------------------------------
  2845. // Update members log in key...
  2846. //-----------------------------------------
  2847.  
  2848. $key = IPSMember::generateAutoLoginKey();
  2849.  
  2850. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'member_login_key' => $key, 'bw_local_password_set' => 1 ) ) );
  2851.  
  2852. $this->ok_message = $this->lang->words['pw_change_successful'];
  2853.  
  2854. return TRUE;
  2855. }
  2856.  
  2857. /**
  2858. * UserCP Save Form: Display Name
  2859. *
  2860. * @return mixed Array of errors / boolean true
  2861. */
  2862. public function saveFormDisplayname()
  2863. {
  2864. //-----------------------------------------
  2865. // INIT
  2866. //-----------------------------------------
  2867.  
  2868. $members_display_name = trim($this->request['displayName']);
  2869. $password_check = trim( $this->request['displayPassword'] );
  2870.  
  2871. //-----------------------------------------
  2872. // Check for blanks...
  2873. //-----------------------------------------
  2874.  
  2875. if ( ! $members_display_name OR ( ! $this->_isFBUser AND ! $password_check ) )
  2876. {
  2877. return array( 0 => $this->lang->words['complete_entire_form'] );
  2878. }
  2879.  
  2880. //-----------------------------------------
  2881. // Check password
  2882. //-----------------------------------------
  2883.  
  2884. if ( ! $this->_isFBUser )
  2885. {
  2886. if ( $this->_checkPassword( $password_check ) === FALSE )
  2887. {
  2888. return array( 0 => $this->lang->words['current_pw_bad'] );
  2889. }
  2890. }
  2891.  
  2892. try
  2893. {
  2894. if ( IPSMember::getFunction()->updateName( $this->memberData['member_id'], $members_display_name, 'members_display_name' ) === TRUE )
  2895. {
  2896. $this->cache->rebuildCache( 'stats', 'global' );
  2897.  
  2898. return $this->showFormDisplayname( '', $this->lang->words['dname_change_ok'] );
  2899. }
  2900. else
  2901. {
  2902. # We should absolutely never get here. So this is a fail-safe, really to
  2903. # prevent a "false" positive outcome for the end-user
  2904. return array( 0 => $this->lang->words['name_taken_change'] );
  2905. }
  2906. }
  2907. catch( Exception $error )
  2908. {
  2909. switch( $error->getMessage() )
  2910. {
  2911. case 'NO_MORE_CHANGES':
  2912. return array( 0 => $this->lang->words['name_change_no_more'] );
  2913. break;
  2914. case 'NO_USER':
  2915. return array( 0 => $this->lang->words['name_change_noload'] );
  2916. break;
  2917. case 'NO_PERMISSION':
  2918. return array( 0 => $this->lang->words['name_change_noperm'] );
  2919. case 'NO_NAME':
  2920. return array( 0 => sprintf( $this->lang->words['name_change_tooshort'], $this->settings['max_user_name_length'] ) );
  2921. break;
  2922. case 'TOO_LONG':
  2923. return array( 0 => sprintf( $this->lang->words['name_change_tooshort'], $this->settings['max_user_name_length'] ) );
  2924. break;
  2925. case 'ILLEGAL_CHARS':
  2926. return array( 0 => $this->lang->words['name_change_illegal'] );
  2927. break;
  2928. case 'USER_NAME_EXISTS':
  2929. return array( 0 => $this->lang->words['name_change_taken'] );
  2930. break;
  2931. default:
  2932. return array( 0 => $error->getMessage() );
  2933. break;
  2934. }
  2935. }
  2936.  
  2937. return TRUE;
  2938. }
  2939.  
  2940. /**
  2941. * UserCP Save Form: Email Address
  2942. *
  2943. * @return mixed Array of errors / boolean true
  2944. */
  2945. public function saveFormEmailPassword()
  2946. {
  2947. //-----------------------------------------
  2948. // INIT
  2949. //-----------------------------------------
  2950.  
  2951. $_emailOne = strtolower( trim($this->request['in_email_1']) );
  2952. $_emailTwo = strtolower( trim($this->request['in_email_2']) );
  2953. $cur_pass = trim($this->request['current_pass']);
  2954. $new_pass = trim($this->request['new_pass_1']);
  2955. $chk_pass = trim($this->request['new_pass_2']);
  2956. $isRemote = ( ! $this->memberData['bw_local_password_set'] AND $this->memberData['members_created_remote'] ) ? true : false;
  2957.  
  2958. if ( $cur_pass OR $new_pass )
  2959. {
  2960. if( $this->memberData['g_access_cp'] )
  2961. {
  2962. return array( 0 => $this->lang->words['admin_emailpassword'] );
  2963. }
  2964.  
  2965. if ( $isRemote === false AND ( ! $_POST['current_pass'] OR ( empty($new_pass) ) or ( empty($chk_pass) ) ) )
  2966. {
  2967. return array( 0 => $this->lang->words['complete_entire_form'] );
  2968. }
  2969.  
  2970. //-----------------------------------------
  2971. // Do the passwords actually match?
  2972. //-----------------------------------------
  2973.  
  2974. if ( $new_pass != $chk_pass )
  2975. {
  2976. return array( 0 => $this->lang->words['passwords_not_matchy'] );
  2977. }
  2978.  
  2979. //-----------------------------------------
  2980. // Check password...
  2981. //-----------------------------------------
  2982.  
  2983. if ( $isRemote === false )
  2984. {
  2985. if ( $this->_checkPassword( $cur_pass ) !== TRUE )
  2986. {
  2987. return array( 0 => $this->lang->words['current_pw_bad'] );
  2988. }
  2989. }
  2990. else
  2991. {
  2992. /* This is INIT in _checkPassword */
  2993. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/handlers/han_login.php', 'han_login' );
  2994. $this->han_login = new $classToLoad( $this->registry );
  2995. $this->han_login->init();
  2996. }
  2997.  
  2998. //-----------------------------------------
  2999. // Create new password...
  3000. //-----------------------------------------
  3001.  
  3002. $md5_pass = md5($new_pass);
  3003.  
  3004. //-----------------------------------------
  3005. // han_login was loaded during check_password
  3006. //-----------------------------------------
  3007.  
  3008. $this->han_login->changePass( $this->memberData['email'], $md5_pass, $new_pass, $this->memberData );
  3009.  
  3010. if ( $this->han_login->return_code AND $this->han_login->return_code != 'METHOD_NOT_DEFINED' AND $this->han_login->return_code != 'SUCCESS' )
  3011. {
  3012. return array( 0 => $this->lang->words['hanlogin_pw_failed'] );
  3013. }
  3014.  
  3015. //-----------------------------------------
  3016. // Update the DB
  3017. //-----------------------------------------
  3018.  
  3019. IPSMember::updatePassword( $this->memberData['email'], $md5_pass );
  3020.  
  3021. IPSLib::runMemberSync( 'onPassChange', $this->memberData['member_id'], $new_pass );
  3022.  
  3023. //-----------------------------------------
  3024. // Update members log in key...
  3025. //-----------------------------------------
  3026.  
  3027. $key = IPSMember::generateAutoLoginKey();
  3028.  
  3029. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'member_login_key' => $key, 'bw_local_password_set' => 1 ) ) );
  3030.  
  3031. $this->ok_message = $this->lang->words['pw_change_successful'];
  3032. }
  3033.  
  3034. if ( $_emailOne or $_emailTwo )
  3035. {
  3036. //-----------------------------------------
  3037. // Do not allow validating members to change
  3038. // email when admin validation is on
  3039. // @see http://community.invisionpower.com/tracker/issue-19964-loophole-in-registration-procedure/
  3040. //-----------------------------------------
  3041.  
  3042. if( $this->memberData['member_group_id'] == $this->settings['auth_group'] AND in_array( $this->settings['reg_auth_type'], array( 'admin', 'admin_user' ) ) )
  3043. {
  3044. $this->registry->output->showError( $this->lang->words['admin_val_no_email_chg'], 10190 );
  3045. }
  3046.  
  3047. //-----------------------------------------
  3048. // Check input
  3049. //-----------------------------------------
  3050.  
  3051. if( $this->memberData['g_access_cp'] )
  3052. {
  3053. return array( 0 => $this->lang->words['admin_emailpassword'] );
  3054. }
  3055.  
  3056. if ( ! $_POST['in_email_1'] OR ! $_POST['in_email_2'] )
  3057. {
  3058. return array( 0 => $this->lang->words['complete_entire_form'] );
  3059. }
  3060.  
  3061. //-----------------------------------------
  3062. // Check password...
  3063. //-----------------------------------------
  3064.  
  3065. if ( ! $this->_isFBUser )
  3066. {
  3067. if ( $this->_checkPassword( $this->request['password'] ) === FALSE )
  3068. {
  3069. return array( 0 => $this->lang->words['current_pw_bad'] );
  3070. }
  3071. }
  3072.  
  3073. //-----------------------------------------
  3074. // Test email addresses
  3075. //-----------------------------------------
  3076.  
  3077. if ( $_emailOne != $_emailTwo )
  3078. {
  3079. return array( 0 => $this->lang->words['emails_no_matchy'] );
  3080. }
  3081.  
  3082. if ( IPSText::checkEmailAddress( $_emailOne ) !== TRUE )
  3083. {
  3084. return array( 0 => $this->lang->words['email_not_valid'] );
  3085. }
  3086.  
  3087. //-----------------------------------------
  3088. // Is this email addy taken?
  3089. //-----------------------------------------
  3090.  
  3091. if ( IPSMember::checkByEmail( $_emailOne ) == TRUE )
  3092. {
  3093. return array( 0 => $this->lang->words['email_is_taken'] );
  3094. }
  3095.  
  3096. //-----------------------------------------
  3097. // Load ban filters
  3098. //-----------------------------------------
  3099. $banfilters = array();
  3100. $this->DB->build( array( 'select' => '*', 'from' => 'banfilters' ) );
  3101. $this->DB->execute();
  3102.  
  3103. while( $r = $this->DB->fetch() )
  3104. {
  3105. $banfilters[ $r['ban_type'] ][] = $r['ban_content'];
  3106. }
  3107.  
  3108. //-----------------------------------------
  3109. // Check in banned list
  3110. //-----------------------------------------
  3111.  
  3112. if ( isset($banfilters['email']) AND is_array( $banfilters['email'] ) and count( $banfilters['email'] ) )
  3113. {
  3114. foreach ( $banfilters['email'] as $email )
  3115. {
  3116. $email = str_replace( '\*', '.*' , preg_quote($email, "/") );
  3117.  
  3118. if ( preg_match( "/^{$email}$/i", $_emailOne ) )
  3119. {
  3120. return array( 0 => $this->lang->words['email_is_taken'] );
  3121. }
  3122. }
  3123. }
  3124.  
  3125. //-----------------------------------------
  3126. // Load handler...
  3127. //-----------------------------------------
  3128.  
  3129. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/handlers/han_login.php', 'han_login' );
  3130. $this->han_login = new $classToLoad( $this->registry );
  3131. $this->han_login->init();
  3132.  
  3133. if ( $this->han_login->emailExistsCheck( $_emailOne ) !== FALSE )
  3134. {
  3135. return array( 0 => $this->lang->words['email_is_taken'] );
  3136. }
  3137.  
  3138. $this->han_login->changeEmail( $this->memberData['email'], $_emailOne, $this->memberData );
  3139.  
  3140. if ( $this->han_login->return_code AND $this->han_login->return_code != 'METHOD_NOT_DEFINED' AND $this->han_login->return_code != 'SUCCESS' )
  3141. {
  3142. return array( 0 => $this->lang->words['email_is_taken'] );
  3143. }
  3144.  
  3145. //-----------------------------------------
  3146. // Want a new validation? NON ADMINS ONLY
  3147. //-----------------------------------------
  3148.  
  3149. if ( $this->settings['reg_auth_type'] AND !$this->memberData['g_access_cp'] )
  3150. {
  3151. //-----------------------------------------
  3152. // Remove any existing entries
  3153. //-----------------------------------------
  3154.  
  3155. $_previous = $this->DB->buildAndFetch( array( 'select' => 'prev_email, real_group', 'from' => 'validating', 'where' => "member_id={$this->memberData['member_id']} AND email_chg=1" ) );
  3156.  
  3157. if( $_previous['prev_email'] )
  3158. {
  3159. $this->DB->delete( 'validating', "member_id={$this->memberData['member_id']} AND email_chg=1" );
  3160.  
  3161. $this->memberData['email'] = $_previous['prev_email'];
  3162. $this->memberData['member_group_id'] = $_previous['real_group'];
  3163. }
  3164.  
  3165. $validate_key = md5( IPSMember::makePassword() . time() );
  3166.  
  3167. //-----------------------------------------
  3168. // Update the new email, but enter a validation key
  3169. // and put the member in "awaiting authorisation"
  3170. // and send an email..
  3171. //-----------------------------------------
  3172.  
  3173. $db_str = array(
  3174. 'vid' => $validate_key,
  3175. 'member_id' => $this->memberData['member_id'],
  3176. 'temp_group' => $this->settings['auth_group'],
  3177. 'entry_date' => time(),
  3178. 'coppa_user' => 0,
  3179. 'email_chg' => 1,
  3180. 'ip_address' => $this->member->ip_address,
  3181. 'prev_email' => $this->memberData['email'],
  3182. );
  3183.  
  3184. if ( $this->memberData['member_group_id'] != $this->settings['auth_group'] )
  3185. {
  3186. $db_str['real_group'] = $this->memberData['member_group_id'];
  3187. }
  3188.  
  3189. $this->DB->insert( 'validating', $db_str );
  3190.  
  3191. IPSLib::runMemberSync( 'onEmailChange', $this->memberData['member_id'], strtolower( $_emailOne ), $this->memberData['email'] );
  3192.  
  3193. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'member_group_id' => $this->settings['auth_group'],
  3194. 'email' => $_emailOne ) ) );
  3195.  
  3196. //-----------------------------------------
  3197. // Update their session with the new member group
  3198. //-----------------------------------------
  3199.  
  3200. if ( $this->member->session_id )
  3201. {
  3202. $this->member->sessionClass()->convertMemberToGuest();
  3203. }
  3204.  
  3205. //-----------------------------------------
  3206. // Kill the cookies to stop auto log in
  3207. //-----------------------------------------
  3208.  
  3209. IPSCookie::set( 'pass_hash' , '-1', 0 );
  3210. IPSCookie::set( 'member_id' , '-1', 0 );
  3211. IPSCookie::set( 'session_id' , '-1', 0 );
  3212.  
  3213. //-----------------------------------------
  3214. // Dispatch the mail, and return to the activate form.
  3215. //-----------------------------------------
  3216.  
  3217. IPSText::getTextClass( 'email' )->getTemplate("newemail");
  3218.  
  3219. IPSText::getTextClass( 'email' )->buildMessage( array(
  3220. 'NAME' => $this->memberData['members_display_name'],
  3221. 'THE_LINK' => $this->settings['base_url']."app=core&module=global&section=register&do=auto_validate&type=newemail&uid=".$this->memberData['member_id']."&aid=".$validate_key,
  3222. 'ID' => $this->memberData['member_id'],
  3223. 'MAN_LINK' => $this->settings['base_url']."app=core&module=global&section=register&do=07",
  3224. 'CODE' => $validate_key,
  3225. ) );
  3226.  
  3227. IPSText::getTextClass( 'email' )->subject = $this->lang->words['lp_subject'].' '.$this->settings['board_name'];
  3228. IPSText::getTextClass( 'email' )->to = $_emailOne;
  3229.  
  3230. IPSText::getTextClass( 'email' )->sendMail();
  3231.  
  3232. $this->registry->getClass('output')->silentRedirect( $this->settings['base_url'] . 'app=core&amp;module=global&amp;section=register&amp;do=07' );
  3233. }
  3234. else
  3235. {
  3236. //-----------------------------------------
  3237. // No authorisation needed, change email addy and return
  3238. //-----------------------------------------
  3239.  
  3240. IPSLib::runMemberSync( 'onEmailChange', $this->memberData['member_id'], strtolower( $_emailOne ), $this->memberData['email'] );
  3241.  
  3242. IPSMember::save( $this->memberData['member_id'], array( 'core' => array( 'email' => $_emailOne ) ) );
  3243.  
  3244. //-----------------------------------------
  3245. // Add to OK message
  3246. //-----------------------------------------
  3247.  
  3248. $this->ok_message = $this->lang->words['ok_email_changed'];
  3249. }
  3250. }
  3251.  
  3252. return TRUE;
  3253. }
  3254.  
  3255. /**
  3256. * Password check
  3257. *
  3258. * @param string Plain Text Password
  3259. * @return boolean Password matched or not
  3260. */
  3261. protected function _checkPassword( $password_check )
  3262. {
  3263. //-----------------------------------------
  3264. // Ok, check password first
  3265. //-----------------------------------------
  3266.  
  3267. $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/handlers/han_login.php', 'han_login' );
  3268. $this->han_login = new $classToLoad( $this->registry );
  3269. $this->han_login->init();
  3270.  
  3271. //-----------------------------------------
  3272. // Is this a username or email address?
  3273. //-----------------------------------------
  3274.  
  3275. $this->han_login->loginPasswordCheck( $this->memberData['name'], $this->memberData['email'], $password_check );
  3276.  
  3277. if ( $this->han_login->return_code == 'SUCCESS' )
  3278. {
  3279. return TRUE;
  3280. }
  3281. else
  3282. {
  3283. return FALSE;
  3284. }
  3285. }
  3286. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement