PageRenderTime 71ms CodeModel.GetById 24ms RepoModel.GetById 5ms app.codeStats 0ms

/184.168.182.1/wp-content/plugins/jetpack/modules/publicize.php

https://gitlab.com/endomorphosis/falkenstein
PHP | 307 lines | 206 code | 53 blank | 48 comment | 40 complexity | 60a27757fb5a5a9a5db61dd6bede6f12 MD5 | raw file
  1. <?php
  2. /**
  3. * Module Name: Publicize
  4. * Module Description: Connect your site to popular social networks and automatically share new posts with your friends.
  5. * Sort Order: 1
  6. * First Introduced: 2.0
  7. * Requires Connection: Yes
  8. * Auto Activate: Yes
  9. * Module Tags: Social
  10. */
  11. class Jetpack_Publicize {
  12. var $in_jetpack = true;
  13. function __construct() {
  14. global $publicize_ui;
  15. $this->in_jetpack = ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'enable_module_configurable' ) ) ? true : false;
  16. if ( $this->in_jetpack && method_exists( 'Jetpack', 'module_configuration_load' ) ) {
  17. Jetpack::enable_module_configurable( __FILE__ );
  18. Jetpack::module_configuration_load( __FILE__, array( $this, 'jetpack_configuration_load' ) );
  19. add_action( 'init', array( $this, 'sync_posts_init' ), 999 );
  20. }
  21. require_once dirname( __FILE__ ) . '/publicize/publicize.php';
  22. if ( $this->in_jetpack )
  23. require_once dirname( __FILE__ ) . '/publicize/publicize-jetpack.php';
  24. else {
  25. require_once dirname( dirname( __FILE__ ) ) . '/mu-plugins/keyring/keyring.php';
  26. require_once dirname( __FILE__ ) . '/publicize/publicize-wpcom.php';
  27. }
  28. require_once dirname( __FILE__ ) . '/publicize/ui.php';
  29. $publicize_ui = new Publicize_UI();
  30. $publicize_ui->in_jetpack = $this->in_jetpack;
  31. // Jetpack specific checks / hooks
  32. if ( $this->in_jetpack) {
  33. add_action( 'jetpack_activate_module_publicize', array( $this, 'module_state_toggle' ) );
  34. add_action( 'jetpack_deactivate_module_publicize', array( $this, 'module_state_toggle' ) );
  35. add_filter( 'jetpack_sync_post_module_custom_data', array( $this, 'sync_post_module_custom_data' ), 10, 2 );
  36. // if sharedaddy isn't active, the sharing menu hasn't been added yet
  37. $active = Jetpack::get_active_modules();
  38. if ( in_array( 'publicize', $active ) && !in_array( 'sharedaddy', $active ) )
  39. add_action( 'admin_menu', array( &$publicize_ui, 'sharing_menu' ) );
  40. }
  41. }
  42. function sync_posts_init() {
  43. $post_types = array( 'post', 'page' );
  44. $all_post_types = get_post_types();
  45. foreach ( $all_post_types as $post_type ) {
  46. // sync Custom Post Types that support publicize
  47. if ( post_type_supports( $post_type, 'publicize' ) ) {
  48. $post_types[] = $post_type;
  49. }
  50. }
  51. Jetpack_Sync::sync_posts( __FILE__, array(
  52. 'post_types' => $post_types,
  53. ) );
  54. }
  55. function sync_post_module_custom_data( $custom_data, $post ) {
  56. if ( post_type_supports( get_post_type( $post ), 'publicize' ) ) {
  57. $custom_data['cpt_publicizeable'] = true;
  58. }
  59. return $custom_data;
  60. }
  61. function module_state_toggle() {
  62. // extra check that we are on the JP blog, just incase
  63. if ( class_exists( 'Jetpack' ) && $this->in_jetpack ) {
  64. $jetpack = Jetpack::init();
  65. $jetpack->sync->register( 'noop' );
  66. }
  67. }
  68. function jetpack_configuration_load() {
  69. wp_safe_redirect( menu_page_url( 'sharing', false ) );
  70. exit;
  71. }
  72. }
  73. global $publicize_ui;
  74. new Jetpack_Publicize;
  75. /**
  76. * Helper functions for shared use in the services files
  77. */
  78. class Publicize_Util {
  79. /**
  80. * Truncates a string to be shorter than or equal to the length specified
  81. * Attempts to truncate on word boundaries
  82. *
  83. * @param string $string
  84. * @param int $length
  85. * @return string
  86. */
  87. function crop_str( $string, $length = 256 ) {
  88. $string = wp_strip_all_tags( (string) $string, true ); // true: collapse Linear Whitespace into " "
  89. $length = absint( $length );
  90. if ( mb_strlen( $string, 'UTF-8' ) <= $length ) {
  91. return $string;
  92. }
  93. // @see wp_trim_words()
  94. if ( 'characters' == _x( 'words', 'word count: words or characters?', 'jetpack' ) ) {
  95. return trim( mb_substr( $string, 0, $length - 1, 'UTF-8' ) ) . "\xE2\x80\xA6"; // ellipsis
  96. }
  97. $words = explode( ' ', $string );
  98. $return = '';
  99. while ( strlen( $word = array_shift( $words ) ) ) {
  100. $new_return = $return ? "$return $word" : $word;
  101. $new_return_length = mb_strlen( $new_return, 'UTF-8' );
  102. if ( $new_return_length < $length - 1 ) {
  103. $return = $new_return;
  104. continue;
  105. } elseif ( $new_return_length == $length - 1 ) {
  106. $return = $new_return;
  107. break;
  108. }
  109. if ( !$return ) {
  110. $return = mb_substr( $new_return, 0, $length - 1, 'UTF-8' );
  111. }
  112. break;
  113. }
  114. return "$return\xE2\x80\xA6"; // ellipsis
  115. }
  116. /**
  117. * Returns an array of DOMNodes that are comments (including recursing child nodes)
  118. *
  119. * @param DOMNode $node
  120. * @return array
  121. */
  122. function get_comment_nodes( $node ) {
  123. $comment_nodes = array();
  124. foreach ( $node->childNodes as $child ) {
  125. if ( XML_COMMENT_NODE === $child->nodeType ) {
  126. $comment_nodes[] = $child;
  127. }
  128. if ( $child->hasChildNodes() ) {
  129. $child_comment_nodes = self::get_comment_nodes( $child );
  130. $comment_nodes = array_merge( $comment_nodes, $child_comment_nodes );
  131. }
  132. }
  133. return $comment_nodes;
  134. }
  135. /**
  136. * Truncates HTML so that its textContent (text without markup) is shorter than or equal to the length specified.
  137. * The length of the returned string may be larger than the specified length due to the markup.
  138. * Attempts to truncate on word boundaries.
  139. *
  140. * @param string $string
  141. * @param int $length
  142. * @param array $allowed_tags KSES input
  143. * @return string
  144. */
  145. function crop_html( $string, $length = 256, $allowed_tags = array() ) {
  146. $tags = $GLOBALS['allowedtags']; // Markup allowed in comments...
  147. $tags['img'] = array( // ... plus images ...
  148. 'alt' => true,
  149. 'height' => true,
  150. 'src' => true,
  151. 'width' => true,
  152. );
  153. // ... and some other basics
  154. $tags['p'] = array();
  155. $tags['ul'] = array();
  156. $tags['ol'] = array();
  157. $tags['li'] = array();
  158. $tags['br'] = array();
  159. $tags = array_merge( $tags, $allowed_tags );
  160. // Clean up, then KSES to really lock it down
  161. $string = trim( (string) $string );
  162. $string = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $string );
  163. $string = wp_kses( $string, $tags );
  164. $string = mb_convert_encoding( $string, 'HTML-ENTITIES', 'UTF-8' );
  165. $dom = new DOMDocument( '1.0', 'UTF-8' );
  166. @$dom->loadHTML( "<html><body>$string</body></html>" ); // suppress parser warning
  167. // Strip comment nodes, if any
  168. $comment_nodes = self::get_comment_nodes( $dom->documentElement );
  169. foreach ( $comment_nodes as &$comment_node ) {
  170. $comment_node->parentNode->removeChild( $comment_node );
  171. }
  172. if ( $comment_nodes ) {
  173. // Update the $string (some return paths work from just $string)
  174. $string = $dom->saveHTML();
  175. $string = preg_replace( '/^<!DOCTYPE.+?>/', '', $string );
  176. $string = str_replace( array('<html>', '</html>', '<body>', '</body>' ), array( '', '', '', '' ), $string );
  177. $string = trim( $string );
  178. }
  179. // Find the body
  180. $body = false;
  181. foreach ( $dom->childNodes as $child ) {
  182. if ( XML_ELEMENT_NODE === $child->nodeType && 'html' === strtolower( $child->tagName ) ) {
  183. $body = $child->firstChild;
  184. break;
  185. }
  186. }
  187. if ( !$body ) {
  188. return self::crop_str( $string, $length );
  189. }
  190. // If the text (without the markup) is shorter than $length, just return
  191. if ( mb_strlen( $body->textContent, 'UTF-8' ) <= $length ) {
  192. return $string;
  193. }
  194. $node = false;
  195. do {
  196. $node = self::remove_innermost_last_child( $body, $node_removed_from );
  197. $new_string_length = mb_strlen( $body->textContent, 'UTF-8' );
  198. } while ( $new_string_length > $length );
  199. $new_string = $dom->saveHTML( $body );
  200. $new_string = mb_substr( $new_string, 6, -7, 'UTF-8' ); // 6: <body>, 7: </body>
  201. if ( !$node ) {
  202. return $new_string ? $new_string : self::crop_str( $string, $length );
  203. }
  204. $append_string_length = $length - $new_string_length;
  205. if ( !$append_string_length ) {
  206. return $new_string;
  207. }
  208. if ( $append_string_length > 1 && XML_TEXT_NODE === $node->nodeType ) { // 1: ellipsis
  209. $append_string = self::crop_str( $node->textContent, $append_string_length ); // includes ellipsis
  210. $append_node = $dom->createTextNode( $append_string );
  211. $node_removed_from->appendChild( $append_node );
  212. $new_string = $dom->saveHTML( $body );
  213. $new_string = mb_substr( $new_string, 6, -7, 'UTF-8' );
  214. } elseif ( $append_string_length > 9 && XML_ELEMENT_NODE === $node->nodeType && 'p' == strtolower( $node->nodeName ) ) { // 9: '<p>X{\xE2\x80\xA6}</p>'
  215. $new_string .= '<p>' . self::crop_str( $node->textContent, $append_string_length - 8 ) . '</p>';
  216. }
  217. // Clean up any empty Paragraphs that might have occurred after removing their children
  218. return trim( preg_replace( '#<p>\s*</p>#i', '', $new_string ) );
  219. }
  220. function remove_innermost_last_child( $node, &$node_removed_from ) {
  221. $node_removed_from = $node;
  222. if ( !$node->lastChild ) {
  223. return false;
  224. }
  225. if ( $node->lastChild->hasChildNodes() ) {
  226. return self::remove_innermost_last_child( $node->lastChild, $node_removed_from );
  227. }
  228. $innermost_last_child = $node->lastChild;
  229. $node->removeChild( $innermost_last_child );
  230. return $innermost_last_child;
  231. }
  232. function bump_stats_extras_publicize_url( $bin, $post_id ) {
  233. static $done = array();
  234. if ( isset( $done[$post_id] ) ) {
  235. return;
  236. }
  237. $done[$post_id] = true;
  238. if ( function_exists( 'bump_stats_extras' ) )
  239. bump_stats_extras( 'publicize_url', $bin );
  240. }
  241. public static function build_sprintf( $args ) {
  242. $search = array();
  243. $replace = array();
  244. foreach ( $args as $k => $arg ) {
  245. if ( 0 == $k ) {
  246. $string = $arg;
  247. continue;
  248. }
  249. $search[] = "%$arg%";
  250. $replace[] = "%$k\$s";
  251. }
  252. return str_replace( $search, $replace, $string );
  253. }
  254. }