/lib/page.php

  1. <?php 
  2. /** 
  3. * License: GPLv3 
  4. * License URI: https://www.gnu.org/licenses/gpl.txt 
  5. * Copyright 2012-2017 Jean-Sebastien Morisset (https://surniaulula.com/) 
  6. */ 
  7.  
  8. if ( ! defined( 'ABSPATH' ) ) { 
  9. die( 'These aren\'t the droids you\'re looking for...' ); 
  10.  
  11. if ( ! class_exists( 'NgfbPage' ) ) { 
  12.  
  13. class NgfbPage { 
  14.  
  15. private $p; 
  16.  
  17. public function __construct( &$plugin ) { 
  18. $this->p =& $plugin; 
  19.  
  20. if ( $this->p->debug->enabled ) { 
  21. $this->p->debug->mark(); 
  22.  
  23. public function get_quote( array &$mod ) { 
  24.  
  25. $quote = apply_filters( $this->p->cf['lca'].'_quote_seed', '', $mod ); 
  26.  
  27. if ( $quote != '' ) { 
  28. if ( $this->p->debug->enabled ) { 
  29. $this->p->debug->log( 'quote seed = "'.$quote.'"' ); 
  30. } else { 
  31. if ( has_excerpt( $mod['id'] ) ) { 
  32. $quote = get_the_excerpt( $mod['id'] ); 
  33. } else { 
  34. $quote = get_post_field( 'post_content', $mod['id'] ); 
  35.  
  36. // remove shortcodes, etc., but don't strip html tags 
  37. $quote = $this->p->util->cleanup_html_tags( $quote, false ); 
  38.  
  39. return apply_filters( $this->p->cf['lca'].'_quote', $quote, $mod ); 
  40.  
  41. // $type = title | excerpt | both 
  42. // $mod = true | false | post_id | $mod array 
  43. public function get_caption( $type = 'title', $textlen = 200, $mod = true, $use_cache = true,  
  44. $add_hashtags = true, $encode = true, $md_idx = '' ) { 
  45.  
  46. if ( $this->p->debug->enabled ) { 
  47. $this->p->debug->log_args( array( 
  48. 'type' => $type,  
  49. 'textlen' => $textlen,  
  50. 'mod' => $mod,  
  51. 'use_cache' => $use_cache,  
  52. 'add_hashtags' => $add_hashtags, // true/false/numeric 
  53. 'encode' => $encode,  
  54. 'md_idx' => $md_idx,  
  55. ) ); 
  56.  
  57. // $mod is preferred but not required 
  58. // $mod = true | false | post_id | $mod array 
  59. if ( ! is_array( $mod ) ) { 
  60. if ( $this->p->debug->enabled ) { 
  61. $this->p->debug->log( 'optional call to get_page_mod()' ); 
  62. $mod = $this->p->util->get_page_mod( $mod ); 
  63.  
  64. $caption = false; 
  65. $separator = html_entity_decode( $this->p->options['og_title_sep'],  
  66. ENT_QUOTES, get_bloginfo( 'charset' ) ); 
  67.  
  68. if ( $md_idx === true ) { 
  69. switch ( $type ) { 
  70. case 'title': 
  71. $md_idx = 'og_title'; 
  72. break; 
  73. case 'excerpt': 
  74. $md_idx = 'og_desc'; 
  75. break; 
  76. case 'both': 
  77. $md_idx = 'og_caption'; 
  78. break; 
  79.  
  80. // skip if no metadata index / key name 
  81. if ( ! empty( $md_idx ) ) { 
  82. $caption = $mod['obj'] ? $mod['obj']->get_options_multi( $mod['id'], $md_idx ) : null; 
  83.  
  84. // maybe add hashtags to a post caption 
  85. if ( $mod['is_post'] ) { 
  86. if ( ! empty( $caption ) && ! empty( $add_hashtags ) && ! preg_match( '/( #[a-z0-9\-]+)+$/U', $caption ) ) { 
  87. $hashtags = $this->get_hashtags( $mod['id'], $add_hashtags ); 
  88. if ( ! empty( $hashtags ) ) { 
  89. $caption = $this->p->util->limit_text_length( $caption,  
  90. $textlen - strlen( $hashtags ) - 1, '...', false ). // $cleanup_html = false 
  91. ' '.$hashtags; 
  92. if ( $this->p->debug->enabled ) { 
  93. if ( empty( $caption ) ) { 
  94. $this->p->debug->log( 'no custom caption found for '.$md_idx ); 
  95. } else { 
  96. $this->p->debug->log( 'custom caption = "'.$caption.'"' ); 
  97. } elseif ( $this->p->debug->enabled ) { 
  98. $this->p->debug->log( 'custom caption skipped: no md_idx value' ); 
  99.  
  100. if ( empty( $caption ) ) { 
  101.  
  102. if ( ! empty( $md_idx ) ) { 
  103. $md_prefix = preg_replace( '/_(title|desc|caption)$/', '', $md_idx ); 
  104. $md_title = $md_prefix.'_title'; 
  105. $md_desc = $md_prefix.'_desc'; 
  106. } else { 
  107. $md_title = $md_desc = $md_idx; 
  108.  
  109. // request all values un-encoded, then encode once we have the complete caption text 
  110. switch ( $type ) { 
  111. case 'title': 
  112. $caption = $this->get_title( $textlen, '...', $mod, $use_cache, $add_hashtags, false, $md_title ); 
  113. break; 
  114.  
  115. case 'excerpt': 
  116. $caption = $this->get_description( $textlen, '...', $mod, $use_cache, $add_hashtags, false, $md_desc ); 
  117. break; 
  118.  
  119. case 'both': 
  120. // get the title first 
  121. $caption = $this->get_title( 0, '', $mod, $use_cache, false, false, $md_title ); // $add_hashtags = false 
  122.  
  123. // add a separator between title and description 
  124. if ( ! empty( $caption ) ) { 
  125. $caption .= ' '.$separator.' '; 
  126.  
  127. // reduce the requested $textlen by the title text length we already have 
  128. $caption .= $this->get_description( $textlen - strlen( $caption ),  
  129. '...', $mod, $use_cache, $add_hashtags, false, $md_desc ); 
  130. break; 
  131.  
  132. if ( $encode === true ) { 
  133. $caption = SucomUtil::encode_emoji( htmlentities( $caption,  
  134. ENT_QUOTES, get_bloginfo( 'charset' ), false ) ); // double_encode = false 
  135. } else { // just in case 
  136. $caption = html_entity_decode( SucomUtil::decode_utf8( $caption ),  
  137. ENT_QUOTES, get_bloginfo( 'charset' ) ); 
  138.  
  139. return apply_filters( $this->p->cf['lca'].'_caption', $caption, $mod, $add_hashtags, $md_idx ); 
  140.  
  141. // $mod = true | false | post_id | $mod array 
  142. public function get_title( $textlen = 70, $trailing = '', $mod = false, $use_cache = true,  
  143. $add_hashtags = false, $encode = true, $md_idx = 'og_title' ) { 
  144.  
  145. if ( $this->p->debug->enabled ) { 
  146. $this->p->debug->log_args( array( 
  147. 'textlen' => $textlen,  
  148. 'trailing' => $trailing,  
  149. 'mod' => $mod,  
  150. 'use_cache' => $use_cache,  
  151. 'add_hashtags' => $add_hashtags, // true/false/numeric 
  152. 'encode' => $encode,  
  153. 'md_idx' => $md_idx,  
  154. ) ); 
  155.  
  156. // $mod is preferred but not required 
  157. // $mod = true | false | post_id | $mod array 
  158. if ( ! is_array( $mod ) ) { 
  159. if ( $this->p->debug->enabled ) { 
  160. $this->p->debug->log( 'optional call to get_page_mod()' ); 
  161. $mod = $this->p->util->get_page_mod( $mod ); 
  162.  
  163. $lca = $this->p->cf['lca']; 
  164. $title = false; 
  165. $hashtags = ''; 
  166. $paged_suffix = ''; 
  167. $separator = html_entity_decode( $this->p->options['og_title_sep'],  
  168. ENT_QUOTES, get_bloginfo( 'charset' ) ); 
  169.  
  170. // setup filters to save and restore original / pre-filtered title value 
  171. if ( empty( $this->p->options['plugin_filter_title'] ) ) { 
  172. SucomUtil::add_filter_protection( 'wp_title' ); 
  173.  
  174. // skip if no metadata index / key name 
  175. if ( ! empty( $md_idx ) ) { 
  176. $title = is_object( $mod['obj'] ) ? 
  177. $mod['obj']->get_options_multi( $mod['id'], array( $md_idx, 'og_title' ) ) : null; 
  178. if ( $this->p->debug->enabled ) { 
  179. if ( empty( $title ) ) { 
  180. $this->p->debug->log( 'no custom title found for '.$md_idx ); 
  181. } else { 
  182. $this->p->debug->log( 'custom title = "'.$title.'"' ); 
  183. } elseif ( $this->p->debug->enabled ) { 
  184. $this->p->debug->log( 'custom title skipped: no md_idx value' ); 
  185.  
  186. // get seed if no custom meta title 
  187. if ( empty( $title ) ) { 
  188. $title = apply_filters( $lca.'_title_seed', '', $mod, $add_hashtags, $md_idx, $separator ); 
  189. if ( ! empty( $title ) ) { 
  190. if ( $this->p->debug->enabled ) { 
  191. $this->p->debug->log( 'title seed = "'.$title.'"' ); 
  192.  
  193. // check for hashtags in meta or seed title, remove and then add again after shorten 
  194. if ( preg_match( '/(.*)(( #[a-z0-9\-]+)+)$/U', $title, $match ) ) { 
  195. $title = $match[1]; 
  196. $hashtags = trim( $match[2] ); 
  197.  
  198. } elseif ( $mod['is_post'] ) { 
  199. if ( ! empty( $add_hashtags ) && ! empty( $this->p->options['og_desc_hashtags'] ) ) { 
  200. $hashtags = $this->get_hashtags( $mod['id'], $add_hashtags ); // $add_hashtags = true | false | numeric 
  201.  
  202. if ( $hashtags && $this->p->debug->enabled ) { 
  203. $this->p->debug->log( 'hashtags found = "'.$hashtags.'"' ); 
  204.  
  205. // construct a title of our own 
  206. if ( empty( $title ) ) { 
  207.  
  208. if ( $mod['is_post'] ) { 
  209.  
  210. $title = apply_filters( 'wp_title',  
  211. get_the_title( $mod['id'] ).' '.$separator.' ', $separator, 'right' ); 
  212.  
  213. if ( $this->p->debug->enabled ) { 
  214. $this->p->debug->log( 'post ID get_the_title() = "'.$title.'"' ); 
  215.  
  216. } elseif ( $mod['is_term'] ) { 
  217.  
  218. $term_obj = SucomUtil::get_term_object( $mod['id'], $mod['tax_slug'] ); 
  219.  
  220. if ( SucomUtil::is_category_page( $mod['id'] ) ) { 
  221. $title = $this->get_category_title( $term_obj, '', $separator ); // includes parents in title string 
  222. } elseif ( isset( $term_obj->name ) ) { 
  223. $title = apply_filters( 'wp_title',  
  224. $term_obj->name.' '.$separator.' ', $separator, 'right' ); 
  225. } elseif ( $this->p->debug->enabled ) { 
  226. $this->p->debug->log( 'name property missing in term object' ); 
  227.  
  228. } elseif ( $mod['is_user'] ) { 
  229.  
  230. $user_obj = SucomUtil::get_user_object( $mod['id'] ); 
  231.  
  232. $title = apply_filters( 'wp_title',  
  233. $user_obj->display_name.' '.$separator.' ', $separator, 'right' ); 
  234.  
  235. $title = apply_filters( $lca.'_user_object_title', $title, $user_obj ); 
  236.  
  237. } else { 
  238. $title = wp_title( $separator, false, 'right' ); 
  239.  
  240. if ( $this->p->debug->enabled ) { 
  241. $this->p->debug->log( 'default wp_title() = "'.$title.'"' ); 
  242.  
  243. // just in case 
  244. if ( empty( $title ) ) { 
  245.  
  246. if ( $this->p->debug->enabled ) { 
  247. $this->p->debug->log( 'fallback get_bloginfo() = "'.$title.'"' ); 
  248.  
  249. if ( ! ( $title = get_bloginfo( 'name', 'display' ) ) ) { 
  250. $title = 'No Title'; // just in case 
  251.  
  252. if ( empty( $this->p->options['plugin_filter_title'] ) ) { 
  253. SucomUtil::remove_filter_protection( 'wp_title' ); 
  254.  
  255. $title = $this->p->util->cleanup_html_tags( $title ); // strip html tags before removing separator 
  256.  
  257. if ( ! empty( $separator ) ) { 
  258. $title = preg_replace( '/ *'.preg_quote( $separator, '/' ).' *$/', '', $title ); // trim excess separator 
  259.  
  260. // apply title filter before adjusting it's length 
  261. $title = apply_filters( $lca.'_title_pre_limit', $title ); 
  262.  
  263. // check title against string length limits 
  264. if ( $textlen > 0 ) { 
  265. // seo-like title modifications 
  266. if ( $this->p->avail['seo']['*'] === false ) { 
  267. $paged = get_query_var( 'paged' ); 
  268. if ( $paged > 1 ) { 
  269. if ( ! empty( $separator ) ) { 
  270. $paged_suffix .= $separator.' '; 
  271. $paged_suffix .= sprintf( 'Page %s', $paged ); 
  272. $textlen = $textlen - strlen( $paged_suffix ) - 1; 
  273. if ( ! empty( $add_hashtags ) && 
  274. ! empty( $hashtags ) ) { 
  275. $textlen = $textlen - strlen( $hashtags ) - 1; 
  276.  
  277. $title = $this->p->util->limit_text_length( $title, $textlen, $trailing, false ); // $cleanup_html = false 
  278.  
  279. if ( ! empty( $paged_suffix ) ) { 
  280. $title .= ' '.$paged_suffix; 
  281.  
  282. if ( ! empty( $add_hashtags ) && ! empty( $hashtags ) ) { 
  283. $title .= ' '.$hashtags; 
  284.  
  285. if ( $encode === true ) { 
  286. foreach ( array( 'title', 'separator' ) as $var ) { 
  287. $$var = SucomUtil::encode_emoji( htmlentities( $$var,  
  288. ENT_QUOTES, get_bloginfo( 'charset' ), false ) ); // double_encode = false 
  289.  
  290. return apply_filters( $lca.'_title', $title, $mod, $add_hashtags, $md_idx, $separator ); 
  291.  
  292. // $mod = true | false | post_id | $mod array 
  293. public function get_description( $textlen = 156, $trailing = '...', $mod = false, $use_cache = true,  
  294. $add_hashtags = true, $encode = true, $md_idx = 'og_desc' ) { 
  295.  
  296. if ( $this->p->debug->enabled ) { 
  297. $this->p->debug->mark( 'render description' ); // begin timer 
  298.  
  299. $this->p->debug->log_args( array( 
  300. 'textlen' => $textlen,  
  301. 'trailing' => $trailing,  
  302. 'mod' => $mod,  
  303. 'use_cache' => $use_cache,  
  304. 'add_hashtags' => $add_hashtags, // true | false | numeric 
  305. 'encode' => $encode,  
  306. 'md_idx' => $md_idx,  
  307. ) ); 
  308.  
  309. // $mod is preferred but not required 
  310. // $mod = true | false | post_id | $mod array 
  311. if ( ! is_array( $mod ) ) { 
  312. if ( $this->p->debug->enabled ) { 
  313. $this->p->debug->log( 'optional call to get_page_mod()' ); 
  314. $mod = $this->p->util->get_page_mod( $mod ); 
  315.  
  316. $lca = $this->p->cf['lca']; 
  317. $desc = false; 
  318. $hashtags = ''; 
  319.  
  320. // skip if no metadata index / key name 
  321. if ( ! empty( $md_idx ) ) { 
  322. // fallback to og_desc value 
  323. $desc = is_object( $mod['obj'] ) ? 
  324. $mod['obj']->get_options_multi( $mod['id'], array( $md_idx, 'og_desc' ) ) : null; 
  325. if ( $this->p->debug->enabled ) { 
  326. if ( empty( $desc ) ) { 
  327. $this->p->debug->log( 'no custom description found for '.$md_idx ); 
  328. } else { 
  329. $this->p->debug->log( 'custom description = "'.$desc.'"' ); 
  330. } elseif ( $this->p->debug->enabled ) { 
  331. $this->p->debug->log( 'custom description skipped: no md_idx value' ); 
  332.  
  333. // get seed if no custom meta description 
  334. if ( empty( $desc ) ) { 
  335. $desc = apply_filters( $lca.'_description_seed', '', $mod, $add_hashtags, $md_idx ); 
  336. if ( ! empty( $desc ) ) { 
  337. if ( $this->p->debug->enabled ) { 
  338. $this->p->debug->log( 'description seed = "'.$desc.'"' ); 
  339.  
  340. // check for hashtags in meta or seed desc, remove and then add again after shorten 
  341. if ( preg_match( '/^(.*)(( *#[a-z][a-z0-9\-]+)+)$/U', $desc, $match ) ) { 
  342. $desc = $match[1]; 
  343. $hashtags = trim( $match[2] ); 
  344.  
  345. } elseif ( $mod['is_post'] ) { 
  346. if ( ! empty( $add_hashtags ) && ! empty( $this->p->options['og_desc_hashtags'] ) ) { 
  347. $hashtags = $this->get_hashtags( $mod['id'], $add_hashtags ); 
  348.  
  349. if ( $hashtags && $this->p->debug->enabled ) { 
  350. $this->p->debug->log( 'hashtags found = "'.$hashtags.'"' ); 
  351.  
  352. // if there's no custom description, and no pre-seed,  
  353. // then go ahead and generate the description value 
  354. if ( empty( $desc ) ) { 
  355.  
  356. if ( $mod['is_post'] ) { 
  357.  
  358. // use the excerpt, if we have one 
  359. if ( has_excerpt( $mod['id'] ) ) { 
  360.  
  361. if ( $this->p->debug->enabled ) { 
  362. $this->p->debug->log( 'getting the excerpt for post ID '.$mod['id'] ); 
  363.  
  364. $desc = get_post_field( 'post_excerpt', $mod['id'] ); 
  365.  
  366. if ( ! empty( $this->p->options['plugin_filter_excerpt'] ) ) { 
  367.  
  368. $filter_modified = apply_filters( $lca.'_text_filter_begin',  
  369. false, 'get_the_excerpt' ); 
  370.  
  371. if ( $this->p->debug->enabled ) { 
  372. $this->p->debug->log( 'applying the WordPress get_the_excerpt filters' ); 
  373.  
  374. $desc = apply_filters( 'get_the_excerpt', $desc ); 
  375.  
  376. if ( $filter_modified ) { 
  377. apply_filters( $lca.'_text_filter_end',  
  378. false, 'get_the_excerpt' ); 
  379.  
  380. } elseif ( $this->p->debug->enabled ) { 
  381. $this->p->debug->log( 'skipped the WordPress get_the_excerpt filters' ); 
  382.  
  383. // if there's no excerpt, then fallback to the content 
  384. if ( empty( $desc ) ) { 
  385.  
  386. if ( $this->p->debug->enabled ) { 
  387. $this->p->debug->log( 'getting the content for post ID '.$mod['id'] ); 
  388.  
  389. $desc = $this->get_content( $mod, $use_cache, $md_idx ); 
  390.  
  391. // ignore everything before the first paragraph if true 
  392. if ( $this->p->options['plugin_p_strip'] ) { 
  393. if ( $this->p->debug->enabled ) { 
  394. $this->p->debug->log( 'removing all text before the first paragraph' ); 
  395. $desc = preg_replace( '/^.*?<p>/i', '', $desc ); // question mark makes regex un-greedy 
  396.  
  397. } elseif ( $mod['is_term'] ) { 
  398. if ( SucomUtil::is_tag_page( $mod['id'] ) ) { 
  399. if ( ! $desc = tag_description( $mod['id'] ) ) { 
  400. $term_obj = get_tag( $mod['id'] ); 
  401. if ( ! empty( $term_obj->name ) ) { 
  402. $desc = sprintf( 'Tagged with %s', $term_obj->name ); 
  403. } elseif ( SucomUtil::is_category_page( $mod['id'] ) ) { 
  404. if ( ! $desc = category_description( $mod['id'] ) ) { 
  405. $desc = sprintf( '%s Category', get_cat_name( $mod['id'] ) ); 
  406. } else { // other taxonomies 
  407. $term_obj = SucomUtil::get_term_object( $mod['id'], $mod['tax_slug'] ); 
  408.  
  409. if ( ! empty( $term_obj->description ) ) { 
  410. $desc = $term_obj->description; 
  411. } elseif ( ! empty( $term_obj->name ) ) { 
  412. $desc = $term_obj->name.' Archives'; 
  413. } elseif ( $mod['is_user'] ) { 
  414. $user_obj = SucomUtil::get_user_object( $mod['id'] ); 
  415.  
  416. if ( ! empty( $user_obj->description ) ) { 
  417. $desc = $user_obj->description; 
  418. } elseif ( ! empty( $user_obj->display_name ) ) { 
  419. $desc = sprintf( 'Authored by %s', $user_obj->display_name ); 
  420.  
  421. $desc = apply_filters( $lca.'_user_object_description', $desc, $user_obj ); 
  422.  
  423. } elseif ( is_day() ) { 
  424. $desc = sprintf( 'Daily Archives for %s', get_the_date() ); 
  425. } elseif ( is_month() ) { 
  426. $desc = sprintf( 'Monthly Archives for %s', get_the_date('F Y') ); 
  427. } elseif ( is_year() ) { 
  428. $desc = sprintf( 'Yearly Archives for %s', get_the_date('Y') ); 
  429. } elseif ( SucomUtil::is_archive_page() ) { // just in case 
  430. $desc = sprintf( 'Archive Page' ); 
  431.  
  432. // if there's still no description, then fallback to a generic version 
  433. if ( empty( $desc ) ) { 
  434. if ( $mod['post_status'] === 'auto-draft' ) { 
  435. if ( $this->p->debug->enabled ) { 
  436. $this->p->debug->log( 'post_status is auto-draft: using empty description' ); 
  437. } elseif ( ! ( $desc = SucomUtil::get_site_description( $this->p->options, $mod ) ) ) { 
  438. $desc = 'No Description'; // just in case 
  439.  
  440. $strlen_pre_cleanup = $this->p->debug->enabled ? strlen( $desc ) : 0; 
  441. $desc = $this->p->util->cleanup_html_tags( $desc, true, $this->p->options['plugin_use_img_alt'] ); 
  442.  
  443. if ( $this->p->debug->enabled ) { 
  444. $this->p->debug->log( 'description strlen before html cleanup '. 
  445. $strlen_pre_cleanup.' and after '.strlen( $desc ) ); 
  446.  
  447. $desc = apply_filters( $this->p->cf['lca'].'_description_pre_limit', $desc ); 
  448.  
  449. if ( $textlen > 0 ) { 
  450.  
  451. if ( ! empty( $add_hashtags ) && ! empty( $hashtags ) ) { 
  452. $textlen = $textlen - strlen( $hashtags ) - 1; 
  453.  
  454. if ( $this->p->debug->enabled ) { 
  455. $this->p->debug->log( 'description strlen before limit length '. 
  456. strlen( $desc ).' (limiting to '.$textlen.' chars)' ); 
  457.  
  458. $desc = $this->p->util->limit_text_length( $desc, $textlen, $trailing, false ); // $cleanup_html = false 
  459.  
  460. } elseif ( $this->p->debug->enabled ) { 
  461. $this->p->debug->log( 'description limit text length skipped' ); 
  462.  
  463. if ( ! empty( $add_hashtags ) && ! empty( $hashtags ) ) { 
  464. $desc .= ' '.$hashtags; 
  465.  
  466. if ( $encode === true ) { 
  467. $desc = SucomUtil::encode_emoji( htmlentities( $desc,  
  468. ENT_QUOTES, get_bloginfo( 'charset' ), false ) ); // double_encode = false 
  469.  
  470. if ( $this->p->debug->enabled ) { 
  471. $this->p->debug->mark( 'render description' ); // end timer 
  472.  
  473. return apply_filters( $lca.'_description', $desc, $mod, $add_hashtags, $md_idx ); 
  474.  
  475. public function get_content( array $mod, $use_cache = true, $md_idx = '' ) { 
  476.  
  477. if ( $this->p->debug->enabled ) { 
  478. $this->p->debug->log_args( array( 
  479. 'mod' => $mod,  
  480. 'use_cache' => $use_cache,  
  481. 'md_idx' => $md_idx,  
  482. ) ); 
  483.  
  484. $lca = $this->p->cf['lca']; 
  485. $sharing_url = $this->p->util->get_sharing_url( $mod ); 
  486. $filter_content = empty( $this->p->options['plugin_filter_content'] ) ? false : true; 
  487. $content_array = array(); 
  488. $content_index = 'locale:'.SucomUtil::get_locale( $mod ).'_filter:'.( $filter_content ? 'true' : 'false' ); 
  489. $cache_salt = __METHOD__.'('.SucomUtil::get_mod_salt( $mod, $sharing_url ).')'; 
  490. $cache_id = $lca.'_'.md5( $cache_salt ); 
  491. $cache_exp = (int) apply_filters( $lca.'_cache_expire_content_text',  
  492. $this->p->options['plugin_content_cache_exp'] ); 
  493.  
  494. if ( $this->p->debug->enabled ) { 
  495. $this->p->debug->log( 'sharing url = '.$sharing_url ); 
  496. $this->p->debug->log( 'content index = '.$content_index ); 
  497. $this->p->debug->log( 'wp_cache expire = '.$cache_exp ); 
  498. $this->p->debug->log( 'wp_cache salt = '.$cache_salt ); 
  499.  
  500. /** 
  501. * Retrieve the content 
  502. */ 
  503.  
  504. if ( $cache_exp > 0 && $use_cache ) { 
  505. $content_array = wp_cache_get( $cache_id, __METHOD__ ); 
  506. if ( isset( $content_array[$content_index] ) ) { 
  507. if ( $this->p->debug->enabled ) { 
  508. $this->p->debug->log( 'content index found in array from wp_cache '.$cache_id ); 
  509. return $content_array[$content_index]; 
  510. } elseif ( $this->p->debug->enabled ) { 
  511. $this->p->debug->log( 'content index not in array from wp_cache '.$cache_id ); 
  512. } elseif ( $this->p->debug->enabled ) { 
  513. $this->p->debug->log( 'content array wp_cache is disabled' ); 
  514.  
  515. $content_array[$content_index] = false; 
  516. $content_text =& $content_array[$content_index]; 
  517. $content_text = apply_filters( $lca.'_content_seed', '', $mod, $use_cache, $md_idx ); 
  518.  
  519. if ( ! empty( $content_text ) ) { 
  520. if ( $this->p->debug->enabled ) { 
  521. $this->p->debug->log( 'content seed is "'.$content_text.'"' ); 
  522. } elseif ( $mod['is_post'] ) { 
  523.  
  524. $content_text = get_post_field( 'post_content', $mod['id'] ); 
  525.  
  526. if ( empty( $content_text ) ) { 
  527. if ( $this->p->debug->enabled ) { 
  528. $this->p->debug->log( 'exiting early: no post_content for post id '.$mod['id'] ); 
  529. return false; 
  530.  
  531. /** 
  532. * Modify the content 
  533. */ 
  534.  
  535. // save content length (for comparison) before making changes 
  536. $strlen_before_filters = strlen( $content_text ); 
  537.  
  538. // remove singlepics, which we detect and use before-hand 
  539. $content_text = preg_replace( '/\[singlepic[^\]]+\]/', '', $content_text, -1, $count ); 
  540.  
  541. if ( $count > 0 ) { 
  542. if ( $this->p->debug->enabled ) { 
  543. $this->p->debug->log( $count.' [singlepic] shortcode(s) removed from content' ); 
  544.  
  545. if ( $filter_content ) { 
  546. $filter_modified = apply_filters( $lca.'_text_filter_begin',  
  547. false, 'the_content' ); 
  548.  
  549. // remove all of our shortcodes 
  550. if ( isset( $this->p->cf['*']['lib']['shortcode'] ) && 
  551. is_array( $this->p->cf['*']['lib']['shortcode'] ) ) { 
  552. foreach ( $this->p->cf['*']['lib']['shortcode'] as $id => $name ) { 
  553. if ( array_key_exists( $id, $this->p->sc ) && 
  554. is_object( $this->p->sc[$id] ) ) { 
  555. $this->p->sc[$id]->remove(); 
  556.  
  557. global $post; 
  558. if ( $this->p->debug->enabled ) { 
  559. $this->p->debug->log( 'saving the original $post object' ); 
  560. $post_saved = $post; // save the original GLOBAL post object 
  561.  
  562. // WordPress oEmbed needs a $post ID, so make sure we have one 
  563. // see shortcode() in WP_Embed class (wp-includes/class-wp-embed.php) 
  564. if ( empty( $post->ID ) && $mod['is_post'] ) { 
  565. if ( $this->p->debug->enabled ) { 
  566. $this->p->debug->log( 'post id property empty: re-setting post object from mod id '.$mod['id'] ); 
  567. $post = SucomUtil::get_post_object( $mod['id'] ); // redefine $post global 
  568.  
  569. // apply the content filters 
  570. if ( $this->p->debug->enabled ) { 
  571. $this->p->debug->log( 'applying wordpress the_content filters' ); 
  572.  
  573. $content_text = apply_filters( 'the_content', $content_text ); 
  574.  
  575. if ( $this->p->debug->enabled ) { 
  576. $this->p->debug->log( 'restoring the original post object' ); 
  577. $post = $post_saved; // restore the original GLOBAL post object 
  578.  
  579. // cleanup for NGG pre-v2 album shortcode 
  580. unset ( $GLOBALS['subalbum'] ); 
  581. unset ( $GLOBALS['nggShowGallery'] ); 
  582.  
  583. if ( $filter_modified ) { 
  584. apply_filters( $lca.'_text_filter_end',  
  585. false, 'the_content' ); 
  586.  
  587. // add our shortcodes back 
  588. if ( isset( $this->p->cf['*']['lib']['shortcode'] ) && 
  589. is_array( $this->p->cf['*']['lib']['shortcode'] ) ) { 
  590. foreach ( $this->p->cf['*']['lib']['shortcode'] as $id => $name ) { 
  591. if ( array_key_exists( $id, $this->p->sc ) && 
  592. is_object( $this->p->sc[$id] ) ) { 
  593. $this->p->sc[$id]->add(); 
  594.  
  595. } elseif ( $this->p->debug->enabled ) { 
  596. $this->p->debug->log( 'the_content filters skipped (shortcodes not expanded)' ); 
  597.  
  598. $content_text = preg_replace( '/[\s\n\r]+/s', ' ', $content_text ); // put everything on one line 
  599. $content_text = preg_replace( '/^.*<!--'.$lca.'-content-->(.*)<!--\/'. 
  600. $lca.'-content-->.*$/', '$1', $content_text ); 
  601.  
  602. // remove "Google+" link and text 
  603. if ( strpos( $content_text, '>Google+<' ) !== false ) { 
  604. $content_text = preg_replace( '/<a +rel="author" +href="" +style="display:none;">Google\+<\/a>/', ' ', $content_text ); 
  605.  
  606. if ( strpos( $content_text, '<p class="wp-caption-text">' ) !== false ) { 
  607. $caption_prefix = isset( $this->p->options['plugin_p_cap_prefix'] ) ? 
  608. $this->p->options['plugin_p_cap_prefix'] : 'Caption:'; 
  609. if ( ! empty( $caption_prefix ) ) { 
  610. $content_text = preg_replace( '/<p class="wp-caption-text">/', '${0}'.$caption_prefix.' ', $content_text ); 
  611.  
  612. if ( strpos( $content_text, ']]>' ) !== false ) { 
  613. $content_text = str_replace( ']]>', ']]>', $content_text ); 
  614.  
  615. $strlen_after_filters = strlen( $content_text ); 
  616. if ( $this->p->debug->enabled ) { 
  617. $this->p->debug->log( 'content strlen before '.$strlen_before_filters.' and after changes / filters '.$strlen_after_filters ); 
  618.  
  619. // apply filters before caching 
  620. $content_array[$content_index] = apply_filters( $lca.'_content', $content_text, $mod, $use_cache, $md_idx ); 
  621.  
  622. if ( $cache_exp > 0 ) { 
  623. wp_cache_add_non_persistent_groups( array( __METHOD__ ) ); // only some caching plugins support this feature 
  624. wp_cache_set( $cache_id, $content_array, __METHOD__, $cache_exp ); 
  625. if ( $this->p->debug->enabled ) { 
  626. $this->p->debug->log( 'content array saved to wp_cache '.$cache_id.' ('.$cache_exp.' seconds)'); 
  627.  
  628. return $content_array[$content_index]; 
  629.  
  630. public function get_article_section( $post_id ) { 
  631. $section = ''; 
  632.  
  633. if ( ! empty( $post_id ) ) { 
  634. // get_options() returns null if an index key is not found 
  635. $section = $this->p->m['util']['post']->get_options( $post_id, 'og_art_section' ); 
  636.  
  637. if ( ! empty( $section ) ) { // must be a non-empty string 
  638. if ( $this->p->debug->enabled ) { 
  639. $this->p->debug->log( 'found custom meta article section = '.$section ); 
  640. } else { 
  641. $section = $this->p->options['og_art_section']; 
  642.  
  643. if ( $section === 'none' ) { 
  644. $section = ''; 
  645.  
  646. return apply_filters( $this->p->cf['lca'].'_article_section', $section, $post_id ); 
  647.  
  648. public function get_hashtags( $post_id, $add_hashtags = true ) { 
  649.  
  650. if ( empty( $add_hashtags ) ) { // check for false or 0 
  651. return; 
  652. } elseif ( is_numeric( $add_hashtags ) ) { 
  653. $max_hashtags = $add_hashtags; 
  654. } elseif ( ! empty( $this->p->options['og_desc_hashtags'] ) ) { 
  655. $max_hashtags = $this->p->options['og_desc_hashtags']; 
  656. } else { 
  657. return; 
  658.  
  659. $hashtags = apply_filters( $this->p->cf['lca'].'_hashtags_seed', '', $post_id, $add_hashtags ); 
  660. if ( ! empty( $hashtags ) ) { 
  661. if ( $this->p->debug->enabled ) { 
  662. $this->p->debug->log( 'hashtags seed = "'.$hashtags.'"' ); 
  663. } else { 
  664. $tags = array_slice( $this->get_tags( $post_id ), 0, $max_hashtags ); 
  665. if ( ! empty( $tags ) ) { 
  666. // remove special character incompatible with Twitter 
  667. $hashtags = SucomUtil::array_to_hashtags( $tags ); 
  668. if ( $this->p->debug->enabled ) { 
  669. $this->p->debug->log( 'hashtags (max '.$max_hashtags.') = "'.$hashtags.'"' ); 
  670.  
  671. return apply_filters( $this->p->cf['lca'].'_hashtags', $hashtags, $post_id, $add_hashtags ); 
  672.  
  673. public function get_tags( $post_id ) { 
  674.  
  675. $tags = apply_filters( $this->p->cf['lca'].'_tags_seed', array(), $post_id ); 
  676. if ( ! empty( $tags ) ) { 
  677. if ( $this->p->debug->enabled ) { 
  678. $this->p->debug->log( 'tags seed = "'.implode( ', ', $tags ).'"' ); 
  679. } else { 
  680. if ( is_singular() || ! empty( $post_id ) ) { 
  681. $tags = $this->get_wp_tags( $post_id ); 
  682. if ( isset( $this->p->m['media']['ngg'] ) && 
  683. $this->p->options['og_ngg_tags'] && 
  684. $this->p->avail['*']['featured'] && 
  685. has_post_thumbnail( $post_id ) ) { 
  686.  
  687. $pid = get_post_thumbnail_id( $post_id ); 
  688.  
  689. // featured images from ngg pre-v2 had 'ngg-' prefix 
  690. if ( is_string( $pid ) && substr( $pid, 0, 4 ) == 'ngg-' ) { 
  691. $tags = array_merge( $tags, $this->p->m['media']['ngg']->get_tags( $pid ) ); 
  692. } elseif ( is_search() ) { 
  693. $tags = preg_split( '/ *, */', get_search_query( false ) ); 
  694.  
  695. if ( $this->p->debug->enabled ) { 
  696. $this->p->debug->log( 'raw tags = "'.implode( ', ', $tags ).'"' ); 
  697. $tags = array_unique( array_map( array( 'SucomUtil', 'sanitize_tag' ), $tags ) ); 
  698. if ( $this->p->debug->enabled ) { 
  699. $this->p->debug->log( 'sanitized tags = "'.implode( ', ', $tags ).'"' ); 
  700.  
  701. return apply_filters( $this->p->cf['lca'].'_tags', $tags, $post_id ); 
  702.  
  703. public function get_wp_tags( $post_id ) { 
  704.  
  705. $tags = apply_filters( $this->p->cf['lca'].'_wp_tags_seed', array(), $post_id ); 
  706. if ( ! empty( $tags ) ) { 
  707. $this->p->debug->log( 'wp tags seed = "'.implode( ', ', $tags ).'"' ); 
  708. } else { 
  709. $post_ids = array ( $post_id ); // array of one 
  710.  
  711. // add the parent tags if option is enabled 
  712. if ( $this->p->options['og_page_parent_tags'] && is_page( $post_id ) ) { 
  713. $post_ids = array_merge( $post_ids, get_post_ancestors( $post_id ) ); 
  714. foreach ( $post_ids as $id ) { 
  715. if ( $this->p->options['og_page_title_tag'] && is_page( $id ) ) { 
  716. $tags[] = SucomUtil::sanitize_tag( get_the_title( $id ) ); 
  717. foreach ( wp_get_post_tags( $id, array( 'fields' => 'names') ) as $tag_name ) { 
  718. $tags[] = $tag_name; 
  719. return apply_filters( $this->p->cf['lca'].'_wp_tags', $tags, $post_id ); 
  720.  
  721. public function get_category_title( $term_id = 0, $tax_slug = '', $separator = false ) { 
  722.  
  723. if ( is_object( $term_id ) ) { 
  724. $term_obj = $term_id; 
  725. } else { 
  726. $term_obj = SucomUtil::get_term_object( $term_id, $tax_slug ); 
  727.  
  728. if ( $separator === false ) { 
  729. $separator = html_entity_decode( $this->p->options['og_title_sep'],  
  730. ENT_QUOTES, get_bloginfo( 'charset' ) ); 
  731.  
  732. if ( isset( $term_obj->name ) ) { 
  733. $title = $term_obj->name.' Archives '.$separator.' '; // default value 
  734. } elseif ( $this->p->debug->enabled ) { 
  735. $this->p->debug->log( 'name property missing in term object' ); 
  736.  
  737. $cat = get_category( $term_obj->term_id ); 
  738.  
  739. if ( ! empty( $cat->category_parent ) ) { 
  740. $cat_parents = get_category_parents( $term_obj->term_id, false, ' '.$separator.' ', false ); 
  741. if ( is_wp_error( $cat_parents ) ) { 
  742. if ( $this->p->debug->enabled ) { 
  743. $this->p->debug->log( 'get_category_parents error: '.$cat_parents->get_error_message() ); 
  744. } else { 
  745. if ( $this->p->debug->enabled ) { 
  746. $this->p->debug->log( 'get_category_parents() = "'.$cat_parents.'"' ); 
  747. if ( ! empty( $cat_parents ) ) { 
  748. $title = $cat_parents; 
  749.  
  750. return apply_filters( 'wp_title', $title, $separator, 'right' ); 
  751.  
  752. ?> 
.