~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-includes/bookmark.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Link/Bookmark API
 
4
 *
 
5
 * @package WordPress
 
6
 * @subpackage Bookmark
 
7
 */
 
8
 
 
9
/**
 
10
 * Retrieve Bookmark data
 
11
 *
 
12
 * @since 2.1.0
 
13
 * @uses $wpdb Database Object
 
14
 *
 
15
 * @param mixed $bookmark
 
16
 * @param string $output Optional. Either OBJECT, ARRAY_N, or ARRAY_A constant
 
17
 * @param string $filter Optional, default is 'raw'.
 
18
 * @return array|object Type returned depends on $output value.
 
19
 */
 
20
function get_bookmark($bookmark, $output = OBJECT, $filter = 'raw') {
 
21
        global $wpdb;
 
22
 
 
23
        if ( empty($bookmark) ) {
 
24
                if ( isset($GLOBALS['link']) )
 
25
                        $_bookmark = & $GLOBALS['link'];
 
26
                else
 
27
                        $_bookmark = null;
 
28
        } elseif ( is_object($bookmark) ) {
 
29
                wp_cache_add($bookmark->link_id, $bookmark, 'bookmark');
 
30
                $_bookmark = $bookmark;
 
31
        } else {
 
32
                if ( isset($GLOBALS['link']) && ($GLOBALS['link']->link_id == $bookmark) ) {
 
33
                        $_bookmark = & $GLOBALS['link'];
 
34
                } elseif ( ! $_bookmark = wp_cache_get($bookmark, 'bookmark') ) {
 
35
                        $_bookmark = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->links WHERE link_id = %d LIMIT 1", $bookmark));
 
36
                        if ( $_bookmark ) {
 
37
                                $_bookmark->link_category = array_unique( wp_get_object_terms( $_bookmark->link_id, 'link_category', array( 'fields' => 'ids' ) ) );
 
38
                                wp_cache_add( $_bookmark->link_id, $_bookmark, 'bookmark' );
 
39
                        }
 
40
                }
 
41
        }
 
42
 
 
43
        if ( ! $_bookmark )
 
44
                return $_bookmark;
 
45
 
 
46
        $_bookmark = sanitize_bookmark($_bookmark, $filter);
 
47
 
 
48
        if ( $output == OBJECT ) {
 
49
                return $_bookmark;
 
50
        } elseif ( $output == ARRAY_A ) {
 
51
                return get_object_vars($_bookmark);
 
52
        } elseif ( $output == ARRAY_N ) {
 
53
                return array_values(get_object_vars($_bookmark));
 
54
        } else {
 
55
                return $_bookmark;
 
56
        }
 
57
}
 
58
 
 
59
/**
 
60
 * Retrieve single bookmark data item or field.
 
61
 *
 
62
 * @since 2.3.0
 
63
 * @uses get_bookmark() Gets bookmark object using $bookmark as ID
 
64
 * @uses sanitize_bookmark_field() Sanitizes Bookmark field based on $context.
 
65
 *
 
66
 * @param string $field The name of the data field to return
 
67
 * @param int $bookmark The bookmark ID to get field
 
68
 * @param string $context Optional. The context of how the field will be used.
 
69
 * @return string
 
70
 */
 
71
function get_bookmark_field( $field, $bookmark, $context = 'display' ) {
 
72
        $bookmark = (int) $bookmark;
 
73
        $bookmark = get_bookmark( $bookmark );
 
74
 
 
75
        if ( is_wp_error($bookmark) )
 
76
                return $bookmark;
 
77
 
 
78
        if ( !is_object($bookmark) )
 
79
                return '';
 
80
 
 
81
        if ( !isset($bookmark->$field) )
 
82
                return '';
 
83
 
 
84
        return sanitize_bookmark_field($field, $bookmark->$field, $bookmark->link_id, $context);
 
85
}
 
86
 
 
87
/**
 
88
 * Retrieves the list of bookmarks
 
89
 *
 
90
 * Attempts to retrieve from the cache first based on MD5 hash of arguments. If
 
91
 * that fails, then the query will be built from the arguments and executed. The
 
92
 * results will be stored to the cache.
 
93
 *
 
94
 * @since 2.1.0
 
95
 *
 
96
 * @global wpdb $wpdb WordPress database access abstraction object.
 
97
 *
 
98
 * @param string|array $args {
 
99
 *     Optional. String or array of arguments to retrieve bookmarks.
 
100
 *
 
101
 *     @type string   $orderby        How to order the links by. Accepts post fields. Default 'name'.
 
102
 *     @type string   $order          Whether to order bookmarks in ascending or descending order.
 
103
 *                                    Accepts 'ASC' (ascending) or 'DESC' (descending). Default 'ASC'.
 
104
 *     @type int      $limit          Amount of bookmarks to display. Accepts 1+ or -1 for all.
 
105
 *                                    Default -1.
 
106
 *     @type string   $category       Comma-separated list of category ids to include links from.
 
107
 *                                    Default empty.
 
108
 *     @type string   $category_name  Category to retrieve links for by name. Default empty.
 
109
 *     @type int|bool $hide_invisible Whether to show or hide links marked as 'invisible'. Accepts
 
110
 *                                    1|true or 0|false. Default 1|true.
 
111
 *     @type int|bool $show_updated   Whether to display the time the bookmark was last updated.
 
112
 *                                    Accepts 1|true or 0|false. Default 0|false.
 
113
 *     @type string   $include        Comma-separated list of bookmark IDs to include. Default empty.
 
114
 *     @type string   $exclude        Comma-separated list of bookmark IDs to exclude. Default empty.
 
115
 * }
 
116
 * @return array List of bookmark row objects.
 
117
 */
 
