PageRenderTime 48ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/theme-my-login/modules/user-moderation/admin/user-moderation-admin.php

https://gitlab.com/Gashler/sg
PHP | 432 lines | 203 code | 65 blank | 164 comment | 31 complexity | 22fcb4a318f5f350ff2391d43ce86c7e MD5 | raw file
  1. <?php
  2. /**
  3. * Holds Theme My Login User Moderation Admin class
  4. *
  5. * @package Theme_My_Login
  6. * @subpackage Theme_My_Login_User_Moderation
  7. * @since 6.0
  8. */
  9. if ( ! class_exists( 'Theme_My_Login_User_Moderation_Admin' ) ) :
  10. /**
  11. * Theme My Login User Moderation Admin class
  12. *
  13. * @since 6.0
  14. */
  15. class Theme_My_Login_User_Moderation_Admin extends Theme_My_Login_Abstract {
  16. /**
  17. * Holds options key
  18. *
  19. * @since 6.3
  20. * @access protected
  21. * @var string
  22. */
  23. protected $options_key = 'theme_my_login_moderation';
  24. /**
  25. * Returns singleton instance
  26. *
  27. * @since 6.3
  28. * @access public
  29. * @return object
  30. */
  31. public static function get_object( $class = null ) {
  32. return parent::get_object( __CLASS__ );
  33. }
  34. /**
  35. * Loads the module
  36. *
  37. * @since 6.0
  38. * @access protected
  39. */
  40. protected function load() {
  41. add_action( 'tml_activate_user-moderation/user-moderation.php', array( &$this, 'activate' ) );
  42. add_action( 'tml_uninstall_user-moderation/user-moderation.php', array( &$this, 'uninstall' ) );
  43. add_action( 'tml_modules_loaded', array( &$this, 'modules_loaded' ) );
  44. if ( is_multisite() )
  45. return;
  46. add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
  47. add_action( 'admin_init', array( &$this, 'admin_init' ) );
  48. add_action( 'load-users.php', array( &$this, 'load_users_page' ) );
  49. add_filter( 'user_row_actions', array( &$this, 'user_row_actions' ), 10, 2 );
  50. add_action( 'delete_user', array( &$this, 'deny_user' ) );
  51. }
  52. /**
  53. * Returns default options
  54. *
  55. * @since 6.3
  56. * @access public
  57. *
  58. * @return array Default options
  59. */
  60. public static function default_options() {
  61. return Theme_My_Login_User_Moderation::default_options();
  62. }
  63. /**
  64. * Activates the module
  65. *
  66. * Callback for "tml_activate_user-moderation/user-moderation.php" hook in method Theme_My_Login_Admin::activate_module()
  67. *
  68. * @see Theme_My_Login_Admin::activate_module()
  69. * @since 6.0
  70. * @access public
  71. *
  72. * @param object $theme_my_login Reference to global $theme_my_login object
  73. */
  74. public function activate() {
  75. if ( is_multisite() ) {
  76. add_settings_error( $this->options_key, 'invalid_module', __( 'User Moderation is not currently compatible with multisite.', 'theme-my-login' ) );
  77. return;
  78. }
  79. add_role( 'pending', 'Pending', array() );
  80. }
  81. /**
  82. * Uninstalls the module
  83. *
  84. * Callback for "tml_uninstall_user-moderation/user-moderation.php" hook in method Theme_My_Login_Admin::uninstall()
  85. *
  86. * @see Theme_My_Login_Admin::uninstall()
  87. * @since 6.3
  88. * @access public
  89. */
  90. public function uninstall() {
  91. delete_option( $this->options_key );
  92. remove_role( 'pending' );
  93. }
  94. /**
  95. * Disables the module if multisite
  96. *
  97. * @since 6.3
  98. * @access public
  99. */
  100. public function modules_loaded() {
  101. if ( is_multisite() ) {
  102. $theme_my_login_admin = Theme_My_Login_Admin::get_object();
  103. $active_modules = $theme_my_login_admin->get_option( 'active_modules' );
  104. $active_modules = array_values( array_diff( $active_modules, array( 'user-moderation/user-moderation.php' ) ) );
  105. $theme_my_login_admin->set_option( 'active_modules', $active_modules );
  106. $theme_my_login_admin->save_options();
  107. return;
  108. }
  109. }
  110. /**
  111. * Adds "Moderation" to Theme My Login menu
  112. *
  113. * Callback for "admin_menu" hook
  114. *
  115. * @since 6.0
  116. * @access public
  117. */
  118. public function admin_menu() {
  119. add_submenu_page(
  120. 'theme_my_login',
  121. __( 'Theme My Login User Moderation Settings', 'theme-my-login' ),
  122. __( 'Moderation', 'theme-my-login' ),
  123. 'manage_options',
  124. $this->options_key,
  125. array( &$this, 'settings_page' )
  126. );
  127. add_settings_section( 'general', null, '__return_false', $this->options_key );
  128. add_settings_field( 'type', __( 'Moderation Type', 'theme-my-login' ), array( &$this, 'settings_field_moderation_type' ), $this->options_key, 'general' );
  129. }
  130. /**
  131. * Registers options group
  132. *
  133. * Callback for "admin_init" hook
  134. *
  135. * @since 6.0
  136. * @access public
  137. */
  138. public function admin_init() {
  139. register_setting( $this->options_key, $this->options_key, array( &$this, 'save_settings' ) );
  140. }
  141. /**
  142. * Renders settings page
  143. *
  144. * @since 6.3
  145. * @access public
  146. */
  147. public function settings_page() {
  148. Theme_My_Login_Admin::settings_page( array(
  149. 'title' => __( 'Theme My Login User Moderation Settings', 'theme-my-login' ),
  150. 'options_key' => $this->options_key
  151. ) );
  152. }
  153. /**
  154. * Renders Moderation Type settings field
  155. *
  156. * @since 6.3
  157. * @access public
  158. */
  159. public function settings_field_moderation_type() {
  160. ?>
  161. <input name="<?php echo $this->options_key; ?>[type]" type="radio" id="<?php echo $this->options_key; ?>_type_none" value="none"<?php checked( $this->get_option( 'type' ), 'none' ); ?> />
  162. <label for="<?php echo $this->options_key; ?>_type_none"><?php _e( 'None', 'theme-my-login' ); ?></label>
  163. <p class="description"><?php _e( 'Check this option to require no moderation.', 'theme-my-login' ); ?></p>
  164. <input name="<?php echo $this->options_key; ?>[type]" type="radio" id="<?php echo $this->options_key; ?>_type_email" value="email" <?php checked( $this->get_option( 'type' ), 'email' ); ?> />
  165. <label for="<?php echo $this->options_key; ?>_type_email"><?php _e( 'E-mail Confirmation', 'theme-my-login' ); ?></label>
  166. <p class="description"><?php _e( 'Check this option to require new users to confirm their e-mail address before they may log in.', 'theme-my-login' ); ?></p>
  167. <input name="<?php echo $this->options_key; ?>[type]" type="radio" id="<?php echo $this->options_key; ?>_type_admin" value="admin" <?php checked( $this->get_option( 'type' ), 'admin' ); ?> />
  168. <label for="<?php echo $this->options_key; ?>_type_admin"><?php _e( 'Admin Approval', 'theme-my-login' ); ?></label>
  169. <p class="description"><?php _e( 'Check this option to require new users to be approved by an administrator before they may log in.', 'theme-my-login' ); ?></p>
  170. <?php
  171. }
  172. /**
  173. * Sanitizes settings
  174. *
  175. * @since 6.3
  176. * @access public
  177. *
  178. * @param array $settings Posted settings
  179. * @return array Sanitized settings
  180. */
  181. public function save_settings( $settings ) {
  182. return array(
  183. 'type' => in_array( $settings['type'], array( 'none', 'email', 'admin' ) ) ? $settings['type'] : 'none'
  184. );
  185. }
  186. /**
  187. * Attaches actions/filters explicitly to users.php
  188. *
  189. * Callback for "load-users.php" hook
  190. *
  191. * @since 6.0
  192. * @access public
  193. */
  194. public function load_users_page() {
  195. add_action( 'admin_notices', array( &$this, 'admin_notices' ) );
  196. // Is there an action?
  197. if ( isset( $_GET['action'] ) ) {
  198. // Is it a sanctioned action?
  199. if ( in_array( $_GET['action'], array( 'approve', 'resendactivation' ) ) ) {
  200. // Is there a user ID?
  201. $user = isset( $_GET['user'] ) ? $_GET['user'] : '';
  202. // No user ID?
  203. if ( ! $user || ! current_user_can( 'edit_user', $user ) )
  204. wp_die( __( 'You can&#8217;t edit that user.', 'theme-my-login' ) );
  205. // Where did we come from?
  206. $redirect_to = isset( $_REQUEST['wp_http_referer'] ) ? remove_query_arg( array( 'wp_http_referer', 'updated', 'delete_count' ), stripslashes( $_REQUEST['wp_http_referer'] ) ) : 'users.php';
  207. switch ( $_GET['action'] ) {
  208. case 'approve' :
  209. check_admin_referer( 'approve-user' );
  210. if ( ! self::approve_user( $user ) )
  211. wp_die( __( 'You can&#8217;t edit that user.' ) );
  212. $redirect_to = add_query_arg( 'update', 'approve', $redirect_to );
  213. break;
  214. case 'resendactivation' :
  215. check_admin_referer( 'resend-activation' );
  216. do_action( 'tml_user_activation_resend', $user );
  217. if ( ! Theme_My_Login_User_Moderation::new_user_activation_notification( $user ) )
  218. wp_die( __( 'The e-mail could not be sent.' ) . "<br />\n" . __( 'Possible reason: your host may have disabled the mail() function...' ) );
  219. $redirect_to = add_query_arg( 'update', 'sendactivation', $redirect_to );
  220. break;
  221. }
  222. wp_redirect( $redirect_to );
  223. exit;
  224. }
  225. }
  226. }
  227. /**
  228. * Adds update messages to the admin screen
  229. *
  230. * Callback for "admin_notices" hook in file admin-header.php
  231. *
  232. * @since 6.0
  233. * @access public
  234. */
  235. public function admin_notices() {
  236. if ( isset( $_GET['update'] ) && in_array( $_GET['update'], array( 'approve', 'sendactivation' ) ) ) {
  237. echo '<div id="message" class="updated fade"><p>';
  238. if ( 'approve' == $_GET['update'] )
  239. _e( 'User approved.', 'theme-my-login' );
  240. elseif ( 'sendactivation' == $_GET['update'] )
  241. _e( 'Activation sent.', 'theme-my-login' );
  242. echo '</p></div>';
  243. }
  244. }
  245. /**
  246. * Adds "Approve" link for each pending user on users.php
  247. *
  248. * Callback for "user_row_actions" hook in {@internal unknown}
  249. *
  250. * @since 6.0
  251. * @access public
  252. *
  253. * @param array $actions The user actions
  254. * @param WP_User $user_object The current user object
  255. * @return array The filtered user actions
  256. */
  257. public function user_row_actions( $actions, $user_object ) {
  258. $current_user = wp_get_current_user();
  259. if ( $current_user->ID != $user_object->ID ) {
  260. if ( in_array( 'pending', (array) $user_object->roles ) ) {
  261. switch ( $this->get_option( 'type' ) ) {
  262. case 'email' :
  263. // Add "Resend Activation" link
  264. $actions['resend-activation'] = sprintf( '<a href="%1$s">%2$s</a>',
  265. add_query_arg( 'wp_http_referer',
  266. urlencode( esc_url( stripslashes( $_SERVER['REQUEST_URI'] ) ) ),
  267. wp_nonce_url( "users.php?action=resendactivation&amp;user=$user_object->ID", 'resend-activation' )
  268. ),
  269. __( 'Resend Activation', 'theme-my-login' )
  270. );
  271. break;
  272. case 'admin' :
  273. // Add "Approve" link
  274. $actions['approve-user'] = sprintf( '<a href="%1$s">%2$s</a>',
  275. add_query_arg( 'wp_http_referer',
  276. urlencode( esc_url( stripslashes( $_SERVER['REQUEST_URI'] ) ) ),
  277. wp_nonce_url( "users.php?action=approve&amp;user=$user_object->ID", 'approve-user' )
  278. ),
  279. __( 'Approve', 'theme-my-login' )
  280. );
  281. break;
  282. }
  283. }
  284. }
  285. return $actions;
  286. }
  287. /**
  288. * Handles activating a new user by admin approval
  289. *
  290. * @since 6.0
  291. * @access public
  292. *
  293. * @param int $user_id User's ID
  294. * @return bool Returns false if not a valid user
  295. */
  296. public static function approve_user( $user_id ) {
  297. global $wpdb, $current_site;
  298. $user_id = (int) $user_id;
  299. // Get user by ID
  300. $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE ID = %d", $user_id ) );
  301. if ( empty( $user ) )
  302. return false;
  303. do_action( 'approve_user', $user->ID );
  304. // Clear the activation key if there is one
  305. $wpdb->update( $wpdb->users, array( 'user_activation_key' => '' ), array( 'ID' => $user->ID ) );
  306. $approval_role = apply_filters( 'tml_approval_role', get_option( 'default_role' ), $user->ID );
  307. // Set user role
  308. $user_object = new WP_User( $user->ID );
  309. $user_object->set_role( $approval_role );
  310. unset( $user_object );
  311. // Check for plaintext pass
  312. if ( ! $user_pass = get_user_meta( $user->ID, 'user_pass', true ) ) {
  313. $user_pass = wp_generate_password();
  314. wp_set_password( $user_pass, $user->ID );
  315. }
  316. // Delete plaintext pass
  317. delete_user_meta( $user->ID, 'user_pass' );
  318. if ( is_multisite() ) {
  319. $blogname = $current_site->site_name;
  320. } else {
  321. // The blogname option is escaped with esc_html on the way into the database in sanitize_option
  322. // we want to reverse this for the plain text arena of emails.
  323. $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  324. }
  325. $message = sprintf( __( 'You have been approved access to %s', 'theme-my-login' ), $blogname ) . "\r\n\r\n";
  326. $message .= sprintf( __( 'Username: %s', 'theme-my-login' ), $user->user_login ) . "\r\n";
  327. $message .= sprintf( __( 'Password: %s', 'theme-my-login' ), $user_pass ) . "\r\n\r\n";
  328. $message .= site_url( 'wp-login.php', 'login' ) . "\r\n";
  329. $title = sprintf( __( '[%s] Registration Approved', 'theme-my-login' ), $blogname );
  330. $title = apply_filters( 'user_approval_notification_title', $title, $user->ID );
  331. $message = apply_filters( 'user_approval_notification_message', $message, $user_pass, $user->ID );
  332. if ( $message && ! wp_mail( $user->user_email, $title, $message ) )
  333. die( '<p>' . __( 'The e-mail could not be sent.' ) . "<br />\n" . __( 'Possible reason: your host may have disabled the mail() function...' ) . '</p>' );
  334. return true;
  335. }
  336. /**
  337. * Called upon deletion of a user in the "Pending" role
  338. *
  339. * @since 6.0
  340. * @access public
  341. *
  342. * @param int $user_id User's ID
  343. */
  344. public function deny_user( $user_id ) {
  345. global $current_site;
  346. $user_id = (int) $user_id;
  347. $user = new WP_User( $user_id );
  348. if ( ! in_array( 'pending', (array) $user->roles ) )
  349. return;
  350. do_action( 'deny_user', $user->ID );
  351. if ( is_multisite() ) {
  352. $blogname = $current_site->site_name;
  353. } else {
  354. // The blogname option is escaped with esc_html on the way into the database in sanitize_option
  355. // we want to reverse this for the plain text arena of emails.
  356. $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  357. }
  358. $message = sprintf( __( 'You have been denied access to %s', 'theme-my-login' ), $blogname );
  359. $title = sprintf( __( '[%s] Registration Denied', 'theme-my-login' ), $blogname );
  360. $title = apply_filters( 'user_denial_notification_title', $title, $user_id );
  361. $message = apply_filters( 'user_denial_notification_message', $message, $user_id );
  362. if ( $message && ! wp_mail( $user->user_email, $title, $message ) )
  363. die( '<p>' . __( 'The e-mail could not be sent.' ) . "<br />\n" . __( 'Possible reason: your host may have disabled the mail() function...' ) . '</p>' );
  364. }
  365. }
  366. Theme_My_Login_User_Moderation_Admin::get_object();
  367. endif;