civicrm.users.php 9.24 KB
Newer Older
1
2
3
<?php
/*
 +--------------------------------------------------------------------+
4
 | Copyright CiviCRM LLC. All rights reserved.                        |
5
 |                                                                    |
6
7
8
 | This work is published under the GNU AGPLv3 license with some      |
 | permitted exceptions and without any warranty. For full license    |
 | and copyright information, see https://civicrm.org/licensing       |
9
 +--------------------------------------------------------------------+
10
 */
11
12
13
14

/**
 *
 * @package CRM
15
 * @copyright CiviCRM LLC https://civicrm.org/licensing
16
17
18
 *
 */

19
// This file must not accessed directly.
20
21
22
if (!defined('ABSPATH')) {
  exit;
}
23
24

/**
25
26
27
 * Define CiviCRM_For_WordPress_Users Class.
 *
 * @since 4.6
28
29
30
31
 */
class CiviCRM_For_WordPress_Users {

  /**
32
   * @var object
33
34
35
   * Plugin object reference.
   * @since 4.6
   * @access public
36
37
   */
  public $civi;
38

39
  /**
40
   * Instance constructor.
41
   *
42
   * @since 4.6
43
   */
44
  public function __construct() {
45

46
    // Store reference to CiviCRM plugin object.
47
    $this->civi = civi_wp();
48

49
    // Always listen for activation action.
50
    add_action('civicrm_activation', [$this, 'activate']);
51
52
53
54
55
56
57
58
59
60

  }

  /**
   * Plugin activation tasks.
   *
   * @since 5.6
   */
  public function activate() {

61
62
63
64
    /*
     * Assign minimum capabilities for all WordPress roles and create
     * 'anonymous_user' role.
     */
65
66
    $this->set_wp_user_capabilities();

67
68
69
  }

  /**
70
   * Register hooks.
71
   *
72
   * @since 4.6
73
74
   */
  public function register_hooks() {
75

76
    // Add CiviCRM access capabilities to WordPress roles.
77
    $this->set_access_capabilities();
78

79
    // Do not hook into user updates if CiviCRM not installed yet.
80
81
82
    if (!CIVICRM_INSTALLED) {
      return;
    }
83

84
    // Synchronise users on insert and update.
85
86
    add_action('user_register', [$this, 'update_user']);
    add_action('profile_update', [$this, 'update_user']);
87

88
    // Delete ufMatch record when a WordPress user is deleted.
89
    add_action('deleted_user', [$this, 'delete_user_ufmatch'], 10, 1);
90

91
92
93
  }

  /**
94
95
   * Check permissions.
   *
96
97
   * Authentication function used by basepage_register_hooks()
   *
98
99
100
101
   * @since 4.6
   *
   * @param array $args The page arguments array.
   * @return bool True if authenticated, false otherwise.
102
   */
103
  public function check_permission($args) {
104

105
    if ($args[0] != 'civicrm') {
106
107
108
109
110
      return FALSE;
    }

    $config = CRM_Core_Config::singleton();

111
    // Set frontend true.
112
113
114
    $config->userFrameworkFrontend = TRUE;

    require_once 'CRM/Utils/Array.php';
115

116
    // All profile and file urls, as well as user dashboard and tell-a-friend are valid.
117
    $arg1 = CRM_Utils_Array::value(1, $args);
118
    $invalidPaths = ['admin'];
119
    if (in_array($arg1, $invalidPaths)) {
120
121
122
123
      return FALSE;
    }

    return TRUE;
124

125
126
  }

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  /**
   * Check a CiviCRM permission.
   *
   * @since 5.35
   *
   * @param str $permission The permission string.
   * @return bool $permitted True if allowed, false otherwise.
   */
  public function check_civicrm_permission($permission) {

    // Always deny if CiviCRM is not initialised.
    if (!$this->civi->initialize()) {
      return FALSE;
    }

    // Deny by default.
    $permitted = FALSE;

    // Check CiviCRM permissions.
    if (CRM_Core_Permission::check($permission)) {
      $permitted = TRUE;
    }

    return $permitted;

  }

154
  /**
155
156
   * Get "permission denied" text.
   *
157
158
   * Called when authentication fails in basepage_register_hooks()
   *
159
160
161
   * @since 4.6
   *
   * @return string Warning message.
162
163
   */
  public function get_permission_denied() {
164
    return __('You do not have permission to access this content.', 'civicrm');
165
166
167
  }