118
function get_bookmarks( $args = '' ) {
 
119
        global $wpdb;
 
120
 
 
121
        $defaults = array(
 
122
                'orderby' => 'name', 'order' => 'ASC',
 
123
                'limit' => -1, 'category' => '',
 
124
                'category_name' => '', 'hide_invisible' => 1,
 
125
                'show_updated' => 0, 'include' => '',
 
126
                'exclude' => '', 'search' => ''
 
127
        );
 
128
 
 
129
        $r = wp_parse_args( $args, $defaults );
 
130
 
 
131
        $key = md5( serialize( $r ) );
 
132
        if ( $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ) ) {
 
133
                if ( is_array( $cache ) && isset( $cache[ $key ] ) ) {
 
134
                        $bookmarks = $cache[ $key ];
 
135
                        /**
 
136
                         * Filter the returned list of bookmarks.
 
137
                         *
 
138
                         * The first time the hook is evaluated in this file, it returns the cached
 
139
                         * bookmarks list. The second evaluation returns a cached bookmarks list if the
 
140
                         * link category is passed but does not exist. The third evaluation returns
 
141
                         * the full cached results.
 
142
                         *
 
143
                         * @since 2.1.0
 
144
                         *
 
145
                         * @see get_bookmarks()
 
146
                         *
 
147
                         * @param array $bookmarks List of the cached bookmarks.
 
148
                         * @param array $r         An array of bookmark query arguments.
 
149
                         */
 
150
                        return apply_filters( 'get_bookmarks', $bookmarks, $r );
 
151
                }
 
152
        }
 
153
 
 
154
        if ( ! is_array( $cache ) ) {
 
155
                $cache = array();
 
156
        }
 
157
 
 
158
        $inclusions = '';
 
159
        if ( ! empty( $r['include'] ) ) {
 
160
                $r['exclude'] = '';  //ignore exclude, category, and category_name params if using include
 
161
                $r['category'] = '';
 
162
                $r['category_name'] = '';
 
163
                $inclinks = preg_split( '/[\s,]+/', $r['include'] );
 
164
                if ( count( $inclinks ) ) {
 
165
                        foreach ( $inclinks as $inclink ) {
 
166
                                if ( empty( $inclusions ) ) {
 
167
                                        $inclusions = ' AND ( link_id = ' . intval( $inclink ) . ' ';
 
168
                                } else {
 
169
                                        $inclusions .= ' OR link_id = ' . intval( $inclink ) . ' ';
 
170
                                }
 
171
                        }
 
172
                }
 
173
        }
 
174
        if (! empty( $inclusions ) ) {
 
175
                $inclusions .= ')';
 
176
        }
 
177
 
 
178
        $exclusions = '';
 
179
        if ( ! empty( $r['exclude'] ) ) {
 
180
                $exlinks = preg_split( '/[\s,]+/', $r['exclude'] );
 
181
                if ( count( $exlinks ) ) {
 
182
                        foreach ( $exlinks as $exlink ) {
 
183
                                if ( empty( $exclusions ) ) {
 
184
                                        $exclusions = ' AND ( link_id <> ' . intval( $exlink ) . ' ';
 
185
                                } else {
 
186
                                        $exclusions .= ' AND link_id <> ' . intval( $exlink ) . ' ';
 
187
                                }
 
188
                        }
 
189
                }
 
190
        }
 
191
        if ( ! empty( $exclusions ) ) {
 
192
                $exclusions .= ')';
 
193
        }
 
194
 
 
195
        if ( ! empty( $r['category_name'] ) ) {
 
196
                if ( $r['category'] = get_term_by('name', $r['category_name'], 'link_category') ) {
 
197
                        $r['category'] = $r['category']->term_id;
 
198
                } else {
 
199
                        $cache[ $key ] = array();
 
200
                        wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
 
201
                        /** This filter is documented in wp-includes/bookmark.php */
 
202
                        return apply_filters( 'get_bookmarks', array(), $r );
 
203
                }
 
204
        }
 
