Fishpig_Wordpress_Integration - Version 4.2.1.9

Version Notes

For changes, please see http://fishpig.co.uk/magento/wordpress-integration/#changelog

Download this release

Release Info

Developer fishpig
Extension Fishpig_Wordpress_Integration
Version 4.2.1.9
Comparing to
See all releases


Code changes from version 4.2.1.8 to 4.2.1.9

app/code/community/Fishpig/Wordpress/Addon/WordPressSEO/Helper/Data.php CHANGED
@@ -298,6 +298,10 @@ class Fishpig_Wordpress_Addon_WordPressSEO_Helper_Data extends Fishpig_Wordpress
298
  $meta->setRobots(implode(',', $robots));
299
  }
300
 
 
 
 
 
301
  $this->_applyMeta($meta->getData());
302
 
303
  if ($canon = $object->getMetaValue('_yoast_wpseo_canonical')) {
298
  $meta->setRobots(implode(',', $robots));
299
  }
300
 
301
+ if (!$meta->getDescription()) {
302
+ $meta->setDescription($object->getMetaDescription());
303
+ }
304
+
305
  $this->_applyMeta($meta->getData());
306
 
307
  if ($canon = $object->getMetaValue('_yoast_wpseo_canonical')) {
app/code/community/Fishpig/Wordpress/Helper/Plugin/Seo/Abstract.php CHANGED
@@ -108,10 +108,12 @@ abstract class Fishpig_Wordpress_Helper_Plugin_Seo_Abstract extends Fishpig_Word
108
  }
109
 
110
  if (($value = $this->_rewriteString($value)) !== false) {
111
- $headBlock->setData($key, $value);
 
112
 
113
- if ($key === 'title') {
114
- $this->_action->ignoreAutomaticTitles();
 
115
  }
116
  }
117
  }
108
  }
109
 
110
  if (($value = $this->_rewriteString($value)) !== false) {
111
+ if ($value) {
112
+ $headBlock->setData($key, $value);
113
 
114
+ if ($key === 'title') {
115
+ $this->_action->ignoreAutomaticTitles();
116
+ }
117
  }
118
  }
119
  }
app/code/community/Fishpig/Wordpress/Model/Post.php CHANGED
@@ -704,6 +704,6 @@ class Fishpig_Wordpress_Model_Post extends Fishpig_Wordpress_Model_Abstract
704
 
705
  public function getMetaDescription($maxWords = 30)
706
  {
707
- return $this->getPostExcerpt($maxWords);
708
  }
709
  }
704
 
705
  public function getMetaDescription($maxWords = 30)
706
  {
707
+ return strip_tags($this->getPostExcerpt($maxWords));
708
  }
709
  }
app/code/community/Fishpig/Wordpress/change-log.txt CHANGED
@@ -5,6 +5,9 @@
5
  * @author Ben Tideswell <ben@fishpig.co.uk>
6
  */
7
 
 
 
 
8
  17/02/2017 - 4.2.1.8
9
  - Fixed issue with Yoast SEO and og:description tag
10
 
5
  * @author Ben Tideswell <ben@fishpig.co.uk>
6
  */
7
 
8
+ 08/03/2017 - 4.2.1.9
9
+ - Added missing file. This fixes issue with wpautop not functioning correctly.
10
+
11
  17/02/2017 - 4.2.1.8
12
  - Fixed issue with Yoast SEO and og:description tag
13
 
app/code/community/Fishpig/Wordpress/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Fishpig_Wordpress>
5
- <version>4.2.1.8</version>
6
  </Fishpig_Wordpress>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <Fishpig_Wordpress>
5
+ <version>4.2.1.9</version>
6
  </Fishpig_Wordpress>
7
  </modules>
8
  <global>
app/code/community/Fishpig/Wordpress/etc/fishpig.xml CHANGED
@@ -1,2 +1,2 @@
1
  <?xml version="1.0"?>
2
- <config><fishpig><extensions><Fishpig_Wordpress_Addon_ACF><new_version>1.4.0.12</new_version><name>Advanced Custom Fields</name><id>advanced-custom-field</id><url>https://fishpig.co.uk/magento/wordpress-integration/advanced-custom-fields/</url></Fishpig_Wordpress_Addon_ACF><Fishpig_Wordpress_Addon_CPT><new_version>2.1.1.2</new_version><id>posttypes-taxonomies</id><name>Post Types and Taxonomies</name><url>http://fishpig.co.uk/magento/wordpress-integration/post-types-taxonomies/</url></Fishpig_Wordpress_Addon_CPT><Fishpig_Wordpress_Addon_CS><new_version>1.3.4.0</new_version><id>customer-synch</id><name>Customer Synchronisation</name><url>http://fishpig.co.uk/magento/wordpress-integration/customer-synchronisation/</url></Fishpig_Wordpress_Addon_CS><Fishpig_Wordpress_Addon_ContactForm7><new_version>1.6.0.18</new_version><id>contact-form-7</id><name>Contact Form 7</name><url>https://fishpig.co.uk/magento/wordpress-integration/contact-form-7/</url></Fishpig_Wordpress_Addon_ContactForm7><Fishpig_Wordpress_Addon_Disqus><new_version>1.3.0.1</new_version><id>disqus</id><name>Disqus</name><url>http://fishpig.co.uk/magento/wordpress-integration/disqus/</url></Fishpig_Wordpress_Addon_Disqus><Fishpig_Wordpress_Addon_EventsCalendar><new_version>1.1.0.21</new_version><id>events-calendar</id><name>The Events Calendar</name><url>http://fishpig.co.uk/magento/wordpress-integration/events-calendar/</url></Fishpig_Wordpress_Addon_EventsCalendar><Fishpig_Wordpress_Addon_FormAssembly><new_version>1.0.0.0</new_version><id>form-assembly</id><name>Form Assembly</name><url>http://fishpig.co.uk/magento/wordpress-integration/</url></Fishpig_Wordpress_Addon_FormAssembly><Fishpig_Wordpress_Addon_GravityForms><new_version>1.1.0.19</new_version><id>gravity-forms</id><name>Gravity Forms</name><url>http://fishpig.co.uk/magento/wordpress-integration/gravity-forms/</url></Fishpig_Wordpress_Addon_GravityForms><Fishpig_Wordpress_Addon_IntegratedSearch><new_version>1.3.0.0</new_version><name>Integrated Search</name><url>http://fishpig.co.uk/magento/wordpress-integration/integrated-search/</url></Fishpig_Wordpress_Addon_IntegratedSearch><Fishpig_Wordpress_Addon_Multisite><new_version>2.1.1.2</new_version><name>Multisite Integration</name><url>http://fishpig.co.uk/magento/wordpress-integration/multisite/</url></Fishpig_Wordpress_Addon_Multisite><Fishpig_Wordpress_Addon_ReCaptcha><new_version>1.3.0.1</new_version><name>ReCaptcha</name><url>http://fishpig.co.uk/magento/wordpress-integration/recaptcha/</url></Fishpig_Wordpress_Addon_ReCaptcha><Fishpig_Wordpress_Addon_RevolutionSlider><new_version>1.1.0.18</new_version><id>revolutionslider</id><name>Revolution Slider</name><url>http://fishpig.co.uk/magento/wordpress-integration/revolution-slider/</url></Fishpig_Wordpress_Addon_RevolutionSlider><Fishpig_Wordpress_Addon_Root><new_version>1.1.0.10</new_version><name>Root</name><url>http://fishpig.co.uk/magento/wordpress-integration/root/</url></Fishpig_Wordpress_Addon_Root><Fishpig_Wordpress_Addon_TOC><new_version>1.0.0.3</new_version><id>toc</id><name>Table of Contents Plus</name><url>http://fishpig.co.uk/magento/wordpress-integration/</url></Fishpig_Wordpress_Addon_TOC><Fishpig_Wordpress_Addon_Tablepress><new_version>1.1.0.17</new_version><name>Tablepress</name><id>tablepress</id><url>http://fishpig.co.uk/magento/wordpress-integration/tablepress/</url></Fishpig_Wordpress_Addon_Tablepress><Fishpig_Wordpress_Addon_UCE><new_version>1.4.0.0</new_version><id>ultimate-category-excluder</id><name>Ultimate Category Excluder</name><url>http://fishpig.co.uk/magento-wordpress-ultimate-category-excluder.html</url></Fishpig_Wordpress_Addon_UCE><Fishpig_Wordpress_Addon_VisualComposer><new_version>1.1.0.20</new_version><id>visual-composer</id><name>Visual Composer</name><url>https://fishpig.co.uk/magento/wordpress-integration/visual-composer/</url></Fishpig_Wordpress_Addon_VisualComposer><Fishpig_Wordpress_Addon_WPSubscribe><new_version>1.0.0.4</new_version><id>wp-subscribe</id><name>WP Subscribe</name><url>http://fishpig.co.uk/magento/wordpress-integration/wp-subscribe/</url></Fishpig_Wordpress_Addon_WPSubscribe></extensions></fishpig></config>
1
  <?xml version="1.0"?>