  /**
168
169
   * Handle WordPress user events.
   *
170
171
   * Callback function for 'user_register' hook.
   * Callback function for 'profile_update' hook.
172
   *
173
174
   * CMW: seems to (wrongly) create new CiviCRM Contact every time a user changes
   * their first_name or last_name attributes in WordPress.
175
   *
176
177
   * @since 4.6
   *
178
   * @param int $user_id The numeric ID of the WordPress user.
179
   */
180
  public function update_user($user_id) {
181

182
183
184
    $user = get_userdata($user_id);
    if ($user) {
      $this->sync_user($user);
haystack's avatar
haystack committed
185
186
187
    }

  }
188

haystack's avatar
haystack committed
189
  /**
190
191
192
   * Keep WordPress user synced with CiviCRM Contact.
   *
   * @since 4.6
haystack's avatar
haystack committed
193
   *
194
   * @param object $user The WordPress user object.
haystack's avatar
haystack committed
195
   */
196
  public function sync_user($user = FALSE) {
197

198
    // Sanity check
199
    if ($user === FALSE || !is_a($user, 'WP_User')) {
haystack's avatar
haystack committed
200
      return;
201
    }
202

haystack's avatar
haystack committed
203
204
205
    if (!$this->civi->initialize()) {
      return;
    }
206

haystack's avatar
haystack committed
207
    require_once 'CRM/Core/BAO/UFMatch.php';
208

209
210
211
212
    /*
     * This does not return anything, so if we want to do anything further
     * to the CiviCRM Contact, we have to search for it all over again.
     */
haystack's avatar
haystack committed
213
    CRM_Core_BAO_UFMatch::synchronize(
214
215
216
217
218
219
220
221
      // User object.
      $user,
      // Update = true.
      TRUE,
      // CMS.
      'WordPress',
      // Contact Type.
      'Individual'
haystack's avatar
haystack committed
222
    );
223

224
225
226
  }

  /**
227
   * When a WordPress user is deleted, delete the UFMatch record.
228
   *
229
   * Callback function for 'delete_user' hook.
230
   *
231
232
233
   * @since 4.6
   *
   * @param $user_id The numerical ID of the WordPress user.
234
   */
235
  public function delete_user_ufmatch($user_id) {
236

237
    if (!$this->civi->initialize()) {
238
239
240
      return;
    }

241
    // Delete the UFMatch record.
242
    require_once 'CRM/Core/BAO/UFMatch.php';
haystack's avatar
haystack committed
243
    CRM_Core_BAO_UFMatch::deleteUser($user_id);
244
245
246
247

  }

