ForbodingAngel

Untitled

May 3rd, 2014
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.27 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4. Plugin Name: Root Relative URLs
  5. Plugin URI: http://www.marcuspope.com/wordpress/
  6. Description: A Wordpress Plugin that converts all URL formats to root relative URL's to enable seamless transitioning
  7. between staging and production host environments without requiring hackish content find-replace or host/NAT
  8. spoofing strategies.
  9. Author: Marcus E. Pope, marcuspope
  10. Author URI: http://www.marcuspope.com
  11. Version: 2.3
  12.  
  13. Copyright 2011 Marcus E. Pope (email : [email protected])
  14.  
  15. This program is free software; you can redistribute it and/or modify
  16. it under the terms of the GNU General Public License, version 2, as
  17. published by the Free Software Foundation.
  18.  
  19. This program is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. GNU General Public License for more details.
  23.  
  24. You should have received a copy of the GNU General Public License
  25. along with this program; if not, write to the Free Software
  26. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  27.  
  28. */
  29.  
  30. //Ideally this function runs before any other plugin
  31. add_action('plugins_loaded', array('MP_WP_Root_Relative_URLS', 'init'), 1);
  32.  
  33. class MP_WP_Root_Relative_URLS {
  34. //Wordpress Root Relative URL Hack - this allows for accessing a Wordpress site from multiple domain names and
  35. //munges absolute urls provided to the wysiwyg editor to be root relative instead of absolute
  36. //generally displays urls throughout the admin area as root relative instead of absolute
  37.  
  38. //Normally we inject root relative urls when possible, especially for content creation
  39. static $massage = false;
  40.  
  41. static function add_actions($tag_arry, $func, $p = 10, $a = 1) {
  42. //allows for multiple tags to bind to the same funciton call
  43. //useful when using lambda functions
  44. foreach ($tag_arry as $v) {
  45. add_filter($v, $func, $p, $a);
  46. }
  47. }
  48.  
  49. static function scheme( $url ) {
  50. //And this here is a prime example of why absolute urls in Wordpress create extra overhead and processing.
  51. //And in the core, they use four different approaches to acheive this translation!
  52. //For reference, see: http://core.trac.wordpress.org/ticket/19037
  53. if (is_ssl()) {
  54. $url = str_replace('http://', 'https://', $url);
  55. }
  56. else {
  57. $url = str_replace('https://', 'http://', $url);
  58. }
  59. return $url;
  60. }
  61.  
  62. static function dynamic_absolute_url($url) {
  63. //These URL's cannot be reformmated into root-relative urls for various reasons. Either they are indescriminantly
  64. //used in export functions or RSS feeds. Or because they are literally checked against the domain of URLs stored
  65. //in the database - a needless process for any website.
  66. $url = @parse_url($url);
  67.  
  68. if (!isset($url['path'])) $url['path'] = '';
  69.  
  70. $relative = ltrim(@$url['path'], '/') . (isset($url['query']) ? "?" . $url['query'] : '');
  71.  
  72. return MP_WP_Root_Relative_URLS::scheme(
  73. 'http://' . @$_SERVER['HTTP_HOST'] .
  74. (!empty($relative) ? '/' . $relative : '') .
  75. (isset($url['fragment']) ? '#' . $url['fragment'] : '')
  76. );
  77. }
  78.  
  79. static function dynamic_rss_absolute_url($info, $type = 'url') {
  80. //Generates dynamic absolute URI's for RSS Feeds
  81. //get_bloginfo_rss returns multiple types of info, the_permalink_rss only returns a url.
  82. //so when type is not passed in, consider it a url, otherwise only parse when type == url
  83. if ($type == 'url') {
  84. return MP_WP_Root_Relative_URLS::dynamic_absolute_url($info);
  85. }
  86. return $info;
  87. }
  88.  
  89. static function enable_content_massage() {
  90. //this is only called when an external feed is being called
  91. //this lets the content filter know that we should convert root relative urls back in to absolute urls since
  92. //some external sources don't understand the html spec
  93. self::$massage = true;
  94.  
  95. //massage global post object
  96. global $post;
  97. $post->post_content = self::massage_external_content($post->post_content);
  98. $post->post_excerpt= self::massage_external_content($post->post_excerpt);
  99. }
  100.  
  101. static function massage_external_content($a) {
  102. //Here is where we fix the root relative content urls into absolute urls using the current host name
  103. //this shouldn't be required but companies like feedburner and feedblitz don't understand the web :(
  104. if (self::$massage == true) {
  105. $a = preg_replace_callback('#(<[^>]+(?:href|src)\s*?=\s*?[\'"])(\/)#i', array("MP_WP_Root_Relative_URLS", "do_absolute_massage_cb"), $a);
  106. }
  107. return $a;
  108. }
  109.  
  110. static function do_absolute_massage_cb($a) {
  111. //callback handler that does the physical insertion of absolute domain into root relative urls
  112. return $a[1] . self::scheme('http://' . @$_SERVER['HTTP_HOST'] . $a[2]);
  113. }
  114.  
  115. static function proper_root_relative_url($url) {
  116. //This method is used for urls that can be acceptably reformatted into root-relative urls without causing issues
  117. //related to other deficiencies in the wp core.
  118.  
  119. if (self::$massage) {
  120. //massage back to absolute because we're rendering a feed and the platform mixes url procurment methods between the delivery methods
  121. //despite offering _rss specific filters
  122. return MP_WP_Root_Relative_URLS::dynamic_absolute_url($url);
  123. } else {
  124. $url = @parse_url($url);
  125.  
  126. if (!isset($url['path'])) $url['path'] = '';
  127.  
  128. return '/' . ltrim(@$url['path'], '/') .
  129. (isset($url['query']) ? "?" . $url['query'] : '') .
  130. (isset($url['fragment']) ? '#' . $url['fragment'] : '');
  131. }
  132. }
  133.  
  134. static function proper_multisite_path_comparison($redirect_bool) {
  135. //Prevents infinite loop caused by the path matching but not the domain when making network admin requests
  136. global $current_blog, $current_site;
  137.  
  138. //don't worry about domain name mismatch as long as the paths are correct
  139. if ($redirect_bool &&
  140. $current_blog->path == $current_site->path) {
  141. $redirect_bool = false;
  142. }
  143.  
  144. return $redirect_bool;
  145. }
  146.  
  147. static function root_relative_url($url, $html) {
  148.  
  149. //If urls already start from root, just return it
  150. if ($url[0] == "/") return $html;
  151.  
  152. $p = parse_url($url);
  153. $root = $p['scheme'] . "://" . $p['host'];
  154. $html = str_ireplace($root, '', $html);
  155. return $html;
  156. }
  157.  
  158. static function root_relative_image_urls($html, $id, $caption, $title, $align, $url, $size, $alt) {
  159. //Same as media_send_to_editor but images are handled separately
  160. return MP_WP_Root_Relative_URLS::root_relative_url($url, $html);
  161. }
  162.  
  163. static function root_relative_media_urls($html, $id, $att) {
  164. //Filter out host from embed urls
  165. return MP_WP_Root_Relative_URLS::root_relative_url($att['url'], $html);
  166. }
  167.  
  168. static function fix_canonical_redirect($redirect, $requested) {
  169. //Fixes infinite redirect loop caused by WP Core bug: http://core.trac.wordpress.org/ticket/21824
  170. if (MP_WP_Root_Relative_URLS::proper_root_relative_url($redirect) ==
  171. MP_WP_Root_Relative_URLS::proper_root_relative_url($requested)) {
  172. return false;
  173. }
  174. }
  175.  
  176. static function fix_upload_paths($o) {
  177. //Fixes attachment urls when user has customized the base url and/or upload folder in Admin > Settings > Media : Uploading Files
  178. $o['url'] = MP_WP_Root_Relative_URLS::proper_root_relative_url($o['url']);
  179. $o['baseurl'] = MP_WP_Root_Relative_URLS::proper_root_relative_url($o['baseurl']);
  180. return $o;
  181. }
  182.  
  183. static function init() {
  184.  
  185. add_action('admin_init', array( 'MP_WP_Root_Relative_URLS', 'admin_settings_init' ));
  186.  
  187. //Here we check the url blacklist to disable proper root relative urls, this helps with certain 3rd party
  188. //plugins / certain clients for rss feeds
  189. $cur_url = MP_WP_Root_Relative_URLS::dynamic_absolute_url(@$_SERVER['REQUEST_URI']);
  190. if (stripos(get_option('emc2_blacklist_urls'), $cur_url) !== false) {
  191. //for blacklists, create a dynamic but full absolute url instead
  192. self::$massage = true;
  193. }
  194.  
  195. //Setup all hooks / filters for either dynamically replacing the host part of a URL with the current host
  196. //or for stripping the scheme + host + port altogether
  197. MP_WP_Root_Relative_URLS::add_actions(
  198. array(
  199. 'option_siteurl',
  200. 'blog_option_siteurl',
  201. 'option_home',
  202. 'admin_url',
  203. 'home_url',
  204. 'includes_url',
  205. 'site_url',
  206. 'plugins_url',
  207. 'content_url',
  208. 'site_option_siteurl',
  209. 'network_home_url',
  210. 'network_site_url'
  211. ),
  212. array(
  213. 'MP_WP_Root_Relative_URLS',
  214. 'dynamic_absolute_url'
  215. ),
  216. 1
  217. );
  218.  
  219. MP_WP_Root_Relative_URLS::add_actions(
  220. array(
  221. 'post_link',
  222. 'page_link',
  223. 'attachment_link',
  224. 'post_type_link',
  225. 'wp_get_attachment_url'
  226. ),
  227. array(
  228. 'MP_WP_Root_Relative_URLS',
  229. 'proper_root_relative_url'
  230. ),
  231. 1
  232. );
  233.  
  234. MP_WP_Root_Relative_URLS::add_actions(
  235. array(
  236. 'get_bloginfo_rss',
  237. 'the_permalink_rss',
  238. 'get_post_comments_feed_link',
  239. 'get_the_author_url',
  240. 'get_comment_link'
  241. ),
  242. array(
  243. 'MP_WP_Root_Relative_URLS',
  244. 'dynamic_rss_absolute_url'
  245. ),
  246. 1, //high priority
  247. 2 //supply second parameter for type checking
  248. );
  249.  
  250. //Used to indicate that an atom feed is being generated so it's ok to massage the content urls for absolute format
  251. MP_WP_Root_Relative_URLS::add_actions(
  252. array(
  253. 'atom_ns',
  254. 'attom_comments_ns',
  255. 'rss2_ns',
  256. 'rss2_comments_ns',
  257. 'rdf_ns',
  258. 'wp_mail'
  259. ),
  260. array(
  261. 'MP_WP_Root_Relative_URLS',
  262. 'enable_content_massage'
  263. )
  264. );
  265.  
  266. MP_WP_Root_Relative_URLS::add_actions(
  267. array(
  268. 'the_excerpt_rss',
  269. 'the_content_feed',
  270. ),
  271. array(
  272. 'MP_WP_Root_Relative_URLS',
  273. 'massage_external_content'
  274. )
  275. );
  276.  
  277. //HACK: This plugin actually won't work for MU Sites until either of the following conditions are true:
  278. //1. Wordpress core team publishes this patch - http://core.trac.wordpress.org/attachment/ticket/18910/ms-blogs.php.patch
  279. //2. You deal with the consequences of patching a core file yourself using the above patch reference
  280. //Regardless of the above, this plugin only supports path-based MU installations - at this point domain-based MU installations are not supported
  281. add_filter(
  282. 'redirect_network_admin_request',
  283. array(
  284. 'MP_WP_Root_Relative_URLS',
  285. 'proper_multisite_path_comparison'
  286. )
  287. );
  288.  
  289. add_filter(
  290. 'image_send_to_editor',
  291. array(
  292. 'MP_WP_Root_Relative_URLS',
  293. 'root_relative_image_urls'
  294. ),
  295. 1, //high priority
  296. 8 //eight params? wow
  297. );
  298.  
  299. add_filter(
  300. 'media_send_to_editor',
  301. array(
  302. 'MP_WP_Root_Relative_URLS',
  303. 'root_relative_media_urls'
  304. ),
  305. 1,
  306. 3
  307. );
  308.  
  309. add_filter(
  310. 'redirect_canonical',
  311. array(
  312. 'MP_WP_Root_Relative_URLS',
  313. 'fix_canonical_redirect'
  314. ),
  315. 10,
  316. 2
  317. );
  318.  
  319. add_filter(
  320. 'upload_dir',
  321. array(
  322. 'MP_WP_Root_Relative_URLS',
  323. 'fix_upload_paths'
  324. ),
  325. 1,
  326. 1
  327. );
  328.  
  329. # fix links to javascript loaded with wp_enqueue_script where the files are located in wp-include (e.g. wp_enqueue_script( 'comment-reply' );
  330. # @credit: @tfmtfm
  331. add_filter(
  332. 'script_loader_src',
  333. array(
  334. 'MP_WP_Root_Relative_URLS',
  335. 'proper_root_relative_url'
  336. )
  337. );
  338.  
  339. # support links generated by the WPML plugin (i.e. for the multi-lingual support)
  340. add_filter(
  341. 'WPML_filter_link',
  342. array(
  343. 'MP_WP_Root_Relative_URLS',
  344. 'proper_root_relative_url'
  345. )
  346. );
  347. }
  348.  
  349. //The following sets up an admin config page
  350. static function admin_settings_init() {
  351.  
  352. //give this setting its own section on the General page
  353. add_settings_section('emc2_blacklist_urls', 'Root Relative Blacklist', array('MP_WP_Root_Relative_URLS', 'render_setting_section'), 'general');
  354.  
  355. add_settings_field('emc2_blacklist_urls', 'Root Relative Blacklist URLs',
  356. array('MP_WP_Root_Relative_URLS', 'render_setting_input'), //render callback
  357. 'general', //page
  358. 'emc2_blacklist_urls', //section
  359. array(
  360. 'label_for' => 'emc2_blacklist_urls'
  361. )
  362. );
  363.  
  364. register_setting('general', 'emc2_blacklist_urls');
  365. }
  366.  
  367. static function render_setting_section($t) {
  368. //add description of section to page
  369. echo "<p>Enter URLs you do not want processed to root relative by the Root Relative URL Plugin. This is particularly useful for fixing 3rd party plugins that depend on absolute URLs.<br/>- Only put one URL per line, you can enter as many urls as you'd like.<br/>- You can use partial URLs, no wildcards needed, but be careful about unintentionally matching a post title.<br/>- The full URL in the browser will be used to check against these entries so you can disable root relative urls for your entire production site simply by putting your production url in this field.<br/>- To disable processing for RSS feeds you would use <span style='background-color: #e8f6fd;'>http://www.mysite.com/?feed</span> to capture all rss, atomic and comment feeds, only you'd replace www.mysite.com with your production URL.</p>";
  370. }
  371.  
  372. static function render_setting_input($attr) {
  373. //Display a list of option boxes for specifying the new line insertion behavior
  374. $options = get_option('emc2_blacklist_urls');
  375. ?>
  376. <textarea id="emc2_blacklist_urls" name="emc2_blacklist_urls" style="width: 70%; min-width: 25em;" rows="20"><?php echo esc_attr($options); ?></textarea>
  377. <?php
  378. }
  379.  
  380. }
Advertisement
Add Comment
Please, Sign In to add comment