2
+ <config><fishpig><extensions><Fishpig_Wordpress_Addon_ACF><new_version>1.4.0.12</new_version><name>Advanced Custom Fields</name><id>advanced-custom-field</id><url>https://fishpig.co.uk/magento/wordpress-integration/advanced-custom-fields/</url></Fishpig_Wordpress_Addon_ACF><Fishpig_Wordpress_Addon_CPT><new_version>2.1.1.3</new_version><id>posttypes-taxonomies</id><name>Post Types and Taxonomies</name><url>http://fishpig.co.uk/magento/wordpress-integration/post-types-taxonomies/</url></Fishpig_Wordpress_Addon_CPT><Fishpig_Wordpress_Addon_CS><new_version>1.3.4.0</new_version><id>customer-synch</id><name>Customer Synchronisation</name><url>http://fishpig.co.uk/magento/wordpress-integration/customer-synchronisation/</url></Fishpig_Wordpress_Addon_CS><Fishpig_Wordpress_Addon_ContactForm7><new_version>1.6.0.18</new_version><id>contact-form-7</id><name>Contact Form 7</name><url>https://fishpig.co.uk/magento/wordpress-integration/contact-form-7/</url></Fishpig_Wordpress_Addon_ContactForm7><Fishpig_Wordpress_Addon_Disqus><new_version>1.3.0.1</new_version><id>disqus</id><name>Disqus</name><url>http://fishpig.co.uk/magento/wordpress-integration/disqus/</url></Fishpig_Wordpress_Addon_Disqus><Fishpig_Wordpress_Addon_EventsCalendar><new_version>1.1.0.21</new_version><id>events-calendar</id><name>The Events Calendar</name><url>http://fishpig.co.uk/magento/wordpress-integration/events-calendar/</url></Fishpig_Wordpress_Addon_EventsCalendar><Fishpig_Wordpress_Addon_FormAssembly><new_version>1.0.0.0</new_version><id>form-assembly</id><name>Form Assembly</name><url>http://fishpig.co.uk/magento/wordpress-integration/</url></Fishpig_Wordpress_Addon_FormAssembly><Fishpig_Wordpress_Addon_GravityForms><new_version>1.1.0.19</new_version><id>gravity-forms</id><name>Gravity Forms</name><url>http://fishpig.co.uk/magento/wordpress-integration/gravity-forms/</url></Fishpig_Wordpress_Addon_GravityForms><Fishpig_Wordpress_Addon_IntegratedSearch><new_version>1.3.0.1</new_version><name>Integrated Search</name><url>http://fishpig.co.uk/magento/wordpress-integration/integrated-search/</url></Fishpig_Wordpress_Addon_IntegratedSearch><Fishpig_Wordpress_Addon_Multisite><new_version>2.1.1.2</new_version><name>Multisite Integration</name><url>http://fishpig.co.uk/magento/wordpress-integration/multisite/</url></Fishpig_Wordpress_Addon_Multisite><Fishpig_Wordpress_Addon_ReCaptcha><new_version>1.3.0.1</new_version><name>ReCaptcha</name><url>http://fishpig.co.uk/magento/wordpress-integration/recaptcha/</url></Fishpig_Wordpress_Addon_ReCaptcha><Fishpig_Wordpress_Addon_RevolutionSlider><new_version>1.1.0.18</new_version><id>revolutionslider</id><name>Revolution Slider</name><url>http://fishpig.co.uk/magento/wordpress-integration/revolution-slider/</url></Fishpig_Wordpress_Addon_RevolutionSlider><Fishpig_Wordpress_Addon_Root><new_version>1.1.0.10</new_version><name>Root</name><url>http://fishpig.co.uk/magento/wordpress-integration/root/</url></Fishpig_Wordpress_Addon_Root><Fishpig_Wordpress_Addon_TOC><new_version>1.0.0.3</new_version><id>toc</id><name>Table of Contents Plus</name><url>http://fishpig.co.uk/magento/wordpress-integration/</url></Fishpig_Wordpress_Addon_TOC><Fishpig_Wordpress_Addon_Tablepress><new_version>1.1.0.17</new_version><name>Tablepress</name><id>tablepress</id><url>http://fishpig.co.uk/magento/wordpress-integration/tablepress/</url></Fishpig_Wordpress_Addon_Tablepress><Fishpig_Wordpress_Addon_UCE><new_version>1.4.0.0</new_version><id>ultimate-category-excluder</id><name>Ultimate Category Excluder</name><url>http://fishpig.co.uk/magento-wordpress-ultimate-category-excluder.html</url></Fishpig_Wordpress_Addon_UCE><Fishpig_Wordpress_Addon_VisualComposer><new_version>1.1.0.20</new_version><id>visual-composer</id><name>Visual Composer</name><url>https://fishpig.co.uk/magento/wordpress-integration/visual-composer/</url></Fishpig_Wordpress_Addon_VisualComposer><Fishpig_Wordpress_Addon_WPSubscribe><new_version>1.0.0.4</new_version><id>wp-subscribe</id><name>WP Subscribe</name><url>http://fishpig.co.uk/magento/wordpress-integration/wp-subscribe/</url></Fishpig_Wordpress_Addon_WPSubscribe></extensions></fishpig></config>
app/code/community/Fishpig/Wordpress/lib/wp/formatting.php ADDED
@@ -0,0 +1,5358 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main WordPress Formatting API.
4
+ *
5
+ * Handles many functions for formatting output.
6
+ *
7
+ * @package WordPress
8
+ */
9
+
10
+ /**
11
+ * Replaces common plain text characters into formatted entities
12
+ *
13
+ * As an example,
14
+ *
15
+ * 'cause today's effort makes it worth tomorrow's "holiday" ...
16
+ *
17
+ * Becomes:
18
+ *
19
+ * &#8217;cause today&#8217;s effort makes it worth tomorrow&#8217;s &#8220;holiday&#8221; &#8230;
20
+ *
21
+ * Code within certain html blocks are skipped.
22
+ *
23
+ * Do not use this function before the {@see 'init'} action hook; everything will break.
24
+ *
25
+ * @since 0.71
26
+ *
27
+ * @global array $wp_cockneyreplace Array of formatted entities for certain common phrases
28
+ * @global array $shortcode_tags
29
+ * @staticvar array $static_characters
30
+ * @staticvar array $static_replacements
31
+ * @staticvar array $dynamic_characters
32
+ * @staticvar array $dynamic_replacements
33
+ * @staticvar array $default_no_texturize_tags
34
+ * @staticvar array $default_no_texturize_shortcodes
35
+ * @staticvar bool $run_texturize
36
+ *
37
+ * @param string $text The text to be formatted
38
+ * @param bool $reset Set to true for unit testing. Translated patterns will reset.
39
+ * @return string The string replaced with html entities
40
+ */
41
+ function wptexturize( $text, $reset = false ) {
42
+ global $wp_cockneyreplace, $shortcode_tags;
43
+ static $static_characters = null,
44
+ $static_replacements = null,
45
+ $dynamic_characters = null,
46
+ $dynamic_replacements = null,
47
+ $default_no_texturize_tags = null,
48
+ $default_no_texturize_shortcodes = null,
49
+ $run_texturize = true,
50
+ $apos = null,
51
+ $prime = null,
52
+ $double_prime = null,
53
+ $opening_quote = null,
54
+ $closing_quote = null,
55
+ $opening_single_quote = null,
56
+ $closing_single_quote = null,
57
+ $open_q_flag = '<!--oq-->',
58
+ $open_sq_flag = '<!--osq-->',
59
+ $apos_flag = '<!--apos-->';
60
+
61
+ // If there's nothing to do, just stop.
62
+ if ( empty( $text ) || false === $run_texturize ) {
63
+ return $text;
64
+ }
65
+
66
+ // Set up static variables. Run once only.
67
+ if ( $reset || ! isset( $static_characters ) ) {
68
+ /**
69
+ * Filters whether to skip running wptexturize().
70
+ *
71
+ * Passing false to the filter will effectively short-circuit wptexturize().
72
+ * returning the original text passed to the function instead.
73
+ *
74
+ * The filter runs only once, the first time wptexturize() is called.
75
+ *
76
+ * @since 4.0.0
77
+ *
78
+ * @see wptexturize()
79
+ *
80
+ * @param bool $run_texturize Whether to short-circuit wptexturize().
81
+ */
82
+ $run_texturize = apply_filters( 'run_wptexturize', $run_texturize );
83
+ if ( false === $run_texturize ) {
84
+ return $text;
85
+ }
86
+
87
+ /* translators: opening curly double quote */
88
+ $opening_quote = _x( '&#8220;', 'opening curly double quote' );
89
+ /* translators: closing curly double quote */
90
+ $closing_quote = _x( '&#8221;', 'closing curly double quote' );
91
+
92
+ /* translators: apostrophe, for example in 'cause or can't */
93
+ $apos = _x( '&#8217;', 'apostrophe' );
94
+
95
+ /* translators: prime, for example in 9' (nine feet) */
96
+ $prime = _x( '&#8242;', 'prime' );
97
+ /* translators: double prime, for example in 9" (nine inches) */
98
+ $double_prime = _x( '&#8243;', 'double prime' );
99
+
100
+ /* translators: opening curly single quote */
101
+ $opening_single_quote = _x( '&#8216;', 'opening curly single quote' );
102
+ /* translators: closing curly single quote */
103
+ $closing_single_quote = _x( '&#8217;', 'closing curly single quote' );
104
+
105
+ /* translators: en dash */
106
+ $en_dash = _x( '&#8211;', 'en dash' );
107
+ /* translators: em dash */
108
+ $em_dash = _x( '&#8212;', 'em dash' );
109
+
110
+ $default_no_texturize_tags = array('pre', 'code', 'kbd', 'style', 'script', 'tt');
111
+ $default_no_texturize_shortcodes = array('code');
112
+
113
+ // if a plugin has provided an autocorrect array, use it
114
+ if ( isset($wp_cockneyreplace) ) {
115
+ $cockney = array_keys( $wp_cockneyreplace );
116
+ $cockneyreplace = array_values( $wp_cockneyreplace );
117
+ } else {
118
+ /* translators: This is a comma-separated list of words that defy the syntax of quotations in normal use,
119
+ * for example... 'We do not have enough words yet' ... is a typical quoted phrase. But when we write
120
+ * lines of code 'til we have enough of 'em, then we need to insert apostrophes instead of quotes.
121
+ */
122
+ $cockney = explode( ',', _x( "'tain't,'twere,'twas,'tis,'twill,'til,'bout,'nuff,'round,'cause,'em",
123
+ 'Comma-separated list of words to texturize in your language' ) );
124
+
125
+ $cockneyreplace = explode( ',', _x( '&#8217;tain&#8217;t,&#8217;twere,&#8217;twas,&#8217;tis,&#8217;twill,&#8217;til,&#8217;bout,&#8217;nuff,&#8217;round,&#8217;cause,&#8217;em',
126
+ 'Comma-separated list of replacement words in your language' ) );
127
+ }
128
+
129
+ $static_characters = array_merge( array( '...', '``', '\'\'', ' (tm)' ), $cockney );
130
+ $static_replacements = array_merge( array( '&#8230;', $opening_quote, $closing_quote, ' &#8482;' ), $cockneyreplace );
131
+
132
+
133
+ // Pattern-based replacements of characters.
134
+ // Sort the remaining patterns into several arrays for performance tuning.
135
+ $dynamic_characters = array( 'apos' => array(), 'quote' => array(), 'dash' => array() );
136
+ $dynamic_replacements = array( 'apos' => array(), 'quote' => array(), 'dash' => array() );
137
+ $dynamic = array();
138
+ $spaces = wp_spaces_regexp();
139
+
140
+ // '99' and '99" are ambiguous among other patterns; assume it's an abbreviated year at the end of a quotation.
141
+ if ( "'" !== $apos || "'" !== $closing_single_quote ) {
142
+ $dynamic[ '/\'(\d\d)\'(?=\Z|[.,:;!?)}\-\]]|&gt;|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_single_quote;
143
+ }
144
+ if ( "'" !== $apos || '"' !== $closing_quote ) {
145
+ $dynamic[ '/\'(\d\d)"(?=\Z|[.,:;!?)}\-\]]|&gt;|' . $spaces . ')/' ] = $apos_flag . '$1' . $closing_quote;
146
+ }
147
+
148
+ // '99 '99s '99's (apostrophe) But never '9 or '99% or '999 or '99.0.
149
+ if ( "'" !== $apos ) {
150
+ $dynamic[ '/\'(?=\d\d(?:\Z|(?![%\d]|[.,]\d)))/' ] = $apos_flag;
151
+ }
152
+
153
+ // Quoted Numbers like '0.42'
154
+ if ( "'" !== $opening_single_quote && "'" !== $closing_single_quote ) {
155
+ $dynamic[ '/(?<=\A|' . $spaces . ')\'(\d[.,\d]*)\'/' ] = $open_sq_flag . '$1' . $closing_single_quote;
156
+ }
157
+
158
+ // Single quote at start, or preceded by (, {, <, [, ", -, or spaces.
159
+ if ( "'" !== $opening_single_quote ) {
160
+ $dynamic[ '/(?<=\A|[([{"\-]|&lt;|' . $spaces . ')\'/' ] = $open_sq_flag;
161
+ }
162
+
163
+ // Apostrophe in a word. No spaces, double apostrophes, or other punctuation.
164
+ if ( "'" !== $apos ) {
165
+ $dynamic[ '/(?<!' . $spaces . ')\'(?!\Z|[.,:;!?"\'(){}[\]\-]|&[lg]t;|' . $spaces . ')/' ] = $apos_flag;
166
+ }
167
+
168
+ $dynamic_characters['apos'] = array_keys( $dynamic );
169
+ $dynamic_replacements['apos'] = array_values( $dynamic );
170
+ $dynamic = array();
171
+
172
+ // Quoted Numbers like "42"
173
+ if ( '"' !== $opening_quote && '"' !== $closing_quote ) {
174
+ $dynamic[ '/(?<=\A|' . $spaces . ')"(\d[.,\d]*)"/' ] = $open_q_flag . '$1' . $closing_quote;
175
+ }
176
+
177
+ // Double quote at start, or preceded by (, {, <, [, -, or spaces, and not followed by spaces.
178
+ if ( '"' !== $opening_quote ) {
179
+ $dynamic[ '/(?<=\A|[([{\-]|&lt;|' . $spaces . ')"(?!' . $spaces . ')/' ] = $open_q_flag;
180
+ }
181
+
182
+ $dynamic_characters['quote'] = array_keys( $dynamic );
183
+ $dynamic_replacements['quote'] = array_values( $dynamic );
184
+ $dynamic = array();
185
+
186
+ // Dashes and spaces
187
+ $dynamic[ '/---/' ] = $em_dash;
188
+ $dynamic[ '/(?<=^|' . $spaces . ')--(?=$|' . $spaces . ')/' ] = $em_dash;
189
+ $dynamic[ '/(?<!xn)--/' ] = $en_dash;
190
+ $dynamic[ '/(?<=^|' . $spaces . ')-(?=$|' . $spaces . ')/' ] = $en_dash;
191
+
192
+ $dynamic_characters['dash'] = array_keys( $dynamic );
193
+ $dynamic_replacements['dash'] = array_values( $dynamic );
194
+ }
195
+
196
+ // Must do this every time in case plugins use these filters in a context sensitive manner
197
+ /**
198
+ * Filters the list of HTML elements not to texturize.
199
+ *
200
+ * @since 2.8.0
201
+ *
202
+ * @param array $default_no_texturize_tags An array of HTML element names.
203
+ */
204
+ $no_texturize_tags = apply_filters( 'no_texturize_tags', $default_no_texturize_tags );
205
+ /**
206
+ * Filters the list of shortcodes not to texturize.
207
+ *
208
+ * @since 2.8.0
209
+ *
210
+ * @param array $default_no_texturize_shortcodes An array of shortcode names.
211
+ */
212
+ $no_texturize_shortcodes = apply_filters( 'no_texturize_shortcodes', $default_no_texturize_shortcodes );
213
+
214
+ $no_texturize_tags_stack = array();
215
+ $no_texturize_shortcodes_stack = array();
216
+
217
+ // Look for shortcodes and HTML elements.
218
+
219
+ preg_match_all( '@\[/?([^<>&/\[\]\x00-\x20=]++)@', $text, $matches );
220
+ $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
221
+ $found_shortcodes = ! empty( $tagnames );
222
+ $shortcode_regex = $found_shortcodes ? _get_wptexturize_shortcode_regex( $tagnames ) : '';
223
+ $regex = _get_wptexturize_split_regex( $shortcode_regex );
224
+
225
+ $textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
226
+
227
+ foreach ( $textarr as &$curl ) {
228
+ // Only call _wptexturize_pushpop_element if $curl is a delimiter.
229
+ $first = $curl[0];
230
+ if ( '<' === $first ) {
231
+ if ( '<!--' === substr( $curl, 0, 4 ) ) {
232
+ // This is an HTML comment delimiter.
233
+ continue;
234
+ } else {
235
+ // This is an HTML element delimiter.
236
+
237
+ // Replace each & with &#038; unless it already looks like an entity.
238
+ $curl = preg_replace( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i', '&#038;', $curl );
239
+
240
+ _wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
241
+ }
242
+
243
+ } elseif ( '' === trim( $curl ) ) {
244
+ // This is a newline between delimiters. Performance improves when we check this.
245
+ continue;
246
+
247
+ } elseif ( '[' === $first && $found_shortcodes && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) {
248
+ // This is a shortcode delimiter.
249
+
250
+ if ( '[[' !== substr( $curl, 0, 2 ) && ']]' !== substr( $curl, -2 ) ) {
251
+ // Looks like a normal shortcode.
252
+ _wptexturize_pushpop_element( $curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes );
253
+ } else {
254
+ // Looks like an escaped shortcode.
255
+ continue;
256
+ }
257
+
258
+ } elseif ( empty( $no_texturize_shortcodes_stack ) && empty( $no_texturize_tags_stack ) ) {
259
+ // This is neither a delimiter, nor is this content inside of no_texturize pairs. Do texturize.
260
+
261
+ $curl = str_replace( $static_characters, $static_replacements, $curl );
262
+
263
+ if ( false !== strpos( $curl, "'" ) ) {
264
+ $curl = preg_replace( $dynamic_characters['apos'], $dynamic_replacements['apos'], $curl );
265
+ $curl = wptexturize_primes( $curl, "'", $prime, $open_sq_flag, $closing_single_quote );
266
+ $curl = str_replace( $apos_flag, $apos, $curl );
267
+ $curl = str_replace( $open_sq_flag, $opening_single_quote, $curl );
268
+ }
269
+ if ( false !== strpos( $curl, '"' ) ) {
270
+ $curl = preg_replace( $dynamic_characters['quote'], $dynamic_replacements['quote'], $curl );
271
+ $curl = wptexturize_primes( $curl, '"', $double_prime, $open_q_flag, $closing_quote );
272
+ $curl = str_replace( $open_q_flag, $opening_quote, $curl );
273
+ }
274
+ if ( false !== strpos( $curl, '-' ) ) {
275
+ $curl = preg_replace( $dynamic_characters['dash'], $dynamic_replacements['dash'], $curl );
276
+ }
277
+
278
+ // 9x9 (times), but never 0x9999
279
+ if ( 1 === preg_match( '/(?<=\d)x\d/', $curl ) ) {
280
+ // Searching for a digit is 10 times more expensive than for the x, so we avoid doing this one!
281
+ $curl = preg_replace( '/\b(\d(?(?<=0)[\d\.,]+|[\d\.,]*))x(\d[\d\.,]*)\b/', '$1&#215;$2', $curl );
282
+ }
283
+
284
+ // Replace each & with &#038; unless it already looks like an entity.
285
+ $curl = preg_replace( '/&(?!#(?:\d+|x[a-f0-9]+);|[a-z1-4]{1,8};)/i', '&#038;', $curl );
286
+ }
287
+ }
288
+
289
+ return implode( '', $textarr );
290
+ }
291
+
292
+ /**
293
+ * Implements a logic tree to determine whether or not "7'." represents seven feet,
294
+ * then converts the special char into either a prime char or a closing quote char.
295
+ *
296
+ * @since 4.3.0
297
+ *
298
+ * @param string $haystack The plain text to be searched.
299
+ * @param string $needle The character to search for such as ' or ".
300
+ * @param string $prime The prime char to use for replacement.
301
+ * @param string $open_quote The opening quote char. Opening quote replacement must be
302
+ * accomplished already.
303
+ * @param string $close_quote The closing quote char to use for replacement.
304
+ * @return string The $haystack value after primes and quotes replacements.
305
+ */
306
+ function wptexturize_primes( $haystack, $needle, $prime, $open_quote, $close_quote ) {
307
+ $spaces = wp_spaces_regexp();
308
+ $flag = '<!--wp-prime-or-quote-->';
309
+ $quote_pattern = "/$needle(?=\\Z|[.,:;!?)}\\-\\]]|&gt;|" . $spaces . ")/";
310
+ $prime_pattern = "/(?<=\\d)$needle/";
311
+ $flag_after_digit = "/(?<=\\d)$flag/";
312
+ $flag_no_digit = "/(?<!\\d)$flag/";
313
+
314
+ $sentences = explode( $open_quote, $haystack );
315
+
316
+ foreach ( $sentences as $key => &$sentence ) {
317
+ if ( false === strpos( $sentence, $needle ) ) {
318
+ continue;
319
+ } elseif ( 0 !== $key && 0 === substr_count( $sentence, $close_quote ) ) {
320
+ $sentence = preg_replace( $quote_pattern, $flag, $sentence, -1, $count );
321
+ if ( $count > 1 ) {
322
+ // This sentence appears to have multiple closing quotes. Attempt Vulcan logic.
323
+ $sentence = preg_replace( $flag_no_digit, $close_quote, $sentence, -1, $count2 );
324
+ if ( 0 === $count2 ) {
325
+ // Try looking for a quote followed by a period.
326
+ $count2 = substr_count( $sentence, "$flag." );
327
+ if ( $count2 > 0 ) {
328
+ // Assume the rightmost quote-period match is the end of quotation.
329
+ $pos = strrpos( $sentence, "$flag." );
330
+ } else {
331
+ // When all else fails, make the rightmost candidate a closing quote.
332
+ // This is most likely to be problematic in the context of bug #18549.
333
+ $pos = strrpos( $sentence, $flag );
334
+ }
335
+ $sentence = substr_replace( $sentence, $close_quote, $pos, strlen( $flag ) );
336
+ }
337
+ // Use conventional replacement on any remaining primes and quotes.
338
+ $sentence = preg_replace( $prime_pattern, $prime, $sentence );
339
+ $sentence = preg_replace( $flag_after_digit, $prime, $sentence );
340
+ $sentence = str_replace( $flag, $close_quote, $sentence );
341
+ } elseif ( 1 == $count ) {
342
+ // Found only one closing quote candidate, so give it priority over primes.
343
+ $sentence = str_replace( $flag, $close_quote, $sentence );
344
+ $sentence = preg_replace( $prime_pattern, $prime, $sentence );
345
+ } else {
346
+ // No closing quotes found. Just run primes pattern.
347
+ $sentence = preg_replace( $prime_pattern, $prime, $sentence );
348
+ }
349
+ } else {
350
+ $sentence = preg_replace( $prime_pattern, $prime, $sentence );
351
+ $sentence = preg_replace( $quote_pattern, $close_quote, $sentence );
352
+ }
353
+ if ( '"' == $needle && false !== strpos( $sentence, '"' ) ) {
354
+ $sentence = str_replace( '"', $close_quote, $sentence );
355
+ }
356
+ }
357
+
358
+ return implode( $open_quote, $sentences );
359
+ }
360
+
361
+ /**
362
+ * Search for disabled element tags. Push element to stack on tag open and pop
363
+ * on tag close.
364
+ *
365
+ * Assumes first char of $text is tag opening and last char is tag closing.
366
+ * Assumes second char of $text is optionally '/' to indicate closing as in </html>.
367
+ *
368
+ * @since 2.9.0
369
+ * @access private
370
+ *
371
+ * @param string $text Text to check. Must be a tag like `<html>` or `[shortcode]`.
372
+ * @param array $stack List of open tag elements.
373
+ * @param array $disabled_elements The tag names to match against. Spaces are not allowed in tag names.
374
+ */
375
+ function _wptexturize_pushpop_element( $text, &$stack, $disabled_elements ) {
376
+ // Is it an opening tag or closing tag?
377
+ if ( isset( $text[1] ) && '/' !== $text[1] ) {
378
+ $opening_tag = true;
379
+ $name_offset = 1;
380
+ } elseif ( 0 == count( $stack ) ) {
381
+ // Stack is empty. Just stop.
382
+ return;
383
+ } else {
384
+ $opening_tag = false;
385
+ $name_offset = 2;
386
+ }
387
+
388
+ // Parse out the tag name.
389
+ $space = strpos( $text, ' ' );
390
+ if ( false === $space ) {
391
+ $space = -1;
392
+ } else {
393
+ $space -= $name_offset;
394
+ }
395
+ $tag = substr( $text, $name_offset, $space );
396
+
397
+ // Handle disabled tags.
398
+ if ( in_array( $tag, $disabled_elements ) ) {
399
+ if ( $opening_tag ) {
400
+ /*
401
+ * This disables texturize until we find a closing tag of our type
402
+ * (e.g. <pre>) even if there was invalid nesting before that
403
+ *
404
+ * Example: in the case <pre>sadsadasd</code>"baba"</pre>
405
+ * "baba" won't be texturize
406
+ */
407
+
408
+ array_push( $stack, $tag );
409
+ } elseif ( end( $stack ) == $tag ) {
410
+ array_pop( $stack );
411
+ }
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Replaces double line-breaks with paragraph elements.
417
+ *
418
+ * A group of regex replaces used to identify text formatted with newlines and
419
+ * replace double line-breaks with HTML paragraph tags. The remaining line-breaks
420
+ * after conversion become <<br />> tags, unless $br is set to '0' or 'false'.
421
+ *
422
+ * @since 0.71
423
+ *
424
+ * @param string $pee The text which has to be formatted.
425
+ * @param bool $br Optional. If set, this will convert all remaining line-breaks
426
+ * after paragraphing. Default true.
427
+ * @return string Text which has been converted into correct paragraph tags.
428
+ */
429
+ function wpautop( $pee, $br = true ) {
430
+ $pre_tags = array();
431
+
432
+ if ( trim($pee) === '' )
433
+ return '';
434
+
435
+ // Just to make things a little easier, pad the end.
436
+ $pee = $pee . "\n";
437
+
438
+ /*
439
+ * Pre tags shouldn't be touched by autop.
440
+ * Replace pre tags with placeholders and bring them back after autop.
441
+ */
442
+ if ( strpos($pee, '<pre') !== false ) {
443
+ $pee_parts = explode( '</pre>', $pee );
444
+ $last_pee = array_pop($pee_parts);
445
+ $pee = '';
446
+ $i = 0;
447
+
448
+ foreach ( $pee_parts as $pee_part ) {
449
+ $start = strpos($pee_part, '<pre');
450
+
451
+ // Malformed html?
452
+ if ( $start === false ) {
453
+ $pee .= $pee_part;
454
+ continue;
455
+ }
456
+
457
+ $name = "<pre wp-pre-tag-$i></pre>";
458
+ $pre_tags[$name] = substr( $pee_part, $start ) . '</pre>';
459
+
460
+ $pee .= substr( $pee_part, 0, $start ) . $name;
461
+ $i++;
462
+ }
463
+
464
+ $pee .= $last_pee;
465
+ }
466
+ // Change multiple <br>s into two line breaks, which will turn into paragraphs.
467
+ $pee = preg_replace('|<br\s*/?>\s*<br\s*/?>|', "\n\n", $pee);
468
+
469
+ $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)';
470
+
471
+ // Add a double line break above block-level opening tags.
472
+ $pee = preg_replace('!(<' . $allblocks . '[\s/>])!', "\n\n$1", $pee);
473
+
474
+ // Add a double line break below block-level closing tags.
475
+ $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
476
+
477
+ // Standardize newline characters to "\n".
478
+ $pee = str_replace(array("\r\n", "\r"), "\n", $pee);
479
+
480
+ // Find newlines in all elements and add placeholders.
481
+ $pee = wp_replace_in_html_tags( $pee, array( "\n" => " <!-- wpnl --> " ) );
482
+
483
+ // Collapse line breaks before and after <option> elements so they don't get autop'd.
484
+ if ( strpos( $pee, '<option' ) !== false ) {
485
+ $pee = preg_replace( '|\s*<option|', '<option', $pee );
486
+ $pee = preg_replace( '|</option>\s*|', '</option>', $pee );
487
+ }
488
+
489
+ /*
490
+ * Collapse line breaks inside <object> elements, before <param> and <embed> elements
491
+ * so they don't get autop'd.
492
+ */
493
+ if ( strpos( $pee, '</object>' ) !== false ) {
494
+ $pee = preg_replace( '|(<object[^>]*>)\s*|', '$1', $pee );
495
+ $pee = preg_replace( '|\s*</object>|', '</object>', $pee );
496
+ $pee = preg_replace( '%\s*(</?(?:param|embed)[^>]*>)\s*%', '$1', $pee );
497
+ }
498
+
499
+ /*
500
+ * Collapse line breaks inside <audio> and <video> elements,
501
+ * before and after <source> and <track> elements.
502
+ */
503
+ if ( strpos( $pee, '<source' ) !== false || strpos( $pee, '<track' ) !== false ) {
504
+ $pee = preg_replace( '%([<\[](?:audio|video)[^>\]]*[>\]])\s*%', '$1', $pee );
505
+ $pee = preg_replace( '%\s*([<\[]/(?:audio|video)[>\]])%', '$1', $pee );
506
+ $pee = preg_replace( '%\s*(<(?:source|track)[^>]*>)\s*%', '$1', $pee );
507
+ }
508
+
509
+ // Remove more than two contiguous line breaks.
510
+ $pee = preg_replace("/\n\n+/", "\n\n", $pee);
511
+
512
+ // Split up the contents into an array of strings, separated by double line breaks.
513
+ $pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
514
+
515
+ // Reset $pee prior to rebuilding.
516
+ $pee = '';
517
+
518
+ // Rebuild the content as a string, wrapping every bit with a <p>.
519
+ foreach ( $pees as $tinkle ) {
520
+ $pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
521
+ }
522
+
523
+ // Under certain strange conditions it could create a P of entirely whitespace.
524
+ $pee = preg_replace('|<p>\s*</p>|', '', $pee);
525
+
526
+ // Add a closing <p> inside <div>, <address>, or <form> tag if missing.
527
+ $pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
528
+
529
+ // If an opening or closing block element tag is wrapped in a <p>, unwrap it.
530
+ $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
531
+
532
+ // In some cases <li> may get wrapped in <p>, fix them.
533
+ $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee);
534
+
535
+ // If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>.
536
+ $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
537
+ $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
538
+
539
+ // If an opening or closing block element tag is preceded by an opening <p> tag, remove it.
540
+ $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
541
+
542
+ // If an opening or closing block element tag is followed by a closing <p> tag, remove it.
543
+ $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
544
+
545
+ // Optionally insert line breaks.
546
+ if ( $br ) {
547
+ // Replace newlines that shouldn't be touched with a placeholder.
548
+ $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', '_autop_newline_preservation_helper', $pee);
549
+
550
+ // Normalize <br>
551
+ $pee = str_replace( array( '<br>', '<br/>' ), '<br />', $pee );
552
+
553
+ // Replace any new line characters that aren't preceded by a <br /> with a <br />.
554
+ $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee);
555
+
556
+ // Replace newline placeholders with newlines.
557
+ $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
558
+ }
559
+
560
+ // If a <br /> tag is after an opening or closing block tag, remove it.
561
+ $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
562
+
563
+ // If a <br /> tag is before a subset of opening or closing block tags, remove it.
564
+ $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
565
+ $pee = preg_replace( "|\n</p>$|", '</p>', $pee );
566
+
567
+ // Replace placeholder <pre> tags with their original content.
568
+ if ( !empty($pre_tags) )
569
+ $pee = str_replace(array_keys($pre_tags), array_values($pre_tags), $pee);
570
+
571
+ // Restore newlines in all elements.
572
+ if ( false !== strpos( $pee, '<!-- wpnl -->' ) ) {
573
+ $pee = str_replace( array( ' <!-- wpnl --> ', '<!-- wpnl -->' ), "\n", $pee );
574
+ }
575
+
576
+ return $pee;
577
+ }
578
+
579
+ /**
580
+ * Separate HTML elements and comments from the text.
581
+ *
582
+ * @since 4.2.4
583
+ *
584
+ * @param string $input The text which has to be formatted.
585
+ * @return array The formatted text.
586
+ */
587
+ function wp_html_split( $input ) {
588
+ return preg_split( get_html_split_regex(), $input, -1, PREG_SPLIT_DELIM_CAPTURE );
589
+ }
590
+
591
+ /**
592
+ * Retrieve the regular expression for an HTML element.
593
+ *
594
+ * @since 4.4.0
595
+ *
596
+ * @return string The regular expression
597
+ */
598
+ function get_html_split_regex() {
599
+ static $regex;
600
+
601
+ if ( ! isset( $regex ) ) {
602
+ $comments =
603
+ '!' // Start of comment, after the <.
604
+ . '(?:' // Unroll the loop: Consume everything until --> is found.
605
+ . '-(?!->)' // Dash not followed by end of comment.
606
+ . '[^\-]*+' // Consume non-dashes.
607
+ . ')*+' // Loop possessively.
608
+ . '(?:-->)?'; // End of comment. If not found, match all input.
609
+
610
+ $cdata =
611
+ '!\[CDATA\[' // Start of comment, after the <.
612
+ . '[^\]]*+' // Consume non-].
613
+ . '(?:' // Unroll the loop: Consume everything until ]]> is found.
614
+ . '](?!]>)' // One ] not followed by end of comment.
615
+ . '[^\]]*+' // Consume non-].
616
+ . ')*+' // Loop possessively.
617
+ . '(?:]]>)?'; // End of comment. If not found, match all input.
618
+
619
+ $escaped =
620
+ '(?=' // Is the element escaped?
621
+ . '!--'
622
+ . '|'
623
+ . '!\[CDATA\['
624
+ . ')'
625
+ . '(?(?=!-)' // If yes, which type?
626
+ . $comments
627
+ . '|'
628
+ . $cdata
629
+ . ')';
630
+
631
+ $regex =
632
+ '/(' // Capture the entire match.
633
+ . '<' // Find start of element.
634
+ . '(?' // Conditional expression follows.
635
+ . $escaped // Find end of escaped element.
636
+ . '|' // ... else ...
637
+ . '[^>]*>?' // Find end of normal element.
638
+ . ')'
639
+ . ')/';
640
+ }
641
+
642
+ return $regex;
643
+ }
644
+
645
+ /**
646
+ * Retrieve the combined regular expression for HTML and shortcodes.
647
+ *
648
+ * @access private
649
+ * @ignore
650
+ * @internal This function will be removed in 4.5.0 per Shortcode API Roadmap.
651
+ * @since 4.4.0
652
+ *
653
+ * @param string $shortcode_regex The result from _get_wptexturize_shortcode_regex(). Optional.
654
+ * @return string The regular expression
655
+ */
656
+ function _get_wptexturize_split_regex( $shortcode_regex = '' ) {
657
+ static $html_regex;
658
+
659
+ if ( ! isset( $html_regex ) ) {
660
+ $comment_regex =
661
+ '!' // Start of comment, after the <.
662
+ . '(?:' // Unroll the loop: Consume everything until --> is found.
663
+ . '-(?!->)' // Dash not followed by end of comment.
664
+ . '[^\-]*+' // Consume non-dashes.
665
+ . ')*+' // Loop possessively.
666
+ . '(?:-->)?'; // End of comment. If not found, match all input.
667
+
668
+ $html_regex = // Needs replaced with wp_html_split() per Shortcode API Roadmap.
669
+ '<' // Find start of element.
670
+ . '(?(?=!--)' // Is this a comment?
671
+ . $comment_regex // Find end of comment.
672
+ . '|'
673
+ . '[^>]*>?' // Find end of element. If not found, match all input.
674
+ . ')';
675
+ }
676
+
677
+ if ( empty( $shortcode_regex ) ) {
678
+ $regex = '/(' . $html_regex . ')/';
679
+ } else {
680
+ $regex = '/(' . $html_regex . '|' . $shortcode_regex . ')/';
681
+ }
682
+
683
+ return $regex;
684
+ }
685
+
686
+ /**
687
+ * Retrieve the regular expression for shortcodes.
688
+ *
689
+ * @access private
690
+ * @ignore
691
+ * @internal This function will be removed in 4.5.0 per Shortcode API Roadmap.
692
+ * @since 4.4.0
693
+ *
694
+ * @param array $tagnames List of shortcodes to find.
695
+ * @return string The regular expression
696
+ */
697
+ function _get_wptexturize_shortcode_regex( $tagnames ) {
698
+ $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
699
+ $tagregexp = "(?:$tagregexp)(?=[\\s\\]\\/])"; // Excerpt of get_shortcode_regex().
700
+ $regex =
701
+ '\[' // Find start of shortcode.
702
+ . '[\/\[]?' // Shortcodes may begin with [/ or [[
703
+ . $tagregexp // Only match registered shortcodes, because performance.
704
+ . '(?:'
705
+ . '[^\[\]<>]+' // Shortcodes do not contain other shortcodes. Quantifier critical.
706
+ . '|'
707
+ . '<[^\[\]>]*>' // HTML elements permitted. Prevents matching ] before >.
708
+ . ')*+' // Possessive critical.
709
+ . '\]' // Find end of shortcode.
710
+ . '\]?'; // Shortcodes may end with ]]
711
+
712
+ return $regex;
713
+ }
714
+
715
+ /**
716
+ * Replace characters or phrases within HTML elements only.
717
+ *
718
+ * @since 4.2.3
719
+ *
720
+ * @param string $haystack The text which has to be formatted.
721
+ * @param array $replace_pairs In the form array('from' => 'to', ...).
722
+ * @return string The formatted text.
723
+ */
724
+ function wp_replace_in_html_tags( $haystack, $replace_pairs ) {
725
+ // Find all elements.
726
+ $textarr = wp_html_split( $haystack );
727
+ $changed = false;
728
+
729
+ // Optimize when searching for one item.
730
+ if ( 1 === count( $replace_pairs ) ) {
731
+ // Extract $needle and $replace.
732
+ foreach ( $replace_pairs as $needle => $replace );
733
+
734
+ // Loop through delimiters (elements) only.
735
+ for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
736
+ if ( false !== strpos( $textarr[$i], $needle ) ) {
737
+ $textarr[$i] = str_replace( $needle, $replace, $textarr[$i] );
738
+ $changed = true;
739
+ }
740
+ }
741
+ } else {
742
+ // Extract all $needles.
743
+ $needles = array_keys( $replace_pairs );
744
+
745
+ // Loop through delimiters (elements) only.
746
+ for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
747
+ foreach ( $needles as $needle ) {
748
+ if ( false !== strpos( $textarr[$i], $needle ) ) {
749
+ $textarr[$i] = strtr( $textarr[$i], $replace_pairs );
750
+ $changed = true;
751
+ // After one strtr() break out of the foreach loop and look at next element.
752
+ break;
753
+ }
754
+ }
755
+ }
756
+ }
757
+
758
+ if ( $changed ) {
759
+ $haystack = implode( $textarr );
760
+ }
761
+
762
+ return $haystack;
763
+ }
764
+
765
+ /**
766
+ * Newline preservation help function for wpautop
767
+ *
768
+ * @since 3.1.0
769
+ * @access private
770
+ *
771
+ * @param array $matches preg_replace_callback matches array
772
+ * @return string
773
+ */
774
+ function _autop_newline_preservation_helper( $matches ) {
775
+ return str_replace( "\n", "<WPPreserveNewline />", $matches[0] );
776
+ }
777
+
778
+ /**
779
+ * Don't auto-p wrap shortcodes that stand alone
780
+ *
781
+ * Ensures that shortcodes are not wrapped in `<p>...</p>`.
782
+ *
783
+ * @since 2.9.0
784
+ *
785
+ * @global array $shortcode_tags
786
+ *
787
+ * @param string $pee The content.
788
+ * @return string The filtered content.
789
+ */
790
+ function shortcode_unautop( $pee ) {
791
+ global $shortcode_tags;
792
+
793
+ if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) {
794
+ return $pee;
795
+ }
796
+
797
+ $tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) );
798
+ $spaces = wp_spaces_regexp();
799
+
800
+ $pattern =
801
+ '/'
802
+ . '<p>' // Opening paragraph
803
+ . '(?:' . $spaces . ')*+' // Optional leading whitespace
804
+ . '(' // 1: The shortcode
805
+ . '\\[' // Opening bracket
806
+ . "($tagregexp)" // 2: Shortcode name
807
+ . '(?![\\w-])' // Not followed by word character or hyphen
808
+ // Unroll the loop: Inside the opening shortcode tag
809
+ . '[^\\]\\/]*' // Not a closing bracket or forward slash
810
+ . '(?:'
811
+ . '\\/(?!\\])' // A forward slash not followed by a closing bracket
812
+ . '[^\\]\\/]*' // Not a closing bracket or forward slash
813
+ . ')*?'
814
+ . '(?:'
815
+ . '\\/\\]' // Self closing tag and closing bracket
816
+ . '|'
817
+ . '\\]' // Closing bracket
818
+ . '(?:' // Unroll the loop: Optionally, anything between the opening and closing shortcode tags
819
+ . '[^\\[]*+' // Not an opening bracket
820
+ . '(?:'
821
+ . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
822
+ . '[^\\[]*+' // Not an opening bracket
823
+ . ')*+'
824
+ . '\\[\\/\\2\\]' // Closing shortcode tag
825
+ . ')?'
826
+ . ')'
827
+ . ')'
828
+ . '(?:' . $spaces . ')*+' // optional trailing whitespace
829
+ . '<\\/p>' // closing paragraph
830
+ . '/';
831
+
832
+ return preg_replace( $pattern, '$1', $pee );
833
+ }
834
+
835
+ /**
836
+ * Checks to see if a string is utf8 encoded.
837
+ *
838
+ * NOTE: This function checks for 5-Byte sequences, UTF8
839
+ * has Bytes Sequences with a maximum length of 4.
840
+ *
841
+ * @author bmorel at ssi dot fr (modified)
842
+ * @since 1.2.1
843
+ *
844
+ * @param string $str The string to be checked
845
+ * @return bool True if $str fits a UTF-8 model, false otherwise.
846
+ */
847
+ function seems_utf8( $str ) {
848
+ mbstring_binary_safe_encoding();
849
+ $length = strlen($str);
850
+ reset_mbstring_encoding();
851
+ for ($i=0; $i < $length; $i++) {
852
+ $c = ord($str[$i]);
853
+ if ($c < 0x80) $n = 0; // 0bbbbbbb
854
+ elseif (($c & 0xE0) == 0xC0) $n=1; // 110bbbbb
855
+ elseif (($c & 0xF0) == 0xE0) $n=2; // 1110bbbb
856
+ elseif (($c & 0xF8) == 0xF0) $n=3; // 11110bbb
857
+ elseif (($c & 0xFC) == 0xF8) $n=4; // 111110bb
858
+ elseif (($c & 0xFE) == 0xFC) $n=5; // 1111110b
859
+ else return false; // Does not match any model
860
+ for ($j=0; $j<$n; $j++) { // n bytes matching 10bbbbbb follow ?
861
+ if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
862
+ return false;
863
+ }
864
+ }
865
+ return true;
866
+ }
867
+
868
+ /**
869
+ * Converts a number of special characters into their HTML entities.
870
+ *
871
+ * Specifically deals with: &, <, >, ", and '.
872
+ *
873
+ * $quote_style can be set to ENT_COMPAT to encode " to
874
+ * &quot;, or ENT_QUOTES to do both. Default is ENT_NOQUOTES where no quotes are encoded.
875
+ *
876
+ * @since 1.2.2
877
+ * @access private
878
+ *
879
+ * @staticvar string $_charset
880
+ *
881
+ * @param string $string The text which is to be encoded.
882
+ * @param int|string $quote_style Optional. Converts double quotes if set to ENT_COMPAT,
883
+ * both single and double if set to ENT_QUOTES or none if set to ENT_NOQUOTES.
884
+ * Also compatible with old values; converting single quotes if set to 'single',
885
+ * double if set to 'double' or both if otherwise set.
886
+ * Default is ENT_NOQUOTES.
887
+ * @param string $charset Optional. The character encoding of the string. Default is false.
888
+ * @param bool $double_encode Optional. Whether to encode existing html entities. Default is false.
889
+ * @return string The encoded text with HTML entities.
890
+ */
891
+ function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
892
+ $string = (string) $string;
893
+
894
+ if ( 0 === strlen( $string ) )
895
+ return '';
896
+
897
+ // Don't bother if there are no specialchars - saves some processing
898
+ if ( ! preg_match( '/[&<>"\']/', $string ) )
899
+ return $string;
900
+
901
+ // Account for the previous behaviour of the function when the $quote_style is not an accepted value
902
+ if ( empty( $quote_style ) )
903
+ $quote_style = ENT_NOQUOTES;
904
+ elseif ( ! in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) )
905
+ $quote_style = ENT_QUOTES;
906
+
907
+ // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
908
+ if ( ! $charset ) {
909
+ static $_charset = null;
910
+ if ( ! isset( $_charset ) ) {
911
+ $alloptions = wp_load_alloptions();
912
+ $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : '';
913
+ }
914
+ $charset = $_charset;
915
+ }
916
+
917
+ if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) )
918
+ $charset = 'UTF-8';
919
+
920
+ $_quote_style = $quote_style;
921
+
922
+ if ( $quote_style === 'double' ) {
923
+ $quote_style = ENT_COMPAT;
924
+ $_quote_style = ENT_COMPAT;
925
+ } elseif ( $quote_style === 'single' ) {
926
+ $quote_style = ENT_NOQUOTES;
927
+ }
928
+
929
+ if ( ! $double_encode ) {
930
+ // Guarantee every &entity; is valid, convert &garbage; into &amp;garbage;
931
+ // This is required for PHP < 5.4.0 because ENT_HTML401 flag is unavailable.
932
+ $string = wp_kses_normalize_entities( $string );
933
+ }
934
+
935
+ $string = @htmlspecialchars( $string, $quote_style, $charset, $double_encode );
936
+
937
+ // Back-compat.
938
+ if ( 'single' === $_quote_style )
939
+ $string = str_replace( "'", '&#039;', $string );
940
+
941
+ return $string;
942
+ }
943
+
944
+ /**
945
+ * Converts a number of HTML entities into their special characters.
946
+ *
947
+ * Specifically deals with: &, <, >, ", and '.
948
+ *
949
+ * $quote_style can be set to ENT_COMPAT to decode " entities,
950
+ * or ENT_QUOTES to do both " and '. Default is ENT_NOQUOTES where no quotes are decoded.
951
+ *
952
+ * @since 2.8.0
953
+ *
954
+ * @param string $string The text which is to be decoded.
955
+ * @param string|int $quote_style Optional. Converts double quotes if set to ENT_COMPAT,
956
+ * both single and double if set to ENT_QUOTES or
957
+ * none if set to ENT_NOQUOTES.
958
+ * Also compatible with old _wp_specialchars() values;
959
+ * converting single quotes if set to 'single',
960
+ * double if set to 'double' or both if otherwise set.
961
+ * Default is ENT_NOQUOTES.
962
+ * @return string The decoded text without HTML entities.
963
+ */
964
+ function wp_specialchars_decode( $string, $quote_style = ENT_NOQUOTES ) {
965
+ $string = (string) $string;
966
+
967
+ if ( 0 === strlen( $string ) ) {
968
+ return '';
969
+ }
970
+
971
+ // Don't bother if there are no entities - saves a lot of processing
972
+ if ( strpos( $string, '&' ) === false ) {
973
+ return $string;
974
+ }
975
+
976
+ // Match the previous behaviour of _wp_specialchars() when the $quote_style is not an accepted value
977
+ if ( empty( $quote_style ) ) {
978
+ $quote_style = ENT_NOQUOTES;
979
+ } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
980
+ $quote_style = ENT_QUOTES;
981
+ }
982
+
983
+ // More complete than get_html_translation_table( HTML_SPECIALCHARS )
984
+ $single = array( '&#039;' => '\'', '&#x27;' => '\'' );
985
+ $single_preg = array( '/&#0*39;/' => '&#039;', '/&#x0*27;/i' => '&#x27;' );
986
+ $double = array( '&quot;' => '"', '&#034;' => '"', '&#x22;' => '"' );
987
+ $double_preg = array( '/&#0*34;/' => '&#034;', '/&#x0*22;/i' => '&#x22;' );
988
+ $others = array( '&lt;' => '<', '&#060;' => '<', '&gt;' => '>', '&#062;' => '>', '&amp;' => '&', '&#038;' => '&', '&#x26;' => '&' );
989
+ $others_preg = array( '/&#0*60;/' => '&#060;', '/&#0*62;/' => '&#062;', '/&#0*38;/' => '&#038;', '/&#x0*26;/i' => '&#x26;' );
990
+
991
+ if ( $quote_style === ENT_QUOTES ) {
992
+ $translation = array_merge( $single, $double, $others );
993
+ $translation_preg = array_merge( $single_preg, $double_preg, $others_preg );
994
+ } elseif ( $quote_style === ENT_COMPAT || $quote_style === 'double' ) {
995
+ $translation = array_merge( $double, $others );
996
+ $translation_preg = array_merge( $double_preg, $others_preg );
997
+ } elseif ( $quote_style === 'single' ) {
998
+ $translation = array_merge( $single, $others );
999
+ $translation_preg = array_merge( $single_preg, $others_preg );
1000
+ } elseif ( $quote_style === ENT_NOQUOTES ) {
1001
+ $translation = $others;
1002
+ $translation_preg = $others_preg;
1003
+ }
1004
+
1005
+ // Remove zero padding on numeric entities
1006
+ $string = preg_replace( array_keys( $translation_preg ), array_values( $translation_preg ), $string );
1007
+
1008
+ // Replace characters according to translation table
1009
+ return strtr( $string, $translation );
1010
+ }
1011
+
1012
+ /**
1013
+ * Checks for invalid UTF8 in a string.
1014
+ *
1015
+ * @since 2.8.0
1016
+ *
1017
+ * @staticvar bool $is_utf8
1018
+ * @staticvar bool $utf8_pcre
1019
+ *
1020
+ * @param string $string The text which is to be checked.
1021
+ * @param bool $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false.
1022
+ * @return string The checked text.
1023
+ */
1024
+ function wp_check_invalid_utf8( $string, $strip = false ) {
1025
+ $string = (string) $string;
1026
+
1027
+ if ( 0 === strlen( $string ) ) {
1028
+ return '';
1029
+ }
1030
+
1031
+ // Store the site charset as a static to avoid multiple calls to get_option()
1032
+ static $is_utf8 = null;
1033
+ if ( ! isset( $is_utf8 ) ) {
1034
+ $is_utf8 = in_array( get_option( 'blog_charset' ), array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) );
1035
+ }
1036
+ if ( ! $is_utf8 ) {
1037
+ return $string;
1038
+ }
1039
+
1040
+ // Check for support for utf8 in the installed PCRE library once and store the result in a static
1041
+ static $utf8_pcre = null;
1042
+ if ( ! isset( $utf8_pcre ) ) {
1043
+ $utf8_pcre = @preg_match( '/^./u', 'a' );
1044
+ }
1045
+ // We can't demand utf8 in the PCRE installation, so just return the string in those cases
1046
+ if ( !$utf8_pcre ) {
1047
+ return $string;
1048
+ }
1049
+
1050
+ // preg_match fails when it encounters invalid UTF8 in $string
1051
+ if ( 1 === @preg_match( '/^./us', $string ) ) {
1052
+ return $string;
1053
+ }
1054
+
1055
+ // Attempt to strip the bad chars if requested (not recommended)
1056
+ if ( $strip && function_exists( 'iconv' ) ) {
1057
+ return iconv( 'utf-8', 'utf-8', $string );
1058
+ }
1059
+
1060
+ return '';
1061
+ }
1062
+
1063
+ /**
1064
+ * Encode the Unicode values to be used in the URI.
1065
+ *
1066
+ * @since 1.5.0
1067
+ *
1068
+ * @param string $utf8_string
1069
+ * @param int $length Max length of the string
1070
+ * @return string String with Unicode encoded for URI.
1071
+ */
1072
+ function utf8_uri_encode( $utf8_string, $length = 0 ) {
1073
+ $unicode = '';
1074
+ $values = array();
1075
+ $num_octets = 1;
1076
+ $unicode_length = 0;
1077
+
1078
+ mbstring_binary_safe_encoding();
1079
+ $string_length = strlen( $utf8_string );
1080
+ reset_mbstring_encoding();
1081
+
1082
+ for ($i = 0; $i < $string_length; $i++ ) {
1083
+
1084
+ $value = ord( $utf8_string[ $i ] );
1085
+
1086
+ if ( $value < 128 ) {
1087
+ if ( $length && ( $unicode_length >= $length ) )
1088
+ break;
1089
+ $unicode .= chr($value);
1090
+ $unicode_length++;
1091
+ } else {
1092
+ if ( count( $values ) == 0 ) {
1093
+ if ( $value < 224 ) {
1094
+ $num_octets = 2;
1095
+ } elseif ( $value < 240 ) {
1096
+ $num_octets = 3;
1097
+ } else {
1098
+ $num_octets = 4;
1099
+ }
1100
+ }
1101
+
1102
+ $values[] = $value;
1103
+
1104
+ if ( $length && ( $unicode_length + ($num_octets * 3) ) > $length )
1105
+ break;
1106
+ if ( count( $values ) == $num_octets ) {
1107
+ for ( $j = 0; $j < $num_octets; $j++ ) {
1108
+ $unicode .= '%' . dechex( $values[ $j ] );
1109
+ }
1110
+
1111
+ $unicode_length += $num_octets * 3;
1112
+
1113
+ $values = array();
1114
+ $num_octets = 1;
1115
+ }
1116
+ }
1117
+ }
1118
+
1119
+ return $unicode;
1120
+ }
1121
+
1122
+ /**
1123
+ * Converts all accent characters to ASCII characters.
1124
+ *
1125
+ * If there are no accent characters, then the string given is just returned.
1126
+ *
1127
+ * **Accent characters converted:**
1128
+ *
1129
+ * Currency signs:
1130
+ *
1131
+ * | Code | Glyph | Replacement | Description |
1132
+ * | -------- | ----- | ----------- | ------------------- |
1133
+ * | U+00A3 | £ | (empty) | British Pound sign |
1134
+ * | U+20AC | € | E | Euro sign |
1135
+ *
1136
+ * Decompositions for Latin-1 Supplement:
1137
+ *
1138
+ * | Code | Glyph | Replacement | Description |
1139
+ * | ------- | ----- | ----------- | -------------------------------------- |
1140
+ * | U+00AA | ª | a | Feminine ordinal indicator |
1141
+ * | U+00BA | º | o | Masculine ordinal indicator |
1142
+ * | U+00C0 | À | A | Latin capital letter A with grave |
1143
+ * | U+00C1 | Á | A | Latin capital letter A with acute |
1144
+ * | U+00C2 | Â | A | Latin capital letter A with circumflex |
1145
+ * | U+00C3 | Ã | A | Latin capital letter A with tilde |
1146
+ * | U+00C4 | Ä | A | Latin capital letter A with diaeresis |
1147
+ * | U+00C5 | Å | A | Latin capital letter A with ring above |
1148
+ * | U+00C6 | Æ | AE | Latin capital letter AE |
1149
+ * | U+00C7 | Ç | C | Latin capital letter C with cedilla |
1150
+ * | U+00C8 | È | E | Latin capital letter E with grave |
1151
+ * | U+00C9 | É | E | Latin capital letter E with acute |
1152
+ * | U+00CA | Ê | E | Latin capital letter E with circumflex |
1153
+ * | U+00CB | Ë | E | Latin capital letter E with diaeresis |
1154
+ * | U+00CC | Ì | I | Latin capital letter I with grave |
1155
+ * | U+00CD | Í | I | Latin capital letter I with acute |
1156
+ * | U+00CE | Î | I | Latin capital letter I with circumflex |
1157
+ * | U+00CF | Ï | I | Latin capital letter I with diaeresis |
1158
+ * | U+00D0 | Ð | D | Latin capital letter Eth |
1159
+ * | U+00D1 | Ñ | N | Latin capital letter N with tilde |
1160
+ * | U+00D2 | Ò | O | Latin capital letter O with grave |
1161
+ * | U+00D3 | Ó | O | Latin capital letter O with acute |
1162
+ * | U+00D4 | Ô | O | Latin capital letter O with circumflex |
1163
+ * | U+00D5 | Õ | O | Latin capital letter O with tilde |
1164
+ * | U+00D6 | Ö | O | Latin capital letter O with diaeresis |
1165
+ * | U+00D8 | Ø | O | Latin capital letter O with stroke |
1166
+ * | U+00D9 | Ù | U | Latin capital letter U with grave |
1167
+ * | U+00DA | Ú | U | Latin capital letter U with acute |
1168
+ * | U+00DB | Û | U | Latin capital letter U with circumflex |
1169
+ * | U+00DC | Ü | U | Latin capital letter U with diaeresis |
1170
+ * | U+00DD | Ý | Y | Latin capital letter Y with acute |
1171
+ * | U+00DE | Þ | TH | Latin capital letter Thorn |
1172
+ * | U+00DF | ß | s | Latin small letter sharp s |
1173
+ * | U+00E0 | à | a | Latin small letter a with grave |
1174
+ * | U+00E1 | á | a | Latin small letter a with acute |
1175
+ * | U+00E2 | â | a | Latin small letter a with circumflex |
1176
+ * | U+00E3 | ã | a | Latin small letter a with tilde |
1177
+ * | U+00E4 | ä | a | Latin small letter a with diaeresis |
1178
+ * | U+00E5 | å | a | Latin small letter a with ring above |
1179
+ * | U+00E6 | æ | ae | Latin small letter ae |
1180
+ * | U+00E7 | ç | c | Latin small letter c with cedilla |
1181
+ * | U+00E8 | è | e | Latin small letter e with grave |
1182
+ * | U+00E9 | é | e | Latin small letter e with acute |
1183
+ * | U+00EA | ê | e | Latin small letter e with circumflex |
1184
+ * | U+00EB | ë | e | Latin small letter e with diaeresis |
1185
+ * | U+00EC | ì | i | Latin small letter i with grave |
1186
+ * | U+00ED | í | i | Latin small letter i with acute |
1187
+ * | U+00EE | î | i | Latin small letter i with circumflex |
1188
+ * | U+00EF | ï | i | Latin small letter i with diaeresis |
1189
+ * | U+00F0 | ð | d | Latin small letter Eth |
1190
+ * | U+00F1 | ñ | n | Latin small letter n with tilde |
1191
+ * | U+00F2 | ò | o | Latin small letter o with grave |
1192
+ * | U+00F3 | ó | o | Latin small letter o with acute |
1193
+ * | U+00F4 | ô | o | Latin small letter o with circumflex |
1194
+ * | U+00F5 | õ | o | Latin small letter o with tilde |
1195
+ * | U+00F6 | ö | o | Latin small letter o with diaeresis |
1196
+ * | U+00F8 | ø | o | Latin small letter o with stroke |
1197
+ * | U+00F9 | ù | u | Latin small letter u with grave |
1198
+ * | U+00FA | ú | u | Latin small letter u with acute |
1199
+ * | U+00FB | û | u | Latin small letter u with circumflex |
1200
+ * | U+00FC | ü | u | Latin small letter u with diaeresis |
1201
+ * | U+00FD | ý | y | Latin small letter y with acute |
1202
+ * | U+00FE | þ | th | Latin small letter Thorn |
1203
+ * | U+00FF | ÿ | y | Latin small letter y with diaeresis |
1204
+ *
1205
+ * Decompositions for Latin Extended-A:
1206
+ *
1207
+ * | Code | Glyph | Replacement | Description |
1208
+ * | ------- | ----- | ----------- | ------------------------------------------------- |
1209
+ * | U+0100 | Ā | A | Latin capital letter A with macron |
1210
+ * | U+0101 | ā | a | Latin small letter a with macron |
1211
+ * | U+0102 | Ă | A | Latin capital letter A with breve |
1212
+ * | U+0103 | ă | a | Latin small letter a with breve |
1213
+ * | U+0104 | Ą | A | Latin capital letter A with ogonek |
1214
+ * | U+0105 | ą | a | Latin small letter a with ogonek |
1215
+ * | U+01006 | Ć | C | Latin capital letter C with acute |
1216
+ * | U+0107 | ć | c | Latin small letter c with acute |
1217
+ * | U+0108 | Ĉ | C | Latin capital letter C with circumflex |
1218
+ * | U+0109 | ĉ | c | Latin small letter c with circumflex |
1219
+ * | U+010A | Ċ | C | Latin capital letter C with dot above |
1220
+ * | U+010B | ċ | c | Latin small letter c with dot above |
1221
+ * | U+010C | Č | C | Latin capital letter C with caron |
1222
+ * | U+010D | č | c | Latin small letter c with caron |
1223
+ * | U+010E | Ď | D | Latin capital letter D with caron |
1224
+ * | U+010F | ď | d | Latin small letter d with caron |
1225
+ * | U+0110 | Đ | D | Latin capital letter D with stroke |
1226
+ * | U+0111 | đ | d | Latin small letter d with stroke |
1227
+ * | U+0112 | Ē | E | Latin capital letter E with macron |
1228
+ * | U+0113 | ē | e | Latin small letter e with macron |
1229
+ * | U+0114 | Ĕ | E | Latin capital letter E with breve |
1230
+ * | U+0115 | ĕ | e | Latin small letter e with breve |
1231
+ * | U+0116 | Ė | E | Latin capital letter E with dot above |
1232
+ * | U+0117 | ė | e | Latin small letter e with dot above |
1233
+ * | U+0118 | Ę | E | Latin capital letter E with ogonek |
1234
+ * | U+0119 | ę | e | Latin small letter e with ogonek |
1235
+ * | U+011A | Ě | E | Latin capital letter E with caron |
1236
+ * | U+011B | ě | e | Latin small letter e with caron |
1237
+ * | U+011C | Ĝ | G | Latin capital letter G with circumflex |
1238
+ * | U+011D | ĝ | g | Latin small letter g with circumflex |
1239
+ * | U+011E | Ğ | G | Latin capital letter G with breve |
1240
+ * | U+011F | ğ | g | Latin small letter g with breve |
1241
+ * | U+0120 | Ġ | G | Latin capital letter G with dot above |
1242
+ * | U+0121 | ġ | g | Latin small letter g with dot above |
1243
+ * | U+0122 | Ģ | G | Latin capital letter G with cedilla |
1244
+ * | U+0123 | ģ | g | Latin small letter g with cedilla |
1245
+ * | U+0124 | Ĥ | H | Latin capital letter H with circumflex |
1246
+ * | U+0125 | ĥ | h | Latin small letter h with circumflex |
1247
+ * | U+0126 | Ħ | H | Latin capital letter H with stroke |
1248
+ * | U+0127 | ħ | h | Latin small letter h with stroke |
1249
+ * | U+0128 | Ĩ | I | Latin capital letter I with tilde |
1250
+ * | U+0129 | ĩ | i | Latin small letter i with tilde |
1251
+ * | U+012A | Ī | I | Latin capital letter I with macron |
1252
+ * | U+012B | ī | i | Latin small letter i with macron |
1253
+ * | U+012C | Ĭ | I | Latin capital letter I with breve |
1254
+ * | U+012D | ĭ | i | Latin small letter i with breve |
1255
+ * | U+012E | Į | I | Latin capital letter I with ogonek |
1256
+ * | U+012F | į | i | Latin small letter i with ogonek |
1257
+ * | U+0130 | İ | I | Latin capital letter I with dot above |
1258
+ * | U+0131 | ı | i | Latin small letter dotless i |
1259
+ * | U+0132 | IJ | IJ | Latin capital ligature IJ |
1260
+ * | U+0133 | ij | ij | Latin small ligature ij |
1261
+ * | U+0134 | Ĵ | J | Latin capital letter J with circumflex |
1262
+ * | U+0135 | ĵ | j | Latin small letter j with circumflex |
1263
+ * | U+0136 | Ķ | K | Latin capital letter K with cedilla |
1264
+ * | U+0137 | ķ | k | Latin small letter k with cedilla |
1265
+ * | U+0138 | ĸ | k | Latin small letter Kra |
1266
+ * | U+0139 | Ĺ | L | Latin capital letter L with acute |
1267
+ * | U+013A | ĺ | l | Latin small letter l with acute |
1268
+ * | U+013B | Ļ | L | Latin capital letter L with cedilla |
1269
+ * | U+013C | ļ | l | Latin small letter l with cedilla |
1270
+ * | U+013D | Ľ | L | Latin capital letter L with caron |
1271
+ * | U+013E | ľ | l | Latin small letter l with caron |
1272
+ * | U+013F | Ŀ | L | Latin capital letter L with middle dot |
1273
+ * | U+0140 | ŀ | l | Latin small letter l with middle dot |
1274
+ * | U+0141 | Ł | L | Latin capital letter L with stroke |
1275
+ * | U+0142 | ł | l | Latin small letter l with stroke |
1276
+ * | U+0143 | Ń | N | Latin capital letter N with acute |
1277
+ * | U+0144 | ń | n | Latin small letter N with acute |
1278
+ * | U+0145 | Ņ | N | Latin capital letter N with cedilla |
1279
+ * | U+0146 | ņ | n | Latin small letter n with cedilla |
1280
+ * | U+0147 | Ň | N | Latin capital letter N with caron |
1281
+ * | U+0148 | ň | n | Latin small letter n with caron |
1282
+ * | U+0149 | ʼn | n | Latin small letter n preceded by apostrophe |
1283
+ * | U+014A | Ŋ | N | Latin capital letter Eng |
1284
+ * | U+014B | ŋ | n | Latin small letter Eng |
1285
+ * | U+014C | Ō | O | Latin capital letter O with macron |
1286
+ * | U+014D | ō | o | Latin small letter o with macron |
1287
+ * | U+014E | Ŏ | O | Latin capital letter O with breve |
1288
+ * | U+014F | ŏ | o | Latin small letter o with breve |
1289
+ * | U+0150 | Ő | O | Latin capital letter O with double acute |
1290
+ * | U+0151 | ő | o | Latin small letter o with double acute |
1291
+ * | U+0152 | Π| OE | Latin capital ligature OE |
1292
+ * | U+0153 | œ | oe | Latin small ligature oe |
1293
+ * | U+0154 | Ŕ | R | Latin capital letter R with acute |
1294
+ * | U+0155 | ŕ | r | Latin small letter r with acute |
1295
+ * | U+0156 | Ŗ | R | Latin capital letter R with cedilla |
1296
+ * | U+0157 | ŗ | r | Latin small letter r with cedilla |
1297
+ * | U+0158 | Ř | R | Latin capital letter R with caron |
1298
+ * | U+0159 | ř | r | Latin small letter r with caron |
1299
+ * | U+015A | Ś | S | Latin capital letter S with acute |
1300
+ * | U+015B | ś | s | Latin small letter s with acute |
1301
+ * | U+015C | Ŝ | S | Latin capital letter S with circumflex |
1302
+ * | U+015D | ŝ | s | Latin small letter s with circumflex |
1303
+ * | U+015E | Ş | S | Latin capital letter S with cedilla |
1304
+ * | U+015F | ş | s | Latin small letter s with cedilla |
1305
+ * | U+0160 | Š | S | Latin capital letter S with caron |
1306
+ * | U+0161 | š | s | Latin small letter s with caron |
1307
+ * | U+0162 | Ţ | T | Latin capital letter T with cedilla |
1308
+ * | U+0163 | ţ | t | Latin small letter t with cedilla |
1309
+ * | U+0164 | Ť | T | Latin capital letter T with caron |
1310
+ * | U+0165 | ť | t | Latin small letter t with caron |
1311
+ * | U+0166 | Ŧ | T | Latin capital letter T with stroke |
1312
+ * | U+0167 | ŧ | t | Latin small letter t with stroke |
1313
+ * | U+0168 | Ũ | U | Latin capital letter U with tilde |
1314
+ * | U+0169 | ũ | u | Latin small letter u with tilde |
1315
+ * | U+016A | Ū | U | Latin capital letter U with macron |
1316
+ * | U+016B | ū | u | Latin small letter u with macron |
1317
+ * | U+016C | Ŭ | U | Latin capital letter U with breve |
1318
+ * | U+016D | ŭ | u | Latin small letter u with breve |
1319
+ * | U+016E | Ů | U | Latin capital letter U with ring above |
1320
+ * | U+016F | ů | u | Latin small letter u with ring above |
1321
+ * | U+0170 | Ű | U | Latin capital letter U with double acute |
1322
+ * | U+0171 | ű | u | Latin small letter u with double acute |
1323
+ * | U+0172 | Ų | U | Latin capital letter U with ogonek |
1324
+ * | U+0173 | ų | u | Latin small letter u with ogonek |
1325
+ * | U+0174 | Ŵ | W | Latin capital letter W with circumflex |
1326
+ * | U+0175 | ŵ | w | Latin small letter w with circumflex |
1327
+ * | U+0176 | Ŷ | Y | Latin capital letter Y with circumflex |
1328
+ * | U+0177 | ŷ | y | Latin small letter y with circumflex |
1329
+ * | U+0178 | Ÿ | Y | Latin capital letter Y with diaeresis |
1330
+ * | U+0179 | Ź | Z | Latin capital letter Z with acute |
1331
+ * | U+017A | ź | z | Latin small letter z with acute |
1332
+ * | U+017B | Ż | Z | Latin capital letter Z with dot above |
1333
+ * | U+017C | ż | z | Latin small letter z with dot above |
1334
+ * | U+017D | Ž | Z | Latin capital letter Z with caron |
1335
+ * | U+017E | ž | z | Latin small letter z with caron |
1336
+ * | U+017F | ſ | s | Latin small letter long s |
1337
+ * | U+01A0 | Ơ | O | Latin capital letter O with horn |
1338
+ * | U+01A1 | ơ | o | Latin small letter o with horn |
1339
+ * | U+01AF | Ư | U | Latin capital letter U with horn |
1340
+ * | U+01B0 | ư | u | Latin small letter u with horn |
1341
+ * | U+01CD | Ǎ | A | Latin capital letter A with caron |
1342
+ * | U+01CE | ǎ | a | Latin small letter a with caron |
1343
+ * | U+01CF | Ǐ | I | Latin capital letter I with caron |
1344
+ * | U+01D0 | ǐ | i | Latin small letter i with caron |
1345
+ * | U+01D1 | Ǒ | O | Latin capital letter O with caron |
1346
+ * | U+01D2 | ǒ | o | Latin small letter o with caron |
1347
+ * | U+01D3 | Ǔ | U | Latin capital letter U with caron |
1348
+ * | U+01D4 | ǔ | u | Latin small letter u with caron |
1349
+ * | U+01D5 | Ǖ | U | Latin capital letter U with diaeresis and macron |
1350
+ * | U+01D6 | ǖ | u | Latin small letter u with diaeresis and macron |
1351
+ * | U+01D7 | Ǘ | U | Latin capital letter U with diaeresis and acute |
1352
+ * | U+01D8 | ǘ | u | Latin small letter u with diaeresis and acute |
1353
+ * | U+01D9 | Ǚ | U | Latin capital letter U with diaeresis and caron |
1354
+ * | U+01DA | ǚ | u | Latin small letter u with diaeresis and caron |
1355
+ * | U+01DB | Ǜ | U | Latin capital letter U with diaeresis and grave |
1356
+ * | U+01DC | ǜ | u | Latin small letter u with diaeresis and grave |
1357
+ *
1358
+ * Decompositions for Latin Extended-B:
1359
+ *
1360
+ * | Code | Glyph | Replacement | Description |
1361
+ * | -------- | ----- | ----------- | ----------------------------------------- |
1362
+ * | U+0218 | Ș | S | Latin capital letter S with comma below |
1363
+ * | U+0219 | ș | s | Latin small letter s with comma below |
1364
+ * | U+021A | Ț | T | Latin capital letter T with comma below |
1365
+ * | U+021B | ț | t | Latin small letter t with comma below |
1366
+ *
1367
+ * Vowels with diacritic (Chinese, Hanyu Pinyin):
1368
+ *
1369
+ * | Code | Glyph | Replacement | Description |
1370
+ * | -------- | ----- | ----------- | ----------------------------------------------------- |
1371
+ * | U+0251 | ɑ | a | Latin small letter alpha |
1372
+ * | U+1EA0 | Ạ | A | Latin capital letter A with dot below |
1373
+ * | U+1EA1 | ạ | a | Latin small letter a with dot below |
1374
+ * | U+1EA2 | Ả | A | Latin capital letter A with hook above |
1375
+ * | U+1EA3 | ả | a | Latin small letter a with hook above |
1376
+ * | U+1EA4 | Ấ | A | Latin capital letter A with circumflex and acute |
1377
+ * | U+1EA5 | ấ | a | Latin small letter a with circumflex and acute |
1378
+ * | U+1EA6 | Ầ | A | Latin capital letter A with circumflex and grave |
1379
+ * | U+1EA7 | ầ | a | Latin small letter a with circumflex and grave |
1380
+ * | U+1EA8 | Ẩ | A | Latin capital letter A with circumflex and hook above |
1381
+ * | U+1EA9 | ẩ | a | Latin small letter a with circumflex and hook above |
1382
+ * | U+1EAA | Ẫ | A | Latin capital letter A with circumflex and tilde |
1383
+ * | U+1EAB | ẫ | a | Latin small letter a with circumflex and tilde |
1384
+ * | U+1EA6 | Ậ | A | Latin capital letter A with circumflex and dot below |
1385
+ * | U+1EAD | ậ | a | Latin small letter a with circumflex and dot below |
1386
+ * | U+1EAE | Ắ | A | Latin capital letter A with breve and acute |
1387
+ * | U+1EAF | ắ | a | Latin small letter a with breve and acute |
1388
+ * | U+1EB0 | Ằ | A | Latin capital letter A with breve and grave |
1389
+ * | U+1EB1 | ằ | a | Latin small letter a with breve and grave |
1390
+ * | U+1EB2 | Ẳ | A | Latin capital letter A with breve and hook above |
1391
+ * | U+1EB3 | ẳ | a | Latin small letter a with breve and hook above |
1392
+ * | U+1EB4 | Ẵ | A | Latin capital letter A with breve and tilde |
1393
+ * | U+1EB5 | ẵ | a | Latin small letter a with breve and tilde |
1394
+ * | U+1EB6 | Ặ | A | Latin capital letter A with breve and dot below |
1395
+ * | U+1EB7 | ặ | a | Latin small letter a with breve and dot below |
1396
+ * | U+1EB8 | Ẹ | E | Latin capital letter E with dot below |
1397
+ * | U+1EB9 | ẹ | e | Latin small letter e with dot below |
1398
+ * | U+1EBA | Ẻ | E | Latin capital letter E with hook above |
1399
+ * | U+1EBB | ẻ | e | Latin small letter e with hook above |
1400
+ * | U+1EBC | Ẽ | E | Latin capital letter E with tilde |
1401
+ * | U+1EBD | ẽ | e | Latin small letter e with tilde |
1402
+ * | U+1EBE | Ế | E | Latin capital letter E with circumflex and acute |
1403
+ * | U+1EBF | ế | e | Latin small letter e with circumflex and acute |
1404
+ * | U+1EC0 | Ề | E | Latin capital letter E with circumflex and grave |
1405
+ * | U+1EC1 | ề | e | Latin small letter e with circumflex and grave |
1406
+ * | U+1EC2 | Ể | E | Latin capital letter E with circumflex and hook above |
1407
+ * | U+1EC3 | ể | e | Latin small letter e with circumflex and hook above |
1408
+ * | U+1EC4 | Ễ | E | Latin capital letter E with circumflex and tilde |
1409
+ * | U+1EC5 | ễ | e | Latin small letter e with circumflex and tilde |
1410
+ * | U+1EC6 | Ệ | E | Latin capital letter E with circumflex and dot below |
1411
+ * | U+1EC7 | ệ | e | Latin small letter e with circumflex and dot below |
1412
+ * | U+1EC8 | Ỉ | I | Latin capital letter I with hook above |
1413
+ * | U+1EC9 | ỉ | i | Latin small letter i with hook above |
1414
+ * | U+1ECA | Ị | I | Latin capital letter I with dot below |
1415
+ * | U+1ECB | ị | i | Latin small letter i with dot below |
1416
+ * | U+1ECC | Ọ | O | Latin capital letter O with dot below |
1417
+ * | U+1ECD | ọ | o | Latin small letter o with dot below |
1418
+ * | U+1ECE | Ỏ | O | Latin capital letter O with hook above |
1419
+ * | U+1ECF | ỏ | o | Latin small letter o with hook above |
1420
+ * | U+1ED0 | Ố | O | Latin capital letter O with circumflex and acute |
1421
+ * | U+1ED1 | ố | o | Latin small letter o with circumflex and acute |
1422
+ * | U+1ED2 | Ồ | O | Latin capital letter O with circumflex and grave |
1423
+ * | U+1ED3 | ồ | o | Latin small letter o with circumflex and grave |
1424
+ * | U+1ED4 | Ổ | O | Latin capital letter O with circumflex and hook above |
1425
+ * | U+1ED5 | ổ | o | Latin small letter o with circumflex and hook above |
1426
+ * | U+1ED6 | Ỗ | O | Latin capital letter O with circumflex and tilde |
1427
+ * | U+1ED7 | ỗ | o | Latin small letter o with circumflex and tilde |
1428
+ * | U+1ED8 | Ộ | O | Latin capital letter O with circumflex and dot below |
1429
+ * | U+1ED9 | ộ | o | Latin small letter o with circumflex and dot below |
1430
+ * | U+1EDA | Ớ | O | Latin capital letter O with horn and acute |
1431
+ * | U+1EDB | ớ | o | Latin small letter o with horn and acute |
1432
+ * | U+1EDC | Ờ | O | Latin capital letter O with horn and grave |
1433
+ * | U+1EDD | ờ | o | Latin small letter o with horn and grave |
1434
+ * | U+1EDE | Ở | O | Latin capital letter O with horn and hook above |
1435
+ * | U+1EDF | ở | o | Latin small letter o with horn and hook above |
1436
+ * | U+1EE0 | Ỡ | O | Latin capital letter O with horn and tilde |
1437
+ * | U+1EE1 | ỡ | o | Latin small letter o with horn and tilde |
1438
+ * | U+1EE2 | Ợ | O | Latin capital letter O with horn and dot below |
1439
+ * | U+1EE3 | ợ | o | Latin small letter o with horn and dot below |
1440
+ * | U+1EE4 | Ụ | U | Latin capital letter U with dot below |
1441
+ * | U+1EE5 | ụ | u | Latin small letter u with dot below |
1442
+ * | U+1EE6 | Ủ | U | Latin capital letter U with hook above |
1443
+ * | U+1EE7 | ủ | u | Latin small letter u with hook above |
1444
+ * | U+1EE8 | Ứ | U | Latin capital letter U with horn and acute |
1445
+ * | U+1EE9 | ứ | u | Latin small letter u with horn and acute |
1446
+ * | U+1EEA | Ừ | U | Latin capital letter U with horn and grave |
1447
+ * | U+1EEB | ừ | u | Latin small letter u with horn and grave |
1448
+ * | U+1EEC | Ử | U | Latin capital letter U with horn and hook above |
1449
+ * | U+1EED | ử | u | Latin small letter u with horn and hook above |
1450
+ * | U+1EEE | Ữ | U | Latin capital letter U with horn and tilde |
1451
+ * | U+1EEF | ữ | u | Latin small letter u with horn and tilde |
1452
+ * | U+1EF0 | Ự | U | Latin capital letter U with horn and dot below |
1453
+ * | U+1EF1 | ự | u | Latin small letter u with horn and dot below |
1454
+ * | U+1EF2 | Ỳ | Y | Latin capital letter Y with grave |
1455
+ * | U+1EF3 | ỳ | y | Latin small letter y with grave |
1456
+ * | U+1EF4 | Ỵ | Y | Latin capital letter Y with dot below |
1457
+ * | U+1EF5 | ỵ | y | Latin small letter y with dot below |
1458
+ * | U+1EF6 | Ỷ | Y | Latin capital letter Y with hook above |
1459
+ * | U+1EF7 | ỷ | y | Latin small letter y with hook above |
1460
+ * | U+1EF8 | Ỹ | Y | Latin capital letter Y with tilde |
1461
+ * | U+1EF9 | ỹ | y | Latin small letter y with tilde |
1462
+ *
1463
+ * German (`de_DE`), German formal (`de_DE_formal`), German (Switzerland) formal (`de_CH`),
1464
+ * and German (Switzerland) informal (`de_CH_informal`) locales:
1465
+ *
1466
+ * | Code | Glyph | Replacement | Description |
1467
+ * | -------- | ----- | ----------- | --------------------------------------- |
1468
+ * | U+00C4 | Ä | Ae | Latin capital letter A with diaeresis |
1469
+ * | U+00E4 | ä | ae | Latin small letter a with diaeresis |
1470
+ * | U+00D6 | Ö | Oe | Latin capital letter O with diaeresis |
1471
+ * | U+00F6 | ö | oe | Latin small letter o with diaeresis |
1472
+ * | U+00DC | Ü | Ue | Latin capital letter U with diaeresis |
1473
+ * | U+00FC | ü | ue | Latin small letter u with diaeresis |
1474
+ * | U+00DF | ß | ss | Latin small letter sharp s |
1475
+ *
1476
+ * Danish (`da_DK`) locale:
1477
+ *
1478
+ * | Code | Glyph | Replacement | Description |
1479
+ * | -------- | ----- | ----------- | --------------------------------------- |
1480
+ * | U+00C6 | Æ | Ae | Latin capital letter AE |
1481
+ * | U+00E6 | æ | ae | Latin small letter ae |
1482
+ * | U+00D8 | Ø | Oe | Latin capital letter O with stroke |
1483
+ * | U+00F8 | ø | oe | Latin small letter o with stroke |
1484
+ * | U+00C5 | Å | Aa | Latin capital letter A with ring above |
1485
+ * | U+00E5 | å | aa | Latin small letter a with ring above |
1486
+ *
1487
+ * Catalan (`ca`) locale:
1488
+ *
1489
+ * | Code | Glyph | Replacement | Description |
1490
+ * | -------- | ----- | ----------- | --------------------------------------- |
1491
+ * | U+00B7 | l·l | ll | Flown dot (between two Ls) |
1492
+ *
1493
+ * Serbian (`sr_RS`) locale:
1494
+ *
1495
+ * | Code | Glyph | Replacement | Description |
1496
+ * | -------- | ----- | ----------- | --------------------------------------- |
1497
+ * | U+0110 | Đ | DJ | Latin capital letter D with stroke |
1498
+ * | U+0111 | đ | dj | Latin small letter d with stroke |
1499
+ *
1500
+ * @since 1.2.1
1501
+ * @since 4.6.0 Added locale support for `de_CH`, `de_CH_informal`, and `ca`.
1502
+ * @since 4.7.0 Added locale support for `sr_RS`.
1503
+ *
1504
+ * @param string $string Text that might have accent characters
1505
+ * @return string Filtered string with replaced "nice" characters.
1506
+ */
1507
+ function remove_accents( $string ) {
1508
+ if ( !preg_match('/[\x80-\xff]/', $string) )
1509
+ return $string;
1510
+
1511
+ if (seems_utf8($string)) {
1512
+ $chars = array(
1513
+ // Decompositions for Latin-1 Supplement
1514
+ 'ª' => 'a', 'º' => 'o',
1515
+ 'À' => 'A', 'Á' => 'A',
1516
+ 'Â' => 'A', 'Ã' => 'A',
1517
+ 'Ä' => 'A', 'Å' => 'A',
1518
+ 'Æ' => 'AE','Ç' => 'C',
1519
+ 'È' => 'E', 'É' => 'E',
1520
+ 'Ê' => 'E', 'Ë' => 'E',
1521
+ 'Ì' => 'I', 'Í' => 'I',
1522
+ 'Î' => 'I', 'Ï' => 'I',
1523
+ 'Ð' => 'D', 'Ñ' => 'N',
1524
+ 'Ò' => 'O', 'Ó' => 'O',
1525
+ 'Ô' => 'O', 'Õ' => 'O',
1526
+ 'Ö' => 'O', 'Ù' => 'U',
1527
+ 'Ú' => 'U', 'Û' => 'U',
1528
+ 'Ü' => 'U', 'Ý' => 'Y',
1529
+ 'Þ' => 'TH','ß' => 's',
1530
+ 'à' => 'a', 'á' => 'a',
1531
+ 'â' => 'a', 'ã' => 'a',
1532
+ 'ä' => 'a', 'å' => 'a',
1533
+ 'æ' => 'ae','ç' => 'c',
1534
+ 'è' => 'e', 'é' => 'e',
1535
+ 'ê' => 'e', 'ë' => 'e',
1536
+ 'ì' => 'i', 'í' => 'i',
1537
+ 'î' => 'i', 'ï' => 'i',
1538
+ 'ð' => 'd', 'ñ' => 'n',
1539
+ 'ò' => 'o', 'ó' => 'o',
1540
+ 'ô' => 'o', 'õ' => 'o',
1541
+ 'ö' => 'o', 'ø' => 'o',
1542
+ 'ù' => 'u', 'ú' => 'u',
1543
+ 'û' => 'u', 'ü' => 'u',
1544
+ 'ý' => 'y', 'þ' => 'th',
1545
+ 'ÿ' => 'y', 'Ø' => 'O',
1546
+ // Decompositions for Latin Extended-A
1547
+ 'Ā' => 'A', 'ā' => 'a',
1548
+ 'Ă' => 'A', 'ă' => 'a',
1549
+ 'Ą' => 'A', 'ą' => 'a',
1550
+ 'Ć' => 'C', 'ć' => 'c',
1551
+ 'Ĉ' => 'C', 'ĉ' => 'c',
1552
+ 'Ċ' => 'C', 'ċ' => 'c',
1553
+ 'Č' => 'C', 'č' => 'c',
1554
+ 'Ď' => 'D', 'ď' => 'd',
1555
+ 'Đ' => 'D', 'đ' => 'd',
1556
+ 'Ē' => 'E', 'ē' => 'e',
1557
+ 'Ĕ' => 'E', 'ĕ' => 'e',
1558
+ 'Ė' => 'E', 'ė' => 'e',
1559
+ 'Ę' => 'E', 'ę' => 'e',
1560
+ 'Ě' => 'E', 'ě' => 'e',
1561
+ 'Ĝ' => 'G', 'ĝ' => 'g',
1562
+ 'Ğ' => 'G', 'ğ' => 'g',
1563
+ 'Ġ' => 'G', 'ġ' => 'g',
1564
+ 'Ģ' => 'G', 'ģ' => 'g',
1565
+ 'Ĥ' => 'H', 'ĥ' => 'h',
1566
+ 'Ħ' => 'H', 'ħ' => 'h',
1567
+ 'Ĩ' => 'I', 'ĩ' => 'i',
1568
+ 'Ī' => 'I', 'ī' => 'i',
1569
+ 'Ĭ' => 'I', 'ĭ' => 'i',
1570
+ 'Į' => 'I', 'į' => 'i',
1571
+ 'İ' => 'I', 'ı' => 'i',
1572
+ 'IJ' => 'IJ','ij' => 'ij',
1573
+ 'Ĵ' => 'J', 'ĵ' => 'j',
1574
+ 'Ķ' => 'K', 'ķ' => 'k',
1575
+ 'ĸ' => 'k', 'Ĺ' => 'L',
1576
+ 'ĺ' => 'l', 'Ļ' => 'L',
1577
+ 'ļ' => 'l', 'Ľ' => 'L',
1578
+ 'ľ' => 'l', 'Ŀ' => 'L',
1579
+ 'ŀ' => 'l', 'Ł' => 'L',
1580
+ 'ł' => 'l', 'Ń' => 'N',
1581
+ 'ń' => 'n', 'Ņ' => 'N',
1582
+ 'ņ' => 'n', 'Ň' => 'N',
1583
+ 'ň' => 'n', 'ʼn' => 'n',
1584
+ 'Ŋ' => 'N', 'ŋ' => 'n',
1585
+ 'Ō' => 'O', 'ō' => 'o',
1586
+ 'Ŏ' => 'O', 'ŏ' => 'o',
1587
+ 'Ő' => 'O', 'ő' => 'o',
1588
+ 'Œ' => 'OE','œ' => 'oe',
1589
+ 'Ŕ' => 'R','ŕ' => 'r',
1590
+ 'Ŗ' => 'R','ŗ' => 'r',
1591
+ 'Ř' => 'R','ř' => 'r',
1592
+ 'Ś' => 'S','ś' => 's',
1593
+ 'Ŝ' => 'S','ŝ' => 's',
1594
+ 'Ş' => 'S','ş' => 's',
1595
+ 'Š' => 'S', 'š' => 's',
1596
+ 'Ţ' => 'T', 'ţ' => 't',
1597
+ 'Ť' => 'T', 'ť' => 't',
1598
+ 'Ŧ' => 'T', 'ŧ' => 't',
1599
+ 'Ũ' => 'U', 'ũ' => 'u',
1600
+ 'Ū' => 'U', 'ū' => 'u',
1601
+ 'Ŭ' => 'U', 'ŭ' => 'u',
1602
+ 'Ů' => 'U', 'ů' => 'u',
1603
+ 'Ű' => 'U', 'ű' => 'u',
1604
+ 'Ų' => 'U', 'ų' => 'u',
1605
+ 'Ŵ' => 'W', 'ŵ' => 'w',
1606
+ 'Ŷ' => 'Y', 'ŷ' => 'y',
1607
+ 'Ÿ' => 'Y', 'Ź' => 'Z',
1608
+ 'ź' => 'z', 'Ż' => 'Z',
1609
+ 'ż' => 'z', 'Ž' => 'Z',
1610
+ 'ž' => 'z', 'ſ' => 's',
1611
+ // Decompositions for Latin Extended-B
1612
+ 'Ș' => 'S', 'ș' => 's',
1613
+ 'Ț' => 'T', 'ț' => 't',
1614
+ // Euro Sign
1615
+ '€' => 'E',
1616
+ // GBP (Pound) Sign
1617
+ '£' => '',
1618
+ // Vowels with diacritic (Vietnamese)
1619
+ // unmarked
1620
+ 'Ơ' => 'O', 'ơ' => 'o',
1621
+ 'Ư' => 'U', 'ư' => 'u',
1622
+ // grave accent
1623
+ 'Ầ' => 'A', 'ầ' => 'a',
1624
+ 'Ằ' => 'A', 'ằ' => 'a',
1625
+ 'Ề' => 'E', 'ề' => 'e',
1626
+ 'Ồ' => 'O', 'ồ' => 'o',
1627
+ 'Ờ' => 'O', 'ờ' => 'o',
1628
+ 'Ừ' => 'U', 'ừ' => 'u',
1629
+ 'Ỳ' => 'Y', 'ỳ' => 'y',
1630
+ // hook
1631
+ 'Ả' => 'A', 'ả' => 'a',
1632
+ 'Ẩ' => 'A', 'ẩ' => 'a',
1633
+ 'Ẳ' => 'A', 'ẳ' => 'a',
1634
+ 'Ẻ' => 'E', 'ẻ' => 'e',
1635
+ 'Ể' => 'E', 'ể' => 'e',
1636
+ 'Ỉ' => 'I', 'ỉ' => 'i',
1637
+ 'Ỏ' => 'O', 'ỏ' => 'o',
1638
+ 'Ổ' => 'O', 'ổ' => 'o',
1639
+ 'Ở' => 'O', 'ở' => 'o',
1640
+ 'Ủ' => 'U', 'ủ' => 'u',
1641
+ 'Ử' => 'U', 'ử' => 'u',
1642
+ 'Ỷ' => 'Y', 'ỷ' => 'y',
1643
+ // tilde
1644
+ 'Ẫ' => 'A', 'ẫ' => 'a',
1645
+ 'Ẵ' => 'A', 'ẵ' => 'a',
1646
+ 'Ẽ' => 'E', 'ẽ' => 'e',
1647
+ 'Ễ' => 'E', 'ễ' => 'e',
1648
+ 'Ỗ' => 'O', 'ỗ' => 'o',
1649
+ 'Ỡ' => 'O', 'ỡ' => 'o',
1650
+ 'Ữ' => 'U', 'ữ' => 'u',
1651
+ 'Ỹ' => 'Y', 'ỹ' => 'y',
1652
+ // acute accent
1653
+ 'Ấ' => 'A', 'ấ' => 'a',
1654
+ 'Ắ' => 'A', 'ắ' => 'a',
1655
+ 'Ế' => 'E', 'ế' => 'e',
1656
+ 'Ố' => 'O', 'ố' => 'o',
1657
+ 'Ớ' => 'O', 'ớ' => 'o',
1658
+ 'Ứ' => 'U', 'ứ' => 'u',
1659
+ // dot below
1660
+ 'Ạ' => 'A', 'ạ' => 'a',
1661
+ 'Ậ' => 'A', 'ậ' => 'a',
1662
+ 'Ặ' => 'A', 'ặ' => 'a',
1663
+ 'Ẹ' => 'E', 'ẹ' => 'e',
1664
+ 'Ệ' => 'E', 'ệ' => 'e',
1665
+ 'Ị' => 'I', 'ị' => 'i',
1666
+ 'Ọ' => 'O', 'ọ' => 'o',
1667
+ 'Ộ' => 'O', 'ộ' => 'o',
1668
+ 'Ợ' => 'O', 'ợ' => 'o',
1669
+ 'Ụ' => 'U', 'ụ' => 'u',
1670
+ 'Ự' => 'U', 'ự' => 'u',
1671
+ 'Ỵ' => 'Y', 'ỵ' => 'y',
1672
+ // Vowels with diacritic (Chinese, Hanyu Pinyin)
1673
+ 'ɑ' => 'a',
1674
+ // macron
1675
+ 'Ǖ' => 'U', 'ǖ' => 'u',
1676
+ // acute accent
1677
+ 'Ǘ' => 'U', 'ǘ' => 'u',
1678
+ // caron
1679
+ 'Ǎ' => 'A', 'ǎ' => 'a',
1680
+ 'Ǐ' => 'I', 'ǐ' => 'i',
1681
+ 'Ǒ' => 'O', 'ǒ' => 'o',
1682
+ 'Ǔ' => 'U', 'ǔ' => 'u',
1683
+ 'Ǚ' => 'U', 'ǚ' => 'u',
1684
+ // grave accent
1685
+ 'Ǜ' => 'U', 'ǜ' => 'u',
1686
+ );
1687
+
1688
+ // Used for locale-specific rules
1689
+ $locale = get_locale();
1690
+
1691
+ if ( 'de_DE' == $locale || 'de_DE_formal' == $locale || 'de_CH' == $locale || 'de_CH_informal' == $locale ) {
1692
+ $chars[ 'Ä' ] = 'Ae';
1693
+ $chars[ 'ä' ] = 'ae';
1694
+ $chars[ 'Ö' ] = 'Oe';
1695
+ $chars[ 'ö' ] = 'oe';
1696
+ $chars[ 'Ü' ] = 'Ue';
1697
+ $chars[ 'ü' ] = 'ue';
1698
+ $chars[ 'ß' ] = 'ss';
1699
+ } elseif ( 'da_DK' === $locale ) {
1700
+ $chars[ 'Æ' ] = 'Ae';
1701
+ $chars[ 'æ' ] = 'ae';
1702
+ $chars[ 'Ø' ] = 'Oe';
1703
+ $chars[ 'ø' ] = 'oe';
1704
+ $chars[ 'Å' ] = 'Aa';
1705
+ $chars[ 'å' ] = 'aa';
1706
+ } elseif ( 'ca' === $locale ) {
1707
+ $chars[ 'l·l' ] = 'll';
1708
+ } elseif ( 'sr_RS' === $locale ) {
1709
+ $chars[ 'Đ' ] = 'DJ';
1710
+ $chars[ 'đ' ] = 'dj';
1711
+ }
1712
+
1713
+ $string = strtr($string, $chars);
1714
+ } else {
1715
+ $chars = array();
1716
+ // Assume ISO-8859-1 if not UTF-8
1717
+ $chars['in'] = "\x80\x83\x8a\x8e\x9a\x9e"
1718
+ ."\x9f\xa2\xa5\xb5\xc0\xc1\xc2"
1719
+ ."\xc3\xc4\xc5\xc7\xc8\xc9\xca"
1720
+ ."\xcb\xcc\xcd\xce\xcf\xd1\xd2"
1721
+ ."\xd3\xd4\xd5\xd6\xd8\xd9\xda"
1722
+ ."\xdb\xdc\xdd\xe0\xe1\xe2\xe3"
1723
+ ."\xe4\xe5\xe7\xe8\xe9\xea\xeb"
1724
+ ."\xec\xed\xee\xef\xf1\xf2\xf3"
1725
+ ."\xf4\xf5\xf6\xf8\xf9\xfa\xfb"
1726
+ ."\xfc\xfd\xff";
1727
+
1728
+ $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
1729
+
1730
+ $string = strtr($string, $chars['in'], $chars['out']);
1731
+ $double_chars = array();
1732
+ $double_chars['in'] = array("\x8c", "\x9c", "\xc6", "\xd0", "\xde", "\xdf", "\xe6", "\xf0", "\xfe");
1733
+ $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
1734
+ $string = str_replace($double_chars['in'], $double_chars['out'], $string);
1735
+ }
1736
+
1737
+ return $string;
1738
+ }
1739
+
1740
+ /**
1741
+ * Sanitizes a filename, replacing whitespace with dashes.
1742
+ *
1743
+ * Removes special characters that are illegal in filenames on certain
1744
+ * operating systems and special characters requiring special escaping
1745
+ * to manipulate at the command line. Replaces spaces and consecutive
1746
+ * dashes with a single dash. Trims period, dash and underscore from beginning
1747
+ * and end of filename. It is not guaranteed that this function will return a
1748
+ * filename that is allowed to be uploaded.
1749
+ *
1750
+ * @since 2.1.0
1751
+ *
1752
+ * @param string $filename The filename to be sanitized
1753
+ * @return string The sanitized filename
1754
+ */
1755
+ function sanitize_file_name( $filename ) {
1756
+ $filename_raw = $filename;
1757
+ $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));
1758
+ /**
1759
+ * Filters the list of characters to remove from a filename.
1760
+ *
1761
+ * @since 2.8.0
1762
+ *
1763
+ * @param array $special_chars Characters to remove.
1764
+ * @param string $filename_raw Filename as it was passed into sanitize_file_name().
1765
+ */
1766
+ $special_chars = apply_filters( 'sanitize_file_name_chars', $special_chars, $filename_raw );
1767
+ $filename = preg_replace( "#\x{00a0}#siu", ' ', $filename );
1768
+ $filename = str_replace( $special_chars, '', $filename );
1769
+ $filename = str_replace( array( '%20', '+' ), '-', $filename );
1770
+ $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename );
1771
+ $filename = trim( $filename, '.-_' );
1772
+
1773
+ if ( false === strpos( $filename, '.' ) ) {
1774
+ $mime_types = wp_get_mime_types();
1775
+ $filetype = wp_check_filetype( 'test.' . $filename, $mime_types );
1776
+ if ( $filetype['ext'] === $filename ) {
1777
+ $filename = 'unnamed-file.' . $filetype['ext'];
1778
+ }
1779
+ }
1780
+
1781
+ // Split the filename into a base and extension[s]
1782
+ $parts = explode('.', $filename);
1783
+
1784
+ // Return if only one extension
1785
+ if ( count( $parts ) <= 2 ) {
1786
+ /**
1787
+ * Filters a sanitized filename string.
1788
+ *
1789
+ * @since 2.8.0
1790
+ *
1791
+ * @param string $filename Sanitized filename.
1792
+ * @param string $filename_raw The filename prior to sanitization.
1793
+ */
1794
+ return apply_filters( 'sanitize_file_name', $filename, $filename_raw );
1795
+ }
1796
+
1797
+ // Process multiple extensions
1798
+ $filename = array_shift($parts);
1799
+ $extension = array_pop($parts);
1800
+ $mimes = get_allowed_mime_types();
1801
+
1802
+ /*
1803
+ * Loop over any intermediate extensions. Postfix them with a trailing underscore
1804
+ * if they are a 2 - 5 character long alpha string not in the extension whitelist.
1805
+ */
1806
+ foreach ( (array) $parts as $part) {
1807
+ $filename .= '.' . $part;
1808
+
1809
+ if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) {
1810
+ $allowed = false;
1811
+ foreach ( $mimes as $ext_preg => $mime_match ) {
1812
+ $ext_preg = '!^(' . $ext_preg . ')$!i';
1813
+ if ( preg_match( $ext_preg, $part ) ) {
1814
+ $allowed = true;
1815
+ break;
1816
+ }
1817
+ }
1818
+ if ( !$allowed )
1819
+ $filename .= '_';
1820
+ }
1821
+ }
1822
+ $filename .= '.' . $extension;
1823
+ /** This filter is documented in wp-includes/formatting.php */
1824
+ return apply_filters('sanitize_file_name', $filename, $filename_raw);
1825
+ }
1826
+
1827
+ /**
1828
+ * Sanitizes a username, stripping out unsafe characters.
1829
+ *
1830
+ * Removes tags, octets, entities, and if strict is enabled, will only keep
1831
+ * alphanumeric, _, space, ., -, @. After sanitizing, it passes the username,
1832
+ * raw username (the username in the parameter), and the value of $strict as
1833
+ * parameters for the {@see 'sanitize_user'} filter.
1834
+ *
1835
+ * @since 2.0.0
1836
+ *
1837
+ * @param string $username The username to be sanitized.
1838
+ * @param bool $strict If set limits $username to specific characters. Default false.
1839
+ * @return string The sanitized username, after passing through filters.
1840
+ */
1841
+ function sanitize_user( $username, $strict = false ) {
1842
+ $raw_username = $username;
1843
+ $username = wp_strip_all_tags( $username );
1844
+ $username = remove_accents( $username );
1845
+ // Kill octets
1846
+ $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username );
1847
+ $username = preg_replace( '/&.+?;/', '', $username ); // Kill entities
1848
+
1849
+ // If strict, reduce to ASCII for max portability.
1850
+ if ( $strict )
1851
+ $username = preg_replace( '|[^a-z0-9 _.\-@]|i', '', $username );
1852
+
1853
+ $username = trim( $username );
1854
+ // Consolidate contiguous whitespace
1855
+ $username = preg_replace( '|\s+|', ' ', $username );
1856
+
1857
+ /**
1858
+ * Filters a sanitized username string.
1859
+ *
1860
+ * @since 2.0.1
1861
+ *
1862
+ * @param string $username Sanitized username.
1863
+ * @param string $raw_username The username prior to sanitization.
1864
+ * @param bool $strict Whether to limit the sanitization to specific characters. Default false.
1865
+ */
1866
+ return apply_filters( 'sanitize_user', $username, $raw_username, $strict );
1867
+ }
1868
+
1869
+ /**
1870
+ * Sanitizes a string key.
1871
+ *
1872
+ * Keys are used as internal identifiers. Lowercase alphanumeric characters, dashes and underscores are allowed.
1873
+ *
1874
+ * @since 3.0.0
1875
+ *
1876
+ * @param string $key String key
1877
+ * @return string Sanitized key
1878
+ */
1879
+ function sanitize_key( $key ) {
1880
+ $raw_key = $key;
1881
+ $key = strtolower( $key );
1882
+ $key = preg_replace( '/[^a-z0-9_\-]/', '', $key );
1883
+
1884
+ /**
1885
+ * Filters a sanitized key string.
1886
+ *
1887
+ * @since 3.0.0
1888
+ *
1889
+ * @param string $key Sanitized key.
1890
+ * @param string $raw_key The key prior to sanitization.
1891
+ */
1892
+ return apply_filters( 'sanitize_key', $key, $raw_key );
1893
+ }
1894
+
1895
+ /**
1896
+ * Sanitizes a title, or returns a fallback title.
1897
+ *
1898
+ * Specifically, HTML and PHP tags are stripped. Further actions can be added
1899
+ * via the plugin API. If $title is empty and $fallback_title is set, the latter
1900
+ * will be used.
1901
+ *
1902
+ * @since 1.0.0
1903
+ *
1904
+ * @param string $title The string to be sanitized.
1905
+ * @param string $fallback_title Optional. A title to use if $title is empty.
1906
+ * @param string $context Optional. The operation for which the string is sanitized
1907
+ * @return string The sanitized string.
1908
+ */
1909
+ function sanitize_title( $title, $fallback_title = '', $context = 'save' ) {
1910
+ $raw_title = $title;
1911
+
1912
+ if ( 'save' == $context )
1913
+ $title = remove_accents($title);
1914
+
1915
+ /**
1916
+ * Filters a sanitized title string.
1917
+ *
1918
+ * @since 1.2.0
1919
+ *
1920
+ * @param string $title Sanitized title.
1921
+ * @param string $raw_title The title prior to sanitization.
1922
+ * @param string $context The context for which the title is being sanitized.
1923
+ */
1924
+ $title = apply_filters( 'sanitize_title', $title, $raw_title, $context );
1925
+
1926
+ if ( '' === $title || false === $title )
1927
+ $title = $fallback_title;
1928
+
1929
+ return $title;
1930
+ }
1931
+
1932
+ /**
1933
+ * Sanitizes a title with the 'query' context.
1934
+ *
1935
+ * Used for querying the database for a value from URL.
1936
+ *
1937
+ * @since 3.1.0
1938
+ *
1939
+ * @param string $title The string to be sanitized.
1940
+ * @return string The sanitized string.
1941
+ */
1942
+ function sanitize_title_for_query( $title ) {
1943
+ return sanitize_title( $title, '', 'query' );
1944
+ }
1945
+
1946
+ /**
1947
+ * Sanitizes a title, replacing whitespace and a few other characters with dashes.
1948
+ *
1949
+ * Limits the output to alphanumeric characters, underscore (_) and dash (-).
1950
+ * Whitespace becomes a dash.
1951
+ *
1952
+ * @since 1.2.0
1953
+ *
1954
+ * @param string $title The title to be sanitized.
1955
+ * @param string $raw_title Optional. Not used.
1956
+ * @param string $context Optional. The operation for which the string is sanitized.
1957
+ * @return string The sanitized title.
1958
+ */
1959
+ function sanitize_title_with_dashes( $title, $raw_title = '', $context = 'display' ) {
1960
+ $title = strip_tags($title);
1961
+ // Preserve escaped octets.
1962
+ $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
1963
+ // Remove percent signs that are not part of an octet.
1964
+ $title = str_replace('%', '', $title);
1965
+ // Restore octets.
1966
+ $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
1967
+
1968
+ if (seems_utf8($title)) {
1969
+ if (function_exists('mb_strtolower')) {
1970
+ $title = mb_strtolower($title, 'UTF-8');
1971
+ }
1972
+ $title = utf8_uri_encode($title, 200);
1973
+ }
1974
+
1975
+ $title = strtolower($title);
1976
+
1977
+ if ( 'save' == $context ) {
1978
+ // Convert nbsp, ndash and mdash to hyphens
1979
+ $title = str_replace( array( '%c2%a0', '%e2%80%93', '%e2%80%94' ), '-', $title );
1980
+ // Convert nbsp, ndash and mdash HTML entities to hyphens
1981
+ $title = str_replace( array( '&nbsp;', '&#160;', '&ndash;', '&#8211;', '&mdash;', '&#8212;' ), '-', $title );
1982
+
1983
+ // Strip these characters entirely
1984
+ $title = str_replace( array(
1985
+ // iexcl and iquest
1986
+ '%c2%a1', '%c2%bf',
1987
+ // angle quotes
1988
+ '%c2%ab', '%c2%bb', '%e2%80%b9', '%e2%80%ba',
1989
+ // curly quotes
1990
+ '%e2%80%98', '%e2%80%99', '%e2%80%9c', '%e2%80%9d',
1991
+ '%e2%80%9a', '%e2%80%9b', '%e2%80%9e', '%e2%80%9f',
1992
+ // copy, reg, deg, hellip and trade
1993
+ '%c2%a9', '%c2%ae', '%c2%b0', '%e2%80%a6', '%e2%84%a2',
1994
+ // acute accents
1995
+ '%c2%b4', '%cb%8a', '%cc%81', '%cd%81',
1996
+ // grave accent, macron, caron
1997
+ '%cc%80', '%cc%84', '%cc%8c',
1998
+ ), '', $title );
1999
+
2000
+ // Convert times to x
2001
+ $title = str_replace( '%c3%97', 'x', $title );
2002
+ }
2003
+
2004
+ $title = preg_replace('/&.+?;/', '', $title); // kill entities
2005
+ $title = str_replace('.', '-', $title);
2006
+
2007
+ $title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
2008
+ $title = preg_replace('/\s+/', '-', $title);
2009
+ $title = preg_replace('|-+|', '-', $title);
2010
+ $title = trim($title, '-');
2011
+
2012
+ return $title;
2013
+ }
2014
+
2015
+ /**
2016
+ * Ensures a string is a valid SQL 'order by' clause.
2017
+ *
2018
+ * Accepts one or more columns, with or without a sort order (ASC / DESC).
2019
+ * e.g. 'column_1', 'column_1, column_2', 'column_1 ASC, column_2 DESC' etc.
2020
+ *
2021
+ * Also accepts 'RAND()'.
2022
+ *
2023
+ * @since 2.5.1
2024
+ *
2025
+ * @param string $orderby Order by clause to be validated.
2026
+ * @return string|false Returns $orderby if valid, false otherwise.
2027
+ */
2028
+ function sanitize_sql_orderby( $orderby ) {
2029
+ if ( preg_match( '/^\s*(([a-z0-9_]+|`[a-z0-9_]+`)(\s+(ASC|DESC))?\s*(,\s*(?=[a-z0-9_`])|$))+$/i', $orderby ) || preg_match( '/^\s*RAND\(\s*\)\s*$/i', $orderby ) ) {
2030
+ return $orderby;
2031
+ }
2032
+ return false;
2033
+ }
2034
+
2035
+ /**
2036
+ * Sanitizes an HTML classname to ensure it only contains valid characters.
2037
+ *
2038
+ * Strips the string down to A-Z,a-z,0-9,_,-. If this results in an empty
2039
+ * string then it will return the alternative value supplied.
2040
+ *
2041
+ * @todo Expand to support the full range of CDATA that a class attribute can contain.
2042
+ *
2043
+ * @since 2.8.0
2044
+ *
2045
+ * @param string $class The classname to be sanitized
2046
+ * @param string $fallback Optional. The value to return if the sanitization ends up as an empty string.
2047
+ * Defaults to an empty string.
2048
+ * @return string The sanitized value
2049
+ */
2050
+ function sanitize_html_class( $class, $fallback = '' ) {
2051
+ //Strip out any % encoded octets
2052
+ $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class );
2053
+
2054
+ //Limit to A-Z,a-z,0-9,_,-
2055
+ $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized );
2056
+
2057
+ if ( '' == $sanitized && $fallback ) {
2058
+ return sanitize_html_class( $fallback );
2059
+ }
2060
+ /**
2061
+ * Filters a sanitized HTML class string.
2062
+ *
2063
+ * @since 2.8.0
2064
+ *
2065
+ * @param string $sanitized The sanitized HTML class.
2066
+ * @param string $class HTML class before sanitization.
2067
+ * @param string $fallback The fallback string.
2068
+ */
2069
+ return apply_filters( 'sanitize_html_class', $sanitized, $class, $fallback );
2070
+ }
2071
+
2072
+ /**
2073
+ * Converts lone & characters into `&#038;` (a.k.a. `&amp;`)
2074
+ *
2075
+ * @since 0.71
2076
+ *
2077
+ * @param string $content String of characters to be converted.
2078
+ * @param string $deprecated Not used.
2079
+ * @return string Converted string.
2080
+ */
2081
+ function convert_chars( $content, $deprecated = '' ) {
2082
+ if ( ! empty( $deprecated ) ) {
2083
+ _deprecated_argument( __FUNCTION__, '0.71' );
2084
+ }
2085
+
2086
+ if ( strpos( $content, '&' ) !== false ) {
2087
+ $content = preg_replace( '/&([^#])(?![a-z1-4]{1,8};)/i', '&#038;$1', $content );
2088
+ }
2089
+
2090
+ return $content;
2091
+ }
2092
+
2093
+ /**
2094
+ * Converts invalid Unicode references range to valid range.
2095
+ *
2096
+ * @since 4.3.0
2097
+ *
2098
+ * @param string $content String with entities that need converting.
2099
+ * @return string Converted string.
2100
+ */
2101
+ function convert_invalid_entities( $content ) {
2102
+ $wp_htmltranswinuni = array(
2103
+ '&#128;' => '&#8364;', // the Euro sign
2104
+ '&#129;' => '',
2105
+ '&#130;' => '&#8218;', // these are Windows CP1252 specific characters
2106
+ '&#131;' => '&#402;', // they would look weird on non-Windows browsers
2107
+ '&#132;' => '&#8222;',
2108
+ '&#133;' => '&#8230;',
2109
+ '&#134;' => '&#8224;',
2110
+ '&#135;' => '&#8225;',
2111
+ '&#136;' => '&#710;',
2112
+ '&#137;' => '&#8240;',
2113
+ '&#138;' => '&#352;',
2114
+ '&#139;' => '&#8249;',
2115
+ '&#140;' => '&#338;',
2116
+ '&#141;' => '',
2117
+ '&#142;' => '&#381;',
2118
+ '&#143;' => '',
2119
+ '&#144;' => '',
2120
+ '&#145;' => '&#8216;',
2121
+ '&#146;' => '&#8217;',
2122
+ '&#147;' => '&#8220;',
2123
+ '&#148;' => '&#8221;',
2124
+ '&#149;' => '&#8226;',
2125
+ '&#150;' => '&#8211;',
2126
+ '&#151;' => '&#8212;',
2127
+ '&#152;' => '&#732;',
2128
+ '&#153;' => '&#8482;',
2129
+ '&#154;' => '&#353;',
2130
+ '&#155;' => '&#8250;',
2131
+ '&#156;' => '&#339;',
2132
+ '&#157;' => '',
2133
+ '&#158;' => '&#382;',
2134
+ '&#159;' => '&#376;'
2135
+ );
2136
+
2137
+ if ( strpos( $content, '&#1' ) !== false ) {
2138
+ $content = strtr( $content, $wp_htmltranswinuni );
2139
+ }
2140
+
2141
+ return $content;
2142
+ }
2143
+
2144
+ /**
2145
+ * Balances tags if forced to, or if the 'use_balanceTags' option is set to true.
2146
+ *
2147
+ * @since 0.71
2148
+ *
2149
+ * @param string $text Text to be balanced
2150
+ * @param bool $force If true, forces balancing, ignoring the value of the option. Default false.
2151
+ * @return string Balanced text
2152
+ */
2153
+ function balanceTags( $text, $force = false ) {
2154
+ if ( $force || get_option('use_balanceTags') == 1 ) {
2155
+ return force_balance_tags( $text );
2156
+ } else {
2157
+ return $text;
2158
+ }
2159
+ }
2160
+
2161
+ /**
2162
+ * Balances tags of string using a modified stack.
2163
+ *
2164
+ * @since 2.0.4
2165
+ *
2166
+ * @author Leonard Lin <leonard@acm.org>
2167
+ * @license GPL
2168
+ * @copyright November 4, 2001
2169
+ * @version 1.1
2170
+ * @todo Make better - change loop condition to $text in 1.2
2171
+ * @internal Modified by Scott Reilly (coffee2code) 02 Aug 2004
2172
+ * 1.1 Fixed handling of append/stack pop order of end text
2173
+ * Added Cleaning Hooks
2174
+ * 1.0 First Version
2175
+ *
2176
+ * @param string $text Text to be balanced.
2177
+ * @return string Balanced text.
2178
+ */
2179
+ function force_balance_tags( $text ) {
2180
+ $tagstack = array();
2181
+ $stacksize = 0;
2182
+ $tagqueue = '';
2183
+ $newtext = '';
2184
+ // Known single-entity/self-closing tags
2185
+ $single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source' );
2186
+ // Tags that can be immediately nested within themselves
2187
+ $nestable_tags = array( 'blockquote', 'div', 'object', 'q', 'span' );
2188
+
2189
+ // WP bug fix for comments - in case you REALLY meant to type '< !--'
2190
+ $text = str_replace('< !--', '< !--', $text);
2191
+ // WP bug fix for LOVE <3 (and other situations with '<' before a number)
2192
+ $text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
2193
+
2194
+ while ( preg_match("/<(\/?[\w:]*)\s*([^>]*)>/", $text, $regex) ) {
2195
+ $newtext .= $tagqueue;
2196
+
2197
+ $i = strpos($text, $regex[0]);
2198
+ $l = strlen($regex[0]);
2199
+
2200
+ // clear the shifter
2201
+ $tagqueue = '';
2202
+ // Pop or Push
2203
+ if ( isset($regex[1][0]) && '/' == $regex[1][0] ) { // End Tag
2204
+ $tag = strtolower(substr($regex[1],1));
2205
+ // if too many closing tags
2206
+ if ( $stacksize <= 0 ) {
2207
+ $tag = '';
2208
+ // or close to be safe $tag = '/' . $tag;
2209
+ }
2210
+ // if stacktop value = tag close value then pop
2211
+ elseif ( $tagstack[$stacksize - 1] == $tag ) { // found closing tag
2212
+ $tag = '</' . $tag . '>'; // Close Tag
2213
+ // Pop
2214
+ array_pop( $tagstack );
2215
+ $stacksize--;
2216
+ } else { // closing tag not at top, search for it
2217
+ for ( $j = $stacksize-1; $j >= 0; $j-- ) {
2218
+ if ( $tagstack[$j] == $tag ) {
2219
+ // add tag to tagqueue
2220
+ for ( $k = $stacksize-1; $k >= $j; $k--) {
2221
+ $tagqueue .= '</' . array_pop( $tagstack ) . '>';
2222
+ $stacksize--;
2223
+ }
2224
+ break;
2225
+ }
2226
+ }
2227
+ $tag = '';
2228
+ }
2229
+ } else { // Begin Tag
2230
+ $tag = strtolower($regex[1]);
2231
+
2232
+ // Tag Cleaning
2233
+
2234
+ // If it's an empty tag "< >", do nothing
2235
+ if ( '' == $tag ) {
2236
+ // do nothing
2237
+ }
2238
+ // ElseIf it presents itself as a self-closing tag...
2239
+ elseif ( substr( $regex[2], -1 ) == '/' ) {
2240
+ // ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and
2241
+ // immediately close it with a closing tag (the tag will encapsulate no text as a result)
2242
+ if ( ! in_array( $tag, $single_tags ) )
2243
+ $regex[2] = trim( substr( $regex[2], 0, -1 ) ) . "></$tag";
2244
+ }
2245
+ // ElseIf it's a known single-entity tag but it doesn't close itself, do so
2246
+ elseif ( in_array($tag, $single_tags) ) {
2247
+ $regex[2] .= '/';
2248
+ }
2249
+ // Else it's not a single-entity tag
2250
+ else {
2251
+ // If the top of the stack is the same as the tag we want to push, close previous tag
2252
+ if ( $stacksize > 0 && !in_array($tag, $nestable_tags) && $tagstack[$stacksize - 1] == $tag ) {
2253
+ $tagqueue = '</' . array_pop( $tagstack ) . '>';
2254
+ $stacksize--;
2255
+ }
2256
+ $stacksize = array_push( $tagstack, $tag );
2257
+ }
2258
+
2259
+ // Attributes
2260
+ $attributes = $regex[2];
2261
+ if ( ! empty( $attributes ) && $attributes[0] != '>' )
2262
+ $attributes = ' ' . $attributes;
2263
+
2264
+ $tag = '<' . $tag . $attributes . '>';
2265
+ //If already queuing a close tag, then put this tag on, too
2266
+ if ( !empty($tagqueue) ) {
2267
+ $tagqueue .= $tag;
2268
+ $tag = '';
2269
+ }
2270
+ }
2271
+ $newtext .= substr($text, 0, $i) . $tag;
2272
+ $text = substr($text, $i + $l);
2273
+ }
2274
+
2275
+ // Clear Tag Queue
2276
+ $newtext .= $tagqueue;
2277
+
2278
+ // Add Remaining text
2279
+ $newtext .= $text;
2280
+
2281
+ // Empty Stack
2282
+ while( $x = array_pop($tagstack) )
2283
+ $newtext .= '</' . $x . '>'; // Add remaining tags to close
2284
+
2285
+ // WP fix for the bug with HTML comments
2286
+ $newtext = str_replace("< !--","<!--",$newtext);
2287
+ $newtext = str_replace("< !--","< !--",$newtext);
2288
+
2289
+ return $newtext;
2290
+ }
2291
+
2292
+ /**
2293
+ * Acts on text which is about to be edited.
2294
+ *
2295
+ * The $content is run through esc_textarea(), which uses htmlspecialchars()
2296
+ * to convert special characters to HTML entities. If `$richedit` is set to true,
2297
+ * it is simply a holder for the {@see 'format_to_edit'} filter.
2298
+ *
2299
+ * @since 0.71
2300
+ * @since 4.4.0 The `$richedit` parameter was renamed to `$rich_text` for clarity.
2301
+ *
2302
+ * @param string $content The text about to be edited.
2303
+ * @param bool $rich_text Optional. Whether `$content` should be considered rich text,
2304
+ * in which case it would not be passed through esc_textarea().
2305
+ * Default false.
2306
+ * @return string The text after the filter (and possibly htmlspecialchars()) has been run.
2307
+ */
2308
+ function format_to_edit( $content, $rich_text = false ) {
2309
+ /**
2310
+ * Filters the text to be formatted for editing.
2311
+ *
2312
+ * @since 1.2.0
2313
+ *
2314
+ * @param string $content The text, prior to formatting for editing.
2315
+ */
2316
+ $content = apply_filters( 'format_to_edit', $content );
2317
+ if ( ! $rich_text )
2318
+ $content = esc_textarea( $content );
2319
+ return $content;
2320
+ }
2321
+
2322
+ /**
2323
+ * Add leading zeros when necessary.
2324
+ *
2325
+ * If you set the threshold to '4' and the number is '10', then you will get
2326
+ * back '0010'. If you set the threshold to '4' and the number is '5000', then you
2327
+ * will get back '5000'.
2328
+ *
2329
+ * Uses sprintf to append the amount of zeros based on the $threshold parameter
2330
+ * and the size of the number. If the number is large enough, then no zeros will
2331
+ * be appended.
2332
+ *
2333
+ * @since 0.71
2334
+ *
2335
+ * @param int $number Number to append zeros to if not greater than threshold.
2336
+ * @param int $threshold Digit places number needs to be to not have zeros added.
2337
+ * @return string Adds leading zeros to number if needed.
2338
+ */
2339
+ function zeroise( $number, $threshold ) {
2340
+ return sprintf( '%0' . $threshold . 's', $number );
2341
+ }
2342
+
2343
+ /**
2344
+ * Adds backslashes before letters and before a number at the start of a string.
2345
+ *
2346
+ * @since 0.71
2347
+ *
2348
+ * @param string $string Value to which backslashes will be added.
2349
+ * @return string String with backslashes inserted.
2350
+ */
2351
+ function backslashit( $string ) {
2352
+ if ( isset( $string[0] ) && $string[0] >= '0' && $string[0] <= '9' )
2353
+ $string = '\\\\' . $string;
2354
+ return addcslashes( $string, 'A..Za..z' );
2355
+ }
2356
+
2357
+ /**
2358
+ * Appends a trailing slash.
2359
+ *
2360
+ * Will remove trailing forward and backslashes if it exists already before adding
2361
+ * a trailing forward slash. This prevents double slashing a string or path.
2362
+ *
2363
+ * The primary use of this is for paths and thus should be used for paths. It is
2364
+ * not restricted to paths and offers no specific path support.
2365
+ *
2366
+ * @since 1.2.0
2367
+ *
2368
+ * @param string $string What to add the trailing slash to.
2369
+ * @return string String with trailing slash added.
2370
+ */
2371
+ function trailingslashit( $string ) {
2372
+ return untrailingslashit( $string ) . '/';
2373
+ }
2374
+
2375
+ /**
2376
+ * Removes trailing forward slashes and backslashes if they exist.
2377
+ *
2378
+ * The primary use of this is for paths and thus should be used for paths. It is
2379
+ * not restricted to paths and offers no specific path support.
2380
+ *
2381
+ * @since 2.2.0
2382
+ *
2383
+ * @param string $string What to remove the trailing slashes from.
2384
+ * @return string String without the trailing slashes.
2385
+ */
2386
+ function untrailingslashit( $string ) {
2387
+ return rtrim( $string, '/\\' );
2388
+ }
2389
+
2390
+ /**
2391
+ * Adds slashes to escape strings.
2392
+ *
2393
+ * Slashes will first be removed if magic_quotes_gpc is set, see {@link
2394
+ * https://secure.php.net/magic_quotes} for more details.
2395
+ *
2396
+ * @since 0.71
2397
+ *
2398
+ * @param string $gpc The string returned from HTTP request data.
2399
+ * @return string Returns a string escaped with slashes.
2400
+ */
2401
+ function addslashes_gpc($gpc) {
2402
+ if ( get_magic_quotes_gpc() )
2403
+ $gpc = stripslashes($gpc);
2404
+
2405
+ return wp_slash($gpc);
2406
+ }
2407
+
2408
+ /**
2409
+ * Navigates through an array, object, or scalar, and removes slashes from the values.
2410
+ *
2411
+ * @since 2.0.0
2412
+ *
2413
+ * @param mixed $value The value to be stripped.
2414
+ * @return mixed Stripped value.
2415
+ */
2416
+ function stripslashes_deep( $value ) {
2417
+ return map_deep( $value, 'stripslashes_from_strings_only' );
2418
+ }
2419
+
2420
+ /**
2421
+ * Callback function for `stripslashes_deep()` which strips slashes from strings.
2422
+ *
2423
+ * @since 4.4.0
2424
+ *
2425
+ * @param mixed $value The array or string to be stripped.
2426
+ * @return mixed $value The stripped value.
2427
+ */
2428
+ function stripslashes_from_strings_only( $value ) {
2429
+ return is_string( $value ) ? stripslashes( $value ) : $value;
2430
+ }
2431
+
2432
+ /**
2433
+ * Navigates through an array, object, or scalar, and encodes the values to be used in a URL.
2434
+ *
2435
+ * @since 2.2.0
2436
+ *
2437
+ * @param mixed $value The array or string to be encoded.
2438
+ * @return mixed $value The encoded value.
2439
+ */
2440
+ function urlencode_deep( $value ) {
2441
+ return map_deep( $value, 'urlencode' );
2442
+ }
2443
+
2444
+ /**
2445
+ * Navigates through an array, object, or scalar, and raw-encodes the values to be used in a URL.
2446
+ *
2447
+ * @since 3.4.0
2448
+ *
2449
+ * @param mixed $value The array or string to be encoded.
2450
+ * @return mixed $value The encoded value.
2451
+ */
2452
+ function rawurlencode_deep( $value ) {
2453
+ return map_deep( $value, 'rawurlencode' );
2454
+ }
2455
+
2456
+ /**
2457
+ * Navigates through an array, object, or scalar, and decodes URL-encoded values
2458
+ *
2459
+ * @since 4.4.0
2460
+ *
2461
+ * @param mixed $value The array or string to be decoded.
2462
+ * @return mixed $value The decoded value.
2463
+ */
2464
+ function urldecode_deep( $value ) {
2465
+ return map_deep( $value, 'urldecode' );
2466
+ }
2467
+
2468
+ /**
2469
+ * Converts email addresses characters to HTML entities to block spam bots.
2470
+ *
2471
+ * @since 0.71
2472
+ *
2473
+ * @param string $email_address Email address.
2474
+ * @param int $hex_encoding Optional. Set to 1 to enable hex encoding.
2475
+ * @return string Converted email address.
2476
+ */
2477
+ function antispambot( $email_address, $hex_encoding = 0 ) {
2478
+ $email_no_spam_address = '';
2479
+ for ( $i = 0, $len = strlen( $email_address ); $i < $len; $i++ ) {
2480
+ $j = rand( 0, 1 + $hex_encoding );
2481
+ if ( $j == 0 ) {
2482
+ $email_no_spam_address .= '&#' . ord( $email_address[$i] ) . ';';
2483
+ } elseif ( $j == 1 ) {
2484
+ $email_no_spam_address .= $email_address[$i];
2485
+ } elseif ( $j == 2 ) {
2486
+ $email_no_spam_address .= '%' . zeroise( dechex( ord( $email_address[$i] ) ), 2 );
2487
+ }
2488
+ }
2489
+
2490
+ return str_replace( '@', '&#64;', $email_no_spam_address );
2491
+ }
2492
+
2493
+ /**
2494
+ * Callback to convert URI match to HTML A element.
2495
+ *
2496
+ * This function was backported from 2.5.0 to 2.3.2. Regex callback for make_clickable().
2497
+ *
2498
+ * @since 2.3.2
2499
+ * @access private
2500
+ *
2501
+ * @param array $matches Single Regex Match.
2502
+ * @return string HTML A element with URI address.
2503
+ */
2504
+ function _make_url_clickable_cb( $matches ) {
2505
+ $url = $matches[2];
2506
+
2507
+ if ( ')' == $matches[3] && strpos( $url, '(' ) ) {
2508
+ // If the trailing character is a closing parethesis, and the URL has an opening parenthesis in it, add the closing parenthesis to the URL.
2509
+ // Then we can let the parenthesis balancer do its thing below.
2510
+ $url .= $matches[3];
2511
+ $suffix = '';
2512
+ } else {
2513
+ $suffix = $matches[3];
2514
+ }
2515
+
2516
+ // Include parentheses in the URL only if paired
2517
+ while ( substr_count( $url, '(' ) < substr_count( $url, ')' ) ) {
2518
+ $suffix = strrchr( $url, ')' ) . $suffix;
2519
+ $url = substr( $url, 0, strrpos( $url, ')' ) );
2520
+ }
2521
+
2522
+ $url = esc_url($url);
2523
+ if ( empty($url) )
2524
+ return $matches[0];
2525
+
2526
+ return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $suffix;
2527
+ }
2528
+
2529
+ /**
2530
+ * Callback to convert URL match to HTML A element.
2531
+ *
2532
+ * This function was backported from 2.5.0 to 2.3.2. Regex callback for make_clickable().
2533
+ *
2534
+ * @since 2.3.2
2535
+ * @access private
2536
+ *
2537
+ * @param array $matches Single Regex Match.
2538
+ * @return string HTML A element with URL address.
2539
+ */
2540
+ function _make_web_ftp_clickable_cb( $matches ) {
2541
+ $ret = '';
2542
+ $dest = $matches[2];
2543
+ $dest = 'http://' . $dest;
2544
+
2545
+ // removed trailing [.,;:)] from URL
2546
+ if ( in_array( substr($dest, -1), array('.', ',', ';', ':', ')') ) === true ) {
2547
+ $ret = substr($dest, -1);
2548
+ $dest = substr($dest, 0, strlen($dest)-1);
2549
+ }
2550
+
2551
+ $dest = esc_url($dest);
2552
+ if ( empty($dest) )
2553
+ return $matches[0];
2554
+
2555
+ return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>$ret";
2556
+ }
2557
+
2558
+ /**
2559
+ * Callback to convert email address match to HTML A element.
2560
+ *
2561
+ * This function was backported from 2.5.0 to 2.3.2. Regex callback for make_clickable().
2562
+ *
2563
+ * @since 2.3.2
2564
+ * @access private
2565
+ *
2566
+ * @param array $matches Single Regex Match.
2567
+ * @return string HTML A element with email address.
2568
+ */
2569
+ function _make_email_clickable_cb( $matches ) {
2570
+ $email = $matches[2] . '@' . $matches[3];
2571
+ return $matches[1] . "<a href=\"mailto:$email\">$email</a>";
2572
+ }
2573
+
2574
+ /**
2575
+ * Convert plaintext URI to HTML links.
2576
+ *
2577
+ * Converts URI, www and ftp, and email addresses. Finishes by fixing links
2578
+ * within links.
2579
+ *
2580
+ * @since 0.71
2581
+ *
2582
+ * @param string $text Content to convert URIs.
2583
+ * @return string Content with converted URIs.
2584
+ */
2585
+ function make_clickable( $text ) {
2586
+ $r = '';
2587
+ $textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags
2588
+ $nested_code_pre = 0; // Keep track of how many levels link is nested inside <pre> or <code>
2589
+ foreach ( $textarr as $piece ) {
2590
+
2591
+ if ( preg_match( '|^<code[\s>]|i', $piece ) || preg_match( '|^<pre[\s>]|i', $piece ) || preg_match( '|^<script[\s>]|i', $piece ) || preg_match( '|^<style[\s>]|i', $piece ) )
2592
+ $nested_code_pre++;
2593
+ elseif ( $nested_code_pre && ( '</code>' === strtolower( $piece ) || '</pre>' === strtolower( $piece ) || '</script>' === strtolower( $piece ) || '</style>' === strtolower( $piece ) ) )
2594
+ $nested_code_pre--;
2595
+
2596
+ if ( $nested_code_pre || empty( $piece ) || ( $piece[0] === '<' && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) ) ) {
2597
+ $r .= $piece;
2598
+ continue;
2599
+ }
2600
+
2601
+ // Long strings might contain expensive edge cases ...
2602
+ if ( 10000 < strlen( $piece ) ) {
2603
+ // ... break it up
2604
+ foreach ( _split_str_by_whitespace( $piece, 2100 ) as $chunk ) { // 2100: Extra room for scheme and leading and trailing paretheses
2605
+ if ( 2101 < strlen( $chunk ) ) {
2606
+ $r .= $chunk; // Too big, no whitespace: bail.
2607
+ } else {
2608
+ $r .= make_clickable( $chunk );
2609
+ }
2610
+ }
2611
+ } else {
2612
+ $ret = " $piece "; // Pad with whitespace to simplify the regexes
2613
+
2614
+ $url_clickable = '~
2615
+ ([\\s(<.,;:!?]) # 1: Leading whitespace, or punctuation
2616
+ ( # 2: URL
2617
+ [\\w]{1,20}+:// # Scheme and hier-part prefix
2618
+ (?=\S{1,2000}\s) # Limit to URLs less than about 2000 characters long
2619
+ [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+ # Non-punctuation URL character
2620
+ (?: # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character
2621
+ [\'.,;:!?)] # Punctuation URL character
2622
+ [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character
2623
+ )*
2624
+ )
2625
+ (\)?) # 3: Trailing closing parenthesis (for parethesis balancing post processing)
2626
+ ~xS'; // The regex is a non-anchored pattern and does not have a single fixed starting character.
2627
+ // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
2628
+
2629
+ $ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret );
2630
+
2631
+ $ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret );
2632
+ $ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret );
2633
+
2634
+ $ret = substr( $ret, 1, -1 ); // Remove our whitespace padding.
2635
+ $r .= $ret;
2636
+ }
2637
+ }
2638
+
2639
+ // Cleanup of accidental links within links
2640
+ return preg_replace( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $r );
2641
+ }
2642
+
2643
+ /**
2644
+ * Breaks a string into chunks by splitting at whitespace characters.
2645
+ * The length of each returned chunk is as close to the specified length goal as possible,
2646
+ * with the caveat that each chunk includes its trailing delimiter.
2647
+ * Chunks longer than the goal are guaranteed to not have any inner whitespace.
2648
+ *
2649
+ * Joining the returned chunks with empty delimiters reconstructs the input string losslessly.
2650
+ *
2651
+ * Input string must have no null characters (or eventual transformations on output chunks must not care about null characters)
2652
+ *
2653
+ * _split_str_by_whitespace( "1234 67890 1234 67890a cd 1234 890 123456789 1234567890a 45678 1 3 5 7 90 ", 10 ) ==
2654
+ * array (
2655
+ * 0 => '1234 67890 ', // 11 characters: Perfect split
2656
+ * 1 => '1234 ', // 5 characters: '1234 67890a' was too long
2657
+ * 2 => '67890a cd ', // 10 characters: '67890a cd 1234' was too long
2658
+ * 3 => '1234 890 ', // 11 characters: Perfect split
2659
+ * 4 => '123456789 ', // 10 characters: '123456789 1234567890a' was too long
2660
+ * 5 => '1234567890a ', // 12 characters: Too long, but no inner whitespace on which to split
2661
+ * 6 => ' 45678 ', // 11 characters: Perfect split
2662
+ * 7 => '1 3 5 7 90 ', // 11 characters: End of $string
2663
+ * );
2664
+ *
2665
+ * @since 3.4.0
2666
+ * @access private
2667
+ *
2668
+ * @param string $string The string to split.
2669
+ * @param int $goal The desired chunk length.
2670
+ * @return array Numeric array of chunks.
2671
+ */
2672
+ function _split_str_by_whitespace( $string, $goal ) {
2673
+ $chunks = array();
2674
+
2675
+ $string_nullspace = strtr( $string, "\r\n\t\v\f ", "\000\000\000\000\000\000" );
2676
+
2677
+ while ( $goal < strlen( $string_nullspace ) ) {
2678
+ $pos = strrpos( substr( $string_nullspace, 0, $goal + 1 ), "\000" );
2679
+
2680
+ if ( false === $pos ) {
2681
+ $pos = strpos( $string_nullspace, "\000", $goal + 1 );
2682
+ if ( false === $pos ) {
2683
+ break;
2684
+ }
2685
+ }
2686
+
2687
+ $chunks[] = substr( $string, 0, $pos + 1 );
2688
+ $string = substr( $string, $pos + 1 );
2689
+ $string_nullspace = substr( $string_nullspace, $pos + 1 );
2690
+ }
2691
+
2692
+ if ( $string ) {
2693
+ $chunks[] = $string;
2694
+ }
2695
+
2696
+ return $chunks;
2697
+ }
2698
+
2699
+ /**
2700
+ * Adds rel nofollow string to all HTML A elements in content.
2701
+ *
2702
+ * @since 1.5.0
2703
+ *
2704
+ * @param string $text Content that may contain HTML A elements.
2705
+ * @return string Converted content.
2706
+ */
2707
+ function wp_rel_nofollow( $text ) {
2708
+ // This is a pre save filter, so text is already escaped.
2709
+ $text = stripslashes($text);
2710
+ $text = preg_replace_callback('|<a (.+?)>|i', 'wp_rel_nofollow_callback', $text);
2711
+ return wp_slash( $text );
2712
+ }
2713
+
2714
+ /**
2715
+ * Callback to add rel=nofollow string to HTML A element.
2716
+ *
2717
+ * Will remove already existing rel="nofollow" and rel='nofollow' from the
2718
+ * string to prevent from invalidating (X)HTML.
2719
+ *
2720
+ * @since 2.3.0
2721
+ *
2722
+ * @param array $matches Single Match
2723
+ * @return string HTML A Element with rel nofollow.
2724
+ */
2725
+ function wp_rel_nofollow_callback( $matches ) {
2726
+ $text = $matches[1];
2727
+ $atts = shortcode_parse_atts( $matches[1] );
2728
+ $rel = 'nofollow';
2729
+
2730
+ if ( preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'http' ) ) . ')%i', $text ) ||
2731
+ preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'https' ) ) . ')%i', $text )
2732
+ ) {
2733
+ return "<a $text>";
2734
+ }
2735
+
2736
+ if ( ! empty( $atts['rel'] ) ) {
2737
+ $parts = array_map( 'trim', explode( ' ', $atts['rel'] ) );
2738
+ if ( false === array_search( 'nofollow', $parts ) ) {
2739
+ $parts[] = 'nofollow';
2740
+ }
2741
+ $rel = implode( ' ', $parts );
2742
+ unset( $atts['rel'] );
2743
+
2744
+ $html = '';
2745
+ foreach ( $atts as $name => $value ) {
2746
+ $html .= "{$name}=\"$value\" ";
2747
+ }
2748
+ $text = trim( $html );
2749
+ }
2750
+ return "<a $text rel=\"$rel\">";
2751
+ }
2752
+
2753
+ /**
2754
+ * Convert one smiley code to the icon graphic file equivalent.
2755
+ *
2756
+ * Callback handler for convert_smilies().
2757
+ *
2758
+ * Looks up one smiley code in the $wpsmiliestrans global array and returns an
2759
+ * `<img>` string for that smiley.
2760
+ *
2761
+ * @since 2.8.0
2762
+ *
2763
+ * @global array $wpsmiliestrans
2764
+ *
2765
+ * @param array $matches Single match. Smiley code to convert to image.
2766
+ * @return string Image string for smiley.
2767
+ */
2768
+ function translate_smiley( $matches ) {
2769
+ global $wpsmiliestrans;
2770
+
2771
+ if ( count( $matches ) == 0 )
2772
+ return '';
2773
+
2774
+ $smiley = trim( reset( $matches ) );
2775
+ $img = $wpsmiliestrans[ $smiley ];
2776
+
2777
+ $matches = array();
2778
+ $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
2779
+ $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
2780
+
2781
+ // Don't convert smilies that aren't images - they're probably emoji.
2782
+ if ( ! in_array( $ext, $image_exts ) ) {
2783
+ return $img;
2784
+ }
2785
+
2786
+ /**
2787
+ * Filters the Smiley image URL before it's used in the image element.
2788
+ *
2789
+ * @since 2.9.0
2790
+ *
2791
+ * @param string $smiley_url URL for the smiley image.
2792
+ * @param string $img Filename for the smiley image.
2793
+ * @param string $site_url Site URL, as returned by site_url().
2794
+ */
2795
+ $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() );
2796
+
2797
+ return sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', esc_url( $src_url ), esc_attr( $smiley ) );
2798
+ }
2799
+
2800
+ /**
2801
+ * Convert text equivalent of smilies to images.
2802
+ *
2803
+ * Will only convert smilies if the option 'use_smilies' is true and the global
2804
+ * used in the function isn't empty.
2805
+ *
2806
+ * @since 0.71
2807
+ *
2808
+ * @global string|array $wp_smiliessearch
2809
+ *
2810
+ * @param string $text Content to convert smilies from text.
2811
+ * @return string Converted content with text smilies replaced with images.
2812
+ */
2813
+ function convert_smilies( $text ) {
2814
+ global $wp_smiliessearch;
2815
+ $output = '';
2816
+ if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) {
2817
+ // HTML loop taken from texturize function, could possible be consolidated
2818
+ $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between
2819
+ $stop = count( $textarr );// loop stuff
2820
+
2821
+ // Ignore proessing of specific tags
2822
+ $tags_to_ignore = 'code|pre|style|script|textarea';
2823
+ $ignore_block_element = '';
2824
+
2825
+ for ( $i = 0; $i < $stop; $i++ ) {
2826
+ $content = $textarr[$i];
2827
+
2828
+ // If we're in an ignore block, wait until we find its closing tag
2829
+ if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
2830
+ $ignore_block_element = $matches[1];
2831
+ }
2832
+
2833
+ // If it's not a tag and not in ignore block
2834
+ if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) {
2835
+ $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley', $content );
2836
+ }
2837
+
2838
+ // did we exit ignore block
2839
+ if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) {
2840
+ $ignore_block_element = '';
2841
+ }
2842
+
2843
+ $output .= $content;
2844
+ }
2845
+ } else {
2846
+ // return default text.
2847
+ $output = $text;
2848
+ }
2849
+ return $output;
2850
+ }
2851
+
2852
+ /**
2853
+ * Verifies that an email is valid.
2854
+ *
2855
+ * Does not grok i18n domains. Not RFC compliant.
2856
+ *
2857
+ * @since 0.71
2858
+ *
2859
+ * @param string $email Email address to verify.
2860
+ * @param bool $deprecated Deprecated.
2861
+ * @return string|bool Either false or the valid email address.
2862
+ */
2863
+ function is_email( $email, $deprecated = false ) {
2864
+ if ( ! empty( $deprecated ) )
2865
+ _deprecated_argument( __FUNCTION__, '3.0.0' );
2866
+
2867
+ // Test for the minimum length the email can be
2868
+ if ( strlen( $email ) < 3 ) {
2869
+ /**
2870
+ * Filters whether an email address is valid.
2871
+ *
2872
+ * This filter is evaluated under several different contexts, such as 'email_too_short',
2873
+ * 'email_no_at', 'local_invalid_chars', 'domain_period_sequence', 'domain_period_limits',
2874
+ * 'domain_no_periods', 'sub_hyphen_limits', 'sub_invalid_chars', or no specific context.
2875
+ *
2876
+ * @since 2.8.0
2877
+ *
2878
+ * @param bool $is_email Whether the email address has passed the is_email() checks. Default false.
2879
+ * @param string $email The email address being checked.
2880
+ * @param string $context Context under which the email was tested.
2881
+ */
2882
+ return apply_filters( 'is_email', false, $email, 'email_too_short' );
2883
+ }
2884
+
2885
+ // Test for an @ character after the first position
2886
+ if ( strpos( $email, '@', 1 ) === false ) {
2887
+ /** This filter is documented in wp-includes/formatting.php */
2888
+ return apply_filters( 'is_email', false, $email, 'email_no_at' );
2889
+ }
2890
+
2891
+ // Split out the local and domain parts
2892
+ list( $local, $domain ) = explode( '@', $email, 2 );
2893
+
2894
+ // LOCAL PART
2895
+ // Test for invalid characters
2896
+ if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
2897
+ /** This filter is documented in wp-includes/formatting.php */
2898
+ return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
2899
+ }
2900
+
2901
+ // DOMAIN PART
2902
+ // Test for sequences of periods
2903
+ if ( preg_match( '/\.{2,}/', $domain ) ) {
2904
+ /** This filter is documented in wp-includes/formatting.php */
2905
+ return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
2906
+ }
2907
+
2908
+ // Test for leading and trailing periods and whitespace
2909
+ if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
2910
+ /** This filter is documented in wp-includes/formatting.php */
2911
+ return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
2912
+ }
2913
+
2914
+ // Split the domain into subs
2915
+ $subs = explode( '.', $domain );
2916
+
2917
+ // Assume the domain will have at least two subs
2918
+ if ( 2 > count( $subs ) ) {
2919
+ /** This filter is documented in wp-includes/formatting.php */
2920
+ return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
2921
+ }
2922
+
2923
+ // Loop through each sub
2924
+ foreach ( $subs as $sub ) {
2925
+ // Test for leading and trailing hyphens and whitespace
2926
+ if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
2927
+ /** This filter is documented in wp-includes/formatting.php */
2928
+ return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
2929
+ }
2930
+
2931
+ // Test for invalid characters
2932
+ if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
2933
+ /** This filter is documented in wp-includes/formatting.php */
2934
+ return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
2935
+ }
2936
+ }
2937
+
2938
+ // Congratulations your email made it!
2939
+ /** This filter is documented in wp-includes/formatting.php */
2940
+ return apply_filters( 'is_email', $email, $email, null );
2941
+ }
2942
+
2943
+ /**
2944
+ * Convert to ASCII from email subjects.
2945
+ *
2946
+ * @since 1.2.0
2947
+ *
2948
+ * @param string $string Subject line
2949
+ * @return string Converted string to ASCII
2950
+ */
2951
+ function wp_iso_descrambler( $string ) {
2952
+ /* this may only work with iso-8859-1, I'm afraid */
2953
+ if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) {
2954
+ return $string;
2955
+ } else {
2956
+ $subject = str_replace('_', ' ', $matches[2]);
2957
+ return preg_replace_callback( '#\=([0-9a-f]{2})#i', '_wp_iso_convert', $subject );
2958
+ }
2959
+ }
2960
+
2961
+ /**
2962
+ * Helper function to convert hex encoded chars to ASCII
2963
+ *
2964
+ * @since 3.1.0
2965
+ * @access private
2966
+ *
2967
+ * @param array $match The preg_replace_callback matches array
2968
+ * @return string Converted chars
2969
+ */
2970
+ function _wp_iso_convert( $match ) {
2971
+ return chr( hexdec( strtolower( $match[1] ) ) );
2972
+ }
2973
+
2974
+ /**
2975
+ * Returns a date in the GMT equivalent.
2976
+ *
2977
+ * Requires and returns a date in the Y-m-d H:i:s format. If there is a
2978
+ * timezone_string available, the date is assumed to be in that timezone,
2979
+ * otherwise it simply subtracts the value of the 'gmt_offset' option. Return
2980
+ * format can be overridden using the $format parameter.
2981
+ *
2982
+ * @since 1.2.0
2983
+ *
2984
+ * @param string $string The date to be converted.
2985
+ * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
2986
+ * @return string GMT version of the date provided.
2987
+ */
2988
+ function get_gmt_from_date( $string, $format = 'Y-m-d H:i:s' ) {
2989
+ $tz = get_option( 'timezone_string' );
2990
+ if ( $tz ) {
2991
+ $datetime = date_create( $string, new DateTimeZone( $tz ) );
2992
+ if ( ! $datetime ) {
2993
+ return gmdate( $format, 0 );
2994
+ }
2995
+ $datetime->setTimezone( new DateTimeZone( 'UTC' ) );
2996
+ $string_gmt = $datetime->format( $format );
2997
+ } else {
2998
+ if ( ! preg_match( '#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches ) ) {
2999
+ $datetime = strtotime( $string );
3000
+ if ( false === $datetime ) {
3001
+ return gmdate( $format, 0 );
3002
+ }
3003
+ return gmdate( $format, $datetime );
3004
+ }
3005
+ $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
3006
+ $string_gmt = gmdate( $format, $string_time - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
3007
+ }
3008
+ return $string_gmt;
3009
+ }
3010
+
3011
+ /**
3012
+ * Converts a GMT date into the correct format for the blog.
3013
+ *
3014
+ * Requires and returns a date in the Y-m-d H:i:s format. If there is a
3015
+ * timezone_string available, the returned date is in that timezone, otherwise
3016
+ * it simply adds the value of gmt_offset. Return format can be overridden
3017
+ * using the $format parameter
3018
+ *
3019
+ * @since 1.2.0
3020
+ *
3021
+ * @param string $string The date to be converted.
3022
+ * @param string $format The format string for the returned date (default is Y-m-d H:i:s)
3023
+ * @return string Formatted date relative to the timezone / GMT offset.
3024
+ */
3025
+ function get_date_from_gmt( $string, $format = 'Y-m-d H:i:s' ) {
3026
+ $tz = get_option( 'timezone_string' );
3027
+ if ( $tz ) {
3028
+ $datetime = date_create( $string, new DateTimeZone( 'UTC' ) );
3029
+ if ( ! $datetime )
3030
+ return date( $format, 0 );
3031
+ $datetime->setTimezone( new DateTimeZone( $tz ) );
3032
+ $string_localtime = $datetime->format( $format );
3033
+ } else {
3034
+ if ( ! preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches) )
3035
+ return date( $format, 0 );
3036
+ $string_time = gmmktime( $matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1] );
3037
+ $string_localtime = gmdate( $format, $string_time + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
3038
+ }
3039
+ return $string_localtime;
3040
+ }
3041
+
3042
+ /**
3043
+ * Computes an offset in seconds from an iso8601 timezone.
3044
+ *
3045
+ * @since 1.5.0
3046
+ *
3047
+ * @param string $timezone Either 'Z' for 0 offset or '±hhmm'.
3048
+ * @return int|float The offset in seconds.
3049
+ */
3050
+ function iso8601_timezone_to_offset( $timezone ) {
3051
+ // $timezone is either 'Z' or '[+|-]hhmm'
3052
+ if ($timezone == 'Z') {
3053
+ $offset = 0;
3054
+ } else {
3055
+ $sign = (substr($timezone, 0, 1) == '+') ? 1 : -1;
3056
+ $hours = intval(substr($timezone, 1, 2));
3057
+ $minutes = intval(substr($timezone, 3, 4)) / 60;
3058
+ $offset = $sign * HOUR_IN_SECONDS * ($hours + $minutes);
3059
+ }
3060
+ return $offset;
3061
+ }
3062
+
3063
+ /**
3064
+ * Converts an iso8601 date to MySQL DateTime format used by post_date[_gmt].
3065
+ *
3066
+ * @since 1.5.0
3067
+ *
3068
+ * @param string $date_string Date and time in ISO 8601 format {@link https://en.wikipedia.org/wiki/ISO_8601}.
3069
+ * @param string $timezone Optional. If set to GMT returns the time minus gmt_offset. Default is 'user'.
3070
+ * @return string The date and time in MySQL DateTime format - Y-m-d H:i:s.
3071
+ */
3072
+ function iso8601_to_datetime( $date_string, $timezone = 'user' ) {
3073
+ $timezone = strtolower($timezone);
3074
+
3075
+ if ($timezone == 'gmt') {
3076
+
3077
+ preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits);
3078
+
3079
+ if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset
3080
+ $offset = iso8601_timezone_to_offset($date_bits[7]);
3081
+ } else { // we don't have a timezone, so we assume user local timezone (not server's!)
3082
+ $offset = HOUR_IN_SECONDS * get_option('gmt_offset');
3083
+ }
3084
+
3085
+ $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
3086
+ $timestamp -= $offset;
3087
+
3088
+ return gmdate('Y-m-d H:i:s', $timestamp);
3089
+
3090
+ } elseif ($timezone == 'user') {
3091
+ return preg_replace('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string);
3092
+ }
3093
+ }
3094
+
3095
+ /**
3096
+ * Strips out all characters that are not allowable in an email.
3097
+ *
3098
+ * @since 1.5.0
3099
+ *
3100
+ * @param string $email Email address to filter.
3101
+ * @return string Filtered email address.
3102
+ */
3103
+ function sanitize_email( $email ) {
3104
+ // Test for the minimum length the email can be
3105
+ if ( strlen( $email ) < 3 ) {
3106
+ /**
3107
+ * Filters a sanitized email address.
3108
+ *
3109
+ * This filter is evaluated under several contexts, including 'email_too_short',
3110
+ * 'email_no_at', 'local_invalid_chars', 'domain_period_sequence', 'domain_period_limits',
3111
+ * 'domain_no_periods', 'domain_no_valid_subs', or no context.
3112
+ *
3113
+ * @since 2.8.0
3114
+ *
3115
+ * @param string $email The sanitized email address.
3116
+ * @param string $email The email address, as provided to sanitize_email().
3117
+ * @param string $message A message to pass to the user.
3118
+ */
3119
+ return apply_filters( 'sanitize_email', '', $email, 'email_too_short' );
3120
+ }
3121
+
3122
+ // Test for an @ character after the first position
3123
+ if ( strpos( $email, '@', 1 ) === false ) {
3124
+ /** This filter is documented in wp-includes/formatting.php */
3125
+ return apply_filters( 'sanitize_email', '', $email, 'email_no_at' );
3126
+ }
3127
+
3128
+ // Split out the local and domain parts
3129
+ list( $local, $domain ) = explode( '@', $email, 2 );
3130
+
3131
+ // LOCAL PART
3132
+ // Test for invalid characters
3133
+ $local = preg_replace( '/[^a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]/', '', $local );
3134
+ if ( '' === $local ) {
3135
+ /** This filter is documented in wp-includes/formatting.php */
3136
+ return apply_filters( 'sanitize_email', '', $email, 'local_invalid_chars' );
3137
+ }
3138
+
3139
+ // DOMAIN PART
3140
+ // Test for sequences of periods
3141
+ $domain = preg_replace( '/\.{2,}/', '', $domain );
3142
+ if ( '' === $domain ) {
3143
+ /** This filter is documented in wp-includes/formatting.php */
3144
+ return apply_filters( 'sanitize_email', '', $email, 'domain_period_sequence' );
3145
+ }
3146
+
3147
+ // Test for leading and trailing periods and whitespace
3148
+ $domain = trim( $domain, " \t\n\r\0\x0B." );
3149
+ if ( '' === $domain ) {
3150
+ /** This filter is documented in wp-includes/formatting.php */
3151
+ return apply_filters( 'sanitize_email', '', $email, 'domain_period_limits' );
3152
+ }
3153
+
3154
+ // Split the domain into subs
3155
+ $subs = explode( '.', $domain );
3156
+
3157
+ // Assume the domain will have at least two subs
3158
+ if ( 2 > count( $subs ) ) {
3159
+ /** This filter is documented in wp-includes/formatting.php */
3160
+ return apply_filters( 'sanitize_email', '', $email, 'domain_no_periods' );
3161
+ }
3162
+
3163
+ // Create an array that will contain valid subs
3164
+ $new_subs = array();
3165
+
3166
+ // Loop through each sub
3167
+ foreach ( $subs as $sub ) {
3168
+ // Test for leading and trailing hyphens
3169
+ $sub = trim( $sub, " \t\n\r\0\x0B-" );
3170
+
3171
+ // Test for invalid characters
3172
+ $sub = preg_replace( '/[^a-z0-9-]+/i', '', $sub );
3173
+
3174
+ // If there's anything left, add it to the valid subs
3175
+ if ( '' !== $sub ) {
3176
+ $new_subs[] = $sub;
3177
+ }
3178
+ }
3179
+
3180
+ // If there aren't 2 or more valid subs
3181
+ if ( 2 > count( $new_subs ) ) {
3182
+ /** This filter is documented in wp-includes/formatting.php */
3183
+ return apply_filters( 'sanitize_email', '', $email, 'domain_no_valid_subs' );
3184
+ }
3185
+
3186
+ // Join valid subs into the new domain
3187
+ $domain = join( '.', $new_subs );
3188
+
3189
+ // Put the email back together
3190
+ $email = $local . '@' . $domain;
3191
+
3192
+ // Congratulations your email made it!
3193
+ /** This filter is documented in wp-includes/formatting.php */
3194
+ return apply_filters( 'sanitize_email', $email, $email, null );
3195
+ }
3196
+
3197
+ /**
3198
+ * Determines the difference between two timestamps.
3199
+ *
3200
+ * The difference is returned in a human readable format such as "1 hour",
3201
+ * "5 mins", "2 days".
3202
+ *
3203
+ * @since 1.5.0
3204
+ *
3205
+ * @param int $from Unix timestamp from which the difference begins.
3206
+ * @param int $to Optional. Unix timestamp to end the time difference. Default becomes time() if not set.
3207
+ * @return string Human readable time difference.
3208
+ */
3209
+ function human_time_diff( $from, $to = '' ) {
3210
+ if ( empty( $to ) ) {
3211
+ $to = time();
3212
+ }
3213
+
3214
+ $diff = (int) abs( $to - $from );
3215
+
3216
+ if ( $diff < HOUR_IN_SECONDS ) {
3217
+ $mins = round( $diff / MINUTE_IN_SECONDS );
3218
+ if ( $mins <= 1 )
3219
+ $mins = 1;
3220
+ /* translators: Time difference between two dates, in minutes (min=minute). 1: Number of minutes */
3221
+ $since = sprintf( _n( '%s min', '%s mins', $mins ), $mins );
3222
+ } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) {
3223
+ $hours = round( $diff / HOUR_IN_SECONDS );
3224
+ if ( $hours <= 1 )
3225
+ $hours = 1;
3226
+ /* translators: Time difference between two dates, in hours. 1: Number of hours */
3227
+ $since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours );
3228
+ } elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) {
3229
+ $days = round( $diff / DAY_IN_SECONDS );
3230
+ if ( $days <= 1 )
3231
+ $days = 1;
3232
+ /* translators: Time difference between two dates, in days. 1: Number of days */
3233
+ $since = sprintf( _n( '%s day', '%s days', $days ), $days );
3234
+ } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) {
3235
+ $weeks = round( $diff / WEEK_IN_SECONDS );
3236
+ if ( $weeks <= 1 )
3237
+ $weeks = 1;
3238
+ /* translators: Time difference between two dates, in weeks. 1: Number of weeks */
3239
+ $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks );
3240
+ } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) {
3241
+ $months = round( $diff / MONTH_IN_SECONDS );
3242
+ if ( $months <= 1 )
3243
+ $months = 1;
3244
+ /* translators: Time difference between two dates, in months. 1: Number of months */
3245
+ $since = sprintf( _n( '%s month', '%s months', $months ), $months );
3246
+ } elseif ( $diff >= YEAR_IN_SECONDS ) {
3247
+ $years = round( $diff / YEAR_IN_SECONDS );
3248
+ if ( $years <= 1 )
3249
+ $years = 1;
3250
+ /* translators: Time difference between two dates, in years. 1: Number of years */
3251
+ $since = sprintf( _n( '%s year', '%s years', $years ), $years );
3252
+ }
3253
+
3254
+ /**
3255
+ * Filters the human readable difference between two timestamps.
3256
+ *
3257
+ * @since 4.0.0
3258
+ *
3259
+ * @param string $since The difference in human readable text.
3260
+ * @param int $diff The difference in seconds.
3261
+ * @param int $from Unix timestamp from which the difference begins.
3262
+ * @param int $to Unix timestamp to end the time difference.
3263
+ */
3264
+ return apply_filters( 'human_time_diff', $since, $diff, $from, $to );
3265
+ }
3266
+
3267
+ /**
3268
+ * Generates an excerpt from the content, if needed.
3269
+ *
3270
+ * The excerpt word amount will be 55 words and if the amount is greater than
3271
+ * that, then the string ' [&hellip;]' will be appended to the excerpt. If the string
3272
+ * is less than 55 words, then the content will be returned as is.
3273
+ *
3274
+ * The 55 word limit can be modified by plugins/themes using the {@see 'excerpt_length'} filter
3275
+ * The ' [&hellip;]' string can be modified by plugins/themes using the {@see 'excerpt_more'} filter
3276
+ *
3277
+ * @since 1.5.0
3278
+ *
3279
+ * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated.
3280
+ * @return string The excerpt.
3281
+ */
3282
+ function wp_trim_excerpt( $text = '' ) {
3283
+ $raw_excerpt = $text;
3284
+ if ( '' == $text ) {
3285
+ $text = get_the_content('');
3286
+
3287
+ $text = strip_shortcodes( $text );
3288
+
3289
+ /** This filter is documented in wp-includes/post-template.php */
3290
+ $text = apply_filters( 'the_content', $text );
3291
+ $text = str_replace(']]>', ']]&gt;', $text);
3292
+
3293
+ /**
3294
+ * Filters the number of words in an excerpt.
3295
+ *
3296
+ * @since 2.7.0
3297
+ *
3298
+ * @param int $number The number of words. Default 55.
3299
+ */
3300
+ $excerpt_length = apply_filters( 'excerpt_length', 55 );
3301
+ /**
3302
+ * Filters the string in the "more" link displayed after a trimmed excerpt.
3303
+ *
3304
+ * @since 2.9.0
3305
+ *
3306
+ * @param string $more_string The string shown within the more link.
3307
+ */
3308
+ $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[&hellip;]' );
3309
+ $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
3310
+ }
3311
+ /**
3312
+ * Filters the trimmed excerpt string.
3313
+ *
3314
+ * @since 2.8.0
3315
+ *
3316
+ * @param string $text The trimmed text.
3317
+ * @param string $raw_excerpt The text prior to trimming.
3318
+ */
3319
+ return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt );
3320
+ }
3321
+
3322
+ /**
3323
+ * Trims text to a certain number of words.
3324
+ *
3325
+ * This function is localized. For languages that count 'words' by the individual
3326
+ * character (such as East Asian languages), the $num_words argument will apply
3327
+ * to the number of individual characters.
3328
+ *
3329
+ * @since 3.3.0
3330
+ *
3331
+ * @param string $text Text to trim.
3332
+ * @param int $num_words Number of words. Default 55.
3333
+ * @param string $more Optional. What to append if $text needs to be trimmed. Default '&hellip;'.
3334
+ * @return string Trimmed text.
3335
+ */
3336
+ function wp_trim_words( $text, $num_words = 55, $more = null ) {
3337
+ if ( null === $more ) {
3338
+ $more = __( '&hellip;' );
3339
+ }
3340
+
3341
+ $original_text = $text;
3342
+ $text = wp_strip_all_tags( $text );
3343
+
3344
+ /*
3345
+ * translators: If your word count is based on single characters (e.g. East Asian characters),
3346
+ * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
3347
+ * Do not translate into your own language.
3348
+ */
3349
+ if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
3350
+ $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
3351
+ preg_match_all( '/./u', $text, $words_array );
3352
+ $words_array = array_slice( $words_array[0], 0, $num_words + 1 );
3353
+ $sep = '';
3354
+ } else {
3355
+ $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
3356
+ $sep = ' ';
3357
+ }
3358
+
3359
+ if ( count( $words_array ) > $num_words ) {
3360
+ array_pop( $words_array );
3361
+ $text = implode( $sep, $words_array );
3362
+ $text = $text . $more;
3363
+ } else {
3364
+ $text = implode( $sep, $words_array );
3365
+ }
3366
+
3367
+ /**
3368
+ * Filters the text content after words have been trimmed.
3369
+ *
3370
+ * @since 3.3.0
3371
+ *
3372
+ * @param string $text The trimmed text.
3373
+ * @param int $num_words The number of words to trim the text to. Default 5.
3374
+ * @param string $more An optional string to append to the end of the trimmed text, e.g. &hellip;.
3375
+ * @param string $original_text The text before it was trimmed.
3376
+ */
3377
+ return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
3378
+ }
3379
+
3380
+ /**
3381
+ * Converts named entities into numbered entities.
3382
+ *
3383
+ * @since 1.5.1
3384
+ *
3385
+ * @param string $text The text within which entities will be converted.
3386
+ * @return string Text with converted entities.
3387
+ */
3388
+ function ent2ncr( $text ) {
3389
+
3390
+ /**
3391
+ * Filters text before named entities are converted into numbered entities.
3392
+ *
3393
+ * A non-null string must be returned for the filter to be evaluated.
3394
+ *
3395
+ * @since 3.3.0
3396
+ *
3397
+ * @param null $converted_text The text to be converted. Default null.
3398
+ * @param string $text The text prior to entity conversion.
3399
+ */
3400
+ $filtered = apply_filters( 'pre_ent2ncr', null, $text );
3401
+ if ( null !== $filtered )
3402
+ return $filtered;
3403
+
3404
+ $to_ncr = array(
3405
+ '&quot;' => '&#34;',
3406
+ '&amp;' => '&#38;',
3407
+ '&lt;' => '&#60;',
3408
+ '&gt;' => '&#62;',
3409
+ '|' => '&#124;',
3410
+ '&nbsp;' => '&#160;',
3411
+ '&iexcl;' => '&#161;',
3412
+ '&cent;' => '&#162;',
3413
+ '&pound;' => '&#163;',
3414
+ '&curren;' => '&#164;',
3415
+ '&yen;' => '&#165;',
3416
+ '&brvbar;' => '&#166;',
3417
+ '&brkbar;' => '&#166;',
3418
+ '&sect;' => '&#167;',
3419
+ '&uml;' => '&#168;',
3420
+ '&die;' => '&#168;',
3421
+ '&copy;' => '&#169;',
3422
+ '&ordf;' => '&#170;',
3423
+ '&laquo;' => '&#171;',
3424
+ '&not;' => '&#172;',
3425
+ '&shy;' => '&#173;',
3426
+ '&reg;' => '&#174;',
3427
+ '&macr;' => '&#175;',
3428
+ '&hibar;' => '&#175;',
3429
+ '&deg;' => '&#176;',
3430
+ '&plusmn;' => '&#177;',
3431
+ '&sup2;' => '&#178;',
3432
+ '&sup3;' => '&#179;',
3433
+ '&acute;' => '&#180;',
3434
+ '&micro;' => '&#181;',
3435
+ '&para;' => '&#182;',
3436
+ '&middot;' => '&#183;',
3437
+ '&cedil;' => '&#184;',
3438
+ '&sup1;' => '&#185;',
3439
+ '&ordm;' => '&#186;',
3440
+ '&raquo;' => '&#187;',
3441
+ '&frac14;' => '&#188;',
3442
+ '&frac12;' => '&#189;',
3443
+ '&frac34;' => '&#190;',
3444
+ '&iquest;' => '&#191;',
3445
+ '&Agrave;' => '&#192;',
3446
+ '&Aacute;' => '&#193;',
3447
+ '&Acirc;' => '&#194;',
3448
+ '&Atilde;' => '&#195;',
3449
+ '&Auml;' => '&#196;',
3450
+ '&Aring;' => '&#197;',
3451
+ '&AElig;' => '&#198;',
3452
+ '&Ccedil;' => '&#199;',
3453
+ '&Egrave;' => '&#200;',
3454
+ '&Eacute;' => '&#201;',
3455
+ '&Ecirc;' => '&#202;',
3456
+ '&Euml;' => '&#203;',
3457
+ '&Igrave;' => '&#204;',
3458
+ '&Iacute;' => '&#205;',
3459
+ '&Icirc;' => '&#206;',
3460
+ '&Iuml;' => '&#207;',
3461
+ '&ETH;' => '&#208;',
3462
+ '&Ntilde;' => '&#209;',
3463
+ '&Ograve;' => '&#210;',
3464
+ '&Oacute;' => '&#211;',
3465
+ '&Ocirc;' => '&#212;',
3466
+ '&Otilde;' => '&#213;',
3467
+ '&Ouml;' => '&#214;',
3468
+ '&times;' => '&#215;',
3469
+ '&Oslash;' => '&#216;',
3470
+ '&Ugrave;' => '&#217;',
3471
+ '&Uacute;' => '&#218;',
3472
+ '&Ucirc;' => '&#219;',
3473
+ '&Uuml;' => '&#220;',
3474
+ '&Yacute;' => '&#221;',
3475
+ '&THORN;' => '&#222;',
3476
+ '&szlig;' => '&#223;',
3477
+ '&agrave;' => '&#224;',
3478
+ '&aacute;' => '&#225;',
3479
+ '&acirc;' => '&#226;',
3480
+ '&atilde;' => '&#227;',
3481
+ '&auml;' => '&#228;',
3482
+ '&aring;' => '&#229;',
3483
+ '&aelig;' => '&#230;',
3484
+ '&ccedil;' => '&#231;',
3485
+ '&egrave;' => '&#232;',
3486
+ '&eacute;' => '&#233;',
3487
+ '&ecirc;' => '&#234;',
3488
+ '&euml;' => '&#235;',
3489
+ '&igrave;' => '&#236;',
3490
+ '&iacute;' => '&#237;',
3491
+ '&icirc;' => '&#238;',
3492
+ '&iuml;' => '&#239;',
3493
+ '&eth;' => '&#240;',
3494
+ '&ntilde;' => '&#241;',
3495
+ '&ograve;' => '&#242;',
3496
+ '&oacute;' => '&#243;',
3497
+ '&ocirc;' => '&#244;',
3498
+ '&otilde;' => '&#245;',
3499
+ '&ouml;' => '&#246;',
3500
+ '&divide;' => '&#247;',
3501
+ '&oslash;' => '&#248;',
3502
+ '&ugrave;' => '&#249;',
3503
+ '&uacute;' => '&#250;',
3504
+ '&ucirc;' => '&#251;',
3505
+ '&uuml;' => '&#252;',
3506
+ '&yacute;' => '&#253;',
3507
+ '&thorn;' => '&#254;',
3508
+ '&yuml;' => '&#255;',
3509
+ '&OElig;' => '&#338;',
3510
+ '&oelig;' => '&#339;',
3511
+ '&Scaron;' => '&#352;',
3512
+ '&scaron;' => '&#353;',
3513
+ '&Yuml;' => '&#376;',
3514
+ '&fnof;' => '&#402;',
3515
+ '&circ;' => '&#710;',
3516
+ '&tilde;' => '&#732;',
3517
+ '&Alpha;' => '&#913;',
3518
+ '&Beta;' => '&#914;',
3519
+ '&Gamma;' => '&#915;',
3520
+ '&Delta;' => '&#916;',
3521
+ '&Epsilon;' => '&#917;',
3522
+ '&Zeta;' => '&#918;',
3523
+ '&Eta;' => '&#919;',
3524
+ '&Theta;' => '&#920;',
3525
+ '&Iota;' => '&#921;',
3526
+ '&Kappa;' => '&#922;',
3527
+ '&Lambda;' => '&#923;',
3528
+ '&Mu;' => '&#924;',
3529
+ '&Nu;' => '&#925;',
3530
+ '&Xi;' => '&#926;',
3531
+ '&Omicron;' => '&#927;',
3532
+ '&Pi;' => '&#928;',
3533
+ '&Rho;' => '&#929;',
3534
+ '&Sigma;' => '&#931;',
3535
+ '&Tau;' => '&#932;',
3536
+ '&Upsilon;' => '&#933;',
3537
+ '&Phi;' => '&#934;',
3538
+ '&Chi;' => '&#935;',
3539
+ '&Psi;' => '&#936;',
3540
+ '&Omega;' => '&#937;',
3541
+ '&alpha;' => '&#945;',
3542
+ '&beta;' => '&#946;',
3543
+ '&gamma;' => '&#947;',
3544
+ '&delta;' => '&#948;',
3545
+ '&epsilon;' => '&#949;',
3546
+ '&zeta;' => '&#950;',
3547
+ '&eta;' => '&#951;',
3548
+ '&theta;' => '&#952;',
3549
+ '&iota;' => '&#953;',
3550
+ '&kappa;' => '&#954;',
3551
+ '&lambda;' => '&#955;',
3552
+ '&mu;' => '&#956;',
3553
+ '&nu;' => '&#957;',
3554
+ '&xi;' => '&#958;',
3555
+ '&omicron;' => '&#959;',
3556
+ '&pi;' => '&#960;',
3557
+ '&rho;' => '&#961;',
3558
+ '&sigmaf;' => '&#962;',
3559
+ '&sigma;' => '&#963;',
3560
+ '&tau;' => '&#964;',
3561
+ '&upsilon;' => '&#965;',
3562
+ '&phi;' => '&#966;',
3563
+ '&chi;' => '&#967;',
3564
+ '&psi;' => '&#968;',
3565
+ '&omega;' => '&#969;',
3566
+ '&thetasym;' => '&#977;',
3567
+ '&upsih;' => '&#978;',
3568
+ '&piv;' => '&#982;',
3569
+ '&ensp;' => '&#8194;',
3570
+ '&emsp;' => '&#8195;',
3571
+ '&thinsp;' => '&#8201;',
3572
+ '&zwnj;' => '&#8204;',
3573
+ '&zwj;' => '&#8205;',
3574
+ '&lrm;' => '&#8206;',
3575
+ '&rlm;' => '&#8207;',
3576
+ '&ndash;' => '&#8211;',
3577
+ '&mdash;' => '&#8212;',
3578
+ '&lsquo;' => '&#8216;',
3579
+ '&rsquo;' => '&#8217;',
3580
+ '&sbquo;' => '&#8218;',
3581
+ '&ldquo;' => '&#8220;',
3582
+ '&rdquo;' => '&#8221;',
3583
+ '&bdquo;' => '&#8222;',
3584
+ '&dagger;' => '&#8224;',
3585
+ '&Dagger;' => '&#8225;',
3586
+ '&bull;' => '&#8226;',
3587
+ '&hellip;' => '&#8230;',
3588
+ '&permil;' => '&#8240;',
3589
+ '&prime;' => '&#8242;',
3590
+ '&Prime;' => '&#8243;',
3591
+ '&lsaquo;' => '&#8249;',
3592
+ '&rsaquo;' => '&#8250;',
3593
+ '&oline;' => '&#8254;',
3594
+ '&frasl;' => '&#8260;',
3595
+ '&euro;' => '&#8364;',
3596
+ '&image;' => '&#8465;',
3597
+ '&weierp;' => '&#8472;',
3598
+ '&real;' => '&#8476;',
3599
+ '&trade;' => '&#8482;',
3600
+ '&alefsym;' => '&#8501;',
3601
+ '&crarr;' => '&#8629;',
3602
+ '&lArr;' => '&#8656;',
3603
+ '&uArr;' => '&#8657;',
3604
+ '&rArr;' => '&#8658;',
3605
+ '&dArr;' => '&#8659;',
3606
+ '&hArr;' => '&#8660;',
3607
+ '&forall;' => '&#8704;',
3608
+ '&part;' => '&#8706;',
3609
+ '&exist;' => '&#8707;',
3610
+ '&empty;' => '&#8709;',
3611
+ '&nabla;' => '&#8711;',
3612
+ '&isin;' => '&#8712;',
3613
+ '&notin;' => '&#8713;',
3614
+ '&ni;' => '&#8715;',
3615
+ '&prod;' => '&#8719;',
3616
+ '&sum;' => '&#8721;',
3617
+ '&minus;' => '&#8722;',
3618
+ '&lowast;' => '&#8727;',
3619
+ '&radic;' => '&#8730;',
3620
+ '&prop;' => '&#8733;',
3621
+ '&infin;' => '&#8734;',
3622
+ '&ang;' => '&#8736;',
3623
+ '&and;' => '&#8743;',
3624
+ '&or;' => '&#8744;',
3625
+ '&cap;' => '&#8745;',
3626
+ '&cup;' => '&#8746;',
3627
+ '&int;' => '&#8747;',
3628
+ '&there4;' => '&#8756;',
3629
+ '&sim;' => '&#8764;',
3630
+ '&cong;' => '&#8773;',
3631
+ '&asymp;' => '&#8776;',
3632
+ '&ne;' => '&#8800;',
3633
+ '&equiv;' => '&#8801;',
3634
+ '&le;' => '&#8804;',
3635
+ '&ge;' => '&#8805;',
3636
+ '&sub;' => '&#8834;',
3637
+ '&sup;' => '&#8835;',
3638
+ '&nsub;' => '&#8836;',
3639
+ '&sube;' => '&#8838;',
3640
+ '&supe;' => '&#8839;',
3641
+ '&oplus;' => '&#8853;',
3642
+ '&otimes;' => '&#8855;',
3643
+ '&perp;' => '&#8869;',
3644
+ '&sdot;' => '&#8901;',
3645
+ '&lceil;' => '&#8968;',
3646
+ '&rceil;' => '&#8969;',
3647
+ '&lfloor;' => '&#8970;',
3648
+ '&rfloor;' => '&#8971;',
3649
+ '&lang;' => '&#9001;',
3650
+ '&rang;' => '&#9002;',
3651
+ '&larr;' => '&#8592;',
3652
+ '&uarr;' => '&#8593;',
3653
+ '&rarr;' => '&#8594;',
3654
+ '&darr;' => '&#8595;',
3655
+ '&harr;' => '&#8596;',
3656
+ '&loz;' => '&#9674;',
3657
+ '&spades;' => '&#9824;',
3658
+ '&clubs;' => '&#9827;',
3659
+ '&hearts;' => '&#9829;',
3660
+ '&diams;' => '&#9830;'
3661
+ );
3662
+
3663
+ return str_replace( array_keys($to_ncr), array_values($to_ncr), $text );
3664
+ }
3665
+
3666
+ /**
3667
+ * Formats text for the editor.
3668
+ *
3669
+ * Generally the browsers treat everything inside a textarea as text, but
3670
+ * it is still a good idea to HTML entity encode `<`, `>` and `&` in the content.
3671
+ *
3672
+ * The filter {@see 'format_for_editor'} is applied here. If `$text` is empty the
3673
+ * filter will be applied to an empty string.
3674
+ *
3675
+ * @since 4.3.0
3676
+ *
3677
+ * @see _WP_Editors::editor()
3678
+ *
3679
+ * @param string $text The text to be formatted.
3680
+ * @param string $default_editor The default editor for the current user.
3681
+ * It is usually either 'html' or 'tinymce'.
3682
+ * @return string The formatted text after filter is applied.
3683
+ */
3684
+ function format_for_editor( $text, $default_editor = null ) {
3685
+ if ( $text ) {
3686
+ $text = htmlspecialchars( $text, ENT_NOQUOTES, get_option( 'blog_charset' ) );
3687
+ }
3688
+
3689
+ /**
3690
+ * Filters the text after it is formatted for the editor.
3691
+ *
3692
+ * @since 4.3.0
3693
+ *
3694
+ * @param string $text The formatted text.
3695
+ * @param string $default_editor The default editor for the current user.
3696
+ * It is usually either 'html' or 'tinymce'.
3697
+ */
3698
+ return apply_filters( 'format_for_editor', $text, $default_editor );
3699
+ }
3700
+
3701
+ /**
3702
+ * Perform a deep string replace operation to ensure the values in $search are no longer present
3703
+ *
3704
+ * Repeats the replacement operation until it no longer replaces anything so as to remove "nested" values
3705
+ * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that
3706
+ * str_replace would return
3707
+ *
3708
+ * @since 2.8.1
3709
+ * @access private
3710
+ *
3711
+ * @param string|array $search The value being searched for, otherwise known as the needle.
3712
+ * An array may be used to designate multiple needles.
3713
+ * @param string $subject The string being searched and replaced on, otherwise known as the haystack.
3714
+ * @return string The string with the replaced svalues.
3715
+ */
3716
+ function _deep_replace( $search, $subject ) {
3717
+ $subject = (string) $subject;
3718
+
3719
+ $count = 1;
3720
+ while ( $count ) {
3721
+ $subject = str_replace( $search, '', $subject, $count );
3722
+ }
3723
+
3724
+ return $subject;
3725
+ }
3726
+
3727
+ /**
3728
+ * Escapes data for use in a MySQL query.
3729
+ *
3730
+ * Usually you should prepare queries using wpdb::prepare().
3731
+ * Sometimes, spot-escaping is required or useful. One example
3732
+ * is preparing an array for use in an IN clause.
3733
+ *
3734
+ * @since 2.8.0
3735
+ *
3736
+ * @global wpdb $wpdb WordPress database abstraction object.
3737
+ *
3738
+ * @param string|array $data Unescaped data
3739
+ * @return string|array Escaped data
3740
+ */
3741
+ function esc_sql( $data ) {
3742
+ global $wpdb;
3743
+ return $wpdb->_escape( $data );
3744
+ }
3745
+
3746
+ /**
3747
+ * Checks and cleans a URL.
3748
+ *
3749
+ * A number of characters are removed from the URL. If the URL is for displaying
3750
+ * (the default behaviour) ampersands are also replaced. The {@see 'clean_url'} filter
3751
+ * is applied to the returned cleaned URL.
3752
+ *
3753
+ * @since 2.8.0
3754
+ *
3755
+ * @param string $url The URL to be cleaned.
3756
+ * @param array $protocols Optional. An array of acceptable protocols.
3757
+ * Defaults to return value of wp_allowed_protocols()
3758
+ * @param string $_context Private. Use esc_url_raw() for database usage.
3759
+ * @return string The cleaned $url after the {@see 'clean_url'} filter is applied.
3760
+ */
3761
+ function esc_url( $url, $protocols = null, $_context = 'display' ) {
3762
+ $original_url = $url;
3763
+
3764
+ if ( '' == $url )
3765
+ return $url;
3766
+
3767
+ $url = str_replace( ' ', '%20', $url );
3768
+ $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url);
3769
+
3770
+ if ( '' === $url ) {
3771
+ return $url;
3772
+ }
3773
+
3774
+ if ( 0 !== stripos( $url, 'mailto:' ) ) {
3775
+ $strip = array('%0d', '%0a', '%0D', '%0A');
3776
+ $url = _deep_replace($strip, $url);
3777
+ }
3778
+
3779
+ $url = str_replace(';//', '://', $url);
3780
+ /* If the URL doesn't appear to contain a scheme, we
3781
+ * presume it needs http:// prepended (unless a relative
3782
+ * link starting with /, # or ? or a php file).
3783
+ */
3784
+ if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) &&
3785
+ ! preg_match('/^[a-z0-9-]+?\.php/i', $url) )
3786
+ $url = 'http://' . $url;
3787
+
3788
+ // Replace ampersands and single quotes only when displaying.
3789
+ if ( 'display' == $_context ) {
3790
+ $url = wp_kses_normalize_entities( $url );
3791
+ $url = str_replace( '&amp;', '&#038;', $url );
3792
+ $url = str_replace( "'", '&#039;', $url );
3793
+ }
3794
+
3795
+ if ( ( false !== strpos( $url, '[' ) ) || ( false !== strpos( $url, ']' ) ) ) {
3796
+
3797
+ $parsed = wp_parse_url( $url );
3798
+ $front = '';
3799
+
3800
+ if ( isset( $parsed['scheme'] ) ) {
3801
+ $front .= $parsed['scheme'] . '://';
3802
+ } elseif ( '/' === $url[0] ) {
3803
+ $front .= '//';
3804
+ }
3805
+
3806
+ if ( isset( $parsed['user'] ) ) {
3807
+ $front .= $parsed['user'];
3808
+ }
3809
+
3810
+ if ( isset( $parsed['pass'] ) ) {
3811
+ $front .= ':' . $parsed['pass'];
3812
+ }
3813
+
3814
+ if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) {
3815
+ $front .= '@';
3816
+ }
3817
+
3818
+ if ( isset( $parsed['host'] ) ) {
3819
+ $front .= $parsed['host'];
3820
+ }
3821
+
3822
+ if ( isset( $parsed['port'] ) ) {
3823
+ $front .= ':' . $parsed['port'];
3824
+ }
3825
+
3826
+ $end_dirty = str_replace( $front, '', $url );
3827
+ $end_clean = str_replace( array( '[', ']' ), array( '%5B', '%5D' ), $end_dirty );
3828
+ $url = str_replace( $end_dirty, $end_clean, $url );
3829
+
3830
+ }
3831
+
3832
+ if ( '/' === $url[0] ) {
3833
+ $good_protocol_url = $url;
3834
+ } else {
3835
+ if ( ! is_array( $protocols ) )
3836
+ $protocols = wp_allowed_protocols();
3837
+ $good_protocol_url = wp_kses_bad_protocol( $url, $protocols );
3838
+ if ( strtolower( $good_protocol_url ) != strtolower( $url ) )
3839
+ return '';
3840
+ }
3841
+
3842
+ /**
3843
+ * Filters a string cleaned and escaped for output as a URL.
3844
+ *
3845
+ * @since 2.3.0
3846
+ *
3847
+ * @param string $good_protocol_url The cleaned URL to be returned.
3848
+ * @param string $original_url The URL prior to cleaning.
3849
+ * @param string $_context If 'display', replace ampersands and single quotes only.
3850
+ */
3851
+ return apply_filters( 'clean_url', $good_protocol_url, $original_url, $_context );
3852
+ }
3853
+
3854
+ /**
3855
+ * Performs esc_url() for database usage.
3856
+ *
3857
+ * @since 2.8.0
3858
+ *
3859
+ * @param string $url The URL to be cleaned.
3860
+ * @param array $protocols An array of acceptable protocols.
3861
+ * @return string The cleaned URL.
3862
+ */
3863
+ function esc_url_raw( $url, $protocols = null ) {
3864
+ return esc_url( $url, $protocols, 'db' );
3865
+ }
3866
+
3867
+ /**
3868
+ * Convert entities, while preserving already-encoded entities.
3869
+ *
3870
+ * @link https://secure.php.net/htmlentities Borrowed from the PHP Manual user notes.
3871
+ *
3872
+ * @since 1.2.2
3873
+ *
3874
+ * @param string $myHTML The text to be converted.
3875
+ * @return string Converted text.
3876
+ */
3877
+ function htmlentities2( $myHTML ) {
3878
+ $translation_table = get_html_translation_table( HTML_ENTITIES, ENT_QUOTES );
3879
+ $translation_table[chr(38)] = '&';
3880
+ return preg_replace( "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/", "&amp;", strtr($myHTML, $translation_table) );
3881
+ }
3882
+
3883
+ /**
3884
+ * Escape single quotes, htmlspecialchar " < > &, and fix line endings.
3885
+ *
3886
+ * Escapes text strings for echoing in JS. It is intended to be used for inline JS
3887
+ * (in a tag attribute, for example onclick="..."). Note that the strings have to
3888
+ * be in single quotes. The {@see 'js_escape'} filter is also applied here.
3889
+ *
3890
+ * @since 2.8.0
3891
+ *
3892
+ * @param string $text The text to be escaped.
3893
+ * @return string Escaped text.
3894
+ */
3895
+ function esc_js( $text ) {
3896
+ $safe_text = wp_check_invalid_utf8( $text );
3897
+ $safe_text = _wp_specialchars( $safe_text, ENT_COMPAT );
3898
+ $safe_text = preg_replace( '/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes( $safe_text ) );
3899
+ $safe_text = str_replace( "\r", '', $safe_text );
3900
+ $safe_text = str_replace( "\n", '\\n', addslashes( $safe_text ) );
3901
+ /**
3902
+ * Filters a string cleaned and escaped for output in JavaScript.
3903
+ *
3904
+ * Text passed to esc_js() is stripped of invalid or special characters,
3905
+ * and properly slashed for output.
3906
+ *
3907
+ * @since 2.0.6
3908
+ *
3909
+ * @param string $safe_text The text after it has been escaped.
3910
+ * @param string $text The text prior to being escaped.
3911
+ */
3912
+ return apply_filters( 'js_escape', $safe_text, $text );
3913
+ }
3914
+
3915
+ /**
3916
+ * Escaping for HTML blocks.
3917
+ *
3918
+ * @since 2.8.0
3919
+ *
3920
+ * @param string $text
3921
+ * @return string
3922
+ */
3923
+ function esc_html( $text ) {
3924
+ $safe_text = wp_check_invalid_utf8( $text );
3925
+ $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
3926
+ /**
3927
+ * Filters a string cleaned and escaped for output in HTML.
3928
+ *
3929
+ * Text passed to esc_html() is stripped of invalid or special characters
3930
+ * before output.
3931
+ *
3932
+ * @since 2.8.0
3933
+ *
3934
+ * @param string $safe_text The text after it has been escaped.
3935
+ * @param string $text The text prior to being escaped.
3936
+ */
3937
+ return apply_filters( 'esc_html', $safe_text, $text );
3938
+ }
3939
+
3940
+ /**
3941
+ * Escaping for HTML attributes.
3942
+ *
3943
+ * @since 2.8.0
3944
+ *
3945
+ * @param string $text
3946
+ * @return string
3947
+ */
3948
+ function esc_attr( $text ) {
3949
+ $safe_text = wp_check_invalid_utf8( $text );
3950
+ $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
3951
+ /**
3952
+ * Filters a string cleaned and escaped for output in an HTML attribute.
3953
+ *
3954
+ * Text passed to esc_attr() is stripped of invalid or special characters
3955
+ * before output.
3956
+ *
3957
+ * @since 2.0.6
3958
+ *
3959
+ * @param string $safe_text The text after it has been escaped.
3960
+ * @param string $text The text prior to being escaped.
3961
+ */
3962
+ return apply_filters( 'attribute_escape', $safe_text, $text );
3963
+ }
3964
+
3965
+ /**
3966
+ * Escaping for textarea values.
3967
+ *
3968
+ * @since 3.1.0
3969
+ *
3970
+ * @param string $text
3971
+ * @return string
3972
+ */
3973
+ function esc_textarea( $text ) {
3974
+ $safe_text = htmlspecialchars( $text, ENT_QUOTES, get_option( 'blog_charset' ) );
3975
+ /**
3976
+ * Filters a string cleaned and escaped for output in a textarea element.
3977
+ *
3978
+ * @since 3.1.0
3979
+ *
3980
+ * @param string $safe_text The text after it has been escaped.
3981
+ * @param string $text The text prior to being escaped.
3982
+ */
3983
+ return apply_filters( 'esc_textarea', $safe_text, $text );
3984
+ }
3985
+
3986
+ /**
3987
+ * Escape an HTML tag name.
3988
+ *
3989
+ * @since 2.5.0
3990
+ *
3991
+ * @param string $tag_name
3992
+ * @return string
3993
+ */
3994
+ function tag_escape( $tag_name ) {
3995
+ $safe_tag = strtolower( preg_replace('/[^a-zA-Z0-9_:]/', '', $tag_name) );
3996
+ /**
3997
+ * Filters a string cleaned and escaped for output as an HTML tag.
3998
+ *
3999
+ * @since 2.8.0
4000
+ *
4001
+ * @param string $safe_tag The tag name after it has been escaped.
4002
+ * @param string $tag_name The text before it was escaped.
4003
+ */
4004
+ return apply_filters( 'tag_escape', $safe_tag, $tag_name );
4005
+ }
4006
+
4007
+ /**
4008
+ * Convert full URL paths to absolute paths.
4009
+ *
4010
+ * Removes the http or https protocols and the domain. Keeps the path '/' at the
4011
+ * beginning, so it isn't a true relative link, but from the web root base.
4012
+ *
4013
+ * @since 2.1.0
4014
+ * @since 4.1.0 Support was added for relative URLs.
4015
+ *
4016
+ * @param string $link Full URL path.
4017
+ * @return string Absolute path.
4018
+ */
4019
+ function wp_make_link_relative( $link ) {
4020
+ return preg_replace( '|^(https?:)?//[^/]+(/?.*)|i', '$2', $link );
4021
+ }
4022
+
4023
+ /**
4024
+ * Sanitises various option values based on the nature of the option.
4025
+ *
4026
+ * This is basically a switch statement which will pass $value through a number
4027
+ * of functions depending on the $option.
4028
+ *
4029
+ * @since 2.0.5
4030
+ *
4031
+ * @global wpdb $wpdb WordPress database abstraction object.
4032
+ *
4033
+ * @param string $option The name of the option.
4034
+ * @param string $value The unsanitised value.
4035
+ * @return string Sanitized value.
4036
+ */
4037
+ function sanitize_option( $option, $value ) {
4038
+ global $wpdb;
4039
+
4040
+ $original_value = $value;
4041
+ $error = '';
4042
+
4043
+ switch ( $option ) {
4044
+ case 'admin_email' :
4045
+ case 'new_admin_email' :
4046
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4047
+ if ( is_wp_error( $value ) ) {
4048
+ $error = $value->get_error_message();
4049
+ } else {
4050
+ $value = sanitize_email( $value );
4051
+ if ( ! is_email( $value ) ) {
4052
+ $error = __( 'The email address entered did not appear to be a valid email address. Please enter a valid email address.' );
4053
+ }
4054
+ }
4055
+ break;
4056
+
4057
+ case 'thumbnail_size_w':
4058
+ case 'thumbnail_size_h':
4059
+ case 'medium_size_w':
4060
+ case 'medium_size_h':
4061
+ case 'medium_large_size_w':
4062
+ case 'medium_large_size_h':
4063
+ case 'large_size_w':
4064
+ case 'large_size_h':
4065
+ case 'mailserver_port':
4066
+ case 'comment_max_links':
4067
+ case 'page_on_front':
4068
+ case 'page_for_posts':
4069
+ case 'rss_excerpt_length':
4070
+ case 'default_category':
4071
+ case 'default_email_category':
4072
+ case 'default_link_category':
4073
+ case 'close_comments_days_old':
4074
+ case 'comments_per_page':
4075
+ case 'thread_comments_depth':
4076
+ case 'users_can_register':
4077
+ case 'start_of_week':
4078
+ case 'site_icon':
4079
+ $value = absint( $value );
4080
+ break;
4081
+
4082
+ case 'posts_per_page':
4083
+ case 'posts_per_rss':
4084
+ $value = (int) $value;
4085
+ if ( empty($value) )
4086
+ $value = 1;
4087
+ if ( $value < -1 )
4088
+ $value = abs($value);
4089
+ break;
4090
+
4091
+ case 'default_ping_status':
4092
+ case 'default_comment_status':
4093
+ // Options that if not there have 0 value but need to be something like "closed"
4094
+ if ( $value == '0' || $value == '')
4095
+ $value = 'closed';
4096
+ break;
4097
+
4098
+ case 'blogdescription':
4099
+ case 'blogname':
4100
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4101
+ if ( $value !== $original_value ) {
4102
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', wp_encode_emoji( $original_value ) );
4103
+ }
4104
+
4105
+ if ( is_wp_error( $value ) ) {
4106
+ $error = $value->get_error_message();
4107
+ } else {
4108
+ $value = esc_html( $value );
4109
+ }
4110
+ break;
4111
+
4112
+ case 'blog_charset':
4113
+ $value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); // strips slashes
4114
+ break;
4115
+
4116
+ case 'blog_public':
4117
+ // This is the value if the settings checkbox is not checked on POST. Don't rely on this.
4118
+ if ( null === $value )
4119
+ $value = 1;
4120
+ else
4121
+ $value = intval( $value );
4122
+ break;
4123
+
4124
+ case 'date_format':
4125
+ case 'time_format':
4126
+ case 'mailserver_url':
4127
+ case 'mailserver_login':
4128
+ case 'mailserver_pass':
4129
+ case 'upload_path':
4130
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4131
+ if ( is_wp_error( $value ) ) {
4132
+ $error = $value->get_error_message();
4133
+ } else {
4134
+ $value = strip_tags( $value );
4135
+ $value = wp_kses_data( $value );
4136
+ }
4137
+ break;
4138
+
4139
+ case 'ping_sites':
4140
+ $value = explode( "\n", $value );
4141
+ $value = array_filter( array_map( 'trim', $value ) );
4142
+ $value = array_filter( array_map( 'esc_url_raw', $value ) );
4143
+ $value = implode( "\n", $value );
4144
+ break;
4145
+
4146
+ case 'gmt_offset':
4147
+ $value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes
4148
+ break;
4149
+
4150
+ case 'siteurl':
4151
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4152
+ if ( is_wp_error( $value ) ) {
4153
+ $error = $value->get_error_message();
4154
+ } else {
4155
+ if ( preg_match( '#http(s?)://(.+)#i', $value ) ) {
4156
+ $value = esc_url_raw( $value );
4157
+ } else {
4158
+ $error = __( 'The WordPress address you entered did not appear to be a valid URL. Please enter a valid URL.' );
4159
+ }
4160
+ }
4161
+ break;
4162
+
4163
+ case 'home':
4164
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4165
+ if ( is_wp_error( $value ) ) {
4166
+ $error = $value->get_error_message();
4167
+ } else {
4168
+ if ( preg_match( '#http(s?)://(.+)#i', $value ) ) {
4169
+ $value = esc_url_raw( $value );
4170
+ } else {
4171
+ $error = __( 'The Site address you entered did not appear to be a valid URL. Please enter a valid URL.' );
4172
+ }
4173
+ }
4174
+ break;
4175
+
4176
+ case 'WPLANG':
4177
+ $allowed = get_available_languages();
4178
+ if ( ! is_multisite() && defined( 'WPLANG' ) && '' !== WPLANG && 'en_US' !== WPLANG ) {
4179
+ $allowed[] = WPLANG;
4180
+ }
4181
+ if ( ! in_array( $value, $allowed ) && ! empty( $value ) ) {
4182
+ $value = get_option( $option );
4183
+ }
4184
+ break;
4185
+
4186
+ case 'illegal_names':
4187
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4188
+ if ( is_wp_error( $value ) ) {
4189
+ $error = $value->get_error_message();
4190
+ } else {
4191
+ if ( ! is_array( $value ) )
4192
+ $value = explode( ' ', $value );
4193
+
4194
+ $value = array_values( array_filter( array_map( 'trim', $value ) ) );
4195
+
4196
+ if ( ! $value )
4197
+ $value = '';
4198
+ }
4199
+ break;
4200
+
4201
+ case 'limited_email_domains':
4202
+ case 'banned_email_domains':
4203
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4204
+ if ( is_wp_error( $value ) ) {
4205
+ $error = $value->get_error_message();
4206
+ } else {
4207
+ if ( ! is_array( $value ) )
4208
+ $value = explode( "\n", $value );
4209
+
4210
+ $domains = array_values( array_filter( array_map( 'trim', $value ) ) );
4211
+ $value = array();
4212
+
4213
+ foreach ( $domains as $domain ) {
4214
+ if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) ) {
4215
+ $value[] = $domain;
4216
+ }
4217
+ }
4218
+ if ( ! $value )
4219
+ $value = '';
4220
+ }
4221
+ break;
4222
+
4223
+ case 'timezone_string':
4224
+ $allowed_zones = timezone_identifiers_list();
4225
+ if ( ! in_array( $value, $allowed_zones ) && ! empty( $value ) ) {
4226
+ $error = __( 'The timezone you have entered is not valid. Please select a valid timezone.' );
4227
+ }
4228
+ break;
4229
+
4230
+ case 'permalink_structure':
4231
+ case 'category_base':
4232
+ case 'tag_base':
4233
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4234
+ if ( is_wp_error( $value ) ) {
4235
+ $error = $value->get_error_message();
4236
+ } else {
4237
+ $value = esc_url_raw( $value );
4238
+ $value = str_replace( 'http://', '', $value );
4239
+ }
4240
+
4241
+ if ( 'permalink_structure' === $option && '' !== $value && ! preg_match( '/%[^\/%]+%/', $value ) ) {
4242
+ $error = sprintf(
4243
+ /* translators: %s: Codex URL */
4244
+ __( 'A structure tag is required when using custom permalinks. <a href="%s">Learn more</a>' ),
4245
+ __( 'https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure' )
4246
+ );
4247
+ }
4248
+ break;
4249
+
4250
+ case 'default_role' :
4251
+ if ( ! get_role( $value ) && get_role( 'subscriber' ) )
4252
+ $value = 'subscriber';
4253
+ break;
4254
+
4255
+ case 'moderation_keys':
4256
+ case 'blacklist_keys':
4257
+ $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
4258
+ if ( is_wp_error( $value ) ) {
4259
+ $error = $value->get_error_message();
4260
+ } else {
4261
+ $value = explode( "\n", $value );
4262
+ $value = array_filter( array_map( 'trim', $value ) );
4263
+ $value = array_unique( $value );
4264
+ $value = implode( "\n", $value );
4265
+ }
4266
+ break;
4267
+ }
4268
+
4269
+ if ( ! empty( $error ) ) {
4270
+ $value = get_option( $option );
4271
+ if ( function_exists( 'add_settings_error' ) ) {
4272
+ add_settings_error( $option, "invalid_{$option}", $error );
4273
+ }
4274
+ }
4275
+
4276
+ /**
4277
+ * Filters an option value following sanitization.
4278
+ *
4279
+ * @since 2.3.0
4280
+ * @since 4.3.0 Added the `$original_value` parameter.
4281
+ *
4282
+ * @param string $value The sanitized option value.
4283
+ * @param string $option The option name.
4284
+ * @param string $original_value The original value passed to the function.
4285
+ */
4286
+ return apply_filters( "sanitize_option_{$option}", $value, $option, $original_value );
4287
+ }
4288
+
4289
+ /**
4290
+ * Maps a function to all non-iterable elements of an array or an object.
4291
+ *
4292
+ * This is similar to `array_walk_recursive()` but acts upon objects too.
4293
+ *
4294
+ * @since 4.4.0
4295
+ *
4296
+ * @param mixed $value The array, object, or scalar.
4297
+ * @param callable $callback The function to map onto $value.
4298
+ * @return mixed The value with the callback applied to all non-arrays and non-objects inside it.
4299
+ */
4300
+ function map_deep( $value, $callback ) {
4301
+ if ( is_array( $value ) ) {
4302
+ foreach ( $value as $index => $item ) {
4303
+ $value[ $index ] = map_deep( $item, $callback );
4304
+ }
4305
+ } elseif ( is_object( $value ) ) {
4306
+ $object_vars = get_object_vars( $value );
4307
+ foreach ( $object_vars as $property_name => $property_value ) {
4308
+ $value->$property_name = map_deep( $property_value, $callback );
4309
+ }
4310
+ } else {
4311
+ $value = call_user_func( $callback, $value );
4312
+ }
4313
+
4314
+ return $value;
4315
+ }
4316
+
4317
+ /**
4318
+ * Parses a string into variables to be stored in an array.
4319
+ *
4320
+ * Uses {@link https://secure.php.net/parse_str parse_str()} and stripslashes if
4321
+ * {@link https://secure.php.net/magic_quotes magic_quotes_gpc} is on.
4322
+ *
4323
+ * @since 2.2.1
4324
+ *
4325
+ * @param string $string The string to be parsed.
4326
+ * @param array $array Variables will be stored in this array.
4327
+ */
4328
+ function wp_parse_str( $string, &$array ) {
4329
+ parse_str( $string, $array );
4330
+ if ( get_magic_quotes_gpc() )
4331
+ $array = stripslashes_deep( $array );
4332
+ /**
4333
+ * Filters the array of variables derived from a parsed string.
4334
+ *
4335
+ * @since 2.3.0
4336
+ *
4337
+ * @param array $array The array populated with variables.
4338
+ */
4339
+ $array = apply_filters( 'wp_parse_str', $array );
4340
+ }
4341
+
4342
+ /**
4343
+ * Convert lone less than signs.
4344
+ *
4345
+ * KSES already converts lone greater than signs.
4346
+ *
4347
+ * @since 2.3.0
4348
+ *
4349
+ * @param string $text Text to be converted.
4350
+ * @return string Converted text.
4351
+ */
4352
+ function wp_pre_kses_less_than( $text ) {
4353
+ return preg_replace_callback('%<[^>]*?((?=<)|>|$)%', 'wp_pre_kses_less_than_callback', $text);
4354
+ }
4355
+
4356
+ /**
4357
+ * Callback function used by preg_replace.
4358
+ *
4359
+ * @since 2.3.0
4360
+ *
4361
+ * @param array $matches Populated by matches to preg_replace.
4362
+ * @return string The text returned after esc_html if needed.
4363
+ */
4364
+ function wp_pre_kses_less_than_callback( $matches ) {
4365
+ if ( false === strpos($matches[0], '>') )
4366
+ return esc_html($matches[0]);
4367
+ return $matches[0];
4368
+ }
4369
+
4370
+ /**
4371
+ * WordPress implementation of PHP sprintf() with filters.
4372
+ *
4373
+ * @since 2.5.0
4374
+ * @link https://secure.php.net/sprintf
4375
+ *
4376
+ * @param string $pattern The string which formatted args are inserted.
4377
+ * @param mixed $args ,... Arguments to be formatted into the $pattern string.
4378
+ * @return string The formatted string.
4379
+ */
4380
+ function wp_sprintf( $pattern ) {
4381
+ $args = func_get_args();
4382
+ $len = strlen($pattern);
4383
+ $start = 0;
4384
+ $result = '';
4385
+ $arg_index = 0;
4386
+ while ( $len > $start ) {
4387
+ // Last character: append and break
4388
+ if ( strlen($pattern) - 1 == $start ) {
4389
+ $result .= substr($pattern, -1);
4390
+ break;
4391
+ }
4392
+
4393
+ // Literal %: append and continue
4394
+ if ( substr($pattern, $start, 2) == '%%' ) {
4395
+ $start += 2;
4396
+ $result .= '%';
4397
+ continue;
4398
+ }
4399
+
4400
+ // Get fragment before next %
4401
+ $end = strpos($pattern, '%', $start + 1);
4402
+ if ( false === $end )
4403
+ $end = $len;
4404
+ $fragment = substr($pattern, $start, $end - $start);
4405
+
4406
+ // Fragment has a specifier
4407
+ if ( $pattern[$start] == '%' ) {
4408
+ // Find numbered arguments or take the next one in order
4409
+ if ( preg_match('/^%(\d+)\$/', $fragment, $matches) ) {
4410
+ $arg = isset($args[$matches[1]]) ? $args[$matches[1]] : '';
4411
+ $fragment = str_replace("%{$matches[1]}$", '%', $fragment);
4412
+ } else {
4413
+ ++$arg_index;
4414
+ $arg = isset($args[$arg_index]) ? $args[$arg_index] : '';
4415
+ }
4416
+
4417
+ /**
4418
+ * Filters a fragment from the pattern passed to wp_sprintf().
4419
+ *
4420
+ * If the fragment is unchanged, then sprintf() will be run on the fragment.
4421
+ *
4422
+ * @since 2.5.0
4423
+ *
4424
+ * @param string $fragment A fragment from the pattern.
4425
+ * @param string $arg The argument.
4426
+ */
4427
+ $_fragment = apply_filters( 'wp_sprintf', $fragment, $arg );
4428
+ if ( $_fragment != $fragment )
4429
+ $fragment = $_fragment;
4430
+ else
4431
+ $fragment = sprintf($fragment, strval($arg) );
4432
+ }
4433
+
4434
+ // Append to result and move to next fragment
4435
+ $result .= $fragment;
4436
+ $start = $end;
4437
+ }
4438
+ return $result;
4439
+ }
4440
+
4441
+ /**
4442
+ * Localize list items before the rest of the content.
4443
+ *
4444
+ * The '%l' must be at the first characters can then contain the rest of the
4445
+ * content. The list items will have ', ', ', and', and ' and ' added depending
4446
+ * on the amount of list items in the $args parameter.
4447
+ *
4448
+ * @since 2.5.0
4449
+ *
4450
+ * @param string $pattern Content containing '%l' at the beginning.
4451
+ * @param array $args List items to prepend to the content and replace '%l'.
4452
+ * @return string Localized list items and rest of the content.
4453
+ */
4454
+ function wp_sprintf_l( $pattern, $args ) {
4455
+ // Not a match
4456
+ if ( substr($pattern, 0, 2) != '%l' )
4457
+ return $pattern;
4458
+
4459
+ // Nothing to work with
4460
+ if ( empty($args) )
4461
+ return '';
4462
+
4463
+ /**
4464
+ * Filters the translated delimiters used by wp_sprintf_l().
4465
+ * Placeholders (%s) are included to assist translators and then
4466
+ * removed before the array of strings reaches the filter.
4467
+ *
4468
+ * Please note: Ampersands and entities should be avoided here.
4469
+ *
4470
+ * @since 2.5.0
4471
+ *
4472
+ * @param array $delimiters An array of translated delimiters.
4473
+ */
4474
+ $l = apply_filters( 'wp_sprintf_l', array(
4475
+ /* translators: used to join items in a list with more than 2 items */
4476
+ 'between' => sprintf( __('%s, %s'), '', '' ),
4477
+ /* translators: used to join last two items in a list with more than 2 times */
4478
+ 'between_last_two' => sprintf( __('%s, and %s'), '', '' ),
4479
+ /* translators: used to join items in a list with only 2 items */
4480
+ 'between_only_two' => sprintf( __('%s and %s'), '', '' ),
4481
+ ) );
4482
+
4483
+ $args = (array) $args;
4484
+ $result = array_shift($args);
4485
+ if ( count($args) == 1 )
4486
+ $result .= $l['between_only_two'] . array_shift($args);
4487
+ // Loop when more than two args
4488
+ $i = count($args);
4489
+ while ( $i ) {
4490
+ $arg = array_shift($args);
4491
+ $i--;
4492
+ if ( 0 == $i )
4493
+ $result .= $l['between_last_two'] . $arg;
4494
+ else
4495
+ $result .= $l['between'] . $arg;
4496
+ }
4497
+ return $result . substr($pattern, 2);
4498
+ }
4499
+
4500
+ /**
4501
+ * Safely extracts not more than the first $count characters from html string.
4502
+ *
4503
+ * UTF-8, tags and entities safe prefix extraction. Entities inside will *NOT*
4504
+ * be counted as one character. For example &amp; will be counted as 4, &lt; as
4505
+ * 3, etc.
4506
+ *
4507
+ * @since 2.5.0
4508
+ *
4509
+ * @param string $str String to get the excerpt from.
4510
+ * @param int $count Maximum number of characters to take.
4511
+ * @param string $more Optional. What to append if $str needs to be trimmed. Defaults to empty string.
4512
+ * @return string The excerpt.
4513
+ */
4514
+ function wp_html_excerpt( $str, $count, $more = null ) {
4515
+ if ( null === $more )
4516
+ $more = '';
4517
+ $str = wp_strip_all_tags( $str, true );
4518
+ $excerpt = mb_substr( $str, 0, $count );
4519
+ // remove part of an entity at the end
4520
+ $excerpt = preg_replace( '/&[^;\s]{0,6}$/', '', $excerpt );
4521
+ if ( $str != $excerpt )
4522
+ $excerpt = trim( $excerpt ) . $more;
4523
+ return $excerpt;
4524
+ }
4525
+
4526
+ /**
4527
+ * Add a Base url to relative links in passed content.
4528
+ *
4529
+ * By default it supports the 'src' and 'href' attributes. However this can be
4530
+ * changed via the 3rd param.
4531
+ *
4532
+ * @since 2.7.0
4533
+ *
4534
+ * @global string $_links_add_base
4535
+ *
4536
+ * @param string $content String to search for links in.
4537
+ * @param string $base The base URL to prefix to links.
4538
+ * @param array $attrs The attributes which should be processed.
4539
+ * @return string The processed content.
4540
+ */
4541
+ function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) {
4542
+ global $_links_add_base;
4543
+ $_links_add_base = $base;
4544
+ $attrs = implode('|', (array)$attrs);
4545
+ return preg_replace_callback( "!($attrs)=(['\"])(.+?)\\2!i", '_links_add_base', $content );
4546
+ }
4547
+
4548
+ /**
4549
+ * Callback to add a base url to relative links in passed content.
4550
+ *
4551
+ * @since 2.7.0
4552
+ * @access private
4553
+ *
4554
+ * @global string $_links_add_base
4555
+ *
4556
+ * @param string $m The matched link.
4557
+ * @return string The processed link.
4558
+ */
4559
+ function _links_add_base( $m ) {
4560
+ global $_links_add_base;
4561
+ //1 = attribute name 2 = quotation mark 3 = URL
4562
+ return $m[1] . '=' . $m[2] .
4563
+ ( preg_match( '#^(\w{1,20}):#', $m[3], $protocol ) && in_array( $protocol[1], wp_allowed_protocols() ) ?
4564
+ $m[3] :
4565
+ WP_Http::make_absolute_url( $m[3], $_links_add_base )
4566
+ )
4567
+ . $m[2];
4568
+ }
4569
+
4570
+ /**
4571
+ * Adds a Target attribute to all links in passed content.
4572
+ *
4573
+ * This function by default only applies to `<a>` tags, however this can be
4574
+ * modified by the 3rd param.
4575
+ *
4576
+ * *NOTE:* Any current target attributed will be stripped and replaced.
4577
+ *
4578
+ * @since 2.7.0
4579
+ *
4580
+ * @global string $_links_add_target
4581
+ *
4582
+ * @param string $content String to search for links in.
4583
+ * @param string $target The Target to add to the links.
4584
+ * @param array $tags An array of tags to apply to.
4585
+ * @return string The processed content.
4586
+ */
4587
+ function links_add_target( $content, $target = '_blank', $tags = array('a') ) {
4588
+ global $_links_add_target;
4589
+ $_links_add_target = $target;
4590
+ $tags = implode('|', (array)$tags);
4591
+ return preg_replace_callback( "!<($tags)([^>]*)>!i", '_links_add_target', $content );
4592
+ }
4593
+
4594
+ /**
4595
+ * Callback to add a target attribute to all links in passed content.
4596
+ *
4597
+ * @since 2.7.0
4598
+ * @access private
4599
+ *
4600
+ * @global string $_links_add_target
4601
+ *
4602
+ * @param string $m The matched link.
4603
+ * @return string The processed link.
4604
+ */
4605
+ function _links_add_target( $m ) {
4606
+ global $_links_add_target;
4607
+ $tag = $m[1];
4608
+ $link = preg_replace('|( target=([\'"])(.*?)\2)|i', '', $m[2]);
4609
+ return '<' . $tag . $link . ' target="' . esc_attr( $_links_add_target ) . '">';
4610
+ }
4611
+
4612
+ /**
4613
+ * Normalize EOL characters and strip duplicate whitespace.
4614
+ *
4615
+ * @since 2.7.0
4616
+ *
4617
+ * @param string $str The string to normalize.
4618
+ * @return string The normalized string.
4619
+ */
4620
+ function normalize_whitespace( $str ) {
4621
+ $str = trim( $str );
4622
+ $str = str_replace( "\r", "\n", $str );
4623
+ $str = preg_replace( array( '/\n+/', '/[ \t]+/' ), array( "\n", ' ' ), $str );
4624
+ return $str;
4625
+ }
4626
+
4627
+ /**
4628
+ * Properly strip all HTML tags including script and style
4629
+ *
4630
+ * This differs from strip_tags() because it removes the contents of
4631
+ * the `<script>` and `<style>` tags. E.g. `strip_tags( '<script>something</script>' )`
4632
+ * will return 'something'. wp_strip_all_tags will return ''
4633
+ *
4634
+ * @since 2.9.0
4635
+ *
4636
+ * @param string $string String containing HTML tags
4637
+ * @param bool $remove_breaks Optional. Whether to remove left over line breaks and white space chars
4638
+ * @return string The processed string.
4639
+ */
4640
+ function wp_strip_all_tags($string, $remove_breaks = false) {
4641
+ $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string );
4642
+ $string = strip_tags($string);
4643
+
4644
+ if ( $remove_breaks )
4645
+ $string = preg_replace('/[\r\n\t ]+/', ' ', $string);
4646
+
4647
+ return trim( $string );
4648
+ }
4649
+
4650
+ /**
4651
+ * Sanitizes a string from user input or from the database.
4652
+ *
4653
+ * - Checks for invalid UTF-8,
4654
+ * - Converts single `<` characters to entities
4655
+ * - Strips all tags
4656
+ * - Removes line breaks, tabs, and extra whitespace
4657
+ * - Strips octets
4658
+ *
4659
+ * @since 2.9.0
4660
+ *
4661
+ * @see sanitize_textarea_field()
4662
+ * @see wp_check_invalid_utf8()
4663
+ * @see wp_strip_all_tags()
4664
+ *
4665
+ * @param string $str String to sanitize.
4666
+ * @return string Sanitized string.
4667
+ */
4668
+ function sanitize_text_field( $str ) {
4669
+ $filtered = _sanitize_text_fields( $str, false );
4670
+
4671
+ /**
4672
+ * Filters a sanitized text field string.
4673
+ *
4674
+ * @since 2.9.0
4675
+ *
4676
+ * @param string $filtered The sanitized string.
4677
+ * @param string $str The string prior to being sanitized.
4678
+ */
4679
+ return apply_filters( 'sanitize_text_field', $filtered, $str );
4680
+ }
4681
+
4682
+ /**
4683
+ * Sanitizes a multiline string from user input or from the database.
4684
+ *
4685
+ * The function is like sanitize_text_field(), but preserves
4686
+ * new lines (\n) and other whitespace, which are legitimate
4687
+ * input in textarea elements.
4688
+ *
4689
+ * @see sanitize_text_field()
4690
+ *
4691
+ * @since 4.7.0
4692
+ *
4693
+ * @param string $str String to sanitize.
4694
+ * @return string Sanitized string.
4695
+ */
4696
+ function sanitize_textarea_field( $str ) {
4697
+ $filtered = _sanitize_text_fields( $str, true );
4698
+
4699
+ /**
4700
+ * Filters a sanitized textarea field string.
4701
+ *
4702
+ * @since 4.7.0
4703
+ *
4704
+ * @param string $filtered The sanitized string.
4705
+ * @param string $str The string prior to being sanitized.
4706
+ */
4707
+ return apply_filters( 'sanitize_textarea_field', $filtered, $str );
4708
+ }
4709
+
4710
+ /**
4711
+ * Internal helper function to sanitize a string from user input or from the db
4712
+ *
4713
+ * @since 4.7.0
4714
+ * @access private
4715
+ *
4716
+ * @param string $str String to sanitize.
4717
+ * @param bool $keep_newlines optional Whether to keep newlines. Default: false.
4718
+ * @return string Sanitized string.
4719
+ */
4720
+ function _sanitize_text_fields( $str, $keep_newlines = false ) {
4721
+ $filtered = wp_check_invalid_utf8( $str );
4722
+
4723
+ if ( strpos($filtered, '<') !== false ) {
4724
+ $filtered = wp_pre_kses_less_than( $filtered );
4725
+ // This will strip extra whitespace for us.
4726
+ $filtered = wp_strip_all_tags( $filtered, false );
4727
+
4728
+ // Use html entities in a special case to make sure no later
4729
+ // newline stripping stage could lead to a functional tag
4730
+ $filtered = str_replace("<\n", "&lt;\n", $filtered);
4731
+ }
4732
+
4733
+ if ( ! $keep_newlines ) {
4734
+ $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
4735
+ }
4736
+ $filtered = trim( $filtered );
4737
+
4738
+ $found = false;
4739
+ while ( preg_match('/%[a-f0-9]{2}/i', $filtered, $match) ) {
4740
+ $filtered = str_replace($match[0], '', $filtered);
4741
+ $found = true;
4742
+ }
4743
+
4744
+ if ( $found ) {
4745
+ // Strip out the whitespace that may now exist after removing the octets.
4746
+ $filtered = trim( preg_replace('/ +/', ' ', $filtered) );
4747
+ }
4748
+
4749
+ return $filtered;
4750
+ }
4751
+
4752
+ /**
4753
+ * i18n friendly version of basename()
4754
+ *
4755
+ * @since 3.1.0
4756
+ *
4757
+ * @param string $path A path.
4758
+ * @param string $suffix If the filename ends in suffix this will also be cut off.
4759
+ * @return string
4760
+ */
4761
+ function wp_basename( $path, $suffix = '' ) {
4762
+ return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) );
4763
+ }
4764
+
4765
+ /**
4766
+ * Forever eliminate "Wordpress" from the planet (or at least the little bit we can influence).
4767
+ *
4768
+ * Violating our coding standards for a good function name.
4769
+ *
4770
+ * @since 3.0.0
4771
+ *
4772
+ * @staticvar string|false $dblq
4773
+ *
4774
+ * @param string $text The text to be modified.
4775
+ * @return string The modified text.
4776
+ */
4777
+ function capital_P_dangit( $text ) {
4778
+ // Simple replacement for titles
4779
+ $current_filter = current_filter();
4780
+ if ( 'the_title' === $current_filter || 'wp_title' === $current_filter )
4781
+ return str_replace( 'Wordpress', 'WordPress', $text );
4782
+ // Still here? Use the more judicious replacement
4783
+ static $dblq = false;
4784
+ if ( false === $dblq ) {
4785
+ $dblq = _x( '&#8220;', 'opening curly double quote' );
4786
+ }
4787
+ return str_replace(
4788
+ array( ' Wordpress', '&#8216;Wordpress', $dblq . 'Wordpress', '>Wordpress', '(Wordpress' ),
4789
+ array( ' WordPress', '&#8216;WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ),
4790
+ $text );
4791
+ }
4792
+
4793
+ /**
4794
+ * Sanitize a mime type
4795
+ *
4796
+ * @since 3.1.3
4797
+ *
4798
+ * @param string $mime_type Mime type
4799
+ * @return string Sanitized mime type
4800
+ */
4801
+ function sanitize_mime_type( $mime_type ) {
4802
+ $sani_mime_type = preg_replace( '/[^-+*.a-zA-Z0-9\/]/', '', $mime_type );
4803
+ /**
4804
+ * Filters a mime type following sanitization.
4805
+ *
4806
+ * @since 3.1.3
4807
+ *
4808
+ * @param string $sani_mime_type The sanitized mime type.
4809
+ * @param string $mime_type The mime type prior to sanitization.
4810
+ */
4811
+ return apply_filters( 'sanitize_mime_type', $sani_mime_type, $mime_type );
4812
+ }
4813
+
4814
+ /**
4815
+ * Sanitize space or carriage return separated URLs that are used to send trackbacks.
4816
+ *
4817
+ * @since 3.4.0
4818
+ *
4819
+ * @param string $to_ping Space or carriage return separated URLs
4820
+ * @return string URLs starting with the http or https protocol, separated by a carriage return.
4821
+ */
4822
+ function sanitize_trackback_urls( $to_ping ) {
4823
+ $urls_to_ping = preg_split( '/[\r\n\t ]/', trim( $to_ping ), -1, PREG_SPLIT_NO_EMPTY );
4824
+ foreach ( $urls_to_ping as $k => $url ) {
4825
+ if ( !preg_match( '#^https?://.#i', $url ) )
4826
+ unset( $urls_to_ping[$k] );
4827
+ }
4828
+ $urls_to_ping = array_map( 'esc_url_raw', $urls_to_ping );
4829
+ $urls_to_ping = implode( "\n", $urls_to_ping );
4830
+ /**
4831
+ * Filters a list of trackback URLs following sanitization.
4832
+ *
4833
+ * The string returned here consists of a space or carriage return-delimited list
4834
+ * of trackback URLs.
4835
+ *
4836
+ * @since 3.4.0
4837
+ *
4838
+ * @param string $urls_to_ping Sanitized space or carriage return separated URLs.
4839
+ * @param string $to_ping Space or carriage return separated URLs before sanitization.
4840
+ */
4841
+ return apply_filters( 'sanitize_trackback_urls', $urls_to_ping, $to_ping );
4842
+ }
4843
+
4844
+ /**
4845
+ * Add slashes to a string or array of strings.
4846
+ *
4847
+ * This should be used when preparing data for core API that expects slashed data.
4848
+ * This should not be used to escape data going directly into an SQL query.
4849
+ *
4850
+ * @since 3.6.0
4851
+ *
4852
+ * @param string|array $value String or array of strings to slash.
4853
+ * @return string|array Slashed $value
4854
+ */
4855
+ function wp_slash( $value ) {
4856
+ if ( is_array( $value ) ) {
4857
+ foreach ( $value as $k => $v ) {
4858
+ if ( is_array( $v ) ) {
4859
+ $value[$k] = wp_slash( $v );
4860
+ } else {
4861
+ $value[$k] = addslashes( $v );
4862
+ }
4863
+ }
4864
+ } else {
4865
+ $value = addslashes( $value );
4866
+ }
4867
+
4868
+ return $value;
4869
+ }
4870
+
4871
+ /**
4872
+ * Remove slashes from a string or array of strings.
4873
+ *
4874
+ * This should be used to remove slashes from data passed to core API that
4875
+ * expects data to be unslashed.
4876
+ *
4877
+ * @since 3.6.0
4878
+ *
4879
+ * @param string|array $value String or array of strings to unslash.
4880
+ * @return string|array Unslashed $value
4881
+ */
4882
+ function wp_unslash( $value ) {
4883
+ return stripslashes_deep( $value );
4884
+ }
4885
+
4886
+ /**
4887
+ * Extract and return the first URL from passed content.
4888
+ *
4889
+ * @since 3.6.0
4890
+ *
4891
+ * @param string $content A string which might contain a URL.
4892
+ * @return string|false The found URL.
4893
+ */
4894
+ function get_url_in_content( $content ) {
4895
+ if ( empty( $content ) ) {
4896
+ return false;
4897
+ }
4898
+
4899
+ if ( preg_match( '/<a\s[^>]*?href=([\'"])(.+?)\1/is', $content, $matches ) ) {
4900
+ return esc_url_raw( $matches[2] );
4901
+ }
4902
+
4903
+ return false;
4904
+ }
4905
+
4906
+ /**
4907
+ * Returns the regexp for common whitespace characters.
4908
+ *
4909
+ * By default, spaces include new lines, tabs, nbsp entities, and the UTF-8 nbsp.
4910
+ * This is designed to replace the PCRE \s sequence. In ticket #22692, that
4911
+ * sequence was found to be unreliable due to random inclusion of the A0 byte.
4912
+ *
4913
+ * @since 4.0.0
4914
+ *
4915
+ * @staticvar string $spaces
4916
+ *
4917
+ * @return string The spaces regexp.
4918
+ */
4919
+ function wp_spaces_regexp() {
4920
+ static $spaces = '';
4921
+
4922
+ if ( empty( $spaces ) ) {
4923
+ /**
4924
+ * Filters the regexp for common whitespace characters.
4925
+ *
4926
+ * This string is substituted for the \s sequence as needed in regular
4927
+ * expressions. For websites not written in English, different characters
4928
+ * may represent whitespace. For websites not encoded in UTF-8, the 0xC2 0xA0
4929
+ * sequence may not be in use.
4930
+ *
4931
+ * @since 4.0.0
4932
+ *
4933
+ * @param string $spaces Regexp pattern for matching common whitespace characters.
4934
+ */
4935
+ $spaces = apply_filters( 'wp_spaces_regexp', '[\r\n\t ]|\xC2\xA0|&nbsp;' );
4936
+ }
4937
+
4938
+ return $spaces;
4939
+ }
4940
+
4941
+ /**
4942
+ * Print the important emoji-related styles.
4943
+ *
4944
+ * @since 4.2.0
4945
+ *
4946
+ * @staticvar bool $printed
4947
+ */
4948
+ function print_emoji_styles() {
4949
+ static $printed = false;
4950
+
4951
+ if ( $printed ) {
4952
+ return;
4953
+ }
4954
+
4955
+ $printed = true;
4956
+ ?>
4957
+ <style type="text/css">
4958
+ img.wp-smiley,
4959
+ img.emoji {
4960
+ display: inline !important;
4961
+ border: none !important;
4962
+ box-shadow: none !important;
4963
+ height: 1em !important;
4964
+ width: 1em !important;
4965
+ margin: 0 .07em !important;
4966
+ vertical-align: -0.1em !important;
4967
+ background: none !important;
4968
+ padding: 0 !important;
4969
+ }
4970
+ </style>
4971
+ <?php
4972
+ }
4973
+
4974
+ /**
4975
+ * Print the inline Emoji detection script if it is not already printed.
4976
+ *
4977
+ * @since 4.2.0
4978
+ * @staticvar bool $printed
4979
+ */
4980
+ function print_emoji_detection_script() {
4981
+ static $printed = false;
4982
+
4983
+ if ( $printed ) {
4984
+ return;
4985
+ }
4986
+
4987
+ $printed = true;
4988
+
4989
+ _print_emoji_detection_script();
4990
+ }
4991
+
4992
+ /**
4993
+ * Prints inline Emoji dection script
4994
+ *
4995
+ * @ignore
4996
+ * @since 4.6.0
4997
+ * @access private
4998
+ */
4999
+ function _print_emoji_detection_script() {
5000
+ $settings = array(
5001
+ /**
5002
+ * Filters the URL where emoji png images are hosted.
5003
+ *
5004
+ * @since 4.2.0
5005
+ *
5006
+ * @param string The emoji base URL for png images.
5007
+ */
5008
+ 'baseUrl' => apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/2.2.1/72x72/' ),
5009
+
5010
+ /**
5011
+ * Filters the extension of the emoji png files.
5012
+ *
5013
+ * @since 4.2.0
5014
+ *
5015
+ * @param string The emoji extension for png files. Default .png.
5016
+ */
5017
+ 'ext' => apply_filters( 'emoji_ext', '.png' ),
5018
+
5019
+ /**
5020
+ * Filters the URL where emoji SVG images are hosted.
5021
+ *
5022
+ * @since 4.6.0
5023
+ *
5024
+ * @param string The emoji base URL for svg images.
5025
+ */
5026
+ 'svgUrl' => apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2.2.1/svg/' ),
5027
+
5028
+ /**
5029
+ * Filters the extension of the emoji SVG files.
5030
+ *
5031
+ * @since 4.6.0
5032
+ *
5033
+ * @param string The emoji extension for svg files. Default .svg.
5034
+ */
5035
+ 'svgExt' => apply_filters( 'emoji_svg_ext', '.svg' ),
5036
+ );
5037
+
5038
+ $version = 'ver=' . get_bloginfo( 'version' );
5039
+
5040
+ if ( SCRIPT_DEBUG ) {
5041
+ $settings['source'] = array(
5042
+ /** This filter is documented in wp-includes/class.wp-scripts.php */
5043
+ 'wpemoji' => apply_filters( 'script_loader_src', includes_url( "js/wp-emoji.js?$version" ), 'wpemoji' ),
5044
+ /** This filter is documented in wp-includes/class.wp-scripts.php */
5045
+ 'twemoji' => apply_filters( 'script_loader_src', includes_url( "js/twemoji.js?$version" ), 'twemoji' ),
5046
+ );
5047
+
5048
+ ?>
5049
+ <script type="text/javascript">
5050
+ window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>;
5051
+ <?php readfile( ABSPATH . WPINC . "/js/wp-emoji-loader.js" ); ?>
5052
+ </script>
5053
+ <?php
5054
+ } else {
5055
+ $settings['source'] = array(
5056
+ /** This filter is documented in wp-includes/class.wp-scripts.php */
5057
+ 'concatemoji' => apply_filters( 'script_loader_src', includes_url( "js/wp-emoji-release.min.js?$version" ), 'concatemoji' ),
5058
+ );
5059
+
5060
+ /*
5061
+ * If you're looking at a src version of this file, you'll see an "include"
5062
+ * statement below. This is used by the `grunt build` process to directly
5063
+ * include a minified version of wp-emoji-loader.js, instead of using the
5064
+ * readfile() method from above.
5065
+ *
5066
+ * If you're looking at a build version of this file, you'll see a string of
5067
+ * minified JavaScript. If you need to debug it, please turn on SCRIPT_DEBUG
5068
+ * and edit wp-emoji-loader.js directly.
5069
+ */
5070
+ ?>
5071
+ <script type="text/javascript">
5072
+ window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>;
5073
+ !function(a,b,c){function d(a){var b,c,d,e,f=String.fromCharCode;if(!k||!k.fillText)return!1;switch(k.clearRect(0,0,j.width,j.height),k.textBaseline="top",k.font="600 32px Arial",a){case"flag":return k.fillText(f(55356,56826,55356,56819),0,0),!(j.toDataURL().length<3e3)&&(k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,57331,65039,8205,55356,57096),0,0),b=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,57331,55356,57096),0,0),c=j.toDataURL(),b!==c);case"emoji4":return k.fillText(f(55357,56425,55356,57341,8205,55357,56507),0,0),d=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55357,56425,55356,57341,55357,56507),0,0),e=j.toDataURL(),d!==e}return!1}function e(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var f,g,h,i,j=b.createElement("canvas"),k=j.getContext&&j.getContext("2d");for(i=Array("flag","emoji4"),c.supports={everything:!0,everythingExceptFlag:!0},h=0;h<i.length;h++)c.supports[i[h]]=d(i[h]),c.supports.everything=c.supports.everything&&c.supports[i[h]],"flag"!==i[h]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[i[h]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(g=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",g,!1),a.addEventListener("load",g,!1)):(a.attachEvent("onload",g),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),f=c.source||{},f.concatemoji?e(f.concatemoji):f.wpemoji&&f.twemoji&&(e(f.twemoji),e(f.wpemoji)))}(window,document,window._wpemojiSettings);
5074
+ </script>
5075
+ <?php
5076
+ }
5077
+ }
5078
+
5079
+ /**
5080
+ * Convert any 4 byte emoji in a string to their equivalent HTML entity.
5081
+ *
5082
+ * Currently, only Unicode 7 emoji are supported. Skin tone modifiers are allowed,
5083
+ * all other Unicode 8 emoji will be added when the spec is finalised.
5084
+ *
5085
+ * This allows us to store emoji in a DB using the utf8 character set.
5086
+ *
5087
+ * @since 4.2.0
5088
+ *
5089
+ * @param string $content The content to encode.
5090
+ * @return string The encoded content.
5091
+ */
5092
+ function wp_encode_emoji( $content ) {
5093
+ if ( function_exists( 'mb_convert_encoding' ) ) {
5094
+ $regex = '/(
5095
+ \x23\xE2\x83\xA3 # Digits
5096
+ [\x30-\x39]\xE2\x83\xA3
5097
+ | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters
5098
+ | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc
5099
+ | \xF0\x9F\x98[\x80-\xBF] # Smilies
5100
+ | \xF0\x9F\x99[\x80-\x8F]
5101
+ | \xF0\x9F\x9A[\x80-\xBF] # Transport and map symbols
5102
+ )/x';
5103
+
5104
+ $matches = array();
5105
+ if ( preg_match_all( $regex, $content, $matches ) ) {
5106
+ if ( ! empty( $matches[1] ) ) {
5107
+ foreach ( $matches[1] as $emoji ) {
5108
+ /*
5109
+ * UTF-32's hex encoding is the same as HTML's hex encoding.
5110
+ * So, by converting the emoji from UTF-8 to UTF-32, we magically
5111
+ * get the correct hex encoding.
5112
+ */
5113
+ $unpacked = unpack( 'H*', mb_convert_encoding( $emoji, 'UTF-32', 'UTF-8' ) );
5114
+ if ( isset( $unpacked[1] ) ) {
5115
+ $entity = '&#x' . ltrim( $unpacked[1], '0' ) . ';';
5116
+ $content = str_replace( $emoji, $entity, $content );
5117
+ }
5118
+ }
5119
+ }
5120
+ }
5121
+ }
5122
+
5123
+ return $content;
5124
+ }
5125
+
5126
+ /**
5127
+ * Convert emoji to a static img element.
5128
+ *
5129
+ * @since 4.2.0
5130
+ *
5131
+ * @param string $text The content to encode.
5132
+ * @return string The encoded content.
5133
+ */
5134
+ function wp_staticize_emoji( $text ) {
5135
+ $text = wp_encode_emoji( $text );
5136
+
5137
+ /** This filter is documented in wp-includes/formatting.php */
5138
+ $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/2.2.1/72x72/' );
5139
+
5140
+ /** This filter is documented in wp-includes/formatting.php */
5141
+ $ext = apply_filters( 'emoji_ext', '.png' );
5142
+
5143
+ $output = '';
5144
+ /*
5145
+ * HTML loop taken from smiley function, which was taken from texturize function.
5146
+ * It'll never be consolidated.
5147
+ *
5148
+ * First, capture the tags as well as in between.
5149
+ */
5150
+ $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE );
5151
+ $stop = count( $textarr );
5152
+
5153
+ // Ignore processing of specific tags.
5154
+ $tags_to_ignore = 'code|pre|style|script|textarea';
5155
+ $ignore_block_element = '';
5156
+
5157
+ for ( $i = 0; $i < $stop; $i++ ) {
5158
+ $content = $textarr[$i];
5159
+
5160
+ // If we're in an ignore block, wait until we find its closing tag.
5161
+ if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
5162
+ $ignore_block_element = $matches[1];
5163
+ }
5164
+
5165
+ // If it's not a tag and not in ignore block.
5166
+ if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) {
5167
+ $matches = array();
5168
+ if ( preg_match_all( '/(&#x1f1(e[6-9a-f]|f[0-9a-f]);){2}/', $content, $matches ) ) {
5169
+ if ( ! empty( $matches[0] ) ) {
5170
+ foreach ( $matches[0] as $flag ) {
5171
+ $chars = str_replace( array( '&#x', ';'), '', $flag );
5172
+
5173
+ list( $char1, $char2 ) = str_split( $chars, 5 );
5174
+ $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $char1 . '-' . $char2 . $ext, html_entity_decode( $flag ) );
5175
+
5176
+ $content = str_replace( $flag, $entity, $content );
5177
+ }
5178
+ }
5179
+ }
5180
+
5181
+ // Loosely match the Emoji Unicode range.
5182
+ $regex = '/(&#x[2-3][0-9a-f]{3};|&#x1f[1-6][0-9a-f]{2};)/';
5183
+
5184
+ $matches = array();
5185
+ if ( preg_match_all( $regex, $content, $matches ) ) {
5186
+ if ( ! empty( $matches[1] ) ) {
5187
+ foreach ( $matches[1] as $emoji ) {
5188
+ $char = str_replace( array( '&#x', ';'), '', $emoji );
5189
+ $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $char . $ext, html_entity_decode( $emoji ) );
5190
+
5191
+ $content = str_replace( $emoji, $entity, $content );
5192
+ }
5193
+ }
5194
+ }
5195
+ }
5196
+
5197
+ // Did we exit ignore block.
5198
+ if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) {
5199
+ $ignore_block_element = '';
5200
+ }
5201
+
5202
+ $output .= $content;
5203
+ }
5204
+
5205
+ return $output;
5206
+ }
5207
+
5208
+ /**
5209
+ * Convert emoji in emails into static images.
5210
+ *
5211
+ * @since 4.2.0
5212
+ *
5213
+ * @param array $mail The email data array.
5214
+ * @return array The email data array, with emoji in the message staticized.
5215
+ */
5216
+ function wp_staticize_emoji_for_email( $mail ) {
5217
+ if ( ! isset( $mail['message'] ) ) {
5218
+ return $mail;
5219
+ }
5220
+
5221
+ /*
5222
+ * We can only transform the emoji into images if it's a text/html email.
5223
+ * To do that, here's a cut down version of the same process that happens
5224
+ * in wp_mail() - get the Content-Type from the headers, if there is one,
5225
+ * then pass it through the wp_mail_content_type filter, in case a plugin
5226
+ * is handling changing the Content-Type.
5227
+ */
5228
+ $headers = array();
5229
+ if ( isset( $mail['headers'] ) ) {
5230
+ if ( is_array( $mail['headers'] ) ) {
5231
+ $headers = $mail['headers'];
5232
+ } else {
5233
+ $headers = explode( "\n", str_replace( "\r\n", "\n", $mail['headers'] ) );
5234
+ }
5235
+ }
5236
+
5237
+ foreach ( $headers as $header ) {
5238
+ if ( strpos($header, ':') === false ) {
5239
+ continue;
5240
+ }
5241
+
5242
+ // Explode them out.
5243
+ list( $name, $content ) = explode( ':', trim( $header ), 2 );
5244
+
5245
+ // Cleanup crew.
5246
+ $name = trim( $name );
5247
+ $content = trim( $content );
5248
+
5249
+ if ( 'content-type' === strtolower( $name ) ) {
5250
+ if ( strpos( $content, ';' ) !== false ) {
5251
+ list( $type, $charset ) = explode( ';', $content );
5252
+ $content_type = trim( $type );
5253
+ } else {
5254
+ $content_type = trim( $content );
5255
+ }
5256
+ break;
5257
+ }
5258
+ }
5259
+
5260
+ // Set Content-Type if we don't have a content-type from the input headers.
5261
+ if ( ! isset( $content_type ) ) {
5262
+ $content_type = 'text/plain';
5263
+ }
5264
+
5265
+ /** This filter is documented in wp-includes/pluggable.php */
5266
+ $content_type = apply_filters( 'wp_mail_content_type', $content_type );
5267
+
5268
+ if ( 'text/html' === $content_type ) {
5269
+ $mail['message'] = wp_staticize_emoji( $mail['message'] );
5270
+ }
5271
+
5272
+ return $mail;
5273
+ }
5274
+
5275
+ /**
5276
+ * Shorten a URL, to be used as link text.
5277
+ *
5278
+ * @since 1.2.0
5279
+ * @since 4.4.0 Moved to wp-includes/formatting.php from wp-admin/includes/misc.php and added $length param.
5280
+ *
5281
+ * @param string $url URL to shorten.
5282
+ * @param int $length Optional. Maximum length of the shortened URL. Default 35 characters.
5283
+ * @return string Shortened URL.
5284
+ */
5285
+ function url_shorten( $url, $length = 35 ) {
5286
+ $stripped = str_replace( array( 'https://', 'http://', 'www.' ), '', $url );
5287
+ $short_url = untrailingslashit( $stripped );
5288
+
5289
+ if ( strlen( $short_url ) > $length ) {
5290
+ $short_url = substr( $short_url, 0, $length - 3 ) . '&hellip;';
5291
+ }
5292
+ return $short_url;
5293
+ }
5294
+
5295
+ /**
5296
+ * Sanitizes a hex color.
5297
+ *
5298
+ * Returns either '', a 3 or 6 digit hex color (with #), or nothing.
5299
+ * For sanitizing values without a #, see sanitize_hex_color_no_hash().
5300
+ *
5301
+ * @since 3.4.0
5302
+ *
5303
+ * @param string $color
5304
+ * @return string|void
5305
+ */
5306
+ function sanitize_hex_color( $color ) {
5307
+ if ( '' === $color ) {
5308
+ return '';
5309
+ }
5310
+
5311
+ // 3 or 6 hex digits, or the empty string.
5312
+ if ( preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
5313
+ return $color;
5314
+ }
5315
+ }
5316
+
5317
+ /**
5318
+ * Sanitizes a hex color without a hash. Use sanitize_hex_color() when possible.
5319
+ *
5320
+ * Saving hex colors without a hash puts the burden of adding the hash on the
5321
+ * UI, which makes it difficult to use or upgrade to other color types such as
5322
+ * rgba, hsl, rgb, and html color names.
5323
+ *
5324
+ * Returns either '', a 3 or 6 digit hex color (without a #), or null.
5325
+ *
5326
+ * @since 3.4.0
5327
+ *
5328
+ * @param string $color
5329
+ * @return string|null
5330
+ */
5331
+ function sanitize_hex_color_no_hash( $color ) {
5332
+ $color = ltrim( $color, '#' );
5333
+
5334
+ if ( '' === $color ) {
5335
+ return '';
5336
+ }
5337
+
5338
+ return sanitize_hex_color( '#' . $color ) ? $color : null;
5339
+ }
5340
+
5341
+ /**
5342
+ * Ensures that any hex color is properly hashed.
5343
+ * Otherwise, returns value untouched.
5344
+ *
5345
+ * This method should only be necessary if using sanitize_hex_color_no_hash().
5346
+ *
5347
+ * @since 3.4.0
5348
+ *
5349
+ * @param string $color
5350
+ * @return string
5351
+ */
5352
+ function maybe_hash_hex_color( $color ) {
5353
+ if ( $unhashed = sanitize_hex_color_no_hash( $color ) ) {
5354
+ return '#' . $unhashed;
5355
+ }
5356
+
5357
+ return $color;
5358
+ }
app/design/frontend/base/default/template/wordpress/post/list/renderer/default.phtml CHANGED
@@ -26,7 +26,7 @@
26
  *