  /**
248
249
250
251
252
   * Create anonymous role and define capabilities.
   *
   * Function to create 'anonymous_user' role, if 'anonymous_user' role is not
   * in the WordPress installation and assign minimum capabilities for all
   * WordPress roles.
253
   *
254
255
   * The legacy global scope function civicrm_wp_set_capabilities() is called
   * from upgrade_4_3_alpha1()
256
   *
257
   * @since 4.6
258
259
260
261
   */
  public function set_wp_user_capabilities() {

    global $wp_roles;
262
    if (!isset($wp_roles)) {
263
264
265
      $wp_roles = new WP_Roles();
    }

266
    // Define minimum capabilities (CiviCRM permissions).
267
    $default_min_capabilities = [
268
269
270
271
272
273
274
275
276
277
278
      'access_civimail_subscribe_unsubscribe_pages' => 1,
      'access_all_custom_data' => 1,
      'access_uploaded_files' => 1,
      'make_online_contributions' => 1,
      'profile_create' => 1,
      'profile_edit' => 1,
      'profile_view' => 1,
      'register_for_events' => 1,
      'view_event_info' => 1,
      'sign_civicrm_petition' => 1,
      'view_public_civimail_content' => 1,
279
    ];
280

281
282
283
284
285
286
287
288
    /**
     * Allow minimum capabilities to be filtered.
     *
     * @since 4.6
     *
     * @param array $default_min_capabilities The minimum capabilities.
     * @return array $default_min_capabilities The modified capabilities.
     */
289
    $min_capabilities = apply_filters('civicrm_min_capabilities', $default_min_capabilities);
290

291
    // Assign the minimum capabilities to all WordPress roles.
292
293
294
295
    foreach ($wp_roles->role_names as $role => $name) {
      $roleObj = $wp_roles->get_role($role);
      foreach ($min_capabilities as $capability_name => $capability_value) {
        $roleObj->add_cap($capability_name);
296
297
298
299
      }
    }

    // Add the 'anonymous_user' role with minimum capabilities.
300
    if (!in_array('anonymous_user', $wp_roles->roles)) {
301
302
      add_role(
        'anonymous_user',
303
        __('Anonymous User', 'civicrm'),
304
305
306
307
308
309
310
        $min_capabilities
      );
    }

  }

  /**
311
312
313
   * Add CiviCRM access capabilities to WordPress roles.
   *
   * This is a callback for the 'init' hook in register_hooks().
314
315
316
317
   *
   * The legacy global scope function wp_civicrm_capability() is called by
   * postProcess() in civicrm/CRM/ACL/Form/WordPress/Permissions.php
   *
318
   * @since 4.6
319
320
321
   */
  public function set_access_capabilities() {

322
    // Test for existing global
323
    global $wp_roles;
324
    if (!isset($wp_roles)) {
325
326
327
      $wp_roles = new WP_Roles();
    }

328
329
330
331
332
333
334
335
336
337
338
    /**
     * Filter the default roles with access to CiviCRM.
     *
     * The 'access_civicrm' capability is the most basic CiviCRM capability and
     * is required to see the CiviCRM menu link in the WordPress Admin menu.
     *
     * @since 4.6
     *
     * @param array The default roles with access to CiviCRM.
     * @return array The modified roles with access to CiviCRM.
     */
339
    $roles = apply_filters('civicrm_access_roles', ['super admin', 'administrator']);
340

341
    // Give access to CiviCRM to particular roles.
342
343
    foreach ($roles as $role) {
      $roleObj = $wp_roles->get_role($role);
344
      if (
345
346
347
        is_object($roleObj) &&
        is_array($roleObj->capabilities) &&
        !array_key_exists('access_civicrm', $wp_roles->get_role($role)->capabilities)
348
      ) {
349
        $wp_roles->add_cap($role, 'access_civicrm');
350
351
352
353
354
355
      }
    }

  }

  /**
356
   * Get CiviCRM Contact Type.
357
358
   *
   * @since 4.6
359
   *
360
361
   * @param string $default The requested Contact Type.
   * @return string $ctype The computed Contact Type.
362
   */
363
  public function get_civicrm_contact_type($default = NULL) {
364

365
366
367
368
    /*
     * Here we are creating a new Contact.
     * Get the Contact Type from the POST variables if any.
     */
369
    if (isset($_REQUEST['ctype'])) {
370
      $ctype = $_REQUEST['ctype'];
371
372
373
374
    }
    elseif (
      isset($_REQUEST['edit']) &&
      isset($_REQUEST['edit']['ctype'])
375
376
    ) {
      $ctype = $_REQUEST['edit']['ctype'];
377
378
    }
    else {
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
      $ctype = $default;
    }

    if (
      $ctype != 'Individual' &&
      $ctype != 'Organization' &&
      $ctype != 'Household'
    ) {
      $ctype = $default;
    }

    return $ctype;

  }

394
}