class-fl-builder-user-access.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <?php
  2. /**
  3. * Manages settings that can be used to grant or
  4. * limit access to builder features.
  5. *
  6. * @since 1.10
  7. */
  8. final class FLBuilderUserAccess {
  9. /**
  10. * An array of registered data for each setting.
  11. *
  12. * @since 1.10
  13. * @access private
  14. * @var array $registered_settings
  15. */
  16. static private $registered_settings = array();
  17. /**
  18. * A cached array of saved settings.
  19. *
  20. * @since 1.10
  21. * @access private
  22. * @var array $settings
  23. */
  24. static private $settings = null;
  25. /**
  26. * Initialize user access.
  27. *
  28. * @since 1.10
  29. * @return void
  30. */
  31. static public function init() {
  32. add_action( 'after_setup_theme', __CLASS__ . '::register_default_settings' );
  33. }
  34. /**
  35. * Registers a single user access setting.
  36. *
  37. * @since 1.10
  38. * @param string $key The setting key.
  39. * @param array $data The setting data.
  40. * @return void
  41. */
  42. static public function register_setting( $key, $data ) {
  43. if ( ! isset( $data['group'] ) ) {
  44. $data['group'] = __( 'Misc', 'fl-builder' );
  45. }
  46. if ( ! isset( $data['order'] ) ) {
  47. $data['order'] = '10';
  48. }
  49. self::$registered_settings[ $key ] = $data;
  50. self::$settings = null; // must bust the settings cache.
  51. }
  52. /**
  53. * Returns the registered user access settings.
  54. *
  55. * @since 1.10
  56. * @return array
  57. */
  58. static public function get_registered_settings() {
  59. return self::$registered_settings;
  60. }
  61. /**
  62. * Returns the registered user access settings in their
  63. * defined groups.
  64. *
  65. * @since 1.10
  66. * @return array
  67. */
  68. static public function get_grouped_registered_settings() {
  69. $groups = array();
  70. $settings = self::$registered_settings;
  71. uasort( $settings, array( __CLASS__, 'sort' ) );
  72. foreach ( $settings as $key => $data ) {
  73. if ( ! isset( $groups[ $data['group'] ] ) ) {
  74. $groups[ $data['group'] ] = array();
  75. }
  76. $groups[ $data['group'] ][ $key ] = $data;
  77. }
  78. return $groups;
  79. }
  80. /**
  81. * Custom sort function instead of create_function which is deprecated in php 7.2
  82. * @since 1.11
  83. */
  84. private static function sort( $a, $b ) {
  85. return $a['order'] > $b['order'];
  86. }
  87. /**
  88. * Returns the saved user access settings and merges in
  89. * any default roles that haven't been saved.
  90. *
  91. * @since 1.10
  92. * @return array
  93. */
  94. static public function get_saved_settings() {
  95. if ( self::$settings ) {
  96. return self::$settings;
  97. }
  98. $roles = self::get_all_roles();
  99. $settings = FLBuilderModel::get_admin_settings_option( '_fl_builder_user_access', true );
  100. $ms_settings = FLBuilderModel::get_admin_settings_option( '_fl_builder_user_access', false );
  101. $ms_support = FLBuilderAdminSettings::multisite_support();
  102. if ( ! is_array( $settings ) ) {
  103. $settings = array();
  104. }
  105. foreach ( self::$registered_settings as $key => $data ) {
  106. if ( ! isset( $settings[ $key ] ) ) {
  107. if ( $ms_support && isset( $ms_settings[ $key ] ) ) {
  108. $settings[ $key ] = $ms_settings[ $key ];
  109. } else {
  110. $settings[ $key ] = array();
  111. }
  112. }
  113. foreach ( $roles as $role_key => $role_data ) {
  114. if ( ! isset( $settings[ $key ][ $role_key ] ) ) {
  115. if ( ! isset( $data['default'] ) || ! $data['default'] ) {
  116. $settings[ $key ][ $role_key ] = false;
  117. } elseif ( is_array( $data['default'] ) ) {
  118. if ( in_array( $role_key, $data['default'] ) ) {
  119. $settings[ $key ][ $role_key ] = true;
  120. } else {
  121. $settings[ $key ][ $role_key ] = false;
  122. }
  123. } else {
  124. $settings[ $key ][ $role_key ] = true;
  125. }
  126. }
  127. }
  128. }
  129. self::$settings = $settings;
  130. return $settings;
  131. }
  132. /**
  133. * Returns the raw user access settings without any
  134. * defaults merged in.
  135. *
  136. * @since 1.10
  137. * @return array
  138. */
  139. static public function get_raw_settings() {
  140. $settings = FLBuilderModel::get_admin_settings_option( '_fl_builder_user_access', true );
  141. if ( ! is_array( $settings ) ) {
  142. $settings = array();
  143. }
  144. return $settings;
  145. }
  146. /**
  147. * Saves the user access settings.
  148. *
  149. * @since 1.10
  150. * @param array $data The user access data to save.
  151. * @return void
  152. */
  153. static public function save_settings( $data = array() ) {
  154. $roles = self::get_all_roles();
  155. $settings = array();
  156. $ms_support = FLBuilderAdminSettings::multisite_support();
  157. $ms_overrides = $ms_support && isset( $_POST['fl_ua_override_ms'] ) ? $_POST['fl_ua_override_ms'] : array();
  158. foreach ( self::$registered_settings as $registered_key => $registered_data ) {
  159. if ( ! isset( $data[ $registered_key ] ) ) {
  160. $data[ $registered_key ] = array();
  161. }
  162. }
  163. foreach ( $data as $data_key => $data_roles ) {
  164. if ( ! is_network_admin() && $ms_support && ! isset( $ms_overrides[ $data_key ] ) ) {
  165. continue;
  166. }
  167. $settings[ $data_key ] = array();
  168. foreach ( $roles as $role_key => $role_data ) {
  169. $settings[ $data_key ][ $role_key ] = in_array( $role_key, $data_roles ) ? true : false;
  170. }
  171. }
  172. self::$settings = null;
  173. FLBuilderModel::update_admin_settings_option( '_fl_builder_user_access', $settings, false );
  174. }
  175. /**
  176. * Gets all roles that can be used for user access settings.
  177. *
  178. * @since 1.10
  179. * @return array
  180. */
  181. static public function get_all_roles() {
  182. if ( ! function_exists( 'get_editable_roles' ) ) {
  183. require_once( ABSPATH . 'wp-admin/includes/user.php' );
  184. }
  185. $editable_roles = get_editable_roles();
  186. $roles = array();
  187. $caps = apply_filters( 'fl_builder_user_access_capabilities', array( 'edit_posts' ) );
  188. foreach ( $editable_roles as $role => $data ) {
  189. foreach ( $caps as $cap ) {
  190. if ( isset( $data['capabilities'][ $cap ] ) && 1 == $data['capabilities'][ $cap ] ) {
  191. $roles[ $role ] = $data['name'];
  192. }
  193. }
  194. }
  195. return $roles;
  196. }
  197. /**
  198. * Checks to see if the current user has access to a specific
  199. * builder feature. Not meant as a security feature but more
  200. * as a guide rail by simplifying the interface for clients.
  201. *
  202. * @since 1.10
  203. * @param string $key The feature key to check.
  204. * @return bool
  205. */
  206. static public function current_user_can( $key ) {
  207. $user = wp_get_current_user();
  208. $settings = self::get_saved_settings();
  209. // Return false if no settings saved.
  210. if ( ! isset( $settings[ $key ] ) ) {
  211. return false;
  212. }
  213. // Make sure super admins have administrator access.
  214. if ( is_super_admin() && ! in_array( 'administrator', $user->roles ) ) {
  215. $user->roles[] = 'administrator';
  216. }
  217. // Check the user's roles against the saved settings.
  218. foreach ( $user->roles as $role ) {
  219. // Return true if the user has access.
  220. if ( isset( $settings[ $key ][ $role ] ) && $settings[ $key ][ $role ] ) {
  221. return true;
  222. }
  223. }
  224. return false;
  225. }
  226. /**
  227. * Registers the default user access settings.
  228. *
  229. * @since 1.10
  230. * @private
  231. * @return void
  232. */
  233. static function register_default_settings() {
  234. self::register_setting( 'builder_access', array(
  235. 'default' => 'all',
  236. 'group' => __( 'Frontend', 'fl-builder' ),
  237. 'label' => __( 'Builder Access', 'fl-builder' ),
  238. 'description' => __( 'The selected roles will have access to the builder for editing posts, pages, and CPTs.', 'fl-builder' ),
  239. 'order' => '1',
  240. ) );
  241. self::register_setting( 'unrestricted_editing', array(
  242. 'default' => 'all',
  243. 'group' => __( 'Frontend', 'fl-builder' ),
  244. 'label' => __( 'Unrestricted Editing', 'fl-builder' ),
  245. 'description' => __( 'The selected roles will have unrestricted access to all editing features within the builder.', 'fl-builder' ),
  246. 'order' => '2',
  247. ) );
  248. }
  249. }
  250. FLBuilderUserAccess::init();