Projet

Général

Profil

Paste
Télécharger (4,25 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / flag / includes / flag.cookie_storage.inc @ 76e2e7c3

1
<?php
2

    
3
/**
4
 * @file
5
 * Contains the FlagCookieStorage class.
6
 */
7

    
8
/**
9
 * Utility class to handle cookies.
10
 *
11
 * Cookies are used to record flaggings for anonymous users on cached pages.
12
 *
13
 * This class contains only two instance methods. Usage example:
14
 * @code
15
 *   $storage = FlagCookieStorage::factory($flag);
16
 *   $storage->flag(145);
17
 *   $storage->unflag(17);
18
 * @endcode
19
 *
20
 * You may delete all the cookies with <code>FlagCookieStorage::drop()</code>.
21
 */
22
abstract class FlagCookieStorage {
23

    
24
  /**
25
   * Returns the actual storage object compatible with the flag.
26
   */
27
  static function factory($flag) {
28
    if ($flag->global) {
29
      return new FlagGlobalCookieStorage($flag);
30
    }
31
    else {
32
      return new FlagNonGlobalCookieStorage($flag);
33
    }
34
  }
35

    
36
  function __construct($flag) {
37
    $this->flag = $flag;
38
  }
39

    
40
  /**
41
   * "Flags" an item.
42
   *
43
   * It just records this fact in a cookie.
44
   */
45
  abstract function flag($entity_id);
46

    
47
  /**
48
   * "Unflags" an item.
49
   *
50
   * It just records this fact in a cookie.
51
   */
52
  abstract function unflag($entity_id);
53

    
54
  /**
55
   * Deletes all the cookies.
56
   *
57
   * (Etymology: "drop" as in "drop database".)
58
   */
59
  static function drop() {
60
    FlagGlobalCookieStorage::drop();
61
    FlagNonGlobalCookieStorage::drop();
62
  }
63
}
64

    
65
/**
66
 * Storage handler for global flags.
67
 */
68
class FlagGlobalCookieStorage extends FlagCookieStorage {
69

    
70
  function flag($entity_id) {
71
    $cookie_key = $this->cookie_key($entity_id);
72
    setcookie($cookie_key, 1, REQUEST_TIME + $this->get_lifetime(), base_path());
73
    $_COOKIE[$cookie_key] = 1;
74
  }
75

    
76
  function unflag($entity_id) {
77
    $cookie_key = $this->cookie_key($entity_id);
78
    setcookie($cookie_key, 0, REQUEST_TIME + $this->get_lifetime(), base_path());
79
    $_COOKIE[$cookie_key] = 0;
80
  }
81

    
82
  // Global flags persist for the length of the minimum cache lifetime.
83
  protected function get_lifetime() {
84
    $cookie_lifetime = variable_get('cache', 0) ? variable_get('cache_lifetime', 0) : -1;
85
    // Do not let the cookie lifetime be 0 (which is the no cache limit on
86
    // anonymous page caching), since it would expire immediately. Usually
87
    // the no cache limit means caches are cleared on cron, which usually runs
88
    // at least once an hour.
89
    if ($cookie_lifetime == 0) {
90
      $cookie_lifetime = 3600;
91
    }
92
    return $cookie_lifetime;
93
  }
94

    
95
  protected function cookie_key($entity_id) {
96
    return 'flag_global_' . $this->flag->name . '_' . $entity_id;
97
  }
98

    
99
  /**
100
   * Deletes all the global cookies.
101
   */
102
  static function drop() {
103
    foreach ($_COOKIE as $key => $value) {
104
      if (strpos($key, 'flag_global_') === 0) {
105
        setcookie($key, FALSE, 0, base_path());
106
        unset($_COOKIE[$key]);
107
      }
108
    }
109
  }
110
}
111

    
112
/**
113
 * Storage handler for non-global flags.
114
 */
115
class FlagNonGlobalCookieStorage extends FlagCookieStorage {
116

    
117
  // The anonymous per-user flaggings are stored in a single cookie, so that
118
  // all of them persist as long as the Drupal cookie lifetime.
119

    
120
  function __construct($flag) {
121
    parent::__construct($flag);
122
    $this->flaggings = isset($_COOKIE['flags']) ? explode(' ', $_COOKIE['flags']) : array();
123
  }
124

    
125
  function flag($entity_id) {
126
    if (!$this->is_flagged($entity_id)) {
127
      $this->flaggings[] = $this->cookie_key($entity_id);
128
      $this->write();
129
    }
130
  }
131

    
132
  function unflag($entity_id) {
133
    if (($index = $this->index_of($entity_id)) !== FALSE) {
134
      unset($this->flaggings[$index]);
135
      $this->write();
136
    }
137
  }
138

    
139
  protected function get_lifetime() {
140
    return min((int) ini_get('session.cookie_lifetime'), (int) ini_get('session.gc_maxlifetime'));
141
  }
142

    
143
  protected function cookie_key($entity_id) {
144
    return $this->flag->name . '_' . $entity_id;
145
  }
146

    
147
  protected function write() {
148
    $serialized = implode(' ', array_filter($this->flaggings));
149
    setcookie('flags', $serialized, REQUEST_TIME + $this->get_lifetime(), base_path());
150
    $_COOKIE['flags'] = $serialized;
151
  }
152

    
153
  protected function is_flagged($entity_id) {
154
    return $this->index_of($entity_id) !== FALSE;
155
  }
156

    
157
  protected function index_of($entity_id) {
158
    return array_search($this->cookie_key($entity_id), $this->flaggings);
159
  }
160

    
161
  /**
162
   * Deletes the cookie.
163
   */
164
  static function drop() {
165
    if (isset($_COOKIE['flags'])) {
166
      setcookie('flags', FALSE, 0, base_path());
167
      unset($_COOKIE['flags']);
168
    }
169
  }
170
}