Projet

Général

Profil

Paste
Télécharger (9,56 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / flag / includes / views / flag_handler_relationships.inc @ 4cfd8be6

1
<?php
2

    
3
/**
4
 * @file
5
 * Contains various relationship handlers.
6
 */
7

    
8
/**
9
 * Base class for all our relationship classes.
10
 *
11
 * @ingroup views
12
 */
13
abstract class flag_handler_relationship extends views_handler_relationship {
14

    
15
  /**
16
   * Every relationship has a 'flag' option.
17
   */
18
  function option_definition() {
19
    $options = parent::option_definition();
20
    $options['flag'] = array('default' => NULL);
21
    $options['required'] = array('default' => 1);
22
    return $options;
23
  }
24

    
25
  /**
26
   * Make sure the flag exists.
27
   *
28
   * When importing views, or when deleting flags, inconsistent views may
29
   * result. This validator is called by Views before saving or previewing a
30
   * view.
31
   */
32
  function validate() {
33
    $errors = array();
34
    $tokens = array(
35
      '@relationship-name' => $this->ui_name() . ' ' . $this->admin_summary(),
36
      '@flag-name' => $this->options['flag'],
37
    );
38
    if (!$this->options['flag']) {
39
      $errors[] = t('You must pick a flag to use for the relationship "@relationship-name".', $tokens);
40
    }
41
    elseif (!flag_get_flag($this->options['flag'])) {
42
      $errors[] = t('This view is looking for a flag by the name "@flag-name", but there is no such flag. Perhaps it was deleted. Please update the relationship "@relationship-name" in this view to use an existing flag.', $tokens);
43
    }
44
    return $errors;
45
  }
46

    
47
  /**
48
   * Get the type of the flag this relationship uses.
49
   *
50
   * This looks at the data set in the relationship definition in Views data.
51
   *
52
   * @return
53
   *  The flag's type, e.g., 'node' or 'taxonomy_term', or NULL if this is not
54
   *  set in data from hook_views_data().
55
   *
56
   * @see flag_views_data_alter()
57
   */
58
  function get_flag_type() {
59
    return isset($this->definition['flag type']) ? $this->definition['flag type'] : NULL;
60
  }
61

    
62
  /**
63
   * Returns the flag object.
64
   */
65
  function get_flag() {
66

    
67
    // Backward compatibility: There may exist old views on the system whose
68
    // 'flag' option isn't set. (This happens if the admin had skippped
69
    // clicking the 'Update' button.) When run, these views should behave as
70
    // if the first flag was selected.
71
    if (!isset($this->options['flag'])) {
72
      $this->options['flag'] = flag_views_flag_default($this->get_flag_type());
73
    }
74

    
75
    // Validation: Since validate() is called only when in Views's
76
    // administrative UI, we need to do validation at "run time" ourselves.
77
    if (($errors = $this->validate())) {
78
      foreach ($errors as $error) {
79
        drupal_set_message($error, 'error');
80
      }
81
    }
82

    
83
    return flag_get_flag($this->options['flag']);
84
  }
85

    
86
  // @todo: It's logical that this class should also implement options_form(),
87
  // to show the flag selector, and query(), to filter on the flag.
88
}
89

    
90
/**
91
 * Views relationship handler associating flags and content.
92
 *
93
 * This forms a bridge from the entity table to the {flagging} table, with
94
 * options to restrict the join to only flagged content, and to flagged content
95
 * by the current user.
96
 *
97
 * @ingroup views
98
 */
99
class flag_handler_relationship_content extends flag_handler_relationship {
100

    
101
  function option_definition() {
102
    $options = parent::option_definition();
103
    $options['user_scope'] = array('default' => 'current');
104
    return $options;
105
  }
106

    
107
  function options_form(&$form, &$form_state) {
108
    parent::options_form($form, $form_state);
109
    $entity_type = $this->definition['flag type'];
110
    $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.');
111
    $form['flag'] = flag_views_flag_config_form('radios', $entity_type, $this->options['flag']);
112

    
113
    $form['user_scope'] = array(
114
      '#type' => 'radios',
115
      '#title' => t('By'),
116
      '#options' => array('current' => t('Current user'), 'any' => t('Any user')),
117
      '#default_value' => $this->options['user_scope'],
118
    );
119

    
120
    $form['required']['#title'] = t('Include only flagged content');
121
    $form['required']['#description'] = t('If checked, only content that has this flag will be included. Leave unchecked to include all content; or, in combination with the <em>Flagged</em> filter, <a href="@unflagged-url">to limit the results to specifically unflagged content</a>.', array('@unflagged-url' => 'http://drupal.org/node/299335'));
122

    
123
    if (!$form['flag']['#options']) {
124
      $form = array(
125
        'error' => array(
126
          '#markup' => '<p class="error form-item">' . t('No %type flags exist. You must first <a href="@create-url">create a %type flag</a> before being able to use this relationship type.', array('%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH))) . '</p>',
127
        ),
128
      );
129
      $form_state['no flags exist'] = TRUE;
130
    }
131
    if (module_exists('session_api')) {
132
      $form['session_warning'] = array(
133
        '#markup' => '<p class="warning form-item">' . t('<strong>Warning</strong>: Adding this relationship for any flag that contains <strong>anonymous flagging access</strong> will disable page caching for anonymous users when this view is executed. (But this is only true when the relationship is constrained to "Current user", not to "Any user".) It is recommended to create a dedicated page for views containing anonymous user data.') . '</p>',
134
      );
135
    }
136
  }
137

    
138
  function options_validate(&$form, &$form_state) {
139
    if (!empty($form_state['no flags exist'])) {
140
      form_error($form, t('You must first create a flag'));
141
    }
142
  }
143

    
144
  function admin_summary() {
145
    return $this->options['user_scope'] == 'current' ? t('by current user') : t('by any user');
146
  }
147

    
148
  function ui_name($short = FALSE) {
149
    // We put the bookmark name in the UI string to save space.
150
    return t('!group: !title', array('!group' => $this->definition['group'], '!title' => empty($this->options['flag']) ? t('(Please select a flag)') : $this->options['flag']));
151
  }
152

    
153
  /**
154
   * Called to implement a relationship in a query.
155
   */
156
  function query() {
157
    if (!($flag = $this->get_flag())) {
158
      return;
159
    }
160

    
161
    $this->definition['extra'][] = array(
162
      'field' => 'fid',
163
      'value' => $flag->fid,
164
      'numeric' => TRUE,
165
    );
166
    if ($this->options['user_scope'] == 'current' && !$flag->global) {
167
      $this->definition['extra'][] = array(
168
        'field' => 'uid',
169
        'value' => '***CURRENT_USER***',
170
        'numeric' => TRUE,
171
      );
172
      $flag_roles = user_roles(FALSE, "flag $flag->name");
173
      if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) {
174
        // Disable page caching for anonymous users.
175
        drupal_page_is_cacheable(FALSE);
176

    
177
        // Add in the SID from Session API for anonymous users.
178
        $this->definition['extra'][] = array(
179
          'field' => 'sid',
180
          'value' => '***FLAG_CURRENT_USER_SID***',
181
          'numeric' => TRUE,
182
        );
183
      }
184
    }
185
    parent::query();
186
  }
187
}
188

    
189
/**
190
 * Views relationship handler associating flag counts and content.
191
 *
192
 * This forms a bridge from the entity table to the {flag_counts} table, with
193
 * the option to restrict the join to include only flagged content.
194
 *
195
 * @ingroup views
196
 */
197
class flag_handler_relationship_counts extends flag_handler_relationship {
198

    
199
  function options_form(&$form, &$form_state) {
200
    parent::options_form($form, $form_state);
201
    $entity_type = $this->definition['flag type'];
202
    $form['flag'] = flag_views_flag_config_form('radios', $entity_type, $this->options['flag']);
203

    
204
    $form['required']['#title'] = t('Include only flagged content');
205
    $form['required']['#description'] = t('If checked, only content that is flagged will be included.');
206
  }
207

    
208
  function admin_summary() {
209
    // Nothing to show.
210
  }
211

    
212
  function ui_name($short = FALSE) {
213
    // We put the bookmark name in the UI string to save space.
214
    return t('!group: !title counter', array('!group' => $this->definition['group'], '!title' => $this->options['flag']));
215
  }
216

    
217
  /**
218
   * Called to implement a relationship in a query.
219
   */
220
  function query() {
221
    if (!($flag = $this->get_flag())) {
222
      return;
223
    }
224

    
225
    $this->definition['extra'][] = array(
226
      'field' => 'fid',
227
      'value' => $flag->fid,
228
      'numeric' => TRUE,
229
    );
230
    if (!empty($this->options['required'])) {
231
      // Unfortunately, we may have zeros in our table, so having
232
      // parent::query() do INNER JOIN doesn't suffice. We need to filter these
233
      // zeros out.
234
      // @todo Make sure zero records aren't written in the first place, and
235
      // remove this code.
236
      $this->definition['extra'][] = array(
237
        'field' => 'count',
238
        'operator' => '>',
239
        'value' => '0',
240
        'numeric' => TRUE,
241
      );
242
    }
243
    parent::query();
244
  }
245
}
246

    
247
/**
248
 * Views relationship handler associating flags and users.
249
 *
250
 * This forms a bridge from the the {users} table to the {flagging} table.
251
 *
252
 * @ingroup views
253
 */
254
class flag_handler_relationship_user_content extends flag_handler_relationship {
255

    
256
  function options_form(&$form, &$form_state) {
257
    parent::options_form($form, $form_state);
258
    $form['label']['#description'] .= ' ' . t('Including name of the selected flag helps identify this relationship.');
259

    
260
    $form['flag'] = flag_views_flag_config_form('radios', NULL, $this->options['flag']);
261
    $form['flag']['#title'] = t('Flagged');
262

    
263
    $form['required']['#title'] = t('Include only users who have flagged content.');
264
    $form['required']['#description'] = t('If checked, only users that have flagged any content with this flag will be included.');
265
  }
266

    
267
  function admin_summary() {
268
    return $this->options['flag'];
269
  }
270

    
271
  /**
272
   * Called to implement a relationship in a query.
273
   */
274
  function query() {
275
    if (!($flag = $this->get_flag())) {
276
      return;
277
    }
278

    
279
    $this->definition['extra'][] = array(
280
      'field' => 'fid',
281
      'value' => $flag->fid,
282
      'numeric' => TRUE,
283
    );
284
    parent::query();
285
  }
286
}