cache_example.module

Tracking 8.x-1.x branch
  1. drupal
    1. 7 contributions/examples/cache_example/cache_example.module
    2. 8 contributions/examples/cache_example/cache_example.module

Outlines how a module can use the Cache API.

@todo: Demonstrate cache expiration.

Functions & methods

NameDescription
cache_example_form_cache_clearingSubmit handler to demonstrate the various uses of cache_clear_all().
cache_example_form_create_expiring_itemSubmit handler to create a new cache item with specified expiration.
cache_example_form_expire_filesSubmit handler that explicitly clears cache_example_files_count from cache.
cache_example_menuImplements hook_menu().
cache_example_page_formcache_example page/form callback.

File

View source
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
<?php

/**
 * @file
 * Outlines how a module can use the Cache API.
 *
 * @todo: Demonstrate cache expiration.
 */

/**
 * @defgroup cache_example Example: Cache API
 * @ingroup examples
 * @{
 * Outlines how a module can use the Cache API.
 *
 * Cache API allows us to cache data that is heavy to calculate. As this can
 * significantly speed up the Drupal site, it is recommended to use cache
 * mechanism when it is appropriate.
 *
 * Cache in Drupal is very easy to use. This example will search entire Drupal
 * folder and display all files. Since this operation includes filesystem it can
 * take a while. This list will not change much on production
 * websites, so we decide to cache it.
 *
 * @see cache_get()
 * @see cache_set()
 * @see cache_clear_all()
 */

/**
 * Implements hook_menu().
 */
function cache_example_menu() {
  $items = array();
  $items['examples/cache_example'] = array(
    'title' => 'Cache example',
    'description' => 'Example of Drupal Cache API',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('cache_example_page_form'),
    'access callback' => TRUE,
  );

  return $items;
}

/**
 * cache_example page/form callback.
 *
 * Displays a page/form which outlines how Drupal's cache works.
 */
function cache_example_page_form($form, &$form_state) {
  // Log execution time.
  $start_time = microtime(TRUE);


   // Try to load the files count from cache. This function will accept two
   // arguments:
   // - cache object name (cid)
   // - cache bin, the (optional) cache bin (most often a database table) where
   //   the object is to be saved.
   //
   // cache_get() returns the cached object or FALSE if object does not exist.
  if ($cache = cache_get('cache_example_files_count')) {
    /*
     * Get cached data. Complex data types will be unserialized automatically.
     */
    $files_count = $cache->data;
  }
  else {
    // If there was no cached data available we have to search filesystem.
    // Recursively get all files from Drupal's folder.
    $files_count = count(file_scan_directory('.', '/.*/'));


    // Since we have recalculated, we now need to store the new data into cache.
    // Complex data types will be automatically serialized before being saved
    // into cache.
    // Here we use the default setting and create an unexpiring cache item.
    // See below for an example that creates an expiring cache item.
    cache_set('cache_example_files_count', $files_count);
  }

  $end_time = microtime(TRUE);
  $duration = $end_time - $start_time;


  // Format intro message.
  $intro_message = '<p>' . t('This example will search the entire drupal folder and display a count of the files in it.') . ' ';
  $intro_message .= t('This can take a while, since there are a lot of files to be searched.') . ' ';
  $intro_message .= t('We will search filesystem just once and save output to the cache. We will use cached data for later requests.') . '</p>';
  $intro_message .= '<p>' . t('<a href="@url">Reload this page</a> to see cache in action.', array('@url' => request_uri())) . ' ';
  $intro_message .= t('You can use the button below to remove cached data.') . '</p>';

  $form['file_search'] = array(
    '#type' => 'fieldset',
    '#title' => t('File search caching'),
  );
  $form['file_search']['introduction'] = array(
    '#markup' => $intro_message,
  );

  $color = empty($cache) ? 'red' : 'green';
  $retrieval = empty($cache) ? t('calculated by traversing the filesystem') : t('retrieved from cache');

  $form['file_search']['statistics'] = array(
    '#type' => 'item',
    '#markup' => t('%count files exist in this Drupal installation; @retrieval in @time ms. <br/>(Source: <span style="color:@color;">@source</span>)',
      array(
        '%count' => $files_count,
        '@retrieval' => $retrieval,
        '@time' => number_format($duration * 1000, 2),
        '@color' => $color,
        '@source' => empty($cache) ? t('actual file search') : t('cached'),
      )
    ),
  );
  $form['file_search']['remove_file_count'] = array(
    '#type' => 'submit',
    '#submit' => array('cache_example_form_expire_files'),
    '#value' => t('Explicitly remove cached file count'),
  );

  $form['expiration_demo'] = array(
    '#type' => 'fieldset',
    '#title' => t('Cache expiration settings'),
  );
  $form['expiration_demo']['explanation'] = array(
    '#markup' => t('A cache item can be set as CACHE_PERMANENT, meaning that it will only be removed when explicitly cleared, or it can have an expiration time (a Unix timestamp).'),
  );
  $expiring_item = cache_get('cache_example_expiring_item');
  $item_status = $expiring_item ?
      t('Cache item exists and is set to expire at %time', array('%time' => $expiring_item->data)) :
      t('Cache item does not exist');
  $form['expiration_demo']['current_status'] = array(
    '#type' => 'item',
    '#title' => t('Current status of cache item "cache_example_expiring_item"'),
    '#markup' => $item_status,
  );
  $form['expiration_demo']['expiration'] = array(
    '#type' => 'select',
    '#title' => t('Time before cache expiration'),
    '#options' => array(
      'never_remove' => t('CACHE_PERMANENT'),
      -10 => t('Immediate expiration'),
      10 => t('10 seconds from form submission'),
      60 => t('1 minute from form submission'),
      300 => t('5 minutes from form submission'),
    ),
    '#default_value' => -10,
    '#description' => t('Any cache item can be set to only expire when explicitly cleared, or to expire at a given time.')
  );
  $form['expiration_demo']['create_cache_item'] = array(
    '#type' => 'submit',
    '#value' => t('Create a cache item with this expiration'),
    '#submit' => array('cache_example_form_create_expiring_item'),
  );

  $form['cache_clearing'] = array(
    '#type' => 'fieldset',
    '#title' => t('Expire and remove options'),
    '#description' => t("We have APIs to expire cached items and also to just remove them. Unfortunately, they're all the same API, cache_clear_all"),
  );
  $form['cache_clearing']['cache_clear_type'] = array(
    '#type' => 'radios',
    '#title' => t('Type of cache clearing to do'),
    '#options' => array(
      'expire' => t('Remove items from the "cache" bin that have expired'),
      'remove_all' => t('Remove all items from the "cache" bin regardless of expiration (super-wildcard)'),
      'remove_wildcard' => t('Remove all items from the "cache" bin that match the pattern "cache_example"'),
    ),
    '#default_value' => 'expire',
  );
  // Submit button to clear cached data.
  $form['cache_clearing']['clear_expired'] = array(
    '#type' => 'submit',
    '#value' => t('Clear or expire cache'),
    '#submit' => array('cache_example_form_cache_clearing'),
    '#access' => user_access('administer site configuration'),
  );
  return $form;
}

