| 1 | <?php |
|---|
| 2 | /* |
|---|
| 3 | Plugin Name: WP-Cats |
|---|
| 4 | Plugin URI: http://www.uwmike.com/wordpress/wp-cats/ |
|---|
| 5 | Description: Ajax-y category controls added to the Manage Posts screen |
|---|
| 6 | Author: Mike Purvis |
|---|
| 7 | Author URI: http://www.uwmike.com |
|---|
| 8 | Version: 0.13 |
|---|
| 9 | |
|---|
| 10 | Copyright 2006 Mike Purvis (mike@uwmike.com) |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | This program is free software; you can redistribute it and/or modify |
|---|
| 14 | it under the terms of the GNU General Public License as published by |
|---|
| 15 | the Free Software Foundation; either version 2 of the License, or |
|---|
| 16 | (at your option) any later version. |
|---|
| 17 | |
|---|
| 18 | This program is distributed in the hope that it will be useful, |
|---|
| 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 21 | GNU General Public License for more details. |
|---|
| 22 | |
|---|
| 23 | You should have received a copy of the GNU General Public License |
|---|
| 24 | along with this program; if not, write to the Free Software |
|---|
| 25 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 26 | |
|---|
| 27 | */ |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | $wp_cats_mozilla_columns = false; |
|---|
| 31 | $wp_cats_mozilla_column_height = '310px'; |
|---|
| 32 | |
|---|
| 33 | |
|---|
| 34 | |
|---|
| 35 | add_action('plugins_loaded', create_function('$a', 'global $wp_cats; $wp_cats = new wp_cats;')); |
|---|
| 36 | add_action('admin_head', array(&$wp_cats, 'header_inserts')); |
|---|
| 37 | add_action('init', array(&$wp_cats, 'hijack')); |
|---|
| 38 | |
|---|
| 39 | class wp_cats { |
|---|
| 40 | |
|---|
| 41 | function header_inserts() { |
|---|
| 42 | global $parent_file; |
|---|
| 43 | |
|---|
| 44 | if ('edit.php' == $parent_file) { |
|---|
| 45 | echo '<script type="text/javascript">var wp_cats_category_title = \''.__('Categories').'\';</script>' . "\n"; |
|---|
| 46 | echo '<script type="text/javascript" src="' . get_bloginfo('url') . '/?wp-cats=js&v=00002"></script>' . "\n"; |
|---|
| 47 | echo '<link rel="stylesheet" type="text/css" href="' . get_bloginfo('url') . '/?wp-cats=css&v=00002" />'; |
|---|
| 48 | } |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | |
|---|
| 52 | function hijack() { |
|---|
| 53 | if (!isset($_GET['wp-cats'])) return; |
|---|
| 54 | |
|---|
| 55 | if ('cats' == $_GET['wp-cats']) { |
|---|
| 56 | echo '<div id="wp-cats-visible-list">'; |
|---|
| 57 | wp_list_cats('hide_empty=false'); |
|---|
| 58 | echo '</div><div id="wp-cats-hidden-list">'; |
|---|
| 59 | remove_filter('list_cats', 'wptexturize'); |
|---|
| 60 | wp_list_cats('hide_empty=false'); |
|---|
| 61 | echo '</div>'; |
|---|
| 62 | die(); |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | if ('modify' == $_GET['wp-cats']) { |
|---|
| 66 | global $wp_query; |
|---|
| 67 | |
|---|
| 68 | if (!isset($_POST['post_id']) || !isset($_POST['cat_name']) || !isset($_POST['addremove']) ) die('<error>Request malformed.</error>'); |
|---|
| 69 | |
|---|
| 70 | $post_id = (int)$_POST['post_id']; |
|---|
| 71 | $cat_id = get_cat_id($_POST['cat_name']); |
|---|
| 72 | |
|---|
| 73 | if (!current_user_can('edit_post', $post_id)) die('<error>You don\'t have permission to modify this entry.</error>'); |
|---|
| 74 | |
|---|
| 75 | $post_cats = wp_get_post_cats('', $post_id); |
|---|
| 76 | if (count($post_cats) == 1 && 'add' == $_POST['addremove'] && get_cat_name($post_cats[0]) == 'Uncategorized') |
|---|
| 77 | unset($post_cats[0]); |
|---|
| 78 | |
|---|
| 79 | $cat_search = array_search($cat_id, $post_cats); |
|---|
| 80 | |
|---|
| 81 | if ('add' == $_POST['addremove'] and $cat_search === false) $post_cats[] = $cat_id; |
|---|
| 82 | if ('remove' == $_POST['addremove'] and $cat_search !== false) unset($post_cats[$cat_search]); |
|---|
| 83 | |
|---|
| 84 | wp_set_post_cats('', $post_id, $post_cats); |
|---|
| 85 | |
|---|
| 86 | // Spoof "the_category" into thinking it's inside "the loop" |
|---|
| 87 | global $post; |
|---|
| 88 | $post = (object) NULL; |
|---|
| 89 | $post->ID = $post_id; |
|---|
| 90 | the_category(', '); |
|---|
| 91 | |
|---|
| 92 | die(); |
|---|
| 93 | } |
|---|
| 94 | |
|---|
| 95 | |
|---|
| 96 | if ('js' == $_GET['wp-cats']) { |
|---|
| 97 | header("Content-type: text/javascript"); |
|---|
| 98 | die($this->js()); |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | if ('css' == $_GET['wp-cats']) { |
|---|
| 102 | header("Content-type: text/css"); |
|---|
| 103 | die($this->css()); |
|---|
| 104 | } |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | function js() |
|---|
| 108 | { |
|---|
| 109 | return <<<EOJS |
|---|
| 110 | |
|---|
| 111 | /* Javascript functions for WP-Cats */ |
|---|
| 112 | |
|---|
| 113 | var js_wp_catbox, js_wp_cats = '', js_wp_column_categories = 0; |
|---|
| 114 | var js_wp_catbox_closeit = function() {}; |
|---|
| 115 | |
|---|
| 116 | function js_wp_cats_make_link(title, f) { |
|---|
| 117 | var new_link = document.createElement('a'); |
|---|
| 118 | new_link.className = 'wp-cats-button'; |
|---|
| 119 | if (title == '+') new_link.className += ' wp-cats-button-plus'; |
|---|
| 120 | new_link.innerHTML = title; |
|---|
| 121 | new_link.href = '#'; |
|---|
| 122 | new_link.onclick = f; |
|---|
| 123 | return new_link; |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | function wp_cats_linkify_row(this_row) { |
|---|
| 127 | var post_id = this_row.getElementsByTagName('th')[0].innerHTML; |
|---|
| 128 | var cats_cell = this_row.getElementsByTagName('td')[js_wp_column_categories - 1]; |
|---|
| 129 | var cat_links = cats_cell.getElementsByTagName('a'); |
|---|
| 130 | |
|---|
| 131 | // Link to add categories |
|---|
| 132 | var add_this = function() { |
|---|
| 133 | cats_cell.insertBefore(js_wp_cats_make_link('+', function() { |
|---|
| 134 | js_wp_cats_popup(post_id, cats_cell); |
|---|
| 135 | return false; |
|---|
| 136 | }), cats_cell.firstChild); |
|---|
| 137 | }; |
|---|
| 138 | |
|---|
| 139 | // Links to remove existing categories |
|---|
| 140 | for (var link_iterate = cat_links.length - 1; link_iterate >= 0; link_iterate--) { |
|---|
| 141 | var this_link = cat_links[link_iterate]; |
|---|
| 142 | |
|---|
| 143 | add_this = (function(link, attached, last) { |
|---|
| 144 | return function () { |
|---|
| 145 | last(); |
|---|
| 146 | cats_cell.insertBefore(link, attached.nextSibling); |
|---|
| 147 | } |
|---|
| 148 | })( |
|---|
| 149 | (function(post_id, category_name) { |
|---|
| 150 | return js_wp_cats_make_link('-', function() { |
|---|
| 151 | js_wp_cats_modify(post_id, category_name, cats_cell, 'remove'); |
|---|
| 152 | return false; |
|---|
| 153 | }); |
|---|
| 154 | })(post_id, this_link.innerHTML), this_link, add_this); |
|---|
| 155 | } |
|---|
| 156 | |
|---|
| 157 | add_this(); |
|---|
| 158 | } |
|---|
| 159 | |
|---|
| 160 | function js_wp_cats_setup() { |
|---|
| 161 | var table, columns, rows; |
|---|
| 162 | var new_link; |
|---|
| 163 | if (!(table = document.getElementById('the-list-x'))) return; // bail if there's no post list |
|---|
| 164 | rows = table.getElementsByTagName('tr'); |
|---|
| 165 | columns = rows[0].getElementsByTagName('th'); |
|---|
| 166 | for (var column_iterate in columns) { |
|---|
| 167 | if (columns[column_iterate].innerHTML == wp_cats_category_title) { |
|---|
| 168 | js_wp_column_categories = column_iterate; |
|---|
| 169 | break; |
|---|
| 170 | } |
|---|
| 171 | } |
|---|
| 172 | if (js_wp_column_categories == 0) return; // bail if there's no column for categories |
|---|
| 173 | |
|---|
| 174 | for (var row_iterate = rows.length - 1; row_iterate > 0; row_iterate--) { |
|---|
| 175 | wp_cats_linkify_row(rows[row_iterate]); |
|---|
| 176 | } |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | // Adds onclick handlers to the links in the popup selection box. |
|---|
| 180 | function wp_cats_linkify_popup(container, post_id) { |
|---|
| 181 | var cat_links = container.getElementsByTagName('a'); |
|---|
| 182 | for (var link_iterate = cat_links.length - 1; link_iterate >= 0; link_iterate--) { |
|---|
| 183 | cat_links[link_iterate].onclick = function() { |
|---|
| 184 | // this is a hack to get around the texturized category names; a second list is kept |
|---|
| 185 | // hidden, which contains the untexturized versions. |
|---|
| 186 | var hidden_links = container.getElementsByTagName('a'); |
|---|
| 187 | var cat_name = ''; |
|---|
| 188 | for (var hidden_iterate = hidden_links.length - 1; hidden_iterate >= 0; hidden_iterate--) { |
|---|
| 189 | if (hidden_links[hidden_iterate].href == this.href && hidden_links[hidden_iterate] != this) { |
|---|
| 190 | cat_name = hidden_links[hidden_iterate].innerHTML; |
|---|
| 191 | } |
|---|
| 192 | } |
|---|
| 193 | js_wp_cats_modify(post_id, cat_name, container.parentNode, 'add'); |
|---|
| 194 | js_wp_catbox_closeit(); |
|---|
| 195 | return false; |
|---|
| 196 | } |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | return container; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | function js_wp_cats_popup(post_id, clickedElement) { |
|---|
| 203 | if ('' == js_wp_cats) { |
|---|
| 204 | // first use this pageview; must fetch cat list/markup |
|---|
| 205 | var xmlhttp = js_wp_cats_xmlhttp(); |
|---|
| 206 | xmlhttp.onreadystatechange = function() { |
|---|
| 207 | if (xmlhttp.readyState == 4) { |
|---|
| 208 | if (xmlhttp.status == 200) { |
|---|
| 209 | js_wp_cats = '<ul>' + xmlhttp.responseText + '</ul>'; |
|---|
| 210 | js_wp_cats_popup(post_id, clickedElement); |
|---|
| 211 | } |
|---|
| 212 | else |
|---|
| 213 | alert('Remote request error, please try clicking again.'); |
|---|
| 214 | } |
|---|
| 215 | } |
|---|
| 216 | |
|---|
| 217 | var url = ('' + window.location).split('#')[0].split('?')[0] + '?wp-cats=cats'; |
|---|
| 218 | xmlhttp.open("GET", url, true); |
|---|
| 219 | xmlhttp.send(null); |
|---|
| 220 | |
|---|
| 221 | return; |
|---|
| 222 | } |
|---|
| 223 | |
|---|
| 224 | var popupDiv = document.createElement('div'); |
|---|
| 225 | popupDiv.className = 'wp-cats-popup'; |
|---|
| 226 | popupDiv.innerHTML = js_wp_cats; |
|---|
| 227 | clickedElement.appendChild(wp_cats_linkify_popup(popupDiv, post_id)); |
|---|
| 228 | |
|---|
| 229 | var prevHandler = clickedElement.getElementsByTagName('a')[0].onclick; |
|---|
| 230 | js_wp_catbox_closeit(); |
|---|
| 231 | |
|---|
| 232 | js_wp_catbox_closeit = function() { |
|---|
| 233 | clickedElement.removeChild(popupDiv); |
|---|
| 234 | clickedElement.getElementsByTagName('a')[0].onclick = prevHandler; |
|---|
| 235 | js_wp_catbox_closeit = function() {}; |
|---|
| 236 | return false; |
|---|
| 237 | } |
|---|
| 238 | |
|---|
| 239 | clickedElement.getElementsByTagName('a')[0].onclick = js_wp_catbox_closeit; |
|---|
| 240 | } |
|---|
| 241 | |
|---|
| 242 | function js_wp_cats_modify(post_id, category_name, container, addremove) { |
|---|
| 243 | container.style.backgroundColor='#aaa'; |
|---|
| 244 | |
|---|
| 245 | var xmlhttp = js_wp_cats_xmlhttp(); |
|---|
| 246 | var url = ('' + window.location).split('#')[0].split('?')[0] + '?wp-cats=modify'; |
|---|
| 247 | xmlhttp.open("POST", url, true); |
|---|
| 248 | |
|---|
| 249 | xmlhttp.onreadystatechange = function() { |
|---|
| 250 | if (xmlhttp.readyState == 4) { |
|---|
| 251 | if (xmlhttp.status == 200) { |
|---|
| 252 | var response = xmlhttp.responseText; |
|---|
| 253 | var errorRegexp = /^<error>(.*)<\/error>$/; |
|---|
| 254 | if (response.match(errorRegexp)) { |
|---|
| 255 | var match = errorRegexp.exec(response); |
|---|
| 256 | container.style.backgroundColor=''; |
|---|
| 257 | alert(match[1]); |
|---|
| 258 | return; |
|---|
| 259 | } |
|---|
| 260 | container.innerHTML = response; |
|---|
| 261 | container.style.backgroundColor=''; |
|---|
| 262 | wp_cats_linkify_row(container.parentNode); |
|---|
| 263 | } |
|---|
| 264 | else |
|---|
| 265 | { |
|---|
| 266 | container.style.backgroundColor=''; |
|---|
| 267 | alert('Remote request error, please try again.'); |
|---|
| 268 | } |
|---|
| 269 | } |
|---|
| 270 | } |
|---|
| 271 | xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
|---|
| 272 | xmlhttp.send('post_id='+post_id+'&cat_name='+category_name+'&addremove='+addremove); |
|---|
| 273 | } |
|---|
| 274 | |
|---|
| 275 | |
|---|
| 276 | // plundered from Jeremy Keith. Yarr. |
|---|
| 277 | function js_wp_cats_xmlhttp() { |
|---|
| 278 | var xmlhttp = false; |
|---|
| 279 | if (window.XMLHttpRequest) { |
|---|
| 280 | xmlhttp = new XMLHttpRequest(); |
|---|
| 281 | } else if(window.ActiveXObject) { |
|---|
| 282 | try { |
|---|
| 283 | xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); |
|---|
| 284 | } catch (e) { |
|---|
| 285 | try { |
|---|
| 286 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); |
|---|
| 287 | } catch (e) { |
|---|
| 288 | xmlhttp = false; |
|---|
| 289 | } |
|---|
| 290 | } |
|---|
| 291 | } |
|---|
| 292 | return xmlhttp; |
|---|
| 293 | } |
|---|
| 294 | |
|---|
| 295 | |
|---|
| 296 | addLoadEvent(js_wp_cats_setup); |
|---|
| 297 | |
|---|
| 298 | EOJS; |
|---|
| 299 | } |
|---|
| 300 | |
|---|
| 301 | function css() { |
|---|
| 302 | $css_extra = ''; |
|---|
| 303 | |
|---|
| 304 | if (isset($_GET['foo'])) { die(var_dump($this)); } |
|---|
| 305 | |
|---|
| 306 | if ($GLOBALS['wp_cats_mozilla_columns']) |
|---|
| 307 | $css_extra .= '.wp-cats-popup { height: ' . $GLOBALS['wp_cats_mozilla_column_height'] . '; -moz-column-width: 120px; padding-right: 135px; }'; |
|---|
| 308 | |
|---|
| 309 | return <<<EOCSS |
|---|
| 310 | |
|---|
| 311 | /* CSS for WP-Cats */ |
|---|
| 312 | |
|---|
| 313 | a.wp-cats-button { |
|---|
| 314 | padding: 0 3px; |
|---|
| 315 | margin: 0 0 0 5px; |
|---|
| 316 | background: #ccc; |
|---|
| 317 | border: none; |
|---|
| 318 | text-decoration: none; |
|---|
| 319 | } |
|---|
| 320 | |
|---|
| 321 | a.wp-cats-button-plus { |
|---|
| 322 | margin: 0 5px 0 0; |
|---|
| 323 | } |
|---|
| 324 | a.wp-cats-button:hover { |
|---|
| 325 | background: #bbb; |
|---|
| 326 | } |
|---|
| 327 | .wp-cats-popup { |
|---|
| 328 | position: absolute; |
|---|
| 329 | background: white; |
|---|
| 330 | border: 1px solid black; |
|---|
| 331 | z-index: 10000; |
|---|
| 332 | padding: 4px 0; |
|---|
| 333 | } |
|---|
| 334 | |
|---|
| 335 | .wp-cats-popup ul { |
|---|
| 336 | padding: 0; |
|---|
| 337 | margin: 0; |
|---|
| 338 | list-style: none; |
|---|
| 339 | } |
|---|
| 340 | .wp-cats-popup li { |
|---|
| 341 | margin: 0; |
|---|
| 342 | padding: 0; |
|---|
| 343 | display: block; |
|---|
| 344 | } |
|---|
| 345 | .wp-cats-popup li a { |
|---|
| 346 | display: block; |
|---|
| 347 | font-size: 10px; |
|---|
| 348 | border: 0; |
|---|
| 349 | padding: 1px 7px 1px 7px; |
|---|
| 350 | } |
|---|
| 351 | .wp-cats-popup li li a { padding-left: 17px; } |
|---|
| 352 | .wp-cats-popup li li li a { padding-left: 27px; } |
|---|
| 353 | .wp-cats-popup li li li li a { padding-left: 37px; } |
|---|
| 354 | .wp-cats-popup li a:hover { |
|---|
| 355 | background: #ddd; |
|---|
| 356 | } |
|---|
| 357 | .wp-cats-popup #wp-cats-hidden-list { display: none; } |
|---|
| 358 | |
|---|
| 359 | * html .wp-cats-popup li a { display: inline; /* stupid IE */ } |
|---|
| 360 | |
|---|
| 361 | $css_extra |
|---|
| 362 | |
|---|
| 363 | EOCSS; |
|---|
| 364 | } |
|---|
| 365 | |
|---|
| 366 | } |
|---|
| 367 | |
|---|
| 368 | ?> |
|---|