blogs/0000755000000000000000000000000011077645205010671 5ustar rootrootblogs/wp-feed.php0000644000000000000000000000122511077635520012730 0ustar rootroot blogs/wpmu-settings.php0000644000000000000000000002201211077635520014224 0ustar rootrootget_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $domain, $path) ); if( $current_site != null ) return $current_site; $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $domain) ); if( $current_site != null ) { $path = '/'; return $current_site; } $sitedomain = substr( $domain, 1 + strpos( $domain, '.' ) ); $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $sitedomain, $path) ); if( $current_site != null ) return $current_site; $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $sitedomain) ); if( $current_site == null && defined( "WP_INSTALLING" ) == false ) { if( count( $sites ) == 1 ) { $current_site = $sites[0]; die( "That blog does not exist. Please try http://{$current_site->domain}{$current_site->path}" ); } else { die( "No WPMU site defined on this host. If you are the owner of this site, please check Debugging WPMU for further assistance." ); } } else { $path = '/'; } } else { $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $domain, $path) ); if( $current_site != null ) return $current_site; $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $domain) ); if( $current_site == null && defined( "WP_INSTALLING" ) == false ) { if( count( $sites ) == 1 ) { $current_site = $sites[0]; die( "That blog does not exist. Please try http://{$current_site->domain}{$current_site->path}" ); } else { die( "No WPMU site defined on this host. If you are the owner of this site, please check Debugging WPMU for further assistance." ); } } else { $path = '/'; } } return $current_site; } $wpdb->suppress_errors(); $sites = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); // usually only one site if( count( $sites ) == 1 ) { $current_site = $sites[0]; $path = $current_site->path; } else { $current_site = wpmu_current_site(); } if( constant( 'VHOST' ) == 'yes' ) { $current_blog = $wpdb->get_row("SELECT * FROM $wpdb->blogs WHERE domain = '$domain'"); if( $current_blog != null ) { $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE id = %d", $current_blog->site_id) ); } else { $blogname = substr( $domain, 0, strpos( $domain, '.' ) ); } } else { $blogname = htmlspecialchars( substr( $_SERVER[ 'REQUEST_URI' ], strlen( $path ) ) ); if( strpos( $blogname, '/' ) ) $blogname = substr( $blogname, 0, strpos( $blogname, '/' ) ); if( strpos( " ".$blogname, '?' ) ) $blogname = substr( $blogname, 0, strpos( $blogname, '?' ) ); $blognames = array( 'page', 'comments', 'blog', 'wp-admin', 'wp-includes', 'wp-content', 'files', 'feed' ); if( $blogname == '' || in_array( $blogname, $blognames ) || is_file( $blogname ) || is_blogname_page( $blogname ) ) { $current_blog = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $domain, $path) ); } else { $current_blog = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $domain, $path.$blogname.'/') ); } } if( defined( "WP_INSTALLING" ) == false ) { if( $current_site && $current_blog == null ) { $current_blog = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path) ); } if( $current_blog == false || $current_site == false ) is_installed(); } function is_blogname_page( $blogname ) { global $wpdb, $table_prefix, $domain, $path; $blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $domain, $path) ); // is the request for a page of the main blog? We need to cache this information somewhere to save a request $pages = $wpdb->get_col( "SELECT LOWER(post_name) FROM {$table_prefix}{$blog_id}_posts WHERE post_type='page'" ); if( is_array( $pages ) == false ) return false; if( in_array( strtolower( $blogname ), $pages ) ) { return true; } else { return false; } } $blog_id = $current_blog->blog_id; $public = $current_blog->public; if( $current_blog->site_id == 0 || $current_blog->site_id == '' ) $current_blog->site_id = 1; $site_id = $current_blog->site_id; $current_site->site_name = $wpdb->get_var( $wpdb->prepare("SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = %d AND meta_key = 'site_name'", $site_id) ); if( $current_site->site_name == null ) $current_site->site_name = ucfirst( $current_site->domain ); if( $blog_id == false ) { // no blog found, are we installing? Check if the table exists. if ( defined('WP_INSTALLING') ) { $blog_id = $wpdb->get_var( "SELECT blog_id FROM $wpdb->blogs LIMIT 0,1" ); if( $blog_id == false ) { // table doesn't exist. This is the first blog $blog_id = 1; } else { // table exists // don't create record at this stage. we're obviously installing so it doesn't matter what the table vars below are like. // default to using the "main" blog. $blog_id = 1; } $current_blog->blog_id = $blog_id; } else { $check = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); if( $check == false ) { $msg = ': DB Tables Missing'; } else { $msg = ''; } die( "No Blog by that name on this system." . $msg ); } } $wpdb->suppress_errors( false ); if( '0' == $current_blog->public ) { // This just means the blog shouldn't show up in google, etc. Only to registered members } function is_installed() { global $wpdb, $domain, $path; $base = stripslashes( $base ); if( defined( "WP_INSTALLING" ) == false ) { $check = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); $msg = "If your blog does not display, please contact the owner of this site.

If you are the owner of this site please check that MySQL is running properly and all tables are error free.

"; if( $check == false ) { $msg .= "Database Tables Missing.
Database tables are missing. This means that MySQL is either not running, WPMU was not installed properly, or someone deleted {$wpdb->site}. You really should look at your database now.
"; } else { $msg .= 'Could Not Find Blog!
'; $msg .= "Searched for " . $domain . $path . " in " . DB_NAME . "::" . $wpdb->blogs . " table. Is that right?
"; } $msg .= "
\n

What do I do now?

"; $msg .= "Read the bug report page. Some of the guidelines there may help you figure out what went wrong.
"; $msg .= "If you're still stuck with this message, then check that your database contains the following tables:"; $msg .= "If you suspect a problem please report it to the support forums but you must include the information asked for in the WPMU bug reporting guidelines!

"; if( is_file( 'release-info.txt' ) ) { $msg .= 'Your bug report must include the following text: "'; $info = file( 'release-info.txt' ); $msg .= $info[ 4 ] . '"'; } die( "

Fatal Error

