/bp-core/admin/bp-core-admin-components.php

  1. <?php 
  2. /** 
  3. * BuddyPress Admin Component Functions. 
  4. * 
  5. * @package BuddyPress 
  6. * @subpackage CoreAdministration 
  7. * @since 2.3.0 
  8. */ 
  9.  
  10. // Exit if accessed directly. 
  11. defined( 'ABSPATH' ) || exit; 
  12.  
  13. /** 
  14. * Renders the Component Setup admin panel. 
  15. * 
  16. * @since 1.6.0 
  17. * 
  18. */ 
  19. function bp_core_admin_components_settings() { 
  20. ?> 
  21.  
  22. <div class="wrap"> 
  23.  
  24. <h1><?php _e( 'BuddyPress Settings', 'buddypress' ); ?> </h1> 
  25.  
  26. <h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Components', 'buddypress' ) ); ?></h2> 
  27. <form action="" method="post" id="bp-admin-component-form"> 
  28.  
  29. <?php bp_core_admin_components_options(); ?> 
  30.  
  31. <p class="submit clear"> 
  32. <input class="button-primary" type="submit" name="bp-admin-component-submit" id="bp-admin-component-submit" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ) ?>"/> 
  33. </p> 
  34.  
  35. <?php wp_nonce_field( 'bp-admin-component-setup' ); ?> 
  36.  
  37. </form> 
  38. </div> 
  39.  
  40. <?php 
  41.  
  42. /** 
  43. * Creates reusable markup for component setup on the Components and Pages dashboard panel. 
  44. * 
  45. * @since 1.6.0 
  46. * 
  47. * @todo Use settings API 
  48. */ 
  49. function bp_core_admin_components_options() { 
  50.  
  51. // Declare local variables. 
  52. $deactivated_components = array(); 
  53.  
  54. /** 
  55. * Filters the array of available components. 
  56. * 
  57. * @since 1.5.0 
  58. * 
  59. * @param mixed $value Active components. 
  60. */ 
  61. $active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) ); 
  62.  
  63. // The default components (if none are previously selected). 
  64. $default_components = array( 
  65. 'xprofile' => array( 
  66. 'title' => __( 'Extended Profiles', 'buddypress' ),  
  67. 'description' => __( 'Customize your community with fully editable profile fields that allow your users to describe themselves.', 'buddypress' ) 
  68. ),  
  69. 'settings' => array( 
  70. 'title' => __( 'Account Settings', 'buddypress' ),  
  71. 'description' => __( 'Allow your users to modify their account and notification settings directly from within their profiles.', 'buddypress' ) 
  72. ),  
  73. 'notifications' => array( 
  74. 'title' => __( 'Notifications', 'buddypress' ),  
  75. 'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' ) 
  76. ),  
  77. ); 
  78.  
  79. $optional_components = bp_core_admin_get_components( 'optional' ); 
  80. $required_components = bp_core_admin_get_components( 'required' ); 
  81. $retired_components = bp_core_admin_get_components( 'retired' ); 
  82.  
  83. // Don't show Forums component in optional components if it's disabled. 
  84. if ( ! bp_is_active( 'forums' ) ) { 
  85. unset( $optional_components['forums'] ); 
  86.  
  87. // Merge optional and required together. 
  88. $all_components = $optional_components + $required_components; 
  89.  
  90. // If this is an upgrade from before BuddyPress 1.5, we'll have to convert 
  91. // deactivated components into activated ones. 
  92. if ( empty( $active_components ) ) { 
  93. $deactivated_components = bp_get_option( 'bp-deactivated-components' ); 
  94. if ( !empty( $deactivated_components ) ) { 
  95.  
  96. // Trim off namespace and filename. 
  97. $trimmed = array(); 
  98. foreach ( array_keys( (array) $deactivated_components ) as $component ) { 
  99. $trimmed[] = str_replace( '.php', '', str_replace( 'bp-', '', $component ) ); 
  100.  
  101. // Loop through the optional components to create an active component array. 
  102. foreach ( array_keys( (array) $optional_components ) as $ocomponent ) { 
  103. if ( !in_array( $ocomponent, $trimmed ) ) { 
  104. $active_components[$ocomponent] = 1; 
  105.  
  106. // On new install, set active components to default. 
  107. if ( empty( $active_components ) ) { 
  108. $active_components = $default_components; 
  109.  
  110. // Core component is always active. 
  111. $active_components['core'] = $all_components['core']; 
  112. $inactive_components = array_diff( array_keys( $all_components ) , array_keys( $active_components ) ); 
  113.  
  114. /** Display ************************************************************** 
  115. */ 
  116.  
  117. // Get the total count of all plugins. 
  118. $all_count = count( $all_components ); 
  119. $page = bp_core_do_network_admin() ? 'settings.php' : 'options-general.php'; 
  120. $action = !empty( $_GET['action'] ) ? $_GET['action'] : 'all'; 
  121.  
  122. switch( $action ) { 
  123. case 'all' : 
  124. $current_components = $all_components; 
  125. break; 
  126. case 'active' : 
  127. foreach ( array_keys( $active_components ) as $component ) { 
  128. $current_components[$component] = $all_components[$component]; 
  129. break; 
  130. case 'inactive' : 
  131. foreach ( $inactive_components as $component ) { 
  132. $current_components[$component] = $all_components[$component]; 
  133. break; 
  134. case 'mustuse' : 
  135. $current_components = $required_components; 
  136. break; 
  137. case 'retired' : 
  138. $current_components = $retired_components; 
  139. break; 
  140. } ?> 
  141.  
  142. <h3 class="screen-reader-text"><?php 
  143. /** translators: accessibility text */ 
  144. _e( 'Filter components list', 'buddypress' ); 
  145. ?></h3> 
  146.  
  147. <ul class="subsubsub"> 
  148. <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'all' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'all' ) : ?>class="current"<?php endif; ?>><?php printf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $all_count, 'plugins', 'buddypress' ), number_format_i18n( $all_count ) ); ?></a> | </li> 
  149. <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'active' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'active' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', count( $active_components ), 'buddypress' ), number_format_i18n( count( $active_components ) ) ); ?></a> | </li> 
  150. <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'inactive' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'inactive' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', count( $inactive_components ), 'buddypress' ), number_format_i18n( count( $inactive_components ) ) ); ?></a> | </li> 
  151. <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'mustuse' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'mustuse' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Must-Use <span class="count">(%s)</span>', 'Must-Use <span class="count">(%s)</span>', count( $required_components ), 'buddypress' ), number_format_i18n( count( $required_components ) ) ); ?></a> | </li> 
  152. <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'retired' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'retired' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>', count( $retired_components ), 'buddypress' ), number_format_i18n( count( $retired_components ) ) ); ?></a></li> 
  153. </ul> 
  154.  
  155. <h3 class="screen-reader-text"><?php 
  156. /** translators: accessibility text */ 
  157. _e( 'Components list', 'buddypress' ); 
  158. ?></h3> 
  159.  
  160. <table class="wp-list-table widefat plugins"> 
  161. <thead> 
  162. <tr> 
  163. <td id="cb" class="manage-column column-cb check-column"><input id="cb-select-all-1" type="checkbox" disabled><label class="screen-reader-text" for="cb-select-all-1"><?php 
  164. /** translators: accessibility text */ 
  165. _e( 'Bulk selection is disabled', 'buddypress' ); 
  166. ?></label></td> 
  167. <th scope="col" id="name" class="manage-column column-title column-primary"><?php _e( 'Component', 'buddypress' ); ?></th> 
  168. <th scope="col" id="description" class="manage-column column-description"><?php _e( 'Description', 'buddypress' ); ?></th> 
  169. </tr> 
  170. </thead> 
  171.  
  172. <tbody id="the-list"> 
  173.  
  174. <?php if ( !empty( $current_components ) ) : ?> 
  175.  
  176. <?php foreach ( $current_components as $name => $labels ) : ?> 
  177.  
  178. <?php if ( !in_array( $name, array( 'core', 'members' ) ) ) : 
  179. $class = isset( $active_components[esc_attr( $name )] ) ? 'active' : 'inactive'; 
  180. else : 
  181. $class = 'active'; 
  182. endif; ?> 
  183.  
  184. <tr id="<?php echo esc_attr( $name ); ?>" class="<?php echo esc_attr( $name ) . ' ' . esc_attr( $class ); ?>"> 
  185. <th scope="row" class="check-column"> 
  186.  
  187. <?php if ( !in_array( $name, array( 'core', 'members' ) ) ) : ?> 
  188.  
  189. <input type="checkbox" id="<?php echo esc_attr( "bp_components[$name]" ); ?>" name="<?php echo esc_attr( "bp_components[$name]" ); ?>" value="1"<?php checked( isset( $active_components[esc_attr( $name )] ) ); ?> /><label for="<?php echo esc_attr( "bp_components[$name]" ); ?>" class="screen-reader-text"><?php 
  190. /** translators: accessibility text */ 
  191. printf( __( 'Select %s', 'buddypress' ), esc_html( $labels['title'] ) ); ?></label> 
  192.  
  193. <?php else : ?> 
  194.  
  195. <input type="checkbox" id="<?php echo esc_attr( "bp_components[$name]" ); ?>" name="<?php echo esc_attr( "bp_components[$name]" ); ?>" value="1" checked="checked" disabled><label for="<?php echo esc_attr( "bp_components[$name]" ); ?>" class="screen-reader-text"><?php 
  196. /** translators: accessibility text */ 
  197. printf( __( '%s is a required component', 'buddypress' ), esc_html( $labels['title'] ) ); ?></label> 
  198.  
  199. <?php endif; ?> 
  200.  
  201. </th> 
  202. <td class="plugin-title column-primary"> 
  203. <span aria-hidden="true"></span> 
  204. <strong><?php echo esc_html( $labels['title'] ); ?></strong> 
  205. </td> 
  206.  
  207. <td class="column-description desc"> 
  208. <div class="plugin-description"> 
  209. <p><?php echo $labels['description']; ?></p> 
  210. </div> 
  211.  
  212. </td> 
  213. </tr> 
  214.  
  215. <?php endforeach ?> 
  216.  
  217. <?php else : ?> 
  218.  
  219. <tr class="no-items"> 
  220. <td class="colspanchange" colspan="3"><?php _e( 'No components found.', 'buddypress' ); ?></td> 
  221. </tr> 
  222.  
  223. <?php endif; ?> 
  224.  
  225. </tbody> 
  226.  
  227. <tfoot> 
  228. <tr> 
  229. <td class="manage-column column-cb check-column"><input id="cb-select-all-2" type="checkbox" disabled><label class="screen-reader-text" for="cb-select-all-2"><?php 
  230. /** translators: accessibility text */ 
  231. _e( 'Bulk selection is disabled', 'buddypress' ); 
  232. ?></label></td> 
  233. <th class="manage-column column-title column-primary"><?php _e( 'Component', 'buddypress' ); ?></th> 
  234. <th class="manage-column column-description"><?php _e( 'Description', 'buddypress' ); ?></th> 
  235. </tr> 
  236. </tfoot> 
  237.  
  238. </table> 
  239.  
  240. <input type="hidden" name="bp_components[members]" value="1" /> 
  241.  
  242. <?php 
  243.  
  244. /** 
  245. * Handle saving the Component settings. 
  246. * 
  247. * @since 1.6.0 
  248. * 
  249. * @todo Use settings API when it supports saving network settings 
  250. */ 
  251. function bp_core_admin_components_settings_handler() { 
  252.  
  253. // Bail if not saving settings. 
  254. if ( ! isset( $_POST['bp-admin-component-submit'] ) ) 
  255. return; 
  256.  
  257. // Bail if nonce fails. 
  258. if ( ! check_admin_referer( 'bp-admin-component-setup' ) ) 
  259. return; 
  260.  
  261. // Settings form submitted, now save the settings. First, set active components. 
  262. if ( isset( $_POST['bp_components'] ) ) { 
  263.  
  264. // Load up BuddyPress. 
  265. $bp = buddypress(); 
  266.  
  267. // Save settings and upgrade schema. 
  268. require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); 
  269. require_once( $bp->plugin_dir . '/bp-core/admin/bp-core-admin-schema.php' ); 
  270.  
  271. $submitted = stripslashes_deep( $_POST['bp_components'] ); 
  272. $bp->active_components = bp_core_admin_get_active_components_from_submitted_settings( $submitted ); 
  273.  
  274. bp_core_install( $bp->active_components ); 
  275. bp_core_add_page_mappings( $bp->active_components ); 
  276. bp_update_option( 'bp-active-components', $bp->active_components ); 
  277.  
  278. // Where are we redirecting to? 
  279. $base_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components', 'updated' => 'true' ), 'admin.php' ) ); 
  280.  
  281. // Redirect. 
  282. wp_redirect( $base_url ); 
  283. die(); 
  284. add_action( 'bp_admin_init', 'bp_core_admin_components_settings_handler' ); 
  285.  
  286. /** 
  287. * Calculates the components that should be active after save, based on submitted settings. 
  288. * 
  289. * The way that active components must be set after saving your settings must 
  290. * be calculated differently depending on which of the Components subtabs you 
  291. * are coming from: 
  292. * - When coming from All or Active, the submitted checkboxes accurately 
  293. * reflect the desired active components, so we simply pass them through 
  294. * - When coming from Inactive, components can only be activated - already 
  295. * active components will not be passed in the $_POST global. Thus, we must 
  296. * parse the newly activated components with the already active components 
  297. * saved in the $bp global 
  298. * - When activating a Retired component, the situation is similar to Inactive. 
  299. * - When deactivating a Retired component, no value is passed in the $_POST 
  300. * global (because the component settings are checkboxes). So, in order to 
  301. * determine whether a retired component is being deactivated, we retrieve a 
  302. * list of retired components, and check each one to ensure that its checkbox 
  303. * is not present, before merging the submitted components with the active 
  304. * ones. 
  305. * 
  306. * @since 1.7.0 
  307. * 
  308. * @param array $submitted This is the array of component settings coming from the POST 
  309. * global. You should stripslashes_deep() before passing to this function. 
  310. * @return array The calculated list of component settings 
  311. */ 
  312. function bp_core_admin_get_active_components_from_submitted_settings( $submitted ) { 
  313. $current_action = 'all'; 
  314.  
  315. if ( isset( $_GET['action'] ) && in_array( $_GET['action'], array( 'active', 'inactive', 'retired' ) ) ) { 
  316. $current_action = $_GET['action']; 
  317.  
  318. $current_components = buddypress()->active_components; 
  319.  
  320. switch ( $current_action ) { 
  321. case 'retired' : 
  322. $retired_components = bp_core_admin_get_components( 'retired' ); 
  323. foreach ( array_keys( $retired_components ) as $retired_component ) { 
  324. if ( ! isset( $submitted[ $retired_component ] ) ) { 
  325. unset( $current_components[ $retired_component ] ); 
  326. } // Fall through. 
  327.  
  328.  
  329. case 'inactive' : 
  330. $components = array_merge( $submitted, $current_components ); 
  331. break; 
  332.  
  333. case 'all' : 
  334. case 'active' : 
  335. default : 
  336. $components = $submitted; 
  337. break; 
  338.  
  339. return $components; 
  340.  
  341. /** 
  342. * Return a list of component information. 
  343. * 
  344. * We use this information both to build the markup for the admin screens, as 
  345. * well as to do some processing on settings data submitted from those screens. 
  346. * 
  347. * @since 1.7.0 
  348. * 
  349. * @param string $type Optional; component type to fetch. Default value is 'all', or 'optional', 'retired', 'required'. 
  350. * @return array Requested components' data. 
  351. */ 
  352. function bp_core_admin_get_components( $type = 'all' ) { 
  353. $components = bp_core_get_components( $type ); 
  354.  
  355. /** 
  356. * Filters the list of component information. 
  357. * 
  358. * @since 2.0.0 
  359. * 
  360. * @param array $components Array of component information. 
  361. * @param string $type Type of component list requested. 
  362. * Possible values include 'all', 'optional',  
  363. * 'retired', 'required'. 
  364. */ 
  365. return apply_filters( 'bp_core_admin_get_components', $components, $type ); 
.