/**
 * Submit handler that explicitly clears cache_example_files_count from cache.
 */
function cache_example_form_expire_files($form, &$form_state) {
  // Clear cached data. This function will delete cached object from cache bin.
  //
  // The first argument is cache id to be deleted. Since we've provided it
  // explicitly, it will be removed whether or not it has an associated
  // expiration time. The second argument (required here) is the cache bin.
  // Using cache_clear_all() explicitly in this way
  // forces removal of the cached item.
  cache_clear_all('cache_example_files_count', 'cache');

  // Display message to the user.
  drupal_set_message(t('Cached data key "cache_example_files_count" was cleared.'), 'status');
}

/**
 * Submit handler to create a new cache item with specified expiration.
 */
function cache_example_form_create_expiring_item($form, &$form_state) {
  $interval = $form_state['values']['expiration'];
  if ($interval == 'never_remove') {
    $expiration = CACHE_PERMANENT;
    $expiration_friendly = t('Never expires');
  }
  else {
    $expiration = time() + $interval;
    $expiration_friendly = format_date($expiration);
  }
  // Set the expiration to the actual Unix timestamp of the end of the required
  // interval.
  cache_set('cache_example_expiring_item', $expiration_friendly, 'cache', $expiration);
  drupal_set_message(t('cache_example_expiring_item was set to expire at %time', array('%time' => $expiration_friendly)));
}

/**
 * Submit handler to demonstrate the various uses of cache_clear_all().
 */
function cache_example_form_cache_clearing($form, &$form_state) {
  switch ($form_state['values']['cache_clear_type']) {
    case 'expire':
      // Here we'll remove all cache keys in the 'cache' bin that have expired.
      cache_clear_all(NULL, 'cache');
      drupal_set_message(t('cache_clear_all(NULL, "cache") was called, removing any expired cache items.'));
      break;
    case 'remove_all':
      // This removes all keys in a bin using a super-wildcard. This
      // has nothing to do with expiration. It's just brute-force removal.
      cache_clear_all('*', 'cache', TRUE);
      drupal_set_message(t('ALL entries in the "cache" bin were removed with cache_clear_all("*", "cache", TRUE).'));
      break;
    case 'remove_wildcard':
      // We can also explicitly remove all cache items whose cid begins with
      // 'cache_example' by using a wildcard. This again is brute-force
      // removal, not expiration.
      cache_clear_all('cache_example', 'cache', TRUE);
      drupal_set_message(t('Cache entries whose cid began with "cache_example" in the "cache" bin were removed with cache_clear_all("cache_example", "cache", TRUE).'));
      break;
  }
}

/**
 * @} End of "defgroup cache_example".
 */