27
  **/
28
  ?>
29
- <?php echo $post->getPostExcerpt() ?>
30
  <?php else: ?>
31
  <?php echo $post->getPostContent() ?>
32
  <?php endif; ?>
26
  *
27
  **/
28
  ?>
29
+ <?php echo $post->getPostExcerpt(50) ?>
30
  <?php else: ?>
31
  <?php echo $post->getPostContent() ?>
32
  <?php endif; ?>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Fishpig_Wordpress_Integration</name>
4
- <version>4.2.1.8</version>
5
  <stability>stable</stability>
6
  <license uri="http://fishpig.co.uk/license.txt">FishPig EULA</license>
7
  <channel>community</channel>
@@ -10,9 +10,9 @@
10
  <description>Easily integrate Magento and WordPress without modifying any core files.</description>
11
  <notes>For changes, please see http://fishpig.co.uk/magento/wordpress-integration/#changelog</notes>
12
  <authors><author><name>fishpig</name><user>fishpig</user><email>ben@fishpig.co.uk</email></author></authors>
13
- <date>2017-02-17</date>
14
- <time>11:26:19</time>
15
- <contents><target name="magecommunity"><dir name="Fishpig"><dir name="Wordpress"><dir name="Block"><file name="Abstract.php" hash="bf9e97598ed72068b3172dc477978c9f"/><dir name="Adminhtml"><dir name="Associations"><file name="Abstract.php" hash="dd589f8fcae2122632457e08c01aa774"/><dir name="Category"><file name="Category.php" hash="26782c6bc34cfbf7f81d1775c40a8a35"/><file name="Post.php" hash="1dd1330e619bdff79ad7d7c6fd08edd6"/></dir><dir name="Cms"><dir name="Page"><file name="Category.php" hash="7442c0874792bc08438c472875368b21"/><file name="Post.php" hash="5bed4c4e1baa1d0f0430d5cdfa87d020"/></dir></dir><dir name="Product"><file name="Category.php" hash="f99636a65b55ccc8818a98230439949d"/><file name="Post.php" hash="0493ae37198cbf50f5ae45565432f894"/></dir></dir><file name="Extend.php" hash="8f5d6ffe4ccb8b48221626ff33882090"/><dir name="Frontend"><file name="Autologin.php" hash="7a795c13d35491ba0a79fd1b15854c6a"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Route.php" hash="cb79ab33659cf906988b1403e0fc625c"/></dir></dir></dir></dir><file name="Update.php" hash="d1aa4001cc758132bcaca792c8dc5f07"/></dir><file name="Ajax.php" hash="0e8e97efddde53b1818c1eaec2b305b0"/><dir name="Archive"><file name="View.php" hash="b56c0c8b9e26a071c28440a0e52e6800"/></dir><dir name="Author"><file name="View.php" hash="03fa439ff3bece2c0cc2e56c2412740a"/></dir><dir name="Feed"><file name="Abstract.php" hash="d8405e51ded312cda6c00b09dd873788"/><dir name="Post"><file name="Comment.php" hash="6e279932f0d45375b5fdee0939e15415"/></dir><file name="Post.php" hash="d1bf0bfcfd687d5f3ca50b341afff560"/></dir><file name="Homepage.php" hash="d5383c14b381594e211a2c7438684d41"/><file name="Menu.php" hash="5dc369f5542bcf6ac87ab7ce8a98c6c1"/><dir name="Page"><file name="View.php" hash="dedf5c07dc52afc6aac0a87fb0c239b6"/></dir><dir name="Post"><file name="Abstract.php" hash="b782a654b478c4067aacba20f0431dc0"/><dir name="Associated"><file name="Products.php" hash="8a74abcfe97df273d75d7fb7b0f9d8d6"/></dir><file name="Associated.php" hash="6fbae669e0269916e578e4f6a1355415"/><dir name="List"><file name="Associated.php" hash="056fd7910da5a30d71c884982297879b"/><file name="Pager.php" hash="7def684fe156c3f59ac8185a0aad345f"/><file name="Renderer.php" hash="35fa1e4294f07d43bf2f8b5e7628161a"/><dir name="Wrapper"><file name="Abstract.php" hash="0a0e7eafe02de151e05353c01d6d4a67"/></dir></dir><file name="List.php" hash="85aa53897a40f88f5dd2f5af982bff8f"/><file name="Meta.php" hash="4482daab91f5c1a731d1d45d79c369b5"/><dir name="View"><dir name="Comment"><file name="Abstract.php" hash="06c0592b3f10c6af2bc8d3d7cdc5a73e"/><file name="Form.php" hash="3a75d0ebbd104076afb8195cc46e339d"/><file name="Pager.php" hash="d0d6c23852f6e4fa894cded53cb289a5"/><file name="Wrapper.php" hash="6318449f58d4a3b11018b3354252f021"/></dir><file name="Comments.php" hash="d3bee9fd86a5318b7986a4d776eed5f7"/></dir><file name="View.php" hash="4a8aca01c7ea5ee32027569c802bbc86"/></dir><dir name="Search"><file name="Result.php" hash="ad8ea64756a575b874afcae9250f6b97"/></dir><dir name="Shortcode"><file name="Product.php" hash="53b1986e1376ea0bdb2a793744253804"/></dir><dir name="Sidebar"><dir name="Widget"><file name="Abstract.php" hash="67234d08da2afec0e61c191ce2e90819"/><file name="Archives.php" hash="cba60c97dc3c9e6b4b73db53787e0aa4"/><file name="Calendar.php" hash="eb838cc8406a0ff3d33b767bdeec0044"/><file name="Categories.php" hash="c9c419da25dd707b8b932abca7bfd892"/><file name="Comments.php" hash="8d38d35bd7aa16188d3b33f3844a6e42"/><file name="Image.php" hash="655fdcb2700a2603539e3008b07b7ae1"/><file name="Instagram.php" hash="ab8a8d7b68f991e91c5e31c3044ebded"/><file name="Links.php" hash="1985b68fd53b3502540e932d25d77ae8"/><file name="Menu.php" hash="5c55903395588b36fa2f6c2779a4ed62"/><file name="Meta.php" hash="942292929971a6705379a87d73e3c226"/><file name="Pages.php" hash="cde08845cca7a7f43ea2e40ca6d090ef"/><file name="Posts.php" hash="1b35086ddc34206ea272856ce447f5dc"/><dir name="Rss"><file name="Abstract.php" hash="c07d0787e920060313db1b7698437c40"/></dir><file name="Rss.php" hash="4b16b12cb7c7370cd4977375d31c184b"/><file name="Search.php" hash="18d02709f88950490e60b00adf98bf54"/><file name="Tagcloud.php" hash="e7ddcb0652286b1442bab0d82aebef00"/><file name="Taxonomy.php" hash="3bb2ee45b014e8aa3a59a15c44cdc03d"/><file name="Text.php" hash="a789e156497390baeb488277b4c837e5"/><file name="Yarpp.php" hash="418b6d211410a98f0336130769c998a0"/></dir></dir><file name="Sidebar.php" hash="06d6ba70df5abb07c23278418efc4089"/><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><dir name="Post"><file name="Type.php" hash="dcc3e93873f10829d1211f8325f40044"/></dir></dir></dir></dir></dir><file name="Template.php" hash="aadd68bcb1da5cfe974d36dabc498754"/><dir name="Term"><file name="View.php" hash="f640abf673b7412cf05528924db2646f"/></dir></dir><dir name="Controller"><file name="Abstract.php" hash="936db8d033b8c257c9d4df5ff919b9e1"/><file name="Router.php" hash="98c155ccd254f43470857a7084bb696e"/><dir name="Router"><file name="Addon.php" hash="896162d5b3608442134e71eb5ab7b06c"/></dir></dir><file name="Exception.php" hash="ef2e08daa502bce27f98d83c9194c8f2"/><dir name="Helper"><file name="Abstract.php" hash="c0e97b8c7b60545b1b127b8439a8e736"/><file name="App.php" hash="8a560c3d8da5bac2f8abeda5a73b1896"/><file name="Associations.php" hash="9a08b34d4eb505059555f3bb65ca4229"/><dir name="Catalog"><file name="Product.php" hash="d00afec7c5bfe37e8ba1aa21d638ae90"/></dir><file name="Data.php" hash="b2fdb68f6a04e8abe9fbf17fb7d75be9"/><file name="Database.php" hash="dcd89ce8c8627c9917206ad65e18f6f3"/><file name="Filter.php" hash="ee675c1fce66b7de954054e12c7b8b62"/><dir name="Plugin"><file name="Abstract.php" hash="c8f9e76ddf381ee131efc9441a2990a2"/><dir name="Seo"><file name="Abstract.php" hash="4cf4a5d807ba6d36670d92d8b8deae1e"/></dir></dir><file name="Plugin.php" hash="046ed88b3892c7456c894d86656113bd"/><file name="Router.php" hash="0218c7adc12511f45afa683184875c95"/><dir name="Shortcode"><file name="Abstract.php" hash="af5f542e136a7171cfb8c4f99f77bdde"/><file name="AssociatedProducts.php" hash="146595bd7d7294794004c8813dad234c"/><file name="Caption.php" hash="47455590dafb7ee27f9872592312d3f0"/><file name="Code.php" hash="002746d8c64e8faa9c2340a4496ae7b6"/><file name="Dailymotion.php" hash="e12adc8cef400f0a382cf69138610426"/><file name="Gallery.php" hash="53ec715f115e2844edf56e22a4687d41"/><file name="Gist.php" hash="c90ad1b6293d29845a38eca66099ca2b"/><file name="Instagram.php" hash="4e155d67366c8c6598b8fdd4c5c395c2"/><file name="Product.php" hash="d37b2513b66a554349b4ccdf854edc11"/><file name="Scribd.php" hash="4b70de264a033be1104dd63d9e78f1c6"/><file name="Spotify.php" hash="d041bb90577d6a8acc1521f95637b302"/><file name="Vimeo.php" hash="83b242ee25c6debc72b3af3c79b97a68"/><file name="Youtube.php" hash="1113665a651bd7f1478111966516b87d"/></dir><file name="Social.php" hash="5ee03cfac0e48660e3a0eb49d4d28d28"/><file name="System.php" hash="afd0fba62df5e72b676564b1b8c77000"/></dir><dir name="Model"><file name="Abstract.php" hash="57aaab0c828039b58b7552c36602927a"/><file name="Archive.php" hash="bf512f09abb2ea7c20e63c1f6e6c734f"/><file name="Image.php" hash="ba5aefa5aaaba530cef51a2237ba5042"/><dir name="Menu"><file name="Item.php" hash="b88d7ee44f3bcc6d1d2521dc89a677f7"/></dir><file name="Menu.php" hash="de877052ac65514d393a131df3d5c142"/><file name="Observer.php" hash="c74292899a8bb47a73df2aee6d4280a6"/><dir name="Post"><dir name="Attachment"><file name="Abstract.php" hash="3068111ba883bacabe87f7fff5f1f795"/></dir><file name="Comment.php" hash="8f7a5797db8aad19b4d55dba6f6ab857"/><file name="Type.php" hash="b789aef92421a82d2cdafe19898356a3"/></dir><file name="Post.php" hash="d719956608034406d13df65518491214"/><dir name="Resource"><file name="Abstract.php" hash="003a37262547fb8f02679739e21338c1"/><dir name="Collection"><file name="Abstract.php" hash="7d9a68175201177ec22deb6f6f29d388"/></dir><dir name="Image"><file name="Collection.php" hash="7d36d6dbe46b12d6a8412dbd07d3bc41"/></dir><file name="Image.php" hash="1b637473b71dd672ccd6a10a4f702ee2"/><dir name="Menu"><file name="Collection.php" hash="7deacc7b99f35392fd8c14ca3905d6ea"/><dir name="Item"><file name="Collection.php" hash="08249f3bed35c5d44adc01bd04ffc7a7"/></dir><file name="Item.php" hash="7e6ebd1cf1b1d4d33f2fb052cfa6e554"/></dir><file name="Menu.php" hash="c0e53a408ce206a801e81d667712dfc0"/><dir name="Post"><dir name="Attachment"><file name="Abstract.php" hash="357167e7379412bd047a2a7d63a7a6c3"/><dir name="Collection"><file name="Abstract.php" hash="c618bf7c6af0b1693c24432616368c71"/></dir></dir><file name="Collection.php" hash="2a71cf7573bc75d7bc3f8abf88bad235"/><dir name="Comment"><file name="Collection.php" hash="a44a18593da1b78efaee9b26be2f7e32"/></dir><file name="Comment.php" hash="1d9a8e258581120a084d84f556911636"/></dir><file name="Post.php" hash="90516c1b09928be401916a33c368a236"/><file name="Setup.php" hash="81d4730bb23b8139cb9e6dc654d366b8"/><dir name="Term"><file name="Collection.php" hash="7089f8aeb441ebac4601fb9e070e74b2"/></dir><file name="Term.php" hash="85f42eaa2f05be6f2cd3fc5268e93559"/><dir name="User"><file name="Collection.php" hash="16e628d55a0fa01747e01a695f709e00"/></dir><file name="User.php" hash="2f3a904ba1a03a9ea36e628059d4b73f"/></dir><dir name="Sitemap"><file name="Sitemap.php" hash="bca54ec7d86e4920e50da0b587c4b99e"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Autologin.php" hash="7d2664238443b07ea685ef3df01f5eff"/><file name="Encrypted.php" hash="520824f9a5533cf790aa8b5bb136e7c9"/></dir><dir name="Source"><file name="Menu.php" hash="9caaf56ff64f3858d4e206c6335c37ec"/><dir name="Social"><dir name="Media"><file name="Service.php" hash="61f66b78e2a122f07a9307b273b62feb"/></dir></dir></dir></dir></dir><dir name="Term"><file name="Taxonomy.php" hash="e2976a1b2c1b7cb7199b88a73dd78ea9"/></dir><file name="Term.php" hash="c185736836c876efa91bd29ee5cf7110"/><file name="User.php" hash="0f75d9705aaa0b690217721a61ecd3e6"/></dir><file name="change-log.txt" hash="84c3cdc3ea17ed49d6f33d57b956f845"/><dir name="controllers"><dir name="Adminhtml"><dir name="Wordpress"><file name="AssociationsController.php" hash="304218bd303b88e788487c2f2e2cbb04"/></dir><file name="WordpressController.php" hash="3c40d9782f0a970798574f4a3eb4235a"/></dir><file name="AjaxController.php" hash="410a9d84692fabfc3e846598a772c803"/><file name="ArchiveController.php" hash="e9ec7c6d89501c9efd8a33db2170bcb9"/><file name="AuthorController.php" hash="8056629849e92b754e6eb85e1537565a"/><file name="IndexController.php" hash="a5fee64e05a8a14babb50e95eeff0906"/><file name="PostController.php" hash="1d6635aa6d098009cc1d7fa5bdaf2ead"/><file name="SearchController.php" hash="fceba89823f011517bbf48a04c4bb361"/><file name="TermController.php" hash="8bc39e2dca19b04ac52f7e320d41bc8c"/></dir><dir name="etc"><file name="adminhtml.xml" hash="22061db5a80dc2fa952a64778a346dfe"/><file name="config.xml" hash="8c51040863ae91b7a010087f7474969c"/><file name="fishpig.xml" hash="d9f519d26497463db27ef274734b2288"/><file name="system.xml" hash="8dce70be3871210de82104253045535a"/><file name="widget.xml" hash="b7b586ef3d869177a43e8e87a04b1222"/></dir><dir name="sql"><dir name="wordpress_setup"><file name="mysql4-install-0.1.0.php" hash="771dbb85a173051acc83b506fe67067d"/><file name="mysql4-upgrade-2.5.9.0-2.5.9.1.php" hash="a295aaeb8aa45d84bc1541fdac70d7ad"/><file name="mysql4-upgrade-3.2.0.0-3.2.0.1.php" hash="504da139c47e676666ac2b4210916d5f"/></dir></dir><dir name="Addon"><dir name="WordPressSEO"><dir name="Helper"><file name="Data.php" hash="af572cddaf1e1d878c70193dcb2adb3c"/></dir><dir name="etc"><file name="config.xml" hash="d1dde914497c73e0523b108a7bbd8841"/></dir></dir><dir name="Yarpp"><dir name="Block"><dir name="Sidebar"><file name="Widget.php" hash="98d5edda7378a0514f00950816f768e8"/></dir></dir><dir name="etc"><file name="config.xml" hash="746bd41d16f1d2402a35e64f12786520"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="wordpress.xml" hash="025b215d245317fbc619ae5677979339"/></dir><dir name="template"><dir name="wordpress"><file name="integration-tests.phtml" hash="6f7030e821d62e240675ba6831966aa7"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="wordpress.xml" hash="75f001e822e2d2a7213b531ae7066a97"/></dir><dir name="template"><dir name="wordpress"><dir><dir name="archive"><file name="view.phtml" hash="7243f533d0357685aa5cf8c115b148a1"/></dir><dir name="author"><file name="view.phtml" hash="1e52d2c16276406553a8d48c75eeb306"/></dir><dir name="post"><dir name="associated"><file name="products.phtml" hash="0b635b1cb6eab98aaa641a1f27bbe5fa"/></dir><file name="associated.phtml" hash="80e9593a788da42a0fcbe24f53c27cb5"/><dir name="list"><dir name="renderer"><file name="default.phtml" hash="68d65457c905c7cdf85c8fb93473e2f0"/></dir><file name="wrapper.phtml" hash="19549d50d36482dee642d80b7a932765"/></dir><file name="list.phtml" hash="19d0395edf4b1a3d787be50b61a487f1"/><file name="meta.phtml" hash="5eb9a91335c357ec77717495cbc513c6"/><dir name="view"><dir name="comment"><file name="form.phtml" hash="c22607dc13b7cc294da7c6d605925893"/><file name="wrapper.phtml" hash="dd6980b9b432634d2c63b03e635f09a4"/></dir><file name="comments.phtml" hash="05668659c30bf78727bbedfdbd49c6ac"/><file name="page.phtml" hash="a693be74e920be8e04ff726cf16abaee"/></dir><file name="view.phtml" hash="3c15b1c39adb91857cd5d88a7550b600"/></dir><dir name="search"><file name="result.phtml" hash="263b739fe9302e6e5d815f3bf2279b2e"/></dir><dir name="shortcode"><file name="gallery.phtml" hash="ff7e796c4e511e2f27a823be104a4374"/><file name="product.phtml" hash="7fb95222834907fac31477e5934ceedc"/></dir><dir name="sidebar"><dir name="widget"><file name="abstract.phtml" hash="1979cff1c6a6337b6980f62c2cd89577"/><file name="archives.phtml" hash="6f7d3e877b22cac88b130ef2b68fe286"/><file name="calendar.phtml" hash="fe0dca9946a9d0bd82a6114786c865c9"/><file name="categories.phtml" hash="4340111e138cd3f9c47c48ea7736013e"/><file name="categoryposts.phtml" hash="8dad6f1026313e2a327d8fd4fa4a786d"/><file name="comments.phtml" hash="184e6434d5a7f23f83a03cb21b0d8083"/><file name="image.phtml" hash="c7657307809b127e252764c911bb9a1e"/><file name="instagram.phtml" hash="bd37446ccf42a6e0dbb4b6c63edc3533"/><file name="links.phtml" hash="cf40ee224503d5eaf48c9494023e22c0"/><file name="menu.phtml" hash="7029074d6173761261ca6c30fcc194bb"/><file name="meta.phtml" hash="40fdc4df47d5d94e693dbfac00c0ca3b"/><file name="pages.phtml" hash="f3bbea9d984360f236ceb78f781d6199"/><file name="posts.phtml" hash="27c09919df79d50909c0fcb90c374cba"/><file name="rss.phtml" hash="ad8ad715f82a23540356920d76f8b74a"/><file name="search.phtml" hash="bb5846228cae41d0d71cc97b3e4a28a6"/><file name="tagcloud.phtml" hash="4978442189cf818ae4d57207ba642615"/><dir name="taxonomy"><file name="renderer.phtml" hash="41af9ae08f1aee29818c764b0bc1a256"/></dir><file name="taxonomy.phtml" hash="13a7cce60b3aeddee57484c237db697a"/><file name="text.phtml" hash="08f656c30d7e072f7f2c29e04743129c"/></dir></dir><dir name="term"><file name="view.phtml" hash="6c1a13cb279b137e0d915ea3e17d90fd"/></dir></dir><file name="homepage.phtml" hash="05856d1c44562bfc3d64f205f70c1de0"/><file name="protected.phtml" hash="31f5a14ccba3f7b69e3a4075c53bc539"/><file name="sidebar.phtml" hash="c6268b9ec5074662b8125d5aabc05b0c"/></dir><dir name="wordpress-addons"><dir name="yarpp"><file name="related.phtml" hash="08ee87974b6762c3b350464f76b85c91"/><dir name="sidebar"><file name="widget.phtml" hash="821b64bb40296aa65314ddfe7ed232f4"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="app"><dir name="etc"><dir name="modules"><file name="Fishpig_Wordpress.xml" hash="f7947cc170ce6bf1ab7a21e58ac48d31"/></dir></dir></dir><dir name="js"><dir name="fishpig"><dir name="wordpress"><file name="comments.js" hash="a3c5286844ccb293a9976bac46605289"/><file name="update.js" hash="3df101b798daa5248a279989f7fe2ff9"/><file name="search.js" hash="5631d5149f4fc145db04864b1527b2a8"/><file name="lightbox.js" hash="bb7c9e300dc33d399ca72039e727e266"/></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="wordpress"><file name="styles.css" hash="8e85ffde94798850dcf5c70cdd06ad00"/><file name="ajax-loader.gif" hash="a51c5608d01acf32df728f299767f82b"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="cs_CZ"><file name="Fishpig_Wordpress.csv" hash="416afbb6426b717f2cb37c99daf77adc"/></dir><dir name="da_DK"><file name="Fishpig_Wordpress.csv" hash="d4c4803edc751baf3c7726afc6c5568f"/></dir><dir name="de_DE"><file name="Fishpig_Wordpress.csv" hash="6479677778d79a8932597bfc4a23cc20"/></dir><dir name="es_ES"><file name="Fishpig_Wordpress.csv" hash="c3397d271f0c75c1dbe1b0878f404df4"/></dir><dir name="fr_FR"><file name="Fishpig_Wordpress.csv" hash="605d8ea12a5bbb3448a360bf46c9572a"/></dir><dir name="it_IT"><file name="Fishpig_Wordpress.csv" hash="60208176d94e30400d260494d440cb3c"/></dir><dir name="ja_JP"><file name="Fishpig_Wordpress.csv" hash="3fe07f48ab2e9cc1d899264f3a9cef52"/></dir><dir name="nb_NO"><file name="Fishpig_Wordpress.csv" hash="b0d5de887b5518beb1db976ca72dd2e5"/></dir><dir name="nl_NL"><file name="Fishpig_Wordpress.csv" hash="c8f0fb68fe1e207a554b9f49b82c01ea"/></dir><dir name="nn_NO"><file name="Fishpig_Wordpress.csv" hash="bfcb347e03369a2539f0217541badf4c"/></dir><dir name="pl_PL"><file name="Fishpig_Wordpress.csv" hash="0bd6f726386f5feaf89725453460a0ca"/></dir><dir name="pt_BR"><file name="Fishpig_Wordpress.csv" hash="92f644b350b828fa44f6ba9a82df0fe2"/></dir><dir name="pt_PT"><file name="Fishpig_Wordpress.csv" hash="a222f515815ae5effe2ce57f53072c90"/></dir><dir name="ru_RU"><file name="Fishpig_Wordpress.csv" hash="b534ad6f293419af26b045f3348a1a83"/></dir><dir name="sv_SE"><file name="Fishpig_Wordpress.csv" hash="c790bfe6a98530de1f4fe47ba6d8e113"/></dir><dir name="zh_CN"><file name="Fishpig_Wordpress.csv" hash="caef42e20155f23aafb4421ee46979ff"/></dir><dir name="en_GB"><file name="Fishpig_Wordpress.csv" hash="1e1b37fed9d6f60e9ea8129fac657953"/></dir><dir name="en_US"><file name="Fishpig_Wordpress.csv" hash="1e1b37fed9d6f60e9ea8129fac657953"/></dir><dir name="sl_SI"><file name="Fishpig_Wordpress.csv" hash="f5d57703149cc50dfaed42c2c390b7d4"/></dir><dir name="tr_TR"><file name="Fishpig_Wordpress.csv" hash="8f31cfca1e7ab452b404ec29a4b782bf"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>8.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Fishpig_Wordpress_Integration</name>
4
+ <version>4.2.1.9</version>
5
  <stability>stable</stability>
