PluginProbe
Redirection / 2.2.12
Redirection v2.2.12
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / plugin.php

plugin.php in Redirection 2.2.12, at plugin.php

516 lines 17.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // ======================================================================================
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or(at your option) any later version.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 // ======================================================================================
14 // @author John Godley(http://urbangiraffe.com)
15 // @version 0.2.7
16 // @copyright Copyright &copy; 2009 John Godley, All Rights Reserved
17 // ======================================================================================
18 // 0.1.6 - Corrected WP locale functions
19 // 0.1.7 - Add phpdoc comments
20 // 0.1.8 - Support for Admin SSL
21 // 0.1.9 - URL encoding, defer localization until init
22 // 0.1.10 - Better URL encoding
23 // 0.1.11 - Make work in WP 2.0, fix HTTPS issue on IIS
24 // 0.1.12 - Activation/deactivation actions that take into account the directory
25 // 0.1.13 - Add realpath function
26 // 0.1.14 - Add select/checked functions, fix locale loader
27 // 0.1.15 - Remove dependency on prototype
28 // 0.1.16 - Add support for homedir in realpath
29 // 0.1.17 - Added widget class
30 // 0.1.18 - Expand checked function
31 // 0.1.19 - Make url() cope with sites with no trailing slash
32 // 0.1.20 - Change init function to prevent overloading
33 // 0.1.21 - Make widget work for WP 2.1
34 // 0.1.22 - Make select work with option groups, RSS compatability fix
35 // 0.1.23 - Make widget count work better, fix widgets in K2
36 // 0.1.24 - Make realpath better
37 // 0.1.25 - Support for new WP2.6 config location
38 // 0.1.26 - Add description to widget class
39 // 0.1.27 - Realpath on windows again
40 // 0.1.28 - Plugin version information
41 // 0.1.29 - Plugin version for older WP
42 // 0.1.30 - Add htmlspecialchars for non-support charsets
43 // 0.2 - WP Coding style
44 // 0.2.1 - Better HTTPS detection
45 // 0.2.2 - Plugin settings, base function
46 // 0.2.3 - More HTTPS
47 // 0.2.4 - Ajax helper, more compatability functions
48 // 0.2.5 - _n helper
49 // 0.2.6 - Compatability functions js_esc
50 // 0.2.7 - Allow multiple hooks in add_action/add_filter
51 // ======================================================================================
52
53
54 /**
55 * Wraps up several useful functions for WordPress plugins and provides a method to separate
56 * display HTML from PHP code.
57 *
58 * <h4>Display Rendering</h4>
59 * The class uses a similar technique to Ruby On Rails views, whereby the display HTML is kept
60 * in a separate directory and file from the main code. A display is 'rendered'(sent to the browser)
61 * or 'captured'(returned to the calling function).
62 *
63 * Template files are separated into two areas: admin and user. Admin templates are only for display in
64 * the WordPress admin interface, while user templates are typically for display on the site(although neither
65 * of these are enforced). All templates are PHP code, but are referred to without .php extension.
66 *
67 * The reason for this separation is that one golden rule of plugin creation is that someone will always want to change
68 * the formatting and style of your output. Rather than forcing them to modify the plugin(bad), or modify files within
69 * the plugin(equally bad), the class allows user templates to be overridden with files contained within the theme.
70 *
71 * An additional benefit is that it leads to code re-use, especially with regards to Ajax(i.e. your display code can be called from
72 * many locations)
73 *
74 * Template files are located within the 'view' subdirectory of the plugins base(specified when registering the plugin):
75 *
76 * <pre>myplugin/view/admin
77 * myplugin/view/myplugin</pre>
78 *
79 * Admin templates are contained within 'admin', and user templates are contained within a directory of the same name as the plugin.
80 *
81 * User files can be overridden within the theme by creating a similar directory structure:
82 *
83 * <pre>/themes/mytheme/view/myplugin</pre>
84 *
85 * The class will first look in the theme and then defaults to the plugin. A plugin should always provide default templates.
86 *
87 * <h4>Display Parameters</h4>
88 * Also similar to Ruby On Rails, when you display a template you must supply the parameters that the template has access to. This tries
89 * to ensure a very clean separation between code and display. Parameters are supplied as an associative array mapping variable name to variable value.
90 *
91 * For example,
92 *
93 * array( 'message' => 'Your data was processed', 'items' => 103);
94 *
95 * <h4>How it works in practice</h4>
96 * You create a template file to display how many items have been processed. You store this in 'view/admin/processed.php':
97 *
98 * <pre>&lt;p&gt;You processed &lt;?php echo $items ?&gt; items&lt;/p&gt;</pre>
99 *
100 * When you want to display this in your plugin you use:
101 *
102 * <pre> $this->render_admin( 'processed', array( 'items' => 100));</pre>
103 *
104 * @package WordPress base library
105 * @author John Godley
106 * @copyright Copyright(C) John Godley
107 **/
108
109 class Redirection_Plugin {
110 /**
111 * Plugin name
112 * @var string
113 **/
114 var $plugin_name;
115
116 /**
117 * Plugin 'view' directory
118 * @var string Directory
119 **/
120 var $plugin_base;
121
122 /**
123 * Version URL(if enabled)
124 * @var string URL
125 **/
126 var $version_url;
127
128 /**
129 * Register your plugin with a name and base directory. This <strong>must</strong> be called once.
130 *
131 * @param string $name Name of your plugin. Is used to determine the plugin locale domain
132 * @param string $base Directory containing the plugin's 'view' files.
133 * @return void
134 **/
135 function register_plugin( $name, $base ) {
136 $this->plugin_base = rtrim( dirname( $base ), '/' );
137 $this->plugin_name = $name;
138
139 $this->add_action( 'init', 'load_locale' );
140 }
141
142 /**
143 * Hook called to change the locale directory
144 * @return void
145 **/
146 function load_locale() {
147 // Here we manually fudge the plugin locale as WP doesnt allow many options
148 $locale = get_locale();
149 if( empty( $locale ) )
150 $locale = 'en_US';
151
152 $mofile = dirname( __FILE__ )."/locale/$locale.mo";
153 load_textdomain( $this->plugin_name, $mofile );
154 }
155
156
157 /**
158 * Register a WordPress action and map it back to the calling object
159 *
160 * @param mixed $action Name of the action (single string or array of strings)
161 * @param string $function Function name (optional, if an array is given for $action then first $action is used as function name)
162 * @param int $priority WordPress priority(optional)
163 * @param int $accepted_args Number of arguments the function accepts(optional)
164 * @return void
165 **/
166 function add_action( $actions, $function = '', $priority = 10, $accepted_args = 1 ) {
167 if ( !is_array( $actions ) )
168 $actions = array( $actions );
169
170 foreach ( $actions AS $action ) {
171 add_action( $action, array( &$this, $function == '' ? $actions[0] : $function ), $priority, $accepted_args );
172 }
173 }
174
175
176 /**
177 * Register a WordPress filter and map it back to the calling object
178 *
179 * @param mixed $action Name of the action (single string or array of strings)
180 * @param string $function Function name (optional, if an array is given for $action then first $action is used as function name)
181 * @param int $priority WordPress priority(optional)
182 * @param int $accepted_args Number of arguments the function accepts(optional)
183 * @return void
184 **/
185 function add_filter( $filters, $function = '', $priority = 10, $accepted_args = 1 ) {
186 if ( !is_array( $filters ) )
187 $filters = array( $filters );
188
189 foreach ( $filters AS $filter ) {
190 add_filter( $filter, array( &$this, $function == '' ? $filters[0] : $function ), $priority, $accepted_args );
191 }
192 }
193
194
195 /**
196 * Special activation function that takes into account the plugin directory
197 *
198 * @param string $pluginfile The plugin file location(i.e. __FILE__)
199 * @param string $function Optional function name, or default to 'activate'
200 * @return void
201 **/
202 function register_activation( $pluginfile, $function = '' ) {
203 add_action( 'activate_'.basename( dirname( $pluginfile ) ).'/'.basename( $pluginfile ), array( &$this, $function == '' ? 'activate' : $function ) );
204 }
205
206 function register_ajax( $action, $function = '', $priority = 10 ) {
207 add_action( 'wp_ajax_'.$action, array( &$this, $function == '' ? $action : $function ), $priority );
208 }
209
210 /**
211 * Special deactivation function that takes into account the plugin directory
212 *
213 * @param string $pluginfile The plugin file location(i.e. __FILE__)
214 * @param string $function Optional function name, or default to 'deactivate'
215 * @return void
216 **/
217 function register_deactivation( $pluginfile, $function = '' ) {
218 add_action( 'deactivate_'.basename( dirname( $pluginfile ) ).'/'.basename( $pluginfile ), array( &$this, $function == '' ? 'deactivate' : $function ) );
219 }
220
221 function register_plugin_settings( $pluginfile, $function = '' ) {
222 add_action( 'plugin_action_links_'.basename( dirname( $pluginfile ) ).'/'.basename( $pluginfile ), array( &$this, $function == '' ? 'plugin_settings' : $function ), 10, 4 );
223 }
224
225 /**
226 * Renders an admin section of display code
227 *
228 * @param string $ug_name Name of the admin file(without extension)
229 * @param string $array Array of variable name=>value that is available to the display code(optional)
230 * @return void
231 **/
232 function render_admin( $ug_name, $ug_vars = array() ) {
233 global $plugin_base;
234
235 foreach ( $ug_vars AS $key => $val ) {
236 $$key = $val;
237 }
238
239 if ( file_exists( "{$this->plugin_base}/view/admin/$ug_name.php" ) )
240 include "{$this->plugin_base}/view/admin/$ug_name.php";
241 else
242 echo "<p>Rendering of admin template {$this->plugin_base}/view/admin/$ug_name.php failed</p>";
243 }
244
245 /**
246 * Renders a section of user display code. The code is first checked for in the current theme display directory
247 * before defaulting to the plugin
248 *
249 * @param string $ug_name Name of the admin file(without extension)
250 * @param string $array Array of variable name=>value that is available to the display code(optional)
251 * @return void
252 **/
253 function render( $ug_name, $ug_vars = array() ) {
254 foreach ( $ug_vars AS $key => $val ) {
255 $$key = $val;
256 }
257
258 if ( file_exists( TEMPLATEPATH."/view/{$this->plugin_name}/$ug_name.php" ) )
259 include TEMPLATEPATH."/view/{$this->plugin_name}/$ug_name.php";
260 elseif ( file_exists( "{$this->plugin_base}/view/{$this->plugin_name}/$ug_name.php" ) )
261 include "{$this->plugin_base}/view/{$this->plugin_name}/$ug_name.php";
262 else
263 echo "<p>Rendering of template $ug_name.php failed</p>";
264 }
265
266 /**
267 * Renders a section of user display code. The code is first checked for in the current theme display directory
268 * before defaulting to the plugin
269 *
270 * @param string $ug_name Name of the admin file(without extension)
271 * @param string $array Array of variable name=>value that is available to the display code(optional)
272 * @return void
273 **/
274 function capture( $ug_name, $ug_vars = array() ) {
275 ob_start();
276
277 $this->render( $ug_name, $ug_vars );
278 $output = ob_get_contents();
279
280 ob_end_clean();
281 return $output;
282 }
283
284 /**
285 * Captures an admin section of display code
286 *
287 * @param string $ug_name Name of the admin file(without extension)
288 * @param string $array Array of variable name=>value that is available to the display code(optional)
289 * @return string Captured code
290 **/
291 function capture_admin( $ug_name, $ug_vars = array() ) {
292 ob_start();
293
294 $this->render_admin( $ug_name, $ug_vars );
295 $output = ob_get_contents();
296
297 ob_end_clean();
298 return $output;
299 }
300
301 /**
302 * Display a standard error message(using CSS ID 'message' and classes 'fade' and 'error)
303 *
304 * @param string $message Message to display
305 * @return void
306 **/
307 function render_error( $message ) {
308 ?>
309 <div class="fade error" id="message">
310 <p><?php echo $message ?></p>
311 </div>
312 <?php
313 }
314
315 /**
316 * Display a standard notice(using CSS ID 'message' and class 'updated' ).
317 * Note that the notice can be made to automatically disappear, and can be removed
318 * by clicking on it.
319 *
320 * @param string $message Message to display
321 * @param int $timeout Number of seconds to automatically remove the message(optional)
322 * @return void
323 **/
324 function render_message( $message, $timeout = 0 ) {
325 ?>
326 <div class="updated" id="message" onclick="this.parentNode.removeChild(this)">
327 <p><?php echo $message ?></p>
328 </div>
329 <?php
330 }
331
332 /**
333 * Get the plugin's base directory
334 *
335 * @return string Base directory
336 **/
337 function dir() {
338 return $this->plugin_base;
339 }
340
341 function base () {
342 return admin_url( $this->plugin_name );
343 }
344
345 /**
346 * Get a URL to the plugin. Useful for specifying JS and CSS files
347 *
348 * For example, <img src="<?php echo $this->url() ?>/myimage.png"/>
349 *
350 * @return string URL
351 **/
352 function url( $url = '' ) {
353 if ( $url )
354 return str_replace( '\\', urlencode( '\\' ), str_replace( '&amp;amp', '&amp;', str_replace( '&', '&amp;', $url ) ) );
355
356 $root = ABSPATH;
357 if ( defined( 'WP_PLUGIN_DIR' ) )
358 $root = WP_PLUGIN_DIR;
359
360 $url = substr( $this->plugin_base, strlen( $this->realpath( $root ) ) );
361 if ( DIRECTORY_SEPARATOR != '/' )
362 $url = str_replace( DIRECTORY_SEPARATOR, '/', $url );
363
364 if ( defined( 'WP_PLUGIN_URL' ) )
365 $url = WP_PLUGIN_URL.'/'.ltrim( $url, '/' );
366 else
367 $url = get_bloginfo( 'wpurl' ).'/'.ltrim( $url, '/' );
368
369 // Do an SSL check - only works on Apache
370 global $is_IIS;
371 if ( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on' && $is_IIS === false )
372 $url = str_replace( 'http://', 'https://', $url );
373
374 return $url;
375 }
376
377 /**
378 * Version of realpath that will work on systems without realpath
379 *
380 * @param string $path The path to canonicalize
381 * @return string Canonicalized path
382 **/
383 function realpath( $path ) {
384 if ( function_exists( 'realpath' ) && DIRECTORY_SEPARATOR == '/' )
385 return realpath( $path );
386 elseif ( DIRECTORY_SEPARATOR == '/' )
387 {
388 $path = preg_replace( '/^~/', $_SERVER['DOCUMENT_ROOT'], $path );
389
390 // canonicalize
391 $path = explode( DIRECTORY_SEPARATOR, $path );
392 $newpath = array();
393
394 for ( $i = 0; $i < count( $path ); $i++ ) {
395 if ( $path[$i] === '' || $path[$i] === '.' )
396 continue;
397
398 if ( $path[$i] === '..' ) {
399 array_pop( $newpath );
400 continue;
401 }
402
403 array_push( $newpath, $path[$i] );
404 }
405
406 return DIRECTORY_SEPARATOR.implode( DIRECTORY_SEPARATOR, $newpath );
407 }
408
409 return $path;
410 }
411
412 /**
413 * Helper function to check a checkbox if the item has been checked
414 *
415 * @param mixed $item Checkbox value, or array of checkbox values: field => value
416 * @param string $field Fieldname, if array is given for $item
417 * @return void
418 **/
419 function checked( $item, $field = '' ) {
420 if ( $field && is_array( $item ) ) {
421 if ( isset( $item[$field] ) && $item[$field] )
422 echo ' checked="checked"';
423 }
424 elseif ( !empty( $item ) )
425 echo ' checked="checked"';
426 }
427
428 /**
429 * Helper function to display a dropdown select box
430 *
431 * @param array $items Associative array of: fieldname => label
432 * @param string $default Default fieldname to select
433 * @return void
434 **/
435 function select( $items, $default = '' ) {
436 if ( count( $items ) > 0 ) {
437 foreach ( $items AS $key => $value ) {
438 if ( is_array( $value ) ) {
439 echo '<optgroup label="'.esc_attr( $key ).'">';
440
441 foreach ( $value AS $sub => $subvalue ) {
442 echo '<option value="'.esc_attr( $sub ).'"'.( $sub == $default ? ' selected="selected"' : '' ).'>'.esc_html( $subvalue ).'</option>';
443 }
444
445 echo '</optgroup>';
446 }
447 else
448 echo '<option value="'.esc_attr( $key ).'"'.( $key == $default ? ' selected="selected"' : '' ).'>'.esc_html( $value ).'</option>';
449 }
450 }
451 }
452
453 /**
454 * Expanded version of htmlspecialchars which detects the blog encoding and runs iconv on any encoding that is not supported by htmlspecialchars
455 *
456 * @param string $text Text to run htmlspecialchars on
457 * @return void
458 **/
459 function specialchars( $text ) {
460 $charset = get_option( 'blog_charset' );
461
462 if ( $charset != 'UTF-8' && function_exists( 'iconv' ) && !in_array( $charset, array( 'ISO-8859-1', 'ISO-8859-15', 'cp1251', 'cp1252', 'KOI8-R', 'BIG5', 'GB2312', 'Shift_JIS', 'EUC-JP' ) ) )
463 return iconv( 'UTF-8//IGNORE', $charset, htmlspecialchars( iconv( $charset, 'UTF-8//IGNORE', $text ) ) );
464 return htmlspecialchars( $text, ENT_COMPAT, $charset );
465 }
466
467 /**
468 * Special version of strlen that runs mb_strlen if blog encoding is not UTF-8
469 *
470 * @param string $name Name of your plugin. Is used to determine the plugin locale domain
471 * @param string $base Directory containing the plugin's 'view' files.
472 * @return void
473 **/
474 function strlen( $text ) {
475 $charset = get_option( 'blog_charset' );
476
477 if ( $charset != 'UTF-8' && function_exists( 'mb_strlen' ) )
478 return mb_strlen( $text );
479 return strlen( $text );
480 }
481
482 /**
483 * Returns version of plugin
484 *
485 * @return string Version
486 **/
487 function version() {
488 $plugin_data = implode( '', file( $this->plugin_base ) );
489
490 if ( preg_match( '|Version:(.*)|i', $plugin_data, $version ) )
491 return trim( $version[1] );
492 return '';
493 }
494 }
495
496 /**
497 * Debug helper, borrowed from CakePHP, that displays a print_r inside <pre></pre> tags
498 *
499 * @param string $name Name of your plugin. Is used to determine the plugin locale domain
500 * @param string $base Directory containing the plugin's 'view' files.
501 * @return void
502 **/
503 if ( !function_exists( 'pr' ) ) {
504 function pr( $thing ) {
505 echo '<pre>';
506 print_r( $thing );
507 echo '</pre>';
508 }
509 }
510
511 if ( !function_exists( '_n' ) ) {
512 function _n($single, $plural, $number, $domain = 'default') {
513 return __ngettext($single, $plural, $number, $domain = 'default');
514 }
515 }
516