" . $msg ); } } ?> blogs/license.txt0000644000000000000000000003542711077635520013066 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS blogs/wp-settings.php0000644000000000000000000004527411077635520013701 0ustar rootroot $v ) if ( !in_array($k, $noUnset) && isset($GLOBALS[$k]) ) { $GLOBALS[$k] = NULL; unset($GLOBALS[$k]); } } wp_unregister_GLOBALS(); unset( $wp_filter, $cache_lastcommentmodified, $cache_lastpostdate ); /** * The $blog_id global, which you can change in the config allows you to create a simple * multiple blog installation using just one WordPress and changing $blog_id around. * * @global int $blog_id * @since 2.0.0 */ if ( ! isset($blog_id) ) $blog_id = 0; // Fix for IIS, which doesn't set REQUEST_URI if ( empty( $_SERVER['REQUEST_URI'] ) ) { // IIS Mod-Rewrite if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) { $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_ORIGINAL_URL']; } // IIS Isapi_Rewrite else if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL']; } else { // Use ORIG_PATH_INFO if there is no PATH_INFO if ( !isset($_SERVER['PATH_INFO']) && isset($_SERVER['ORIG_PATH_INFO']) ) $_SERVER['PATH_INFO'] = $_SERVER['ORIG_PATH_INFO']; // Some IIS + PHP configurations puts the script-name in the path-info (No need to append it twice) if ( isset($_SERVER['PATH_INFO']) ) { if ( $_SERVER['PATH_INFO'] == $_SERVER['SCRIPT_NAME'] ) $_SERVER['REQUEST_URI'] = $_SERVER['PATH_INFO']; else $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO']; } // Append the query string if it exists and isn't null if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) { $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING']; } } } // Fix for PHP as CGI hosts that set SCRIPT_FILENAME to something ending in php.cgi for all requests if ( isset($_SERVER['SCRIPT_FILENAME']) && ( strpos($_SERVER['SCRIPT_FILENAME'], 'php.cgi') == strlen($_SERVER['SCRIPT_FILENAME']) - 7 ) ) $_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED']; // Fix for Dreamhost and other PHP as CGI hosts if (strpos($_SERVER['SCRIPT_NAME'], 'php.cgi') !== false) unset($_SERVER['PATH_INFO']); if ( version_compare( '4.3', phpversion(), '>' ) ) { die( sprintf( /*WP_I18N_OLD_PHP*/'Your server is running PHP version %s but WordPress requires at least 4.3.'/*/WP_I18N_OLD_PHP*/, phpversion() ) ); } if ( !defined('WP_CONTENT_DIR') ) define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // no trailing slash, full paths only - WP_CONTENT_URL is defined further down if ( !extension_loaded('mysql') && !file_exists(WP_CONTENT_DIR . '/db.php') ) die( /*WP_I18N_OLD_MYSQL*/'Your PHP installation appears to be missing the MySQL extension which is required by WordPress.'/*/WP_I18N_OLD_MYSQL*/ ); /** * timer_start() - PHP 4 standard microtime start capture * * @access private * @since 0.71 * @global int $timestart Seconds and Microseconds added together from when function is called * @return bool Always returns true */ function timer_start() { global $timestart; $mtime = explode(' ', microtime() ); $mtime = $mtime[1] + $mtime[0]; $timestart = $mtime; return true; } /** * timer_stop() - Return and/or display the time from the page start to when function is called. * * You can get the results and print them by doing: * * $nTimePageTookToExecute = timer_stop(); * echo $nTimePageTookToExecute; * * * Or instead, you can do: * * timer_stop(1); * * which will do what the above does. If you need the result, you can assign it to a variable, but * most cases, you only need to echo it. * * @since 0.71 * @global int $timestart Seconds and Microseconds added together from when timer_start() is called * @global int $timeend Seconds and Microseconds added together from when function is called * * @param int $display Use '0' or null to not echo anything and 1 to echo the total time * @param int $precision The amount of digits from the right of the decimal to display. Default is 3. * @return float The "second.microsecond" finished time calculation */ function timer_stop($display = 0, $precision = 3) { //if called like timer_stop(1), will echo $timetotal global $timestart, $timeend; $mtime = microtime(); $mtime = explode(' ',$mtime); $mtime = $mtime[1] + $mtime[0]; $timeend = $mtime; $timetotal = $timeend-$timestart; $r = ( function_exists('number_format_i18n') ) ? number_format_i18n($timetotal, $precision) : number_format($timetotal, $precision); if ( $display ) echo $r; return $r; } timer_start(); // Add define('WP_DEBUG',true); to wp-config.php to enable display of notices during development. if (defined('WP_DEBUG') and WP_DEBUG == true) { error_reporting(E_ALL); } else { error_reporting(E_ALL ^ E_NOTICE ^ E_USER_NOTICE); } // For an advanced caching plugin to use, static because you would only want one if ( defined('WP_CACHE') ) @include WP_CONTENT_DIR . '/advanced-cache.php'; /** * Stores the location of the WordPress directory of functions, classes, and core content. * * @since 1.0.0 */ define('WPINC', 'wp-includes'); if ( !defined('WP_LANG_DIR') ) { /** * Stores the location of the language directory. First looks for language folder in WP_CONTENT_DIR * and uses that folder if it exists. Or it uses the "languages" folder in WPINC. * * @since 2.1.0 */ if ( file_exists(WP_CONTENT_DIR . '/languages') && @is_dir(WP_CONTENT_DIR . '/languages') ) { define('WP_LANG_DIR', WP_CONTENT_DIR . '/languages'); // no leading slash, no trailing slash, full path, not relative to ABSPATH if (!defined('LANGDIR')) { // Old static relative path maintained for limited backwards compatibility - won't work in some cases define('LANGDIR', 'wp-content/languages'); } } else { define('WP_LANG_DIR', ABSPATH . WPINC . '/languages'); // no leading slash, no trailing slash, full path, not relative to ABSPATH if (!defined('LANGDIR')) { // Old relative path maintained for backwards compatibility define('LANGDIR', WPINC . '/languages'); } } } require (ABSPATH . WPINC . '/compat.php'); require (ABSPATH . WPINC . '/functions.php'); require (ABSPATH . WPINC . '/classes.php'); require_wp_db(); if ( !empty($wpdb->error) ) dead_db(); $prefix = $wpdb->set_prefix($table_prefix); // set up global tables if ( is_wp_error($prefix) ) wp_die(/*WP_I18N_BAD_PREFIX*/'ERROR: $table_prefix in wp-config.php can only contain numbers, letters, and underscores.'/*/WP_I18N_BAD_PREFIX*/); if ( file_exists(WP_CONTENT_DIR . '/object-cache.php') ) require_once (WP_CONTENT_DIR . '/object-cache.php'); else require_once (ABSPATH . WPINC . '/cache.php'); wp_cache_init(); if ( function_exists('wp_cache_add_global_groups') ) { wp_cache_add_global_groups(array ('users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss')); wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' )); } if( defined( 'SUNRISE' ) ) include_once( ABSPATH . 'wp-content/sunrise.php' ); require_once ( ABSPATH . 'wpmu-settings.php' ); $wpdb->blogid = $current_blog->blog_id; $wpdb->siteid = $current_blog->site_id; $wpdb->set_prefix($table_prefix); // set up blog tables $table_prefix = $table_prefix . $blog_id . '_'; // Fix empty PHP_SELF $PHP_SELF = $_SERVER['PHP_SELF']; if ( empty($PHP_SELF) || ( constant( 'VHOST' ) == 'no' && $current_blog->path != '/' ) ) $_SERVER['PHP_SELF'] = $PHP_SELF = preg_replace("/(\?.*)?$/",'',$_SERVER["REQUEST_URI"]); wp_cache_init(); // need to init cache again after blog_id is set if ( function_exists('wp_cache_add_global_groups') ) { // need to add these again. Yes, it's an ugly hack wp_cache_add_global_groups(array ('users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss')); wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' )); } if( !defined( "UPLOADS" ) ) define( "UPLOADS", "wp-content/blogs.dir/{$wpdb->blogid}/files/" ); require (ABSPATH . WPINC . '/plugin.php'); require (ABSPATH . WPINC . '/default-filters.php'); if( defined( "SHORTINIT" ) && constant( "SHORTINIT" ) == true ) // stop most of WP being loaded, we just want the basics return false; include_once(ABSPATH . WPINC . '/streams.php'); include_once(ABSPATH . WPINC . '/gettext.php'); require_once (ABSPATH . WPINC . '/l10n.php'); if ( !is_blog_installed() && !defined('WP_INSTALLING') ) { die( __( 'The blog you have requested is not installed properly. Please contact the system administrator.' ) ); // have to die here ~ Mark } require (ABSPATH . WPINC . '/formatting.php'); require (ABSPATH . WPINC . '/capabilities.php'); require (ABSPATH . WPINC . '/query.php'); require (ABSPATH . WPINC . '/theme.php'); require (ABSPATH . WPINC . '/user.php'); require (ABSPATH . WPINC . '/general-template.php'); require (ABSPATH . WPINC . '/link-template.php'); require (ABSPATH . WPINC . '/author-template.php'); require (ABSPATH . WPINC . '/post.php'); require (ABSPATH . WPINC . '/post-template.php'); require (ABSPATH . WPINC . '/category.php'); require (ABSPATH . WPINC . '/category-template.php'); require (ABSPATH . WPINC . '/comment.php'); require (ABSPATH . WPINC . '/comment-template.php'); require (ABSPATH . WPINC . '/rewrite.php'); require (ABSPATH . WPINC . '/feed.php'); require (ABSPATH . WPINC . '/bookmark.php'); require (ABSPATH . WPINC . '/bookmark-template.php'); require (ABSPATH . WPINC . '/kses.php'); require (ABSPATH . WPINC . '/cron.php'); require (ABSPATH . WPINC . '/version.php'); require (ABSPATH . WPINC . '/deprecated.php'); require (ABSPATH . WPINC . '/script-loader.php'); require (ABSPATH . WPINC . '/taxonomy.php'); require (ABSPATH . WPINC . '/update.php'); require (ABSPATH . WPINC . '/canonical.php'); require (ABSPATH . WPINC . '/shortcodes.php'); require (ABSPATH . WPINC . '/media.php'); if ( !defined('WP_CONTENT_URL') ) define( 'WP_CONTENT_URL', get_option('siteurl') . '/wp-content'); // full url - WP_CONTENT_DIR is defined further up require_once( ABSPATH . WPINC . '/wpmu-functions.php' ); require (ABSPATH . WPINC . '/wpmu-default-filters.php'); // WPmu Filters /** * Allows for the plugins directory to be moved from the default location. * * @since 2.6 */ if ( !defined('WP_PLUGIN_DIR') ) define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' ); // full path, no trailing slash if ( !defined('WP_PLUGIN_URL') ) define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' ); // full url, no trailing slash if ( !defined('PLUGINDIR') ) define( 'PLUGINDIR', 'wp-content/plugins' ); // Relative to ABSPATH. For back compat. if( !isset($current_site->site_name) ) $current_site->site_name = get_site_option('site_name'); if( $current_site->site_name == false ) $current_site->site_name = ucfirst( $current_site->domain ); // Used to guarantee unique hash cookies $cookiehash = ''; /** * Used to guarantee unique hash cookies * @since 1.5 */ define('COOKIEHASH', '' ); $wpdb->hide_errors(); if( defined( 'MUPLUGINDIR' ) == false ) define( 'MUPLUGINDIR', 'wp-content/mu-plugins' ); if( is_dir( ABSPATH . MUPLUGINDIR ) ) { if( $dh = opendir( ABSPATH . MUPLUGINDIR ) ) { while( ( $plugin = readdir( $dh ) ) !== false ) { if( substr( $plugin, -4 ) == '.php' ) { include_once( ABSPATH . MUPLUGINDIR . '/' . $plugin ); } } } } $wpdb->show_errors(); if ( '1' == $current_blog->deleted ) { header('HTTP/1.1 410 Gone'); graceful_fail(__('This user has elected to delete their account and the content is no longer available.')); } if ( '2' == $current_blog->deleted ) graceful_fail( sprintf( __( 'This blog has not been activated yet. If you are having problems activating your blog, please contact %1$s.' ), str_replace( '@', ' AT ', get_site_option( 'admin_email', "support@{$current_site->domain}" ) ) ) ); if( $current_blog->archived == '1' || $current_blog->spam == '1' ) { header('HTTP/1.1 410 Gone'); graceful_fail(__('This blog has been archived or suspended.')); } /** * Should be exactly the same as the default value of SECRET_KEY in wp-config-sample.php * @since 2.5 */ $wp_default_secret_key = 'put your unique phrase here'; if( defined( 'SECRET_KEY' ) ) $wp_default_secret_key = SECRET_KEY; /** * It is possible to define this in wp-config.php * @since 2.0.0 */ if ( !defined('USER_COOKIE') ) define('USER_COOKIE', 'wordpressuser_' . COOKIEHASH); /** * It is possible to define this in wp-config.php * @since 2.0.0 */ if ( !defined('PASS_COOKIE') ) define('PASS_COOKIE', 'wordpresspass_' . COOKIEHASH); /** * It is possible to define this in wp-config.php * @since 2.5 */ if ( !defined('AUTH_COOKIE') ) define('AUTH_COOKIE', 'wordpress_' . COOKIEHASH); /** * It is possible to define this in wp-config.php * @since 2.6 */ if ( !defined('SECURE_AUTH_COOKIE') ) define('SECURE_AUTH_COOKIE', 'wordpress_sec_' . COOKIEHASH); /** * It is possible to define this in wp-config.php * @since 2.6 */ if ( !defined('LOGGED_IN_COOKIE') ) define('LOGGED_IN_COOKIE', 'wordpress_logged_in_' . COOKIEHASH); /** * It is possible to define this in wp-config.php * @since 2.3.0 */ if ( !defined('TEST_COOKIE') ) define('TEST_COOKIE', 'wordpress_test_cookie'); /** * It is possible to define this in wp-config.php * @since 1.2.0 */ if ( !defined('COOKIEPATH') ) define('COOKIEPATH', $current_site->path ); /** * It is possible to define this in wp-config.php * @since 1.5.0 */ if ( !defined('SITECOOKIEPATH') ) define('SITECOOKIEPATH', $current_site->path ); /** * It is possible to define this in wp-config.php * @since 2.6 */ if ( !defined('ADMIN_COOKIE_PATH') ) { if( constant( 'VHOST' ) == 'no' ) { define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH ); } else { define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH . 'wp-admin' ); } } /** * It is possible to define this in wp-config.php * @since 2.6 */ if ( !defined('PLUGINS_COOKIE_PATH') ) define( 'PLUGINS_COOKIE_PATH', preg_replace('|https?://[^/]+|i', '', WP_PLUGIN_URL) ); /** * It is possible to define this in wp-config.php * @since 2.0.0 */ if ( !defined('COOKIE_DOMAIN') ) define('COOKIE_DOMAIN', '.' . $current_site->domain); /** * It is possible to define this in wp-config.php * @since 2.6 */ if ( !defined('FORCE_SSL_ADMIN') ) define('FORCE_SSL_ADMIN', false); force_ssl_admin(FORCE_SSL_ADMIN); /** * It is possible to define this in wp-config.php * @since 2.6 */ if ( !defined('FORCE_SSL_LOGIN') ) define('FORCE_SSL_LOGIN', false); force_ssl_login(FORCE_SSL_LOGIN); /** * It is possible to define this in wp-config.php * @since 2.5.0 */ if ( !defined( 'AUTOSAVE_INTERVAL' ) ) define( 'AUTOSAVE_INTERVAL', 60 ); require (ABSPATH . WPINC . '/vars.php'); if ( get_option('active_plugins') ) { $current_plugins = get_option('active_plugins'); if ( is_array($current_plugins) ) { foreach ($current_plugins as $plugin) { if ( '' != $plugin && 0 == validate_file($plugin) && file_exists(WP_PLUGIN_DIR . '/' . $plugin) ) include_once(WP_PLUGIN_DIR . '/' . $plugin); } } } require (ABSPATH . WPINC . '/pluggable.php'); /* * In most cases the default internal encoding is latin1, which is of no use, * since we want to use the mb_ functions for utf-8 strings */ if (function_exists('mb_internal_encoding')) { if (!@mb_internal_encoding(get_option('blog_charset'))) mb_internal_encoding('UTF-8'); } if ( defined('WP_CACHE') && function_exists('wp_cache_postload') ) wp_cache_postload(); do_action('plugins_loaded'); $default_constants = array( 'WP_POST_REVISIONS' => true ); foreach ( $default_constants as $c => $v ) @define( $c, $v ); // will fail if the constant is already defined unset($default_constants, $c, $v); // If already slashed, strip. if ( get_magic_quotes_gpc() ) { $_GET = stripslashes_deep($_GET ); $_POST = stripslashes_deep($_POST ); $_COOKIE = stripslashes_deep($_COOKIE); } // Escape with wpdb. $_GET = add_magic_quotes($_GET ); $_POST = add_magic_quotes($_POST ); $_COOKIE = add_magic_quotes($_COOKIE); $_SERVER = add_magic_quotes($_SERVER); do_action('sanitize_comment_cookies'); /** * WordPress Query object * @global object $wp_the_query * @since 2.0.0 */ $wp_the_query =& new WP_Query(); /** * Holds the reference to @see $wp_the_query * Use this global for WordPress queries * @global object $wp_query * @since 1.5.0 */ $wp_query =& $wp_the_query; /** * Holds the WordPress Rewrite object for creating pretty URLs * @global object $wp_rewrite * @since 1.5.0 */ $wp_rewrite =& new WP_Rewrite(); /** * WordPress Object * @global object $wp * @since 2.0.0 */ $wp =& new WP(); do_action('setup_theme'); /** * Web Path to the current active template directory * @since 1.5 */ define('TEMPLATEPATH', get_template_directory()); /** * Web Path to the current active template stylesheet directory * @since 2.1 */ define('STYLESHEETPATH', get_stylesheet_directory()); // Load the default text localization domain. load_default_textdomain(); /** * The locale of the blog * @since 1.5.0 */ $locale = get_locale(); $locale_file = WP_LANG_DIR . "/$locale.php"; if ( is_readable($locale_file) ) require_once($locale_file); // Pull in locale data after loading text domain. require_once(ABSPATH . WPINC . '/locale.php'); /** * WordPress Locale object for loading locale domain date and various strings. * @global object $wp_locale * @since 2.1.0 */ $wp_locale =& new WP_Locale(); // Load functions for active theme. if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists(STYLESHEETPATH . '/functions.php') ) include(STYLESHEETPATH . '/functions.php'); if ( file_exists(TEMPLATEPATH . '/functions.php') ) include(TEMPLATEPATH . '/functions.php'); /** * shutdown_action_hook() - Runs just before PHP shuts down execution. * * @access private * @since 1.2 */ function shutdown_action_hook() { do_action('shutdown'); wp_cache_close(); } register_shutdown_function('shutdown_action_hook'); $wp->init(); // Sets up current user. // Everything is loaded and initialized. do_action('init'); ?> blogs/wp-atom.php0000644000000000000000000000105411077635520012765 0ustar rootroot blogs/README.txt0000644000000000000000000001672411077635520012400 0ustar rootrootWordPress Multi User -------------------- WordPress MU is a multi user version of WordPress. If you're not comfortable editing PHP code, taking care of a complex webserver and database system and being pro-active about following developments of this project then run, don't walk, to http://wordpress.com/ and sign yourself and your friends up to free blogs. It's easier in the long run and you'll save yourself a lot of pain and angst. Apache ====== Apache must be configured so that mod_rewrite works. Here are instructions for Apache 2. Apache 1.3 is very similar. 1. Make sure a line like the following appears in your httpd.conf LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so 2. In the directive of your virtual host, look for this line "AllowOverride None" and change it to "AllowOverride FileInfo Options" 3. In the section of the config file for your host there will be a line defining the hostname. You need to add the following if you want virtual hosts to work properly: "ServerAlias *.domain.tld" Replace domain.tld with whatever your one is, and remove the quotes. DNS === If you want to host blogs of the form http://blog.domain.tld/ where domain.tld is the domain name of your machine then you must add a wildcard record to your DNS records. This usually means adding a "*" hostname record pointing at your webserver in your DNS configuration tool. Matt has a more detailed explanation: http://ma.tt/2003/10/10/wildcard-dns-and-sub-domains/ PHP === 1. Don't display error messages to the browser. This is almost always turned off but sometimes when you're testing you turn this on and forget to reset it. 2. If your PHP is compiled with memory limit checks, the default is 8MB which is much too small. You should increase this to at least 32MB or 64MB to avoid PHP out of memory errors. Look for "memory_limit" in your php.ini file. 3. GLOBAL variables must be turned off. This is one of the first things any security aware admin will do. These days the default is for it to be off! The easiest way of configuring it is via the .htaccess file that is created during the install. If you haven't installed WPMU yet then edit the file htaccess.dist in this directory and add these two lines at the top: php_flag register_globals 0 php_flag display_errors 0 This is NOT included in that file by default because it doesn't work on all machines. If it doesn't work on your machine, you'll get a cryptic "500 internal error" after you install WPMU. To remove the offending lines just edit the file ".htaccess" in your install directory and you'll see them at the top. Delete and save the file again. Read here for how to enable this: http://ie.php.net/configuration.changes If you don't want to edit your .htaccess file then you need to change your php.ini. It's beyond the scope of this README to know exactly where it is on your machine, but if you're on a shared hosted server you probably don't have access to it as it requires root or administrator privileges to change. If you do have root access, try "locate php.ini" or check in: /etc/php4/apache2/php.ini /usr/local/lib/php.ini Once you have opened your php.ini, look for the sections related to register_globals and display_errors. Make sure both are Off like so: display_errors = Off register_globals = Off You'll have to restart Apache after you modify your php.ini for the settings to be updated. 4. If you want to restrict blog signups, set the restrict domain email setting in the admin. Install ======= 1. Download and unzip the WordPress MU package, if you haven't already. The unzipped files will be created in a directory named "wordpressmu" followed by a version number. 2. Create a database for WordPress MU on your web server, as well as a MySQL user who has all privileges for accessing and modifying it. 3. Place the WordPress MU files in the desired location on your web server: * If you want to integrate WordPress MU into the root of your domain (e.g. http://example.com/), move or upload all the files and directories of the unzipped WordPress MU directory into the root directory of your web server. * If you want to have your WordPress MU installation in its own subdirectory on your web site (e.g. http://example.com/blogs/), rename the directory wordpressmu to the name you'd like the subdirectory to have and move or upload it to your web server. For example if you want the WordPress MU installation in a subdirectory called "blog", you should rename the directory called "wordpressmu" to "blogs" and upload it to the root directory of your web server. 4. Make sure your install directory and the wp-contents directory are writeable by the webserver. 5. Run the WordPress MU installation script by accessing index.php in your favorite web browser. * If you installed WordPress MU in the root directory, you should visit: http://example.com/index.php * If you installed WordPress MU in its own subdirectory called blogs, for example, you should visit: http://example.com/blogs/index.php (Adapted from http://codex.wordpress.org/Installing_WordPress) If you're upgrading, skip to the end of this document. ERROR LOGGING ============= If you are developing a site based on WPMU it is recommended that you turn on PHP error logging. Look in your php.ini for the section marked "Error handling and logging" where you can configure it. Mysql database errors are logged to the PHP error log if enabled or it can also send error reports to a file of your choice. After installing, edit wp-config.php and define a constant, "ERRORLOGFILE", pointing at your MySQL error log. This file must be writeable by your webserver. Please don't log to a file visible by your webserver or people may figure out they can download it. Example definition: define( "ERRORLOGFILE", "/tmp/mysql.log" ); UPGRADING ========= Please see this page for instructions on upgrading your install: http://codex.wordpress.org/Upgrading_WPMU PERFORMANCE =========== WordPress MU has a caching framework which allows third party developers to create cache engines that improve performance. There are two types of caching plugins available for WordPress. 1. Object Cache. These work by storing commonly accessed data in a rapid access storage container such as RAM or directly on the filesystem. To install these plugins copy them into your wp-content folder. Memcached: http://dev.wp-plugins.org/browser/memcached/trunk/ Filesystem: http://neosmart.net/dl.php?id=14 Xcache: http://neosmart.net/dl.php?id=12 eAccelerator: http://neosmart.net/dl.php?id=13 2. Full page cache. These work by storing complete web pages and are generally faster than object cache plugins at the expense of less flexibility. On a busy WordPress MU site these may in fact slow down your server due to limitations in how the cached files are stored. Clearing out the cached files on a regular basis will alleviate this problem. YMMV. WP Super Cache: http://ocaoimh.ie/wp-super-cache/ Support Forum and Bug Reports ============================= Please read http://codex.wordpress.org/Debugging_WPMU before asking any questions. Without all the information required there we'll just ask for it anyway or worse, your request will be ignored. http://mu.wordpress.org/forums/ Trac is our bug tracking system. Again, please read the above link before submitting a bug report. http://trac.mu.wordpress.org/report/1 You can login to both sites using your wordpress.org username and password. http://mu.wordpress.org/ blogs/wp-includes/0000755000000000000000000000000011077645606013130 5ustar rootrootblogs/wp-includes/kses.php0000644000000000000000000007555011077635520014614 0ustar rootroot * * @package External * @subpackage KSES * * @internal * *** CONTACT INFORMATION *** * E-mail: metaur at users dot sourceforge dot net * Web page: http://sourceforge.net/projects/kses * Paper mail: Ulf Harnhammar * Ymergatan 17 C * 753 25 Uppsala * SWEDEN * * [kses strips evil scripts!] */ /** * You can override this in your my-hacks.php file * You can also override this in a plugin file. The * my-hacks.php is deprecated in its usage. * * @since 1.2.0 */ if (!defined('CUSTOM_TAGS')) define('CUSTOM_TAGS', false); if (!CUSTOM_TAGS) { /** * Kses global for default allowable HTML tags * * Can be override by using CUSTOM_TAGS constant * @global array $allowedposttags * @since 2.0.0 */ $allowedposttags = array( 'address' => array(), 'a' => array( 'class' => array (), 'href' => array (), 'id' => array (), 'title' => array (), 'rel' => array (), 'rev' => array (), 'name' => array (), 'target' => array()), 'abbr' => array( 'class' => array (), 'title' => array ()), 'acronym' => array( 'title' => array ()), 'b' => array(), 'big' => array(), 'blockquote' => array( 'id' => array (), 'cite' => array (), 'class' => array(), 'lang' => array(), 'xml:lang' => array()), 'br' => array ( 'class' => array ()), 'button' => array( 'disabled' => array (), 'name' => array (), 'type' => array (), 'value' => array ()), 'caption' => array( 'align' => array (), 'class' => array ()), 'cite' => array ( 'class' => array(), 'dir' => array(), 'lang' => array(), 'title' => array ()), 'code' => array ( 'style' => array()), 'col' => array( 'align' => array (), 'char' => array (), 'charoff' => array (), 'span' => array (), 'dir' => array(), 'style' => array (), 'valign' => array (), 'width' => array ()), 'del' => array( 'datetime' => array ()), 'dd' => array(), 'div' => array( 'align' => array (), 'class' => array (), 'dir' => array (), 'id' => array (), 'lang' => array(), 'style' => array (), 'xml:lang' => array()), 'dl' => array(), 'dt' => array(), 'em' => array(), 'fieldset' => array(), 'font' => array( 'color' => array (), 'face' => array (), 'size' => array ()), 'form' => array( 'action' => array (), 'accept' => array (), 'accept-charset' => array (), 'enctype' => array (), 'method' => array (), 'name' => array (), 'target' => array ()), 'h1' => array( 'align' => array (), 'style' => array (), 'class' => array ()), 'h2' => array( 'align' => array (), 'style' => array (), 'class' => array ()), 'h3' => array( 'align' => array (), 'style' => array (), 'class' => array ()), 'h4' => array( 'align' => array (), 'style' => array (), 'class' => array ()), 'h5' => array( 'align' => array (), 'style' => array (), 'class' => array ()), 'h6' => array( 'align' => array (), 'style' => array (), 'class' => array ()), 'hr' => array( 'align' => array (), 'class' => array (), 'noshade' => array (), 'size' => array (), 'width' => array ()), 'i' => array(), 'img' => array( 'alt' => array (), 'align' => array (), 'border' => array (), 'class' => array (), 'height' => array (), 'hspace' => array (), 'longdesc' => array (), 'vspace' => array (), 'src' => array (), 'style' => array (), 'width' => array ()), 'ins' => array( 'datetime' => array (), 'cite' => array ()), 'kbd' => array(), 'label' => array( 'for' => array ()), 'legend' => array( 'align' => array ()), 'li' => array ( 'align' => array (), 'class' => array ()), 'p' => array( 'class' => array (), 'align' => array (), 'dir' => array(), 'lang' => array(), 'style' => array (), 'xml:lang' => array()), 'pre' => array( 'style' => array(), 'width' => array ()), 'q' => array( 'cite' => array ()), 's' => array(), 'span' => array ( 'class' => array (), 'dir' => array (), 'align' => array (), 'lang' => array (), 'style' => array (), 'title' => array (), 'xml:lang' => array()), 'strike' => array(), 'strong' => array(), 'sub' => array(), 'sup' => array(), 'table' => array( 'align' => array (), 'bgcolor' => array (), 'border' => array (), 'cellpadding' => array (), 'cellspacing' => array (), 'class' => array (), 'dir' => array(), 'id' => array(), 'rules' => array (), 'style' => array (), 'summary' => array (), 'width' => array ()), 'tbody' => array( 'align' => array (), 'char' => array (), 'charoff' => array (), 'valign' => array ()), 'td' => array( 'abbr' => array (), 'align' => array (), 'axis' => array (), 'bgcolor' => array (), 'char' => array (), 'charoff' => array (), 'class' => array (), 'colspan' => array (), 'dir' => array(), 'headers' => array (), 'height' => array (), 'nowrap' => array (), 'rowspan' => array (), 'scope' => array (), 'style' => array (), 'valign' => array (), 'width' => array ()), 'textarea' => array( 'cols' => array (), 'rows' => array (), 'disabled' => array (), 'name' => array (), 'readonly' => array ()), 'tfoot' => array( 'align' => array (), 'char' => array (), 'class' => array (), 'charoff' => array (), 'valign' => array ()), 'th' => array( 'abbr' => array (), 'align' => array (), 'axis' => array (), 'bgcolor' => array (), 'char' => array (), 'charoff' => array (), 'class' => array (), 'colspan' => array (), 'headers' => array (), 'height' => array (), 'nowrap' => array (), 'rowspan' => array (), 'scope' => array (), 'valign' => array (), 'width' => array ()), 'thead' => array( 'align' => array (), 'char' => array (), 'charoff' => array (), 'class' => array (), 'valign' => array ()), 'title' => array(), 'tr' => array( 'align' => array (), 'bgcolor' => array (), 'char' => array (), 'charoff' => array (), 'class' => array (), 'style' => array (), 'valign' => array ()), 'tt' => array(), 'u' => array(), 'ul' => array ( 'class' => array (), 'style' => array (), 'type' => array ()), 'ol' => array ( 'class' => array (), 'start' => array (), 'style' => array (), 'type' => array ()), 'var' => array ()); /** * Kses allowed HTML elements * * @global array $allowedtags * @since 1.0.0 */ $allowedtags = array( 'a' => array( 'href' => array (), 'title' => array ()), 'abbr' => array( 'title' => array ()), 'acronym' => array( 'title' => array ()), 'b' => array(), 'blockquote' => array( 'cite' => array ()), // 'br' => array(), 'cite' => array (), 'code' => array(), 'del' => array( 'datetime' => array ()), // 'dd' => array(), // 'dl' => array(), // 'dt' => array(), 'em' => array (), 'i' => array (), // 'ins' => array('datetime' => array(), 'cite' => array()), // 'li' => array(), // 'ol' => array(), // 'p' => array(), 'q' => array( 'cite' => array ()), 'strike' => array(), 'strong' => array(), // 'sub' => array(), // 'sup' => array(), // 'u' => array(), // 'ul' => array(), ); } /** * wp_kses() - Filters content and keeps only allowable HTML elements. * * This function makes sure that only the allowed HTML element names, * attribute names and attribute values plus only sane HTML entities * will occur in $string. You have to remove any slashes from PHP's * magic quotes before you call this function. * * The default allowed protocols are 'http', 'https', 'ftp', 'mailto', * 'news', 'irc', 'gopher', 'nntp', 'feed', and finally 'telnet. This * covers all common link protocols, except for 'javascript' which * should not be allowed for untrusted users. * * @since 1.0.0 * * @param string $string Content to filter through kses * @param array $allowed_html List of allowed HTML elements * @param array $allowed_protocols Optional. Allowed protocol in links. * @return string Filtered content with only allowed HTML elements */ function wp_kses($string, $allowed_html, $allowed_protocols = array ('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet')) { $string = wp_kses_no_null($string); $string = wp_kses_js_entities($string); $string = wp_kses_normalize_entities($string); $allowed_html_fixed = wp_kses_array_lc($allowed_html); $string = wp_kses_hook($string, $allowed_html_fixed, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook return wp_kses_split($string, $allowed_html_fixed, $allowed_protocols); } /** * wp_kses_hook() - You add any kses hooks here. * * There is currently only one kses WordPress hook and it is * called here. All parameters are passed to the hooks and * expected to recieve a string. * * @since 1.0.0 * * @param string $string Content to filter through kses * @param array $allowed_html List of allowed HTML elements * @param array $allowed_protocols Allowed protocol in links * @return string Filtered content through 'pre_kses' hook */ function wp_kses_hook($string, $allowed_html, $allowed_protocols) { $string = apply_filters('pre_kses', $string, $allowed_html, $allowed_protocols); return $string; } /** * wp_kses_version() - This function returns kses' version number. * * @since 1.0.0 * * @return string Version Number */ function wp_kses_version() { return '0.2.2'; } /** * wp_kses_split() - Searches for HTML tags, no matter how malformed * * It also matches stray ">" characters. * * @since 1.0.0 * * @param string $string Content to filter * @param array $allowed_html Allowed HTML elements * @param array $allowed_protocols Allowed protocols to keep * @return string Content with fixed HTML tags */ function wp_kses_split($string, $allowed_html, $allowed_protocols) { return preg_replace('%((|$))|(<[^>]*(>|$)|>))%e', "wp_kses_split2('\\1', \$allowed_html, ".'$allowed_protocols)', $string); } /** * wp_kses_split2() - Callback for wp_kses_split for fixing malformed HTML tags * * This function does a lot of work. It rejects some very malformed things * like <:::>. It returns an empty string, if the element isn't allowed (look * ma, no strip_tags()!). Otherwise it splits the tag into an element and an * attribute list. * * After the tag is split into an element and an attribute list, it is run * through another filter which will remove illegal attributes and once * that is completed, will be returned. * * @since 1.0.0 * @uses wp_kses_attr() * * @param string $string Content to filter * @param array $allowed_html Allowed HTML elements * @param array $allowed_protocols Allowed protocols to keep * @return string Fixed HTML element */ function wp_kses_split2($string, $allowed_html, $allowed_protocols) { $string = wp_kses_stripslashes($string); if (substr($string, 0, 1) != '<') return '>'; # It matched a ">" character if (preg_match('%^)?$%', $string, $matches)) { $string = str_replace(array(''), '', $matches[1]); while ( $string != $newstring = wp_kses($string, $allowed_html, $allowed_protocols) ) $string = $newstring; if ( $string == '' ) return ''; // prevent multiple dashes in comments $string = preg_replace('/--+/', '-', $string); // prevent three dashes closing a comment $string = preg_replace('/-$/', '', $string); return ""; } # Allow HTML comments if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches)) return ''; # It's seriously malformed $slash = trim($matches[1]); $elem = $matches[2]; $attrlist = $matches[3]; if (!@isset($allowed_html[strtolower($elem)])) return ''; # They are using a not allowed HTML element if ($slash != '') return "<$slash$elem>"; # No attributes are allowed for closing elements return wp_kses_attr("$slash$elem", $attrlist, $allowed_html, $allowed_protocols); } /** * wp_kses_attr() - Removes all attributes, if none are allowed for this element * * If some are allowed it calls wp_kses_hair() to split them further, and then * it builds up new HTML code from the data that kses_hair() returns. It also * removes "<" and ">" characters, if there are any left. One more thing it * does is to check if the tag has a closing XHTML slash, and if it does, it * puts one in the returned code as well. * * @since 1.0.0 * * @param string $element HTML element/tag * @param string $attr HTML attributes from HTML element to closing HTML element tag * @param array $allowed_html Allowed HTML elements * @param array $allowed_protocols Allowed protocols to keep * @return string Sanitized HTML element */ function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { # Is there a closing XHTML slash at the end of the attributes? $xhtml_slash = ''; if (preg_match('%\s/\s*$%', $attr)) $xhtml_slash = ' /'; # Are any attributes allowed at all for this element? if (@ count($allowed_html[strtolower($element)]) == 0) return "<$element$xhtml_slash>"; # Split it $attrarr = wp_kses_hair($attr, $allowed_protocols); # Go through $attrarr, and save the allowed attributes for this element # in $attr2 $attr2 = ''; foreach ($attrarr as $arreach) { if (!@ isset ($allowed_html[strtolower($element)][strtolower($arreach['name'])])) continue; # the attribute is not allowed $current = $allowed_html[strtolower($element)][strtolower($arreach['name'])]; if ($current == '') continue; # the attribute is not allowed if (!is_array($current)) $attr2 .= ' '.$arreach['whole']; # there are no checks else { # there are some checks $ok = true; foreach ($current as $currkey => $currval) if (!wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval)) { $ok = false; break; } if ( $arreach['name'] == 'style' ) { $orig_value = $arreach['value']; $value = safecss_filter_attr($orig_value, $element); if ( empty($value) ) continue; $arreach['value'] = $value; $arreach['whole'] = str_replace($orig_value, $value, $arreach['whole']); } if ($ok) $attr2 .= ' '.$arreach['whole']; # it passed them } # if !is_array($current) } # foreach # Remove any "<" or ">" characters $attr2 = preg_replace('/[<>]/', '', $attr2); return "<$element$attr2$xhtml_slash>"; } /** * wp_kses_hair() - Builds an attribute list from string containing attributes. * * This function does a lot of work. It parses an attribute list into an array * with attribute data, and tries to do the right thing even if it gets weird * input. It will add quotes around attribute values that don't have any quotes * or apostrophes around them, to make it easier to produce HTML code that will * conform to W3C's HTML specification. It will also remove bad URL protocols * from attribute values. It also reduces duplicate attributes by using the * attribute defined first (foo='bar' foo='baz' will result in foo='bar'). * * @since 1.0.0 * * @param string $attr Attribute list from HTML element to closing HTML element tag * @param array $allowed_protocols Allowed protocols to keep * @return array List of attributes after parsing */ function wp_kses_hair($attr, $allowed_protocols) { $attrarr = array (); $mode = 0; $attrname = ''; # Loop through the whole attribute list while (strlen($attr) != 0) { $working = 0; # Was the last operation successful? switch ($mode) { case 0 : # attribute name, href for instance if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) { $attrname = $match[1]; $working = $mode = 1; $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr); } break; case 1 : # equals sign or valueless ("selected") if (preg_match('/^\s*=\s*/', $attr)) # equals sign { $working = 1; $mode = 2; $attr = preg_replace('/^\s*=\s*/', '', $attr); break; } if (preg_match('/^\s+/', $attr)) # valueless { $working = 1; $mode = 0; if(FALSE === array_key_exists($attrname, $attrarr)) { $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); } $attr = preg_replace('/^\s+/', '', $attr); } break; case 2 : # attribute value, a URL after href= for instance if (preg_match('/^"([^"]*)"(\s+|$)/', $attr, $match)) # "value" { $thisval = ($attrname=='style') ? $match[1] : wp_kses_bad_protocol($match[1], $allowed_protocols); if(FALSE === array_key_exists($attrname, $attrarr)) { $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); } $working = 1; $mode = 0; $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); break; } if (preg_match("/^'([^']*)'(\s+|$)/", $attr, $match)) # 'value' { $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); if(FALSE === array_key_exists($attrname, $attrarr)) { $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n'); } $working = 1; $mode = 0; $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); break; } if (preg_match("%^([^\s\"']+)(\s+|$)%", $attr, $match)) # value { $thisval = wp_kses_bad_protocol($match[1], $allowed_protocols); if(FALSE === array_key_exists($attrname, $attrarr)) { $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); } # We add quotes to conform to W3C's HTML spec. $working = 1; $mode = 0; $attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr); } break; } # switch if ($working == 0) # not well formed, remove and try again { $attr = wp_kses_html_error($attr); $mode = 0; } } # while if ($mode == 1 && FALSE === array_key_exists($attrname, $attrarr)) # special case, for when the attribute list ends with a valueless # attribute like "selected" $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); return $attrarr; } /** * wp_kses_check_attr_val() - Performs different checks for attribute values. * * The currently implemented checks are "maxlen", "minlen", "maxval", "minval" * and "valueless" with even more checks to come soon. * * @since 1.0.0 * * @param string $value Attribute value * @param string $vless Whether the value is valueless or not. Use 'y' or 'n' * @param string $checkname What $checkvalue is checking for. * @param mixed $checkvalue What constraint the value should pass * @return bool Whether check passes (true) or not (false) */ function wp_kses_check_attr_val($value, $vless, $checkname, $checkvalue) { $ok = true; switch (strtolower($checkname)) { case 'maxlen' : # The maxlen check makes sure that the attribute value has a length not # greater than the given value. This can be used to avoid Buffer Overflows # in WWW clients and various Internet servers. if (strlen($value) > $checkvalue) $ok = false; break; case 'minlen' : # The minlen check makes sure that the attribute value has a length not # smaller than the given value. if (strlen($value) < $checkvalue) $ok = false; break; case 'maxval' : # The maxval check does two things: it checks that the attribute value is # an integer from 0 and up, without an excessive amount of zeroes or # whitespace (to avoid Buffer Overflows). It also checks that the attribute # value is not greater than the given value. # This check can be used to avoid Denial of Service attacks. if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value)) $ok = false; if ($value > $checkvalue) $ok = false; break; case 'minval' : # The minval check checks that the attribute value is a positive integer, # and that it is not smaller than the given value. if (!preg_match('/^\s{0,6}[0-9]{1,6}\s{0,6}$/', $value)) $ok = false; if ($value < $checkvalue) $ok = false; break; case 'valueless' : # The valueless check checks if the attribute has a value # (like ) or not (
  • " . $details['postcount'] . " $url
  • "; } } } return array_slice( $most_active, 0, $num ); } function get_blog_list( $start = 0, $num = 10, $deprecated = '' ) { global $wpdb; $blogs = get_site_option( "blog_list" ); $update = false; if( is_array( $blogs ) ) { if( ( $blogs['time'] + 60 ) < time() ) { // cache for 60 seconds. $update = true; } } else { $update = true; } if( $update == true ) { unset( $blogs ); $blogs = $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid), ARRAY_A ); foreach ( (array) $blogs as $details ) { $blog_list[ $details['blog_id'] ] = $details; $blog_list[ $details['blog_id'] ]['postcount'] = $wpdb->get_var( "SELECT COUNT(ID) FROM " . $wpdb->base_prefix . $details['blog_id'] . "_posts WHERE post_status='publish' AND post_type='post'" ); } unset( $blogs ); $blogs = $blog_list; update_site_option( "blog_list", $blogs ); } if( $num == 'all' ) { return array_slice( $blogs, $start, count( $blogs ) ); } else { return array_slice( $blogs, $start, $num ); } } function get_blog_count( $id = 0 ) { global $wpdb; if( $id == 0 ) $id = $wpdb->siteid; $count_ts = get_site_option( "blog_count_ts" ); if( time() - $count_ts > 3600 ) { $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $id) ); update_site_option( "blog_count", $count ); update_site_option( "blog_count_ts", time() ); } $count = get_site_option( "blog_count" ); return $count; } function get_blog_post( $blog_id, $post_id ) { global $wpdb; $key = $blog_id."-".$post_id."-blog_post"; $post = wp_cache_get( $key, "site-options" ); if( $post == false ) { $post = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}{$blog_id}_posts WHERE ID = %d", $post_id) ); wp_cache_add( $key, $post, "site-options", 120 ); } return $post; } function add_user_to_blog( $blog_id, $user_id, $role ) { switch_to_blog($blog_id); $user = new WP_User($user_id); if ( empty($user) ) return new WP_Error('user_does_not_exist', __('That user does not exist.')); if ( !get_usermeta($user_id, 'primary_blog') ) { update_usermeta($user_id, 'primary_blog', $blog_id); $details = get_blog_details($blog_id); update_usermeta($user_id, 'source_domain', $details->domain); } $user->set_role($role); do_action('add_user_to_blog', $user_id, $role, $blog_id); wp_cache_delete( $user_id, 'users' ); restore_current_blog(); return true; } function remove_user_from_blog($user_id, $blog_id = '') { switch_to_blog($blog_id); $user_id = (int) $user_id; do_action('remove_user_from_blog', $user_id, $blog_id); // If being removed from the primary blog, set a new primary if the user is assigned // to multiple blogs. $primary_blog = get_usermeta($user_id, 'primary_blog'); if ( $primary_blog == $blog_id ) { $new_id = ''; $new_domain = ''; $blogs = get_blogs_of_user($user_id); foreach ( (array) $blogs as $blog ) { if ( $blog->userblog_id == $blog_id ) continue; $new_id = $blog->userblog_id; $new_domain = $blog->domain; break; } update_usermeta($user_id, 'primary_blog', $new_id); update_usermeta($user_id, 'source_domain', $new_domain); } wp_revoke_user($user_id); $blogs = get_blogs_of_user($user_id); if ( count($blogs) == 0 ) { update_usermeta($user_id, 'primary_blog', ''); update_usermeta($user_id, 'source_domain', ''); } restore_current_blog(); } function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) { $domain = addslashes( $domain ); $weblog_title = addslashes( $weblog_title ); if( empty($path) ) $path = '/'; // Check if the domain has been used already. We should return an error message. if ( domain_exists($domain, $path, $site_id) ) return __('error: Blog URL already taken.'); // Need to backup wpdb table names, and create a new wp_blogs entry for new blog. // Need to get blog_id from wp_blogs, and create new table names. // Must restore table names at the end of function. if ( ! $blog_id = insert_blog($domain, $path, $site_id) ) return __('error: problem creating blog entry'); switch_to_blog($blog_id); install_blog($blog_id); restore_current_blog(); return $blog_id; } function get_blog_permalink( $blog_id, $post_id ) { $key = "{$blog_id}-{$post_id}-blog_permalink"; $link = wp_cache_get( $key, 'site-options' ); if( $link == false ) { switch_to_blog( $blog_id ); $link = get_permalink( $post_id ); restore_current_blog(); wp_cache_add( $key, $link, "site-options", 30 ); } return $link; } // wpmu admin functions function wpmu_admin_do_redirect( $url = '' ) { $ref = ''; if ( isset( $_GET['ref'] ) ) $ref = $_GET['ref']; if ( isset( $_POST['ref'] ) ) $ref = $_POST['ref']; if( $ref ) { $ref = wpmu_admin_redirect_add_updated_param( $ref ); wp_redirect( $ref ); exit(); } if( empty( $_SERVER['HTTP_REFERER'] ) == false ) { wp_redirect( $_SERVER['HTTP_REFERER'] ); exit(); } $url = wpmu_admin_redirect_add_updated_param( $url ); if( isset( $_GET['redirect'] ) ) { if( substr( $_GET['redirect'], 0, 2 ) == 's_' ) { $url .= "&action=blogs&s=". wp_specialchars( substr( $_GET['redirect'], 2 ) ); } } elseif( isset( $_POST['redirect'] ) ) { $url = wpmu_admin_redirect_add_updated_param( $_POST['redirect'] ); } wp_redirect( $url ); exit(); } function wpmu_admin_redirect_add_updated_param( $url = '' ) { if( strpos( $url, 'updated=true' ) === false ) { if( strpos( $url, '?' ) === false ) { return $url . '?updated=true'; } else { return $url . '&updated=true'; } } return $url; } function wpmu_admin_redirect_url() { if( isset( $_GET['s'] ) ) { return "s_".$_GET['s']; } } function is_blog_user( $blog_id = 0 ) { global $current_user, $wpdb; if ( !$blog_id ) $blog_id = $wpdb->blogid; $cap_key = $wpdb->base_prefix . $blog_id . '_capabilities'; if ( is_array($current_user->$cap_key) && in_array(1, $current_user->$cap_key) ) return true; return false; } function validate_email( $email, $check_domain = true) { if (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.'@'. '[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'. '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $email)) { if ($check_domain && function_exists('checkdnsrr')) { list (, $domain) = explode('@', $email); if (checkdnsrr($domain.'.', 'MX') || checkdnsrr($domain.'.', 'A')) { return true; } return false; } return true; } return false; } function is_email_address_unsafe( $user_email ) { $banned_names = get_site_option( "banned_email_domains" ); if ( is_array( $banned_names ) && empty( $banned_names ) == false ) { $email_domain = strtolower( substr( $user_email, 1 + strpos( $user_email, '@' ) ) ); foreach( (array) $banned_names as $banned_domain ) { if( $banned_domain == '' ) continue; if ( strstr( $email_domain, $banned_domain ) || ( strstr( $banned_domain, '/' ) && preg_match( $banned_domain, $email_domain ) ) ) return true; } } return false; } function wpmu_validate_user_signup($user_name, $user_email) { global $wpdb; $errors = new WP_Error(); $user_name = preg_replace( "/\s+/", '', sanitize_user( $user_name, true ) ); $user_email = sanitize_email( $user_email ); if ( empty( $user_name ) ) $errors->add('user_name', __("Please enter a username")); $maybe = array(); preg_match( "/[a-z0-9]+/", $user_name, $maybe ); if( $user_name != $maybe[0] ) { $errors->add('user_name', __("Only lowercase letters and numbers allowed")); } $illegal_names = get_site_option( "illegal_names" ); if( is_array( $illegal_names ) == false ) { $illegal_names = array( "www", "web", "root", "admin", "main", "invite", "administrator" ); add_site_option( "illegal_names", $illegal_names ); } if( in_array( $user_name, $illegal_names ) == true ) { $errors->add('user_name', __("That username is not allowed")); } if( is_email_address_unsafe( $user_email ) ) $errors->add('user_email', __("You cannot use that email address to signup. We are having problems with them blocking some of our email. Please use another email provider.")); if( strlen( $user_name ) < 4 ) { $errors->add('user_name', __("Username must be at least 4 characters")); } if ( strpos( " " . $user_name, "_" ) != false ) $errors->add('user_name', __("Sorry, usernames may not contain the character '_'!")); // all numeric? $match = array(); preg_match( '/[0-9]*/', $user_name, $match ); if ( $match[0] == $user_name ) $errors->add('user_name', __("Sorry, usernames must have letters too!")); if ( !is_email( $user_email ) ) $errors->add('user_email', __("Please enter a correct email address")); if ( !validate_email( $user_email ) ) $errors->add('user_email', __("Please check your email address.")); $limited_email_domains = get_site_option( 'limited_email_domains' ); if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) { $emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) ); if( in_array( $emaildomain, $limited_email_domains ) == false ) { $errors->add('user_email', __("Sorry, that email address is not allowed!")); } } // Check if the username has been used already. if ( username_exists($user_name) ) $errors->add('user_name', __("Sorry, that username already exists!")); // Check if the email address has been used already. if ( email_exists($user_email) ) $errors->add('user_email', __("Sorry, that email address is already used!")); // Has someone already signed up for this username? $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) ); if ( $signup != null ) { $registered_at = mysql2date('U', $signup->registered); $now = current_time( 'timestamp', true ); $diff = $now - $registered_at; // If registered more than two days ago, cancel registration and let this signup go through. if ( $diff > 172800 ) { $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE user_login = %s", $user_name) ); } else { $errors->add('user_name', __("That username is currently reserved but may be available in a couple of days.")); } if( $signup->active == 0 && $signup->user_email == $user_email ) $errors->add('user_email_used', __("username and email used")); } $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email) ); if ( $signup != null ) { $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered); // If registered more than two days ago, cancel registration and let this signup go through. if ( $diff > 172800 ) { $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE user_email = %s", $user_email) ); } else { $errors->add('user_email', __("That email address has already been used. Please check your inbox for an activation email. It will become available in a couple of days if you do nothing.")); } } $result = array('user_name' => $user_name, 'user_email' => $user_email, 'errors' => $errors); return apply_filters('wpmu_validate_user_signup', $result); } function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { global $wpdb, $domain, $base; $blogname = preg_replace( "/\s+/", '', sanitize_user( $blogname, true ) ); $blog_title = strip_tags( $blog_title ); $blog_title = substr( $blog_title, 0, 50 ); $errors = new WP_Error(); $illegal_names = get_site_option( "illegal_names" ); if( $illegal_names == false ) { $illegal_names = array( "www", "web", "root", "admin", "main", "invite", "administrator" ); add_site_option( "illegal_names", $illegal_names ); } if ( empty( $blogname ) ) $errors->add('blogname', __("Please enter a blog name")); $maybe = array(); preg_match( "/[a-z0-9]+/", $blogname, $maybe ); if( $blogname != $maybe[0] ) { $errors->add('blogname', __("Only lowercase letters and numbers allowed")); } if( in_array( $blogname, $illegal_names ) == true ) { $errors->add('blogname', __("That name is not allowed")); } if( strlen( $blogname ) < 4 && !is_site_admin() ) { $errors->add('blogname', __("Blog name must be at least 4 characters")); } if ( strpos( " " . $blogname, "_" ) != false ) $errors->add('blogname', __("Sorry, blog names may not contain the character '_'!")); // all numeric? $match = array(); preg_match( '/[0-9]*/', $blogname, $match ); if ( $match[0] == $blogname ) $errors->add('blogname', __("Sorry, blog names must have letters too!")); $blogname = apply_filters( "newblogname", $blogname ); $blog_title = stripslashes( $blog_title ); if ( empty( $blog_title ) ) $errors->add('blog_title', __("Please enter a blog title")); // Check if the domain/path has been used already. if( constant( "VHOST" ) == 'yes' ) { $mydomain = "$blogname.$domain"; $path = $base; } else { $mydomain = "$domain"; $path = $base.$blogname.'/'; } if ( domain_exists($mydomain, $path) ) $errors->add('blogname', __("Sorry, that blog already exists!")); if ( username_exists($blogname) ) { if ( !is_object($user) && ( $user->user_login != $blogname ) ) $errors->add('blogname', __("Sorry, that blog is reserved!")); } // Has someone already signed up for this domain? $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); // TODO: Check email too? if ( ! empty($signup) ) { $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered); // If registered more than two days ago, cancel registration and let this signup go through. if ( $diff > 172800 ) { $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->signups WHERE domain = %s AND path = %s", $mydomain, $path) ); } else { $errors->add('blogname', __("That blog is currently reserved but may be available in a couple days.")); } } $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors); return apply_filters('wpmu_validate_blog_signup', $result); } // Record signup information for future activation. wpmu_validate_signup() should be run // on the inputs before calling wpmu_signup(). function wpmu_signup_blog($domain, $path, $title, $user, $user_email, $meta = '') { global $wpdb; // Format data $key = substr( md5( time() . rand() . $domain ), 0, 16 ); $meta = serialize($meta); $domain = $wpdb->escape($domain); $path = $wpdb->escape($path); $title = $wpdb->escape($title); $wpdb->insert( $wpdb->signups, array( 'domain' => $domain, 'path' => $path, 'title' => $title, 'user_login' => $user, 'user_email' => $user_email, 'registered' => current_time('mysql', true), 'activation_key' => $key, 'meta' => $meta ) ); wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta); } function wpmu_signup_user($user, $user_email, $meta = '') { global $wpdb; // Format data $user = preg_replace( "/\s+/", '', sanitize_user( $user, true ) ); $user_email = sanitize_email( $user_email ); $key = substr( md5( time() . rand() . $user_email ), 0, 16 ); $meta = serialize($meta); $wpdb->insert( $wpdb->signups, array( 'domain' => '', 'path' => '', 'title' => '', 'user_login' => $user, 'user_email' => $user_email, 'registered' => current_time('mysql', true), 'activation_key' => $key, 'meta' => $meta ) ); wpmu_signup_user_notification($user, $user_email, $key, $meta); } // Notify user of signup success. function wpmu_signup_blog_notification($domain, $path, $title, $user, $user_email, $key, $meta = '') { global $current_site; if( !apply_filters('wpmu_signup_blog_notification', $domain, $path, $title, $user, $user_email, $key, $meta) ) return false; // Send email with activation link. if( constant( "VHOST" ) == 'no' ) { $activate_url = "http://" . $current_site->domain . $current_site->path . "wp-activate.php?key=$key"; } else { $activate_url = "http://{$domain}{$path}wp-activate.php?key=$key"; } $activate_url = clean_url($activate_url); $admin_email = get_site_option( "admin_email" ); if( $admin_email == '' ) $admin_email = 'support@' . $_SERVER['SERVER_NAME']; $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) ); $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; $message = sprintf(__("To activate your blog, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\nAfter you activate, you can visit your blog here:\n\n%s"), $activate_url, clean_url("http://{$domain}{$path}")); // TODO: Don't hard code activation link. $subject = '[' . $from_name . '] ' . sprintf(__('Activate %s'), clean_url('http://' . $domain . $path)); wp_mail($user_email, $subject, $message, $message_headers); return true; } function wpmu_signup_user_notification($user, $user_email, $key, $meta = '') { global $current_site; if( !apply_filters('wpmu_signup_user_notification', $user, $user_email, $key, $meta) ) return false; // Send email with activation link. $admin_email = get_site_option( "admin_email" ); if( $admin_email == '' ) $admin_email = 'support@' . $_SERVER['SERVER_NAME']; $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) ); $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; $message = sprintf(__("To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\n"), clean_url("http://{$current_site->domain}{$current_site->path}wp-activate.php?key=$key") ); // TODO: Don't hard code activation link. $subject = sprintf(__('Activate %s'), $user); wp_mail($user_email, $subject, $message, $message_headers); return true; } function wpmu_activate_signup($key) { global $wpdb; $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) ); if ( empty($signup) ) return new WP_Error('invalid_key', __('Invalid activation key.')); if ( $signup->active ) return new WP_Error('already_active', __('The blog is already active.'), $signup); $meta = unserialize($signup->meta); $user_login = $wpdb->escape($signup->user_login); $user_email = $wpdb->escape($signup->user_email); wpmu_validate_user_signup($user_login, $user_email); $password = generate_random_password(); $user_id = username_exists($user_login); if ( ! $user_id ) $user_id = wpmu_create_user($user_login, $password, $user_email); else $user_already_exists = true; if ( ! $user_id ) return new WP_Error('create_user', __('Could not create user'), $signup); $now = current_time('mysql', true); if ( empty($signup->domain) ) { $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) ); if ( isset($user_already_exists) ) return new WP_Error('user_already_exists', __('That username is already activated.'), $signup); wpmu_welcome_user_notification($user_id, $password, $meta); add_user_to_blog('1', $user_id, 'subscriber'); do_action('wpmu_activate_user', $user_id, $password, $meta); return array('user_id' => $user_id, 'password' => $password, 'meta' => $meta); } wpmu_validate_blog_signup($signup->domain, $signup->title); $blog_id = wpmu_create_blog($signup->domain, $signup->path, $signup->title, $user_id, $meta, $wpdb->siteid); // TODO: What to do if we create a user but cannot create a blog? if ( is_wp_error($blog_id) ) { // If blog is taken, that means a previous attempt to activate this blog failed in between creating the blog and // setting the activation flag. Let's just set the active flag and instruct the user to reset their password. if ( 'blog_taken' == $blog_id->get_error_code() ) { $blog_id->add_data($signup); $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) ); } return $blog_id; } $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $key) ); wpmu_welcome_notification($blog_id, $user_id, $password, $signup->title, $meta); do_action('wpmu_activate_blog', $blog_id, $user_id, $password, $signup->title, $meta); return array('blog_id' => $blog_id, 'user_id' => $user_id, 'password' => $password, 'title' => $signup->title, 'meta' => $meta); } function generate_random_password( $len = 8 ) { $random_password = substr(md5(uniqid(microtime())), 0, intval( $len ) ); $random_password = apply_filters('random_password', $random_password); return $random_password; } function wpmu_create_user( $user_name, $password, $email) { $user_name = preg_replace( "/\s+/", '', sanitize_user( $user_name, true ) ); if ( username_exists($user_name) ) return false; // Check if the email address has been used already. if ( email_exists($email) ) return false; $user_id = wp_create_user( $user_name, $password, $email ); $user = new WP_User($user_id); // Newly created users have no roles or caps until they are added to a blog. update_usermeta($user_id, 'capabilities', ''); update_usermeta($user_id, 'user_level', ''); do_action( 'wpmu_new_user', $user_id ); return $user_id; } function wpmu_create_blog($domain, $path, $title, $user_id, $meta = '', $site_id = 1) { $domain = preg_replace( "/\s+/", '', sanitize_user( $domain, true ) ); if( constant( 'VHOST' ) == 'yes' ) $domain = str_replace( '@', '', $domain ); $title = strip_tags( $title ); $user_id = (int) $user_id; if( empty($path) ) $path = '/'; // Check if the domain has been used already. We should return an error message. if ( domain_exists($domain, $path, $site_id) ) return new WP_Error('blog_taken', __('Blog already exists.')); if ( !defined("WP_INSTALLING") ) define( "WP_INSTALLING", true ); if ( ! $blog_id = insert_blog($domain, $path, $site_id) ) return new WP_Error('insert_blog', __('Could not create blog.')); switch_to_blog($blog_id); install_blog($blog_id, $title); install_blog_defaults($blog_id, $user_id); add_user_to_blog($blog_id, $user_id, 'administrator'); if ( is_array($meta) ) foreach ($meta as $key => $value) { if( $key == 'public' || $key == 'archived' || $key == 'mature' || $key == 'spam' || $key == 'deleted' || $key == 'lang_id' ) { update_blog_status( $blog_id, $key, $value ); } else { update_option( $key, $value ); } } add_option( 'WPLANG', get_site_option( 'WPLANG' ) ); update_option( 'blog_public', $meta['public'] ); if(get_usermeta( $user_id, 'primary_blog' ) == 1 ) update_usermeta( $user_id, 'primary_blog', $blog_id ); restore_current_blog(); do_action( 'wpmu_new_blog', $blog_id, $user_id ); return $blog_id; } function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) { global $current_site; if( get_site_option( 'registrationnotification' ) != 'yes' ) return false; $email = get_site_option( 'admin_email' ); if( is_email($email) == false ) return false; $options_site_url = clean_url("http://{$current_site->domain}{$current_site->path}wp-admin/wpmu-options.php"); $msg = sprintf(__("New Blog: %1s URL: %2s Remote IP: %3s Disable these notifications: %4s"), get_blog_option( $blog_id, "blogname" ), get_blog_option( $blog_id, "siteurl" ), $_SERVER['REMOTE_ADDR'], $options_site_url); $msg = apply_filters( 'newblog_notify_siteadmin', $msg ); wp_mail( $email, sprintf(__("New Blog Registration: %s"), get_blog_option( $blog_id, "siteurl" )), $msg ); return true; } function newuser_notify_siteadmin( $user_id ) { global $current_site; if( get_site_option( 'registrationnotification' ) != 'yes' ) return false; $email = get_site_option( 'admin_email' ); if( is_email($email) == false ) return false; $user = new WP_User($user_id); $options_site_url = clean_url("http://{$current_site->domain}{$current_site->path}wp-admin/wpmu-options.php"); $msg = sprintf(__("New User: %1s Remote IP: %2s Disable these notifications: %3s"), $user->user_login, $_SERVER['REMOTE_ADDR'], $options_site_url); $msg = apply_filters( 'newuser_notify_siteadmin', $msg ); wp_mail( $email, sprintf(__("New User Registration: %s"), $user->user_login), $msg ); return true; } function domain_exists($domain, $path, $site_id = 1) { global $wpdb; return $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) ); } function insert_blog($domain, $path, $site_id) { global $wpdb; $path = trailingslashit($path); $site_id = (int) $site_id; $wpdb->insert( $wpdb->blogs, array('site_id' => $site_id, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql')) ); if ( !$wpdb->insert_id ) return false; refresh_blog_details($wpdb->insert_id); return $wpdb->insert_id; } // Install an empty blog. wpdb should already be switched. function install_blog($blog_id, $blog_title = '') { global $wpdb, $table_prefix, $wp_roles; // Cast for security $blog_id = (int) $blog_id; require_once( ABSPATH . 'wp-admin/includes/upgrade.php'); $wpdb->suppress_errors(); if ( $wpdb->get_results("SELECT ID FROM $wpdb->posts") ) die(__('

    Already Installed

    You appear to have already installed WordPress. To reinstall please clear your old database tables first.

    ') . ''); $wpdb->suppress_errors( false); $url = get_blogaddress_by_id($blog_id); // Set everything up make_db_current_silent(); populate_options(); populate_roles(); $wp_roles->_init(); // fix url. update_option('siteurl', $url); update_option('home', $url); update_option('fileupload_url', $url . "files" ); update_option('upload_path', "wp-content/blogs.dir/" . $blog_id . "/files"); update_option('blogname', $blog_title); update_option('admin_email', ''); $wpdb->update( $wpdb->options, array('option_value' => ''), array('option_name' => 'admin_email') ); // Default category $wpdb->insert( $wpdb->terms, array('term_id' => 1, 'name' => __('Uncategorized'), 'slug' => sanitize_title(__('Uncategorized')), 'term_group' => 0) ); $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => 1, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1) ); // Default link category $cat_name = __('Blogroll'); $cat_slug = sanitize_title($cat_name); $blogroll_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) ); if( $blogroll_id == null ) { $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql')) ); $blogroll_id = $wpdb->insert_id; } $wpdb->insert( $wpdb->terms, array('term_id' => $blogroll_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) ); $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $blogroll_id, 'taxonomy' => 'link_category', 'description' => '', 'parent' => 0, 'count' => 2) ); update_option('default_link_category', $blogroll_id); // remove all perms $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key = %s", $table_prefix.'user_level') ); $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key = %s", $table_prefix.'capabilities') ); wp_cache_delete('notoptions', 'options'); wp_cache_delete('alloptions', 'options'); $wpdb->suppress_errors( false ); } function install_blog_defaults($blog_id, $user_id) { global $wpdb, $wp_rewrite, $current_site, $table_prefix; $wpdb->suppress_errors(); // Cast for security $user_id = (int) $user_id; $blog_id = (int) $blog_id; // Default links $wpdb->insert( $wpdb->links, array('link_url' => 'http://wordpress.com/', 'link_name' => 'WordPress.com', 'link_category' => '1356', 'link_owner' => $user_id, 'link_rss' => 'http://wordpress.com/feed/') ); $wpdb->insert( $wpdb->links, array('link_url' => 'http://wordpress.org/', 'link_name' => 'WordPress.org', 'link_category' => '1356', 'link_owner' => $user_id, 'link_rss' => 'http://wordpress.org/development/feed/') ); $wpdb->insert( $wpdb->term_relationships, array('object_id' => 1, 'term_taxonomy_id' => 2)); $wpdb->insert( $wpdb->term_relationships, array('object_id' => 2, 'term_taxonomy_id' => 2)); // First post $now = date('Y-m-d H:i:s'); $now_gmt = gmdate('Y-m-d H:i:s'); $first_post = get_site_option( 'first_post' ); if( $first_post == false ) { $first_post = stripslashes( __( 'Welcome to SITE_NAME. This is your first post. Edit or delete it, then start blogging!' ) ); } $first_post = str_replace( "SITE_URL", clean_url("http://" . $current_site->domain . $current_site->path), $first_post ); $first_post = str_replace( "SITE_NAME", $current_site->site_name, $first_post ); $wpdb->insert( $wpdb->posts, array( 'post_author' => $user_id, 'post_date' => $now, 'post_date_gmt' => $now_gmt, 'post_content' => stripslashes( $first_post ), 'post_excerpt' => '', 'post_title' => __('Hello world!'), 'post_category' => 0, 'post_name' => __('hello-world'), 'post_modified' => $now, 'post_modified_gmt' => $now_gmt, 'comment_count' => 1 ) ); $wpdb->insert( $wpdb->term_relationships, array('object_id' => 1, 'term_taxonomy_id' => 1)); update_option( "post_count", 1 ); // First page $wpdb->insert( $wpdb->posts, array( 'post_author' => $user_id, 'post_date' => $now, 'post_date_gmt' => $now_gmt, 'post_content' => __('This is an example of a WordPress page, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many pages like this one or sub-pages as you like and manage all of your content inside of WordPress.'), 'post_excerpt' => '', 'post_title' => __('About'), 'post_category' => 0, 'post_name' => __('about'), 'post_modified' => $now, 'post_modified_gmt' => $now_gmt, 'post_status' => 'publish', 'post_type' => 'page', 'to_ping' => '', 'pinged' => '', 'post_content_filtered' => '' ) ); // Flush rules to pick up the new page. $wp_rewrite->init(); $wp_rewrite->flush_rules(); // Default comment $wpdb->insert( $wpdb->comments, array( 'comment_post_ID' => '1', 'comment_author' => __('Mr WordPress'), 'comment_author_email' => '', 'comment_author_url' => 'http://' . $current_site->domain . $current_site->path, 'comment_author_IP' => '127.0.0.1', 'comment_date' => $now, 'comment_date_gmt' => $now_gmt, 'comment_content' => __("Hi, this is a comment.
    To delete a comment, just log in, and view the posts' comments, there you will have the option to edit or delete them.") ) ); $user = new WP_User($user_id); $wpdb->update( $wpdb->options, array('option_value' => $user->user_email), array('option_name' => 'admin_email') ); // Remove all perms except for the login user. $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'user_level') ); $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id != %d AND meta_key = %s", $user_id, $table_prefix.'capabilities') ); // Delete any caps that snuck into the previously active blog. (Hardcoded to blog 1 for now.) TODO: Get previous_blog_id. if ( !is_site_admin( $user->user_login ) && $user_id != 1 ) $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $wpdb->base_prefix.'1_capabilities') ); $wpdb->suppress_errors( false ); } function wpmu_welcome_notification($blog_id, $user_id, $password, $title, $meta = '') { global $current_site; if( !apply_filters('wpmu_welcome_notification', $blog_id, $user_id, $password, $title, $meta) ) return false; $welcome_email = stripslashes( get_site_option( 'welcome_email' ) ); if( $welcome_email == false ) $welcome_email = stripslashes( __( "Dear User, Your new SITE_NAME blog has been successfully set up at: BLOG_URL You can log in to the administrator account with the following information: Username: USERNAME Password: PASSWORD Login Here: BLOG_URLwp-login.php We hope you enjoy your new weblog. Thanks! --The WordPress Team SITE_NAME" ) ); $url = get_blogaddress_by_id($blog_id); $user = new WP_User($user_id); $welcome_email = str_replace( "SITE_NAME", $current_site->site_name, $welcome_email ); $welcome_email = str_replace( "BLOG_URL", $url, $welcome_email ); $welcome_email = str_replace( "USERNAME", $user->user_login, $welcome_email ); $welcome_email = str_replace( "PASSWORD", $password, $welcome_email ); $welcome_email = apply_filters( "update_welcome_email", $welcome_email, $blog_id, $user_id, $password, $title, $meta); $admin_email = get_site_option( "admin_email" ); if( $admin_email == '' ) $admin_email = 'support@' . $_SERVER['SERVER_NAME']; $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) ); $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; $message = $welcome_email; if( empty( $current_site->site_name ) ) $current_site->site_name = "WordPress MU"; $subject = sprintf(__('New %1$s Blog: %2$s'), $current_site->site_name, $title); wp_mail($user->user_email, $subject, $message, $message_headers); return true; } function wpmu_welcome_user_notification($user_id, $password, $meta = '') { global $current_site; if( !apply_filters('wpmu_welcome_user_notification', $user_id, $password, $meta) ) return false; $welcome_email = __( "Dear User, Your new account is setup. You can log in with the following information: Username: USERNAME Password: PASSWORD Thanks! --The WordPress Team SITE_NAME" ); $user = new WP_User($user_id); $welcome_email = apply_filters( "update_welcome_user_email", $welcome_email, $user_id, $password, $meta); $welcome_email = str_replace( "SITE_NAME", $current_site->site_name, $welcome_email ); $welcome_email = str_replace( "USERNAME", $user->user_login, $welcome_email ); $welcome_email = str_replace( "PASSWORD", $password, $welcome_email ); $admin_email = get_site_option( "admin_email" ); if( $admin_email == '' ) $admin_email = 'support@' . $_SERVER['SERVER_NAME']; $from_name = get_site_option( "site_name" ) == '' ? 'WordPress' : wp_specialchars( get_site_option( "site_name" ) ); $message_headers = "MIME-Version: 1.0\n" . "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; $message = $welcome_email; if( empty( $current_site->site_name ) ) $current_site->site_name = "WordPress MU"; $subject = sprintf(__('New %1$s User: %2$s'), $current_site->site_name, $user->user_login); wp_mail($user->user_email, $subject, $message, $message_headers); return true; } function get_current_site() { global $current_site; return $current_site; } function get_user_id_from_string( $string ) { global $wpdb; if( is_email( $string ) ) { return $wpdb->get_var( $wpdb->prepare("SELECT ID FROM {$wpdb->users} WHERE user_email = %s", $string) ); } elseif ( is_numeric( $string ) ) { return $string; } return $wpdb->get_var( $wpdb->prepare("SELECT ID FROM {$wpdb->users} WHERE user_login = %s", $string) ); } function get_most_recent_post_of_user( $user_id ) { global $wpdb; $user_blogs = get_blogs_of_user( (int) $user_id ); $most_recent_post = array(); // Walk through each blog and get the most recent post // published by $user_id foreach ( (array) $user_blogs as $blog ) { $recent_post = $wpdb->get_row( $wpdb->prepare("SELECT ID, post_date_gmt FROM {$wpdb->base_prefix}{$blog->userblog_id}_posts WHERE post_author = %d AND post_type = 'post' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1", $user_id ), ARRAY_A); // Make sure we found a post if ( isset($recent_post['ID']) ) { $post_gmt_ts = strtotime($recent_post['post_date_gmt']); // If this is the first post checked or if this post is // newer than the current recent post, make it the new // most recent post. if ( !isset($most_recent_post['post_gmt_ts']) || ($post_gmt_ts > $most_recent_post['post_gmt_ts']) ) { $most_recent_post = array( 'blog_id' => $blog->userblog_id, 'post_id' => $recent_post['ID'], 'post_date_gmt' => $recent_post['post_date_gmt'], 'post_gmt_ts' => $post_gmt_ts ); } } } return $most_recent_post; } /* Misc functions */ function fix_upload_details( $uploads ) { $uploads['url'] = str_replace( UPLOADS, "files", $uploads['url'] ); return $uploads; } function get_dirsize($directory) { $size = 0; if(substr($directory,-1) == '/') $directory = substr($directory,0,-1); if(!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) return false; if($handle = opendir($directory)) { while(($file = readdir($handle)) !== false) { $path = $directory.'/'.$file; if($file != '.' && $file != '..') { if(is_file($path)) { $size += filesize($path); } elseif(is_dir($path)) { $handlesize = get_dirsize($path); if($handlesize >= 0) { $size += $handlesize; } else { return false; } } } } closedir($handle); } return $size; } function upload_is_user_over_quota( $echo = true ) { $spaceAllowed = get_space_allowed(); if(empty($spaceAllowed) || !is_numeric($spaceAllowed)) $spaceAllowed = 10; // Default space allowed is 10 MB $dirName = constant( "ABSPATH" ) . constant( "UPLOADS" ); $size = get_dirsize($dirName) / 1024 / 1024; if( ($spaceAllowed-$size) < 0 ) { if( $echo ) _e( "Sorry, you have used your space allocation. Please delete some files to upload more files." ); //No space left return true; } else { return false; } } function check_upload_mimes($mimes) { $site_exts = explode( " ", get_site_option( "upload_filetypes" ) ); foreach ( $site_exts as $ext ) { foreach ( $mimes as $ext_pattern => $mime ) { if( strpos( $ext_pattern, $ext ) !== false ) { $site_mimes[$ext_pattern] = $mime; } } } return $site_mimes; } function update_posts_count( $deprecated = '' ) { global $wpdb; update_option( "post_count", (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ) ); } function wpmu_log_new_registrations( $blog_id, $user_id ) { global $wpdb; $user = new WP_User( (int) $user_id ); $wpdb->insert( $wpdb->registration_log, array('email' => $user->user_email, 'IP' => preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] ), 'blog_id' => $blog_id, 'date_registered' => current_time('mysql')) ); } function fix_import_form_size( $size ) { if( upload_is_user_over_quota( false ) == true ) { return 0; } $spaceAllowed = 1024 * 1024 * get_space_allowed(); $dirName = constant( "ABSPATH" ) . constant( "UPLOADS" ); $dirsize = get_dirsize($dirName) ; if( $size > $spaceAllowed - $dirsize ) { return $spaceAllowed - $dirsize; // remaining space } else { return $size; // default } } if ( !function_exists('graceful_fail') ) : function graceful_fail( $message ) { $message = apply_filters('graceful_fail', $message); die(' Error!

    ' . $message . '

    '); } endif; /* Delete blog */ class delete_blog { function delete_blog() { $this->reallydeleteblog = false; add_action('admin_menu', array(&$this, 'admin_menu')); add_action('admin_footer', array(&$this, 'admin_footer')); } function admin_footer() { global $wpdb, $current_blog, $current_site; if( $current_blog->domain . $current_blog->path == $current_site->domain . $current_site->path ) return false; if( $this->reallydeleteblog == true ) { wpmu_delete_blog( $wpdb->blogid ); } } function admin_menu() { global $current_blog, $current_site; if( $current_blog->domain . $current_blog->path != $current_site->domain . $current_site->path ) add_submenu_page('options-general.php', __('Delete Blog'), __('Delete Blog'), 'manage_options', 'delete-blog', array(&$this, 'plugin_content')); } function plugin_content() { global $current_blog, $current_site; $this->delete_blog_hash = get_settings('delete_blog_hash'); echo '

    ' . __('Delete Blog') . '

    '; if( $_POST['action'] == "deleteblog" && $_POST['confirmdelete'] == '1' ) { $hash = substr( md5( $_SERVER['REQUEST_URI'] . time() ), 0, 6 ); update_option( "delete_blog_hash", $hash ); $url_delete = get_option( "siteurl" ) . "/wp-admin/options-general.php?page=delete-blog&h=" . $hash; $msg = __("Dear User, You recently clicked the 'Delete Blog' link on your blog and filled in a form on that page. If you really want to delete your blog, click the link below. You will not be asked to confirm again so only click this link if you are 100% certain: URL_DELETE If you delete your blog, please consider opening a new blog here some time in the future! (But remember your current blog and username are gone forever.) Thanks for using the site, Webmaster SITE_NAME "); $msg = str_replace( "URL_DELETE", $url_delete, $msg ); $msg = str_replace( "SITE_NAME", $current_site->site_name, $msg ); wp_mail( get_option( "admin_email" ), "[ " . get_option( "blogname" ) . " ] ".__("Delete My Blog"), $msg ); ?>

    reallydeleteblog = true; echo "

    " . sprintf(__('Thank you for using %s, your blog has been deleted. Happy trails to you until we meet again.'), $current_site->site_name) . "

    "; } else { $this->reallydeleteblog = false; echo "

    " . __("I'm sorry, the link you clicked is stale. Please select another option.") . "

    "; } } else { ?>

    Delete My Blog you will be sent an email with a link in it. Click on this link to delete your blog.'), $current_site->site_name); ?>

    ' />

    "; } } $delete_blog_obj = new delete_blog(); /* Global Categories */ function global_terms( $term_id, $deprecated = '' ) { global $wpdb; $term_id = intval( $term_id ); $c = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->terms WHERE term_id = %d", $term_id ) ); $global_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM $wpdb->sitecategories WHERE category_nicename = %s", $c->slug ) ); if ( $global_id == null ) { $wpdb->insert( $wpdb->sitecategories, array('cat_name' => $c->name, 'category_nicename' => $c->slug) ); $global_id = $wpdb->insert_id; } if ( $global_id == $term_id ) return $global_id; if( get_option( 'default_category' ) == $term_id ) update_option( 'default_category', $global_id ); $wpdb->update( $wpdb->terms, array('term_id' => $global_id), array('term_id' => $term_id) ); $wpdb->update( $wpdb->term_taxonomy, array('term_id' => $global_id), array('term_id' => $term_id) ); $wpdb->update( $wpdb->term_taxonomy, array('parent' => $global_id), array('parent' => $term_id) ); clean_term_cache($term_id); return $global_id; } function choose_primary_blog() { global $current_user; ?>
    ID ); if( count( $all_blogs ) > 1 ) { $primary_blog = get_usermeta($current_user->ID, 'primary_blog'); ?>
    domain ); } function upload_is_file_too_big( $upload ) { if( is_array( $upload ) == false || defined( 'WP_IMPORTING' ) ) return $upload; if( strlen( $upload[ 'bits' ] ) > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) ) { return sprintf(__( "This file is too big. Files must be less than %dKb in size.
    " ), get_site_option( 'fileupload_maxk', 1500 )); } return $upload; } function safecss_filter_attr( $css, $deprecated = '' ) { $css = wp_kses_no_null($css); $css = str_replace(array("\n","\r","\t"), '', $css); $css_array = split( ';', trim( $css ) ); $allowed_attr = apply_filters( 'safe_style_css', array( 'text-align', 'margin', 'color', 'float', 'text-direction', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'height', 'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'width', 'border', 'vertical-align', 'text-decoration' ) ); $css = ''; foreach( $css_array as $css_item ) { if( $css_item == '' ) continue; $css_item = trim( $css_item ); $found = false; if( strpos( $css_item, ':' ) === false ) { $found = true; } elseif( in_array( substr( $css_item, 0, strpos( $css_item, ':' ) ), $allowed_attr ) ) { $found = true; } if( $found ) { if( $css != '' ) $css .= ';'; $css .= $css_item; } } return $css; } function wordpressmu_authenticate_siteadmin( $user, $password = '' ) { if( is_site_admin( $user->user_login ) == false && ( $primary_blog = get_usermeta( $user->user_id, "primary_blog" ) ) ) { $details = get_blog_details( $primary_blog ); if( is_object( $details ) && $details->spam == 1 ) { return new WP_Error('blog_suspended', __('Blog Suspended.')); } } return $user; } function wordpressmu_wp_mail_from( $email ) { if( strpos( $email, 'wordpress@' ) !== false ) $email = get_option( 'admin_email' ); return $email; } /* XMLRPC getUsersBlogs() for a multiblog environment http://trac.mu.wordpress.org/attachment/ticket/551/xmlrpc-mu.php */ function wpmu_blogger_getUsersBlogs($args) { global $current_blog; $domain = $current_blog->domain; $path = $current_blog->path . 'xmlrpc.php'; $rpc = new IXR_Client("http://{$domain}{$path}"); $rpc->query('wp.getUsersBlogs', $args[1], $args[2]); $blogs = $rpc->getResponse(); if ( isset($blogs['faultCode']) ) { return new IXR_Error($blogs['faultCode'], $blogs['faultString']); } if ( $_SERVER['HTTP_HOST'] == $domain && $_SERVER['REQUEST_URI'] == $path ) { return $blogs; } else { foreach ( (array) $blogs as $blog ) { if ( strpos($blog['url'], $_SERVER['HTTP_HOST']) ) return array($blog); } return array(); } } function attach_wpmu_xmlrpc($methods) { $methods['blogger.getUsersBlogs'] = 'wpmu_blogger_getUsersBlogs'; return $methods; } /* Users */ function promote_if_site_admin(&$user) { if ( !is_site_admin( $user->user_login ) ) return false; global $wpdb; $level = $wpdb->prefix . 'user_level'; $user->{$level} = 10; $user->user_level = 10; $cap_key = $wpdb->prefix . 'capabilities'; $user->{$cap_key} = array( 'administrator' => '1' ); return true; } if( is_object( $wp_object_cache ) ) { $wp_object_cache->global_groups = array ('users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss'); $wp_object_cache->non_persistent_groups = array('comment', 'counts'); } function mu_locale( $locale ) { if( defined('WP_INSTALLING') == false ) { $mu_locale = get_option('WPLANG'); if( $mu_locale === false ) $mu_locale = get_site_option('WPLANG'); if( $mu_locale !== false ) return $mu_locale; } return $locale; } function signup_nonce_fields() { $id = mt_rand(); echo ""; wp_nonce_field('signup_form_' . $id, '_signup_form', false); } function signup_nonce_check( $result ) { if( !strpos( $_SERVER[ 'PHP_SELF' ], 'wp-signup.php' ) ) return $result; if ( wp_create_nonce('signup_form_' . $_POST[ 'signup_form_id' ]) != $_POST['_signup_form'] ) wp_die( __('Please try again!') ); return $result; } function maybe_redirect_404() { if( is_main_blog() && is_404() && defined( 'NOBLOGREDIRECT' ) && constant( 'NOBLOGREDIRECT' ) != '' ) { wp_redirect( constant( 'NOBLOGREDIRECT' ) ); exit(); } } function remove_tinymce_media_button( $buttons ) { unset( $buttons[ array_search( 'media', $buttons ) ] ); return $buttons; } function add_existing_user_to_blog() { if( false !== strpos( $_SERVER[ 'REQUEST_URI' ], '/newbloguser/' ) ) { $parts = explode( '/', $_SERVER[ 'REQUEST_URI' ] ); $key = array_pop( $parts ); if( $key == '' ) $key = array_pop( $parts ); $details = get_option( "new_user_" . $key ); if( is_array( $details ) ) { add_user_to_blog( '', $details[ 'user_id' ], $details[ 'role' ] ); delete_option( 'new_user_' . $key ); do_action( "added_existing_user", $details[ 'user_id' ] ); wp_die( sprintf(__('You have been added to this blog. Please visit the homepage or login using your username and password.'), site_url(), site_url( '/wp-admin/' ) ) ); } } } ?> blogs/wp-includes/feed-rdf.php0000644000000000000000000000404411077635520015311 0ustar rootroot '; ?> > "> <?php bloginfo_rss('name'); wp_title_rss(); ?> hourly 1 2000-01-01T12:00+00:00 <?php the_title_rss() ?> post_date_gmt, false); ?> ]]> blogs/wp-includes/category.php0000644000000000000000000002611511077635520015455 0ustar rootroot 'category'); $args = wp_parse_args($args, $defaults); $taxonomy = 'category'; if ( 'link' == $args['type'] ) $taxonomy = 'link_category'; $categories = get_terms($taxonomy, $args); foreach ( array_keys($categories) as $k ) _make_cat_compat($categories[$k]); return $categories; } /** * Retrieves category data given a category ID or category object. * * If you pass the $category parameter an object, which is assumed to be the * category row object retrieved the database. It will cache the category data. * * If you pass $category an integer of the category ID, then that category will * be retrieved from the database, if it isn't already cached, and pass it back. * * If you look at get_term(), then both types will be passed through several * filters and finally sanitized based on the $filter parameter value. * * The category will converted to maintain backwards compatibility. * * @since 2.1.0 * @uses get_term() Used to get the category data from the taxonomy. * * @param int|object $category Category ID or Category row object * @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N * @param string $filter Optional. Default is raw or no WordPress defined filter will applied. * @return mixed Category data in type defined by $output parameter. */ function &get_category($category, $output = OBJECT, $filter = 'raw') { $category = get_term($category, 'category', $output, $filter); if ( is_wp_error( $category ) ) return $category; _make_cat_compat($category); return $category; } /** * Retrieve category based on URL containing the category slug. * * Breaks the $category_path parameter up to get the category slug. * * Tries to find the child path and will return it. If it doesn't find a * match, then it will return the first category matching slug, if $full_match, * is set to false. If it does not, then it will return null. * * It is also possible that it will return a WP_Error object on failure. Check * for it when using this function. * * @since 2.1.0 * * @param string $category_path URL containing category slugs. * @param bool $full_match Optional. Whether should match full path or not. * @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N * @return null|object|array Null on failure. Type is based on $output value. */ function get_category_by_path($category_path, $full_match = true, $output = OBJECT) { $category_path = rawurlencode(urldecode($category_path)); $category_path = str_replace('%2F', '/', $category_path); $category_path = str_replace('%20', ' ', $category_path); $category_paths = '/' . trim($category_path, '/'); $leaf_path = sanitize_title(basename($category_paths)); $category_paths = explode('/', $category_paths); $full_path = ''; foreach ( (array) $category_paths as $pathdir ) $full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir); $categories = get_terms('category', "get=all&slug=$leaf_path"); if ( empty($categories) ) return null; foreach ($categories as $category) { $path = '/' . $leaf_path; $curcategory = $category; while ( ($curcategory->parent != 0) && ($curcategory->parent != $curcategory->term_id) ) { $curcategory = get_term($curcategory->parent, 'category'); if ( is_wp_error( $curcategory ) ) return $curcategory; $path = '/' . $curcategory->slug . $path; } if ( $path == $full_path ) return get_category($category->term_id, $output); } // If full matching is not required, return the first cat that matches the leaf. if ( ! $full_match ) return get_category($categories[0]->term_id, $output); return null; } /** * Retrieve category object by category slug. * * @since 2.3.0 * * @param string $slug The category slug. * @return object Category data object */ function get_category_by_slug( $slug ) { $category = get_term_by('slug', $slug, 'category'); if ( $category ) _make_cat_compat($category); return $category; } /** * Retrieve the ID of a category from its name. * * @since 1.0.0 * * @param string $cat_name Optional. Default is 'General' and can be any category name. * @return int 0, if failure and ID of category on success. */ function get_cat_ID($cat_name='General') { $cat = get_term_by('name', $cat_name, 'category'); if ($cat) return $cat->term_id; return 0; } /** * Retrieve the category name by the category ID. * * @since 0.71 * @deprecated Use get_cat_name() * @see get_cat_name() get_catname() is deprecated in favor of get_cat_name(). * * @param int $cat_ID Category ID * @return string category name */ function get_catname($cat_ID) { return get_cat_name($cat_ID); } /** * Retrieve the name of a category from its ID. * * @since 1.0.0 * * @param int $cat_id Category ID * @return string Category name */ function get_cat_name($cat_id) { $cat_id = (int) $cat_id; $category = &get_category($cat_id); return $category->name; } /** * Check if a category is an ancestor of another category. * * You can use either an id or the category object for both parameters. If you * use an integer the category will be retrieved. * * @since 2.1.0 * * @param int|object $cat1 ID or object to check if this is the parent category. * @param int|object $cat2 The child category. * @return bool Whether $cat2 is child of $cat1 */ function cat_is_ancestor_of($cat1, $cat2) { if ( is_int($cat1) ) $cat1 = & get_category($cat1); if ( is_int($cat2) ) $cat2 = & get_category($cat2); if ( !$cat1->term_id || !$cat2->parent ) return false; if ( $cat2->parent == $cat1->term_id ) return true; return cat_is_ancestor_of($cat1, get_category($cat2->parent)); } /** * Sanitizes category data based on context. * * @since 2.3.0 * @uses sanitize_term() See this function for what context are supported. * * @param object|array $category Category data * @param string $context Optional. Default is 'display'. * @return object|array Same type as $category with sanitized data for safe use. */ function sanitize_category($category, $context = 'display') { return sanitize_term($category, 'category', $context); } /** * Sanitizes data in single category key field. * * @since 2.3.0 * @uses sanitize_term_field() See function for more details. * * @param string $field Category key to sanitize * @param mixed $value Category value to sanitize * @param int $cat_id Category ID * @param string $context What filter to use, 'raw', 'display', etc. * @return mixed Same type as $value after $value has been sanitized. */ function sanitize_category_field($field, $value, $cat_id, $context) { return sanitize_term_field($field, $value, $cat_id, 'category', $context); } /* Tags */ /** * Retrieves all post tags. * * @since 2.3.0 * @see get_terms() For list of arguments to pass. * @uses apply_filters() Calls 'get_tags' hook on array of tags and with $args. * * @param string|array $args Tag arguments to use when retrieving tags. * @return array List of tags. */ function &get_tags($args = '') { $tags = get_terms('post_tag', $args); if ( empty($tags) ) return array(); $tags = apply_filters('get_tags', $tags, $args); return $tags; } /** * Retrieve post tag by tag ID or tag object. * * If you pass the $tag parameter an object, which is assumed to be the tag row * object retrieved the database. It will cache the tag data. * * If you pass $tag an integer of the tag ID, then that tag will * be retrieved from the database, if it isn't already cached, and pass it back. * * If you look at get_term(), then both types will be passed through several * filters and finally sanitized based on the $filter parameter value. * * @since 2.3.0 * * @param int|object $tag * @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N * @param string $filter Optional. Default is raw or no WordPress defined filter will applied. * @return object|array Return type based on $output value. */ function &get_tag($tag, $output = OBJECT, $filter = 'raw') { return get_term($tag, 'post_tag', $output, $filter); } /* Cache */ /** * Update the categories cache. * * This function does not appear to be used anymore or does not appear to be * needed. It might be a legacy function left over from when there was a need * for updating the category cache. * * @since 1.5.0 * * @return bool Always return True */ function update_category_cache() { return true; } /** * Remove the category cache data based on ID. * * @since 2.1.0 * @uses clean_term_cache() Clears the cache for the category based on ID * * @param int $id Category ID */ function clean_category_cache($id) { clean_term_cache($id, 'category'); } /** * Update category structure to old pre 2.3 from new taxonomy structure. * * This function was added for the taxonomy support to update the new category * structure with the old category one. This will maintain compatibility with * plugins and themes which depend on the old key or property names. * * The parameter should only be passed a variable and not create the array or * object inline to the parameter. The reason for this is that parameter is * passed by reference and PHP will fail unless it has the variable. * * There is no return value, because everything is updated on the variable you * pass to it. This is one of the features with using pass by reference in PHP. * * @since 2.3.0 * @access private * * @param array|object $category Category Row object or array */ function _make_cat_compat( &$category) { if ( is_object($category) ) { $category->cat_ID = &$category->term_id; $category->category_count = &$category->count; $category->category_description = &$category->description; $category->cat_name = &$category->name; $category->category_nicename = &$category->slug; $category->category_parent = &$category->parent; } else if ( is_array($category) && isset($category['term_id']) ) { $category['cat_ID'] = &$category['term_id']; $category['category_count'] = &$category['count']; $category['category_description'] = &$category['description']; $category['cat_name'] = &$category['name']; $category['category_nicename'] = &$category['slug']; $category['category_parent'] = &$category['parent']; } } ?> blogs/wp-includes/class-phpmailer.php0000644000000000000000000012770611077635520016734 0ustar rootrootContentType = "text/html"; else $this->ContentType = "text/plain"; } /** * Sets Mailer to send message using SMTP. * @return void */ function IsSMTP() { $this->Mailer = "smtp"; } /** * Sets Mailer to send message using PHP mail() function. * @return void */ function IsMail() { $this->Mailer = "mail"; } /** * Sets Mailer to send message using the $Sendmail program. * @return void */ function IsSendmail() { $this->Mailer = "sendmail"; } /** * Sets Mailer to send message using the qmail MTA. * @return void */ function IsQmail() { $this->Sendmail = "/var/qmail/bin/sendmail"; $this->Mailer = "sendmail"; } ///////////////////////////////////////////////// // RECIPIENT METHODS ///////////////////////////////////////////////// /** * Adds a "To" address. * @param string $address * @param string $name * @return void */ function AddAddress($address, $name = "") { $cur = count($this->to); $this->to[$cur][0] = trim($address); $this->to[$cur][1] = $name; } /** * Adds a "Cc" address. Note: this function works * with the SMTP mailer on win32, not with the "mail" * mailer. * @param string $address * @param string $name * @return void */ function AddCC($address, $name = "") { $cur = count($this->cc); $this->cc[$cur][0] = trim($address); $this->cc[$cur][1] = $name; } /** * Adds a "Bcc" address. Note: this function works * with the SMTP mailer on win32, not with the "mail" * mailer. * @param string $address * @param string $name * @return void */ function AddBCC($address, $name = "") { $cur = count($this->bcc); $this->bcc[$cur][0] = trim($address); $this->bcc[$cur][1] = $name; } /** * Adds a "Reply-to" address. * @param string $address * @param string $name * @return void */ function AddReplyTo($address, $name = "") { $cur = count($this->ReplyTo); $this->ReplyTo[$cur][0] = trim($address); $this->ReplyTo[$cur][1] = $name; } ///////////////////////////////////////////////// // MAIL SENDING METHODS ///////////////////////////////////////////////// /** * Creates message and assigns Mailer. If the message is * not sent successfully then it returns false. Use the ErrorInfo * variable to view description of the error. * @return bool */ function Send() { $header = ""; $body = ""; $result = true; if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { $this->SetError($this->Lang("provide_address")); return false; } // Set whether the message is multipart/alternative if(!empty($this->AltBody)) $this->ContentType = "multipart/alternative"; $this->error_count = 0; // reset errors $this->SetMessageType(); $header .= $this->CreateHeader(); $body = $this->CreateBody(); if($body == "") { return false; } // Choose the mailer switch($this->Mailer) { case "sendmail": $result = $this->SendmailSend($header, $body); break; case "mail": $result = $this->MailSend($header, $body); break; case "smtp": $result = $this->SmtpSend($header, $body); break; default: $this->SetError($this->Mailer . $this->Lang("mailer_not_supported")); $result = false; break; } return $result; } /** * Sends mail using the $Sendmail program. * @access private * @return bool */ function SendmailSend($header, $body) { if ($this->Sender != "") $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, escapeshellarg($this->Sender)); else $sendmail = sprintf("%s -oi -t", $this->Sendmail); if(!@$mail = popen($sendmail, "w")) { $this->SetError($this->Lang("execute") . $this->Sendmail); return false; } fputs($mail, $header); fputs($mail, $body); $result = pclose($mail) >> 8 & 0xFF; if($result != 0) { $this->SetError($this->Lang("execute") . $this->Sendmail); return false; } return true; } /** * Sends mail using the PHP mail() function. * @access private * @return bool */ function MailSend($header, $body) { $to = ""; for($i = 0; $i < count($this->to); $i++) { if($i != 0) { $to .= ", "; } $to .= $this->to[$i][0]; } if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) { $old_from = ini_get("sendmail_from"); ini_set("sendmail_from", $this->Sender); $params = sprintf("-oi -f %s", $this->Sender); $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header, $params); } else $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); if (isset($old_from)) ini_set("sendmail_from", $old_from); if(!$rt) { $this->SetError($this->Lang("instantiate")); return false; } return true; } /** * Sends mail via SMTP using PhpSMTP (Author: * Chris Ryan). Returns bool. Returns false if there is a * bad MAIL FROM, RCPT, or DATA input. * @access private * @return bool */ function SmtpSend($header, $body) { include_once($this->PluginDir . "class-smtp.php"); $error = ""; $bad_rcpt = array(); if(!$this->SmtpConnect()) return false; $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; if(!$this->smtp->Mail($smtp_from)) { $error = $this->Lang("from_failed") . $smtp_from; $this->SetError($error); $this->smtp->Reset(); return false; } // Attempt to send attach all recipients for($i = 0; $i < count($this->to); $i++) { if(!$this->smtp->Recipient($this->to[$i][0])) $bad_rcpt[] = $this->to[$i][0]; } for($i = 0; $i < count($this->cc); $i++) { if(!$this->smtp->Recipient($this->cc[$i][0])) $bad_rcpt[] = $this->cc[$i][0]; } for($i = 0; $i < count($this->bcc); $i++) { if(!$this->smtp->Recipient($this->bcc[$i][0])) $bad_rcpt[] = $this->bcc[$i][0]; } if(count($bad_rcpt) > 0) // Create error message { for($i = 0; $i < count($bad_rcpt); $i++) { if($i != 0) { $error .= ", "; } $error .= $bad_rcpt[$i]; } $error = $this->Lang("recipients_failed") . $error; $this->SetError($error); $this->smtp->Reset(); return false; } if(!$this->smtp->Data($header . $body)) { $this->SetError($this->Lang("data_not_accepted")); $this->smtp->Reset(); return false; } if($this->SMTPKeepAlive == true) $this->smtp->Reset(); else $this->SmtpClose(); return true; } /** * Initiates a connection to an SMTP server. Returns false if the * operation failed. * @access private * @return bool */ function SmtpConnect() { if($this->smtp == NULL) { $this->smtp = new SMTP(); } $this->smtp->do_debug = $this->SMTPDebug; $hosts = explode(";", $this->Host); $index = 0; $connection = ($this->smtp->Connected()); // Retry while there is no connection while($index < count($hosts) && $connection == false) { if(strstr($hosts[$index], ":")) list($host, $port) = explode(":", $hosts[$index]); else { $host = $hosts[$index]; $port = $this->Port; } if($this->smtp->Connect($host, $port, $this->Timeout)) { if ($this->Helo != '') $this->smtp->Hello($this->Helo); else $this->smtp->Hello($this->ServerHostname()); if($this->SMTPAuth) { if(!$this->smtp->Authenticate($this->Username, $this->Password)) { $this->SetError($this->Lang("authenticate")); $this->smtp->Reset(); $connection = false; } } $connection = true; } $index++; } if(!$connection) $this->SetError($this->Lang("connect_host")); return $connection; } /** * Closes the active SMTP session if one exists. * @return void */ function SmtpClose() { if($this->smtp != NULL) { if($this->smtp->Connected()) { $this->smtp->Quit(); $this->smtp->Close(); } } } /** * Sets the language for all class error messages. Returns false * if it cannot load the language file. The default language type * is English. * @param string $lang_type Type of language (e.g. Portuguese: "br") * @param string $lang_path Path to the language file directory * @access public * @return bool */ function SetLanguage($lang_type, $lang_path = "language/") { if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); else if(file_exists($lang_path.'phpmailer.lang-en.php')) include($lang_path.'phpmailer.lang-en.php'); else { $this->SetError("Could not load language file"); return false; } $this->language = $PHPMAILER_LANG; return true; } ///////////////////////////////////////////////// // MESSAGE CREATION METHODS ///////////////////////////////////////////////// /** * Creates recipient headers. * @access private * @return string */ function AddrAppend($type, $addr) { $addr_str = $type . ": "; $addr_str .= $this->AddrFormat($addr[0]); if(count($addr) > 1) { for($i = 1; $i < count($addr); $i++) $addr_str .= ", " . $this->AddrFormat($addr[$i]); } $addr_str .= $this->LE; return $addr_str; } /** * Formats an address correctly. * @access private * @return string */ function AddrFormat($addr) { if(empty($addr[1])) $formatted = $addr[0]; else { $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . $addr[0] . ">"; } return $formatted; } /** * Wraps message for use with mailers that do not * automatically perform wrapping and for quoted-printable. * Original written by philippe. * @access private * @return string */ function WrapText($message, $length, $qp_mode = false) { $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; $message = $this->FixEOL($message); if (substr($message, -1) == $this->LE) $message = substr($message, 0, -1); $line = explode($this->LE, $message); $message = ""; for ($i=0 ;$i < count($line); $i++) { $line_part = explode(" ", $line[$i]); $buf = ""; for ($e = 0; $e $length)) { $space_left = $length - strlen($buf) - 1; if ($e != 0) { if ($space_left > 20) { $len = $space_left; if (substr($word, $len - 1, 1) == "=") $len--; elseif (substr($word, $len - 2, 1) == "=") $len -= 2; $part = substr($word, 0, $len); $word = substr($word, $len); $buf .= " " . $part; $message .= $buf . sprintf("=%s", $this->LE); } else { $message .= $buf . $soft_break; } $buf = ""; } while (strlen($word) > 0) { $len = $length; if (substr($word, $len - 1, 1) == "=") $len--; elseif (substr($word, $len - 2, 1) == "=") $len -= 2; $part = substr($word, 0, $len); $word = substr($word, $len); if (strlen($word) > 0) $message .= $part . sprintf("=%s", $this->LE); else $buf = $part; } } else { $buf_o = $buf; $buf .= ($e == 0) ? $word : (" " . $word); if (strlen($buf) > $length and $buf_o != "") { $message .= $buf_o . $soft_break; $buf = $word; } } } $message .= $buf . $this->LE; } return $message; } /** * Set the body wrapping. * @access private * @return void */ function SetWordWrap() { if($this->WordWrap < 1) return; switch($this->message_type) { case "alt": // fall through case "alt_attachments": $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); break; default: $this->Body = $this->WrapText($this->Body, $this->WordWrap); break; } } /** * Assembles message header. * @access private * @return string */ function CreateHeader() { $result = ""; // Set the boundaries $uniq_id = md5(uniqid(time())); $this->boundary[1] = "b1_" . $uniq_id; $this->boundary[2] = "b2_" . $uniq_id; $result .= $this->HeaderLine("Date", $this->RFCDate()); if($this->Sender == "") $result .= $this->HeaderLine("Return-Path", trim($this->From)); else $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); // To be created automatically by mail() if($this->Mailer != "mail") { if(count($this->to) > 0) $result .= $this->AddrAppend("To", $this->to); else if (count($this->cc) == 0) $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); if(count($this->cc) > 0) $result .= $this->AddrAppend("Cc", $this->cc); } $from = array(); $from[0][0] = trim($this->From); $from[0][1] = $this->FromName; $result .= $this->AddrAppend("From", $from); // sendmail and mail() extract Bcc from the header before sending if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) $result .= $this->AddrAppend("Bcc", $this->bcc); if(count($this->ReplyTo) > 0) $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); // mail() sets the subject itself if($this->Mailer != "mail") $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject))); $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); $result .= $this->HeaderLine("X-Priority", $this->Priority); if($this->ConfirmReadingTo != "") { $result .= $this->HeaderLine("Disposition-Notification-To", "<" . trim($this->ConfirmReadingTo) . ">"); } // Add custom headers for($index = 0; $index < count($this->CustomHeader); $index++) { $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); } $result .= $this->HeaderLine("MIME-Version", "1.0"); switch($this->message_type) { case "plain": $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); break; case "attachments": // fall through case "alt_attachments": if($this->InlineImageExists()) { $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", "multipart/related", $this->LE, $this->LE, $this->boundary[1], $this->LE); } else { $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); } break; case "alt": $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); break; } if($this->Mailer != "mail") $result .= $this->LE.$this->LE; return $result; } /** * Assembles the message body. Returns an empty string on failure. * @access private * @return string */ function CreateBody() { $result = ""; $this->SetWordWrap(); switch($this->message_type) { case "alt": $result .= $this->GetBoundary($this->boundary[1], "", "text/plain", ""); $result .= $this->EncodeString($this->AltBody, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->GetBoundary($this->boundary[1], "", "text/html", ""); $result .= $this->EncodeString($this->Body, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->EndBoundary($this->boundary[1]); break; case "plain": $result .= $this->EncodeString($this->Body, $this->Encoding); break; case "attachments": $result .= $this->GetBoundary($this->boundary[1], "", "", ""); $result .= $this->EncodeString($this->Body, $this->Encoding); $result .= $this->LE; $result .= $this->AttachAll(); break; case "alt_attachments": $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", "multipart/alternative", $this->LE, $this->boundary[2], $this->LE.$this->LE); // Create text body $result .= $this->GetBoundary($this->boundary[2], "", "text/plain", "") . $this->LE; $result .= $this->EncodeString($this->AltBody, $this->Encoding); $result .= $this->LE.$this->LE; // Create the HTML body $result .= $this->GetBoundary($this->boundary[2], "", "text/html", "") . $this->LE; $result .= $this->EncodeString($this->Body, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->EndBoundary($this->boundary[2]); $result .= $this->AttachAll(); break; } if($this->IsError()) $result = ""; return $result; } /** * Returns the start of a message boundary. * @access private */ function GetBoundary($boundary, $charSet, $contentType, $encoding) { $result = ""; if($charSet == "") { $charSet = $this->CharSet; } if($contentType == "") { $contentType = $this->ContentType; } if($encoding == "") { $encoding = $this->Encoding; } $result .= $this->TextLine("--" . $boundary); $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet); $result .= $this->LE; $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); $result .= $this->LE; return $result; } /** * Returns the end of a message boundary. * @access private */ function EndBoundary($boundary) { return $this->LE . "--" . $boundary . "--" . $this->LE; } /** * Sets the message type. * @access private * @return void */ function SetMessageType() { if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) $this->message_type = "plain"; else { if(count($this->attachment) > 0) $this->message_type = "attachments"; if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) $this->message_type = "alt"; if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) $this->message_type = "alt_attachments"; } } /** * Returns a formatted header line. * @access private * @return string */ function HeaderLine($name, $value) { return $name . ": " . $value . $this->LE; } /** * Returns a formatted mail line. * @access private * @return string */ function TextLine($value) { return $value . $this->LE; } ///////////////////////////////////////////////// // ATTACHMENT METHODS ///////////////////////////////////////////////// /** * Adds an attachment from a path on the filesystem. * Returns false if the file could not be found * or accessed. * @param string $path Path to the attachment. * @param string $name Overrides the attachment name. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return bool */ function AddAttachment($path, $name = "", $encoding = "base64", $type = "application/octet-stream") { if(!@is_file($path)) { $this->SetError($this->Lang("file_access") . $path); return false; } $filename = basename($path); if($name == "") $name = $filename; $cur = count($this->attachment); $this->attachment[$cur][0] = $path; $this->attachment[$cur][1] = $filename; $this->attachment[$cur][2] = $name; $this->attachment[$cur][3] = $encoding; $this->attachment[$cur][4] = $type; $this->attachment[$cur][5] = false; // isStringAttachment $this->attachment[$cur][6] = "attachment"; $this->attachment[$cur][7] = 0; return true; } /** * Attaches all fs, string, and binary attachments to the message. * Returns an empty string on failure. * @access private * @return string */ function AttachAll() { // Return text of body $mime = array(); // Add all attachments for($i = 0; $i < count($this->attachment); $i++) { // Check for string attachment $bString = $this->attachment[$i][5]; if ($bString) $string = $this->attachment[$i][0]; else $path = $this->attachment[$i][0]; $filename = $this->attachment[$i][1]; $name = $this->attachment[$i][2]; $encoding = $this->attachment[$i][3]; $type = $this->attachment[$i][4]; $disposition = $this->attachment[$i][6]; $cid = $this->attachment[$i][7]; $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); if($disposition == "inline") $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); // Encode as string attachment if($bString) { $mime[] = $this->EncodeString($string, $encoding); if($this->IsError()) { return ""; } $mime[] = $this->LE.$this->LE; } else { $mime[] = $this->EncodeFile($path, $encoding); if($this->IsError()) { return ""; } $mime[] = $this->LE.$this->LE; } } $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); return join("", $mime); } /** * Encodes attachment in requested format. Returns an * empty string on failure. * @access private * @return string */ function EncodeFile ($path, $encoding = "base64") { if(!@$fd = fopen($path, "rb")) { $this->SetError($this->Lang("file_open") . $path); return ""; } $magic_quotes = get_magic_quotes_runtime(); set_magic_quotes_runtime(0); $file_buffer = fread($fd, filesize($path)); $file_buffer = $this->EncodeString($file_buffer, $encoding); fclose($fd); set_magic_quotes_runtime($magic_quotes); return $file_buffer; } /** * Encodes string to requested format. Returns an * empty string on failure. * @access private * @return string */ function EncodeString ($str, $encoding = "base64") { $encoded = ""; switch(strtolower($encoding)) { case "base64": // chunk_split is found in PHP >= 3.0.6 $encoded = chunk_split(base64_encode($str), 76, $this->LE); break; case "7bit": case "8bit": $encoded = $this->FixEOL($str); if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; break; case "binary": $encoded = $str; break; case "quoted-printable": $encoded = $this->EncodeQP($str); break; default: $this->SetError($this->Lang("encoding") . $encoding); break; } return $encoded; } /** * Encode a header string to best of Q, B, quoted or none. * @access private * @return string */ function EncodeHeader ($str, $position = 'text') { $x = 0; switch (strtolower($position)) { case 'phrase': if (!preg_match('/[\200-\377]/', $str)) { // Can't use addslashes as we don't know what value has magic_quotes_sybase. $encoded = addcslashes($str, "\0..\37\177\\\""); if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) return ($encoded); else return ("\"$encoded\""); } $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); break; case 'comment': $x = preg_match_all('/[()"]/', $str, $matches); // Fall-through case 'text': default: $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); break; } if ($x == 0) return ($str); $maxlen = 75 - 7 - strlen($this->CharSet); // Try to select the encoding which should produce the shortest output if (strlen($str)/3 < $x) { $encoding = 'B'; $encoded = base64_encode($str); $maxlen -= $maxlen % 4; $encoded = trim(chunk_split($encoded, $maxlen, "\n")); } else { $encoding = 'Q'; $encoded = $this->EncodeQ($str, $position); $encoded = $this->WrapText($encoded, $maxlen, true); $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); } $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); $encoded = trim(str_replace("\n", $this->LE, $encoded)); return $encoded; } /** * Encode string to quoted-printable. * @access private * @return string */ function EncodeQP ($str) { $encoded = $this->FixEOL($str); if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; // Replace every high ascii, control and = characters $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded); // Replace every spaces and tabs when it's the last character on a line $encoded = preg_replace("/([\011\040])".$this->LE."/e", "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); // Maximum line length of 76 characters before CRLF (74 + space + '=') $encoded = $this->WrapText($encoded, 74, true); return $encoded; } /** * Encode string to q encoding. * @access private * @return string */ function EncodeQ ($str, $position = "text") { // There should not be any EOL in the string $encoded = preg_replace("[\r\n]", "", $str); switch (strtolower($position)) { case "phrase": $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); break; case "comment": $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); case "text": default: // Replace every high ascii, control =, ? and _ characters $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded); break; } // Replace every spaces to _ (more readable than =20) $encoded = str_replace(" ", "_", $encoded); return $encoded; } /** * Adds a string or binary attachment (non-filesystem) to the list. * This method can be used to attach ascii or binary data, * such as a BLOB record from a database. * @param string $string String attachment data. * @param string $filename Name of the attachment. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return void */ function AddStringAttachment($string, $filename, $encoding = "base64", $type = "application/octet-stream") { // Append to $attachment array $cur = count($this->attachment); $this->attachment[$cur][0] = $string; $this->attachment[$cur][1] = $filename; $this->attachment[$cur][2] = $filename; $this->attachment[$cur][3] = $encoding; $this->attachment[$cur][4] = $type; $this->attachment[$cur][5] = true; // isString $this->attachment[$cur][6] = "attachment"; $this->attachment[$cur][7] = 0; } /** * Adds an embedded attachment. This can include images, sounds, and * just about any other document. Make sure to set the $type to an * image type. For JPEG images use "image/jpeg" and for GIF images * use "image/gif". * @param string $path Path to the attachment. * @param string $cid Content ID of the attachment. Use this to identify * the Id for accessing the image in an HTML form. * @param string $name Overrides the attachment name. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return bool */ function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", $type = "application/octet-stream") { if(!@is_file($path)) { $this->SetError($this->Lang("file_access") . $path); return false; } $filename = basename($path); if($name == "") $name = $filename; // Append to $attachment array $cur = count($this->attachment); $this->attachment[$cur][0] = $path; $this->attachment[$cur][1] = $filename; $this->attachment[$cur][2] = $name; $this->attachment[$cur][3] = $encoding; $this->attachment[$cur][4] = $type; $this->attachment[$cur][5] = false; // isStringAttachment $this->attachment[$cur][6] = "inline"; $this->attachment[$cur][7] = $cid; return true; } /** * Returns true if an inline attachment is present. * @access private * @return bool */ function InlineImageExists() { $result = false; for($i = 0; $i < count($this->attachment); $i++) { if($this->attachment[$i][6] == "inline") { $result = true; break; } } return $result; } ///////////////////////////////////////////////// // MESSAGE RESET METHODS ///////////////////////////////////////////////// /** * Clears all recipients assigned in the TO array. Returns void. * @return void */ function ClearAddresses() { $this->to = array(); } /** * Clears all recipients assigned in the CC array. Returns void. * @return void */ function ClearCCs() { $this->cc = array(); } /** * Clears all recipients assigned in the BCC array. Returns void. * @return void */ function ClearBCCs() { $this->bcc = array(); } /** * Clears all recipients assigned in the ReplyTo array. Returns void. * @return void */ function ClearReplyTos() { $this->ReplyTo = array(); } /** * Clears all recipients assigned in the TO, CC and BCC * array. Returns void. * @return void */ function ClearAllRecipients() { $this->to = array(); $this->cc = array(); $this->bcc = array(); } /** * Clears all previously set filesystem, string, and binary * attachments. Returns void. * @return void */ function ClearAttachments() { $this->attachment = array(); } /** * Clears all custom headers. Returns void. * @return void */ function ClearCustomHeaders() { $this->CustomHeader = array(); } ///////////////////////////////////////////////// // MISCELLANEOUS METHODS ///////////////////////////////////////////////// /** * Adds the error message to the error container. * Returns void. * @access private * @return void */ function SetError($msg) { $this->error_count++; $this->ErrorInfo = $msg; } /** * Returns the proper RFC 822 formatted date. * @access private * @return string */ function RFCDate() { $tz = date("Z"); $tzs = ($tz < 0) ? "-" : "+"; $tz = abs($tz); $tz = ($tz/3600)*100 + ($tz%3600)/60; $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); return $result; } /** * Returns the appropriate server variable. Should work with both * PHP 4.1.0+ as well as older versions. Returns an empty string * if nothing is found. * @access private * @return mixed */ function ServerVar($varName) { global $HTTP_SERVER_VARS; global $HTTP_ENV_VARS; if(!isset($_SERVER)) { $_SERVER = $HTTP_SERVER_VARS; if(!isset($_SERVER["REMOTE_ADDR"])) $_SERVER = $HTTP_ENV_VARS; // must be Apache } if(isset($_SERVER[$varName])) return $_SERVER[$varName]; else return ""; } /** * Returns the server hostname or 'localhost.localdomain' if unknown. * @access private * @return string */ function ServerHostname() { if ($this->Hostname != "") $result = $this->Hostname; elseif ($this->ServerVar('SERVER_NAME') != "") $result = $this->ServerVar('SERVER_NAME'); else $result = "localhost.localdomain"; return $result; } /** * Returns a message in the appropriate language. * @access private * @return string */ function Lang($key) { if(count($this->language) < 1) $this->SetLanguage("en"); // set the default language if(isset($this->language[$key])) return $this->language[$key]; else return "Language string failed to load: " . $key; } /** * Returns true if an error occurred. * @return bool */ function IsError() { return ($this->error_count > 0); } /** * Changes every end of line from CR or LF to CRLF. * @access private * @return string */ function FixEOL($str) { $str = str_replace("\r\n", "\n", $str); $str = str_replace("\r", "\n", $str); $str = str_replace("\n", $this->LE, $str); return $str; } /** * Adds a custom header. * @return void */ function AddCustomHeader($custom_header) { $this->CustomHeader[] = explode(":", $custom_header, 2); } } ?> blogs/wp-includes/l10n.php0000644000000000000000000002346311077635520014415 0ustar rootroottranslate($text), $text); else return $text; } /** * translate_with_context() - Retrieve the translated text and strip context * * If the domain is set in the $l10n global, then the text is run * through the domain's translate method. After it is passed to * the 'gettext' filter hook, along with the untranslated text as * the second parameter. * * If the domain is not set, the $text is just returned. * * @since 2.5 * @uses translate() * * @param string $text Text to translate * @param string $domain Domain to retrieve the translated text * @return string Translated text */ function translate_with_context($text, $domain = 'default') { $whole = translate($text, $domain); $last_bar = strrpos($whole, '|'); if ( false == $last_bar ) { return $whole; } else { return substr($whole, 0, $last_bar); } } /** * __() - Retrieve a translated string * * __() is a convenience function which retrieves the translated * string from the translate(). * * @see translate() An alias of translate() * @since 2.1.0 * * @param string $text Text to translate * @param string $domain Optional. Domain to retrieve the translated text * @return string Translated text */ function __($text, $domain = 'default') { return translate($text, $domain); } // . /** * _e() - Display a translated string * * _e() is a convenience function which displays the returned * translated text from translate(). * * @see translate() Echos returned translate() string * @since 1.2.0 * * @param string $text Text to translate * @param string $domain Optional. Domain to retrieve the translated text */ function _e($text, $domain = 'default') { echo translate($text, $domain); } /** * _c() - Retrieve context translated string * * Quite a few times, there will be collisions with similar * translatable text found in more than two places but with * different translated context. * * In order to use the separate contexts, the _c() function * is used and the translatable string uses a pipe ('|') * which has the context the string is in. * * When the translated string is returned, it is everything * before the pipe, not including the pipe character. If * there is no pipe in the translated text then everything * is returned. * * @since 2.2.0 * * @param string $text Text to translate * @param string $domain Optional. Domain to retrieve the translated text * @return string Translated context string without pipe */ function _c($text, $domain = 'default') { return translate_with_context($text, $domain); } /** * __ngettext() - Retrieve the plural or single form based on the amount * * If the domain is not set in the $l10n list, then a comparsion * will be made and either $plural or $single parameters returned. * * If the domain does exist, then the parameters $single, $plural, * and $number will first be passed to the domain's ngettext method. * Then it will be passed to the 'ngettext' filter hook along with * the same parameters. The expected type will be a string. * * @since 1.2.0 * @uses $l10n Gets list of domain translated string (gettext_reader) objects * @uses apply_filters() Calls 'ngettext' hook on domains text returned, * along with $single, $plural, and $number parameters. Expected to return string. * * @param string $single The text that will be used if $number is 1 * @param string $plural The text that will be used if $number is not 1 * @param int $number The number to compare against to use either $single or $plural * @param string $domain Optional. The domain identifier the text should be retrieved in * @return string Either $single or $plural translated text */ function __ngettext($single, $plural, $number, $domain = 'default') { global $l10n; if (isset($l10n[$domain])) { return apply_filters('ngettext', $l10n[$domain]->ngettext($single, $plural, $number), $single, $plural, $number); } else { if ($number != 1) return $plural; else return $single; } } /** * __ngettext_noop() - register plural strings in POT file, but don't translate them * * Used when you want do keep structures with translatable plural strings and * use them later. * * Example: * $messages = array( * 'post' => ngettext_noop('%s post', '%s posts'), * 'page' => ngettext_noop('%s pages', '%s pages') * ); * ... * $message = $messages[$type]; * $usable_text = sprintf(__ngettext($message[0], $message[1], $count), $count); * * @since 2.5 * @param $single Single form to be i18ned * @param $plural Plural form to be i18ned * @param $number Not used, here for compatibility with __ngettext, optional * @param $domain Not used, here for compatibility with __ngettext, optional * @return array array($single, $plural) */ function __ngettext_noop($single, $plural, $number=1, $domain = 'default') { return array($single, $plural); } /** * load_textdomain() - Loads MO file into the list of domains * * If the domain already exists, the inclusion will fail. If the * MO file is not readable, the inclusion will fail. * * On success, the mofile will be placed in the $l10n global by * $domain and will be an gettext_reader object. * * @since 1.5.0 * @uses $l10n Gets list of domain translated string (gettext_reader) objects * @uses CacheFileReader Reads the MO file * @uses gettext_reader Allows for retrieving translated strings * * @param string $domain Unique identifier for retrieving translated strings * @param string $mofile Path to the .mo file * @return null On failure returns null and also on success returns nothing. */ function load_textdomain($domain, $mofile) { global $l10n; if ( is_readable($mofile)) $input = new CachedFileReader($mofile); else return; $gettext = new gettext_reader($input); if (isset($l10n[$domain])) { $l10n[$domain]->load_tables(); $gettext->load_tables(); $l10n[$domain]->cache_translations = array_merge($gettext->cache_translations, $l10n[$domain]->cache_translations); } else $l10n[$domain] = $gettext; unset($input, $gettext); } /** * load_default_textdomain() - Loads default translated strings based on locale * * Loads the .mo file in WP_LANG_DIR constant path from WordPress root. * The translated (.mo) file is named based off of the locale. * * @since 1.5.0 */ function load_default_textdomain() { $locale = get_locale(); $mofile = WP_LANG_DIR . "/$locale.mo"; load_textdomain('default', $mofile); } /** * load_plugin_textdomain() - Loads the plugin's translated strings * * If the path is not given then it will be the root of the plugin * directory. The .mo file should be named based on the domain with a * dash followed by a dash, and then the locale exactly. * * @since 1.5.0 * * @param string $domain Unique identifier for retrieving translated strings * @param string $abs_rel_path Optional. Relative path to ABSPATH of a folder, * where the .mo file resides. Deprecated, but still functional until 2.7 * @param string $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR. This is the preferred argument to use. It takes precendence over $abs_rel_path */ function load_plugin_textdomain($domain, $abs_rel_path = false, $plugin_rel_path = false) { $locale = get_locale(); if ( false !== $plugin_rel_path ) $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/'); else if ( false !== $abs_rel_path) $path = ABSPATH . trim( $abs_rel_path, '/'); else $path = WP_PLUGIN_DIR; $mofile = $path . '/'. $domain . '-' . $locale . '.mo'; load_textdomain($domain, $mofile); } /** * load_theme_textdomain() - Includes theme's translated strings for the theme * * If the current locale exists as a .mo file in the theme's root directory, it * will be included in the translated strings by the $domain. * * The .mo files must be named based on the locale exactly. * * @since 1.5.0 * * @param string $domain Unique identifier for retrieving translated strings */ function load_theme_textdomain($domain) { $locale = get_locale(); $mofile = get_template_directory() . "/$locale.mo"; load_textdomain($domain, $mofile); } ?> blogs/wp-includes/wpmu-default-filters.php0000644000000000000000000000343011077635520017713 0ustar rootrootblogs/wp-includes/cron.php0000644000000000000000000001237511077635520014604 0ustar rootroot false, 'args' => $args ); uksort( $crons, "strnatcasecmp" ); _set_cron_array( $crons ); } function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) { $crons = _get_cron_array(); $schedules = wp_get_schedules(); $key = md5(serialize($args)); if ( !isset( $schedules[$recurrence] ) ) return false; $crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] ); uksort( $crons, "strnatcasecmp" ); _set_cron_array( $crons ); } function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) { $crons = _get_cron_array(); $schedules = wp_get_schedules(); $key = md5(serialize($args)); $interval = 0; // First we try to get it from the schedule if ( 0 == $interval ) $interval = $schedules[$recurrence]['interval']; // Now we try to get it from the saved interval in case the schedule disappears if ( 0 == $interval ) $interval = $crons[$timestamp][$hook][$key]['interval']; // Now we assume something is wrong and fail to schedule if ( 0 == $interval ) return false; while ( $timestamp < time() + 1 ) $timestamp += $interval; wp_schedule_event( $timestamp, $recurrence, $hook, $args ); } function wp_unschedule_event( $timestamp, $hook, $args = array() ) { $crons = _get_cron_array(); $key = md5(serialize($args)); unset( $crons[$timestamp][$hook][$key] ); if ( empty($crons[$timestamp][$hook]) ) unset( $crons[$timestamp][$hook] ); if ( empty($crons[$timestamp]) ) unset( $crons[$timestamp] ); _set_cron_array( $crons ); } function wp_clear_scheduled_hook( $hook ) { $args = array_slice( func_get_args(), 1 ); while ( $timestamp = wp_next_scheduled( $hook, $args ) ) wp_unschedule_event( $timestamp, $hook, $args ); } function wp_next_scheduled( $hook, $args = array() ) { $crons = _get_cron_array(); $key = md5(serialize($args)); if ( empty($crons) ) return false; foreach ( $crons as $timestamp => $cron ) { if ( isset( $cron[$hook][$key] ) ) return $timestamp; } return false; } function spawn_cron() { $crons = _get_cron_array(); if ( !is_array($crons) ) return; $keys = array_keys( $crons ); if ( array_shift( $keys ) > time() ) return; $cron_url = get_option( 'siteurl' ) . '/wp-cron.php'; $parts = parse_url( $cron_url ); if ($parts['scheme'] == 'https') { // support for SSL was added in 4.3.0 if (version_compare(phpversion(), '4.3.0', '>=') && function_exists('openssl_open')) { $port = isset($parts['port']) ? $parts['port'] : 443; $argyle = @fsockopen('ssl://' . $parts['host'], $port, $errno, $errstr, 0.01); } else { return false; } } else { $port = isset($parts['port']) ? $parts['port'] : 80; $argyle = @ fsockopen( $parts['host'], $port, $errno, $errstr, 0.01 ); } if ( $argyle ) fputs( $argyle, "GET {$parts['path']}?check=" . wp_hash('187425') . " HTTP/1.0\r\n" . "Host: {$_SERVER['HTTP_HOST']}\r\n\r\n" ); } function wp_cron() { // Prevent infinite loops caused by lack of wp-cron.php if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false ) return; $crons = _get_cron_array(); if ( !is_array($crons) ) return; $keys = array_keys( $crons ); if ( isset($keys[0]) && $keys[0] > time() ) return; $schedules = wp_get_schedules(); foreach ( $crons as $timestamp => $cronhooks ) { if ( $timestamp > time() ) break; foreach ( $cronhooks as $hook => $args ) { if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) ) continue; spawn_cron(); break 2; } } } function wp_get_schedules() { $schedules = array( 'hourly' => array( 'interval' => 3600, 'display' => __('Once Hourly') ), 'twicedaily' => array( 'interval' => 43200, 'display' => __('Twice Daily') ), 'daily' => array( 'interval' => 86400, 'display' => __('Once Daily') ), ); return array_merge( apply_filters( 'cron_schedules', array() ), $schedules ); } function wp_get_schedule($hook, $args = array()) { $crons = _get_cron_array(); $key = md5(serialize($args)); if ( empty($crons) ) return false; foreach ( $crons as $timestamp => $cron ) { if ( isset( $cron[$hook][$key] ) ) return $cron[$hook][$key]['schedule']; } return false; } // // Private functions // function _get_cron_array() { $cron = get_option('cron'); if ( ! is_array($cron) ) return false; if ( !isset($cron['version']) ) $cron = _upgrade_cron_array($cron); unset($cron['version']); return $cron; } function _set_cron_array($cron) { $cron['version'] = 2; update_option( 'cron', $cron ); } function _upgrade_cron_array($cron) { if ( isset($cron['version']) && 2 == $cron['version']) return $cron; $new_cron = array(); foreach ($cron as $timestamp => $hooks) { foreach ( $hooks as $hook => $args ) { $key = md5(serialize($args['args'])); $new_cron[$timestamp][$hook][$key] = $args; } } $new_cron['version'] = 2; update_option( 'cron', $new_cron ); return $new_cron; } ?> blogs/wp-includes/rewrite.php0000644000000000000000000010234211077635520015316 0ustar rootrootadd_rule($regex, $redirect, $after); } //Add a new tag (like %postname%) //warning: you must call this on init or earlier, otherwise the query var addition stuff won't work function add_rewrite_tag($tagname, $regex) { //validation if (strlen($tagname) < 3 || $tagname{0} != '%' || $tagname{strlen($tagname)-1} != '%') { return; } $qv = trim($tagname, '%'); global $wp_rewrite, $wp; $wp->add_query_var($qv); $wp_rewrite->add_rewrite_tag($tagname, $regex, $qv . '='); } //Add a new feed type like /atom1/ function add_feed($feedname, $function) { global $wp_rewrite; if (!in_array($feedname, $wp_rewrite->feeds)) { //override the file if it is $wp_rewrite->feeds[] = $feedname; } $hook = 'do_feed_' . $feedname; // Remove default function hook remove_action($hook, $hook, 10, 1); add_action($hook, $function, 10, 1); return $hook; } define('EP_PERMALINK', 1 ); define('EP_ATTACHMENT', 2 ); define('EP_DATE', 4 ); define('EP_YEAR', 8 ); define('EP_MONTH', 16 ); define('EP_DAY', 32 ); define('EP_ROOT', 64 ); define('EP_COMMENTS', 128 ); define('EP_SEARCH', 256 ); define('EP_CATEGORIES', 512 ); define('EP_TAGS', 1024 ); define('EP_AUTHORS', 2048); define('EP_PAGES', 4096); //pseudo-places define('EP_NONE', 0 ); define('EP_ALL', 8191); //and an endpoint, like /trackback/ function add_rewrite_endpoint($name, $places) { global $wp_rewrite; $wp_rewrite->add_endpoint($name, $places); } /** * _wp_filter_taxonomy_base() - filter the URL base for taxonomies, to remove any manually prepended /index.php/ * @param string $base the taxonomy base that we're going to filter * @return string * @author Mark Jaquith */ function _wp_filter_taxonomy_base( $base ) { if ( !empty( $base ) ) { $base = preg_replace( '|^/index\.php/|', '', $base ); $base = trim( $base, '/' ); } return $base; } // examine a url (supposedly from this blog) and try to // determine the post ID it represents. function url_to_postid($url) { global $wp_rewrite; $url = apply_filters('url_to_postid', $url); // First, check to see if there is a 'p=N' or 'page_id=N' to match against if ( preg_match('#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values) ) { $id = absint($values[2]); if ($id) return $id; } // Check to see if we are using rewrite rules $rewrite = $wp_rewrite->wp_rewrite_rules(); // Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so we're out of options if ( empty($rewrite) ) return 0; // $url cleanup by Mark Jaquith // This fixes things like #anchors, ?query=strings, missing 'www.', // added 'www.', or added 'index.php/' that will mess up our WP_Query // and return a false negative // Get rid of the #anchor $url_split = explode('#', $url); $url = $url_split[0]; // Get rid of URL ?query=string $url_split = explode('?', $url); $url = $url_split[0]; // Add 'www.' if it is absent and should be there if ( false !== strpos(get_option('home'), '://www.') && false === strpos($url, '://www.') ) $url = str_replace('://', '://www.', $url); // Strip 'www.' if it is present and shouldn't be if ( false === strpos(get_option('home'), '://www.') ) $url = str_replace('://www.', '://', $url); // Strip 'index.php/' if we're not using path info permalinks if ( !$wp_rewrite->using_index_permalinks() ) $url = str_replace('index.php/', '', $url); if ( false !== strpos($url, get_option('home')) ) { // Chop off http://domain.com $url = str_replace(get_option('home'), '', $url); } else { // Chop off /path/to/blog $home_path = parse_url(get_option('home')); $home_path = $home_path['path']; $url = str_replace($home_path, '', $url); } // Trim leading and lagging slashes $url = trim($url, '/'); $request = $url; // Done with cleanup // Look for matches. $request_match = $request; foreach ($rewrite as $match => $query) { // If the requesting file is the anchor of the match, prepend it // to the path info. if ( (! empty($url)) && (strpos($match, $url) === 0) && ($url != $request)) { $request_match = $url . '/' . $request; } if ( preg_match("!^$match!", $request_match, $matches) ) { // Got a match. // Trim the query of everything up to the '?'. $query = preg_replace("!^.+\?!", '', $query); // Substitute the substring matches into the query. eval("\$query = \"" . addslashes($query) . "\";"); // Filter out non-public query vars global $wp; parse_str($query, $query_vars); $query = array(); foreach ( $query_vars as $key => $value ) { if ( in_array($key, $wp->public_query_vars) ) $query[$key] = $value; } // Do the query $query = new WP_Query($query); if ( $query->is_single || $query->is_page ) return $query->post->ID; else return 0; } } return 0; } /* WP_Rewrite class *******************************************************************************/ class WP_Rewrite { var $permalink_structure; var $use_trailing_slashes; var $category_base; var $tag_base; var $category_structure; var $tag_structure; var $author_base = 'author'; var $author_structure; var $date_structure; var $page_structure; var $search_base = 'search'; var $search_structure; var $comments_base = 'comments'; var $feed_base = 'feed'; var $comments_feed_structure; var $feed_structure; var $front; var $root = ''; var $index = 'index.php'; var $matches = ''; var $rules; var $extra_rules = array(); //those not generated by the class, see add_rewrite_rule() var $extra_rules_top = array(); //those not generated by the class, see add_rewrite_rule() var $non_wp_rules = array(); //rules that don't redirect to WP's index.php var $extra_permastructs = array(); var $endpoints; var $use_verbose_rules = false; var $use_verbose_page_rules = true; var $rewritecode = array( '%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%postname%', '%post_id%', '%category%', '%tag%', '%author%', '%pagename%', '%search%' ); var $rewritereplace = array( '([0-9]{4})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([^/]+)', '([0-9]+)', '(.+?)', '(.+?)', '([^/]+)', '([^/]+?)', '(.+)' ); var $queryreplace = array ( 'year=', 'monthnum=', 'day=', 'hour=', 'minute=', 'second=', 'name=', 'p=', 'category_name=', 'tag=', 'author_name=', 'pagename=', 's=' ); var $feeds = array ( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); function using_permalinks() { if (empty($this->permalink_structure)) return false; else return true; } function using_index_permalinks() { if (empty($this->permalink_structure)) { return false; } // If the index is not in the permalink, we're using mod_rewrite. if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) { return true; } return false; } function using_mod_rewrite_permalinks() { if ( $this->using_permalinks() && ! $this->using_index_permalinks()) return true; else return false; } function preg_index($number) { $match_prefix = '$'; $match_suffix = ''; if (! empty($this->matches)) { $match_prefix = '$' . $this->matches . '['; $match_suffix = ']'; } return "$match_prefix$number$match_suffix"; } function page_uri_index() { global $wpdb; //get pages in order of hierarchy, i.e. children after parents $posts = get_page_hierarchy($wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'page'")); //now reverse it, because we need parents after children for rewrite rules to work properly $posts = array_reverse($posts, true); $page_uris = array(); $page_attachment_uris = array(); if ( !$posts ) return array( array(), array() ); foreach ($posts as $id => $post) { // URL => page name $uri = get_page_uri($id); $attachments = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = %d", $id )); if ( $attachments ) { foreach ( $attachments as $attachment ) { $attach_uri = get_page_uri($attachment->ID); $page_attachment_uris[$attach_uri] = $attachment->ID; } } $page_uris[$uri] = $id; } return array( $page_uris, $page_attachment_uris ); } function page_rewrite_rules() { $rewrite_rules = array(); $page_structure = $this->get_page_permastruct(); if ( ! $this->use_verbose_page_rules ) { $this->add_rewrite_tag('%pagename%', "(.+?)", 'pagename='); $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); return $rewrite_rules; } $page_uris = $this->page_uri_index(); $uris = $page_uris[0]; $attachment_uris = $page_uris[1]; if( is_array( $attachment_uris ) ) { foreach ($attachment_uris as $uri => $pagename) { $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment='); $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); } } if( is_array( $uris ) ) { foreach ($uris as $uri => $pagename) { $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename='); $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); } } return $rewrite_rules; } function get_date_permastruct() { if (isset($this->date_structure)) { return $this->date_structure; } if (empty($this->permalink_structure)) { $this->date_structure = ''; return false; } // The date permalink must have year, month, and day separated by slashes. $endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%'); $this->date_structure = ''; $date_endian = ''; foreach ($endians as $endian) { if (false !== strpos($this->permalink_structure, $endian)) { $date_endian= $endian; break; } } if ( empty($date_endian) ) $date_endian = '%year%/%monthnum%/%day%'; // Do not allow the date tags and %post_id% to overlap in the permalink // structure. If they do, move the date tags to $front/date/. $front = $this->front; preg_match_all('/%.+?%/', $this->permalink_structure, $tokens); $tok_index = 1; foreach ($tokens[0] as $token) { if ( ($token == '%post_id%') && ($tok_index <= 3) ) { $front = $front . 'date/'; break; } $tok_index++; } $this->date_structure = $front . $date_endian; return $this->date_structure; } function get_year_permastruct() { $structure = $this->get_date_permastruct($this->permalink_structure); if (empty($structure)) { return false; } $structure = str_replace('%monthnum%', '', $structure); $structure = str_replace('%day%', '', $structure); $structure = preg_replace('#/+#', '/', $structure); return $structure; } function get_month_permastruct() { $structure = $this->get_date_permastruct($this->permalink_structure); if (empty($structure)) { return false; } $structure = str_replace('%day%', '', $structure); $structure = preg_replace('#/+#', '/', $structure); return $structure; } function get_day_permastruct() { return $this->get_date_permastruct($this->permalink_structure); } function get_category_permastruct() { if (isset($this->category_structure)) { return $this->category_structure; } if (empty($this->permalink_structure)) { $this->category_structure = ''; return false; } if (empty($this->category_base)) $this->category_structure = trailingslashit( $this->front . 'category' ); else $this->category_structure = trailingslashit( '/' . $this->root . $this->category_base ); $this->category_structure .= '%category%'; return $this->category_structure; } function get_tag_permastruct() { if (isset($this->tag_structure)) { return $this->tag_structure; } if (empty($this->permalink_structure)) { $this->tag_structure = ''; return false; } if (empty($this->tag_base)) $this->tag_structure = trailingslashit( $this->front . 'tag' ); else $this->tag_structure = trailingslashit( '/' . $this->root . $this->tag_base ); $this->tag_structure .= '%tag%'; return $this->tag_structure; } function get_extra_permastruct($name) { if ( isset($this->extra_permastructs[$name]) ) return $this->extra_permastructs[$name]; return false; } function get_author_permastruct() { if (isset($this->author_structure)) { return $this->author_structure; } if (empty($this->permalink_structure)) { $this->author_structure = ''; return false; } $this->author_structure = $this->front . $this->author_base . '/%author%'; return $this->author_structure; } function get_search_permastruct() { if (isset($this->search_structure)) { return $this->search_structure; } if (empty($this->permalink_structure)) { $this->search_structure = ''; return false; } $this->search_structure = $this->root . $this->search_base . '/%search%'; return $this->search_structure; } function get_page_permastruct() { if (isset($this->page_structure)) { return $this->page_structure; } if (empty($this->permalink_structure)) { $this->page_structure = ''; return false; } $this->page_structure = $this->root . '%pagename%'; return $this->page_structure; } function get_feed_permastruct() { if (isset($this->feed_structure)) { return $this->feed_structure; } if (empty($this->permalink_structure)) { $this->feed_structure = ''; return false; } $this->feed_structure = $this->root . $this->feed_base . '/%feed%'; return $this->feed_structure; } function get_comment_feed_permastruct() { if (isset($this->comment_feed_structure)) { return $this->comment_feed_structure; } if (empty($this->permalink_structure)) { $this->comment_feed_structure = ''; return false; } $this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%'; return $this->comment_feed_structure; } function add_rewrite_tag($tag, $pattern, $query) { // If the tag already exists, replace the existing pattern and query for // that tag, otherwise add the new tag, pattern, and query to the end of // the arrays. $position = array_search($tag, $this->rewritecode); if (FALSE !== $position && NULL !== $position) { $this->rewritereplace[$position] = $pattern; $this->queryreplace[$position] = $query; } else { $this->rewritecode[] = $tag; $this->rewritereplace[] = $pattern; $this->queryreplace[] = $query; } } //the main WP_Rewrite function. generate the rules from permalink structure function generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true) { //build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/? $feedregex2 = ''; foreach ($this->feeds as $feed_name) { $feedregex2 .= $feed_name . '|'; } $feedregex2 = '(' . trim($feedregex2, '|') . ')/?$'; //$feedregex is identical but with /feed/ added on as well, so URLs like /feed/atom //and /atom are both possible $feedregex = $this->feed_base . '/' . $feedregex2; //build a regex to match the trackback and page/xx parts of URLs $trackbackregex = 'trackback/?$'; $pageregex = 'page/?([0-9]{1,})/?$'; //build up an array of endpoint regexes to append => queries to append if ($endpoints) { $ep_query_append = array (); foreach ($this->endpoints as $endpoint) { //match everything after the endpoint name, but allow for nothing to appear there $epmatch = $endpoint[1] . '(/(.*))?/?$'; //this will be appended on to the rest of the query for each dir $epquery = '&' . $endpoint[1] . '='; $ep_query_append[$epmatch] = array ( $endpoint[0], $epquery ); } } //get everything up to the first rewrite tag $front = substr($permalink_structure, 0, strpos($permalink_structure, '%')); //build an array of the tags (note that said array ends up being in $tokens[0]) preg_match_all('/%.+?%/', $permalink_structure, $tokens); $num_tokens = count($tokens[0]); $index = $this->index; //probably 'index.php' $feedindex = $index; $trackbackindex = $index; //build a list from the rewritecode and queryreplace arrays, that will look something like //tagname=$matches[i] where i is the current $i for ($i = 0; $i < $num_tokens; ++$i) { if (0 < $i) { $queries[$i] = $queries[$i - 1] . '&'; } else { $queries[$i] = ''; } $query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1); $queries[$i] .= $query_token; } //get the structure, minus any cruft (stuff that isn't tags) at the front $structure = $permalink_structure; if ($front != '/') { $structure = str_replace($front, '', $structure); } //create a list of dirs to walk over, making rewrite rules for each level //so for example, a $structure of /%year%/%month%/%postname% would create //rewrite rules for /%year%/, /%year%/%month%/ and /%year%/%month%/%postname% $structure = trim($structure, '/'); if ($walk_dirs) { $dirs = explode('/', $structure); } else { $dirs[] = $structure; } $num_dirs = count($dirs); //strip slashes from the front of $front $front = preg_replace('|^/+|', '', $front); //the main workhorse loop $post_rewrite = array(); $struct = $front; for ($j = 0; $j < $num_dirs; ++$j) { //get the struct for this dir, and trim slashes off the front $struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above $struct = ltrim($struct, '/'); //replace tags with regexes $match = str_replace($this->rewritecode, $this->rewritereplace, $struct); //make a list of tags, and store how many there are in $num_toks $num_toks = preg_match_all('/%.+?%/', $struct, $toks); //get the 'tagname=$matches[i]' $query = ( isset($queries) && is_array($queries) ) ? $queries[$num_toks - 1] : ''; //set up $ep_mask_specific which is used to match more specific URL types switch ($dirs[$j]) { case '%year%': $ep_mask_specific = EP_YEAR; break; case '%monthnum%': $ep_mask_specific = EP_MONTH; break; case '%day%': $ep_mask_specific = EP_DAY; break; } //create query for /page/xx $pagematch = $match . $pageregex; $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1); //create query for /feed/(feed|atom|rss|rss2|rdf) $feedmatch = $match . $feedregex; $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); //create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex) $feedmatch2 = $match . $feedregex2; $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); //if asked to, turn the feed queries into comment feed ones if ($forcomments) { $feedquery .= '&withcomments=1'; $feedquery2 .= '&withcomments=1'; } //start creating the array of rewrites for this dir $rewrite = array(); if ($feed) //...adding on /feed/ regexes => queries $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2); if ($paged) //...and /page/xx ones $rewrite = array_merge($rewrite, array($pagematch => $pagequery)); //do endpoints if ($endpoints) { foreach ($ep_query_append as $regex => $ep) { //add the endpoints on if the mask fits if ($ep[0] & $ep_mask || $ep[0] & $ep_mask_specific) { $rewrite[$match . $regex] = $index . '?' . $query . $ep[1] . $this->preg_index($num_toks + 2); } } } //if we've got some tags in this dir if ($num_toks) { $post = false; $page = false; //check to see if this dir is permalink-level: i.e. the structure specifies an //individual post. Do this by checking it contains at least one of 1) post name, //2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and //minute all present). Set these flags now as we need them for the endpoints. if (strpos($struct, '%postname%') !== false || strpos($struct, '%post_id%') !== false || strpos($struct, '%pagename%') !== false || (strpos($struct, '%year%') !== false && strpos($struct, '%monthnum%') !== false && strpos($struct, '%day%') !== false && strpos($struct, '%hour%') !== false && strpos($struct, '%minute%') !== false && strpos($struct, '%second%') !== false)) { $post = true; if (strpos($struct, '%pagename%') !== false) $page = true; } //if we're creating rules for a permalink, do all the endpoints like attachments etc if ($post) { $post = true; //create query and regex for trackback $trackbackmatch = $match . $trackbackregex; $trackbackquery = $trackbackindex . '?' . $query . '&tb=1'; //trim slashes from the end of the regex for this dir $match = rtrim($match, '/'); //get rid of brackets $submatchbase = str_replace(array('(',')'),'',$match); //add a rule for at attachments, which take the form of /some-text $sub1 = $submatchbase . '/([^/]+)/'; $sub1tb = $sub1 . $trackbackregex; //add trackback regex /trackback/... $sub1feed = $sub1 . $feedregex; //and /feed/(atom|...) $sub1feed2 = $sub1 . $feedregex2; //and /(feed|atom...) //add an ? as we don't have to match that last slash, and finally a $ so we //match to the end of the URL //add another rule to match attachments in the explicit form: ///attachment/some-text $sub2 = $submatchbase . '/attachment/([^/]+)/'; $sub2tb = $sub2 . $trackbackregex; //and add trackbacks /attachment/trackback $sub2feed = $sub2 . $feedregex; //feeds, /attachment/feed/(atom|...) $sub2feed2 = $sub2 . $feedregex2; //and feeds again on to this /attachment/(feed|atom...) //create queries for these extra tag-ons we've just dealt with $subquery = $index . '?attachment=' . $this->preg_index(1); $subtbquery = $subquery . '&tb=1'; $subfeedquery = $subquery . '&feed=' . $this->preg_index(2); //do endpoints for attachments if (! empty($endpoint) ) { foreach ($ep_query_append as $regex => $ep) { if ($ep[0] & EP_ATTACHMENT) { $rewrite[$sub1 . $regex] = $subquery . '?' . $ep[1] . $this->preg_index(2); $rewrite[$sub2 . $regex] = $subquery . '?' . $ep[1] . $this->preg_index(2); } } } //now we've finished with endpoints, finish off the $sub1 and $sub2 matches $sub1 .= '?$'; $sub2 .= '?$'; //allow URLs like /2 for /page/2 $match = $match . '(/[0-9]+)?/?$'; $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1); } else { //not matching a permalink so this is a lot simpler //close the match and finalise the query $match .= '?$'; $query = $index . '?' . $query; } //create the final array for this dir by joining the $rewrite array (which currently //only contains rules/queries for trackback, pages etc) to the main regex/query for //this dir $rewrite = array_merge($rewrite, array($match => $query)); //if we're matching a permalink, add those extras (attachments etc) on if ($post) { //add trackback $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite); //add regexes/queries for attachments, attachment trackbacks and so on if ( ! $page ) //require /attachment/stuff form for pages because of confusion with subpages $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery)); $rewrite = array_merge(array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery), $rewrite); } } //if($num_toks) //add the rules for this dir to the accumulating $post_rewrite $post_rewrite = array_merge($rewrite, $post_rewrite); } //foreach ($dir) return $post_rewrite; //the finished rules. phew! } function generate_rewrite_rule($permalink_structure, $walk_dirs = false) { return $this->generate_rewrite_rules($permalink_structure, EP_NONE, false, false, false, $walk_dirs); } /* rewrite_rules * Construct rewrite matches and queries from permalink structure. * Returns an associate array of matches and queries. */ function rewrite_rules() { $rewrite = array(); if (empty($this->permalink_structure)) { return $rewrite; } // robots.txt $robots_rewrite = array('robots.txt$' => $this->index . '?robots=1'); //Default Feed rules - These are require to allow for the direct access files to work with permalink structure starting with %category% $default_feeds = array( '.*wp-atom.php$' => $this->index .'?feed=atom', '.*wp-rdf.php$' => $this->index .'?feed=rdf', '.*wp-rss.php$' => $this->index .'?feed=rss', '.*wp-rss2.php$' => $this->index .'?feed=rss2', '.*wp-feed.php$' => $this->index .'?feed=feed', '.*wp-commentsrss2.php$' => $this->index . '?feed=rss2&withcomments=1'); // Post $post_rewrite = $this->generate_rewrite_rules($this->permalink_structure, EP_PERMALINK); $post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite); // Date $date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct(), EP_DATE); $date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite); // Root $root_rewrite = $this->generate_rewrite_rules($this->root . '/', EP_ROOT); $root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite); // Comments $comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, EP_COMMENTS, true, true, true, false); $comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite); // Search $search_structure = $this->get_search_permastruct(); $search_rewrite = $this->generate_rewrite_rules($search_structure, EP_SEARCH); $search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite); // Categories $category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct(), EP_CATEGORIES); $category_rewrite = apply_filters('category_rewrite_rules', $category_rewrite); // Tags $tag_rewrite = $this->generate_rewrite_rules($this->get_tag_permastruct(), EP_TAGS); $tag_rewrite = apply_filters('tag_rewrite_rules', $tag_rewrite); // Authors $author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct(), EP_AUTHORS); $author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite); // Pages $page_rewrite = $this->page_rewrite_rules(); $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite); // Extra permastructs foreach ( $this->extra_permastructs as $permastruct ) $this->extra_rules_top = array_merge($this->extra_rules_top, $this->generate_rewrite_rules($permastruct, EP_NONE)); // Put them together. if ( $this->use_verbose_page_rules ) $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $tag_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules); else $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $tag_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules); do_action_ref_array('generate_rewrite_rules', array(&$this)); $this->rules = apply_filters('rewrite_rules_array', $this->rules); return $this->rules; } function wp_rewrite_rules() { $this->rules = get_option('rewrite_rules'); if ( empty($this->rules) ) { $this->matches = 'matches'; $this->rewrite_rules(); update_option('rewrite_rules', $this->rules); } return $this->rules; } function mod_rewrite_rules() { if ( ! $this->using_permalinks()) { return ''; } $site_root = parse_url(get_option('siteurl')); $site_root = trailingslashit($site_root['path']); $home_root = parse_url(get_option('home')); $home_root = trailingslashit($home_root['path']); $rules = "\n"; $rules .= "RewriteEngine On\n"; $rules .= "RewriteBase $home_root\n"; //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all) foreach ($this->non_wp_rules as $match => $query) { // Apache 1.3 does not support the reluctant (non-greedy) modifier. $match = str_replace('.+?', '.+', $match); // If the match is unanchored and greedy, prepend rewrite conditions // to avoid infinite redirects and eclipsing of real files. if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) { //nada. } $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; } if ($this->use_verbose_rules) { $this->matches = ''; $rewrite = $this->rewrite_rules(); $num_rules = count($rewrite); $rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" . "RewriteCond %{REQUEST_FILENAME} -d\n" . "RewriteRule ^.*$ - [S=$num_rules]\n"; foreach ($rewrite as $match => $query) { // Apache 1.3 does not support the reluctant (non-greedy) modifier. $match = str_replace('.+?', '.+', $match); // If the match is unanchored and greedy, prepend rewrite conditions // to avoid infinite redirects and eclipsing of real files. if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) { //nada. } if (strpos($query, $this->index) !== false) { $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; } else { $rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n"; } } } else { $rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" . "RewriteCond %{REQUEST_FILENAME} !-d\n" . "RewriteRule . {$home_root}{$this->index} [L]\n"; } $rules .= "\n"; $rules = apply_filters('mod_rewrite_rules', $rules); $rules = apply_filters('rewrite_rules', $rules); // Deprecated return $rules; } //Add a straight rewrite rule function add_rule($regex, $redirect, $after = 'bottom') { //get everything up to the first ? $index = (strpos($redirect, '?') == false ? strlen($redirect) : strpos($redirect, '?')); $front = substr($redirect, 0, $index); if ($front != $this->index) { //it doesn't redirect to WP's index.php $this->add_external_rule($regex, $redirect); } else { if ( 'bottom' == $after) $this->extra_rules = array_merge($this->extra_rules, array($regex => $redirect)); else $this->extra_rules_top = array_merge($this->extra_rules_top, array($regex => $redirect)); //$this->extra_rules[$regex] = $redirect; } } //add a rule that doesn't redirect to index.php function add_external_rule($regex, $redirect) { $this->non_wp_rules[$regex] = $redirect; } //add an endpoint, like /trackback/, to be inserted after certain URL types (specified in $places) function add_endpoint($name, $places) { global $wp; $this->endpoints[] = array ( $places, $name ); $wp->add_query_var($name); } function add_permastruct($name, $struct, $with_front = true) { if ( $with_front ) $struct = $this->front . $struct; $this->extra_permastructs[$name] = $struct; } function flush_rules() { delete_option('rewrite_rules'); $this->wp_rewrite_rules(); if ( function_exists('save_mod_rewrite_rules') ) save_mod_rewrite_rules(); } function init() { $this->extra_rules = $this->non_wp_rules = $this->endpoints = array(); $this->permalink_structure = get_option('permalink_structure'); $this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%')); $this->root = ''; if ($this->using_index_permalinks()) { $this->root = $this->index . '/'; } $this->category_base = get_option( 'category_base' ); $this->tag_base = get_option( 'tag_base' ); unset($this->category_structure); unset($this->author_structure); unset($this->date_structure); unset($this->page_structure); unset($this->search_structure); unset($this->feed_structure); unset($this->comment_feed_structure); $this->use_trailing_slashes = ( substr($this->permalink_structure, -1, 1) == '/' ) ? true : false; // Enable generic rules for pages if permalink structure doesn't begin with a wildcard. $structure = ltrim($this->permalink_structure, '/'); if ( $this->using_index_permalinks() ) $structure = ltrim($this->permalink_structure, $this->index . '/'); if ( 0 === strpos($structure, '%postname%') || 0 === strpos($structure, '%category%') || 0 === strpos($structure, '%tag%') || 0 === strpos($structure, '%author%') ) $this->use_verbose_page_rules = true; else $this->use_verbose_page_rules = false; } function set_permalink_structure($permalink_structure) { if ($permalink_structure != $this->permalink_structure) { update_option('permalink_structure', $permalink_structure); $this->init(); } } function set_category_base($category_base) { if ($category_base != $this->category_base) { update_option('category_base', $category_base); $this->init(); } } function set_tag_base( $tag_base ) { if ( $tag_base != $this->tag_base ) { update_option( 'tag_base', $tag_base ); $this->init(); } } function WP_Rewrite() { $this->init(); } } ?> blogs/wp-includes/widgets.php0000644000000000000000000015563311077635520015316 0ustar rootroot 1 ) { $_args['name'] = isset($args['name']) ? sprintf($args['name'], $i) : sprintf(__('Sidebar %d'), $i); } else { $_args['name'] = isset($args['name']) ? $args['name'] : __('Sidebar'); } if (isset($args['id'])) { $_args['id'] = $args['id']; } else { $n = count($wp_registered_sidebars); do { $n++; $_args['id'] = "sidebar-$n"; } while (isset($wp_registered_sidebars[$_args['id']])); } register_sidebar($_args); } } function register_sidebar($args = array()) { global $wp_registered_sidebars; if ( is_string($args) ) parse_str($args, $args); $i = count($wp_registered_sidebars) + 1; $defaults = array( 'name' => sprintf(__('Sidebar %d'), $i ), 'id' => "sidebar-$i", 'before_widget' => '
  • ', 'after_widget' => "
  • \n", 'before_title' => '

    ', 'after_title' => "

    \n", ); $sidebar = array_merge($defaults, (array) $args); $wp_registered_sidebars[$sidebar['id']] = $sidebar; return $sidebar['id']; } function unregister_sidebar( $name ) { global $wp_registered_sidebars; if ( isset( $wp_registered_sidebars[$name] ) ) unset( $wp_registered_sidebars[$name] ); } function register_sidebar_widget($name, $output_callback, $classname = '') { // Compat if ( is_array($name) ) { if ( count($name) == 3 ) $name = sprintf($name[0], $name[2]); else $name = $name[0]; } $id = sanitize_title($name); $options = array(); if ( !empty($classname) && is_string($classname) ) $options['classname'] = $classname; $params = array_slice(func_get_args(), 2); $args = array($id, $name, $output_callback, $options); if ( !empty($params) ) $args = array_merge($args, $params); call_user_func_array('wp_register_sidebar_widget', $args); } function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) { global $wp_registered_widgets; $id = strtolower($id); if ( empty($output_callback) ) { unset($wp_registered_widgets[$id]); return; } $defaults = array('classname' => $output_callback); $options = wp_parse_args($options, $defaults); $widget = array( 'name' => $name, 'id' => $id, 'callback' => $output_callback, 'params' => array_slice(func_get_args(), 4) ); $widget = array_merge($widget, $options); if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) ) $wp_registered_widgets[$id] = $widget; } function wp_widget_description( $id ) { if ( !is_scalar($id) ) return; global $wp_registered_widgets; if ( isset($wp_registered_widgets[$id]['description']) ) return wp_specialchars( $wp_registered_widgets[$id]['description'] ); } function unregister_sidebar_widget($id) { return wp_unregister_sidebar_widget($id); } function wp_unregister_sidebar_widget($id) { wp_register_sidebar_widget($id, '', ''); wp_unregister_widget_control($id); } function register_widget_control($name, $control_callback, $width = '', $height = '') { // Compat if ( is_array($name) ) { if ( count($name) == 3 ) $name = sprintf($name[0], $name[2]); else $name = $name[0]; } $id = sanitize_title($name); $options = array(); if ( !empty($width) ) $options['width'] = $width; if ( !empty($height) ) $options['height'] = $height; $params = array_slice(func_get_args(), 4); $args = array($id, $name, $control_callback, $options); if ( !empty($params) ) $args = array_merge($args, $params); call_user_func_array('wp_register_widget_control', $args); } /* $options: height, width, id_base * height: never used * width: width of fully expanded control form. Try hard to use the default width. * id_base: for multi-widgets (widgets which allow multiple instances such as the text widget), an id_base must be provided. * the widget id will ennd up looking like {$id_base}-{$unique_number} */ function wp_register_widget_control($id, $name, $control_callback, $options = array()) { global $wp_registered_widget_controls; $id = strtolower($id); if ( empty($control_callback) ) { unset($wp_registered_widget_controls[$id]); return; } if ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) ) return; $defaults = array('width' => 250, 'height' => 200 ); // height is never used $options = wp_parse_args($options, $defaults); $options['width'] = (int) $options['width']; $options['height'] = (int) $options['height']; $widget = array( 'name' => $name, 'id' => $id, 'callback' => $control_callback, 'params' => array_slice(func_get_args(), 4) ); $widget = array_merge($widget, $options); $wp_registered_widget_controls[$id] = $widget; } function unregister_widget_control($id) { return wp_unregister_widget_control($id); } function wp_unregister_widget_control($id) { return wp_register_widget_control($id, '', ''); } function dynamic_sidebar($index = 1) { global $wp_registered_sidebars, $wp_registered_widgets; if ( is_int($index) ) { $index = "sidebar-$index"; } else { $index = sanitize_title($index); foreach ( $wp_registered_sidebars as $key => $value ) { if ( sanitize_title($value['name']) == $index ) { $index = $key; break; } } } $sidebars_widgets = wp_get_sidebars_widgets(); if ( empty($wp_registered_sidebars[$index]) || !array_key_exists($index, $sidebars_widgets) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) ) return false; $sidebar = $wp_registered_sidebars[$index]; $did_one = false; foreach ( $sidebars_widgets[$index] as $id ) { $params = array_merge( array( array_merge( $sidebar, array('widget_id' => $id, 'widget_name' => $wp_registered_widgets[$id]['name']) ) ), (array) $wp_registered_widgets[$id]['params'] ); // Substitute HTML id and class attributes into before_widget $classname_ = ''; foreach ( (array) $wp_registered_widgets[$id]['classname'] as $cn ) { if ( is_string($cn) ) $classname_ .= '_' . $cn; elseif ( is_object($cn) ) $classname_ .= '_' . get_class($cn); } $classname_ = ltrim($classname_, '_'); $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_); $params = apply_filters( 'dynamic_sidebar_params', $params ); $callback = $wp_registered_widgets[$id]['callback']; if ( is_callable($callback) ) { call_user_func_array($callback, $params); $did_one = true; } } return $did_one; } /* @return mixed false if widget is not active or id of sidebar in which the widget is active */ function is_active_widget($callback, $widget_id = false) { global $wp_registered_widgets; $sidebars_widgets = wp_get_sidebars_widgets(false); if ( is_array($sidebars_widgets) ) foreach ( $sidebars_widgets as $sidebar => $widgets ) if ( is_array($widgets) ) foreach ( $widgets as $widget ) if ( isset($wp_registered_widgets[$widget]['callback']) && $wp_registered_widgets[$widget]['callback'] == $callback ) if ( !$widget_id || $widget_id == $wp_registered_widgets[$widget]['id'] ) return $sidebar; return false; } function is_dynamic_sidebar() { global $wp_registered_widgets, $wp_registered_sidebars; $sidebars_widgets = get_option('sidebars_widgets'); foreach ( $wp_registered_sidebars as $index => $sidebar ) { if ( count($sidebars_widgets[$index]) ) { foreach ( $sidebars_widgets[$index] as $widget ) if ( array_key_exists($widget, $wp_registered_widgets) ) return true; } } return false; } /* Internal Functions */ function wp_get_sidebars_widgets($update = true) { global $wp_registered_widgets, $wp_registered_sidebars; $sidebars_widgets = get_option('sidebars_widgets'); $_sidebars_widgets = array(); if ( !isset($sidebars_widgets['array_version']) ) $sidebars_widgets['array_version'] = 1; switch ( $sidebars_widgets['array_version'] ) { case 1 : foreach ( $sidebars_widgets as $index => $sidebar ) if ( is_array($sidebar) ) foreach ( $sidebar as $i => $name ) { $id = strtolower($name); if ( isset($wp_registered_widgets[$id]) ) { $_sidebars_widgets[$index][$i] = $id; continue; } $id = sanitize_title($name); if ( isset($wp_registered_widgets[$id]) ) { $_sidebars_widgets[$index][$i] = $id; continue; } $found = false; foreach ( $wp_registered_widgets as $widget_id => $widget ) { if ( strtolower($widget['name']) == strtolower($name) ) { $_sidebars_widgets[$index][$i] = $widget['id']; $found = true; break; } elseif ( sanitize_title($widget['name']) == sanitize_title($name) ) { $_sidebars_widgets[$index][$i] = $widget['id']; $found = true; break; } } if ( $found ) continue; unset($_sidebars_widgets[$index][$i]); } $_sidebars_widgets['array_version'] = 2; $sidebars_widgets = $_sidebars_widgets; unset($_sidebars_widgets); case 2 : $sidebars = array_keys( $wp_registered_sidebars ); if ( !empty( $sidebars ) ) { // Move the known-good ones first foreach ( $sidebars as $id ) { if ( array_key_exists( $id, $sidebars_widgets ) ) { $_sidebars_widgets[$id] = $sidebars_widgets[$id]; unset($sidebars_widgets[$id], $sidebars[$id]); } } // Assign to each unmatched registered sidebar the first available orphan unset( $sidebars_widgets[ 'array_version' ] ); while ( ( $sidebar = array_shift( $sidebars ) ) && $widgets = array_shift( $sidebars_widgets ) ) $_sidebars_widgets[ $sidebar ] = $widgets; $_sidebars_widgets['array_version'] = 3; $sidebars_widgets = $_sidebars_widgets; unset($_sidebars_widgets); } if ( $update ) update_option('sidebars_widgets', $sidebars_widgets); } unset($sidebars_widgets['array_version']); return $sidebars_widgets; } function wp_set_sidebars_widgets( $sidebars_widgets ) { update_option( 'sidebars_widgets', $sidebars_widgets ); } function wp_get_widget_defaults() { global $wp_registered_sidebars; $defaults = array(); foreach ( $wp_registered_sidebars as $index => $sidebar ) $defaults[$index] = array(); return $defaults; } /* Default Widgets */ function wp_widget_pages( $args ) { extract( $args ); $options = get_option( 'widget_pages' ); $title = empty( $options['title'] ) ? __( 'Pages' ) : apply_filters('widget_title', $options['title']); $sortby = empty( $options['sortby'] ) ? 'menu_order' : $options['sortby']; $exclude = empty( $options['exclude'] ) ? '' : $options['exclude']; if ( $sortby == 'menu_order' ) { $sortby = 'menu_order, post_title'; } $out = wp_list_pages( array('title_li' => '', 'echo' => 0, 'sort_column' => $sortby, 'exclude' => $exclude) ); if ( !empty( $out ) ) { ?>


    $before_title, 'title_after' => $after_title, 'category_before' => $before_widget, 'category_after' => $after_widget, 'show_images' => true, 'class' => 'linkcat widget' ))); } function wp_widget_search($args) { extract($args); $searchform_template = get_template_directory() . '/searchform.php'; echo $before_widget; // Use current theme search form if it exists if ( file_exists($searchform_template) ) { include_once($searchform_template); } else { ?>


    '; get_calendar(); echo '
    '; echo $after_widget; } function wp_widget_calendar_control() { $options = $newoptions = get_option('widget_calendar'); if ( $_POST["calendar-submit"] ) { $newoptions['title'] = strip_tags(stripslashes($_POST["calendar-title"])); } if ( $options != $newoptions ) { $options = $newoptions; update_option('widget_calendar', $options); } $title = attribute_escape($options['title']); ?>

    $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract( $widget_args, EXTR_SKIP ); $options = get_option('widget_text'); if ( !isset($options[$number]) ) return; $title = apply_filters('widget_title', $options[$number]['title']); $text = apply_filters( 'widget_text', $options[$number]['text'] ); ?>
    $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract( $widget_args, EXTR_SKIP ); $options = get_option('widget_text'); if ( !is_array($options) ) $options = array(); if ( !$updated && !empty($_POST['sidebar']) ) { $sidebar = (string) $_POST['sidebar']; $sidebars_widgets = wp_get_sidebars_widgets(); if ( isset($sidebars_widgets[$sidebar]) ) $this_sidebar =& $sidebars_widgets[$sidebar]; else $this_sidebar = array(); foreach ( $this_sidebar as $_widget_id ) { if ( 'wp_widget_text' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; if ( !in_array( "text-$widget_number", $_POST['widget-id'] ) ) // the widget has been removed. unset($options[$widget_number]); } } foreach ( (array) $_POST['widget-text'] as $widget_number => $widget_text ) { if ( !isset($widget_text['text']) && isset($options[$widget_number]) ) // user clicked cancel continue; $title = strip_tags(stripslashes($widget_text['title'])); if ( current_user_can('unfiltered_html') ) $text = stripslashes( $widget_text['text'] ); else $text = stripslashes(wp_filter_post_kses( $widget_text['text'] )); $options[$widget_number] = compact( 'title', 'text' ); } update_option('widget_text', $options); $updated = true; } if ( -1 == $number ) { $title = ''; $text = ''; $number = '%i%'; } else { $title = attribute_escape($options[$number]['title']); $text = format_to_edit($options[$number]['text']); } ?>

    'widget_text', 'description' => __('Arbitrary text or HTML')); $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'text'); $name = __('Text'); $id = false; foreach ( array_keys($options) as $o ) { // Old widgets can have null values for some reason if ( !isset($options[$o]['title']) || !isset($options[$o]['text']) ) continue; $id = "text-$o"; // Never never never translate an id wp_register_sidebar_widget($id, $name, 'wp_widget_text', $widget_ops, array( 'number' => $o )); wp_register_widget_control($id, $name, 'wp_widget_text_control', $control_ops, array( 'number' => $o )); } // If there are none, we register the widget's existance with a generic template if ( !$id ) { wp_register_sidebar_widget( 'text-1', $name, 'wp_widget_text', $widget_ops, array( 'number' => -1 ) ); wp_register_widget_control( 'text-1', $name, 'wp_widget_text_control', $control_ops, array( 'number' => -1 ) ); } } // See large comment section at end of this file function wp_widget_categories($args, $widget_args = 1) { extract($args, EXTR_SKIP); if ( is_numeric($widget_args) ) $widget_args = array( 'number' => $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract($widget_args, EXTR_SKIP); $options = get_option('widget_categories'); if ( !isset($options[$number]) ) return; $c = $options[$number]['count'] ? '1' : '0'; $h = $options[$number]['hierarchical'] ? '1' : '0'; $d = $options[$number]['dropdown'] ? '1' : '0'; $title = empty($options[$number]['title']) ? __('Categories') : apply_filters('widget_title', $options[$number]['title']); echo $before_widget; echo $before_title . $title . $after_title; $cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h); if ( $d ) { $cat_args['show_option_none'] = __('Select Category'); wp_dropdown_categories($cat_args); ?> $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract($widget_args, EXTR_SKIP); $options = get_option('widget_categories'); if ( !is_array( $options ) ) $options = array(); if ( !$updated && !empty($_POST['sidebar']) ) { $sidebar = (string) $_POST['sidebar']; $sidebars_widgets = wp_get_sidebars_widgets(); if ( isset($sidebars_widgets[$sidebar]) ) $this_sidebar =& $sidebars_widgets[$sidebar]; else $this_sidebar = array(); foreach ( $this_sidebar as $_widget_id ) { if ( 'wp_widget_categories' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; if ( !in_array( "categories-$widget_number", $_POST['widget-id'] ) ) // the widget has been removed. unset($options[$widget_number]); } } foreach ( (array) $_POST['widget-categories'] as $widget_number => $widget_cat ) { if ( !isset($widget_cat['title']) && isset($options[$widget_number]) ) // user clicked cancel continue; $title = trim(strip_tags(stripslashes($widget_cat['title']))); $count = isset($widget_cat['count']); $hierarchical = isset($widget_cat['hierarchical']); $dropdown = isset($widget_cat['dropdown']); $options[$widget_number] = compact( 'title', 'count', 'hierarchical', 'dropdown' ); } update_option('widget_categories', $options); $updated = true; } if ( -1 == $number ) { $title = ''; $count = false; $hierarchical = false; $dropdown = false; $number = '%i%'; } else { $title = attribute_escape( $options[$number]['title'] ); $count = (bool) $options[$number]['count']; $hierarchical = (bool) $options[$number]['hierarchical']; $dropdown = (bool) $options[$number]['dropdown']; } ?>



    'widget_categories', 'description' => __( "A list or dropdown of categories" ) ); $name = __( 'Categories' ); $id = false; foreach ( array_keys($options) as $o ) { // Old widgets can have null values for some reason if ( !isset($options[$o]['title']) ) continue; $id = "categories-$o"; wp_register_sidebar_widget( $id, $name, 'wp_widget_categories', $widget_ops, array( 'number' => $o ) ); wp_register_widget_control( $id, $name, 'wp_widget_categories_control', array( 'id_base' => 'categories' ), array( 'number' => $o ) ); } // If there are none, we register the widget's existance with a generic template if ( !$id ) { wp_register_sidebar_widget( 'categories-1', $name, 'wp_widget_categories', $widget_ops, array( 'number' => -1 ) ); wp_register_widget_control( 'categories-1', $name, 'wp_widget_categories_control', array( 'id_base' => 'categories' ), array( 'number' => -1 ) ); } } function wp_widget_categories_upgrade() { $options = get_option( 'widget_categories' ); if ( !isset( $options['title'] ) ) return $options; $newoptions = array( 1 => $options ); update_option( 'widget_categories', $newoptions ); $sidebars_widgets = get_option( 'sidebars_widgets' ); if ( is_array( $sidebars_widgets ) ) { foreach ( $sidebars_widgets as $sidebar => $widgets ) { if ( is_array( $widgets ) ) { foreach ( $widgets as $widget ) $new_widgets[$sidebar][] = ( $widget == 'categories' ) ? 'categories-1' : $widget; } else { $new_widgets[$sidebar] = $widgets; } } if ( $new_widgets != $sidebars_widgets ) update_option( 'sidebars_widgets', $new_widgets ); } return $newoptions; } function wp_widget_recent_entries($args) { if ( '%BEG_OF_TITLE%' != $args['before_title'] ) { if ( $output = wp_cache_get('widget_recent_entries', 'widget') ) return print($output); ob_start(); } extract($args); $options = get_option('widget_recent_entries'); $title = empty($options['title']) ? __('Recent Posts') : apply_filters('widget_title', $options['title']); if ( !$number = (int) $options['number'] ) $number = 10; else if ( $number < 1 ) $number = 1; else if ( $number > 15 ) $number = 15; $r = new WP_Query(array('showposts' => $number, 'what_to_show' => 'posts', 'nopaging' => 0, 'post_status' => 'publish')); if ($r->have_posts()) : ?>


    15 ) $number = 15; if ( !$comments = wp_cache_get( 'recent_comments', 'widget' ) ) { $comments = $wpdb->get_results("SELECT comment_author, comment_author_url, comment_ID, comment_post_ID FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT $number"); wp_cache_add( 'recent_comments', $comments, 'widget' ); } ?>


    'widget_recent_comments', 'description' => __( 'The most recent comments' ) ); wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $widget_ops); wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control'); if ( is_active_widget('wp_widget_recent_comments') ) add_action('wp_head', 'wp_widget_recent_comments_style'); } // See large comment section at end of this file function wp_widget_rss($args, $widget_args = 1) { extract($args, EXTR_SKIP); if ( is_numeric($widget_args) ) $widget_args = array( 'number' => $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract($widget_args, EXTR_SKIP); $options = get_option('widget_rss'); if ( !isset($options[$number]) ) return; if ( isset($options[$number]['error']) && $options[$number]['error'] ) return; $url = $options[$number]['url']; while ( strstr($url, 'http') != $url ) $url = substr($url, 1); if ( empty($url) ) return; require_once(ABSPATH . WPINC . '/rss.php'); $rss = fetch_rss($url); $link = clean_url(strip_tags($rss->channel['link'])); while ( strstr($link, 'http') != $link ) $link = substr($link, 1); $desc = attribute_escape(strip_tags(html_entity_decode($rss->channel['description'], ENT_QUOTES))); $title = $options[$number]['title']; if ( empty($title) ) $title = htmlentities(strip_tags($rss->channel['title'])); if ( empty($title) ) $title = $desc; if ( empty($title) ) $title = __('Unknown Feed'); $title = apply_filters('widget_title', $title ); $url = clean_url(strip_tags($url)); if ( file_exists(dirname(__FILE__) . '/rss.png') ) $icon = str_replace(ABSPATH, site_url() . '/', dirname(__FILE__)) . '/rss.png'; else $icon = includes_url('images/rss.png'); $title = "RSS $title"; echo $before_widget; echo $before_title . $title . $after_title; wp_widget_rss_output( $rss, $options[$number] ); echo $after_widget; } function wp_widget_rss_output( $rss, $args = array() ) { if ( is_string( $rss ) ) { require_once(ABSPATH . WPINC . '/rss.php'); if ( !$rss = fetch_rss($rss) ) return; } elseif ( is_array($rss) && isset($rss['url']) ) { require_once(ABSPATH . WPINC . '/rss.php'); $args = $rss; if ( !$rss = fetch_rss($rss['url']) ) return; } elseif ( !is_object($rss) ) { return; } extract( $args, EXTR_SKIP ); $items = (int) $items; if ( $items < 1 || 20 < $items ) $items = 10; $show_summary = (int) $show_summary; $show_author = (int) $show_author; $show_date = (int) $show_date; if ( is_array( $rss->items ) && !empty( $rss->items ) ) { $rss->items = array_slice($rss->items, 0, $items); echo ''; } else { echo ''; } } function wp_widget_rss_control($widget_args) { global $wp_registered_widgets; static $updated = false; if ( is_numeric($widget_args) ) $widget_args = array( 'number' => $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract($widget_args, EXTR_SKIP); $options = get_option('widget_rss'); if ( !is_array($options) ) $options = array(); $urls = array(); foreach ( $options as $option ) if ( isset($option['url']) ) $urls[$option['url']] = true; if ( !$updated && 'POST' == $_SERVER['REQUEST_METHOD'] && !empty($_POST['sidebar']) ) { $sidebar = (string) $_POST['sidebar']; $sidebars_widgets = wp_get_sidebars_widgets(); if ( isset($sidebars_widgets[$sidebar]) ) $this_sidebar =& $sidebars_widgets[$sidebar]; else $this_sidebar = array(); foreach ( $this_sidebar as $_widget_id ) { if ( 'wp_widget_rss' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; if ( !in_array( "rss-$widget_number", $_POST['widget-id'] ) ) // the widget has been removed. unset($options[$widget_number]); } } foreach( (array) $_POST['widget-rss'] as $widget_number => $widget_rss ) { if ( !isset($widget_rss['url']) && isset($options[$widget_number]) ) // user clicked cancel continue; $widget_rss = stripslashes_deep( $widget_rss ); $url = sanitize_url(strip_tags($widget_rss['url'])); $options[$widget_number] = wp_widget_rss_process( $widget_rss, !isset($urls[$url]) ); } update_option('widget_rss', $options); $updated = true; } if ( -1 == $number ) { $title = ''; $url = ''; $items = 10; $error = false; $number = '%i%'; $show_summary = 0; $show_author = 0; $show_date = 0; } else { extract( (array) $options[$number] ); } wp_widget_rss_form( compact( 'number', 'title', 'url', 'items', 'error', 'show_summary', 'show_author', 'show_date' ) ); } function wp_widget_rss_form( $args, $inputs = null ) { $default_inputs = array( 'url' => true, 'title' => true, 'items' => true, 'show_summary' => true, 'show_author' => true, 'show_date' => true ); $inputs = wp_parse_args( $inputs, $default_inputs ); extract( $args ); $number = attribute_escape( $number ); $title = attribute_escape( $title ); $url = attribute_escape( $url ); $items = (int) $items; if ( $items < 1 || 20 < $items ) $items = 10; $show_summary = (int) $show_summary; $show_author = (int) $show_author; $show_date = (int) $show_date; if ( $inputs['url'] ) : ?>

    channel['link'])); while ( strstr($link, 'http') != $link ) $link = substr($link, 1); } } return compact( 'title', 'url', 'link', 'items', 'error', 'show_summary', 'show_author', 'show_date' ); } function wp_widget_rss_register() { if ( !$options = get_option('widget_rss') ) $options = array(); $widget_ops = array('classname' => 'widget_rss', 'description' => __( 'Entries from any RSS or Atom feed' )); $control_ops = array('width' => 400, 'height' => 200, 'id_base' => 'rss'); $name = __('RSS'); $id = false; foreach ( array_keys($options) as $o ) { // Old widgets can have null values for some reason if ( !isset($options[$o]['url']) || !isset($options[$o]['title']) || !isset($options[$o]['items']) ) continue; $id = "rss-$o"; // Never never never translate an id wp_register_sidebar_widget($id, $name, 'wp_widget_rss', $widget_ops, array( 'number' => $o )); wp_register_widget_control($id, $name, 'wp_widget_rss_control', $control_ops, array( 'number' => $o )); } // If there are none, we register the widget's existance with a generic template if ( !$id ) { wp_register_sidebar_widget( 'rss-1', $name, 'wp_widget_rss', $widget_ops, array( 'number' => -1 ) ); wp_register_widget_control( 'rss-1', $name, 'wp_widget_rss_control', $control_ops, array( 'number' => -1 ) ); } } function wp_widget_tag_cloud($args) { extract($args); $options = get_option('widget_tag_cloud'); $title = empty($options['title']) ? __('Tags') : apply_filters('widget_title', $options['title']); echo $before_widget; echo $before_title . $title . $after_title; wp_tag_cloud(); echo $after_widget; } function wp_widget_tag_cloud_control() { $options = $newoptions = get_option('widget_tag_cloud'); if ( $_POST['tag-cloud-submit'] ) { $newoptions['title'] = strip_tags(stripslashes($_POST['tag-cloud-title'])); } if ( $options != $newoptions ) { $options = $newoptions; update_option('widget_tag_cloud', $options); } $title = attribute_escape( $options['title'] ); ?>

    'widget_pages', 'description' => __( "Your blog's WordPress Pages") ); wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $widget_ops); wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control' ); $widget_ops = array('classname' => 'widget_calendar', 'description' => __( "A calendar of your blog's posts") ); wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $widget_ops); wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control' ); $widget_ops = array('classname' => 'widget_archive', 'description' => __( "A monthly archive of your blog's posts") ); wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $widget_ops); wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control' ); $widget_ops = array('classname' => 'widget_links', 'description' => __( "Your blogroll") ); wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $widget_ops); $widget_ops = array('classname' => 'widget_meta', 'description' => __( "Log in/out, admin, feed and WordPress links") ); wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $widget_ops); wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control' ); $widget_ops = array('classname' => 'widget_search', 'description' => __( "A search form for your blog") ); wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $widget_ops); $widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "The most recent posts on your blog") ); wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $widget_ops); wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control' ); $widget_ops = array('classname' => 'widget_tag_cloud', 'description' => __( "Your most used tags in cloud format") ); wp_register_sidebar_widget('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud', $widget_ops); wp_register_widget_control('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud_control' ); wp_widget_categories_register(); wp_widget_text_register(); wp_widget_rss_register(); wp_widget_recent_comments_register(); do_action('widgets_init'); } add_action('init', 'wp_widgets_init', 1); /* Pattern for multi-widget (allows multiple instances such as the text widget). // Displays widget on blag // $widget_args: number // number: which of the several widgets of this type do we mean function widget_many( $args, $widget_args = 1 ) { extract( $args, EXTR_SKIP ); if ( is_numeric($widget_args) ) $widget_args = array( 'number' => $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract( $widget_args, EXTR_SKIP ); // Data should be stored as array: array( number => data for that instance of the widget, ... ) $options = get_option('widget_many'); if ( !isset($options[$number]) ) return; echo $before_widget; // Do stuff for this widget, drawing data from $options[$number] echo $after_widget; } // Displays form for a particular instance of the widget. Also updates the data after a POST submit // $widget_args: number // number: which of the several widgets of this type do we mean function widget_many_control( $widget_args = 1 ) { global $wp_registered_widgets; static $updated = false; // Whether or not we have already updated the data after a POST submit if ( is_numeric($widget_args) ) $widget_args = array( 'number' => $widget_args ); $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); extract( $widget_args, EXTR_SKIP ); // Data should be stored as array: array( number => data for that instance of the widget, ... ) $options = get_option('widget_many'); if ( !is_array($options) ) $options = array(); // We need to update the data if ( !$updated && !empty($_POST['sidebar']) ) { // Tells us what sidebar to put the data in $sidebar = (string) $_POST['sidebar']; $sidebars_widgets = wp_get_sidebars_widgets(); if ( isset($sidebars_widgets[$sidebar]) ) $this_sidebar =& $sidebars_widgets[$sidebar]; else $this_sidebar = array(); foreach ( $this_sidebar as $_widget_id ) { // Remove all widgets of this type from the sidebar. We'll add the new data in a second. This makes sure we don't get any duplicate data // since widget ids aren't necessarily persistent across multiple updates if ( 'widget_many' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; if ( !in_array( "many-$widget_number", $_POST['widget-id'] ) ) // the widget has been removed. "many-$widget_number" is "{id_base}-{widget_number} unset($options[$widget_number]); } } foreach ( (array) $_POST['widget-many'] as $widget_number => $widget_many_instance ) { // compile data from $widget_many_instance if ( !isset($widget_many_instance['something']) && isset($options[$widget_number]) ) // user clicked cancel continue; $something = wp_specialchars( $widget_many_instance['something'] ); $options[$widget_number] = array( 'something' => $something ); // Even simple widgets should store stuff in array, rather than in scalar } update_option('widget_many', $options); $updated = true; // So that we don't go through this more than once } // Here we echo out the form if ( -1 == $number ) { // We echo out a template for a form which can be converted to a specific form later via JS $something = ''; $number = '%i%'; } else { $something = attribute_escape($options[$number]['something']); } // The form has inputs with names like widget-many[$number][something] so that all data for that instance of // the widget are stored in one $_POST variable: $_POST['widget-many'][$number] ?>

    'widget_many', 'description' => __('Widget which allows multiple instances')); $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'many'); $name = __('Many'); $registered = false; foreach ( array_keys($options) as $o ) { // Old widgets can have null values for some reason if ( !isset($options[$o]['something']) ) // we used 'something' above in our exampple. Replace with with whatever your real data are. continue; // $id should look like {$id_base}-{$o} $id = "many-$o"; // Never never never translate an id $registered = true; wp_register_sidebar_widget( $id, $name, 'widget_many', $widget_ops, array( 'number' => $o ) ); wp_register_widget_control( $id, $name, 'widget_many_control', $control_ops, array( 'number' => $o ) ); } // If there are none, we register the widget's existance with a generic template if ( !$registered ) { wp_register_sidebar_widget( 'many-1', $name, 'widget_many', $widget_ops, array( 'number' => -1 ) ); wp_register_widget_control( 'many-1', $name, 'widget_many_control', $control_ops, array( 'number' => -1 ) ); } } // This is important add_action( 'widgets_init', 'widget_many_register' ) */ ?> blogs/wp-includes/streams.php0000644000000000000000000001052311077635520015312 0ustar rootroot. This file is part of PHP-gettext. PHP-gettext is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PHP-gettext is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PHP-gettext; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Simple class to wrap file streams, string streams, etc. // seek is essential, and it should be byte stream class StreamReader { // should return a string [FIXME: perhaps return array of bytes?] function read($bytes) { return false; } // should return new position function seekto($position) { return false; } // returns current position function currentpos() { return false; } // returns length of entire stream (limit for seekto()s) function length() { return false; } } class StringReader { var $_pos; var $_str; function StringReader($str='') { $this->_str = $str; $this->_pos = 0; // If string functions are overloaded, we need to use the mb versions $this->is_overloaded = ((ini_get("mbstring.func_overload") & 2) != 0) && function_exists('mb_substr'); } function _substr($string, $start, $length) { if ($this->is_overloaded) { return mb_substr($string,$start,$length,'ascii'); } else { return substr($string,$start,$length); } } function _strlen($string) { if ($this->is_overloaded) { return mb_strlen($string,'ascii'); } else { return strlen($string); } } function read($bytes) { $data = $this->_substr($this->_str, $this->_pos, $bytes); $this->_pos += $bytes; if ($this->_strlen($this->_str)<$this->_pos) $this->_pos = $this->_strlen($this->_str); return $data; } function seekto($pos) { $this->_pos = $pos; if ($this->_strlen($this->_str)<$this->_pos) $this->_pos = $this->_strlen($this->_str); return $this->_pos; } function currentpos() { return $this->_pos; } function length() { return $this->_strlen($this->_str); } } class FileReader { var $_pos; var $_fd; var $_length; function FileReader($filename) { if (file_exists($filename)) { $this->_length=filesize($filename); $this->_pos = 0; $this->_fd = fopen($filename,'rb'); if (!$this->_fd) { $this->error = 3; // Cannot read file, probably permissions return false; } } else { $this->error = 2; // File doesn't exist return false; } } function read($bytes) { if ($bytes) { fseek($this->_fd, $this->_pos); // PHP 5.1.1 does not read more than 8192 bytes in one fread() // the discussions at PHP Bugs suggest it's the intended behaviour while ($bytes > 0) { $chunk = fread($this->_fd, $bytes); $data .= $chunk; $bytes -= strlen($chunk); } $this->_pos = ftell($this->_fd); return $data; } else return ''; } function seekto($pos) { fseek($this->_fd, $pos); $this->_pos = ftell($this->_fd); return $this->_pos; } function currentpos() { return $this->_pos; } function length() { return $this->_length; } function close() { fclose($this->_fd); } } // Preloads entire file in memory first, then creates a StringReader // over it (it assumes knowledge of StringReader internals) class CachedFileReader extends StringReader { function CachedFileReader($filename) { parent::StringReader(); if (file_exists($filename)) { $length=filesize($filename); $fd = fopen($filename,'rb'); if (!$fd) { $this->error = 3; // Cannot read file, probably permissions return false; } $this->_str = fread($fd, $length); fclose($fd); } else { $this->error = 2; // File doesn't exist return false; } } } ?> blogs/wp-includes/taxonomy.php0000644000000000000000000020766411077635520015530 0ustar rootroot 'category', 'object_type' => 'post', 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count'); $wp_taxonomies['post_tag'] = (object) array('name' => 'post_tag', 'object_type' => 'post', 'hierarchical' => false, 'update_count_callback' => '_update_post_term_count'); $wp_taxonomies['link_category'] = (object) array('name' => 'link_category', 'object_type' => 'link', 'hierarchical' => false); /** * Return all of the taxonomy names that are of $object_type. * * It appears that this function can be used to find all of the names inside of * $wp_taxonomies global variable. * * Should * result in Array('category', 'post_tag') * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wp_taxonomies * * @param array|string|object $object Name of the type of taxonomy object, or an object (row from posts) * @return array The names of all taxonomy of $object_type. */ function get_object_taxonomies($object) { global $wp_taxonomies; if ( is_object($object) ) { if ( $object->post_type == 'attachment' ) return get_attachment_taxonomies($object); $object = $object->post_type; } $object = (array) $object; $taxonomies = array(); foreach ( $wp_taxonomies as $taxonomy ) { if ( array_intersect($object, (array) $taxonomy->object_type) ) $taxonomies[] = $taxonomy->name; } return $taxonomies; } /** * Retrieves the taxonomy object of $taxonomy. * * The get_taxonomy function will first check that the parameter string given * is a taxonomy object and if it is, it will return it. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wp_taxonomies * @uses is_taxonomy() Checks whether taxonomy exists * * @param string $taxonomy Name of taxonomy object to return * @return object|bool The Taxonomy Object or false if $taxonomy doesn't exist */ function get_taxonomy( $taxonomy ) { global $wp_taxonomies; if ( ! is_taxonomy($taxonomy) ) return false; return $wp_taxonomies[$taxonomy]; } /** * Checks that the taxonomy name exists. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wp_taxonomies * * @param string $taxonomy Name of taxonomy object * @return bool Whether the taxonomy exists or not. */ function is_taxonomy( $taxonomy ) { global $wp_taxonomies; return isset($wp_taxonomies[$taxonomy]); } /** * Whether the taxonomy object is hierarchical. * * Checks to make sure that the taxonomy is an object first. Then Gets the * object, and finally returns the hierarchical value in the object. * * A false return value might also mean that the taxonomy does not exist. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses is_taxonomy() Checks whether taxonomy exists * @uses get_taxonomy() Used to get the taxonomy object * * @param string $taxonomy Name of taxonomy object * @return bool Whether the taxonomy is hierarchical */ function is_taxonomy_hierarchical($taxonomy) { if ( ! is_taxonomy($taxonomy) ) return false; $taxonomy = get_taxonomy($taxonomy); return $taxonomy->hierarchical; } /** * Create or modify a taxonomy object. Do not use before init. * * A simple function for creating or modifying a taxonomy object based on the * parameters given. The function will accept an array (third optional * parameter), along with strings for the taxonomy name and another string for * the object type. * * Nothing is returned, so expect error maybe or use is_taxonomy() to check * whether taxonomy exists. * * Optional $args contents: * * hierarachical - has some defined purpose at other parts of the API and is a * boolean value. * * update_count_callback - works much like a hook, in that it will be called * when the count is updated. * * rewrite - false to prevent rewrite, or array('slug'=>$slug) to customize * permastruct; default will use $taxonomy as slug. * * query_var - false to prevent queries, or string to customize query var * (?$query_var=$term); default will use $taxonomy as query var. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wp_taxonomies Inserts new taxonomy object into the list * @uses $wp_rewrite Adds rewrite tags and permastructs * @uses $wp Adds query vars * * @param string $taxonomy Name of taxonomy object * @param array|string $object_type Name of the object type for the taxonomy object. * @param array|string $args See above description for the two keys values. */ function register_taxonomy( $taxonomy, $object_type, $args = array() ) { global $wp_taxonomies, $wp_rewrite, $wp; $defaults = array('hierarchical' => false, 'update_count_callback' => '', 'rewrite' => true, 'query_var' => true); $args = wp_parse_args($args, $defaults); if ( false !== $args['query_var'] && !empty($wp) ) { if ( true === $args['query_var'] ) $args['query_var'] = $taxonomy; $args['query_var'] = sanitize_title_with_dashes($args['query_var']); $wp->add_query_var($args['query_var']); } if ( false !== $args['rewrite'] && !empty($wp_rewrite) ) { if ( !is_array($args['rewrite']) ) $args['rewrite'] = array(); if ( !isset($args['rewrite']['slug']) ) $args['rewrite']['slug'] = sanitize_title_with_dashes($taxonomy); $wp_rewrite->add_rewrite_tag("%$taxonomy%", '([^/]+)', $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=$term"); $wp_rewrite->add_permastruct($taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%"); } $args['name'] = $taxonomy; $args['object_type'] = $object_type; $wp_taxonomies[$taxonomy] = (object) $args; } // // Term API // /** * Retrieve object_ids of valid taxonomy and term. * * The strings of $taxonomies must exist before this function will continue. On * failure of finding a valid taxonomy, it will return an WP_Error class, kind * of like Exceptions in PHP 5, except you can't catch them. Even so, you can * still test for the WP_Error class and get the error message. * * The $terms aren't checked the same as $taxonomies, but still need to exist * for $object_ids to be returned. * * It is possible to change the order that object_ids is returned by either * using PHP sort family functions or using the database by using $args with * either ASC or DESC array. The value should be in the key named 'order'. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses wp_parse_args() Creates an array from string $args. * * @param string|array $terms String of term or array of string values of terms that will be used * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names * @param array|string $args Change the order of the object_ids, either ASC or DESC * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success * the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found. */ function get_objects_in_term( $terms, $taxonomies, $args = array() ) { global $wpdb; if ( !is_array( $terms) ) $terms = array($terms); if ( !is_array($taxonomies) ) $taxonomies = array($taxonomies); foreach ( $taxonomies as $taxonomy ) { if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); } $defaults = array('order' => 'ASC'); $args = wp_parse_args( $args, $defaults ); extract($args, EXTR_SKIP); $order = ( 'desc' == strtolower($order) ) ? 'DESC' : 'ASC'; $terms = array_map('intval', $terms); $taxonomies = "'" . implode("', '", $taxonomies) . "'"; $terms = "'" . implode("', '", $terms) . "'"; $object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($terms) ORDER BY tr.object_id $order"); if ( ! $object_ids ) return array(); return $object_ids; } /** * Get all Term data from database by Term ID. * * The usage of the get_term function is to apply filters to a term object. It * is possible to get a term object from the database before applying the * filters. * * $term ID must be part of $taxonomy, to get from the database. Failure, might * be able to be captured by the hooks. Failure would be the same value as $wpdb * returns for the get_row method. * * There are two hooks, one is specifically for each term, named 'get_term', and * the second is for the taxonomy name, 'term_$taxonomy'. Both hooks gets the * term object, and the taxonomy name as parameters. Both hooks are expected to * return a Term object. * * 'get_term' hook - Takes two parameters the term Object and the taxonomy name. * Must return term object. Used in get_term() as a catch-all filter for every * $term. * * 'get_$taxonomy' hook - Takes two parameters the term Object and the taxonomy * name. Must return term object. $taxonomy will be the taxonomy name, so for * example, if 'category', it would be 'get_category' as the filter name. Useful * for custom taxonomies or plugging into default taxonomies. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses sanitize_term() Cleanses the term based on $filter context before returning. * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. * * @param int|object $term If integer, will get from database. If object will apply filters and return $term. * @param string $taxonomy Taxonomy name that $term is part of. * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N * @param string $filter Optional, default is raw or no WordPress defined filter will applied. * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not * exist then WP_Error will be returned. */ function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { global $wpdb; if ( empty($term) ) return null; if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); if ( is_object($term) ) { wp_cache_add($term->term_id, $term, $taxonomy); $_term = $term; } else { $term = (int) $term; if ( ! $_term = wp_cache_get($term, $taxonomy) ) { $_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND t.term_id = %s LIMIT 1", $taxonomy, $term) ); wp_cache_add($term, $_term, $taxonomy); } } $_term = apply_filters('get_term', $_term, $taxonomy); $_term = apply_filters("get_$taxonomy", $_term, $taxonomy); $_term = sanitize_term($_term, $taxonomy, $filter); if ( $output == OBJECT ) { return $_term; } elseif ( $output == ARRAY_A ) { return get_object_vars($_term); } elseif ( $output == ARRAY_N ) { return array_values(get_object_vars($_term)); } else { return $_term; } } /** * Get all Term data from database by Term field and data. * * Warning: $value is not escaped for 'name' $field. You must do it yourself, if * required. * * The default $field is 'id', therefore it is possible to also use null for * field, but not recommended that you do so. * * If $value does not exist, the return value will be false. If $taxonomy exists * and $field and $value combinations exist, the Term will be returned. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses sanitize_term() Cleanses the term based on $filter context before returning. * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. * * @param string $field Either 'slug', 'name', or 'id' * @param string|int $value Search for this term value * @param string $taxonomy Taxonomy Name * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N * @param string $filter Optional, default is raw or no WordPress defined filter will applied. * @return mixed Term Row from database. Will return false if $taxonomy does not exist or $term was not found. */ function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') { global $wpdb; if ( ! is_taxonomy($taxonomy) ) return false; if ( 'slug' == $field ) { $field = 't.slug'; $value = sanitize_title($value); if ( empty($value) ) return false; } else if ( 'name' == $field ) { // Assume already escaped $field = 't.name'; } else { $field = 't.term_id'; $value = (int) $value; } $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND $field = %s LIMIT 1", $taxonomy, $value) ); if ( !$term ) return false; wp_cache_add($term->term_id, $term, $taxonomy); $term = sanitize_term($term, $taxonomy, $filter); if ( $output == OBJECT ) { return $term; } elseif ( $output == ARRAY_A ) { return get_object_vars($term); } elseif ( $output == ARRAY_N ) { return array_values(get_object_vars($term)); } else { return $term; } } /** * Merge all term children into a single array. * * This recursive function will merge all of the children of $term into the same * array. Only useful for taxonomies which are hierarchical. * * Will return an empty array if $term does not exist in $taxonomy. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses _get_term_hierarchy() * @uses get_term_children() Used to get the children of both $taxonomy and the parent $term * * @param string $term Name of Term to get children * @param string $taxonomy Taxonomy Name * @return array|WP_Error List of Term Objects. WP_Error returned if $taxonomy does not exist */ function get_term_children( $term, $taxonomy ) { if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); $terms = _get_term_hierarchy($taxonomy); if ( ! isset($terms[$term]) ) return array(); $children = $terms[$term]; foreach ( $terms[$term] as $child ) { if ( isset($terms[$child]) ) $children = array_merge($children, get_term_children($child, $taxonomy)); } return $children; } /** * Get sanitized Term field. * * Does checks for $term, based on the $taxonomy. The function is for contextual * reasons and for simplicity of usage. See sanitize_term_field() for more * information. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses sanitize_term_field() Passes the return value in sanitize_term_field on success. * * @param string $field Term field to fetch * @param int $term Term ID * @param string $taxonomy Taxonomy Name * @param string $context Optional, default is display. Look at sanitize_term_field() for available options. * @return mixed Will return an empty string if $term is not an object or if $field is not set in $term. */ function get_term_field( $field, $term, $taxonomy, $context = 'display' ) { $term = (int) $term; $term = get_term( $term, $taxonomy ); if ( is_wp_error($term) ) return $term; if ( !is_object($term) ) return ''; if ( !isset($term->$field) ) return ''; return sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context); } /** * Sanitizes Term for editing. * * Return value is sanitize_term() and usage is for sanitizing the term for * editing. Function is for contextual and simplicity. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses sanitize_term() Passes the return value on success * * @param int|object $id Term ID or Object * @param string $taxonomy Taxonomy Name * @return mixed|null|WP_Error Will return empty string if $term is not an object. */ function get_term_to_edit( $id, $taxonomy ) { $term = get_term( $id, $taxonomy ); if ( is_wp_error($term) ) return $term; if ( !is_object($term) ) return ''; return sanitize_term($term, $taxonomy, 'edit'); } /** * Retrieve the terms in taxonomy or list of taxonomies. * * You can fully inject any customizations to the query before it is sent, as * well as control the output with a filter. * * The 'get_terms' filter will be called when the cache has the term and will * pass the found term along with the array of $taxonomies and array of $args. * This filter is also called before the array of terms is passed and will pass * the array of terms, along with the $taxonomies and $args. * * The 'list_terms_exclusions' filter passes the compiled exclusions along with * the $args. * * The list that $args can contain, which will overwrite the defaults. * * orderby - Default is 'name'. Can be name, count, or nothing (will use * term_id). * * order - Default is ASC. Can use DESC. * hide_empty - Default is true. Will not return empty $terms. * fields - Default is all. * slug - Any terms that has this value. Default is empty string. * hierarchical - Whether to return hierarchical taxonomy. Default is true. * name__like - Default is empty string. * * The argument 'pad_counts' will count all of the children along with the * $terms. * * The 'get' argument allows for overwriting 'hide_empty' and 'child_of', which * can be done by setting the value to 'all', instead of its default empty * string value. * * The 'child_of' argument will be used if you use multiple taxonomy or the * first $taxonomy isn't hierarchical or 'parent' isn't used. The default is 0, * which will be translated to a false value. If 'child_of' is set, then * 'child_of' value will be tested against $taxonomy to see if 'child_of' is * contained within. Will return an empty array if test fails. * * If 'parent' is set, then it will be used to test against the first taxonomy. * Much like 'child_of'. Will return an empty array if the test fails. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings. * * @param string|array Taxonomy name or list of Taxonomy names * @param string|array $args The values of what to search for when returning terms * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist. */ function &get_terms($taxonomies, $args = '') { global $wpdb; $empty_array = array(); $single_taxonomy = false; if ( !is_array($taxonomies) ) { $single_taxonomy = true; $taxonomies = array($taxonomies); } foreach ( $taxonomies as $taxonomy ) { if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); } $in_taxonomies = "'" . implode("', '", $taxonomies) . "'"; $defaults = array('orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'exclude' => '', 'include' => '', 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'pad_counts' => false, 'offset' => '', 'search' => ''); $args = wp_parse_args( $args, $defaults ); $args['number'] = absint( $args['number'] ); $args['offset'] = absint( $args['offset'] ); if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' != $args['parent'] ) { $args['child_of'] = 0; $args['hierarchical'] = false; $args['pad_counts'] = false; } if ( 'all' == $args['get'] ) { $args['child_of'] = 0; $args['hide_empty'] = 0; $args['hierarchical'] = false; $args['pad_counts'] = false; } extract($args, EXTR_SKIP); if ( $child_of ) { $hierarchy = _get_term_hierarchy($taxonomies[0]); if ( !isset($hierarchy[$child_of]) ) return $empty_array; } if ( $parent ) { $hierarchy = _get_term_hierarchy($taxonomies[0]); if ( !isset($hierarchy[$parent]) ) return $empty_array; } // $args can be whatever, only use the args defined in defaults to compute the key $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : ''; $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key ); if ( $cache = wp_cache_get( 'get_terms', 'terms' ) ) { if ( isset( $cache[ $key ] ) ) return apply_filters('get_terms', $cache[$key], $taxonomies, $args); } if ( 'count' == $orderby ) $orderby = 'tt.count'; else if ( 'name' == $orderby ) $orderby = 't.name'; else if ( 'slug' == $orderby ) $orderby = 't.slug'; else if ( 'term_group' == $orderby ) $orderby = 't.term_group'; else $orderby = 't.term_id'; $where = ''; $inclusions = ''; if ( !empty($include) ) { $exclude = ''; $interms = preg_split('/[\s,]+/',$include); if ( count($interms) ) { foreach ( $interms as $interm ) { if (empty($inclusions)) $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' '; else $inclusions .= ' OR t.term_id = ' . intval($interm) . ' '; } } } if ( !empty($inclusions) ) $inclusions .= ')'; $where .= $inclusions; $exclusions = ''; if ( !empty($exclude) ) { $exterms = preg_split('/[\s,]+/',$exclude); if ( count($exterms) ) { foreach ( $exterms as $exterm ) { if (empty($exclusions)) $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; else $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; } } } if ( !empty($exclusions) ) $exclusions .= ')'; $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args ); $where .= $exclusions; if ( !empty($slug) ) { $slug = sanitize_title($slug); $where .= " AND t.slug = '$slug'"; } if ( !empty($name__like) ) $where .= " AND t.name LIKE '{$name__like}%'"; if ( '' != $parent ) { $parent = (int) $parent; $where .= " AND tt.parent = '$parent'"; } if ( $hide_empty && !$hierarchical ) $where .= ' AND tt.count > 0'; if ( !empty($number) ) { if( $offset ) $number = 'LIMIT ' . $offset . ',' . $number; else $number = 'LIMIT ' . $number; } else $number = ''; if ( !empty($search) ) { $search = like_escape($search); $where .= " AND (t.name LIKE '%$search%')"; } $select_this = ''; if ( 'all' == $fields ) $select_this = 't.*, tt.*'; else if ( 'ids' == $fields ) $select_this = 't.term_id'; else if ( 'names' == $fields ) $select_this = 't.name'; $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ($in_taxonomies) $where ORDER BY $orderby $order $number"; if ( 'all' == $fields ) { $terms = $wpdb->get_results($query); update_term_cache($terms); } else if ( ('ids' == $fields) || ('names' == $fields) ) { $terms = $wpdb->get_col($query); } if ( empty($terms) ) { $cache[ $key ] = array(); wp_cache_set( 'get_terms', $cache, 'terms' ); return apply_filters('get_terms', array(), $taxonomies, $args); } if ( $child_of || $hierarchical ) { $children = _get_term_hierarchy($taxonomies[0]); if ( ! empty($children) ) $terms = & _get_term_children($child_of, $terms, $taxonomies[0]); } // Update term counts to include children. if ( $pad_counts ) _pad_term_counts($terms, $taxonomies[0]); // Make sure we show empty categories that have children. if ( $hierarchical && $hide_empty ) { foreach ( $terms as $k => $term ) { if ( ! $term->count ) { $children = _get_term_children($term->term_id, $terms, $taxonomies[0]); foreach ( $children as $child ) if ( $child->count ) continue 2; // It really is empty unset($terms[$k]); } } } reset ( $terms ); $cache[ $key ] = $terms; wp_cache_set( 'get_terms', $cache, 'terms' ); $terms = apply_filters('get_terms', $terms, $taxonomies, $args); return $terms; } /** * Check if Term exists. * * Returns the index of a defined term, or 0 (false) if the term doesn't exist. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * * @param int|string $term The term to check * @param string $taxonomy The taxonomy name to use * @return mixed Get the term id or Term Object, if exists. */ function is_term($term, $taxonomy = '') { global $wpdb; $select = "SELECT term_id FROM $wpdb->terms as t WHERE "; $tax_select = "SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE "; if ( is_int($term) ) { if ( 0 == $term ) return 0; $where = 't.term_id = %d'; if ( !empty($taxonomy) ) return $wpdb->get_row( $wpdb->prepare( $tax_select . $where . " AND tt.taxonomy = %s", $term, $taxonomy ), ARRAY_A ); else return $wpdb->get_var( $wpdb->prepare( $select . $where, $term ) ); } if ( '' === $slug = sanitize_title($term) ) return 0; $where = 't.slug = %s'; $else_where = 't.name = %s'; if ( !empty($taxonomy) ) { if ( $result = $wpdb->get_row( $wpdb->prepare("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $where AND tt.taxonomy = %s", $slug, $taxonomy), ARRAY_A) ) return $result; return $wpdb->get_row( $wpdb->prepare("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $else_where AND tt.taxonomy = %s", $term, $taxonomy), ARRAY_A); } if ( $result = $wpdb->get_var( $wpdb->prepare("SELECT term_id FROM $wpdb->terms as t WHERE $where", $slug) ) ) return $result; return $wpdb->get_var( $wpdb->prepare("SELECT term_id FROM $wpdb->terms as t WHERE $else_where", $term) ); } /** * Sanitize Term all fields. * * Relys on sanitize_term_field() to sanitize the term. The difference is that * this function will sanitize all fields. The context is based * on sanitize_term_field(). * * The $term is expected to be either an array or an object. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses sanitize_term_field Used to sanitize all fields in a term * * @param array|object $term The term to check * @param string $taxonomy The taxonomy name to use * @param string $context Default is 'display'. * @return array|object Term with all fields sanitized */ function sanitize_term($term, $taxonomy, $context = 'display') { if ( 'raw' == $context ) return $term; $fields = array('term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group'); $do_object = false; if ( is_object($term) ) $do_object = true; foreach ( $fields as $field ) { if ( $do_object ) $term->$field = sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context); else $term[$field] = sanitize_term_field($field, $term[$field], $term['term_id'], $taxonomy, $context); } return $term; } /** * Cleanse the field value in the term based on the context. * * Passing a term field value through the function should be assumed to have * cleansed the value for whatever context the term field is going to be used. * * If no context or an unsupported context is given, then default filters will * be applied. * * There are enough filters for each context to support a custom filtering * without creating your own filter function. Simply create a function that * hooks into the filter you need. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * * @param string $field Term field to sanitize * @param string $value Search for this term value * @param int $term_id Term ID * @param string $taxonomy Taxonomy Name * @param string $context Either edit, db, display, attribute, or js. * @return mixed sanitized field */ function sanitize_term_field($field, $value, $term_id, $taxonomy, $context) { if ( 'parent' == $field || 'term_id' == $field || 'count' == $field || 'term_group' == $field ) { $value = (int) $value; if ( $value < 0 ) $value = 0; } if ( 'raw' == $context ) return $value; if ( 'edit' == $context ) { $value = apply_filters("edit_term_$field", $value, $term_id, $taxonomy); $value = apply_filters("edit_${taxonomy}_$field", $value, $term_id); if ( 'description' == $field ) $value = format_to_edit($value); else $value = attribute_escape($value); } else if ( 'db' == $context ) { $value = apply_filters("pre_term_$field", $value, $taxonomy); $value = apply_filters("pre_${taxonomy}_$field", $value); // Back compat filters if ( 'slug' == $field ) $value = apply_filters('pre_category_nicename', $value); } else if ( 'rss' == $context ) { $value = apply_filters("term_${field}_rss", $value, $taxonomy); $value = apply_filters("${taxonomy}_${field}_rss", $value); } else { // Use display filters by default. $value = apply_filters("term_$field", $value, $term_id, $taxonomy, $context); $value = apply_filters("${taxonomy}_$field", $value, $term_id, $context); } if ( 'attribute' == $context ) $value = attribute_escape($value); else if ( 'js' == $context ) $value = js_escape($value); return $value; } /** * Count how many terms are in Taxonomy. * * Default $args is 'ignore_empty' which can be 'ignore_empty=true' * or array('ignore_empty' => true);. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses wp_parse_args() Turns strings into arrays and merges defaults into an array. * * @param string $taxonomy Taxonomy name * @param array|string $args Overwrite defaults * @return int How many terms are in $taxonomy */ function wp_count_terms( $taxonomy, $args = array() ) { global $wpdb; $defaults = array('ignore_empty' => false); $args = wp_parse_args($args, $defaults); extract($args, EXTR_SKIP); $where = ''; if ( $ignore_empty ) $where = 'AND count > 0'; return $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE taxonomy = %s $where", $taxonomy) ); } /** * Will unlink the term from the taxonomy. * * Will remove the term's relationship to the taxonomy, not the term or taxonomy * itself. The term and taxonomy will still exist. Will require the term's * object ID to perform the operation. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @param int $object_id The term Object Id that refers to the term * @param string|array $taxonomy List of Taxonomy Names or single Taxonomy name. */ function wp_delete_object_term_relationships( $object_id, $taxonomies ) { global $wpdb; $object_id = (int) $object_id; if ( !is_array($taxonomies) ) $taxonomies = array($taxonomies); foreach ( $taxonomies as $taxonomy ) { $terms = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids'); $in_terms = "'" . implode("', '", $terms) . "'"; $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_terms)", $object_id) ); wp_update_term_count($terms, $taxonomy); } } /** * Removes a term from the database. * * If the term is a parent of other terms, then the children will be updated to * that term's parent. * * The $args 'default' will only override the terms found, if there is only one * term found. Any other and the found terms are used. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses do_action() Calls both 'delete_term' and 'delete_$taxonomy' action * hooks, passing term object, term id. 'delete_term' gets an additional * parameter with the $taxonomy parameter. * * @param int $term Term ID * @param string $taxonomy Taxonomy Name * @param array|string $args Optional. Change 'default' term id and override found term ids. * @return bool|WP_Error Returns false if not term; true if completes delete action. */ function wp_delete_term( $term, $taxonomy, $args = array() ) { global $wpdb; $term = (int) $term; if ( ! $ids = is_term($term, $taxonomy) ) return false; if ( is_wp_error( $ids ) ) return $ids; $tt_id = $ids['term_taxonomy_id']; $defaults = array(); $args = wp_parse_args($args, $defaults); extract($args, EXTR_SKIP); if ( isset($default) ) { $default = (int) $default; if ( ! is_term($default, $taxonomy) ) unset($default); } // Update children to point to new parent if ( is_taxonomy_hierarchical($taxonomy) ) { $term_obj = get_term($term, $taxonomy); if ( is_wp_error( $term_obj ) ) return $term_obj; $parent = $term_obj->parent; $wpdb->update( $wpdb->term_taxonomy, compact( 'parent' ), array( 'parent' => $term_obj->term_id) + compact( 'taxonomy' ) ); } $objects = $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) ); foreach ( (array) $objects as $object ) { $terms = wp_get_object_terms($object, $taxonomy, 'fields=ids'); if ( 1 == count($terms) && isset($default) ) $terms = array($default); else $terms = array_diff($terms, array($term)); $terms = array_map('intval', $terms); wp_set_object_terms($object, $terms, $taxonomy); } $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $tt_id ) ); // Delete the term if no taxonomies use it. if ( !$wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE term_id = %d", $term) ) ) $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->terms WHERE term_id = %d", $term) ); clean_term_cache($term, $taxonomy); do_action('delete_term', $term, $tt_id, $taxonomy); do_action("delete_$taxonomy", $term, $tt_id); return true; } /** * Retrieves the terms associated with the given object(s), in the supplied taxonomies. * * The following information has to do the $args parameter and for what can be * contained in the string or array of that parameter, if it exists. * * The first argument is called, 'orderby' and has the default value of 'name'. * The other value that is supported is 'count'. * * The second argument is called, 'order' and has the default value of 'ASC'. * The only other value that will be acceptable is 'DESC'. * * The final argument supported is called, 'fields' and has the default value of * 'all'. There are multiple other options that can be used instead. Supported * values are as follows: 'all', 'ids', 'names', and finally * 'all_with_object_id'. * * The fields argument also decides what will be returned. If 'all' or * 'all_with_object_id' is choosen or the default kept intact, then all matching * terms objects will be returned. If either 'ids' or 'names' is used, then an * array of all matching term ids or term names will be returned respectively. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @param int|array $object_id The id of the object(s) to retrieve. * @param string|array $taxonomies The taxonomies to retrieve terms from. * @param array|string $args Change what is returned * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if $taxonomy does not exist. */ function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { global $wpdb; if ( !is_array($taxonomies) ) $taxonomies = array($taxonomies); foreach ( $taxonomies as $taxonomy ) { if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); } if ( !is_array($object_ids) ) $object_ids = array($object_ids); $object_ids = array_map('intval', $object_ids); $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all'); $args = wp_parse_args( $args, $defaults ); $terms = array(); if ( count($taxonomies) > 1 ) { foreach ( $taxonomies as $index => $taxonomy ) { $t = get_taxonomy($taxonomy); if ( isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args) ) { unset($taxonomies[$index]); $terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args))); } } } else { $t = get_taxonomy($taxonomies[0]); if ( isset($t->args) && is_array($t->args) ) $args = array_merge($args, $t->args); } extract($args, EXTR_SKIP); if ( 'count' == $orderby ) $orderby = 'tt.count'; else if ( 'name' == $orderby ) $orderby = 't.name'; else if ( 'slug' == $orderby ) $orderby = 't.slug'; else if ( 'term_group' == $orderby ) $orderby = 't.term_group'; else if ( 'term_order' == $orderby ) $orderby = 'tr.term_order'; else $orderby = 't.term_id'; $taxonomies = "'" . implode("', '", $taxonomies) . "'"; $object_ids = implode(', ', $object_ids); $select_this = ''; if ( 'all' == $fields ) $select_this = 't.*, tt.*'; else if ( 'ids' == $fields ) $select_this = 't.term_id'; else if ( 'names' == $fields ) $select_this = 't.name'; else if ( 'all_with_object_id' == $fields ) $select_this = 't.*, tt.*, tr.object_id'; $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) ORDER BY $orderby $order"; if ( 'all' == $fields || 'all_with_object_id' == $fields ) { $terms = array_merge($terms, $wpdb->get_results($query)); update_term_cache($terms); } else if ( 'ids' == $fields || 'names' == $fields ) { $terms = array_merge($terms, $wpdb->get_col($query)); } else if ( 'tt_ids' == $fields ) { $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) ORDER BY tr.term_taxonomy_id $order"); } if ( ! $terms ) return array(); return $terms; } /** * Adds a new term to the database. Optionally marks it as an alias of an existing term. * * Error handling is assigned for the nonexistance of the $taxonomy and $term * parameters before inserting. If both the term id and taxonomy exist * previously, then an array will be returned that contains the term id and the * contents of what is returned. The keys of the array are 'term_id' and * 'term_taxonomy_id' containing numeric values. * * It is assumed that the term does not yet exist or the above will apply. The * term will be first added to the term table and then related to the taxonomy * if everything is well. If everything is correct, then several actions will be * run prior to a filter and then several actions will be run after the filter * is run. * * The arguments decide how the term is handled based on the $args parameter. * The following is a list of the available overrides and the defaults. * * 'alias_of'. There is no default, but if added, expected is the slug that the * term will be an alias of. Expected to be a string. * * 'description'. There is no default. If exists, will be added to the database * along with the term. Expected to be a string. * * 'parent'. Expected to be numeric and default is 0 (zero). Will assign value * of 'parent' to the term. * * 'slug'. Expected to be a string. There is no default. * * If 'slug' argument exists then the slug will be checked to see if it is not * a valid term. If that check succeeds (it is not a valid term), then it is * added and the term id is given. If it fails, then a check is made to whether * the taxonomy is hierarchical and the parent argument is not empty. If the * second check succeeds, the term will be inserted and the term id will be * given. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @uses do_action() Calls 'create_term' hook with the term id and taxonomy id as parameters. * @uses do_action() Calls 'create_$taxonomy' hook with term id and taxonomy id as parameters. * @uses apply_filters() Calls 'term_id_filter' hook with term id and taxonomy id as parameters. * @uses do_action() Calls 'created_term' hook with the term id and taxonomy id as parameters. * @uses do_action() Calls 'created_$taxonomy' hook with term id and taxonomy id as parameters. * * @param int|string $term The term to add or update. * @param string $taxonomy The taxonomy to which to add the term * @param array|string $args Change the values of the inserted term * @return array|WP_Error The Term ID and Term Taxonomy ID */ function wp_insert_term( $term, $taxonomy, $args = array() ) { global $wpdb; if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); if ( is_int($term) && 0 == $term ) return new WP_Error('invalid_term_id', __('Invalid term ID')); if ( '' == trim($term) ) return new WP_Error('empty_term_name', __('A name is required for this term')); $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); $args = wp_parse_args($args, $defaults); $args['name'] = $term; $args['taxonomy'] = $taxonomy; $args = sanitize_term($args, $taxonomy, 'db'); extract($args, EXTR_SKIP); // expected_slashed ($name) $name = stripslashes($name); $description = stripslashes($description); if ( empty($slug) ) $slug = sanitize_title($name); $term_group = 0; if ( $alias_of ) { $alias = $wpdb->get_row( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $alias_of) ); if ( $alias->term_group ) { // The alias we want is already in a group, so let's use that one. $term_group = $alias->term_group; } else { // The alias isn't in a group, so let's create a new one and firstly add the alias term to it. $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $alias->term_id ) ); } } if ( ! $term_id = is_term($slug) ) { $maxterm = $wpdb->get_var( "SELECT max(term_id) FROM {$wpdb->terms}" ); $term_id = mt_rand( $maxterm+100, $maxterm+4000 ); if ( false === $wpdb->insert( $wpdb->terms, compact( 'term_id', 'name', 'slug', 'term_group' ) ) ) return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); } else if ( is_taxonomy_hierarchical($taxonomy) && !empty($parent) ) { // If the taxonomy supports hierarchy and the term has a parent, make the slug unique // by incorporating parent slugs. $slug = wp_unique_term_slug($slug, (object) $args); $maxterm = $wpdb->get_var( "SELECT max(term_id) FROM {$wpdb->terms}" ); $term_id = mt_rand( $maxterm+100, $maxterm+4000 ); if ( false === $wpdb->insert( $wpdb->terms, compact( 'term_id','name', 'slug', 'term_group' ) ) ) return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); } if ( empty($slug) ) { $slug = sanitize_title($slug, $term_id); $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); } $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id ) ); if ( !empty($tt_id) ) return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent') + array( 'count' => 0 ) ); $tt_id = (int) $wpdb->insert_id; do_action("create_term", $term_id, $tt_id); do_action("create_$taxonomy", $term_id, $tt_id); $term_id = apply_filters('term_id_filter', $term_id, $tt_id); clean_term_cache($term_id, $taxonomy); do_action("created_term", $term_id, $tt_id); do_action("created_$taxonomy", $term_id, $tt_id); return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); } /** * Create Term and Taxonomy Relationships. * * Relates an object (post, link etc) to a term and taxonomy type. Creates the * term and taxonomy relationship if it doesn't already exist. Creates a term if * it doesn't exist (using the slug). * * A relationship means that the term is grouped in or belongs to the taxonomy. * A term has no meaning until it is given context by defining which taxonomy it * exists under. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @param int $object_id The object to relate to. * @param array|int|string $term The slug or id of the term. * @param array|string $taxonomy The context in which to relate the term to the object. * @param bool $append If false will delete difference of terms. * @return array|WP_Error Affected Term IDs */ function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) { global $wpdb; $object_id = (int) $object_id; if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); if ( !is_array($terms) ) $terms = array($terms); if ( ! $append ) $old_terms = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids'); $tt_ids = array(); $term_ids = array(); foreach ($terms as $term) { if ( !strlen(trim($term)) ) continue; if ( !$id = is_term($term, $taxonomy) ) $id = wp_insert_term($term, $taxonomy); if ( is_wp_error($id) ) return $id; $term_ids[] = $id['term_id']; $id = $id['term_taxonomy_id']; $tt_ids[] = $id; if ( $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $id ) ) ) continue; $wpdb->insert( $wpdb->term_relationships, array( 'object_id' => $object_id, 'term_taxonomy_id' => $id ) ); } wp_update_term_count($tt_ids, $taxonomy); if ( ! $append ) { $delete_terms = array_diff($old_terms, $tt_ids); if ( $delete_terms ) { $in_delete_terms = "'" . implode("', '", $delete_terms) . "'"; $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_delete_terms)", $object_id) ); wp_update_term_count($delete_terms, $taxonomy); } } $t = get_taxonomy($taxonomy); if ( ! $append && isset($t->sort) && $t->sort ) { $values = array(); $term_order = 0; $final_tt_ids = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids'); foreach ( $tt_ids as $tt_id ) if ( in_array($tt_id, $final_tt_ids) ) $values[] = $wpdb->prepare( "(%d, %d, %d)", $object_id, $tt_id, ++$term_order); if ( $values ) $wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join(',', $values) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)"); } return $tt_ids; } /** * Will make slug unique, if it isn't already. * * The $slug has to be unique global to every taxonomy, meaning that one * taxonomy term can't have a matching slug with another taxonomy term. Each * slug has to be globally unique for every taxonomy. * * The way this works is that if the taxonomy that the term belongs to is * heirarchical and has a parent, it will append that parent to the $slug. * * If that still doesn't return an unique slug, then it try to append a number * until it finds a number that is truely unique. * * The only purpose for $term is for appending a parent, if one exists. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @param string $slug The string that will be tried for a unique slug * @param object $term The term object that the $slug will belong too * @return string Will return a true unique slug. */ function wp_unique_term_slug($slug, $term) { global $wpdb; // If the taxonomy supports hierarchy and the term has a parent, make the slug unique // by incorporating parent slugs. if ( is_taxonomy_hierarchical($term->taxonomy) && !empty($term->parent) ) { $the_parent = $term->parent; while ( ! empty($the_parent) ) { $parent_term = get_term($the_parent, $term->taxonomy); if ( is_wp_error($parent_term) || empty($parent_term) ) break; $slug .= '-' . $parent_term->slug; if ( empty($parent_term->parent) ) break; $the_parent = $parent_term->parent; } } // If we didn't get a unique slug, try appending a number to make it unique. if ( !empty($args['term_id']) ) $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $args['term_id'] ); else $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug ); if ( $wpdb->get_var( $query ) ) { $num = 2; do { $alt_slug = $slug . "-$num"; $num++; $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); } while ( $slug_check ); $slug = $alt_slug; } return $slug; } /** * Update term based on arguments provided. * * The $args will indiscriminately override all values with the same field name. * Care must be taken to not override important information need to update or * update will fail (or perhaps create a new term, neither would be acceptable). * * Defaults will set 'alias_of', 'description', 'parent', and 'slug' if not * defined in $args already. * * 'alias_of' will create a term group, if it doesn't already exist, and update * it for the $term. * * If the 'slug' argument in $args is missing, then the 'name' in $args will be * used. It should also be noted that if you set 'slug' and it isn't unique then * a WP_Error will be passed back. If you don't pass any slug, then a unique one * will be created for you. * * For what can be overrode in $args, check the term scheme can contain and stay * away from the term keys. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses $wpdb * @uses do_action() Will call both 'edit_term' and 'edit_$taxonomy' twice. * @uses apply_filters() Will call the 'term_id_filter' filter and pass the term * id and taxonomy id. * * @param int $term The ID of the term * @param string $taxonomy The context in which to relate the term to the object. * @param array|string $args Overwrite term field values * @return array|WP_Error Returns Term ID and Taxonomy Term ID */ function wp_update_term( $term, $taxonomy, $args = array() ) { global $wpdb; if ( ! is_taxonomy($taxonomy) ) return new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); $term_id = (int) $term; $args = apply_filters( 'pre_update_term', $term, $taxonomy, $args ); // First, get all of the original args $term = get_term ($term_id, $taxonomy, ARRAY_A); // Escape data pulled from DB. $term = add_magic_quotes($term); // Merge old and new args with new args overwriting old ones. $args = array_merge($term, $args); $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); $args = wp_parse_args($args, $defaults); $args = sanitize_term($args, $taxonomy, 'db'); extract($args, EXTR_SKIP); // expected_slashed ($name) $name = stripslashes($name); $description = stripslashes($description); if ( '' == trim($name) ) return new WP_Error('empty_term_name', __('A name is required for this term')); $empty_slug = false; if ( empty($slug) ) { $empty_slug = true; $slug = sanitize_title($name); } if ( $alias_of ) { $alias = $wpdb->get_row( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $alias_of) ); if ( $alias->term_group ) { // The alias we want is already in a group, so let's use that one. $term_group = $alias->term_group; } else { // The alias isn't in a group, so let's create a new one and firstly add the alias term to it. $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; $wpdb->update( $wpdb->terms, compact('term_group'), array( 'term_id' => $alias->term_id ) ); } } // Check for duplicate slug $id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms WHERE slug = %s", $slug ) ); if ( $id && ($id != $term_id) ) { // If an empty slug was passed or the parent changed, reset the slug to something unique. // Otherwise, bail. if ( $empty_slug || ( $parent != $term->parent) ) $slug = wp_unique_term_slug($slug, (object) $args); else return new WP_Error('duplicate_term_slug', sprintf(__('The slug "%s" is already in use by another term'), $slug)); } $wpdb->update($wpdb->terms, compact( 'name', 'slug', 'term_group' ), compact( 'term_id' ) ); if ( empty($slug) ) { $slug = sanitize_title($name, $term_id); $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); } $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id) ); $wpdb->update( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ), array( 'term_taxonomy_id' => $tt_id ) ); do_action("edit_term", $term_id, $tt_id); do_action("edit_$taxonomy", $term_id, $tt_id); $term_id = apply_filters('term_id_filter', $term_id, $tt_id); clean_term_cache($term_id, $taxonomy); do_action("edited_term", $term_id, $tt_id); do_action("edited_$taxonomy", $term_id, $tt_id); return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); } /** * Enable or disable term counting. * * @since 2.6 * * @param bool $defer Optional. * @return bool */ function wp_defer_term_counting($defer=NULL) { static $_defer = false; if ( is_bool($defer) ) { $_defer = $defer; // flush any deferred counts if ( !$defer ) wp_update_term_count( NULL, NULL, true ); } return $_defer; } /** * Updates the amount of terms in taxonomy. * * If there is a taxonomy callback applyed, then it will be called for updating * the count. * * The default action is to count what the amount of terms have the relationship * of term ID. Once that is done, then update the database. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @param int|array $terms The ID of the terms * @param string $taxonomy The context of the term. * @return bool If no terms will return false, and if successful will return true. */ function wp_update_term_count( $terms, $taxonomy, $do_deferred=false ) { static $_deferred = array(); if ( $do_deferred ) { foreach ( array_keys($_deferred) as $tax ) { wp_update_term_count_now( $_deferred[$tax], $tax ); unset( $_deferred[$tax] ); } } if ( empty($terms) ) return false; if ( !is_array($terms) ) $terms = array($terms); if ( wp_defer_term_counting() ) { if ( !isset($_deferred[$taxonomy]) ) $_deferred[$taxonomy] = array(); $_deferred[$taxonomy] = array_unique( array_merge($_deferred[$taxonomy], $terms) ); return true; } return wp_update_term_count_now( $terms, $taxonomy ); } /** * Perform term count update immediately. * * @since 2.6 * * @param array $terms IDs of Terms to update. * @param string $taxonomy The context of the term. * @return bool Always true when complete. */ function wp_update_term_count_now( $terms, $taxonomy ) { global $wpdb; $terms = array_map('intval', $terms); $taxonomy = get_taxonomy($taxonomy); if ( !empty($taxonomy->update_count_callback) ) { call_user_func($taxonomy->update_count_callback, $terms); } else { // Default count updater foreach ($terms as $term) { $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term) ); $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); } } clean_term_cache($terms); return true; } // // Cache // /** * Removes the taxonomy relationship to terms from the cache. * * Will remove the entire taxonomy relationship containing term $object_id. The * term IDs have to exist within the taxonomy $object_type for the deletion to * take place. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @see get_object_taxonomies() for more on $object_type * @uses do_action() Will call action hook named, 'clean_object_term_cache' after completion. * Passes, function params in same order. * * @param int|array $object_ids Single or list of term object ID(s) * @param array|string $object_type The taxonomy object type */ function clean_object_term_cache($object_ids, $object_type) { if ( !is_array($object_ids) ) $object_ids = array($object_ids); foreach ( $object_ids as $id ) foreach ( get_object_taxonomies($object_type) as $taxonomy ) wp_cache_delete($id, "{$taxonomy}_relationships"); do_action('clean_object_term_cache', $object_ids, $object_type); } /** * Will remove all of the term ids from the cache. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wpdb * * @param int|array $ids Single or list of Term IDs * @param string $taxonomy Can be empty and will assume tt_ids, else will use for context. */ function clean_term_cache($ids, $taxonomy = '') { global $wpdb; if ( !is_array($ids) ) $ids = array($ids); $taxonomies = array(); // If no taxonomy, assume tt_ids. if ( empty($taxonomy) ) { $tt_ids = implode(', ', $ids); $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)"); foreach ( (array) $terms as $term ) { $taxonomies[] = $term->taxonomy; wp_cache_delete($term->term_id, $term->taxonomy); } $taxonomies = array_unique($taxonomies); } else { foreach ( $ids as $id ) { wp_cache_delete($id, $taxonomy); } $taxonomies = array($taxonomy); } foreach ( $taxonomies as $taxonomy ) { wp_cache_delete('all_ids', $taxonomy); wp_cache_delete('get', $taxonomy); delete_option("{$taxonomy}_children"); } wp_cache_delete('get_terms', 'terms'); do_action('clean_term_cache', $ids, $taxonomy); } /** * Retrieves the taxonomy relationship to the term object id. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @uses wp_cache_get() Retrieves taxonomy relationship from cache * * @param int|array $id Term object ID * @param string $taxonomy Taxonomy Name * @return bool|array Empty array if $terms found, but not $taxonomy. False if nothing is in cache for $taxonomy and $id. */ function &get_object_term_cache($id, $taxonomy) { $cache = wp_cache_get($id, "{$taxonomy}_relationships"); return $cache; } /** * Updates the cache for Term ID(s). * * Will only update the cache for terms not already cached. * * The $object_ids expects that the ids be separated by commas, if it is a * string. * * It should be noted that update_object_term_cache() is very time extensive. It * is advised that the function is not called very often or at least not for a * lot of terms that exist in a lot of taxonomies. The amount of time increases * for each term and it also increases for each taxonomy the term belongs to. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses wp_get_object_terms() Used to get terms from the database to update * * @param string|array $object_ids Single or list of term object ID(s) * @param array|string $object_type The taxonomy object type * @return null|bool Null value is given with empty $object_ids. False if */ function update_object_term_cache($object_ids, $object_type) { if ( empty($object_ids) ) return; if ( !is_array($object_ids) ) $object_ids = explode(',', $object_ids); $object_ids = array_map('intval', $object_ids); $taxonomies = get_object_taxonomies($object_type); $ids = array(); foreach ( (array) $object_ids as $id ) { foreach ( $taxonomies as $taxonomy ) { if ( false === wp_cache_get($id, "{$taxonomy}_relationships") ) { $ids[] = $id; break; } } } if ( empty( $ids ) ) return false; $terms = wp_get_object_terms($ids, $taxonomies, 'fields=all_with_object_id'); $object_terms = array(); foreach ( (array) $terms as $term ) $object_terms[$term->object_id][$term->taxonomy][$term->term_id] = $term; foreach ( $ids as $id ) { foreach ( $taxonomies as $taxonomy ) { if ( ! isset($object_terms[$id][$taxonomy]) ) { if ( !isset($object_terms[$id]) ) $object_terms[$id] = array(); $object_terms[$id][$taxonomy] = array(); } } } foreach ( $object_terms as $id => $value ) { foreach ( $value as $taxonomy => $terms ) { wp_cache_set($id, $terms, "{$taxonomy}_relationships"); } } } /** * Updates Terms to Taxonomy in cache. * * @package WordPress * @subpackage Taxonomy * @since 2.3 * * @param array $terms List of Term objects to change * @param string $taxonomy Optional. Update Term to this taxonomy in cache */ function update_term_cache($terms, $taxonomy = '') { foreach ( $terms as $term ) { $term_taxonomy = $taxonomy; if ( empty($term_taxonomy) ) $term_taxonomy = $term->taxonomy; wp_cache_add($term->term_id, $term, $term_taxonomy); } } // // Private // /** * Retrieves children of taxonomy. * * @package WordPress * @subpackage Taxonomy * @access private * @since 2.3 * * @uses update_option() Stores all of the children in "$taxonomy_children" * option. That is the name of the taxonomy, immediately followed by '_children'. * * @param string $taxonomy Taxonomy Name * @return array Empty if $taxonomy isn't hierarachical or returns children. */ function _get_term_hierarchy($taxonomy) { if ( !is_taxonomy_hierarchical($taxonomy) ) return array(); $children = get_option("{$taxonomy}_children"); if ( is_array($children) ) return $children; $children = array(); $terms = get_terms($taxonomy, 'get=all'); foreach ( $terms as $term ) { if ( $term->parent > 0 ) $children[$term->parent][] = $term->term_id; } update_option("{$taxonomy}_children", $children); return $children; } /** * Get array of child terms. * * If $terms is an array of objects, then objects will returned from the * function. If $terms is an array of IDs, then an array of ids of children will * be returned. * * @package WordPress * @subpackage Taxonomy * @access private * @since 2.3 * * @param int $term_id Look for this Term ID in $terms * @param array $terms List of Term IDs * @param string $taxonomy Term Context * @return array Empty if $terms is empty else returns full list of child terms. */ function &_get_term_children($term_id, $terms, $taxonomy) { $empty_array = array(); if ( empty($terms) ) return $empty_array; $term_list = array(); $has_children = _get_term_hierarchy($taxonomy); if ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) ) return $empty_array; foreach ( $terms as $term ) { $use_id = false; if ( !is_object($term) ) { $term = get_term($term, $taxonomy); if ( is_wp_error( $term ) ) return $term; $use_id = true; } if ( $term->term_id == $term_id ) continue; if ( $term->parent == $term_id ) { if ( $use_id ) $term_list[] = $term->term_id; else $term_list[] = $term; if ( !isset($has_children[$term->term_id]) ) continue; if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) ) $term_list = array_merge($term_list, $children); } } return $term_list; } /** * Add count of children to parent count. * * Recalculates term counts by including items from child terms. Assumes all * relevant children are already in the $terms argument. * * @package WordPress * @subpackage Taxonomy * @access private * @since 2.3 * @uses $wpdb * * @param array $terms List of Term IDs * @param string $taxonomy Term Context * @return null Will break from function if conditions are not met. */ function _pad_term_counts(&$terms, $taxonomy) { global $wpdb; // This function only works for post categories. if ( 'category' != $taxonomy ) return; $term_hier = _get_term_hierarchy($taxonomy); if ( empty($term_hier) ) return; $term_items = array(); foreach ( $terms as $key => $term ) { $terms_by_id[$term->term_id] = & $terms[$key]; $term_ids[$term->term_taxonomy_id] = $term->term_id; } // Get the object and term ids and stick them in a lookup table $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (".join(',', array_keys($term_ids)).") AND post_type = 'post' AND post_status = 'publish'"); foreach ( $results as $row ) { $id = $term_ids[$row->term_taxonomy_id]; ++$term_items[$id][$row->object_id]; } // Touch every ancestor's lookup row for each post in each term foreach ( $term_ids as $term_id ) { $child = $term_id; while ( $parent = $terms_by_id[$child]->parent ) { if ( !empty($term_items[$term_id]) ) foreach ( $term_items[$term_id] as $item_id => $touches ) ++$term_items[$parent][$item_id]; $child = $parent; } } // Transfer the touched cells foreach ( (array) $term_items as $id => $items ) if ( isset($terms_by_id[$id]) ) $terms_by_id[$id]->count = count($items); } // // Default callbacks // /** * Will update term count based on posts. * * Private function for the default callback for post_tag and category * taxonomies. * * @package WordPress * @subpackage Taxonomy * @access private * @since 2.3 * @uses $wpdb * * @param array $terms List of Term IDs */ function _update_post_term_count( $terms ) { global $wpdb; foreach ( $terms as $term ) { $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type = 'post' AND term_taxonomy_id = %d", $term ) ); $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); } } /** * Generates a permalink for a taxonomy term archive. * * @since 2.6 * * @param object|int|string $term * @param string $taxonomy * @return string HTML link to taxonomy term archive */ function get_term_link( $term, $taxonomy ) { global $wp_rewrite; // use legacy functions for core taxonomies until they are fully plugged in if ( $taxonomy == 'category' ) return get_category_link($term); if ( $taxonomy == 'post_tag' ) return get_tag_link($term); $termlink = $wp_rewrite->get_extra_permastruct($taxonomy); if ( !is_object($term) ) { if ( is_int($term) ) { $term = &get_term($term, $taxonomy); } else { $term = &get_term_by('slug', $term, $taxonomy); } } if ( is_wp_error( $term ) ) return $term; $slug = $term->slug; if ( empty($termlink) ) { $file = get_option('home') . '/'; $t = get_taxonomy($taxonomy); if ( $t->query_var ) $termlink = "$file?$t->query_var=$slug"; else $termlink = "$file?taxonomy=$taxonomy&term=$slug"; } else { $termlink = str_replace("%$taxonomy%", $slug, $termlink); $termlink = get_option('home') . user_trailingslashit($termlink, 'category'); } return apply_filters('term_link', $termlink, $term, $taxonomy); } /** * Display the taxonomies of a post with available options. * * This function can be used within the loop to display the taxonomies for a * post without specifying the Post ID. You can also use it outside the Loop to * display the taxonomies for a specific post. * * The available defaults are: * 'post' : default is 0. The post ID to get taxonomies of. * 'before' : default is empty string. Display before taxonomies list. * 'sep' : default is empty string. Separate every taxonomy with value in this. * 'after' : default is empty string. Display this after the taxonomies list. * * @since 2.6 * @uses get_the_taxonomies() * * @param array $args Override the defaults. */ function the_taxonomies($args = array()) { $defaults = array( 'post' => 0, 'before' => '', 'sep' => ' ', 'after' => '', ); $r = wp_parse_args( $args, $defaults ); extract( $r, EXTR_SKIP ); echo $before . join($sep, get_the_taxonomies($post)) . $after; } /** * Retrieve all taxonomies associated with a post. * * This function can be used within the loop. It will also return an array of * the taxonomies with links to the taxonomy and name. * * @since 2.6 * * @param int $post Optional. Post ID or will use Global Post ID (in loop). * @return array */ function get_the_taxonomies($post = 0) { if ( is_int($post) ) $post =& get_post($post); elseif ( !is_object($post) ) $post =& $GLOBALS['post']; $taxonomies = array(); if ( !$post ) return $taxonomies; $template = apply_filters('taxonomy_template', '%s: %l.'); foreach ( get_object_taxonomies($post) as $taxonomy ) { $t = (array) get_taxonomy($taxonomy); if ( empty($t['label']) ) $t['label'] = $taxonomy; if ( empty($t['args']) ) $t['args'] = array(); if ( empty($t['template']) ) $t['template'] = $template; $terms = get_object_term_cache($post->ID, $taxonomy); if ( empty($terms) ) $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']); $links = array(); foreach ( $terms as $term ) $links[] = "$term->name"; if ( $links ) $taxonomies[$taxonomy] = wp_sprintf($t['template'], $t['label'], $links, $terms); } return $taxonomies; } /** * Retrieve all taxonomies of a post with just the names. * * @since 2.6 * @uses get_object_taxonomies() * * @param int $post Optional. Post ID * @return array */ function get_post_taxonomies($post = 0) { $post =& get_post($post); return get_object_taxonomies($post); } ?> blogs/wp-includes/class-snoopy.php0000644000000000000000000011200111077635520016260 0ustar rootroot * @copyright 1999-2000 ispi, all rights reserved * @version 1.01 * @license GNU Lesser GPL * @link http://snoopy.sourceforge.net/ * @package Snoopy */ if ( !in_array('Snoopy', get_declared_classes() ) ) : /** * Snoopy - the PHP net client * * @author Monte Ohrt * @copyright (c): 1999-2000 ispi, all rights reserved * @version 1.01 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the author of Snoopy by e-mail at: * monte@ispi.net * * Or, write to: * Monte Ohrt * CTO, ispi * 237 S. 70th suite 220 * Lincoln, NE 68510 * * @link http://snoopy.sourceforge.net/ The latest version of Snoopy can be * obtained */ class Snoopy { /**** Public variables ****/ /* user definable vars */ var $host = "www.php.net"; // host name we are connecting to var $port = 80; // port we are connecting to var $proxy_host = ""; // proxy host to use var $proxy_port = ""; // proxy port to use var $proxy_user = ""; // proxy user to use var $proxy_pass = ""; // proxy password to use var $agent = "Snoopy v1.2.3"; // agent we masquerade as var $referer = ""; // referer info to pass var $cookies = array(); // array of cookies to pass // $cookies["username"]="joe"; var $rawheaders = array(); // array of raw headers to send // $rawheaders["Content-type"]="text/html"; var $maxredirs = 5; // http redirection depth maximum. 0 = disallow var $lastredirectaddr = ""; // contains address of last redirected address var $offsiteok = true; // allows redirection off-site var $maxframes = 0; // frame content depth maximum. 0 = disallow var $expandlinks = true; // expand links to fully qualified URLs. // this only applies to fetchlinks() // submitlinks(), and submittext() var $passcookies = true; // pass set cookies back through redirects // NOTE: this currently does not respect // dates, domains or paths. var $user = ""; // user for http authentication var $pass = ""; // password for http authentication // http accept types var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; var $results = ""; // where the content is put var $error = ""; // error messages sent here var $response_code = ""; // response code returned from server var $headers = array(); // headers returned from server sent here var $maxlength = 8192; // max return data length (body) var $read_timeout = 0; // timeout on read operations, in seconds // supported only since PHP 4 Beta 4 // set to 0 to disallow timeouts var $timed_out = false; // if a read operation timed out var $status = 0; // http request status var $temp_dir = "/tmp"; // temporary directory that the webserver // has permission to write to. // under Windows, this should be C:\temp var $curl_path = "/usr/local/bin/curl"; // Snoopy will use cURL for fetching // SSL content if a full system path to // the cURL binary is supplied here. // set to false if you do not have // cURL installed. See http://curl.haxx.se // for details on installing cURL. // Snoopy does *not* use the cURL // library functions built into php, // as these functions are not stable // as of this Snoopy release. /**** Private variables ****/ var $_maxlinelen = 4096; // max line length (headers) var $_httpmethod = "GET"; // default http request method var $_httpversion = "HTTP/1.0"; // default http request version var $_submit_method = "POST"; // default submit method var $_submit_type = "application/x-www-form-urlencoded"; // default submit type var $_mime_boundary = ""; // MIME boundary for multipart/form-data submit type var $_redirectaddr = false; // will be set if page fetched is a redirect var $_redirectdepth = 0; // increments on an http redirect var $_frameurls = array(); // frame src urls var $_framedepth = 0; // increments on frame depth var $_isproxy = false; // set if using a proxy server var $_fp_timeout = 30; // timeout for socket connection /*======================================================================*\ Function: fetch Purpose: fetch the contents of a web page (and possibly other protocols in the future like ftp, nntp, gopher, etc.) Input: $URI the location of the page to fetch Output: $this->results the output text from the fetch \*======================================================================*/ function fetch($URI) { //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS); $URI_PARTS = parse_url($URI); if (!empty($URI_PARTS["user"])) $this->user = $URI_PARTS["user"]; if (!empty($URI_PARTS["pass"])) $this->pass = $URI_PARTS["pass"]; if (empty($URI_PARTS["query"])) $URI_PARTS["query"] = ''; if (empty($URI_PARTS["path"])) $URI_PARTS["path"] = ''; switch(strtolower($URI_PARTS["scheme"])) { case "http": $this->host = $URI_PARTS["host"]; if(!empty($URI_PARTS["port"])) $this->port = $URI_PARTS["port"]; if($this->_connect($fp)) { if($this->_isproxy) { // using proxy, send entire URI $this->_httprequest($URI,$fp,$URI,$this->_httpmethod); } else { $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); // no proxy, send only the path $this->_httprequest($path, $fp, $URI, $this->_httpmethod); } $this->_disconnect($fp); if($this->_redirectaddr) { /* url was redirected, check if we've hit the max depth */ if($this->maxredirs > $this->_redirectdepth) { // only follow redirect if it's on this site, or offsiteok is true if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) { /* follow the redirect */ $this->_redirectdepth++; $this->lastredirectaddr=$this->_redirectaddr; $this->fetch($this->_redirectaddr); } } } if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) { $frameurls = $this->_frameurls; $this->_frameurls = array(); while(list(,$frameurl) = each($frameurls)) { if($this->_framedepth < $this->maxframes) { $this->fetch($frameurl); $this->_framedepth++; } else break; } } } else { return false; } return true; break; case "https": if(!$this->curl_path) return false; if(function_exists("is_executable")) if (!is_executable($this->curl_path)) return false; $this->host = $URI_PARTS["host"]; if(!empty($URI_PARTS["port"])) $this->port = $URI_PARTS["port"]; if($this->_isproxy) { // using proxy, send entire URI $this->_httpsrequest($URI,$URI,$this->_httpmethod); } else { $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); // no proxy, send only the path $this->_httpsrequest($path, $URI, $this->_httpmethod); } if($this->_redirectaddr) { /* url was redirected, check if we've hit the max depth */ if($this->maxredirs > $this->_redirectdepth) { // only follow redirect if it's on this site, or offsiteok is true if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) { /* follow the redirect */ $this->_redirectdepth++; $this->lastredirectaddr=$this->_redirectaddr; $this->fetch($this->_redirectaddr); } } } if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) { $frameurls = $this->_frameurls; $this->_frameurls = array(); while(list(,$frameurl) = each($frameurls)) { if($this->_framedepth < $this->maxframes) { $this->fetch($frameurl); $this->_framedepth++; } else break; } } return true; break; default: // not a valid protocol $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; return false; break; } return true; } /*======================================================================*\ Function: submit Purpose: submit an http form Input: $URI the location to post the data $formvars the formvars to use. format: $formvars["var"] = "val"; $formfiles an array of files to submit format: $formfiles["var"] = "/dir/filename.ext"; Output: $this->results the text output from the post \*======================================================================*/ function submit($URI, $formvars="", $formfiles="") { unset($postdata); $postdata = $this->_prepare_post_body($formvars, $formfiles); $URI_PARTS = parse_url($URI); if (!empty($URI_PARTS["user"])) $this->user = $URI_PARTS["user"]; if (!empty($URI_PARTS["pass"])) $this->pass = $URI_PARTS["pass"]; if (empty($URI_PARTS["query"])) $URI_PARTS["query"] = ''; if (empty($URI_PARTS["path"])) $URI_PARTS["path"] = ''; switch(strtolower($URI_PARTS["scheme"])) { case "http": $this->host = $URI_PARTS["host"]; if(!empty($URI_PARTS["port"])) $this->port = $URI_PARTS["port"]; if($this->_connect($fp)) { if($this->_isproxy) { // using proxy, send entire URI $this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata); } else { $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); // no proxy, send only the path $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata); } $this->_disconnect($fp); if($this->_redirectaddr) { /* url was redirected, check if we've hit the max depth */ if($this->maxredirs > $this->_redirectdepth) { if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); // only follow redirect if it's on this site, or offsiteok is true if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) { /* follow the redirect */ $this->_redirectdepth++; $this->lastredirectaddr=$this->_redirectaddr; if( strpos( $this->_redirectaddr, "?" ) > 0 ) $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get else $this->submit($this->_redirectaddr,$formvars, $formfiles); } } } if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) { $frameurls = $this->_frameurls; $this->_frameurls = array(); while(list(,$frameurl) = each($frameurls)) { if($this->_framedepth < $this->maxframes) { $this->fetch($frameurl); $this->_framedepth++; } else break; } } } else { return false; } return true; break; case "https": if(!$this->curl_path) return false; if(function_exists("is_executable")) if (!is_executable($this->curl_path)) return false; $this->host = $URI_PARTS["host"]; if(!empty($URI_PARTS["port"])) $this->port = $URI_PARTS["port"]; if($this->_isproxy) { // using proxy, send entire URI $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata); } else { $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : ""); // no proxy, send only the path $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata); } if($this->_redirectaddr) { /* url was redirected, check if we've hit the max depth */ if($this->maxredirs > $this->_redirectdepth) { if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr)) $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]); // only follow redirect if it's on this site, or offsiteok is true if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok) { /* follow the redirect */ $this->_redirectdepth++; $this->lastredirectaddr=$this->_redirectaddr; if( strpos( $this->_redirectaddr, "?" ) > 0 ) $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get else $this->submit($this->_redirectaddr,$formvars, $formfiles); } } } if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0) { $frameurls = $this->_frameurls; $this->_frameurls = array(); while(list(,$frameurl) = each($frameurls)) { if($this->_framedepth < $this->maxframes) { $this->fetch($frameurl); $this->_framedepth++; } else break; } } return true; break; default: // not a valid protocol $this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n'; return false; break; } return true; } /*======================================================================*\ Function: fetchlinks Purpose: fetch the links from a web page Input: $URI where you are fetching from Output: $this->results an array of the URLs \*======================================================================*/ function fetchlinks($URI) { if ($this->fetch($URI)) { if($this->lastredirectaddr) $URI = $this->lastredirectaddr; if(is_array($this->results)) { for($x=0;$xresults);$x++) $this->results[$x] = $this->_striplinks($this->results[$x]); } else $this->results = $this->_striplinks($this->results); if($this->expandlinks) $this->results = $this->_expandlinks($this->results, $URI); return true; } else return false; } /*======================================================================*\ Function: fetchform Purpose: fetch the form elements from a web page Input: $URI where you are fetching from Output: $this->results the resulting html form \*======================================================================*/ function fetchform($URI) { if ($this->fetch($URI)) { if(is_array($this->results)) { for($x=0;$xresults);$x++) $this->results[$x] = $this->_stripform($this->results[$x]); } else $this->results = $this->_stripform($this->results); return true; } else return false; } /*======================================================================*\ Function: fetchtext Purpose: fetch the text from a web page, stripping the links Input: $URI where you are fetching from Output: $this->results the text from the web page \*======================================================================*/ function fetchtext($URI) { if($this->fetch($URI)) { if(is_array($this->results)) { for($x=0;$xresults);$x++) $this->results[$x] = $this->_striptext($this->results[$x]); } else $this->results = $this->_striptext($this->results); return true; } else return false; } /*======================================================================*\ Function: submitlinks Purpose: grab links from a form submission Input: $URI where you are submitting from Output: $this->results an array of the links from the post \*======================================================================*/ function submitlinks($URI, $formvars="", $formfiles="") { if($this->submit($URI,$formvars, $formfiles)) { if($this->lastredirectaddr) $URI = $this->lastredirectaddr; if(is_array($this->results)) { for($x=0;$xresults);$x++) { $this->results[$x] = $this->_striplinks($this->results[$x]); if($this->expandlinks) $this->results[$x] = $this->_expandlinks($this->results[$x],$URI); } } else { $this->results = $this->_striplinks($this->results); if($this->expandlinks) $this->results = $this->_expandlinks($this->results,$URI); } return true; } else return false; } /*======================================================================*\ Function: submittext Purpose: grab text from a form submission Input: $URI where you are submitting from Output: $this->results the text from the web page \*======================================================================*/ function submittext($URI, $formvars = "", $formfiles = "") { if($this->submit($URI,$formvars, $formfiles)) { if($this->lastredirectaddr) $URI = $this->lastredirectaddr; if(is_array($this->results)) { for($x=0;$xresults);$x++) { $this->results[$x] = $this->_striptext($this->results[$x]); if($this->expandlinks) $this->results[$x] = $this->_expandlinks($this->results[$x],$URI); } } else { $this->results = $this->_striptext($this->results); if($this->expandlinks) $this->results = $this->_expandlinks($this->results,$URI); } return true; } else return false; } /*======================================================================*\ Function: set_submit_multipart Purpose: Set the form submission content type to multipart/form-data \*======================================================================*/ function set_submit_multipart() { $this->_submit_type = "multipart/form-data"; } /*======================================================================*\ Function: set_submit_normal Purpose: Set the form submission content type to application/x-www-form-urlencoded \*======================================================================*/ function set_submit_normal() { $this->_submit_type = "application/x-www-form-urlencoded"; } /*======================================================================*\ Private functions \*======================================================================*/ /*======================================================================*\ Function: _striplinks Purpose: strip the hyperlinks from an html document Input: $document document to strip. Output: $match an array of the links \*======================================================================*/ function _striplinks($document) { preg_match_all("'<\s*a\s.*?href\s*=\s* # find ]+)) # if quote found, match up to next matching # quote, otherwise match up to next space 'isx",$document,$links); // catenate the non-empty matches from the conditional subpattern while(list($key,$val) = each($links[2])) { if(!empty($val)) $match[] = $val; } while(list($key,$val) = each($links[3])) { if(!empty($val)) $match[] = $val; } // return the links return $match; } /*======================================================================*\ Function: _stripform Purpose: strip the form elements from an html document Input: $document document to strip. Output: $match an array of the links \*======================================================================*/ function _stripform($document) { preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements); // catenate the matches $match = implode("\r\n",$elements[0]); // return the links return $match; } /*======================================================================*\ Function: _striptext Purpose: strip the text from an html document Input: $document document to strip. Output: $text the resulting text \*======================================================================*/ function _striptext($document) { // I didn't use preg eval (//e) since that is only available in PHP 4.0. // so, list your entities one by one here. I included some of the // more common ones. $search = array("']*?>.*?'si", // strip out javascript "'<[\/\!]*?[^<>]*?>'si", // strip out html tags "'([\r\n])[\s]+'", // strip out white space "'&(quot|#34|#034|#x22);'i", // replace html entities "'&(amp|#38|#038|#x26);'i", // added hexadecimal values "'&(lt|#60|#060|#x3c);'i", "'&(gt|#62|#062|#x3e);'i", "'&(nbsp|#160|#xa0);'i", "'&(iexcl|#161);'i", "'&(cent|#162);'i", "'&(pound|#163);'i", "'&(copy|#169);'i", "'&(reg|#174);'i", "'&(deg|#176);'i", "'&(#39|#039|#x27);'", "'&(euro|#8364);'i", // europe "'&a(uml|UML);'", // german "'&o(uml|UML);'", "'&u(uml|UML);'", "'&A(uml|UML);'", "'&O(uml|UML);'", "'&U(uml|UML);'", "'ß'i", ); $replace = array( "", "", "\\1", "\"", "&", "<", ">",