Version Description
- Added: Generate icon file from uploaded images
- Added: Settings link from plugins page
- Optimized: File path resolution
Download this release
Release Info
Developer | Archetyped |
Plugin | Favicon Rotator |
Version | 1.1 |
Comparing to | |
See all releases |
Code changes from version 1.0 to 1.1
- css/media.css +1 -0
- includes/class.base.php +19 -0
- includes/class.media.php +72 -10
- includes/class.utilities.php +280 -23
- js/admin.js +19 -1
- js/media.js +1 -1
- main.php +2 -2
- model.php +37 -13
- readme.txt +15 -3
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
css/media.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.ml-submit { display: none !important; }
|
includes/class.base.php
CHANGED
@@ -9,6 +9,18 @@ require_once 'class.utilities.php';
|
|
9 |
*/
|
10 |
class FVRT_Base {
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Prefix for Cornerstone-related data (attributes, DB tables, etc.)
|
14 |
* @var string
|
@@ -21,6 +33,12 @@ class FVRT_Base {
|
|
21 |
*/
|
22 |
var $util;
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* Legacy constructor
|
26 |
*/
|
@@ -33,6 +51,7 @@ class FVRT_Base {
|
|
33 |
*/
|
34 |
function __construct() {
|
35 |
$this->util =& new FVRT_Utilities();
|
|
|
36 |
}
|
37 |
|
38 |
/**
|
9 |
*/
|
10 |
class FVRT_Base {
|
11 |
|
12 |
+
/**
|
13 |
+
* Size to use for icon attachment
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
var $icon_size = 'favicon';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Favicon Dimensions
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
+
var $icon_dimensions = array('w' => '16', 'h' => '16');
|
23 |
+
|
24 |
/**
|
25 |
* Prefix for Cornerstone-related data (attributes, DB tables, etc.)
|
26 |
* @var string
|
33 |
*/
|
34 |
var $util;
|
35 |
|
36 |
+
/**
|
37 |
+
* Debug instance
|
38 |
+
* @var FVRT_Debug
|
39 |
+
*/
|
40 |
+
var $debug;
|
41 |
+
|
42 |
/**
|
43 |
* Legacy constructor
|
44 |
*/
|
51 |
*/
|
52 |
function __construct() {
|
53 |
$this->util =& new FVRT_Utilities();
|
54 |
+
$this->debug =& new FVRT_Debug();
|
55 |
}
|
56 |
|
57 |
/**
|
includes/class.media.php
CHANGED
@@ -65,11 +65,18 @@ class FVRT_Media extends FVRT_Base {
|
|
65 |
/* Methods */
|
66 |
|
67 |
function register_hooks() {
|
|
|
|
|
|
|
68 |
//Register handler for custom media requests
|
69 |
add_action('media_upload_' . $this->add_prefix('icon'), $this->m('upload_icon'));
|
70 |
-
|
|
|
71 |
add_filter('attachment_fields_to_edit', $this->m('attachment_fields_to_edit'), 11, 2);
|
72 |
|
|
|
|
|
|
|
73 |
//Modify tabs in upload popup for fields
|
74 |
add_filter('media_upload_tabs', $this->m('field_upload_tabs'));
|
75 |
|
@@ -77,6 +84,23 @@ class FVRT_Media extends FVRT_Base {
|
|
77 |
add_filter('upload_file_glob', $this->m('upload_file_types'));
|
78 |
}
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
/**
|
81 |
* Initialize value of instance variables
|
82 |
*/
|
@@ -117,6 +141,34 @@ class FVRT_Media extends FVRT_Base {
|
|
117 |
return $url;
|
118 |
}
|
119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
/**
|
121 |
* Handles upload/selecting of an icon
|
122 |
*/
|
@@ -131,11 +183,15 @@ class FVRT_Media extends FVRT_Base {
|
|
131 |
$field_var = $this->add_prefix('field');
|
132 |
$args = new stdClass();
|
133 |
$args->id = array_shift( array_keys($_POST[$this->var_setmedia]) );
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
$
|
138 |
-
|
|
|
|
|
|
|
|
|
139 |
}
|
140 |
//Build JS Arguments string
|
141 |
$arg_string = array();
|
@@ -175,6 +231,14 @@ class FVRT_Media extends FVRT_Base {
|
|
175 |
return wp_iframe( $upload_form, $type, $errors, $id );
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
/**
|
179 |
* Modifies array of form fields to display on Attachment edit form
|
180 |
* Array items are in the form:
|
@@ -236,18 +300,16 @@ class FVRT_Media extends FVRT_Base {
|
|
236 |
function is_custom_media() {
|
237 |
$ret = false;
|
238 |
$action = $this->var_action;
|
239 |
-
$
|
240 |
-
if (isset($_REQUEST[$action]))
|
241 |
$ret = true;
|
242 |
else {
|
243 |
$qs = array();
|
244 |
-
$ref = parse_url(
|
245 |
if ( isset($ref['query']) )
|
246 |
parse_str($ref['query'], $qs);
|
247 |
if (array_key_exists($action, $qs))
|
248 |
$ret = true;
|
249 |
}
|
250 |
-
|
251 |
return $ret;
|
252 |
}
|
253 |
|
65 |
/* Methods */
|
66 |
|
67 |
function register_hooks() {
|
68 |
+
//Modify layout on media upload page
|
69 |
+
add_action('admin_print_styles-media-upload-popup', $this->m('upload_styles'));
|
70 |
+
|
71 |
//Register handler for custom media requests
|
72 |
add_action('media_upload_' . $this->add_prefix('icon'), $this->m('upload_icon'));
|
73 |
+
|
74 |
+
//Display custom UI in media item box
|
75 |
add_filter('attachment_fields_to_edit', $this->m('attachment_fields_to_edit'), 11, 2);
|
76 |
|
77 |
+
//Resize icons
|
78 |
+
add_filter('intermediate_image_sizes', $this->m('add_intermediate_image_size'));
|
79 |
+
|
80 |
//Modify tabs in upload popup for fields
|
81 |
add_filter('media_upload_tabs', $this->m('field_upload_tabs'));
|
82 |
|
84 |
add_filter('upload_file_glob', $this->m('upload_file_types'));
|
85 |
}
|
86 |
|
87 |
+
/**
|
88 |
+
* Adds icon size to intermediate images
|
89 |
+
* Only added when image is uploaded by plugin
|
90 |
+
* @param array $sizes Names of intermediate sizes
|
91 |
+
* @return array Updated sizes
|
92 |
+
*/
|
93 |
+
function add_intermediate_image_size($sizes) {
|
94 |
+
$img = array('width' => 0, 'height' => 0, 'crop' => true);
|
95 |
+
if ( $this->is_custom_media() ) {
|
96 |
+
$img['width'] = $this->icon_dimensions['w'];
|
97 |
+
$img['height'] = $this->icon_dimensions['h'];
|
98 |
+
}
|
99 |
+
add_image_size($this->icon_size, $img['width'], $img['height'], $img['crop']);
|
100 |
+
$sizes[] = $this->icon_size;
|
101 |
+
return $sizes;
|
102 |
+
}
|
103 |
+
|
104 |
/**
|
105 |
* Initialize value of instance variables
|
106 |
*/
|
141 |
return $url;
|
142 |
}
|
143 |
|
144 |
+
/**
|
145 |
+
* Retrieve source data for icon media
|
146 |
+
* @param int $icon_id Attachment ID
|
147 |
+
* @return array Image data (src, width, height)
|
148 |
+
*/
|
149 |
+
function get_icon_src($icon_id) {
|
150 |
+
$this->update_attachment_metadata($icon_id);
|
151 |
+
$icon = ( wp_attachment_is_image($icon_id) ) ? wp_get_attachment_image_src($icon_id, $this->icon_size) : wp_get_attachment_url($icon_id);
|
152 |
+
if ( is_string($icon) )
|
153 |
+
$icon = array($icon, 0, 0);
|
154 |
+
return $icon;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Updates image thumbnail if necessary
|
159 |
+
* @param int $id Attachment ID
|
160 |
+
*/
|
161 |
+
function update_attachment_metadata($id) {
|
162 |
+
//Generate favicon image file (if necessary)
|
163 |
+
if ( ( $meta = wp_get_attachment_metadata($id) ) && !isset($meta['sizes'][$this->icon_size]) && wp_attachment_is_image($id) ) {
|
164 |
+
//Full metadata update
|
165 |
+
if ( function_exists('wp_generate_attachment_metadata') ) {
|
166 |
+
$data = wp_generate_attachment_metadata($id, get_attached_file($id));
|
167 |
+
wp_update_attachment_metadata( $id, $data );
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
/**
|
173 |
* Handles upload/selecting of an icon
|
174 |
*/
|
183 |
$field_var = $this->add_prefix('field');
|
184 |
$args = new stdClass();
|
185 |
$args->id = array_shift( array_keys($_POST[$this->var_setmedia]) );
|
186 |
+
//Make sure post is valid
|
187 |
+
if ( wp_attachment_is_image($args->id) ) {
|
188 |
+
//Build object of properties to send to parent page
|
189 |
+
$icon = $this->get_icon_src($args->id);
|
190 |
+
if ( !empty($icon) ) {
|
191 |
+
$args->url = $icon[0];
|
192 |
+
$meta = wp_get_attachment_metadata($args->id);
|
193 |
+
$args->name = basename( ( isset($meta['file']) && !empty($meta['file']) ) ? $meta['file'] : wp_get_attachment_url($args->id) );
|
194 |
+
}
|
195 |
}
|
196 |
//Build JS Arguments string
|
197 |
$arg_string = array();
|
231 |
return wp_iframe( $upload_form, $type, $errors, $id );
|
232 |
}
|
233 |
|
234 |
+
/**
|
235 |
+
* Loads CSS Styles for media upload pages
|
236 |
+
*/
|
237 |
+
function upload_styles() {
|
238 |
+
if ( $this->is_custom_media() )
|
239 |
+
wp_enqueue_style($this->add_prefix('media'), $this->util->get_file_url('css/media.css'));
|
240 |
+
}
|
241 |
+
|
242 |
/**
|
243 |
* Modifies array of form fields to display on Attachment edit form
|
244 |
* Array items are in the form:
|
300 |
function is_custom_media() {
|
301 |
$ret = false;
|
302 |
$action = $this->var_action;
|
303 |
+
if ( isset($_REQUEST[$action]) || ( isset($_REQUEST['type']) && $_REQUEST['type'] == $this->var_type ) )
|
|
|
304 |
$ret = true;
|
305 |
else {
|
306 |
$qs = array();
|
307 |
+
$ref = parse_url(wp_get_referer());
|
308 |
if ( isset($ref['query']) )
|
309 |
parse_str($ref['query'], $qs);
|
310 |
if (array_key_exists($action, $qs))
|
311 |
$ret = true;
|
312 |
}
|
|
|
313 |
return $ret;
|
314 |
}
|
315 |
|
includes/class.utilities.php
CHANGED
@@ -3,7 +3,8 @@
|
|
3 |
/**
|
4 |
* Utility methods
|
5 |
*
|
6 |
-
* @package
|
|
|
7 |
* @author Archetyped
|
8 |
*
|
9 |
*/
|
@@ -103,14 +104,32 @@ class FVRT_Utilities {
|
|
103 |
} else {
|
104 |
$trailing_slash = false;
|
105 |
}
|
|
|
106 |
//Trim trailing slashes from path parts
|
107 |
foreach ( $parts as $key => $part ) {
|
108 |
$part = trim($part);
|
|
|
109 |
$parts[$key] = trim($part, $sl_f . $sl_b);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
}
|
111 |
}
|
|
|
112 |
$parts = implode($sl_b, $parts);
|
113 |
$parts = str_replace($sl_b, $sl_f, $parts);
|
|
|
114 |
if ( $trailing_slash )
|
115 |
$parts . $sl_f;
|
116 |
return $parts;
|
@@ -123,12 +142,34 @@ class FVRT_Utilities {
|
|
123 |
*/
|
124 |
function get_file_url($file) {
|
125 |
if (is_string($file) && '' != trim($file)) {
|
126 |
-
$file =
|
127 |
-
$file = sprintf('%s/%s', $this->get_url_base(), $file);
|
128 |
}
|
129 |
return $file;
|
130 |
}
|
131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
/**
|
133 |
* Retrieve base URL for plugin-specific files
|
134 |
* @return string Base URL
|
@@ -256,9 +297,10 @@ class FVRT_Utilities {
|
|
256 |
* - If the current item's value OR the corresponding item in the base array is NOT an array, current item overwrites base item
|
257 |
* @todo Append numerical elements (as opposed to overwriting element at same index in base array)
|
258 |
* @param array Variable number of arrays
|
|
|
259 |
* @return array Merged array
|
260 |
*/
|
261 |
-
function array_merge_recursive_distinct() {
|
262 |
//Get all arrays passed to function
|
263 |
$args = func_get_args();
|
264 |
if (empty($args))
|
@@ -418,12 +460,68 @@ class FVRT_Utilities {
|
|
418 |
return $ret;
|
419 |
}
|
420 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
/*-** Admin **-*/
|
422 |
|
423 |
/**
|
424 |
* Add submenu page in the admin menu
|
425 |
* Adds ability to set the position of the page in the menu
|
426 |
-
* @see
|
427 |
*
|
428 |
* @param $parent
|
429 |
* @param $page_title
|
@@ -435,30 +533,29 @@ class FVRT_Utilities {
|
|
435 |
*
|
436 |
* @global array $submenu Admin page submenus
|
437 |
*/
|
438 |
-
function add_submenu_page($parent, $page_title, $menu_title, $
|
439 |
-
global $submenu;
|
440 |
-
|
441 |
//Add submenu page as usual
|
442 |
$args = func_get_args();
|
443 |
$hookname = call_user_func_array('add_submenu_page', $args);
|
444 |
-
|
445 |
if ( is_int($pos) ) {
|
|
|
446 |
//Get last submenu added
|
447 |
$parent = $this->get_submenu_parent_file($parent);
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
|
|
462 |
}
|
463 |
}
|
464 |
}
|
@@ -541,4 +638,164 @@ class FVRT_Utilities {
|
|
541 |
$parent = $_wp_real_parent_file[$parent];
|
542 |
return $parent;
|
543 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
544 |
}
|
3 |
/**
|
4 |
* Utility methods
|
5 |
*
|
6 |
+
* @package Favicon Rotator
|
7 |
+
* @subpackage Utilities
|
8 |
* @author Archetyped
|
9 |
*
|
10 |
*/
|
104 |
} else {
|
105 |
$trailing_slash = false;
|
106 |
}
|
107 |
+
$first = true;
|
108 |
//Trim trailing slashes from path parts
|
109 |
foreach ( $parts as $key => $part ) {
|
110 |
$part = trim($part);
|
111 |
+
//Special Trim
|
112 |
$parts[$key] = trim($part, $sl_f . $sl_b);
|
113 |
+
//Verify path still contains value
|
114 |
+
if ( empty($parts[$key]) ) {
|
115 |
+
unset($parts[$key]);
|
116 |
+
continue;
|
117 |
+
}
|
118 |
+
//Only continue processing the first valid path segment
|
119 |
+
if ( $first )
|
120 |
+
$first = !$first;
|
121 |
+
else
|
122 |
+
continue;
|
123 |
+
//Add back leading slash if necessary
|
124 |
+
if ( $part[0] == $sl_f || $part[0] == $sl_b )
|
125 |
+
$parts[$key] = $sl_f . $parts[$key];
|
126 |
+
|
127 |
}
|
128 |
}
|
129 |
+
//Join path parts together
|
130 |
$parts = implode($sl_b, $parts);
|
131 |
$parts = str_replace($sl_b, $sl_f, $parts);
|
132 |
+
//Add trailing slash (if necessary)
|
133 |
if ( $trailing_slash )
|
134 |
$parts . $sl_f;
|
135 |
return $parts;
|
142 |
*/
|
143 |
function get_file_url($file) {
|
144 |
if (is_string($file) && '' != trim($file)) {
|
145 |
+
$file = $this->normalize_path($this->get_url_base(), $file);
|
|
|
146 |
}
|
147 |
return $file;
|
148 |
}
|
149 |
|
150 |
+
/**
|
151 |
+
* Retrieves file extension
|
152 |
+
* @param string $file file name/path
|
153 |
+
* @return string File's extension
|
154 |
+
*/
|
155 |
+
function get_file_extension($file) {
|
156 |
+
$ret = '';
|
157 |
+
$sep = '.';
|
158 |
+
if ( is_string($icon) && ( $rpos = strrpos($file, $sep) ) !== false )
|
159 |
+
$ret = substr($file, $rpos + 1);
|
160 |
+
return $ret;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Checks if file has specified extension
|
165 |
+
* @param string $file File name/path
|
166 |
+
* @param string $extension File ending to check $file for
|
167 |
+
* @return bool TRUE if file has extension
|
168 |
+
*/
|
169 |
+
function has_file_extension($file, $extension) {
|
170 |
+
return ( $this->get_file_extension($file) == $extension ) ? true : false;
|
171 |
+
}
|
172 |
+
|
173 |
/**
|
174 |
* Retrieve base URL for plugin-specific files
|
175 |
* @return string Base URL
|
297 |
* - If the current item's value OR the corresponding item in the base array is NOT an array, current item overwrites base item
|
298 |
* @todo Append numerical elements (as opposed to overwriting element at same index in base array)
|
299 |
* @param array Variable number of arrays
|
300 |
+
* @param array $arr1 Default array
|
301 |
* @return array Merged array
|
302 |
*/
|
303 |
+
function array_merge_recursive_distinct($arr1) {
|
304 |
//Get all arrays passed to function
|
305 |
$args = func_get_args();
|
306 |
if (empty($args))
|
460 |
return $ret;
|
461 |
}
|
462 |
|
463 |
+
/**
|
464 |
+
* Generate external stylesheet element
|
465 |
+
* @param $url Stylesheet URL
|
466 |
+
* @return string Stylesheet element
|
467 |
+
*/
|
468 |
+
function build_stylesheet_element($url = '') {
|
469 |
+
$attributes = array('href' => $url, 'type' => 'text/css', 'rel' => 'stylesheet');
|
470 |
+
return $this->build_html_element(array('tag' => 'link', 'wrap' => false, 'attributes' => $attributes));
|
471 |
+
}
|
472 |
+
|
473 |
+
/**
|
474 |
+
* Generate external script element
|
475 |
+
* @param $url Script URL
|
476 |
+
* @return string Script element
|
477 |
+
*/
|
478 |
+
function build_ext_script_element($url = '') {
|
479 |
+
$attributes = array('src' => $url, 'type' => 'text/javascript');
|
480 |
+
return $this->build_html_element(array('tag' => 'script', 'attributes' => $attributes));
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Generate HTML element based on values
|
485 |
+
* @param $args Element arguments
|
486 |
+
* @return string Generated HTML element
|
487 |
+
*/
|
488 |
+
function build_html_element($args) {
|
489 |
+
$defaults = array(
|
490 |
+
'tag' => 'span',
|
491 |
+
'wrap' => true,
|
492 |
+
'content' => '',
|
493 |
+
'attributes' => array()
|
494 |
+
);
|
495 |
+
$el_start = '<';
|
496 |
+
$el_end = '>';
|
497 |
+
$el_close = '/';
|
498 |
+
extract(wp_parse_args($args, $defaults), EXTR_SKIP);
|
499 |
+
$content = trim($content);
|
500 |
+
|
501 |
+
if ( !$wrap && strlen($content) > 0 )
|
502 |
+
$wrap = true;
|
503 |
+
|
504 |
+
$attributes = $this->build_attribute_string($attributes);
|
505 |
+
if ( strlen($attributes) > 0 )
|
506 |
+
$attributes = ' ' . $attributes;
|
507 |
+
|
508 |
+
$ret = $el_start . $tag . $attributes;
|
509 |
+
|
510 |
+
if ( $wrap )
|
511 |
+
$ret .= $el_end . $content . $el_start . $el_close . $tag;
|
512 |
+
else
|
513 |
+
$ret .= ' ' . $el_close;
|
514 |
+
|
515 |
+
$ret .= $el_end;
|
516 |
+
return $ret;
|
517 |
+
}
|
518 |
+
|
519 |
/*-** Admin **-*/
|
520 |
|
521 |
/**
|
522 |
* Add submenu page in the admin menu
|
523 |
* Adds ability to set the position of the page in the menu
|
524 |
+
* @see add_submenu_page (Wraps functionality)
|
525 |
*
|
526 |
* @param $parent
|
527 |
* @param $page_title
|
533 |
*
|
534 |
* @global array $submenu Admin page submenus
|
535 |
*/
|
536 |
+
function add_submenu_page($parent, $page_title, $menu_title, $capability, $file, $function = '', $pos = false) {
|
|
|
|
|
537 |
//Add submenu page as usual
|
538 |
$args = func_get_args();
|
539 |
$hookname = call_user_func_array('add_submenu_page', $args);
|
|
|
540 |
if ( is_int($pos) ) {
|
541 |
+
global $submenu;
|
542 |
//Get last submenu added
|
543 |
$parent = $this->get_submenu_parent_file($parent);
|
544 |
+
if ( isset($submenu[$parent]) ) {
|
545 |
+
$subs =& $submenu[$parent];
|
546 |
+
//Make sure menu isn't already in the desired position
|
547 |
+
if ( $pos <= ( count($subs) - 1 ) ) {
|
548 |
+
//Get submenu that was just added
|
549 |
+
$sub = array_pop($subs);
|
550 |
+
//Insert into desired position
|
551 |
+
if ( 0 == $pos ) {
|
552 |
+
array_unshift($subs, $sub);
|
553 |
+
} else {
|
554 |
+
$top = array_slice($subs, 0, $pos);
|
555 |
+
$bottom = array_slice($subs, $pos);
|
556 |
+
array_push($top, $sub);
|
557 |
+
$subs = array_merge($top, $bottom);
|
558 |
+
}
|
559 |
}
|
560 |
}
|
561 |
}
|
638 |
$parent = $_wp_real_parent_file[$parent];
|
639 |
return $parent;
|
640 |
}
|
641 |
+
}
|
642 |
+
|
643 |
+
class FVRT_Debug {
|
644 |
+
/**
|
645 |
+
* @var array Associative array of debug messages
|
646 |
+
*/
|
647 |
+
var $msgs = array();
|
648 |
+
|
649 |
+
/**
|
650 |
+
* @var array Holds various timer objects
|
651 |
+
*/
|
652 |
+
var $timers = array();
|
653 |
+
|
654 |
+
/* Constructor */
|
655 |
+
|
656 |
+
function CNR_Debug() {
|
657 |
+
$this->__construct();
|
658 |
+
}
|
659 |
+
|
660 |
+
function __construct() {
|
661 |
+
|
662 |
+
}
|
663 |
+
|
664 |
+
/**
|
665 |
+
* Adds debug data to object
|
666 |
+
* @return void
|
667 |
+
* @param String $title Title of debug message
|
668 |
+
* @param mixed $message value to store in message for debugging purposes
|
669 |
+
*/
|
670 |
+
function add_message($title, $message) {
|
671 |
+
$this->msgs[$title] = $message;
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* Returns debug message array
|
676 |
+
* @return array Debug message array
|
677 |
+
*/
|
678 |
+
function get_messages() {
|
679 |
+
return $this->msgs;
|
680 |
+
}
|
681 |
+
|
682 |
+
function show_messages() {
|
683 |
+
echo '<pre>';
|
684 |
+
var_dump($this->get_messages());
|
685 |
+
echo '</pre>';
|
686 |
+
}
|
687 |
+
|
688 |
+
function print_message($msg) {
|
689 |
+
foreach (func_get_args() as $msg) {
|
690 |
+
echo '<pre>';
|
691 |
+
if (is_scalar($msg) && !is_bool($msg)) {
|
692 |
+
echo htmlspecialchars($msg) . "<br />";
|
693 |
+
} else {
|
694 |
+
var_dump($msg);
|
695 |
+
}
|
696 |
+
echo '</pre>';
|
697 |
+
}
|
698 |
+
}
|
699 |
+
|
700 |
+
function microtime_float() {
|
701 |
+
list($usec, $sec) = explode(' ', microtime());
|
702 |
+
return (float)$usec + (float)$sec;
|
703 |
+
}
|
704 |
+
|
705 |
+
function timer_start($name = 'default', $time = null) {
|
706 |
+
if (empty($time)) $time = $this->microtime_float();
|
707 |
+
$this->timers[$name] = new stdClass();
|
708 |
+
$this->timers[$name]->start = $time;
|
709 |
+
$this->timers[$name]->end = $time;
|
710 |
+
}
|
711 |
+
|
712 |
+
function timer_stop($name = 'default') {
|
713 |
+
$time = $this->microtime_float();
|
714 |
+
if (!isset($this->timers[$name])
|
715 |
+
|| !is_object($this->timers[$name])
|
716 |
+
) {
|
717 |
+
$this->timer_start($name, $time);
|
718 |
+
} else {
|
719 |
+
$this->timers[$name]->end = $time;
|
720 |
+
}
|
721 |
+
}
|
722 |
+
|
723 |
+
function timer_show($name = 'default', $format = 'Elapsed time: %s') {
|
724 |
+
if (!isset($this->timers[$name])
|
725 |
+
|| !is_object($this->timers[$name])
|
726 |
+
|| $this->timers[$name]->end < $this->timers[$name]->start
|
727 |
+
) {
|
728 |
+
$this->timer_start($name);
|
729 |
+
}
|
730 |
+
//Get difference in times
|
731 |
+
$res = (float)$this->timers[$name]->end - (float)$this->timers[$name]->start;
|
732 |
+
$this->print_message(sprintf($format, $res));
|
733 |
+
}
|
734 |
+
|
735 |
+
/**
|
736 |
+
* Retrieve current function name
|
737 |
+
* @param string|array $properties (optional) Properties to retrieve for current function
|
738 |
+
* @return string|array Current function properties. Default: function name. Will return array if multiple properties are requested
|
739 |
+
* @see CNR_Debug::backtrace
|
740 |
+
*/
|
741 |
+
function get_current($properties = 'function') {
|
742 |
+
return $this->backtrace($properties, 1, 2);
|
743 |
+
}
|
744 |
+
|
745 |
+
/**
|
746 |
+
* Retrieves calling function name
|
747 |
+
* @param string|array $properties (optional) Properties to retrieve for caller
|
748 |
+
* @return string|array Calling function properties. Default: function name. Will return array if multiple properties are requested
|
749 |
+
* @see CNR_Debug::backtrace
|
750 |
+
*/
|
751 |
+
function get_caller($properties = 'function') {
|
752 |
+
return $this->backtrace($properties, 1, 3);
|
753 |
+
}
|
754 |
+
|
755 |
+
/**
|
756 |
+
* Return customized backtrace
|
757 |
+
* @param string|array $properties (optional) Properties to retrieve for each level (Default: all properties) Can be comma-delimited string or array
|
758 |
+
* @param int $levels (optional) Number of levels to retrieve (Default: entire backtrace)
|
759 |
+
* @param int $offset (optional) Where to start backtrace output (e.g. Remove current/wrapper functions from output, etc.)
|
760 |
+
* @return array|string Backtrace output as Array. Will output string if only one level with one property is in output
|
761 |
+
*/
|
762 |
+
function backtrace($properties = null, $levels = null, $offset = 1) {
|
763 |
+
$out = array();
|
764 |
+
$debug = debug_backtrace();
|
765 |
+
//Remove current & calling functions from trace
|
766 |
+
$offset = ( intval($offset) ) ? intval($offset) : 1;
|
767 |
+
$debug = array_slice($debug, $offset);
|
768 |
+
if ( ($debug_levels = count($debug)) ) {
|
769 |
+
//Setup levels
|
770 |
+
$levels = intval($levels);
|
771 |
+
if ( empty($levels) || $levels > $debug_levels ) {
|
772 |
+
$levels = $debug_levels;
|
773 |
+
}
|
774 |
+
|
775 |
+
//Setup properties
|
776 |
+
if ( is_string($properties) )
|
777 |
+
$properties = explode(',', $properties);
|
778 |
+
if ( is_array($properties) )
|
779 |
+
$properties = array_map('trim', $properties);
|
780 |
+
|
781 |
+
//Build output
|
782 |
+
for ( $x = 0; $x < $levels; $x++ ) {
|
783 |
+
$level_out = array();
|
784 |
+
if ( !is_array($properties) ) {
|
785 |
+
$level_out = $debug[$x];
|
786 |
+
} else {
|
787 |
+
foreach ( $properties as $prop ) {
|
788 |
+
if ( isset($debug[$x][$prop]) )
|
789 |
+
$level_out[$prop] = $debug[$x][$prop];
|
790 |
+
}
|
791 |
+
}
|
792 |
+
if ( !empty($level_out) )
|
793 |
+
$out[] = $level_out;
|
794 |
+
}
|
795 |
+
}
|
796 |
+
//Extract value if single level is in output
|
797 |
+
if ( count($out) == 1 && count($out[0]) == 1 && $out = array_values($out[0]) )
|
798 |
+
$out = $out[0];
|
799 |
+
return $out;
|
800 |
+
}
|
801 |
}
|
js/admin.js
CHANGED
@@ -26,6 +26,7 @@ if ( typeof(fvrt) == 'undefined' || typeof(fvrt) != 'object' )
|
|
26 |
};
|
27 |
|
28 |
fvrt['sel'] = {
|
|
|
29 |
list: '#fv_list',
|
30 |
item: '.fv_item',
|
31 |
image: '.icon',
|
@@ -71,7 +72,12 @@ if ( typeof(fvrt) == 'undefined' || typeof(fvrt) != 'object' )
|
|
71 |
* @return array Icon IDs
|
72 |
*/
|
73 |
fvrt['getIds'] = function() {
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
75 |
};
|
76 |
|
77 |
/**
|
@@ -148,6 +154,8 @@ if ( typeof(fvrt) == 'undefined' || typeof(fvrt) != 'object' )
|
|
148 |
|
149 |
//Add element ID to list
|
150 |
this.addId(args.id);
|
|
|
|
|
151 |
}
|
152 |
};
|
153 |
|
@@ -162,6 +170,16 @@ if ( typeof(fvrt) == 'undefined' || typeof(fvrt) != 'object' )
|
|
162 |
$(el).parents('.fv_item').remove();
|
163 |
//Remove ID from field
|
164 |
this.removeId(id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
};
|
166 |
|
167 |
//Initialize on document load
|
26 |
};
|
27 |
|
28 |
fvrt['sel'] = {
|
29 |
+
no_icons: '#fv_no_icons',
|
30 |
list: '#fv_list',
|
31 |
item: '.fv_item',
|
32 |
image: '.icon',
|
72 |
* @return array Icon IDs
|
73 |
*/
|
74 |
fvrt['getIds'] = function() {
|
75 |
+
var ids = [];
|
76 |
+
var idVal = $(this.getField()).val();
|
77 |
+
if ( idVal.toString().length > 0 ) {
|
78 |
+
ids = idVal.split(',');
|
79 |
+
}
|
80 |
+
return ids;
|
81 |
};
|
82 |
|
83 |
/**
|
154 |
|
155 |
//Add element ID to list
|
156 |
this.addId(args.id);
|
157 |
+
|
158 |
+
this.setMessageVisibility();
|
159 |
}
|
160 |
};
|
161 |
|
170 |
$(el).parents('.fv_item').remove();
|
171 |
//Remove ID from field
|
172 |
this.removeId(id);
|
173 |
+
|
174 |
+
this.setMessageVisibility();
|
175 |
+
};
|
176 |
+
|
177 |
+
fvrt['setMessageVisibility'] = function() {
|
178 |
+
if (this.getIds().length)
|
179 |
+
$(this.sel.no_icons).hide();
|
180 |
+
else {
|
181 |
+
$(this.sel.no_icons).show();
|
182 |
+
}
|
183 |
};
|
184 |
|
185 |
//Initialize on document load
|
js/media.js
CHANGED
@@ -17,7 +17,7 @@ if ( typeof(fvrt) == 'undefined' || typeof(fvrt) != 'object' )
|
|
17 |
* url: Attachment URL
|
18 |
*/
|
19 |
setIcon : function (a) {
|
20 |
-
if ( typeof(a) == 'object' ) {
|
21 |
fvrt.addItem(a);
|
22 |
}
|
23 |
//Close popup
|
17 |
* url: Attachment URL
|
18 |
*/
|
19 |
setIcon : function (a) {
|
20 |
+
if ( typeof(a) == 'object' && fvrt.addItem ) {
|
21 |
fvrt.addItem(a);
|
22 |
}
|
23 |
//Close popup
|
main.php
CHANGED
@@ -3,10 +3,10 @@
|
|
3 |
Plugin Name: Favicon Rotator
|
4 |
Plugin URI: http://archetyped.com/tools/favicon-rotator/
|
5 |
Description: Easily set site favicon and even rotate through multiple icons
|
6 |
-
Version: 1.
|
7 |
Author: Archetyped
|
8 |
Author URI: http://archetyped.com
|
9 |
*/
|
10 |
|
11 |
require_once 'model.php';
|
12 |
-
$fvrt = new FaviconRotator();
|
3 |
Plugin Name: Favicon Rotator
|
4 |
Plugin URI: http://archetyped.com/tools/favicon-rotator/
|
5 |
Description: Easily set site favicon and even rotate through multiple icons
|
6 |
+
Version: 1.1.2
|
7 |
Author: Archetyped
|
8 |
Author URI: http://archetyped.com
|
9 |
*/
|
10 |
|
11 |
require_once 'model.php';
|
12 |
+
$fvrt = new FaviconRotator();
|
model.php
CHANGED
@@ -4,9 +4,8 @@ require_once 'includes/class.base.php';
|
|
4 |
require_once 'includes/class.media.php';
|
5 |
|
6 |
/**
|
7 |
-
*
|
8 |
* @author Archetyped
|
9 |
-
*
|
10 |
*/
|
11 |
class FaviconRotator extends FVRT_Base {
|
12 |
|
@@ -75,7 +74,7 @@ class FaviconRotator extends FVRT_Base {
|
|
75 |
add_action('admin_menu', $this->m('admin_menu'));
|
76 |
//Plugins page
|
77 |
add_filter('plugin_action_links_' . $this->util->get_plugin_base_name(), $this->m('admin_plugin_action_links'), 10, 4);
|
78 |
-
|
79 |
/*-** Main **-*/
|
80 |
|
81 |
//Template
|
@@ -144,11 +143,22 @@ class FaviconRotator extends FVRT_Base {
|
|
144 |
if ( !empty($ids) ) {
|
145 |
$icons = get_posts(array('post_type' => 'attachment', 'include' => $ids));
|
146 |
}
|
147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
149 |
|
150 |
/**
|
151 |
* Save list of selected icons to DB
|
|
|
152 |
*/
|
153 |
function save_icons($ids = null) {
|
154 |
//Check if valid icon IDs are passed to function
|
@@ -159,12 +169,23 @@ class FaviconRotator extends FVRT_Base {
|
|
159 |
}
|
160 |
|
161 |
//Get icon IDs from form submission
|
162 |
-
if ( is_null($ids) && isset($_POST['fv_ids']) && check_admin_referer($this->action_save) )
|
163 |
$ids = explode(',', $_POST['fv_ids']);
|
164 |
-
|
165 |
//Save to DB
|
166 |
-
if ( is_array($ids) )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
$this->set_option($this->opt_icons, $ids);
|
|
|
168 |
}
|
169 |
|
170 |
/**
|
@@ -179,14 +200,17 @@ class FaviconRotator extends FVRT_Base {
|
|
179 |
//Select one from random
|
180 |
$idx = ( count($icons) > 1 ) ? array_rand($icons) : 0;
|
181 |
$icon_id = $icons[$idx];
|
182 |
-
$icon =
|
183 |
-
if ( !$icon || (
|
184 |
//Reset variable to NULL
|
185 |
$icon = null;
|
186 |
//Remove icon from list (no longer valid)
|
187 |
unset($icons[$idx]);
|
188 |
array_values($icons);
|
189 |
}
|
|
|
|
|
|
|
190 |
}
|
191 |
|
192 |
//Display icon
|
@@ -257,17 +281,17 @@ class FaviconRotator extends FVRT_Base {
|
|
257 |
<?php screen_icon(); ?>
|
258 |
<h2><?php _e('Favicon Rotator'); ?> <a href="<?php echo $this->media->get_upload_iframe_src('image'); ?>" class="button add-new-h2 thickbox" title="<?php esc_attr_e('Add Icon'); ?>"><?php echo esc_html_x('Add new', 'file')?></a></h2>
|
259 |
<div id="fv_list_container">
|
260 |
-
<?php if (
|
261 |
-
<p>No favicons set</p>
|
262 |
-
<?php endif; //No icons message ?>
|
263 |
<ul id="fv_list">
|
264 |
<?php foreach ( $icons as $icon ) : //List icons
|
|
|
|
|
265 |
$src = wp_get_attachment_image_src($icon->ID, 'full');
|
266 |
$src = $src[0];
|
267 |
?>
|
268 |
<li class="fv_item">
|
269 |
<div>
|
270 |
-
<img class="icon" src="<?php echo $
|
271 |
<div class="details">
|
272 |
<div class="name"><?php echo basename($src); ?></div>
|
273 |
<div class="options">
|
4 |
require_once 'includes/class.media.php';
|
5 |
|
6 |
/**
|
7 |
+
* @package Favicon Rotator
|
8 |
* @author Archetyped
|
|
|
9 |
*/
|
10 |
class FaviconRotator extends FVRT_Base {
|
11 |
|
74 |
add_action('admin_menu', $this->m('admin_menu'));
|
75 |
//Plugins page
|
76 |
add_filter('plugin_action_links_' . $this->util->get_plugin_base_name(), $this->m('admin_plugin_action_links'), 10, 4);
|
77 |
+
|
78 |
/*-** Main **-*/
|
79 |
|
80 |
//Template
|
143 |
if ( !empty($ids) ) {
|
144 |
$icons = get_posts(array('post_type' => 'attachment', 'include' => $ids));
|
145 |
}
|
146 |
+
|
147 |
+
//Fix icon option if invalid icons were passed
|
148 |
+
if ( count($icons) != count($ids) ) {
|
149 |
+
$ids = array();
|
150 |
+
foreach ( $icons as $icon ) {
|
151 |
+
$ids[] = $icon->ID;
|
152 |
+
}
|
153 |
+
//Save to DB
|
154 |
+
$this->save_icons($ids);
|
155 |
+
}
|
156 |
+
return $icons;
|
157 |
}
|
158 |
|
159 |
/**
|
160 |
* Save list of selected icons to DB
|
161 |
+
* @param array $ids (optional) Array of icon IDs
|
162 |
*/
|
163 |
function save_icons($ids = null) {
|
164 |
//Check if valid icon IDs are passed to function
|
169 |
}
|
170 |
|
171 |
//Get icon IDs from form submission
|
172 |
+
if ( is_null($ids) && isset($_POST['fv_ids']) && check_admin_referer($this->action_save) ) {
|
173 |
$ids = explode(',', $_POST['fv_ids']);
|
174 |
+
}
|
175 |
//Save to DB
|
176 |
+
if ( is_array($ids) ) {
|
177 |
+
//Validate values
|
178 |
+
$changed = false;
|
179 |
+
foreach ( $ids as $key => $id ) {
|
180 |
+
if ( !intval($id) ) {
|
181 |
+
unset($ids[$key]);
|
182 |
+
$changed = true;
|
183 |
+
}
|
184 |
+
}
|
185 |
+
if ( $changed )
|
186 |
+
$ids = array_values($ids);
|
187 |
$this->set_option($this->opt_icons, $ids);
|
188 |
+
}
|
189 |
}
|
190 |
|
191 |
/**
|
200 |
//Select one from random
|
201 |
$idx = ( count($icons) > 1 ) ? array_rand($icons) : 0;
|
202 |
$icon_id = $icons[$idx];
|
203 |
+
$icon = $this->media->get_icon_src($icon_id);
|
204 |
+
if ( !$icon || ( is_string($icon) && 'ico' != substr($icon, strrpos($icon, '.') + 1) ) ) {
|
205 |
//Reset variable to NULL
|
206 |
$icon = null;
|
207 |
//Remove icon from list (no longer valid)
|
208 |
unset($icons[$idx]);
|
209 |
array_values($icons);
|
210 |
}
|
211 |
+
//Load image src (for image attachments)
|
212 |
+
if ( is_array($icon) )
|
213 |
+
$icon = $icon[0];
|
214 |
}
|
215 |
|
216 |
//Display icon
|
281 |
<?php screen_icon(); ?>
|
282 |
<h2><?php _e('Favicon Rotator'); ?> <a href="<?php echo $this->media->get_upload_iframe_src('image'); ?>" class="button add-new-h2 thickbox" title="<?php esc_attr_e('Add Icon'); ?>"><?php echo esc_html_x('Add new', 'file')?></a></h2>
|
283 |
<div id="fv_list_container">
|
284 |
+
<p id="fv_no_icons"<?php if ( $icons ) echo ' style="display: none;"'?>>No favicons set</p>
|
|
|
|
|
285 |
<ul id="fv_list">
|
286 |
<?php foreach ( $icons as $icon ) : //List icons
|
287 |
+
$icon_src = wp_get_attachment_image_src($icon->ID, $this->icon_size);
|
288 |
+
$icon_src = $icon_src[0];
|
289 |
$src = wp_get_attachment_image_src($icon->ID, 'full');
|
290 |
$src = $src[0];
|
291 |
?>
|
292 |
<li class="fv_item">
|
293 |
<div>
|
294 |
+
<img class="icon" src="<?php echo $icon_src; ?>" />
|
295 |
<div class="details">
|
296 |
<div class="name"><?php echo basename($src); ?></div>
|
297 |
<div class="options">
|
readme.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
===
|
2 |
Contributors: archetyped
|
3 |
Tags: favicon,icon,template,theme,customization,simple,media
|
4 |
Requires at least: 3.0
|
@@ -9,9 +9,13 @@ Easily set site favicon and even rotate through multiple icons
|
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
-
Favicon Rotator makes it easy to customize the favicon for your site. Just add a favicon
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
Favicon Rotator supports **multiple icons**, from which a **randomly selected** favicon from the rotation will be displayed.
|
15 |
|
16 |
[More Information on Favicons](http://wikipedia.org/wiki/Favicon)
|
17 |
|
@@ -36,5 +40,13 @@ Go to http://archetyped.com/tools/favicon-rotator/ for any questions or comments
|
|
36 |
1. Favicon submenu in Appearance menu
|
37 |
|
38 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
= 1.0 =
|
40 |
* Initial release
|
1 |
+
=== Favicon Rotator ===
|
2 |
Contributors: archetyped
|
3 |
Tags: favicon,icon,template,theme,customization,simple,media
|
4 |
Requires at least: 3.0
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
+
Favicon Rotator makes it easy to customize the favicon for your site. Just add a favicon via the administration page and it will be displayed whenever someone visits your site.
|
13 |
+
|
14 |
+
#### Highlights
|
15 |
+
* Simply point and click to add a favicon to your site
|
16 |
+
* Support for **multiple icons**, from which a **randomly selected** favicon from the rotation will be displayed.
|
17 |
+
* Automatic icon generation for large images (smaller files and faster loading)
|
18 |
|
|
|
19 |
|
20 |
[More Information on Favicons](http://wikipedia.org/wiki/Favicon)
|
21 |
|
40 |
1. Favicon submenu in Appearance menu
|
41 |
|
42 |
== Changelog ==
|
43 |
+
= 1.1.2 =
|
44 |
+
* Updated: Utilities code (internal)
|
45 |
+
= 1.1 =
|
46 |
+
* Added: Generate icon file from uploaded images
|
47 |
+
* Added: Settings link from plugins page
|
48 |
+
* Optimized: File path resolution
|
49 |
+
= 1.0.1 =
|
50 |
+
* Fix: Various bugs
|
51 |
= 1.0 =
|
52 |
* Initial release
|
screenshot-1.png
DELETED
Binary file
|
screenshot-2.png
DELETED
Binary file
|