| 1 | <?php |
|---|
| 2 | /* |
|---|
| 3 | Plugin Name: Favatars |
|---|
| 4 | Plugin URI: http://dev.wp-plugins.org/wiki/favatars |
|---|
| 5 | Description: A system to show favicon.ico files as avatars: "Favatars". Entire recode by <a href="http://www.thecodepro.com/">Jeff Minard</a> <br /> Previous Versions care of: <a href="http://www.noscope.com">Joen</a>, <a href="http://www.peej.co.uk/projects/favatars.html">Paul James</a>, and <a href="http://www.somefoolwitha.com">Matthew</a>. |
|---|
| 6 | Version: 2 |
|---|
| 7 | Author: Jeff Minard |
|---|
| 8 | Author URI: http://thecodepro.com/ |
|---|
| 9 | */ |
|---|
| 10 | |
|---|
| 11 | // Nothing more to see here. All configuration is done via the admin panel. |
|---|
| 12 | // Move along. |
|---|
| 13 | |
|---|
| 14 | $comment_favicon_exists = fav_maybe_add_column($wpdb->comments, 'comment_favicon_url', "ALTER TABLE `$wpdb->comments` ADD `comment_favicon_url` TEXT NOT NULL"); |
|---|
| 15 | |
|---|
| 16 | if( $comment_favicon_exists == false ) |
|---|
| 17 | die("I could not initialize the need column to make the favicon hack work. Please disable the plugin and contact the author."); |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | function comment_favicon($before='<img src="', $after='" alt="" />') { |
|---|
| 23 | global $comment, $wpdb; |
|---|
| 24 | |
|---|
| 25 | $favicon_url = $wpdb->get_var("SELECT comment_favicon_url FROM `$wpdb->comments` WHERE `comment_ID` = '$comment->comment_ID'"); |
|---|
| 26 | |
|---|
| 27 | if(!empty($favicon_url)) |
|---|
| 28 | echo($before . $favicon_url . $after); |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | |
|---|
| 34 | |
|---|
| 35 | // Now the real meat, the discovery function. |
|---|
| 36 | function discover_favicon($comment_ID) { |
|---|
| 37 | global $wpdb; |
|---|
| 38 | |
|---|
| 39 | $posters_url = $wpdb->get_var("SELECT comment_author_url FROM `$wpdb->comments` WHERE `comment_ID` = '$comment_ID'"); |
|---|
| 40 | |
|---|
| 41 | if(!empty($posters_url)) { |
|---|
| 42 | |
|---|
| 43 | if( $favicon_url = getFavicon($posters_url) ) |
|---|
| 44 | $wpdb->query("UPDATE `$wpdb->comments` SET `comment_favicon_url` = '$favicon_url' WHERE `comment_ID` = '$comment_ID' LIMIT 1"); |
|---|
| 45 | |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | return $comment_ID; |
|---|
| 49 | |
|---|
| 50 | } |
|---|
| 51 | |
|---|
| 52 | // adds the discovery function to happen on comments, tracks, and pings |
|---|
| 53 | add_action('comment_post','discover_favicon'); |
|---|
| 54 | add_action('trackback_post','discover_favicon'); |
|---|
| 55 | add_action('pingback_post','discover_favicon'); |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | /************************************** |
|---|
| 59 | Utility functions needed for this thing |
|---|
| 60 | **************************************/ |
|---|
| 61 | |
|---|
| 62 | /* |
|---|
| 63 | * @return boolean/string |
|---|
| 64 | * @param string $url |
|---|
| 65 | * @desc Attempts to find and return a favicon url based on $url |
|---|
| 66 | */ |
|---|
| 67 | |
|---|
| 68 | function getFavicon($url) { |
|---|
| 69 | |
|---|
| 70 | // start by fetching the contents of the URL they left... |
|---|
| 71 | if( $html = @file_get_contents($url) ) { |
|---|
| 72 | |
|---|
| 73 | if (preg_match('/<link[^>]+rel="(?:shortcut )?icon"[^>]+?href="([^"]+?)"/si', $html, $matches)) { |
|---|
| 74 | // Attempt to grab a favicon link from their webpage url |
|---|
| 75 | |
|---|
| 76 | $linkUrl = html_entity_decode($matches[1]); |
|---|
| 77 | if (substr($linkUrl, 0, 1) == '/') { |
|---|
| 78 | $urlParts = parse_url($url); |
|---|
| 79 | $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].$linkUrl; |
|---|
| 80 | } else if (substr($linkUrl, 0, 7) == 'http://') { |
|---|
| 81 | $faviconURL = $linkUrl; |
|---|
| 82 | } else if (substr($url, -1, 1) == '/') { |
|---|
| 83 | $faviconURL = $url.$linkUrl; |
|---|
| 84 | } else { |
|---|
| 85 | $faviconURL = $url.'/'.$linkUrl; |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | } else { |
|---|
| 89 | // If unsuccessful, attempt to "guess" the favicon location |
|---|
| 90 | |
|---|
| 91 | $urlParts = parse_url($url); |
|---|
| 92 | $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].'/favicon.ico'; |
|---|
| 93 | |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | // Run a test to see if what we have attempted to get actually exists. |
|---|
| 97 | if( $faviconURL_exists = url_validate($faviconURL) ) |
|---|
| 98 | return $faviconURL; |
|---|
| 99 | |
|---|
| 100 | } |
|---|
| 101 | |
|---|
| 102 | // Finally, if we haven't 'returned' yet then there is nothing to see here. |
|---|
| 103 | return false; |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | /** |
|---|
| 108 | ** fav_maybe_add_column() |
|---|
| 109 | ** Add column to db table if it doesn't exist. |
|---|
| 110 | ** Returns: true if already exists or on successful completion |
|---|
| 111 | ** false on error |
|---|
| 112 | */ |
|---|
| 113 | function fav_maybe_add_column($table_name, $column_name, $create_ddl) { |
|---|
| 114 | global $wpdb; |
|---|
| 115 | foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) { |
|---|
| 116 | if ($column == $column_name) |
|---|
| 117 | return true; |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | //didn't find it try to create it. |
|---|
| 121 | $q = $wpdb->query($create_ddl); |
|---|
| 122 | |
|---|
| 123 | // we cannot directly tell that whether this succeeded! |
|---|
| 124 | foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) { |
|---|
| 125 | if ($column == $column_name) |
|---|
| 126 | return true; |
|---|
| 127 | } |
|---|
| 128 | return false; |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | /* |
|---|
| 132 | * @return boolean |
|---|
| 133 | * @param string $link |
|---|
| 134 | * @desc Checks to see if $link actually exists (HTTP-Code: 200|30*, etc) |
|---|
| 135 | */ |
|---|
| 136 | function url_validate( $link ) { |
|---|
| 137 | |
|---|
| 138 | $url_parts = @parse_url( $link ); |
|---|
| 139 | |
|---|
| 140 | if ( empty( $url_parts["host"] ) ) |
|---|
| 141 | return false; |
|---|
| 142 | |
|---|
| 143 | if ( !empty( $url_parts["path"] ) ) { |
|---|
| 144 | $documentpath = $url_parts["path"]; |
|---|
| 145 | } else { |
|---|
| 146 | $documentpath = "/"; |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | if ( !empty( $url_parts["query"] ) ) |
|---|
| 150 | $documentpath .= "?" . $url_parts["query"]; |
|---|
| 151 | |
|---|
| 152 | $host = $url_parts["host"]; |
|---|
| 153 | $port = $url_parts["port"]; |
|---|
| 154 | |
|---|
| 155 | if ( empty($port) ) |
|---|
| 156 | $port = "80"; |
|---|
| 157 | |
|---|
| 158 | $socket = @fsockopen( $host, $port, $errno, $errstr, 30 ); |
|---|
| 159 | |
|---|
| 160 | if ( !$socket ) |
|---|
| 161 | return false; |
|---|
| 162 | |
|---|
| 163 | fwrite ($socket, "HEAD ".$documentpath." HTTP/1.0\r\nHost: $host\r\n\r\n"); |
|---|
| 164 | |
|---|
| 165 | $http_response = fgets( $socket, 22 ); |
|---|
| 166 | |
|---|
| 167 | $responses = "/(200 OK)|(30[0-9] Moved)/"; |
|---|
| 168 | if ( preg_match($responses, $http_response) ) { |
|---|
| 169 | fclose($socket); |
|---|
| 170 | return true; |
|---|
| 171 | } else { |
|---|
| 172 | return false; |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | } |
|---|
| 176 | |
|---|
| 177 | function super_flush() { |
|---|
| 178 | // Because some logs are just too big for flush()... |
|---|
| 179 | flush(); ob_flush(); |
|---|
| 180 | flush(); ob_flush(); |
|---|
| 181 | flush(); ob_flush(); |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | function favatars_option_page() { |
|---|
| 185 | global $wpdb; |
|---|
| 186 | ?> |
|---|
| 187 | |
|---|
| 188 | <div class="wrap"> |
|---|
| 189 | <h2>Favatars</h2> |
|---|
| 190 | |
|---|
| 191 | <?php |
|---|
| 192 | |
|---|
| 193 | if($_GET['clear'] == 1) { |
|---|
| 194 | $comments = $wpdb->get_results("UPDATE `$wpdb->comments` SET `comment_favicon_url` = ''"); |
|---|
| 195 | echo '<div class="updated"><p>All favicons deleted.</p></div>'; |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | ?> |
|---|
| 199 | |
|---|
| 200 | <p>Attempt to find a favatar for every single comment, trackback, and pingback on your site. You should really only need to use this once after your turn the script on as it is primarily for fetching favatars for previous comments. However, you may also use this page to <a href="?page=favatars.php&clear=1" onclick="return confirm('Flush all? You sure?');">flush the favatars from your system</a>.</p> |
|---|
| 201 | |
|---|
| 202 | <?php |
|---|
| 203 | |
|---|
| 204 | $gzipness = get_option('gzipcompression'); |
|---|
| 205 | |
|---|
| 206 | if( $_GET['start'] && $gzipness == false ) { |
|---|
| 207 | // go go go! update those avatars! |
|---|
| 208 | |
|---|
| 209 | DEFINE(SP,' '); |
|---|
| 210 | |
|---|
| 211 | $request = "SELECT comment_ID, comment_author_url FROM $wpdb->comments WHERE comment_favicon_url = '' AND comment_author_url != '' "; |
|---|
| 212 | |
|---|
| 213 | $comments = $wpdb->get_results($request); |
|---|
| 214 | |
|---|
| 215 | $processed_urls = array(); |
|---|
| 216 | |
|---|
| 217 | if ($comments) { |
|---|
| 218 | foreach ($comments as $comment) { |
|---|
| 219 | |
|---|
| 220 | super_flush(); |
|---|
| 221 | echo("Updating Comment: $comment->comment_ID (<a href=\"$comment->comment_author_url\">$comment->comment_author_url</a>) ... <br />"); |
|---|
| 222 | super_flush(); |
|---|
| 223 | |
|---|
| 224 | if(!empty($processed_urls[$comment->comment_author_url])) { |
|---|
| 225 | // commenter url already cached, don't reprocess |
|---|
| 226 | |
|---|
| 227 | if($processed_urls[$comment->comment_author_url] == 'none') { |
|---|
| 228 | // empty one discovered, skip it. |
|---|
| 229 | echo(SP."<em>Cached: Couldn't find a favicon</em><br />\n"); |
|---|
| 230 | } else { |
|---|
| 231 | // normal favicon, go ahead. |
|---|
| 232 | $wpdb->query("UPDATE `$wpdb->comments` SET `comment_favicon_url` = '" . $processed_urls[$comment->comment_author_url] . "' WHERE `comment_ID` = '$comment->comment_ID' LIMIT 1"); |
|---|
| 233 | echo(SP."<em>Cached: Successfully used: " . $processed_urls[$comment->comment_author_url] . "</em><br />\n"); |
|---|
| 234 | } |
|---|
| 235 | |
|---|
| 236 | } else { |
|---|
| 237 | // Not in the cached array. |
|---|
| 238 | |
|---|
| 239 | if( $favicon_url = getFavicon($comment->comment_author_url) ) { |
|---|
| 240 | $wpdb->query("UPDATE `$wpdb->comments` SET `comment_favicon_url` = '$favicon_url' WHERE `comment_ID` = '$comment->comment_ID' LIMIT 1"); |
|---|
| 241 | $processed_urls[$comment->comment_author_url] = $favicon_url; |
|---|
| 242 | echo(SP."Successfully used: $favicon_url<br />\n"); |
|---|
| 243 | } else { |
|---|
| 244 | $processed_urls[$comment->comment_author_url] = 'none'; |
|---|
| 245 | echo(SP."No luck. Couldn't find a favicon<br />\n"); |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | super_flush(); |
|---|
| 251 | sleep(1); |
|---|
| 252 | |
|---|
| 253 | } |
|---|
| 254 | } |
|---|
| 255 | |
|---|
| 256 | |
|---|
| 257 | ?> |
|---|
| 258 | |
|---|
| 259 | <h1>Update Complete!</h1> |
|---|
| 260 | |
|---|
| 261 | <p>You blog should now be all favatar'ed up!</p> |
|---|
| 262 | |
|---|
| 263 | <p><em>You can <a href="?page=favatars.php&gzip=on">turn on gzip compression</a> again if you'd like</em></p> |
|---|
| 264 | |
|---|
| 265 | <?php |
|---|
| 266 | |
|---|
| 267 | } else if( $_GET['start'] && $gzipness == true ) { |
|---|
| 268 | |
|---|
| 269 | ?> |
|---|
| 270 | |
|---|
| 271 | <p>You must <a href="?page=favatars.php&gzip=off">disable GZIP compression</a> for this script to work correctly.</p> |
|---|
| 272 | |
|---|
| 273 | <?php |
|---|
| 274 | |
|---|
| 275 | } else if( !$_GET['start'] && !$_GET['gzip'] ) { |
|---|
| 276 | |
|---|
| 277 | ?> |
|---|
| 278 | |
|---|
| 279 | <p><strong>WARNING: THIS SCRIPT IS HARD CORE</strong><br /> |
|---|
| 280 | It may bring your server to it's knees, it may not. Regardless, it's going to take a very long time - the script has to parse every single comment. So there, you've been warned.</p> |
|---|
| 281 | |
|---|
| 282 | <p>With that said, this script <em>shouldn't</em> do anything nearly as bad as that sounds - it'd most likely just fail to work.</p> |
|---|
| 283 | |
|---|
| 284 | <p><em>Also of note, because of the way it's created, you can run this as many times as you want. The script only updates a comment when it has an author URL but no favicon url.</em></p> |
|---|
| 285 | |
|---|
| 286 | <form method="get"> |
|---|
| 287 | <input type="hidden" name="page" value="favatars.php" /> |
|---|
| 288 | <input type="submit" name="start" id="start" value="Favatise My Blog" style="font-size: 1.7em;" /> |
|---|
| 289 | </form> |
|---|
| 290 | |
|---|
| 291 | <?php |
|---|
| 292 | |
|---|
| 293 | } |
|---|
| 294 | |
|---|
| 295 | if( $_GET['gzip'] == 'off' ) { |
|---|
| 296 | // turn off gzip and proceed to step 2: favatise! |
|---|
| 297 | update_option('gzipcompression', 0); |
|---|
| 298 | ?> |
|---|
| 299 | |
|---|
| 300 | <p>Gzip compression has been <strong>disabled</strong>, you may <a href="?page=favatars.php&start=1">begin generating favatars for all comments.</a></p> |
|---|
| 301 | |
|---|
| 302 | <?php |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | if( $_GET['gzip'] == 'on' ) { |
|---|
| 306 | // turn off gzip and proceed to step 2: favatise! |
|---|
| 307 | update_option('gzipcompression', 1); |
|---|
| 308 | ?> |
|---|
| 309 | |
|---|
| 310 | <p>Gzip compression has been <strong>enabled</strong></p> |
|---|
| 311 | |
|---|
| 312 | <?php |
|---|
| 313 | } |
|---|
| 314 | |
|---|
| 315 | ?> |
|---|
| 316 | |
|---|
| 317 | |
|---|
| 318 | </div> |
|---|
| 319 | |
|---|
| 320 | |
|---|
| 321 | <?php |
|---|
| 322 | |
|---|
| 323 | } |
|---|
| 324 | |
|---|
| 325 | function favatars_add_options() { |
|---|
| 326 | add_options_page('Favatars', 'Favatars Page', 10, __FILE__, 'favatars_option_page'); |
|---|
| 327 | } |
|---|
| 328 | |
|---|
| 329 | add_action('admin_menu', 'favatars_add_options'); |
|---|
| 330 | |
|---|
| 331 | ?> |
|---|