/********************************************************************************** * nWordPress is an automated migration of WordPress 2.5.1 performed by Numiton. * * copyright : (C) 2008 Numiton - www.numiton.com * email : numiton@users.sourceforge.net * * $Id: CanonicalPage.java,v 1.4 2008/10/14 13:15:48 numiton Exp $ * **********************************************************************************/ /********************************************************************************** * * This program 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. * **********************************************************************************/ /*************************************************************************** * * This program 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. * ***************************************************************************/ package org.numiton.nwp.wp_includes; import static com.numiton.PhpCommonConstants.BOOLEAN_FALSE; import static com.numiton.VarHandling.*; import static com.numiton.generic.PhpWeb.*; import java.io.IOException; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.numiton.nwp.NumitonController; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.numiton.FunctionHandling; import com.numiton.System; import com.numiton.URL; import com.numiton.array.Array; import com.numiton.array.ArrayEntry; import com.numiton.generic.*; import com.numiton.ntile.til.libraries.php.quercus.QRegExPerl; import com.numiton.string.Strings; @Controller @Scope("request") public class CanonicalPage extends NumitonController { protected static final Logger LOG = Logger.getLogger(CanonicalPage.class.getName()); @Override @RequestMapping("/wp-includes/canonical.php") public ModelAndView execute(HttpServletRequest javaRequest, HttpServletResponse javaResponse) throws IOException { return super.execute(javaRequest, javaResponse); } @Override public String getViewName() { return "wp_includes/canonical"; } public String redirect_canonical() { return redirect_canonical(null, true); } public String redirect_canonical(String requested_url) { return redirect_canonical(requested_url, true); } /** * Canonical API to handle WordPress Redirecting * * Based on "Permalink Redirect" from Scott Yang and "Enforce www. Preference" by Mark Jaquith * * @author Scott Yang * @author Mark Jaquith * @package WordPress * @since 2.3 */ /** * redirect_canonical() - Redirects incoming links to the proper URL based on the site url * * Search engines consider www.somedomain.com and somedomain.com to be two different URLs * when they both go to the same location. This SEO enhancement prevents penality for * duplicate content by redirecting all incoming links to one or the other. * * Prevents redirection for feeds, trackbacks, searches, comment popup, and admin URLs. * Does not redirect on IIS, page/post previews, and on form data. * * Will also attempt to find the correct link when a user enters a URL that does not exist * based on exact WordPress query. Will instead try to parse the URL or query in an attempt * to figure the correct page to go to. * * @since 2.3 * @uses $wp_rewrite * @uses $is_IIS * * @param string $requested_url Optional. The URL that was requested, used to figure if redirect is needed. * @param bool $do_redirect Optional. Redirect to the new URL. * @return null|false|string Null, if redirect not needed. False, if redirect not needed or the string of the URL */ public String redirect_canonical(String requested_url, boolean do_redirect) { Array<String> original = new Array<String>(); Array<String> redirect = new Array<String>(); String redirect_url = null; String m = null; StdClass author; int paged; Array<String> paged_redirect = new Array<String>(); Array<String> user_home = new Array<String>(); String user_ts_type = null; String func = null; Object type = null; if (getIncluded(QueryPage.class, gVars, gConsts).is_feed() || getIncluded(QueryPage.class, gVars, gConsts).is_trackback() || getIncluded(QueryPage.class, gVars, gConsts).is_search() || getIncluded(QueryPage.class, gVars, gConsts).is_comments_popup() || getIncluded(QueryPage.class, gVars, gConsts).is_admin() || gVars.is_IIS || (isset(gVars.webEnv._POST) && booleanval(Array.count(gVars.webEnv._POST))) || getIncluded(QueryPage.class, gVars, gConsts).is_preview()) { return null; } if (!booleanval(requested_url)) { // build the URL in the address bar requested_url = ((isset(gVars.webEnv.getHttps()) && equal(Strings.strtolower(gVars.webEnv.getHttps()), "on")) ? "https://" : "http://"); requested_url = requested_url + gVars.webEnv.getHttpHost(); requested_url = requested_url + gVars.webEnv.getRequestURI(); } original = URL.parse_url(requested_url); if (empty(original)) { return null; } // Some PHP setups turn requests for / into /index.php in REQUEST_URI original.putValue("path", QRegExPerl.preg_replace("|/index\\.php$|", "/", original.getValue("path"))); redirect = original; redirect_url = strval(false); // These tests give us a WP-generated permalink if (getIncluded(QueryPage.class, gVars, gConsts).is_404()) { redirect_url = redirect_guess_404_permalink(); } else if (is_object(gVars.wp_rewrite) && gVars.wp_rewrite.using_permalinks()) { // rewriting of old ?p=X, ?m=2004, ?m=200401, ?m=20040101 if (getIncluded(QueryPage.class, gVars, gConsts).is_single() && isset(gVars.webEnv._GET.getValue("p"))) { if (booleanval(redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_permalink(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("p"), false))) { redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("p", redirect.getValue("query"))); } } else if (getIncluded(QueryPage.class, gVars, gConsts).is_page("") && isset(gVars.webEnv._GET.getValue("page_id"))) { if (booleanval(redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_permalink(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("page_id"), false))) { redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("page_id", redirect.getValue("query"))); } } else if (isset(gVars.webEnv._GET.getValue("m")) && (getIncluded(QueryPage.class, gVars, gConsts).is_year() || getIncluded(QueryPage.class, gVars, gConsts).is_month() || (((QueryPage) PhpWeb.getIncluded(QueryPage.class, gVars, gConsts))).is_day())) { m = strval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("m")); switch (Strings.strlen(m)) { case 4: { // Yearly redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_year_link(m); break; } case 6: { // Monthly redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_month_link(Strings.substr(m, 0, 4), Strings.substr(m, 4, 2)); break; } case 8: { // Daily redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_day_link(Strings.substr(m, 0, 4), Strings.substr(m, 4, 2), Strings.substr(m, 6, 2)); break; } } if (booleanval(redirect_url)) { redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("m", redirect.getValue("query"))); } // now moving on to non ?m=X year/month/day links } else if (getIncluded(QueryPage.class, gVars, gConsts).is_day() && booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("year")) && booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("monthnum")) && isset(gVars.webEnv._GET.getValue("day"))) { if (booleanval( redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_day_link( strval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("year")), strval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("monthnum")), strval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("day"))))) { redirect.putValue( "query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg(new Array<Object>( new ArrayEntry<Object>("year"), new ArrayEntry<Object>("monthnum"), new ArrayEntry<Object>("day")), redirect.getValue("query"))); } } else if (getIncluded(QueryPage.class, gVars, gConsts).is_month() && booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("year")) && isset(gVars.webEnv._GET.getValue("monthnum"))) { if (booleanval( redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts).get_month_link( strval((((QueryPage) PhpWeb.getIncluded(QueryPage.class, gVars, gConsts))).get_query_var("year")), strval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("monthnum"))))) { redirect.putValue( "query", getIncluded(FunctionsPage.class, gVars, gConsts) .remove_query_arg(new Array<Object>(new ArrayEntry<Object>("year"), new ArrayEntry<Object>("monthnum")), redirect.getValue("query"))); } } else if (getIncluded(QueryPage.class, gVars, gConsts).is_year() && isset(gVars.webEnv._GET.getValue("year"))) { if (booleanval( redirect_url = getIncluded(Link_templatePage.class, gVars, gConsts) .get_year_link(strval((((QueryPage) PhpWeb.getIncluded(QueryPage.class, gVars, gConsts))).get_query_var("year"))))) { redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("year", redirect.getValue("query"))); } } else if (getIncluded(QueryPage.class, gVars, gConsts).is_category(new Array<Object>()) && isset(gVars.webEnv._GET.getValue("cat"))) { if (booleanval(redirect_url = strval(getIncluded(Category_templatePage.class, gVars, gConsts).get_category_link(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("cat"))))) { redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("cat", redirect.getValue("query"))); } } else if (getIncluded(QueryPage.class, gVars, gConsts).is_author() && isset(gVars.webEnv._GET.getValue("author"))) { author = getIncluded(PluggablePage.class, gVars, gConsts).get_userdata(intval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("author"))); if (!strictEqual(null, author) && booleanval( redirect_url = getIncluded(DeprecatedPage.class, gVars, gConsts).get_author_link(false, intval(StdClass.getValue(author, "ID")), StdClass.getValue(author, "user_nicename")))) { redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("author", redirect.getValue("author"))); } } // paging if (booleanval(paged = intval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("paged")))) { if (paged > 0) { if (!booleanval(redirect_url)) { redirect_url = requested_url; } paged_redirect = URL.parse_url(redirect_url); paged_redirect.putValue("path", QRegExPerl.preg_replace("|/page/[0-9]+?(/+)?$|", "/", paged_redirect.getValue("path"))); // strip off any existing paging paged_redirect.putValue("path", QRegExPerl.preg_replace("|/index.php/?$|", "/", paged_redirect.getValue("path"))); // strip off trailing /index.php/ if ((paged > 1) && !getIncluded(QueryPage.class, gVars, gConsts).is_single()) { paged_redirect.putValue("path", getIncluded(FormattingPage.class, gVars, gConsts).trailingslashit(paged_redirect.getValue("path"))); if (gVars.wp_rewrite.using_index_permalinks() && strictEqual(Strings.strpos(paged_redirect.getValue("path"), "/index.php/"), BOOLEAN_FALSE)) { paged_redirect.putValue("path", paged_redirect.getValue("path") + "index.php/"); } paged_redirect.putValue("path", paged_redirect.getValue("path") + getIncluded(Link_templatePage.class, gVars, gConsts).user_trailingslashit("page/" + strval(paged), "paged")); } else if (!getIncluded(QueryPage.class, gVars, gConsts).is_home() && !getIncluded(QueryPage.class, gVars, gConsts).is_single()) { paged_redirect.putValue("path", getIncluded(Link_templatePage.class, gVars, gConsts).user_trailingslashit(paged_redirect.getValue("path"), "paged")); } redirect_url = paged_redirect.getValue("scheme") + "://" + paged_redirect.getValue("host") + paged_redirect.getValue("path"); redirect.putValue("path", paged_redirect.getValue("path")); } redirect.putValue("query", getIncluded(FunctionsPage.class, gVars, gConsts).remove_query_arg("paged", redirect.getValue("query"))); } } // tack on any additional query vars if (booleanval(redirect_url) && booleanval(redirect.getValue("query"))) { if (!strictEqual(Strings.strpos(redirect_url, "?"), BOOLEAN_FALSE)) { redirect_url = redirect_url + "&"; } else { redirect_url = redirect_url + "?"; } redirect_url = redirect_url + redirect.getValue("query"); } if (booleanval(redirect_url)) { redirect = URL.parse_url(redirect_url); } // www.example.com vs example.com user_home = URL.parse_url(strval(getIncluded(FunctionsPage.class, gVars, gConsts).get_option("home"))); redirect.putValue("host", user_home.getValue("host")); // Handle ports if (isset(user_home.getValue("port"))) { redirect.putValue("port", user_home.getValue("port")); } else { redirect.arrayUnset("port"); } // trailing /index.php/ redirect.putValue("path", QRegExPerl.preg_replace("|/index.php/$|", "/", redirect.getValue("path"))); // strip /index.php/ when we're not using PATHINFO permalinks if (!gVars.wp_rewrite.using_index_permalinks()) { redirect.putValue("path", Strings.str_replace("/index.php/", "/", redirect.getValue("path"))); } // trailing slashes if (is_object(gVars.wp_rewrite) && gVars.wp_rewrite.using_permalinks() && !getIncluded(QueryPage.class, gVars, gConsts).is_404() && (!getIncluded(QueryPage.class, gVars, gConsts).is_home() || (getIncluded(QueryPage.class, gVars, gConsts).is_home() && (intval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("paged")) > 1)))) { user_ts_type = ""; if (intval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("paged")) > 0) { user_ts_type = "paged"; } else { for (Map.Entry javaEntry385 : new Array<Object>( new ArrayEntry<Object>("single"), new ArrayEntry<Object>("category"), new ArrayEntry<Object>("page"), new ArrayEntry<Object>("day"), new ArrayEntry<Object>("month"), new ArrayEntry<Object>("year")).entrySet()) { type = javaEntry385.getValue(); func = "is_" + strval(type); if (booleanval(FunctionHandling.call_user_func(new Callback(func, getIncluded(QueryPage.class, gVars, gConsts))))) { user_ts_type = strval(type); } break; } } redirect.putValue("path", getIncluded(Link_templatePage.class, gVars, gConsts).user_trailingslashit(redirect.getValue("path"), user_ts_type)); } else if (getIncluded(QueryPage.class, gVars, gConsts).is_home()) { redirect.putValue("path", getIncluded(FormattingPage.class, gVars, gConsts).trailingslashit(redirect.getValue("path"))); } // Always trailing slash the 'home' URL if (equal(redirect.getValue("path"), user_home.getValue("path"))) { redirect.putValue("path", getIncluded(FormattingPage.class, gVars, gConsts).trailingslashit(redirect.getValue("path"))); } // Ignore differences in host capitalization, as this can lead to infinite redirects if (equal(Strings.strtolower(original.getValue("host")), Strings.strtolower(redirect.getValue("host")))) { redirect.putValue("host", original.getValue("host")); } if (!strictEqual( new Array<Object>( new ArrayEntry<Object>(original.getValue("host")), new ArrayEntry<Object>(original.getValue("port")), new ArrayEntry<Object>(original.getValue("path")), new ArrayEntry<Object>(original.getValue("query"))), new Array<Object>( new ArrayEntry<Object>(redirect.getValue("host")), new ArrayEntry<Object>(redirect.getValue("port")), new ArrayEntry<Object>(redirect.getValue("path")), new ArrayEntry<Object>(redirect.getValue("query"))))) { redirect_url = redirect.getValue("scheme") + "://" + redirect.getValue("host"); if (isset(redirect.getValue("port"))) { redirect_url = redirect_url + ":" + redirect.getValue("port"); } redirect_url = redirect_url + redirect.getValue("path"); if (booleanval(redirect.getValue("query"))) { redirect_url = redirect_url + "?" + redirect.getValue("query"); } } if (!booleanval(redirect_url) || equal(redirect_url, requested_url)) { return strval(false); } // Note that you can use the "redirect_canonical" filter to cancel a canonical redirect for whatever reason by returning FALSE redirect_url = strval(getIncluded(PluginPage.class, gVars, gConsts).apply_filters("redirect_canonical", redirect_url, requested_url)); if (!booleanval(redirect_url) || equal(redirect_url, requested_url)) { // yes, again -- in case the filter aborted the request return strval(false); } if (do_redirect) { // protect against chained redirects if (!booleanval(redirect_canonical(redirect_url, false))) { getIncluded(PluggablePage.class, gVars, gConsts).wp_redirect(redirect_url, 301); System.exit(); } else { return strval(false); } } else { return redirect_url; } return ""; } /** * redirect_guess_404_permalink() - Tries to guess correct post based on * query vars * @since 2.3 * @uses $wpdb * @return bool|string Returns False, if it can't find post, returns correct * location on success. */ public String redirect_guess_404_permalink() { String where = null; Object post_id = null; if (!booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("name"))) { return strval(false); } where = gVars.wpdb.prepare("post_name LIKE %s", getIncluded(QueryPage.class, gVars, gConsts).get_query_var("name") + "%"); // if any of year, monthnum, or day are set, use them to refine the query if (booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("year"))) { where = where + gVars.wpdb.prepare(" AND YEAR(post_date) = %d", getIncluded(QueryPage.class, gVars, gConsts).get_query_var("year")); } if (booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("monthnum"))) { where = where + gVars.wpdb.prepare(" AND MONTH(post_date) = %d", getIncluded(QueryPage.class, gVars, gConsts).get_query_var("monthnum")); } if (booleanval(getIncluded(QueryPage.class, gVars, gConsts).get_query_var("day"))) { where = where + gVars.wpdb.prepare(" AND DAYOFMONTH(post_date) = %d", getIncluded(QueryPage.class, gVars, gConsts).get_query_var("day")); } post_id = gVars.wpdb.get_var("SELECT ID FROM " + gVars.wpdb.posts + " WHERE " + where + " AND post_status = \'publish\'"); if (!booleanval(post_id)) { return strval(false); } return getIncluded(Link_templatePage.class, gVars, gConsts).get_permalink(post_id, false); } public Object generateContent(PhpWebEnvironment webEnv) throws IOException, ServletException { /* Start of block */ super.startBlock("__wp_includes_canonical_block1"); gVars.webEnv = webEnv; getIncluded(PluginPage.class, gVars, gConsts).add_action("template_redirect", Callback.createCallbackArray(this, "redirect_canonical"), 10, 1); return DEFAULT_VAL; } }