6
  <license uri="http://fishpig.co.uk/license.txt">FishPig EULA</license>
7
  <channel>community</channel>
10
  <description>Easily integrate Magento and WordPress without modifying any core files.</description>
11
  <notes>For changes, please see http://fishpig.co.uk/magento/wordpress-integration/#changelog</notes>
12
  <authors><author><name>fishpig</name><user>fishpig</user><email>ben@fishpig.co.uk</email></author></authors>
13
+ <date>2017-03-08</date>
14
+ <time>08:48:34</time>
15
+ <contents><target name="magecommunity"><dir name="Fishpig"><dir name="Wordpress"><dir name="Block"><file name="Abstract.php" hash="bf9e97598ed72068b3172dc477978c9f"/><dir name="Adminhtml"><dir name="Associations"><file name="Abstract.php" hash="dd589f8fcae2122632457e08c01aa774"/><dir name="Category"><file name="Category.php" hash="26782c6bc34cfbf7f81d1775c40a8a35"/><file name="Post.php" hash="1dd1330e619bdff79ad7d7c6fd08edd6"/></dir><dir name="Cms"><dir name="Page"><file name="Category.php" hash="7442c0874792bc08438c472875368b21"/><file name="Post.php" hash="5bed4c4e1baa1d0f0430d5cdfa87d020"/></dir></dir><dir name="Product"><file name="Category.php" hash="f99636a65b55ccc8818a98230439949d"/><file name="Post.php" hash="0493ae37198cbf50f5ae45565432f894"/></dir></dir><file name="Extend.php" hash="8f5d6ffe4ccb8b48221626ff33882090"/><dir name="Frontend"><file name="Autologin.php" hash="7a795c13d35491ba0a79fd1b15854c6a"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Route.php" hash="cb79ab33659cf906988b1403e0fc625c"/></dir></dir></dir></dir><file name="Update.php" hash="d1aa4001cc758132bcaca792c8dc5f07"/></dir><file name="Ajax.php" hash="0e8e97efddde53b1818c1eaec2b305b0"/><dir name="Archive"><file name="View.php" hash="b56c0c8b9e26a071c28440a0e52e6800"/></dir><dir name="Author"><file name="View.php" hash="03fa439ff3bece2c0cc2e56c2412740a"/></dir><dir name="Feed"><file name="Abstract.php" hash="d8405e51ded312cda6c00b09dd873788"/><dir name="Post"><file name="Comment.php" hash="6e279932f0d45375b5fdee0939e15415"/></dir><file name="Post.php" hash="d1bf0bfcfd687d5f3ca50b341afff560"/></dir><file name="Homepage.php" hash="d5383c14b381594e211a2c7438684d41"/><file name="Menu.php" hash="5dc369f5542bcf6ac87ab7ce8a98c6c1"/><dir name="Page"><file name="View.php" hash="dedf5c07dc52afc6aac0a87fb0c239b6"/></dir><dir name="Post"><file name="Abstract.php" hash="b782a654b478c4067aacba20f0431dc0"/><dir name="Associated"><file name="Products.php" hash="8a74abcfe97df273d75d7fb7b0f9d8d6"/></dir><file name="Associated.php" hash="6fbae669e0269916e578e4f6a1355415"/><dir name="List"><file name="Associated.php" hash="056fd7910da5a30d71c884982297879b"/><file name="Pager.php" hash="7def684fe156c3f59ac8185a0aad345f"/><file name="Renderer.php" hash="35fa1e4294f07d43bf2f8b5e7628161a"/><dir name="Wrapper"><file name="Abstract.php" hash="0a0e7eafe02de151e05353c01d6d4a67"/></dir></dir><file name="List.php" hash="85aa53897a40f88f5dd2f5af982bff8f"/><file name="Meta.php" hash="4482daab91f5c1a731d1d45d79c369b5"/><dir name="View"><dir name="Comment"><file name="Abstract.php" hash="06c0592b3f10c6af2bc8d3d7cdc5a73e"/><file name="Form.php" hash="3a75d0ebbd104076afb8195cc46e339d"/><file name="Pager.php" hash="d0d6c23852f6e4fa894cded53cb289a5"/><file name="Wrapper.php" hash="6318449f58d4a3b11018b3354252f021"/></dir><file name="Comments.php" hash="d3bee9fd86a5318b7986a4d776eed5f7"/></dir><file name="View.php" hash="4a8aca01c7ea5ee32027569c802bbc86"/></dir><dir name="Search"><file name="Result.php" hash="ad8ea64756a575b874afcae9250f6b97"/></dir><dir name="Shortcode"><file name="Product.php" hash="53b1986e1376ea0bdb2a793744253804"/></dir><dir name="Sidebar"><dir name="Widget"><file name="Abstract.php" hash="67234d08da2afec0e61c191ce2e90819"/><file name="Archives.php" hash="cba60c97dc3c9e6b4b73db53787e0aa4"/><file name="Calendar.php" hash="eb838cc8406a0ff3d33b767bdeec0044"/><file name="Categories.php" hash="c9c419da25dd707b8b932abca7bfd892"/><file name="Comments.php" hash="8d38d35bd7aa16188d3b33f3844a6e42"/><file name="Image.php" hash="655fdcb2700a2603539e3008b07b7ae1"/><file name="Instagram.php" hash="ab8a8d7b68f991e91c5e31c3044ebded"/><file name="Links.php" hash="1985b68fd53b3502540e932d25d77ae8"/><file name="Menu.php" hash="5c55903395588b36fa2f6c2779a4ed62"/><file name="Meta.php" hash="942292929971a6705379a87d73e3c226"/><file name="Pages.php" hash="cde08845cca7a7f43ea2e40ca6d090ef"/><file name="Posts.php" hash="1b35086ddc34206ea272856ce447f5dc"/><dir name="Rss"><file name="Abstract.php" hash="c07d0787e920060313db1b7698437c40"/></dir><file name="Rss.php" hash="4b16b12cb7c7370cd4977375d31c184b"/><file name="Search.php" hash="18d02709f88950490e60b00adf98bf54"/><file name="Tagcloud.php" hash="e7ddcb0652286b1442bab0d82aebef00"/><file name="Taxonomy.php" hash="3bb2ee45b014e8aa3a59a15c44cdc03d"/><file name="Text.php" hash="a789e156497390baeb488277b4c837e5"/><file name="Yarpp.php" hash="418b6d211410a98f0336130769c998a0"/></dir></dir><file name="Sidebar.php" hash="06d6ba70df5abb07c23278418efc4089"/><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><dir name="Post"><file name="Type.php" hash="dcc3e93873f10829d1211f8325f40044"/></dir></dir></dir></dir></dir><file name="Template.php" hash="aadd68bcb1da5cfe974d36dabc498754"/><dir name="Term"><file name="View.php" hash="f640abf673b7412cf05528924db2646f"/></dir></dir><dir name="Controller"><file name="Abstract.php" hash="936db8d033b8c257c9d4df5ff919b9e1"/><file name="Router.php" hash="98c155ccd254f43470857a7084bb696e"/><dir name="Router"><file name="Addon.php" hash="896162d5b3608442134e71eb5ab7b06c"/></dir></dir><file name="Exception.php" hash="ef2e08daa502bce27f98d83c9194c8f2"/><dir name="Helper"><file name="Abstract.php" hash="c0e97b8c7b60545b1b127b8439a8e736"/><file name="App.php" hash="8a560c3d8da5bac2f8abeda5a73b1896"/><file name="Associations.php" hash="9a08b34d4eb505059555f3bb65ca4229"/><dir name="Catalog"><file name="Product.php" hash="d00afec7c5bfe37e8ba1aa21d638ae90"/></dir><file name="Data.php" hash="b2fdb68f6a04e8abe9fbf17fb7d75be9"/><file name="Database.php" hash="dcd89ce8c8627c9917206ad65e18f6f3"/><file name="Filter.php" hash="ee675c1fce66b7de954054e12c7b8b62"/><dir name="Plugin"><file name="Abstract.php" hash="c8f9e76ddf381ee131efc9441a2990a2"/><dir name="Seo"><file name="Abstract.php" hash="c12dd081ce95340ff1d809e1c9092080"/></dir></dir><file name="Plugin.php" hash="046ed88b3892c7456c894d86656113bd"/><file name="Router.php" hash="0218c7adc12511f45afa683184875c95"/><dir name="Shortcode"><file name="Abstract.php" hash="af5f542e136a7171cfb8c4f99f77bdde"/><file name="AssociatedProducts.php" hash="146595bd7d7294794004c8813dad234c"/><file name="Caption.php" hash="47455590dafb7ee27f9872592312d3f0"/><file name="Code.php" hash="002746d8c64e8faa9c2340a4496ae7b6"/><file name="Dailymotion.php" hash="e12adc8cef400f0a382cf69138610426"/><file name="Gallery.php" hash="53ec715f115e2844edf56e22a4687d41"/><file name="Gist.php" hash="c90ad1b6293d29845a38eca66099ca2b"/><file name="Instagram.php" hash="4e155d67366c8c6598b8fdd4c5c395c2"/><file name="Product.php" hash="d37b2513b66a554349b4ccdf854edc11"/><file name="Scribd.php" hash="4b70de264a033be1104dd63d9e78f1c6"/><file name="Spotify.php" hash="d041bb90577d6a8acc1521f95637b302"/><file name="Vimeo.php" hash="83b242ee25c6debc72b3af3c79b97a68"/><file name="Youtube.php" hash="1113665a651bd7f1478111966516b87d"/></dir><file name="Social.php" hash="5ee03cfac0e48660e3a0eb49d4d28d28"/><file name="System.php" hash="afd0fba62df5e72b676564b1b8c77000"/></dir><dir name="Model"><file name="Abstract.php" hash="57aaab0c828039b58b7552c36602927a"/><file name="Archive.php" hash="bf512f09abb2ea7c20e63c1f6e6c734f"/><file name="Image.php" hash="ba5aefa5aaaba530cef51a2237ba5042"/><dir name="Menu"><file name="Item.php" hash="b88d7ee44f3bcc6d1d2521dc89a677f7"/></dir><file name="Menu.php" hash="de877052ac65514d393a131df3d5c142"/><file name="Observer.php" hash="c74292899a8bb47a73df2aee6d4280a6"/><dir name="Post"><dir name="Attachment"><file name="Abstract.php" hash="3068111ba883bacabe87f7fff5f1f795"/></dir><file name="Comment.php" hash="8f7a5797db8aad19b4d55dba6f6ab857"/><file name="Type.php" hash="b789aef92421a82d2cdafe19898356a3"/></dir><file name="Post.php" hash="737bc94017a79f44232e9e88d112d193"/><dir name="Resource"><file name="Abstract.php" hash="003a37262547fb8f02679739e21338c1"/><dir name="Collection"><file name="Abstract.php" hash="7d9a68175201177ec22deb6f6f29d388"/></dir><dir name="Image"><file name="Collection.php" hash="7d36d6dbe46b12d6a8412dbd07d3bc41"/></dir><file name="Image.php" hash="1b637473b71dd672ccd6a10a4f702ee2"/><dir name="Menu"><file name="Collection.php" hash="7deacc7b99f35392fd8c14ca3905d6ea"/><dir name="Item"><file name="Collection.php" hash="08249f3bed35c5d44adc01bd04ffc7a7"/></dir><file name="Item.php" hash="7e6ebd1cf1b1d4d33f2fb052cfa6e554"/></dir><file name="Menu.php" hash="c0e53a408ce206a801e81d667712dfc0"/><dir name="Post"><dir name="Attachment"><file name="Abstract.php" hash="357167e7379412bd047a2a7d63a7a6c3"/><dir name="Collection"><file name="Abstract.php" hash="c618bf7c6af0b1693c24432616368c71"/></dir></dir><file name="Collection.php" hash="2a71cf7573bc75d7bc3f8abf88bad235"/><dir name="Comment"><file name="Collection.php" hash="a44a18593da1b78efaee9b26be2f7e32"/></dir><file name="Comment.php" hash="1d9a8e258581120a084d84f556911636"/></dir><file name="Post.php" hash="90516c1b09928be401916a33c368a236"/><file name="Setup.php" hash="81d4730bb23b8139cb9e6dc654d366b8"/><dir name="Term"><file name="Collection.php" hash="7089f8aeb441ebac4601fb9e070e74b2"/></dir><file name="Term.php" hash="85f42eaa2f05be6f2cd3fc5268e93559"/><dir name="User"><file name="Collection.php" hash="16e628d55a0fa01747e01a695f709e00"/></dir><file name="User.php" hash="2f3a904ba1a03a9ea36e628059d4b73f"/></dir><dir name="Sitemap"><file name="Sitemap.php" hash="bca54ec7d86e4920e50da0b587c4b99e"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Autologin.php" hash="7d2664238443b07ea685ef3df01f5eff"/><file name="Encrypted.php" hash="520824f9a5533cf790aa8b5bb136e7c9"/></dir><dir name="Source"><file name="Menu.php" hash="9caaf56ff64f3858d4e206c6335c37ec"/><dir name="Social"><dir name="Media"><file name="Service.php" hash="61f66b78e2a122f07a9307b273b62feb"/></dir></dir></dir></dir></dir><dir name="Term"><file name="Taxonomy.php" hash="e2976a1b2c1b7cb7199b88a73dd78ea9"/></dir><file name="Term.php" hash="c185736836c876efa91bd29ee5cf7110"/><file name="User.php" hash="0f75d9705aaa0b690217721a61ecd3e6"/></dir><file name="change-log.txt" hash="3fe794e8f11bfab53fdcee7f6687545b"/><dir name="controllers"><dir name="Adminhtml"><dir name="Wordpress"><file name="AssociationsController.php" hash="304218bd303b88e788487c2f2e2cbb04"/></dir><file name="WordpressController.php" hash="3c40d9782f0a970798574f4a3eb4235a"/></dir><file name="AjaxController.php" hash="410a9d84692fabfc3e846598a772c803"/><file name="ArchiveController.php" hash="e9ec7c6d89501c9efd8a33db2170bcb9"/><file name="AuthorController.php" hash="8056629849e92b754e6eb85e1537565a"/><file name="IndexController.php" hash="a5fee64e05a8a14babb50e95eeff0906"/><file name="PostController.php" hash="1d6635aa6d098009cc1d7fa5bdaf2ead"/><file name="SearchController.php" hash="fceba89823f011517bbf48a04c4bb361"/><file name="TermController.php" hash="8bc39e2dca19b04ac52f7e320d41bc8c"/></dir><dir name="etc"><file name="adminhtml.xml" hash="22061db5a80dc2fa952a64778a346dfe"/><file name="config.xml" hash="43561627704a4b4376bf6ca22aa4916d"/><file name="fishpig.xml" hash="79c16fcd9d2df78ee7b7a30eb6c9a4d4"/><file name="system.xml" hash="8dce70be3871210de82104253045535a"/><file name="widget.xml" hash="b7b586ef3d869177a43e8e87a04b1222"/></dir><dir name="lib"><dir name="wp"><file name="formatting.php" hash="6b77f5df6b4de5c235ccb322af6f61fe"/></dir></dir><dir name="sql"><dir name="wordpress_setup"><file name="mysql4-install-0.1.0.php" hash="771dbb85a173051acc83b506fe67067d"/><file name="mysql4-upgrade-2.5.9.0-2.5.9.1.php" hash="a295aaeb8aa45d84bc1541fdac70d7ad"/><file name="mysql4-upgrade-3.2.0.0-3.2.0.1.php" hash="504da139c47e676666ac2b4210916d5f"/></dir></dir><dir name="Addon"><dir name="WordPressSEO"><dir name="Helper"><file name="Data.php" hash="f8a587308ce42277c242194f8e67c458"/></dir><dir name="etc"><file name="config.xml" hash="d1dde914497c73e0523b108a7bbd8841"/></dir></dir><dir name="Yarpp"><dir name="Block"><dir name="Sidebar"><file name="Widget.php" hash="98d5edda7378a0514f00950816f768e8"/></dir></dir><dir name="etc"><file name="config.xml" hash="746bd41d16f1d2402a35e64f12786520"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="wordpress.xml" hash="025b215d245317fbc619ae5677979339"/></dir><dir name="template"><dir name="wordpress"><file name="integration-tests.phtml" hash="6f7030e821d62e240675ba6831966aa7"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="wordpress.xml" hash="75f001e822e2d2a7213b531ae7066a97"/></dir><dir name="template"><dir name="wordpress"><dir><dir name="archive"><file name="view.phtml" hash="7243f533d0357685aa5cf8c115b148a1"/></dir><dir name="author"><file name="view.phtml" hash="1e52d2c16276406553a8d48c75eeb306"/></dir><dir name="post"><dir name="associated"><file name="products.phtml" hash="0b635b1cb6eab98aaa641a1f27bbe5fa"/></dir><file name="associated.phtml" hash="80e9593a788da42a0fcbe24f53c27cb5"/><dir name="list"><dir name="renderer"><file name="default.phtml" hash="a3fcb4b4177bfca57c4c770190961e9b"/></dir><file name="wrapper.phtml" hash="19549d50d36482dee642d80b7a932765"/></dir><file name="list.phtml" hash="19d0395edf4b1a3d787be50b61a487f1"/><file name="meta.phtml" hash="5eb9a91335c357ec77717495cbc513c6"/><dir name="view"><dir name="comment"><file name="form.phtml" hash="c22607dc13b7cc294da7c6d605925893"/><file name="wrapper.phtml" hash="dd6980b9b432634d2c63b03e635f09a4"/></dir><file name="comments.phtml" hash="05668659c30bf78727bbedfdbd49c6ac"/><file name="page.phtml" hash="a693be74e920be8e04ff726cf16abaee"/></dir><file name="view.phtml" hash="3c15b1c39adb91857cd5d88a7550b600"/></dir><dir name="search"><file name="result.phtml" hash="263b739fe9302e6e5d815f3bf2279b2e"/></dir><dir name="shortcode"><file name="gallery.phtml" hash="ff7e796c4e511e2f27a823be104a4374"/><file name="product.phtml" hash="7fb95222834907fac31477e5934ceedc"/></dir><dir name="sidebar"><dir name="widget"><file name="abstract.phtml" hash="1979cff1c6a6337b6980f62c2cd89577"/><file name="archives.phtml" hash="6f7d3e877b22cac88b130ef2b68fe286"/><file name="calendar.phtml" hash="fe0dca9946a9d0bd82a6114786c865c9"/><file name="categories.phtml" hash="4340111e138cd3f9c47c48ea7736013e"/><file name="categoryposts.phtml" hash="8dad6f1026313e2a327d8fd4fa4a786d"/><file name="comments.phtml" hash="184e6434d5a7f23f83a03cb21b0d8083"/><file name="image.phtml" hash="c7657307809b127e252764c911bb9a1e"/><file name="instagram.phtml" hash="bd37446ccf42a6e0dbb4b6c63edc3533"/><file name="links.phtml" hash="cf40ee224503d5eaf48c9494023e22c0"/><file name="menu.phtml" hash="7029074d6173761261ca6c30fcc194bb"/><file name="meta.phtml" hash="40fdc4df47d5d94e693dbfac00c0ca3b"/><file name="pages.phtml" hash="f3bbea9d984360f236ceb78f781d6199"/><file name="posts.phtml" hash="27c09919df79d50909c0fcb90c374cba"/><file name="rss.phtml" hash="ad8ad715f82a23540356920d76f8b74a"/><file name="search.phtml" hash="bb5846228cae41d0d71cc97b3e4a28a6"/><file name="tagcloud.phtml" hash="4978442189cf818ae4d57207ba642615"/><dir name="taxonomy"><file name="renderer.phtml" hash="41af9ae08f1aee29818c764b0bc1a256"/></dir><file name="taxonomy.phtml" hash="13a7cce60b3aeddee57484c237db697a"/><file name="text.phtml" hash="08f656c30d7e072f7f2c29e04743129c"/></dir></dir><dir name="term"><file name="view.phtml" hash="6c1a13cb279b137e0d915ea3e17d90fd"/></dir></dir><file name="homepage.phtml" hash="05856d1c44562bfc3d64f205f70c1de0"/><file name="protected.phtml" hash="31f5a14ccba3f7b69e3a4075c53bc539"/><file name="sidebar.phtml" hash="c6268b9ec5074662b8125d5aabc05b0c"/></dir><dir name="wordpress-addons"><dir name="yarpp"><file name="related.phtml" hash="08ee87974b6762c3b350464f76b85c91"/><dir name="sidebar"><file name="widget.phtml" hash="821b64bb40296aa65314ddfe7ed232f4"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="app"><dir name="etc"><dir name="modules"><file name="Fishpig_Wordpress.xml" hash="f7947cc170ce6bf1ab7a21e58ac48d31"/></dir></dir></dir><dir name="js"><dir name="fishpig"><dir name="wordpress"><file name="comments.js" hash="a3c5286844ccb293a9976bac46605289"/><file name="update.js" hash="3df101b798daa5248a279989f7fe2ff9"/><file name="search.js" hash="5631d5149f4fc145db04864b1527b2a8"/><file name="lightbox.js" hash="bb7c9e300dc33d399ca72039e727e266"/></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="wordpress"><file name="styles.css" hash="8e85ffde94798850dcf5c70cdd06ad00"/><file name="ajax-loader.gif" hash="a51c5608d01acf32df728f299767f82b"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="cs_CZ"><file name="Fishpig_Wordpress.csv" hash="416afbb6426b717f2cb37c99daf77adc"/></dir><dir name="da_DK"><file name="Fishpig_Wordpress.csv" hash="d4c4803edc751baf3c7726afc6c5568f"/></dir><dir name="de_DE"><file name="Fishpig_Wordpress.csv" hash="6479677778d79a8932597bfc4a23cc20"/></dir><dir name="es_ES"><file name="Fishpig_Wordpress.csv" hash="c3397d271f0c75c1dbe1b0878f404df4"/></dir><dir name="fr_FR"><file name="Fishpig_Wordpress.csv" hash="605d8ea12a5bbb3448a360bf46c9572a"/></dir><dir name="it_IT"><file name="Fishpig_Wordpress.csv" hash="60208176d94e30400d260494d440cb3c"/></dir><dir name="ja_JP"><file name="Fishpig_Wordpress.csv" hash="3fe07f48ab2e9cc1d899264f3a9cef52"/></dir><dir name="nb_NO"><file name="Fishpig_Wordpress.csv" hash="b0d5de887b5518beb1db976ca72dd2e5"/></dir><dir name="nl_NL"><file name="Fishpig_Wordpress.csv" hash="c8f0fb68fe1e207a554b9f49b82c01ea"/></dir><dir name="nn_NO"><file name="Fishpig_Wordpress.csv" hash="bfcb347e03369a2539f0217541badf4c"/></dir><dir name="pl_PL"><file name="Fishpig_Wordpress.csv" hash="0bd6f726386f5feaf89725453460a0ca"/></dir><dir name="pt_BR"><file name="Fishpig_Wordpress.csv" hash="92f644b350b828fa44f6ba9a82df0fe2"/></dir><dir name="pt_PT"><file name="Fishpig_Wordpress.csv" hash="a222f515815ae5effe2ce57f53072c90"/></dir><dir name="ru_RU"><file name="Fishpig_Wordpress.csv" hash="b534ad6f293419af26b045f3348a1a83"/></dir><dir name="sv_SE"><file name="Fishpig_Wordpress.csv" hash="c790bfe6a98530de1f4fe47ba6d8e113"/></dir><dir name="zh_CN"><file name="Fishpig_Wordpress.csv" hash="caef42e20155f23aafb4421ee46979ff"/></dir><dir name="en_GB"><file name="Fishpig_Wordpress.csv" hash="1e1b37fed9d6f60e9ea8129fac657953"/></dir><dir name="en_US"><file name="Fishpig_Wordpress.csv" hash="1e1b37fed9d6f60e9ea8129fac657953"/></dir><dir name="sl_SI"><file name="Fishpig_Wordpress.csv" hash="f5d57703149cc50dfaed42c2c390b7d4"/></dir><dir name="tr_TR"><file name="Fishpig_Wordpress.csv" hash="8f31cfca1e7ab452b404ec29a4b782bf"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.2.0</min><max>8.0.0</max></php></required></dependencies>
18
  </package>