205
 
 
206
        $search = '';
 
207
        if ( ! empty( $r['search'] ) ) {
 
208
                $like = '%' . $wpdb->esc_like( $r['search'] ) . '%';
 
209
                $search = $wpdb->prepare(" AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ", $like, $like, $like );
 
210
        }
 
211
 
 
212
        $category_query = '';
 
213
        $join = '';
 
214
        if ( ! empty( $r['category'] ) ) {
 
215
                $incategories = preg_split( '/[\s,]+/', $r['category'] );
 
216
                if ( count($incategories) ) {
 
217
                        foreach ( $incategories as $incat ) {
 
218
                                if ( empty( $category_query ) ) {
 
219
                                        $category_query = ' AND ( tt.term_id = ' . intval( $incat ) . ' ';
 
220
                                } else {
 
221
                                        $category_query .= ' OR tt.term_id = ' . intval( $incat ) . ' ';
 
222
                                }
 
223
                        }
 
224
                }
 
225
        }
 
226
        if ( ! empty( $category_query ) ) {
 
227
                $category_query .= ") AND taxonomy = 'link_category'";
 
228
                $join = " INNER JOIN $wpdb->term_relationships AS tr ON ($wpdb->links.link_id = tr.object_id) INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id";
 
229
        }
 
230
 
 
231
        if ( $r['show_updated'] ) {
 
232
                $recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated ";
 
233
        } else {
 
234
                $recently_updated_test = '';
 
235
        }
 
236
 
 
237
        $get_updated = ( $r['show_updated'] ) ? ', UNIX_TIMESTAMP(link_updated) AS link_updated_f ' : '';
 
238
 
 
239
        $orderby = strtolower( $r['orderby'] );
 
240
        $length = '';
 
241
        switch ( $orderby ) {
 
242
                case 'length':
 
243
                        $length = ", CHAR_LENGTH(link_name) AS length";
 
244
                        break;
 
245
                case 'rand':
 
246
                        $orderby = 'rand()';
 
247
                        break;
 
248
                case 'link_id':
 
249
                        $orderby = "$wpdb->links.link_id";
 
250
                        break;
 
251
                default:
 
252
                        $orderparams = array();
 
253
                        $keys = array( 'link_id', 'link_name', 'link_url', 'link_visible', 'link_rating', 'link_owner', 'link_updated', 'link_notes' );
 
254
                        foreach ( explode( ',', $orderby ) as $ordparam ) {
 
255
                                $ordparam = trim( $ordparam );
 
256
 
 
257
                                if ( in_array( 'link_' . $ordparam, $keys ) ) {
 
258
                                        $orderparams[] = 'link_' . $ordparam;
 
259
                                } elseif ( in_array( $ordparam, $keys ) ) {
 
260
                                        $orderparams[] = $ordparam;
 
261
                                }
 
262
                        }
 
263
                        $orderby = implode( ',', $orderparams );
 
264
        }
 
265
 
 
266
        if ( empty( $orderby ) ) {
 
267
                $orderby = 'link_name';
 
268
        }
 
269
 
 
270
        $order = strtoupper( $r['order'] );
 
271
        if ( '' !== $order && ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
 
272
                $order = 'ASC';
 
273
        }
 
274
 
 
275
        $visible = '';
 
276
        if ( $r['hide_invisible'] ) {
 
277
                $visible = "AND link_visible = 'Y'";
 
278
        }
 
279
 
 
280
        $query = "SELECT * $length $recently_updated_test $get_updated FROM $wpdb->links $join WHERE 1=1 $visible $category_query";
 
281
        $query .= " $exclusions $inclusions $search";
 
282
        $query .= " ORDER BY $orderby $order";
 
283
        if ( $r['limit'] != -1 ) {
 
284
                $query .= ' LIMIT ' . $r['limit'];
 
285
        }
 
286
 
 
287
        $results = $wpdb->get_results( $query );
 
288
 
 
289
        $cache[ $key ] = $results;
 
290
        wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
 
291
 
 
292
        /** This filter is documented in wp-includes/bookmark.php */
 
293
        return apply_filters( 'get_bookmarks', $results, $r );
 
294
}
 
295
 
 
296
/**
 
297
 * Sanitizes all bookmark fields
 
298
 *
 
299
 * @since 2.3.0
 
300
 *
 
301
 * @param object|array $bookmark Bookmark row
 
302
 * @param string $context Optional, default is 'display'. How to filter the
 
303
 *              fields
 
304
 * @return object|array Same type as $bookmark but with fields sanitized.
 
305
 */
 
