PluginProbe
Hum / 1.1
Hum v1.1
trunk 1.0 1.1 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6
hum / hum.php

hum.php in Hum 1.1, at hum.php

334 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Hum
4 Plugin URI: http://github.com/willnorris/wordpress-hum
5 Description: Personal URL shortener for WordPress
6 Author: Will Norris
7 Author URI: http://willnorris.com/
8 Version: 1.1
9 License: MIT (http://opensource.org/licenses/MIT)
10 Text Domain: hum
11 */
12
13
14 // if you have hum installed, then you probably actually care about short
15 // links, so we'll add it to the admin menu bar.
16 add_action('admin_bar_menu', 'wp_admin_bar_shortlink_menu', 90);
17
18
19 /**
20 * Accept hum query variables.
21 */
22 function hum_query_vars( $vars ) {
23 $vars[] = 'hum';
24 return $vars;
25 }
26 add_action('query_vars', 'hum_query_vars');
27
28
29 /**
30 * Parse request for shortlink.
31 *
32 * @uses do_action() Calls 'hum_request_{$type}" action
33 * @uses do_action() Calls 'hum_request" action
34 */
35 function hum_parse_request( $wp ) {
36 if ( array_key_exists( 'hum', $wp->query_vars ) ) {
37 list($type, $id) = explode('/', $wp->query_vars['hum'], 2);
38 do_action("hum_request_{$type}", $id);
39 do_action('hum_request', $type, $id);
40
41 // hum hasn't handled the request yet, so try again but strip common
42 // punctuation that might appear after a URL in written text: . , )
43 $clean_id = preg_replace('/[\.,\)]+$/', '', $id);
44 if ($id != $clean_id) {
45 do_action("hum_request_{$type}", $clean_id);
46 do_action('hum_request', $type, $clean_id);
47 }
48
49 // hum didn't handle request, so issue 404.
50 // manually setting query vars like this feels very fragile, but
51 // $wp_query->set_404() doesn't do what we need here.
52 $wp->query_vars['error'] = '404';
53 }
54 }
55 add_action('parse_request', 'hum_parse_request');
56
57
58 /**
59 * Redirect shortlinks that are for content hosted directly within WordPress.
60 * The 'id' portion of these URLs is expected to be the sexagesimal post ID.
61 *
62 * @uses apply_filters() Calls 'hum_local_types' filter on prefixes for local
63 * WordPress hosted content
64 * @param string $code the content-type prefix
65 */
66 function hum_redirect_local( $type, $id ) {
67 $local_types = array('b', 't');
68 $local_types = apply_filters('hum_local_types', $local_types);
69
70 if ( in_array($type, $local_types) ) {
71 $p = sxg_to_num( $id );
72 $permalink = get_permalink($p);
73
74 if ( $permalink ) {
75 wp_redirect( $permalink, 301 );
76 exit;
77 }
78 }
79 }
80 add_filter('hum_request', 'hum_redirect_local', 20, 2);
81
82
83 /**
84 * Handles /i/ URLs that have ISBN or ASIN subpaths by redirecting to Amazon.
85 *
86 * @uses do_action() Calls 'hum_request_i_{$subtype}' action
87 * @uses apply_filters() Calls 'amazon_affiliate_id' filter
88 *
89 * @param string $path subpath of URL (after /i/)
90 */
91 function hum_request_i( $path ) {
92 list($subtype, $id) = preg_split('|/|', $path, 2);
93 do_action("hum_request_i_{$subtype}", $id);
94 switch ($subtype) {
95 case 'a':
96 case 'asin':
97 case 'i':
98 case 'isbn':
99 $amazon_id = apply_filters('amazon_affiliate_id', false);
100 if ($amazon_id) {
101 wp_redirect('http://www.amazon.com/gp/redirect.html?ie=UTF8&location='
102 . 'http%3A%2F%2Fwww.amazon.com%2Fdp%2F' . $id . '&tag=' . $amazon_id
103 . '&linkCode=ur2&camp=1789&creative=9325');
104 } else {
105 wp_redirect('http://www.amazon.com/dp/' . $id );
106 }
107 exit;
108 break;
109 }
110 }
111 add_filter('hum_request_i', 'hum_request_i', 20);
112
113
114 /**
115 * Allow for simple redirect rules for shortlink prefixes. Users can provide a
116 * filter to perform simple URL redirect for a given type prefix. For example,
117 * to redirect all /w/ shortlinks to your personal PBworks wiki, you could use:
118 *
119 * add_filter('hum_redirect_base_w',
120 * create_function('', 'return "http://willnorris.pbworks.com/";'));
121 *
122 * @uses apply_filters() Calls 'hum_redirect_base_{$type}' filter on redirect base URL
123 */
124 function hum_redirect_request( $type, $id ) {
125 $url = apply_filters("hum_redirect_base_{$type}", false);
126 if ( $url ) {
127 $url = trailingslashit($url) . $id;
128 wp_redirect( $url );
129 exit;
130 }
131 }
132 add_action('hum_request', 'hum_redirect_request', 30, 2);
133
134
135 /**
136 * Add rewrite rules for hum shortlinks.
137 *
138 * @param object $wp_rewrite
139 */
140 function hum_rewrite_rules( $wp_rewrite ) {
141 $hum_rules = array(
142 '([a-z](/.*)?$)' => 'index.php?hum=$matches[1]',
143 );
144
145 $wp_rewrite->rules = $hum_rules + $wp_rewrite->rules;
146 }
147 add_action('generate_rewrite_rules', 'hum_rewrite_rules');
148
149
150 /**
151 * Flush wp_rewrite rules.
152 */
153 function hum_flush_rewrite_rules() {
154 global $wp_rewrite;
155 $wp_rewrite->flush_rules();
156 }
157 register_activation_hook(__FILE__, 'hum_flush_rewrite_rules');
158 register_deactivation_hook(__FILE__, 'hum_flush_rewrite_rules');
159
160
161 /**
162 * Get the base URL for hum shortlinks. Defaults to the WordPress home url.
163 * Users can define HUM_SHORTLINK_BASE or provide a filter to use a custom
164 * domain for shortlinks.
165 *
166 * @uses apply_filters() Calls 'hum_shortlink_base' filter on base URL
167 * @return string
168 */
169 function hum_shortlink_base() {
170 $base = get_option('hum_shortlink_base');
171 if ( empty( $base ) ) {
172 $base = home_url();
173 }
174 return apply_filters( 'hum_shortlink_base', $base );
175 }
176
177
178 /**
179 * Allow the constant named 'HUM_SHORTLINK_BASE' to override the base URL for shortlinks.
180 */
181 function _config_hum_shortlink_base( $url = '' ) {
182 if ( defined( 'HUM_SHORTLINK_BASE') ) {
183 return untrailingslashit( HUM_SHORTLINK_BASE );
184 }
185 return $url;
186 }
187 add_filter('pre_option_hum_shortlink_base', '_config_hum_shortlink_base');
188
189
190 /**
191 * Get the shortlink for a post, page, attachment, or blog.
192 *
193 * @param string $link the current shortlink for the post
194 * @param int $id post ID
195 * @param string $context
196 * @param boolean $allow_slugs
197 * @return string
198 */
199 function hum_get_shortlink($link, $id, $context, $allow_slugs) {
200 $post_id = 0;
201 if ( 'query' == $context ) {
202 if ( is_front_page() ) {
203 $link = trailingslashit( hum_shortlink_base() );
204 } elseif ( is_singular() ) {
205 $post_id = get_queried_object_id();
206 }
207 } elseif ( 'post' == $context ) {
208 $post = get_post($id);
209 $post_id = $post->ID;
210 }
211
212 if ( !empty($post_id) ) {
213 $type = hum_type_prefix($post_id);
214 $sxg_id = num_to_sxg($post_id);
215 $link = trailingslashit( hum_shortlink_base() ) . $type . '/' . $sxg_id;
216 }
217
218 return $link;
219 }
220 add_filter('pre_get_shortlink', 'hum_get_shortlink', 10, 4);
221
222
223 /**
224 * Get the content-type prefix for the specified post.
225 *
226 * @see http://ttk.me/w/Whistle#design
227 * @uses apply_filters() Calls 'hum_type_prefix' on the content type prefix
228 *
229 * @param int|object $post A post
230 * @return string the content type prefix for the post
231 */
232 function hum_type_prefix( $post ) {
233 $prefix = 'b';
234
235 $post_format = get_post_format( $post );
236 switch($post_format) {
237 case 'aside':
238 $prefix = 't'; break;
239 case 'status':
240 $prefix = 't'; break;
241 }
242
243 return apply_filters('hum_type_prefix', $prefix, $post);
244 }
245
246
247 // Admin Settings
248
249
250 /**
251 * Register admin settings for Hum.
252 */
253 function hum_admin_init() {
254 register_setting('general', 'hum_shortlink_base');
255 }
256 add_action('admin_init', 'hum_admin_init');
257
258
259 /**
260 * Add admin settings fields for Hum.
261 */
262 function hum_admin_menu() {
263 add_settings_field('hum_shortlink_base', __('Shortlink Base (URL)', 'hum'), 'hum_admin_shortlink_base', 'general');
264 }
265 add_action('admin_menu', 'hum_admin_menu');
266
267
268 /**
269 * Admin UI for setting the shortlink base URL.
270 */
271 function hum_admin_shortlink_base() {
272 ?>
273 <input name="hum_shortlink_base" type="text" id="hum_shortlink_base" value="<?php form_option('hum_shortlink_base'); ?>"<?php disabled( defined( 'HUM_SHORTLINK_BASE') ); ?> class="regular-text code<?php if ( defined( 'HUM_SHORTLINK_BASE') ) echo ' disabled' ?>" />
274 <p class="description">
275 If you have a custom domain you want to use for shortlinks, enter the address here.
276 </p>
277
278 <script>
279 // move adjacent to other URL properties
280 jQuery('input#hum_shortlink_base').parents('tr')
281 .insertAfter( jQuery('input#home').parents('tr') );
282 </script>
283 <?php
284 }
285
286
287 // New Base 60 - see http://ttk.me/w/NewBase60
288 //
289 // slightly modified from Cassis Project (http://cassisproject.com/)
290 // Copyright 2010 Tantek Çelik, released under Creative Commons by-sa 3.0
291
292 if ( !function_exists( 'num_to_sxg' ) ):
293 /**
294 * Convert base-10 number to sexagesimal.
295 */
296 function num_to_sxg($n) {
297 $s = "";
298 $m = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz";
299 if ($n===null || $n===0) { return 0; }
300 while ($n>0) {
301 $d = $n % 60;
302 $s = $m[$d] . $s;
303 $n = ($n-$d)/60;
304 }
305 return $s;
306 }
307 endif;
308
309
310 if ( !function_exists( 'sxg_to_num' ) ):
311 /**
312 * Convert sexagesimal to base-10 number.
313 */
314 function sxg_to_num($s) {
315 $n = 0;
316 $j = strlen($s);
317 for ($i=0;$i<$j;$i++) { // iterate from first to last char of $s
318 $c = ord($s[$i]); // put current ASCII of char into $c
319 if ($c>=48 && $c<=57) { $c=$c-48; }
320 else if ($c>=65 && $c<=72) { $c-=55; }
321 else if ($c==73 || $c==108) { $c=1; } // typo capital I, lowercase l to 1
322 else if ($c>=74 && $c<=78) { $c-=56; }
323 else if ($c==79) { $c=0; } // error correct typo capital O to 0
324 else if ($c>=80 && $c<=90) { $c-=57; }
325 else if ($c==95) { $c=34; } // underscore
326 else if ($c>=97 && $c<=107) { $c-=62; }
327 else if ($c>=109 && $c<=122) { $c-=63; }
328 else { $c = 0; } // treat all other noise as 0
329 $n = 60*$n + $c;
330 }
331 return $n;
332 }
333 endif;
334