306
function sanitize_bookmark($bookmark, $context = 'display') {
 
307
        $fields = array('link_id', 'link_url', 'link_name', 'link_image', 'link_target', 'link_category',
 
308
                'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_updated',
 
309
                'link_rel', 'link_notes', 'link_rss', );
 
310
 
 
311
        if ( is_object($bookmark) ) {
 
312
                $do_object = true;
 
313
                $link_id = $bookmark->link_id;
 
314
        } else {
 
315
                $do_object = false;
 
316
                $link_id = $bookmark['link_id'];
 
317
        }
 
318
 
 
319
        foreach ( $fields as $field ) {
 
320
                if ( $do_object ) {
 
321
                        if ( isset($bookmark->$field) )
 
322
                                $bookmark->$field = sanitize_bookmark_field($field, $bookmark->$field, $link_id, $context);
 
323
                } else {
 
324
                        if ( isset($bookmark[$field]) )
 
325
                                $bookmark[$field] = sanitize_bookmark_field($field, $bookmark[$field], $link_id, $context);
 
326
                }
 
327
        }
 
328
 
 
329
        return $bookmark;
 
330
}
 
331
 
 
332
/**
 
333
 * Sanitizes a bookmark field
 
334
 *
 
335
 * Sanitizes the bookmark fields based on what the field name is. If the field
 
336
 * has a strict value set, then it will be tested for that, else a more generic
 
337
 * filtering is applied. After the more strict filter is applied, if the
 
338
 * $context is 'raw' then the value is immediately return.
 
339
 *
 
340
 * Hooks exist for the more generic cases. With the 'edit' context, the
 
341
 * 'edit_$field' filter will be called and passed the $value and $bookmark_id
 
342
 * respectively. With the 'db' context, the 'pre_$field' filter is called and
 
343
 * passed the value. The 'display' context is the final context and has the
 
344
 * $field has the filter name and is passed the $value, $bookmark_id, and
 
345
 * $context respectively.
 
346
 *
 
347
 * @since 2.3.0
 
348
 *
 
349
 * @param string $field The bookmark field
 
350
 * @param mixed $value The bookmark field value
 
351
 * @param int $bookmark_id Bookmark ID
 
352
 * @param string $context How to filter the field value. Either 'raw', 'edit',
 
353
 *              'attribute', 'js', 'db', or 'display'
 
354
 * @return mixed The filtered value
 
355
 */
 
356
function sanitize_bookmark_field($field, $value, $bookmark_id, $context) {
 
357
        switch ( $field ) {
 
358
        case 'link_id' : // ints
 
359
        case 'link_rating' :
 
360
                $value = (int) $value;
 
361
                break;
 
362
        case 'link_category' : // array( ints )
 
363
                $value = array_map('absint', (array) $value);
 
364
                // We return here so that the categories aren't filtered.
 
365
                // The 'link_category' filter is for the name of a link category, not an array of a link's link categories
 
366
                return $value;
 
367
 
 
368
        case 'link_visible' : // bool stored as Y|N
 
369
                $value = preg_replace('/[^YNyn]/', '', $value);
 
370
                break;
 
371
        case 'link_target' : // "enum"
 
372
                $targets = array('_top', '_blank');
 
373
                if ( ! in_array($value, $targets) )
 
374
                        $value = '';
 
375
                break;
 
376
        }
 
377
 
 
378
        if ( 'raw' == $context )
 
379
                return $value;
 
380
 
 
381
        if ( 'edit' == $context ) {
 
382
                /** This filter is documented in wp-includes/post.php */
 
383
                $value = apply_filters( "edit_$field", $value, $bookmark_id );
 
384
 
 
385
                if ( 'link_notes' == $field ) {
 
386
                        $value = esc_html( $value ); // textarea_escaped
 
387
                } else {
 
388
                        $value = esc_attr($value);
 
389
                }
 
390
        } else if ( 'db' == $context ) {
 
391
                /** This filter is documented in wp-includes/post.php */
 
392
                $value = apply_filters( "pre_$field", $value );
 
393
        } else {
 
394
                /** This filter is documented in wp-includes/post.php */
 
395
                $value = apply_filters( $field, $value, $bookmark_id, $context );
 
396
 
 
397
                if ( 'attribute' == $context )
 
398
                        $value = esc_attr($value);
 
399
                else if ( 'js' == $context )
 
400
                        $value = esc_js($value);
 
401
        }
 
402
 
 
403
        return $value;
 
404
}
 
405
 
 
406
/**
 
407
 * Deletes bookmark cache
 
408
 *
 
409
 * @since 2.7.0
 
410
 * @uses wp_cache_delete() Deletes the contents of 'get_bookmarks'
 
411
 */
 
412
function clean_bookmark_cache( $bookmark_id ) {
 
413
        wp_cache_delete( $bookmark_id, 'bookmark' );
 
414
        wp_cache_delete( 'get_bookmarks', 'bookmark' );
 
415
        clean_object_term_cache( $bookmark_id, 'link');
 
416
}