Advertisement
Guest User

Untitled

a guest
Jan 18th, 2017
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 108.47 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * Class containing all necessary methods to output structured HTML output of an entry object.
  5. *
  6. * @package Connections
  7. * @subpackage Entry HTML
  8. * @copyright Copyright (c) 2013, Steven A. Zahm
  9. * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
  10. * @since unknown
  11. */
  12.  
  13. // Exit if accessed directly
  14. if ( ! defined( 'ABSPATH' ) ) exit;
  15.  
  16. /**
  17. * Class cnOutput
  18. */
  19. class cnOutput extends cnEntry {
  20.  
  21. /**
  22. * Echo or return the supplied string.
  23. *
  24. * @access private
  25. * @since 8.2.6
  26. *
  27. * @param bool $return
  28. * @param string $html
  29. *
  30. * @return string
  31. */
  32. private function echoOrReturn( $return, $html ) {
  33.  
  34. if ( $return ) {
  35.  
  36. return $html;
  37.  
  38. } else {
  39.  
  40. echo $html;
  41. return '';
  42. }
  43. }
  44.  
  45. /**
  46. * Echos the 'Entry Sized' image.
  47. *
  48. * @deprecated since 0.7.2.0
  49. */
  50. public function getCardImage() {
  51. $this->getImage();
  52. }
  53.  
  54. /**
  55. * Echos the 'Profile Sized' image.
  56. *
  57. * @deprecated since 0.7.2.0
  58. */
  59. public function getProfileImage() {
  60. $this->getImage( array( 'image' => 'photo' , 'preset' => 'profile' ) );
  61. }
  62.  
  63. /**
  64. * Echos the 'Thumbnail Sized' image.
  65. *
  66. * @deprecated since 0.7.2.0
  67. */
  68. public function getThumbnailImage() {
  69. $this->getImage( array( 'image' => 'photo' , 'preset' => 'thumbnail' ) );
  70. }
  71.  
  72. /**
  73. * Echos the logo image.
  74. *
  75. * @deprecated since 0.7.2.0
  76. */
  77. public function getLogoImage() {
  78.  
  79. $this->getImage( array( 'image' => 'logo' ) );
  80. }
  81.  
  82. /**
  83. * Echo or return the image/logo if associated in a HTML hCard compliant string.
  84. *
  85. * Accepted option for the $atts property are:
  86. * image (string) Select the image to display. Valid values are photo || logo
  87. * preset (string) Select one of the predefined image sizes Must be used in conjunction with the 'image' option. Valid values are thumbnail || entry || profile
  88. * fallback (array) Object to be shown when there is no image or logo.
  89. * type (string) Fallback type. Valid values are; none || default || block
  90. * string (string) The string used with the block fallback
  91. * height (int) Block height. [Required if a image custom size was set.]
  92. * width (int) Block width.
  93. * height (int) Override the values saved in the settings. [Required if providing custom size.]
  94. * width (int) Override the values saved in the settings.
  95. * zc (int) Crop format
  96. * 0 Resize to Fit specified dimensions (no cropping)
  97. * 1 Crop and resize to best fit the dimensions (default behaviour)
  98. * 2 Resize proportionally to fit entire image into specified dimensions, and add borders if required
  99. * 3 Resize proportionally adjusting size of scaled image so there are no borders gaps
  100. * before (string) HTML to output before the image
  101. * after (string) HTML to after before the image
  102. * style (array) Customize an inline stlye tag for the image or the placeholder block. Array format key == attribute; value == value.
  103. * return (bool) Return or echo the string. Default is to echo.
  104. *
  105. * NOTE: If only the height or width was set for a custom image size, the opposite image dimension must be set for
  106. * the fallback block. This does not apply if the fallback is the default image.
  107. *
  108. * Filters:
  109. * cn_output_default_atts_image => (array) Register the methods default attributes.
  110. * cn_output_image => (string) The output string, (array) The $atts.
  111. *
  112. * @todo Enable support for a default image to be set.
  113. *
  114. * @access public
  115. * @since unknown
  116. * @version 1.0
  117. * @param array $atts [optional]
  118. * @return string
  119. */
  120. public function getImage( $atts = array() ) {
  121.  
  122. $displayImage = FALSE;
  123. $cropModes = array( 0 => 'none', 1 => 'crop', 2 => 'fill', 3 => 'fit' );
  124. $targetOptions = array( 'new' => '_blank', 'same' => '_self' );
  125. $tag = array();
  126. $srcset = array();
  127. $anchorStart = '';
  128. $out = '';
  129.  
  130. /*
  131. * // START -- Set the default attributes array. \\
  132. */
  133. $defaults = array(
  134. 'image' => 'photo',
  135. 'preset' => 'entry',
  136. 'fallback' => array(
  137. 'type' => 'none',
  138. 'string' => '',
  139. 'height' => 0,
  140. 'width' => 0
  141. ),
  142. 'width' => 0,
  143. 'height' => 0,
  144. 'zc' => 1,
  145. 'quality' => 80,
  146. 'before' => '',
  147. 'after' => '',
  148. 'sizes' => array( '100vw' ),
  149. 'style' => array(),
  150. 'action' => 'display',
  151. 'return' => FALSE
  152. );
  153.  
  154. $defaults = apply_filters( 'cn_output_default_atts_image' , $defaults );
  155.  
  156. $atts = cnSanitize::args( $atts, $defaults );
  157.  
  158. if ( isset( $atts['fallback'] ) && is_array( $atts['fallback'] ) ) $atts['fallback'] = cnSanitize::args( $atts['fallback'], $defaults['fallback'] );
  159. /*
  160. * // END -- Set the default attributes array if not supplied. \\
  161. */
  162.  
  163. /*
  164. * The $atts key that are not image tag attributes.
  165. */
  166. $nonAtts = array( 'action', 'image', 'preset', 'fallback', 'image_size', 'zc', 'quality', 'before', 'after', 'style', 'return' );
  167.  
  168. $customSize = ( ! empty( $atts['height'] ) || ! empty( $atts['width'] ) ) ? TRUE : FALSE;
  169.  
  170. switch ( $atts['image'] ) {
  171.  
  172. case 'photo':
  173.  
  174. if ( $this->getImageLinked() && ( $this->getImageDisplay() || 'edit' == $atts['action'] ) ) {
  175.  
  176. $displayImage = TRUE;
  177. $atts['class'] = 'cn-image photo';
  178. $atts['alt'] = sprintf( __( 'Photo of %s', 'connections' ), $this->getName() );
  179. $atts['title'] = sprintf( __( 'Photo of %s', 'connections' ), $this->getName() );
  180.  
  181. $atts['alt'] = apply_filters( 'cn_photo_alt', $atts['alt'], $this );
  182. $atts['title'] = apply_filters( 'cn_photo_title', $atts['title'], $this );
  183.  
  184. if ( $customSize ) {
  185.  
  186. $image = $this->getImageMeta(
  187. array(
  188. 'type' => 'photo',
  189. 'size' => 'custom',
  190. 'crop_mode' => $atts['zc'],
  191. 'width' => $atts['width'],
  192. 'height' => $atts['height'],
  193. 'quality' => $atts['quality'],
  194. )
  195. );
  196.  
  197. if ( is_wp_error( $image ) ) {
  198.  
  199. if ( is_admin() ) cnMessage::render( 'error', implode( '<br />', $image->get_error_messages() ) );
  200. $displayImage = FALSE;
  201.  
  202. } else {
  203.  
  204. // Since this is a custom size of an image we can not know which crop mode to use.
  205. // Set the crop mode the the value set in $atts['zc'].
  206. $cropMode = $atts['zc'];
  207.  
  208. // Add the image to the scrset.
  209. $srcset['image_custom'] = array( 'src' => $image['url'], 'width' => '1x' );
  210.  
  211. $atts['width'] = $image['width'];
  212. $atts['height'] = $image['height'];
  213. }
  214.  
  215. } else {
  216.  
  217. $preset = array( 'thumbnail' => 'thumbnail', 'medium' => 'entry', 'large' => 'profile' );
  218.  
  219. if ( $size = array_search( $atts['preset'], $preset ) ) {
  220.  
  221. $image = $this->getImageMeta(
  222. array(
  223. 'type' => 'photo',
  224. 'size' => $size,
  225. )
  226. );
  227.  
  228. if ( is_wp_error( $image ) ) {
  229.  
  230. if ( is_admin() ) cnMessage::render( 'error', implode( '<br />', $image->get_error_messages() ) );
  231. $displayImage = FALSE;
  232.  
  233. } else {
  234.  
  235. // Set the crop mode to the value saved in the settings.
  236. $cropMode = ( $key = array_search( cnSettingsAPI::get( 'connections', "image_{$size}", 'ratio' ), $cropModes ) ) || $key === 0 ? $key : 2;
  237.  
  238. // Add the image to the scrset.
  239. $srcset[ 'image_' . $size ] = array( 'src' => $image['url'], 'width' => '1x' );
  240.  
  241. $atts['width'] = $image['width'];
  242. $atts['height'] = $image['height'];
  243. }
  244.  
  245. } else {
  246.  
  247. $displayImage = FALSE;
  248.  
  249. $atts['fallback']['type'] = 'block';
  250. $atts['fallback']['string'] = sprintf( __( 'Photo present %s is not valid.', 'connections' ), $size );
  251. }
  252. }
  253. }
  254.  
  255. /*
  256. * Create the link for the image if one was assigned.
  257. */
  258. $links = $this->getLinks( array( 'image' => TRUE ) );
  259.  
  260. if ( ! empty( $links ) ) {
  261.  
  262. $link = $links[0];
  263. $target = array_key_exists( $link->target, $targetOptions ) ? $targetOptions[ $link->target ] : '_self';
  264.  
  265. $anchorStart = sprintf( '<a href="%1$s"%2$s%3$s>',
  266. esc_url( $link->url ),
  267. empty( $target ) ? '' : ' target="' . $target . '"',
  268. empty( $link->followString ) ? '' : ' rel="' . $link->followString . '"'
  269. );
  270. }
  271.  
  272. break;
  273.  
  274. case 'logo':
  275.  
  276. if ( $this->getLogoLinked() && ( $this->getLogoDisplay() || 'edit' == $atts['action'] ) ) {
  277.  
  278. $displayImage = TRUE;
  279. $atts['class'] = 'cn-image logo';
  280. $atts['alt'] = sprintf( __( 'Logo for %s', 'connections' ), $this->getName() );
  281. $atts['title'] = sprintf( __( 'Logo for %s', 'connections' ), $this->getName() );
  282. $cropMode = ( $key = array_search( cnSettingsAPI::get( 'connections', 'image_logo', 'ratio' ), $cropModes ) ) || $key === 0 ? $key : 2;
  283.  
  284. $atts['alt'] = apply_filters( 'cn_logo_alt', $atts['alt'], $this );
  285. $atts['title'] = apply_filters( 'cn_logo_title', $atts['title'], $this );
  286.  
  287. if ( $customSize ) {
  288.  
  289. $image = $this->getImageMeta(
  290. array(
  291. 'type' => 'logo',
  292. 'size' => 'custom',
  293. 'crop_mode' => $atts['zc'],
  294. 'width' => $atts['width'],
  295. 'height' => $atts['height'],
  296. 'quality' => $atts['quality'],
  297. )
  298. );
  299.  
  300. if ( is_wp_error( $image ) ) {
  301.  
  302. if ( is_admin() ) cnMessage::render( 'error', implode( '<br />', $image->get_error_messages() ) );
  303. $displayImage = FALSE;
  304.  
  305. } else {
  306.  
  307. // Add the image to the scrset.
  308. $srcset['logo_custom'] = array( 'src' => esc_url( $image['url'] ), 'width' => '1x' );
  309.  
  310. $atts['width'] = $image['width'];
  311. $atts['height'] = $image['height'];
  312. }
  313.  
  314. } else {
  315.  
  316. $image = $this->getImageMeta(
  317. array(
  318. 'type' => 'logo',
  319. 'size' => 'scaled',
  320. )
  321. );
  322.  
  323. if ( is_wp_error( $image ) ) {
  324.  
  325. if ( is_admin() ) cnMessage::render( 'error', implode( '<br />', $image->get_error_messages() ) );
  326. $displayImage = FALSE;
  327.  
  328. } else {
  329.  
  330. // Add the image to the scrset.
  331. $srcset['logo'] = array( 'src' => esc_url( $image['url'] ), 'width' => '1x' );
  332.  
  333. $atts['width'] = $image['width'];
  334. $atts['height'] = $image['height'];
  335. }
  336.  
  337. }
  338. }
  339.  
  340. /*
  341. * Create the link for the image if one was assigned.
  342. */
  343. $links = $this->getLinks( array( 'logo' => TRUE ) );
  344.  
  345. if ( ! empty( $links ) ) {
  346.  
  347. $link = $links[0];
  348. $target = array_key_exists( $link->target, $targetOptions ) ? $targetOptions[ $link->target ] : '_self';
  349.  
  350. $anchorStart = sprintf( '<a href="%1$s"%2$s%3$s>',
  351. esc_url( $link->url ),
  352. empty( $target ) ? '' : ' target="' . $target . '"',
  353. empty( $link->followString ) ? '' : ' rel="' . $link->followString . '"'
  354. );
  355. }
  356.  
  357. break;
  358. }
  359.  
  360. if ( $displayImage ) {
  361.  
  362. // Allow extension to filter the img class.
  363. $atts['class'] = apply_filters( 'cn_image_class', $atts['class'] );
  364.  
  365. // Add the 2x (retina) image to the srcset.
  366. /*$srcset['2x'] = array(
  367. 'src' => add_query_arg(
  368. array(
  369. CN_IMAGE_ENDPOINT => $wp_rewrite->using_permalinks() ? FALSE : TRUE,
  370. 'src' => $this->getOriginalImageURL( $atts['image'] ),
  371. 'cn-entry-slug' => $this->getSlug(),
  372. 'w' => $image['width'] * 2,
  373. 'h' => $atts['height'] * 2,
  374. 'zc' => $cropMode,
  375. ),
  376. ( $wp_rewrite->using_permalinks() ? home_url( CN_IMAGE_ENDPOINT ) : home_url() ) ),
  377. 'width' => '2x'
  378. );*/
  379.  
  380. // Allow extensions to add/remove images to the srcset.
  381. $srcset = apply_filters( 'cn_image_srcset', $srcset );
  382.  
  383. foreach ( $srcset as $src ) {
  384.  
  385. $atts['srcset'][] = implode( ' ', $src );
  386. }
  387.  
  388. $atts['srcset'] = implode( ', ', $atts['srcset'] );
  389.  
  390. // Allow extensions to add/remove sizes media queries.
  391. $atts['sizes'] = apply_filters( 'cn_image_sizes', $atts['sizes'] );
  392.  
  393. $atts['sizes'] = implode( ', ', $atts['sizes'] );
  394.  
  395. // Remove any values in the $atts array that not not img attributes and add those that are to the $tag array.
  396. foreach ( $atts as $attr => $value ) {
  397. if ( ! empty( $value ) && ! in_array( $attr , $nonAtts ) ) $tag[] = "$attr=\"$value\"";
  398. }
  399.  
  400. // All extensions to apply/remove inline styles.
  401. $atts['style'] = apply_filters( 'cn_image_styles', $atts['style'] );
  402.  
  403. if ( is_array( $atts['style'] ) && ! empty( $atts['style'] ) ) array_walk( $atts['style'], create_function( '&$i, $property', '$i = "$property: $i";' ) );
  404.  
  405. // The inner <span> is required for responsive image support. This markup also makes it IE8 compatible.
  406. $out = sprintf( '<span class="cn-image-style"><span style="display: block; max-width: 100%%; width: %2$spx">%3$s<img %4$s%1$s/>%5$s</span></span>',
  407. empty( $atts['style'] ) ? '' : ' style="' . implode( '; ', $atts['style'] ) . ';"',
  408. absint( $image['width'] ),
  409. empty( $anchorStart ) ? '' : $anchorStart,
  410. implode( ' ', $tag ),
  411. empty( $anchorStart ) ? '' : '</a>'
  412. );
  413.  
  414. } else {
  415.  
  416. if ( $customSize ) {
  417.  
  418. /*
  419. * Set the size to the supplied custom. The fallback custom size would take priority if it has been supplied.
  420. */
  421. $atts['style']['width'] = empty( $atts['fallback']['width'] ) ? $atts['width'] . 'px' : $atts['fallback']['width'] . 'px';
  422. $atts['style']['height'] = empty( $atts['fallback']['height'] ) ? $atts['height'] . 'px' : $atts['fallback']['height'] . 'px';
  423.  
  424. } else {
  425. /*
  426. * If a custom size was not set, use the dimensions saved in the settings.
  427. */
  428. switch ( $atts['image'] ) {
  429. case 'photo':
  430.  
  431. switch ( $atts['preset'] ) {
  432.  
  433. case 'entry':
  434. $atts['style']['width'] = cnSettingsAPI::get( 'connections', 'image_medium', 'width' ) . 'px';
  435. $atts['style']['height'] = cnSettingsAPI::get( 'connections', 'image_medium', 'height' ) . 'px';
  436. break;
  437.  
  438. case 'profile':
  439. $atts['style']['width'] = cnSettingsAPI::get( 'connections', 'image_large', 'width' ) . 'px';
  440. $atts['style']['height'] = cnSettingsAPI::get( 'connections', 'image_large', 'height' ) . 'px';
  441. break;
  442.  
  443. case 'thumbnail':
  444. $atts['style']['width'] = cnSettingsAPI::get( 'connections', 'image_thumbnail', 'width' ) . 'px';
  445. $atts['style']['height'] = cnSettingsAPI::get( 'connections', 'image_thumbnail', 'height' ) . 'px';
  446. break;
  447.  
  448. default:
  449. $atts['style']['width'] = cnSettingsAPI::get( 'connections', 'image_medium', 'width' ) . 'px';
  450. $atts['style']['height'] = cnSettingsAPI::get( 'connections', 'image_medium', 'height' ) . 'px';
  451. break;
  452. }
  453.  
  454. break;
  455.  
  456. case 'logo':
  457.  
  458. $atts['style']['width'] = cnSettingsAPI::get( 'connections', 'image_logo', 'width' ) . 'px';
  459. $atts['style']['height'] = cnSettingsAPI::get( 'connections', 'image_logo', 'height' ) . 'px';
  460. break;
  461. }
  462. }
  463.  
  464. switch ( $atts['fallback']['type'] ) {
  465.  
  466. case 'block':
  467.  
  468. $atts['style']['display'] = 'inline-block';
  469.  
  470. if ( is_array( $atts['style'] ) && ! empty( $atts['style'] ) ) array_walk( $atts['style'], create_function( '&$i, $property', '$i = "$property: $i";' ) );
  471.  
  472. $string = empty( $atts['fallback']['string'] ) ? '' : '<span>' . $atts['fallback']['string'] . '</span>';
  473.  
  474. $out = sprintf( '<span class="cn-image-style" style="display: inline-block;"><span class="cn-image-%1$s cn-image-none"%2$s>%3$s</span></span>',
  475. esc_attr( $atts['image'] ),
  476. empty( $atts['style'] ) ? '' : ' style="' . implode( '; ', $atts['style'] ) . ';"',
  477. $string
  478. );
  479.  
  480. break;
  481.  
  482. case 'default':
  483. /*
  484. * @TODO Enable support for a default image to be set.
  485. * NOTE: Use switch for image type to allow a default image for both the image and logo.
  486. */
  487. break;
  488. }
  489. }
  490.  
  491. $out = apply_filters( 'cn_output_image', $out, $atts, $this );
  492.  
  493. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  494.  
  495. return $this->echoOrReturn( $atts['return'], $out );
  496. }
  497.  
  498. /**
  499. * Returns the permalink for the entry.
  500. *
  501. * @access public
  502. * @since 8.1.6
  503. *
  504. * @uses cnURL::permalink()
  505. *
  506. * @return string
  507. */
  508. public function permalink() {
  509.  
  510. cnURL::permalink(
  511. array(
  512. 'type' => 'name',
  513. 'slug' => $this->getSlug(),
  514. 'home_id' => $this->directoryHome['page_id'],
  515. 'force_home' => $this->directoryHome['force_home'],
  516. 'data' => 'url',
  517. 'return' => FALSE,
  518. )
  519. );
  520. }
  521.  
  522. /**
  523. * Echo or return the entry name in a HTML hCard compliant string.
  524. *
  525. * @example
  526. * If an entry is an individual this would return their name as Last Name, First Name
  527. *
  528. * $this->getName( array( 'format' => '%last%, %first% %middle%' ) );
  529. *
  530. * NOTE: If an entry is a organization/family, this will return the organization/family name instead
  531. * ignoring the format attribute because it does not apply.
  532. *
  533. * @access public
  534. * @since unknown
  535. *
  536. * @param array $atts {
  537. * Optional.
  538. *
  539. * @type string $format How the name should be displayed using Tokens for the parts of the name.
  540. * Default, '%prefix% %first% %middle% %last% %suffix%'.
  541. * Accepts any combination of the following tokens:
  542. * '%prefix%', '%first%', '%middle%', '%last%', '%suffix%', '%first_initial%', '%middle_initial%','%last_initial%'
  543. * @type string $before HTML to be displayed before the relations container. Default, empty string.
  544. * @type string $after HTML to be displayed after the relations container. Default, empty string.
  545. * @type bool $return Whether or not to return the HTML. Default, FALSE.
  546. * }
  547. *
  548. * @return string
  549. */
  550. public function getNameBlock( $atts = array() ) {
  551.  
  552. $defaults = array(
  553. 'format' => '%prefix% %first% %middle% %last% %suffix%',
  554. 'link' => cnSettingsAPI::get( 'connections', 'connections_link', 'name' ),
  555. 'target' => 'name',
  556. 'before' => '',
  557. 'after' => '',
  558. 'return' => FALSE
  559. );
  560.  
  561. /**
  562. * Filter the arguments.
  563. *
  564. * @since unknown
  565. *
  566. * @param array $atts An array of arguments.
  567. */
  568. $atts = cnSanitize::args(
  569. apply_filters( 'cn_output_name_atts', $atts ),
  570. apply_filters( 'cn_output_name_default_atts', $defaults )
  571. );
  572.  
  573. $search = array(
  574. '%prefix%',
  575. '%first%',
  576. '%middle%',
  577. '%last%',
  578. '%suffix%',
  579. '%first_initial%',
  580. '%middle_initial%',
  581. '%last_initial%',
  582. );
  583. $replace = array();
  584. $honorificPrefix = $this->getHonorificPrefix();
  585. $first = $this->getFirstName();
  586. $middle = $this->getMiddleName();
  587. $last = $this->getLastName();
  588. $honorificSuffix = $this->getHonorificSuffix();
  589.  
  590. switch ( $this->getEntryType() ) {
  591.  
  592. case 'organization':
  593.  
  594. // The `notranslate` class is added to prevent Google Translate from translating the text.
  595. $html = '<span class="org fn notranslate">' . $this->getOrganization() . '</span>';
  596.  
  597. break;
  598.  
  599. case 'family':
  600.  
  601. $html = '<span class="fn n notranslate"><span class="family-name">' . $this->getFamilyName() . '</span></span>';
  602.  
  603. break;
  604.  
  605. default:
  606.  
  607. $replace[] = 0 == strlen( $honorificPrefix ) ? '' : '<span class="honorific-prefix">' . $honorificPrefix . '</span>';
  608.  
  609. $replace[] = 0 == strlen( $first ) ? '' : '<span class="given-name">' . $first . '</span>';
  610.  
  611. $replace[] = 0 == strlen( $middle ) ? '' : '<span class="additional-name">' . $middle . '</span>';
  612.  
  613. $replace[] = 0 == strlen( $last ) ? '' : '<span class="family-name">' . $last . '</span>';
  614.  
  615. $replace[] = 0 == strlen( $honorificSuffix ) ? '' : '<span class="honorific-suffix">' . $honorificSuffix . '</span>';
  616.  
  617. $replace[] = 0 == strlen( $first ) ? '' : '<span class="given-name-initial">' . $first[0] . '</span>';
  618.  
  619. $replace[] = 0 == strlen( $middle ) ? '' : '<span class="additional-name-initial">' . $middle[0] . '</span>';
  620.  
  621. $replace[] = 0 == strlen( $last ) ? '' : '<span class="family-name-initial">' . $last[0] . '</span>';
  622.  
  623. $html = str_ireplace(
  624. $search,
  625. $replace,
  626. '<span class="fn n notranslate">' . ( empty( $atts['format'] ) ? $defaults['format'] : $atts['format'] ) . '</span>'
  627. );
  628.  
  629. break;
  630. }
  631.  
  632. $html = cnString::replaceWhatWith( $html, ' ' );
  633.  
  634. if ( $atts['link'] ) {
  635.  
  636. $html = cnURL::permalink(
  637. array(
  638. 'type' => $atts['target'],
  639. 'slug' => $this->getSlug(),
  640. 'title' => $this->getName( $atts ),
  641. 'text' => $html,
  642. 'home_id' => $this->directoryHome['page_id'],
  643. 'force_home' => $this->directoryHome['force_home'],
  644. 'return' => TRUE,
  645. )
  646. );
  647. }
  648.  
  649. $html = $atts['before'] . $html . $atts['after'] . PHP_EOL;
  650.  
  651. return $this->echoOrReturn( $atts['return'], $html );
  652. }
  653.  
  654. /**
  655. * Returns the Entry's full first and last name.
  656. *
  657. * NOTE: If an entry is a organization/family, this will return the organization/family name instead
  658. * ignoring the format attribute because it does not apply.
  659. *
  660. * @deprecated since 0.7.2.0
  661. * @return string
  662. */
  663. public function getFullFirstLastNameBlock() {
  664. return $this->getNameBlock( array( 'format' => '%prefix% %first% %middle% %last% %suffix%', 'return' => TRUE ) );
  665. }
  666.  
  667. /**
  668. * Returns the Entry's full first and last name with the last name first.
  669. *
  670. * NOTE: If an entry is a organization/family, this will return the organization/family name instead
  671. * ignoring the format attribute because it does not apply.
  672. *
  673. * @deprecated since 0.7.2.0
  674. * @return string
  675. */
  676. public function getFullLastFirstNameBlock() {
  677. return $this->getNameBlock( array( 'format' => '%last%, %first% %middle%', 'return' => TRUE ) );
  678. }
  679.  
  680. /**
  681. * Echos the family members of the family entry type.
  682. *
  683. * @deprecated since 0.7.1.0
  684. * @return string
  685. */
  686. public function getConnectionGroupBlock() {
  687. $this->getFamilyMemberBlock();
  688. }
  689.  
  690. /**
  691. * Echos the family members of the family entry type.
  692. *
  693. * @access public
  694. * @since unknown
  695. *
  696. * @param array $atts {
  697. * Optional.
  698. *
  699. * @type string $container_tag The relationship container tag. Default `ul`. Accepts HTML tag.
  700. * @type string $item_tag The relationship row tag. Default `li`. Accepts HTML tag.
  701. * @type string $item_format The relationship row HTML markup.
  702. * @type string $name_format How the relationship name should be displayed @see cnEntry::getName().
  703. * @type string $separator The string used to separate the relation label from the relation name. Default ':'.
  704. * @type string $before HTML to be displayed before the relations container. Default, empty string.
  705. * @type string $after HTML to be displayed after the relations container. Default, empty string.
  706. * @type string $before_item HTML to be displayed before a relation row. Default, empty string.
  707. * @type string $after_item HTML to be displayed after a relation row. Default, empty string.
  708. * }
  709. *
  710. * @return string
  711. */
  712. public function getFamilyMemberBlock( $atts = array() ) {
  713.  
  714. $defaults = array(
  715. 'container_tag' => 'ul',
  716. 'item_tag' => 'li',
  717. 'item_format' => '<%1$s class="cn-relation"><span class="cn-relation-label">%relation%</span>%separator% <span class="cn-relation-name notranslate">%name%</span></%1$s>', // The `notranslate` class is added to prevent Google Translate from translating the text.
  718. 'name_format' => '',
  719. 'separator' => ':',
  720. 'before' => '',
  721. 'after' => '',
  722. 'before_item' => '',
  723. 'after_item' => '',
  724. 'return' => FALSE,
  725. );
  726.  
  727. /**
  728. * Filter the arguments.
  729. *
  730. * @since unknown
  731. *
  732. * @param array $atts An array of arguments.
  733. */
  734. $atts = cnSanitize::args(
  735. apply_filters( 'cn_output_family_atts', $atts ),
  736. apply_filters( 'cn_output_family_default_atts', $defaults )
  737. );
  738.  
  739. $html = '';
  740. $search = array( '%relation%', '%name%', '%separator%' );
  741.  
  742. if ( $relations = $this->getFamilyMembers() ) {
  743.  
  744. // Grab an instance of the Connections object.
  745. $instance = Connections_Directory();
  746.  
  747. foreach ( $relations as $relationData ) {
  748.  
  749. $relation = new cnEntry();
  750. $replace = array();
  751.  
  752. if ( $relation->set( $relationData['entry_id'] ) ) {
  753.  
  754. $replace[] = $instance->options->getFamilyRelation( $relationData['relation'] );
  755.  
  756. $replace[] = cnURL::permalink(
  757. array(
  758. 'type' => 'name',
  759. 'slug' => $relation->getSlug(),
  760. 'title' => $relation->getName( array( 'format' => $atts['name_format'] ) ),
  761. 'text' => $relation->getName( array( 'format' => $atts['name_format'] ) ),
  762. 'home_id' => $this->directoryHome['page_id'],
  763. 'force_home' => $this->directoryHome['force_home'],
  764. 'return' => TRUE,
  765. )
  766. );
  767.  
  768. $replace[] = empty( $atts['separator'] ) ? '' : '<span class="cn-separator">' . $atts['separator'] . '</span>';
  769.  
  770. $row = str_ireplace(
  771. $search,
  772. $replace,
  773. empty( $atts['item_format'] ) ? $defaults['item_format'] : $atts['item_format']
  774. );
  775.  
  776. $html .= "\t" . sprintf( $row, $atts['item_tag'] ) . PHP_EOL;
  777. }
  778. }
  779.  
  780. $html = sprintf(
  781. '<%1$s class="cn-relations">' . PHP_EOL . '%2$s</%1$s>',
  782. $atts['container_tag'],
  783. $html
  784. );
  785.  
  786. $html = $atts['before'] . $html . $atts['after'] . PHP_EOL;
  787. }
  788.  
  789. return $this->echoOrReturn( $atts['return'], $html );
  790. }
  791.  
  792. /**
  793. * Echo or return the entry's title in a HTML hCard compliant string.
  794. *
  795. * Accepted options for the $atts property are:
  796. * before (string) HTML to output before an address.
  797. * after (string) HTML to after before an address.
  798. * return (bool) Return string if set to TRUE instead of echo string.
  799. *
  800. * Filters:
  801. * cn_output_default_atts_title => (array) Register the methods default attributes.
  802. *
  803. * @access public
  804. * @since unknown
  805. *
  806. * @param array $atts Accepted values as noted above.
  807. *
  808. * @return string
  809. */
  810. public function getTitleBlock( $atts = array() ) {
  811.  
  812. $defaults = array(
  813. 'tag' => 'span',
  814. 'before' => '',
  815. 'after' => '',
  816. 'return' => FALSE
  817. );
  818.  
  819. /**
  820. * All extensions to filter the method default and supplied args.
  821. *
  822. * @since 8.5.18
  823. */
  824. $atts = cnSanitize::args(
  825. apply_filters( 'cn_output_atts_title', $atts ),
  826. apply_filters( 'cn_output_default_atts_title', $defaults )
  827. );
  828.  
  829. $title = $this->getTitle();
  830.  
  831. if ( ! empty( $title ) ) {
  832.  
  833. // The `notranslate` class is added to prevent Google Translate from translating the text.
  834. $out = sprintf( '<%1$s class="title notranslate">%2$s</%1$s>', $atts['tag'], $title );
  835.  
  836. } else {
  837.  
  838. return '';
  839. }
  840.  
  841. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  842.  
  843. return $this->echoOrReturn( $atts['return'], $out );
  844. }
  845.  
  846. /**
  847. * Echo or return the entry's organization and/or department in a HTML hCard compliant string.
  848. *
  849. * Accepted options for the $atts property are:
  850. * before (string) HTML to output before an address.
  851. * after (string) HTML to after before an address.
  852. * return (bool) Return string if set to TRUE instead of echo string.
  853. *
  854. * Filters:
  855. * cn_output_default_atts_orgunit => (array) Register the methods default attributes.
  856. *
  857. * @access public
  858. * @since unknown
  859. *
  860. * @param array $atts Accepted values as noted above.
  861. *
  862. * @return string
  863. */
  864. public function getOrgUnitBlock( $atts = array() ) {
  865.  
  866. $out = '';
  867.  
  868. $defaults = array(
  869. 'before' => '',
  870. 'after' => '',
  871. 'show_org' => TRUE,
  872. 'show_dept' => TRUE,
  873. 'link' => array(
  874. 'organization' => cnSettingsAPI::get( 'connections', 'connections_link', 'organization' ),
  875. 'department' => cnSettingsAPI::get( 'connections', 'connections_link', 'department' )
  876. ),
  877. 'return' => FALSE
  878. );
  879.  
  880. /**
  881. * All extensions to filter the method default and supplied args.
  882. *
  883. * @since 8.5.18
  884. */
  885. $atts = cnSanitize::args(
  886. apply_filters( 'cn_output_atts_orgunit', $atts ),
  887. apply_filters( 'cn_output_default_atts_orgunit', $defaults )
  888. );
  889.  
  890. $org = $atts['show_org'] ? $this->getOrganization() : '';
  891. $dept = $atts['show_dept'] ? $this->getDepartment() : '';
  892.  
  893. if ( ! empty( $org ) || ! empty( $dept ) ) {
  894.  
  895. $out .= '<span class="org">';
  896.  
  897. if ( ! empty( $org ) ) {
  898.  
  899. if ( $atts['link']['organization'] ) {
  900.  
  901. $organization = cnURL::permalink( array(
  902. 'type' => 'organization',
  903. 'slug' => $org,
  904. 'title' => $org,
  905. 'text' => $org,
  906. 'home_id' => $this->directoryHome['page_id'],
  907. 'force_home' => $this->directoryHome['force_home'],
  908. 'return' => TRUE
  909. )
  910. );
  911.  
  912. } else {
  913.  
  914. $organization = $org;
  915. }
  916.  
  917. // The `notranslate` class is added to prevent Google Translate from translating the text.
  918. $out .= '<span class="organization-name notranslate"' . ( $this->getEntryType() == 'organization' ? ' style="display: none;"' : '' ) . '>' . $organization . '</span>';
  919. }
  920.  
  921. if ( ! empty( $dept ) ) {
  922.  
  923. if ( $atts['link']['department'] ) {
  924.  
  925. $department = cnURL::permalink( array(
  926. 'type' => 'department',
  927. 'slug' => $dept,
  928. 'title' => $dept,
  929. 'text' => $dept,
  930. 'home_id' => $this->directoryHome['page_id'],
  931. 'force_home' => $this->directoryHome['force_home'],
  932. 'return' => TRUE
  933. )
  934. );
  935.  
  936. } else {
  937.  
  938. $department = $dept;
  939. }
  940.  
  941. // The `notranslate` class is added to prevent Google Translate from translating the text.
  942. $out .= '<span class="organization-unit notranslate">' . $department . '</span>';
  943. }
  944.  
  945. $out .= '</span>';
  946. }
  947.  
  948. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  949.  
  950. return $this->echoOrReturn( $atts['return'], $out );
  951. }
  952.  
  953. /**
  954. * Return the entry's organization and/or department in a HTML hCard compliant string.
  955. *
  956. * @deprecated since 0.7.2.0
  957. */
  958. public function getOrganizationBlock() {
  959. return $this->getOrgUnitBlock( array( 'return' => TRUE ) );
  960. }
  961.  
  962. /**
  963. * Return the entry's organization and/or department in a HTML hCard compliant string.
  964. *
  965. * @deprecated since 0.7.2.0
  966. */
  967. public function getDepartmentBlock() {
  968. return $this->getOrgUnitBlock( array( 'return' => TRUE ) );
  969. }
  970.  
  971. /**
  972. * Echo or return the entry's contact name in a HTML string.
  973. *
  974. * @access public
  975. * @since unknown
  976. *
  977. * @param array $atts {
  978. * Optional. An array of arguments.
  979. *
  980. * @type string $format The format the contact name should be returned as.
  981. * Default: %label%%separator% %first% %last%
  982. * Accepts any combination of the following tokens: '%label%', '%first%', '%last%', '%separator%'
  983. * @type string $label The label shown for the contact name.
  984. * Default: Contact
  985. * @type string $separator The separator to use between the label and contact name.
  986. * @type string $before The content to render before the contact name block.
  987. * @type string $after The content to render after the contact name block.
  988. * @type bool $return Whether or not to echo or return the HTML.
  989. * Default: FALSE, which is to echo the result.
  990. * }
  991. *
  992. * @return string
  993. */
  994. public function getContactNameBlock( $atts = array() ) {
  995.  
  996. $defaults = array(
  997. 'format' => '',
  998. 'label' => __( 'Contact', 'connections' ),
  999. 'separator' => ':',
  1000. 'before' => '',
  1001. 'after' => '',
  1002. 'return' => FALSE
  1003. );
  1004.  
  1005. /**
  1006. * All extensions to filter the method default and supplied args.
  1007. *
  1008. * @since 8.5.18
  1009. */
  1010. $atts = cnSanitize::args(
  1011. apply_filters( 'cn_output_atts_contact_name', $atts ),
  1012. apply_filters( 'cn_output_default_atts_contact_name', $defaults )
  1013. );
  1014.  
  1015. $search = array( '%label%', '%first%', '%last%', '%separator%' );
  1016. $replace = array();
  1017. $first = $this->getContactFirstName();
  1018. $last = $this->getContactLastName();
  1019.  
  1020. if ( empty( $first ) && empty( $last ) ) {
  1021.  
  1022. return '';
  1023. }
  1024.  
  1025. $replace[] = 0 == strlen( $first ) && 0 == strlen( $last ) ? '' : '<span class="contact-label">' . $atts['label'] . '</span>';
  1026.  
  1027. // The `notranslate` class is added to prevent Google Translate from translating the text.
  1028. $replace[] = 0 == strlen( $first ) ? '' : '<span class="contact-given-name notranslate">' . $first . '</span>';
  1029.  
  1030. // The `notranslate` class is added to prevent Google Translate from translating the text.
  1031. $replace[] = 0 == strlen( $last ) ? '' : '<span class="contact-family-name notranslate">' . $last . '</span>';
  1032.  
  1033. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  1034.  
  1035. $out = str_ireplace(
  1036. $search,
  1037. $replace,
  1038. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label%%separator% %first% %last%' : $defaults['format'] ) : $atts['format']
  1039. );
  1040.  
  1041. $out = cnString::replaceWhatWith( $out, ' ' );
  1042.  
  1043. $block = '<span class="cn-contact-block">' . $out . '</span>';
  1044.  
  1045. $html = $atts['before'] . $block . $atts['after'] . PHP_EOL;
  1046.  
  1047. return $this->echoOrReturn( $atts['return'], $html );
  1048. }
  1049.  
  1050. /**
  1051. * Echo or return the entry's addresses in a HTML hCard compliant string.
  1052. *
  1053. * Accepted options for the $atts property are:
  1054. * preferred (bool) Retrieve the preferred entry address.
  1055. * type (array) || (string) Retrieve specific address types.
  1056. * Permitted Types:
  1057. * home
  1058. * work
  1059. * school
  1060. * other
  1061. * district (array) || (string) Retrieve addresses in a specific district.
  1062. * county (array) || (string) Retrieve addresses in a specific county.
  1063. * city (array) || (string) Retrieve addresses in a specific city.
  1064. * state (array) || (string) Retrieve addresses in a specific state..
  1065. * zipcode (array) || (string) Retrieve addresses in a specific zipcode.
  1066. * country (array) || (string) Retrieve addresses in a specific country.
  1067. * coordinates (array) Retrieve addresses in with specific coordinates. Both latitude and longitude must be supplied.
  1068. * format (string) The tokens to use to display the address block parts.
  1069. * Permitted Tokens:
  1070. * %label%
  1071. * %line1%
  1072. * %line2%
  1073. * %line3%
  1074. * %city%
  1075. * %state%
  1076. * %zipcode%
  1077. * %country%
  1078. * %geo%
  1079. * %separator%
  1080. * separator (string) The separator to use.
  1081. * before (string) HTML to output before the addresses.
  1082. * after (string) HTML to after before the addresses.
  1083. * return (bool) Return string if set to TRUE instead of echo string.
  1084. *
  1085. * Filters:
  1086. * cn_output_default_atts_address => (array) Register the methods default attributes.
  1087. *
  1088. * @access public
  1089. * @since unknown
  1090. *
  1091. * @param array $atts Accepted values as noted above.
  1092. * @param bool $cached Returns the cached address rather than querying the db.
  1093. *
  1094. * @return string
  1095. */
  1096. public function getAddressBlock( $atts = array(), $cached = TRUE ) {
  1097.  
  1098. $defaults = array(
  1099. 'preferred' => NULL,
  1100. 'type' => NULL,
  1101. 'limit' => NULL,
  1102. 'district' => NULL,
  1103. 'county' => NULL,
  1104. 'city' => NULL,
  1105. 'state' => NULL,
  1106. 'zipcode' => NULL,
  1107. 'country' => NULL,
  1108. 'coordinates' => array(),
  1109. 'format' => '',
  1110. 'link' => array(
  1111. 'district' => cnSettingsAPI::get( 'connections', 'link', 'district' ),
  1112. 'county' => cnSettingsAPI::get( 'connections', 'link', 'county' ),
  1113. 'locality' => cnSettingsAPI::get( 'connections', 'link', 'locality' ),
  1114. 'region' => cnSettingsAPI::get( 'connections', 'link', 'region' ),
  1115. 'postal_code' => cnSettingsAPI::get( 'connections', 'link', 'postal_code' ),
  1116. 'country' => cnSettingsAPI::get( 'connections', 'link', 'country' ),
  1117. ),
  1118. 'separator' => ':',
  1119. 'before' => '',
  1120. 'after' => '',
  1121. 'return' => FALSE,
  1122. );
  1123.  
  1124. /**
  1125. * All extensions to filter the method default and supplied args.
  1126. *
  1127. * @since 8.5.18
  1128. */
  1129. $atts = cnSanitize::args(
  1130. apply_filters( 'cn_output_atts_address', $atts ),
  1131. apply_filters( 'cn_output_default_atts_address', $defaults )
  1132. );
  1133.  
  1134. $atts['link'] = cnSanitize::args( $atts['link'], $defaults['link'] );
  1135. $atts['id'] = $this->getId();
  1136.  
  1137. $out = '';
  1138. $addresses = $this->getAddresses( $atts, $cached );
  1139. $search = array(
  1140. '%label%',
  1141. '%line1%',
  1142. '%line2%',
  1143. '%line3%',
  1144. '%line4%',
  1145. '%district%',
  1146. '%county%',
  1147. '%city%',
  1148. '%state%',
  1149. '%zipcode%',
  1150. '%country%',
  1151. '%geo%',
  1152. '%separator%'
  1153. );
  1154.  
  1155. if ( empty( $addresses ) ) return '';
  1156.  
  1157. $out .= '<span class="address-block">' . PHP_EOL;
  1158.  
  1159. foreach ( $addresses as $address ) {
  1160. $replace = array();
  1161.  
  1162. $out .= '<span class="adr cn-address' . ( $address->preferred ? ' cn-preferred cn-address-preferred' : '' ) . '">' . PHP_EOL;
  1163.  
  1164. // The `notranslate` class is added to prevent Google Translate from translating the text.
  1165. $replace[] = empty( $address->name ) ? '' : '' . PHP_EOL;
  1166. $replace[] = empty( $address->line_1 ) ? '' : '<span class="street-address notranslate">' . $address->line_1 . '</span>' . PHP_EOL;
  1167. $replace[] = empty( $address->line_2 ) ? '' : '<span class="street-address notranslate">' . $address->line_2 . '</span>' . PHP_EOL;
  1168. $replace[] = empty( $address->line_3 ) ? '' : '<span class="street-address notranslate">' . $address->line_3 . '</span>' . PHP_EOL;
  1169. $replace[] = empty( $address->line_4 ) ? '' : '<span class="street-address notranslate">' . $address->line_4 . '</span>' . PHP_EOL;
  1170.  
  1171. if ( 0 == strlen( $address->district ) ) {
  1172.  
  1173. $replace[] = '';
  1174.  
  1175. } else {
  1176.  
  1177. if ( $atts['link']['district'] ) {
  1178.  
  1179. $district = cnURL::permalink(
  1180. array(
  1181. 'type' => 'district',
  1182. 'slug' => $address->district,
  1183. 'title' => $address->district,
  1184. 'text' => $address->district,
  1185. 'home_id' => $this->directoryHome['page_id'],
  1186. 'force_home' => $this->directoryHome['force_home'],
  1187. 'return' => TRUE
  1188. )
  1189. );
  1190.  
  1191. } else {
  1192.  
  1193. $district = $address->district;
  1194. }
  1195.  
  1196. $replace[] = '<span class="district notranslate">' . $district . '</span>' . PHP_EOL;
  1197.  
  1198. }
  1199.  
  1200. if ( 0 == strlen( $address->county ) ) {
  1201.  
  1202. $replace[] = '';
  1203.  
  1204. } else {
  1205.  
  1206. if ( $atts['link']['county'] ) {
  1207.  
  1208. $county = cnURL::permalink(
  1209. array(
  1210. 'type' => 'county',
  1211. 'slug' => $address->county,
  1212. 'title' => $address->county,
  1213. 'text' => $address->county,
  1214. 'home_id' => $this->directoryHome['page_id'],
  1215. 'force_home' => $this->directoryHome['force_home'],
  1216. 'return' => TRUE
  1217. )
  1218. );
  1219.  
  1220. } else {
  1221.  
  1222. $county = $address->county;
  1223. }
  1224.  
  1225. $replace[] = '<span class="county notranslate">' . $county . '</span>' . PHP_EOL;
  1226.  
  1227. }
  1228.  
  1229. if ( empty( $address->city ) ) {
  1230.  
  1231. $replace[] = '';
  1232.  
  1233. } else {
  1234.  
  1235. if ( $atts['link']['locality'] ) {
  1236.  
  1237. $locality = cnURL::permalink( array(
  1238. 'type' => 'locality',
  1239. 'slug' => $address->city,
  1240. 'title' => $address->city,
  1241. 'text' => $address->city,
  1242. 'home_id' => $this->directoryHome['page_id'],
  1243. 'force_home' => $this->directoryHome['force_home'],
  1244. 'return' => TRUE
  1245. )
  1246. );
  1247.  
  1248. } else {
  1249.  
  1250. $locality = $address->city;
  1251. }
  1252.  
  1253. $replace[] = '<span class="locality">' . $locality . '</span>' . PHP_EOL;
  1254.  
  1255. }
  1256.  
  1257. if ( empty( $address->state ) ) {
  1258.  
  1259. $replace[] = '';
  1260.  
  1261. } else {
  1262.  
  1263. if ( $atts['link']['region'] ) {
  1264.  
  1265. $region = cnURL::permalink( array(
  1266. 'type' => 'region',
  1267. 'slug' => $address->state,
  1268. 'title' => $address->state,
  1269. 'text' => $address->state,
  1270. 'home_id' => $this->directoryHome['page_id'],
  1271. 'force_home' => $this->directoryHome['force_home'],
  1272. 'return' => TRUE
  1273. )
  1274. );
  1275.  
  1276. } else {
  1277.  
  1278. $region = $address->state;
  1279. }
  1280.  
  1281. $replace[] = '<span class="region">' . $region . '</span>' . PHP_EOL;
  1282.  
  1283. }
  1284.  
  1285. if ( empty( $address->zipcode ) ) {
  1286.  
  1287. $replace[] = '';
  1288.  
  1289. } else {
  1290.  
  1291. if ( $atts['link']['postal_code'] ) {
  1292.  
  1293. $postal = cnURL::permalink( array(
  1294. 'type' => 'postal_code',
  1295. 'slug' => $address->zipcode,
  1296. 'title' => $address->zipcode,
  1297. 'text' => $address->zipcode,
  1298. 'home_id' => $this->directoryHome['page_id'],
  1299. 'force_home' => $this->directoryHome['force_home'],
  1300. 'return' => TRUE
  1301. )
  1302. );
  1303.  
  1304. } else {
  1305.  
  1306. $postal = $address->zipcode;
  1307. }
  1308.  
  1309. $replace[] = '<span class="postal-code">' . $postal . '</span>' . PHP_EOL;
  1310.  
  1311. }
  1312.  
  1313. if ( empty( $address->country ) ) {
  1314.  
  1315. $replace[] = '';
  1316.  
  1317. } else {
  1318.  
  1319. if ( $atts['link']['country'] ) {
  1320.  
  1321. $country = cnURL::permalink( array(
  1322. 'type' => 'country',
  1323. 'slug' => $address->country,
  1324. 'title' => $address->country,
  1325. 'text' => $address->country,
  1326. 'home_id' => $this->directoryHome['page_id'],
  1327. 'force_home' => $this->directoryHome['force_home'],
  1328. 'return' => TRUE
  1329. )
  1330. );
  1331.  
  1332. } else {
  1333.  
  1334. $country = $address->country;
  1335. }
  1336.  
  1337. $replace[] = '<span class="country-name">' . $country . '</span>' . PHP_EOL;
  1338.  
  1339. }
  1340.  
  1341. if ( ! empty( $address->latitude ) || ! empty( $address->longitude ) ) {
  1342. $replace[] = '<span class="geo">' .
  1343. ( empty( $address->latitude ) ? '' : '<span class="latitude" title="' . $address->latitude . '"><span class="cn-label">' . __( 'Latitude', 'connections' ) . ': </span>' . $address->latitude . '</span>' ) .
  1344. ( empty( $address->longitude ) ? '' : '<span class="longitude" title="' . $address->longitude . '"><span class="cn-label">' . __( 'Longitude', 'connections' ) . ': </span>' . $address->longitude . '</span>' ) .
  1345. '</span>' . PHP_EOL;
  1346. }
  1347.  
  1348. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>' . PHP_EOL;
  1349.  
  1350. $out .= str_ireplace(
  1351. $search,
  1352. $replace,
  1353. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label% %line1% %line2% %line3% %line4% %district% %county% %city% %state% %zipcode% %country%' : $defaults['format'] ) : $atts['format']
  1354. );
  1355.  
  1356. // Set the hCard Address Type.
  1357. $out .= $this->gethCardAdrType( $address->type );
  1358.  
  1359. $out .= '</span>' . PHP_EOL;
  1360. }
  1361.  
  1362. $out .= '</span>' . PHP_EOL;
  1363.  
  1364. $out = cnString::replaceWhatWith( $out, ' ' );
  1365.  
  1366. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  1367.  
  1368. return $this->echoOrReturn( $atts['return'], $out );
  1369. }
  1370.  
  1371. /**
  1372. * Echo or return a <div> with the entry's address within the HTML5 data- attribute. To be used for
  1373. * placing a Google Map in with the jQuery goMap plugin.
  1374. *
  1375. * NOTE: wp_enqueue_script('jquery-gomap-min') must called before use, otherwise just an empty div will be displayed.
  1376. *
  1377. * Accepted options for the $atts property are:
  1378. * preferred (bool) Retrieve the preferred entry address.
  1379. * type (array) || (string) Retrieve specific address types.
  1380. * Permitted Types:
  1381. * home
  1382. * work
  1383. * school
  1384. * other
  1385. * static (bool) Query map via the Google Static Maps API
  1386. * maptype (string) Valid types are: HYBRID, ROADMAP, SATELLITE, TERRAIN
  1387. * zoom (int) Sets the zoom level.
  1388. * height (int) Specifiy the div height in px.
  1389. * width (int) Specifiy the div widdth in px.
  1390. * coordinates (array) Retrieve addresses in with specific coordinates. Both latitude and longitude must be supplied.
  1391. * before (string) HTML to output before the addresses.
  1392. * after (string) HTML to after before the addresses.
  1393. * return (bool) Return string if set to TRUE instead of echo string.
  1394. *
  1395. * @TODO Add support for the Google Maps API Premier client id.
  1396. *
  1397. * Filters:
  1398. * cn_output_default_atts_contact_name => (array) Register the methods default attributes.
  1399. *
  1400. * @access public
  1401. * @since unknown
  1402. *
  1403. * @param array $atts Accepted values as noted above.
  1404. * @param bool $cached Returns the cached address rather than querying the db.
  1405. *
  1406. * @return string
  1407. */
  1408. public function getMapBlock( $atts = array(), $cached = TRUE ) {
  1409.  
  1410. $defaults = array(
  1411. 'preferred' => NULL,
  1412. 'type' => NULL,
  1413. 'static' => FALSE,
  1414. 'maptype' => 'ROADMAP',
  1415. 'zoom' => 13,
  1416. 'height' => 400,
  1417. 'width' => 400,
  1418. 'before' => '',
  1419. 'after' => '',
  1420. 'return' => TRUE,
  1421. );
  1422.  
  1423. /**
  1424. * All extensions to filter the method default and supplied args.
  1425. *
  1426. * @since 8.5.18
  1427. */
  1428. $atts = cnSanitize::args(
  1429. apply_filters( 'cn_output_atts_map', $atts ),
  1430. apply_filters( 'cn_output_default_atts_map', $defaults )
  1431. );
  1432.  
  1433. $atts['id'] = $this->getId();
  1434.  
  1435. $out = '';
  1436. $attr = array();
  1437. $addr = array();
  1438. $geo = array();
  1439.  
  1440. // Limit the map type to one of the valid types to prevent user error.
  1441. $permittedMapTypes = array( 'HYBRID', 'ROADMAP', 'SATELLITE', 'TERRAIN' );
  1442. $atts['maptype'] = strtoupper( $atts['maptype'] );
  1443. if ( ! in_array( $atts['maptype'] , $permittedMapTypes ) ) $atts['maptype'] = 'ROADMAP';
  1444.  
  1445. // Limit the user specified zoom level to between 0 and 21
  1446. if ( ! in_array( $atts['zoom'] , range( 0, 21 ) ) ) $atts['zoom'] = 13;
  1447.  
  1448. // Ensure the requested map size does not exceed the permitted sizes permitted by the Google Static Maps API
  1449. if ( $atts['static'] ) $atts['width'] = ( $atts['width'] <= 640 ) ? $atts['width'] : 640;
  1450. if ( $atts['static'] ) $atts['height'] = ( $atts['height'] <= 640 ) ? $atts['height'] : 640;
  1451.  
  1452. $addresses = $this->getAddresses( $atts , $cached );
  1453.  
  1454. if ( empty( $addresses ) ) return '';
  1455.  
  1456. if ( ! empty( $addresses[0]->line_one ) ) $addr[] = $addresses[0]->line_one;
  1457. if ( ! empty( $addresses[0]->line_two ) ) $addr[] = $addresses[0]->line_two;
  1458. if ( ! empty( $addresses[0]->city ) ) $addr[] = $addresses[0]->city;
  1459. if ( ! empty( $addresses[0]->state ) ) $addr[] = $addresses[0]->state;
  1460. if ( ! empty( $addresses[0]->zipcode ) ) $addr[] = $addresses[0]->zipcode;
  1461.  
  1462. if ( ! empty( $addresses[0]->latitude ) && ! empty( $addresses[0]->longitude ) ) {
  1463. $geo['latitude'] = $addresses[0]->latitude;
  1464. $geo['longitude'] = $addresses[0]->longitude;
  1465. }
  1466.  
  1467. if ( empty( $addr ) && empty( $geo ) ) return '';
  1468.  
  1469. if ( $atts['static'] ) {
  1470. $attr['center'] = ( empty( $geo ) ) ? implode( ', ' , $addr ) : implode( ',' , $geo );
  1471. $attr['markers'] = $attr['center'];
  1472. $attr['size'] = $atts['width'] . 'x' . $atts['height'];
  1473. $attr['maptype'] = $atts['maptype'];
  1474. $attr['zoom'] = $atts['zoom'];
  1475. //$attr['scale'] = 2;
  1476. $attr['format'] = 'png';
  1477. $attr['sensor'] = 'false';
  1478.  
  1479. $out .= '<span class="cn-image-style" style="display: inline-block;"><span class="cn-image" style="height: ' . $atts['height'] . '; width: ' . $atts['width'] . '">';
  1480. $out .= '<img class="map" title="' . $attr['center'] . '" alt="' . $attr['center'] . '" width="' . $atts['width'] . '" height="' . $atts['height'] . '" src="http://maps.googleapis.com/maps/api/staticmap?' . http_build_query( $attr , '' , '&amp;' ) . '"/>';
  1481. $out .= '</span></span>';
  1482. }
  1483. else {
  1484. $attr[] = 'class="cn-gmap" id="map-' . $this->getRuid() . '"';
  1485. if ( ! empty( $addr ) ) $attr[] = 'data-address="' . implode( ', ', $addr ) .'"';
  1486. if ( ! empty( $geo['latitude'] ) ) $attr[] = 'data-latitude="' . $geo['latitude'] .'"';
  1487. if ( ! empty( $geo['longitude'] ) ) $attr[] = 'data-longitude="' . $geo['longitude'] .'"';
  1488. $attr[] = 'style="' . ( ! empty( $atts['width'] ) ? 'width: ' . $atts['width'] . 'px; ' : '' ) . 'height: ' . $atts['height'] . 'px"';
  1489. $attr[] = 'data-maptype="' . $atts['maptype'] . '"';
  1490. $attr[] = 'data-zoom="' . $atts['zoom'] . '"';
  1491.  
  1492. $out = '<div ' . implode( ' ', $attr ) . '></div>';
  1493. }
  1494.  
  1495. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  1496.  
  1497. return $this->echoOrReturn( $atts['return'], $out );
  1498. }
  1499.  
  1500. /**
  1501. * Echo or return the entry's phone numbers in a HTML hCard compliant string.
  1502. *
  1503. * Accepted options for the $atts property are:
  1504. * preferred (bool) Retrieve the preferred entry phone number.
  1505. * type (array) || (string) Retrieve specific phone number types.
  1506. * Permitted Types:
  1507. * homephone
  1508. * homefax
  1509. * cellphone
  1510. * workphone
  1511. * workfax
  1512. * format (string) The tokens to use to display the phone number block parts.
  1513. * Permitted Tokens:
  1514. * %label%
  1515. * %number%
  1516. * %separator%
  1517. * separator (string) The separator to use.
  1518. * before (string) HTML to output before the phone numbers.
  1519. * after (string) HTML to after before the phone numbers.
  1520. * return (bool) Return string if set to TRUE instead of echo string.
  1521. *
  1522. * Filters:
  1523. * cn_output_default_atts_phone => (array) Register the methods default attributes.
  1524. *
  1525. * @access public
  1526. * @since unknown
  1527. *
  1528. * @param array $atts Accepted values as noted above.
  1529. * @param bool $cached Returns the cached data rather than querying the db.
  1530. *
  1531. * @return string
  1532. */
  1533. public function getPhoneNumberBlock( $atts = array(), $cached = TRUE ) {
  1534.  
  1535. // Grab an instance of the Connections object.
  1536. $instance = Connections_Directory();
  1537.  
  1538. $defaults = array(
  1539. 'preferred' => NULL,
  1540. 'type' => NULL,
  1541. 'limit' => NULL,
  1542. 'format' => '',
  1543. 'separator' => ':',
  1544. 'before' => '',
  1545. 'after' => '',
  1546. 'return' => FALSE,
  1547. );
  1548.  
  1549. /**
  1550. * All extensions to filter the method default and supplied args.
  1551. *
  1552. * @since 8.5.18
  1553. */
  1554. $atts = cnSanitize::args(
  1555. apply_filters( 'cn_output_atts_phone', $atts ),
  1556. apply_filters( 'cn_output_default_atts_phone', $defaults )
  1557. );
  1558.  
  1559. $atts['id'] = $this->getId();
  1560.  
  1561. $rows = array();
  1562. $phoneNumbers = $this->getPhoneNumbers( $atts, $cached );
  1563. $search = array( '%label%' , '%number%' , '%separator%' );
  1564.  
  1565. if ( empty( $phoneNumbers ) ) return '';
  1566.  
  1567. foreach ( $phoneNumbers as $phone ) {
  1568. $replace = array();
  1569.  
  1570. $row = "\t" . '<span class="tel cn-phone-number' . ( $phone->preferred ? ' cn-preferred cn-phone-number-preferred' : '' ) . '">';
  1571.  
  1572. $replace[] = empty( $phone->name ) ? '' : '<span class="phone-name">' . $phone->name . '</span>';
  1573.  
  1574. if ( empty( $phone->number ) ) {
  1575. $replace[] = '';
  1576. } else {
  1577.  
  1578. if ( $instance->settings->get( 'connections', 'link', 'phone' ) ) {
  1579.  
  1580. $replace[] = '<a class="value" href="tel:' . $phone->number . '" value="' . preg_replace( '/[^0-9]/', '', $phone->number ) . '">' . $phone->number . '</a>';
  1581.  
  1582. } else {
  1583.  
  1584. $replace[] = '<span class="value">' . $phone->number . '</span>';
  1585. }
  1586.  
  1587. }
  1588.  
  1589. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  1590.  
  1591. $row .= str_ireplace(
  1592. $search,
  1593. $replace,
  1594. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label%%separator% %number%' : $defaults['format'] ) : $atts['format']
  1595. );
  1596.  
  1597. // Set the hCard Phone Number Type.
  1598. $row .= $this->gethCardTelType( $phone->type );
  1599.  
  1600. $row .= '</span>' . PHP_EOL;
  1601.  
  1602. $rows[] = apply_filters( 'cn_output_phone_number', cnString::replaceWhatWith( $row, ' ' ), $phone, $this, $atts );
  1603. }
  1604.  
  1605. $block = '<span class="phone-number-block">' . PHP_EOL . implode( PHP_EOL, $rows ) . PHP_EOL .'</span>';
  1606.  
  1607. $block = apply_filters( 'cn_output_phone_numbers', $block, $phoneNumbers, $this, $atts );
  1608.  
  1609. $html = $atts['before'] . $block . $atts['after'] . PHP_EOL;
  1610.  
  1611. return $this->echoOrReturn( $atts['return'], $html );
  1612. }
  1613.  
  1614. /**
  1615. * Returns the entry's telephone type in a HTML hCard compliant string.
  1616. *
  1617. * @link http://microformats.org/wiki/hcard-cheatsheet
  1618. *
  1619. * @access private
  1620. * @since unknown
  1621. *
  1622. * @param string $data
  1623. *
  1624. * @return string
  1625. */
  1626. public function gethCardTelType( $data ) {
  1627.  
  1628. $type = '';
  1629.  
  1630. switch ( $data ) {
  1631.  
  1632. case 'home':
  1633. $type = '<span class="type" style="display: none;">home</span>';
  1634. break;
  1635. case 'homephone':
  1636. $type = '<span class="type" style="display: none;">home</span>';
  1637. break;
  1638. case 'homefax':
  1639. $type = '<span class="type" style="display: none;">home</span><span class="type" style="display: none;">fax</span>';
  1640. break;
  1641. case 'cell':
  1642. $type = '<span class="type" style="display: none;">cell</span>';
  1643. break;
  1644. case 'cellphone':
  1645. $type = '<span class="type" style="display: none;">cell</span>';
  1646. break;
  1647. case 'work':
  1648. $type = '<span class="type" style="display: none;">work</span>';
  1649. break;
  1650. case 'workphone':
  1651. $type = '<span class="type" style="display: none;">work</span>';
  1652. break;
  1653. case 'workfax':
  1654. $type = '<span class="type" style="display: none;">work</span><span class="type" style="display: none;">fax</span>';
  1655. break;
  1656. case 'fax':
  1657. $type = '<span class="type" style="display: none;">work</span><span class="type" style="display: none;">fax</span>';
  1658. break;
  1659. }
  1660.  
  1661. return $type;
  1662. }
  1663.  
  1664. /**
  1665. * Returns the entry's address type in a HTML hCard compliant string.
  1666. *
  1667. * @link http://microformats.org/wiki/adr-cheatsheet#Properties_.28Class_Names.29
  1668. *
  1669. * @access private
  1670. * @since unknown
  1671. *
  1672. * @param string $adrType
  1673. *
  1674. * @return string
  1675. */
  1676. public function gethCardAdrType( $adrType ) {
  1677.  
  1678. switch ( $adrType ) {
  1679.  
  1680. case 'home':
  1681. $type = '<span class="type" style="display: none;">home</span>';
  1682. break;
  1683. case 'work':
  1684. $type = '<span class="type" style="display: none;">work</span>';
  1685. break;
  1686. case 'school':
  1687. $type = '<span class="type" style="display: none;">postal</span>';
  1688. break;
  1689. case 'other':
  1690. $type = '<span class="type" style="display: none;">postal</span>';
  1691. break;
  1692.  
  1693. default:
  1694. $type = '<span class="type" style="display: none;">postal</span>';
  1695. break;
  1696. }
  1697.  
  1698. return $type;
  1699. }
  1700.  
  1701. /**
  1702. * Echo or return the entry's email addresses in a HTML hCard compliant string.
  1703. *
  1704. * Accepted options for the $atts property are:
  1705. * preferred (bool) Retrieve the preferred entry email address.
  1706. * type (array) || (string) Retrieve specific email address types.
  1707. * Permitted Types:
  1708. * personal
  1709. * work
  1710. * format (string) The tokens to use to display the email address block parts.
  1711. * Permitted Tokens:
  1712. * %label%
  1713. * %address%
  1714. * %icon%
  1715. * %separator%
  1716. * title (string) The link title attribute. Accepts tokens.
  1717. * Permitted Tokens:
  1718. * Name tokens:
  1719. * %prefix%
  1720. * %first%
  1721. * %middle%
  1722. * %last%
  1723. * %suffix%
  1724. * Email tokens:
  1725. * %type%
  1726. * %name%
  1727. * size (int) the icon size. Permitted sizes are 16, 24, 32, 48.
  1728. * separator (string) The separator to use.
  1729. * before (string) HTML to output before the email addresses.
  1730. * after (string) HTML to after before the email addresses.
  1731. * return (bool) Return string if set to TRUE instead of echo string.
  1732. *
  1733. * Filters:
  1734. * cn_output_default_atts_email => (array) Register the methods default attributes.
  1735. *
  1736. * @access public
  1737. * @since unknown
  1738. *
  1739. * @param array $atts Accepted values as noted above.
  1740. * @param bool $cached Returns the cached data rather than querying the db.
  1741. *
  1742. * @return string
  1743. */
  1744. public function getEmailAddressBlock( $atts = array(), $cached = TRUE ) {
  1745.  
  1746. $defaults = array(
  1747. 'preferred' => NULL,
  1748. 'type' => NULL,
  1749. 'limit' => NULL,
  1750. 'format' => '',
  1751. 'title' => '',
  1752. 'size' => 32,
  1753. 'separator' => ':',
  1754. 'before' => '',
  1755. 'after' => '',
  1756. 'return' => FALSE,
  1757. );
  1758.  
  1759. /**
  1760. * All extensions to filter the method default and supplied args.
  1761. *
  1762. * @since 8.5.18
  1763. */
  1764. $atts = cnSanitize::args(
  1765. apply_filters( 'cn_output_atts_email', $atts ),
  1766. apply_filters( 'cn_output_default_atts_email', $defaults )
  1767. );
  1768.  
  1769. $atts['id'] = $this->getId();
  1770.  
  1771. $rows = array();
  1772. $addresses = $this->getEmailAddresses( $atts, $cached );
  1773. $search = array( '%label%', '%address%', '%icon%', '%separator%' );
  1774. $iconSizes = array( 16, 24, 32, 48, 64 );
  1775.  
  1776. if ( empty( $addresses ) ) return '';
  1777.  
  1778. // Replace the 'Name Tokens' with the entry's name.
  1779. $name = $this->getName(
  1780. array(
  1781. 'format' => empty( $atts['title'] ) ? '%first% %last% %type% email.' : $atts['title']
  1782. )
  1783. );
  1784.  
  1785. /*
  1786. * Ensure the supplied size is valid, if not reset to the default value.
  1787. */
  1788. in_array( $atts['size'], $iconSizes ) ? $iconSize = $atts['size'] : $iconSize = 32;
  1789.  
  1790. foreach ( $addresses as $email ) {
  1791.  
  1792. $replace = array();
  1793.  
  1794. // Replace the 'Email Tokens' with the email info.
  1795. $title = str_ireplace( array( '%type%', '%name%' ), array( $email->type, $email->name ), $name );
  1796.  
  1797. $replace[] = ( empty( $email->name ) ) ? '' : '<span class="email-name">' . $email->name . '</span>';
  1798. $replace[] = ( empty( $email->address ) ) ? '' : '<span class="email-address"><a class="value" title="' . $title . '" href="mailto:' . $email->address . '">' . $email->address . '</a></span>';
  1799.  
  1800. /** @noinspection HtmlUnknownTarget */
  1801. $replace[] = ( empty( $email->address ) ) ? '' : '<span class="email-icon"><a class="value" title="' . $title . '" href="mailto:' . $email->address . '"><img src="' . CN_URL . 'assets/images/icons/mail/mail_' . $iconSize . '.png" height="' . $iconSize . '" width="' . $iconSize . '"/></a></span>';
  1802. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  1803.  
  1804. $row = "\t" . '<span class="email cn-email-address' . ( $email->preferred ? ' cn-preferred cn-email-address-preferred' : '' ) . '">';
  1805.  
  1806. $row .= str_ireplace(
  1807. $search,
  1808. $replace,
  1809. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label%%separator% %address%' : $defaults['format'] ) : $atts['format']
  1810. );
  1811.  
  1812. // Set the hCard Email Address Type.
  1813. $row .= '<span class="type" style="display: none;">INTERNET</span>';
  1814.  
  1815. $row .= '</span>';
  1816.  
  1817. $rows[] = apply_filters( 'cn_output_email_address', cnString::replaceWhatWith( $row, ' ' ), $email, $this, $atts );
  1818. }
  1819.  
  1820. $block = '<span class="email-address-block">' . PHP_EOL . implode( PHP_EOL, $rows ) . PHP_EOL . '</span>';
  1821.  
  1822. // This filter is required to allow the ROT13 encryption plugin to function.
  1823. $block = apply_filters( 'cn_output_email_addresses', $block, $addresses, $this, $atts );
  1824.  
  1825. $html = $atts['before'] . $block . $atts['after'] . PHP_EOL;
  1826.  
  1827. return $this->echoOrReturn( $atts['return'], $html );
  1828. }
  1829.  
  1830. /**
  1831. * Echo or return the entry's IM network IDs in a HTML hCard compliant string.
  1832. *
  1833. * Accepted options for the $atts property are:
  1834. * preferred (bool) Retrieve the preferred entry IM network.
  1835. * type (array) || (string) Retrieve specific IM network types.
  1836. * Permitted Types:
  1837. * aim
  1838. * yahoo
  1839. * jabber
  1840. * messenger
  1841. * skype
  1842. * format (string) The tokens to use to display the IM network block parts.
  1843. * Permitted Tokens:
  1844. * %label%
  1845. * %id%
  1846. * %separator%
  1847. * separator (string) The separator to use.
  1848. * before (string) HTML to output before the IM networks.
  1849. * after (string) HTML to after before the IM networks.
  1850. * return (bool) Return string if set to TRUE instead of echo string.
  1851. *
  1852. * Filters:
  1853. * cn_output_default_atts_im => (array) Register the methods default attributes.
  1854. *
  1855. * @url http://microformats.org/wiki/hcard-examples#New_Types_of_Contact_Info
  1856. * @access public
  1857. * @since unknown
  1858. *
  1859. * @param array $atts Accepted values as noted above.
  1860. * @param bool $cached Returns the cached data rather than querying the db.
  1861. *
  1862. * @return string
  1863. */
  1864. public function getImBlock( $atts = array(), $cached = TRUE ) {
  1865.  
  1866. $defaults = array(
  1867. 'preferred' => NULL,
  1868. 'type' => NULL,
  1869. 'format' => '',
  1870. 'separator' => ':',
  1871. 'before' => '',
  1872. 'after' => '',
  1873. 'return' => FALSE,
  1874. );
  1875.  
  1876. /**
  1877. * All extensions to filter the method default and supplied args.
  1878. *
  1879. * @since 8.5.18
  1880. */
  1881. $atts = cnSanitize::args(
  1882. apply_filters( 'cn_output_atts_im', $atts ),
  1883. apply_filters( 'cn_output_default_atts_im', $defaults )
  1884. );
  1885.  
  1886. $atts['id'] = $this->getId();
  1887.  
  1888. $out = '';
  1889. $networks = $this->getIm( $atts , $cached );
  1890. $search = array( '%label%' , '%id%' , '%separator%' );
  1891.  
  1892. if ( empty( $networks ) ) return '';
  1893.  
  1894. $out .= '<span class="im-network-block">' . PHP_EOL;
  1895.  
  1896. foreach ( $networks as $network ) {
  1897. $replace = array();
  1898.  
  1899. $out .= "\t" . '<span class="im-network cn-im-network' . ( $network->preferred ? ' cn-preferred cn-im-network-preferred' : '' ) . '">';
  1900.  
  1901. ( empty( $network->name ) ) ? $replace[] = '' : $replace[] = '<span class="im-name">' . $network->name . '</span>';
  1902.  
  1903. switch ( $network->type ) {
  1904. case 'aim':
  1905. $replace[] = empty( $network->id ) ? '' : '<a class="url im-id" href="aim:goim?screenname=' . $network->id . '">' . $network->id . '</a>';
  1906. break;
  1907.  
  1908. case 'yahoo':
  1909. $replace[] = empty( $network->id ) ? '' : '<a class="url im-id" href="ymsgr:sendIM?' . $network->id . '">' . $network->id . '</a>';
  1910. break;
  1911.  
  1912. case 'jabber':
  1913. $replace[] = empty( $network->id ) ? '' : '<span class="im-id">' . $network->id . '</span>';
  1914. break;
  1915.  
  1916. case 'messenger':
  1917. $replace[] = empty( $network->id ) ? '' : '<a class="url im-id" href="msnim:chat?contact=' . $network->id . '">' . $network->id . '</a>';
  1918. break;
  1919.  
  1920. case 'skype':
  1921. $replace[] = empty( $network->id ) ? '' : '<a class="url im-id" href="skype:' . $network->id . '?chat">' . $network->id . '</a>';
  1922. break;
  1923.  
  1924. case 'icq':
  1925. $replace[] = empty( $network->id ) ? '' : '<a class="url im-id" type="application/x-icq" href="http://www.icq.com/people/cmd.php?uin=' . $network->id . '&action=message">' . $network->id . '</a>';
  1926. break;
  1927.  
  1928. default:
  1929. $replace[] = empty( $network->id ) ? '' : '<span class="im-id">' . $network->id . '</span>';
  1930. break;
  1931. }
  1932.  
  1933. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  1934.  
  1935. $out .= str_ireplace(
  1936. $search,
  1937. $replace,
  1938. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label%%separator% %id%' : $defaults['format'] ) : $atts['format']
  1939. );
  1940.  
  1941. $out .= '</span>' . PHP_EOL;
  1942. }
  1943.  
  1944. $out .= '</span>' . PHP_EOL;
  1945.  
  1946. $out = cnString::replaceWhatWith( $out, ' ' );
  1947.  
  1948. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  1949.  
  1950. return $this->echoOrReturn( $atts['return'], $out );
  1951. }
  1952.  
  1953. /**
  1954. * Echo or return the entry's social media network IDs in a HTML hCard compliant string.
  1955. *
  1956. * Accepted options for the $atts property are:
  1957. * preferred (bool) Retrieve the preferred entry social media network.
  1958. * type (array) || (string) Retrieve specific social media network types.
  1959. * Permitted Types:
  1960. * delicious
  1961. * cdbaby
  1962. * facebook
  1963. * flickr
  1964. * itunes
  1965. * linked-in
  1966. * mixcloud
  1967. * myspace
  1968. * podcast
  1969. * reverbnation
  1970. * rss
  1971. * technorati
  1972. * twitter
  1973. * soundcloud
  1974. * vimeo
  1975. * youtube
  1976. * format (string) The tokens to use to display the social media block parts.
  1977. * Permitted Tokens:
  1978. * %title%
  1979. * %url%
  1980. * %icon%
  1981. * %separator%
  1982. * style (string) The icon style to be used.
  1983. * Permitted Styles:
  1984. * wpzoom
  1985. * Permitted Sizes:
  1986. * 16
  1987. * 24
  1988. * 32
  1989. * 48
  1990. * 64
  1991. * size (int) The icon size to be used.
  1992. * separator (string) The separator to use.
  1993. * before (string) HTML to output before the social media networks.
  1994. * after (string) HTML to after before the social media networks.
  1995. * return (bool) Return string if set to TRUE instead of echo string.
  1996. *
  1997. * Filters:
  1998. * cn_output_default_atts_socialmedia => (array) Register the methods default attributes.
  1999. *
  2000. * @link http://microformats.org/wiki/hcard-examples#Site_profiles
  2001. *
  2002. * @access public
  2003. * @since unknown
  2004. *
  2005. * @param array $atts Accepted values as noted above.
  2006. * @param bool $cached Returns the cached data rather than querying the db.
  2007. *
  2008. * @return string
  2009. */
  2010. public function getSocialMediaBlock( $atts = array(), $cached = TRUE ) {
  2011.  
  2012. $defaults = array(
  2013. 'preferred' => NULL,
  2014. 'type' => NULL,
  2015. 'format' => '',
  2016. 'style' => 'wpzoom',
  2017. 'size' => 32,
  2018. 'separator' => ':',
  2019. 'before' => '',
  2020. 'after' => '',
  2021. 'return' => FALSE,
  2022. );
  2023.  
  2024. /**
  2025. * All extensions to filter the method default and supplied args.
  2026. *
  2027. * @since 8.5.18
  2028. */
  2029. $atts = cnSanitize::args(
  2030. apply_filters( 'cn_output_atts_socialmedia', $atts ),
  2031. apply_filters( 'cn_output_default_atts_socialmedia', $defaults )
  2032. );
  2033.  
  2034. $atts['id'] = $this->getId();
  2035.  
  2036. $networks = $this->getSocialMedia( $atts , $cached );
  2037. $search = array( '%label%' , '%url%' , '%icon%' , '%separator%' );
  2038.  
  2039. $iconStyles = array( 'wpzoom' );
  2040. $iconSizes = array( 16, 24, 32, 48, 64 );
  2041.  
  2042. /*
  2043. * Ensure the supplied icon style and size are valid, if not reset to the default values.
  2044. */
  2045. $iconStyle = ( in_array( $atts['style'], $iconStyles ) ) ? $atts['style'] : 'wpzoom';
  2046. $iconSize = ( in_array( $atts['size'], $iconSizes ) ) ? $atts['size'] : 32;
  2047.  
  2048. if ( empty( $networks ) ) return '';
  2049.  
  2050. $out = '<span class="social-media-block">' . PHP_EOL;
  2051.  
  2052. foreach ( $networks as $network ) {
  2053. $replace = array();
  2054. $iconClass = array();
  2055.  
  2056. /*
  2057. * Create the icon image class. This array will implode to a string.
  2058. */
  2059. $iconClass[] = $network->type;
  2060. $iconClass[] = $iconStyle;
  2061. $iconClass[] = 'sz-' . $iconSize;
  2062.  
  2063. $out .= "\t" . '<span class="social-media-network cn-social-media-network' . ( $network->preferred ? ' cn-preferred cn-social-media-network-preferred' : '' ) . '">';
  2064.  
  2065. $replace[] = '<a class="url ' . $network->type . '" href="' . $network->url . '" target="_blank" title="' . $network->name . '">' . $network->name . '</a>';
  2066.  
  2067. $replace[] = '<a class="url ' . $network->type . '" href="' . $network->url . '" target="_blank" title="' . $network->name . '">' . $network->url . '</a>';
  2068.  
  2069. $replace[] = '<a class="url ' . $network->type . '" href="' . $network->url . '" target="_blank" title="' . $network->name . '"><img class="' . implode( ' ', $iconClass ) . '" src="' . CN_URL . 'assets/images/icons/' . $iconStyle . '/' . $iconSize . '/' . $network->type . '.png" height="' . $iconSize . '" width="' . $iconSize . '" style="width: ' . $iconSize . 'px; height: ' . $iconSize . 'px;" alt="' . $network->name . ' Icon"/></a>';
  2070.  
  2071. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  2072.  
  2073. $out .= str_ireplace(
  2074. $search,
  2075. $replace,
  2076. empty( $atts['format'] ) ? '%icon%' : $atts['format']
  2077. );
  2078.  
  2079. $out .= '</span>' . PHP_EOL;
  2080. }
  2081.  
  2082. $out .= '</span>' . PHP_EOL;
  2083.  
  2084. $out = cnString::replaceWhatWith( $out, ' ' );
  2085.  
  2086. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  2087.  
  2088. return $this->echoOrReturn( $atts['return'], $out );
  2089. }
  2090.  
  2091. /**
  2092. * Return the entry's websites in a HTML hCard compliant string.
  2093. *
  2094. * @deprecated since 0.7.2.0
  2095. */
  2096. public function getWebsiteBlock() {
  2097.  
  2098. /*
  2099. * Set some defaults so the result resembles how the previous rendered.
  2100. */
  2101. return $this->getLinkBlock( array( 'format' => '%label%%separator% %url%' , 'type' => array( 'personal', 'website' ) , 'return' => TRUE ) );
  2102. }
  2103.  
  2104. /**
  2105. * Echo or return the entry's links in a HTML hCard compliant string.
  2106. *
  2107. * Accepted options for the $atts property are:
  2108. * preferred (bool) Retrieve the preferred entry link.
  2109. * type (array) || (string) Retrieve specific link types.
  2110. * Permitted Types:
  2111. * website
  2112. * blog
  2113. * format (string) The tokens to use to display the phone number block parts.
  2114. * Permitted Tokens:
  2115. * %label%
  2116. * %title%
  2117. * %url%
  2118. * %image%
  2119. * %separator%
  2120. * label (string) The label to be displayed for the links.
  2121. * size (string) The valid image sizes. Valid values are: mcr || tny || vsm || sm || lg || xlg
  2122. * separator (string) The separator to use.
  2123. * before (string) HTML to output before the social media networks.
  2124. * after (string) HTML to after before the social media networks.
  2125. * return (bool) Return string if set to TRUE instead of echo string.
  2126. *
  2127. * Filters:
  2128. * cn_output_default_atts_link => (array) Register the methods default attributes.
  2129. *
  2130. * @link http://microformats.org/wiki/hcard-examples#Site_profiles
  2131. *
  2132. * @access public
  2133. * @since unknown
  2134. *
  2135. * @param array $atts Accepted values as noted above.
  2136. * @param bool $cached Returns the cached data rather than querying the db.
  2137. *
  2138. * @return string
  2139. */
  2140. public function getLinkBlock( $atts = array(), $cached = TRUE ) {
  2141.  
  2142. $defaults = array(
  2143. 'preferred' => NULL,
  2144. 'type' => NULL,
  2145. 'format' => '',
  2146. 'label' => NULL,
  2147. 'size' => 'lg',
  2148. 'icon_size' => 32,
  2149. 'separator' => ':',
  2150. 'before' => '',
  2151. 'after' => '',
  2152. 'return' => FALSE,
  2153. );
  2154.  
  2155. /**
  2156. * All extensions to filter the method default and supplied args.
  2157. *
  2158. * @since 8.5.18
  2159. */
  2160. $atts = cnSanitize::args(
  2161. apply_filters( 'cn_output_atts_link', $atts ),
  2162. apply_filters( 'cn_output_default_atts_link', $defaults )
  2163. );
  2164.  
  2165. $atts['id'] = $this->getId();
  2166.  
  2167. $rows = array();
  2168. $links = $this->getLinks( $atts, $cached );
  2169. $search = array( '%label%', '%title%', '%url%', '%image%', '%icon%', '%separator%' );
  2170. $iconSizes = array( 16, 24, 32, 48, 64 );
  2171. $targetOptions = array( 'new' => '_blank', 'same' => '_self' );
  2172.  
  2173. if ( empty( $links ) ) return '';
  2174.  
  2175. /*
  2176. * Ensure the supplied size is valid, if not reset to the default value.
  2177. */
  2178.  
  2179. $icon = array();
  2180.  
  2181. $icon['width'] = in_array( $atts['icon_size'], $iconSizes ) ? $atts['icon_size'] : 32;
  2182. $icon['height'] = $icon['width'];
  2183. $icon['src'] = CN_URL . 'assets/images/icons/link/link_' . $icon['width'] . '.png';
  2184.  
  2185. foreach ( $links as $link ) {
  2186.  
  2187. $icon = apply_filters( 'cn_output_link_icon', $icon, $link->type );
  2188.  
  2189. $replace = array();
  2190.  
  2191. if ( empty( $atts['label'] ) ) {
  2192.  
  2193. $name = empty( $link->name ) ? '' : $link->name;
  2194.  
  2195. } else {
  2196.  
  2197. $name = $atts['label'];
  2198. }
  2199.  
  2200. $url = cnSanitize::field( 'url', $link->url );
  2201. $target = array_key_exists( $link->target, $targetOptions ) ? $targetOptions[ $link->target ] : '_self';
  2202. $follow = $link->follow ? '' : 'rel="nofollow"';
  2203.  
  2204. $replace[] = '<span class="link-name">' . $name . '</span>';
  2205.  
  2206. // The `notranslate` class is added to prevent Google Translate from translating the text.
  2207. $replace[] = empty( $link->title ) ? '' : '<a class="url" href="' . $url . '"' . ' target="' . $target . '" ' . $follow . '>' . $link->title . '</a>';
  2208. $replace[] = '<a class="url notranslate" href="' . $url . '"' . ' target="' . $target . '" ' . $follow . '>' . $url . '</a>';
  2209.  
  2210. if ( FALSE !== filter_var( $link->url, FILTER_VALIDATE_URL ) &&
  2211. FALSE !== strpos( $atts['format'], '%image%' ) ) {
  2212.  
  2213. $screenshot = new cnSiteShot(
  2214. array(
  2215. 'url' => $link->url,
  2216. 'alt' => $url,
  2217. 'title' => $name,
  2218. 'target' => $target,
  2219. 'follow' => $link->follow,
  2220. 'return' => TRUE,
  2221. )
  2222. );
  2223.  
  2224. $size = $screenshot->setSize( $atts['size'] );
  2225.  
  2226. /** @noinspection CssInvalidPropertyValue */
  2227. $screenshot->setBefore( '<span class="cn-image-style" style="display: inline-block;"><span style="display: block; max-width: 100%; width: ' . $size['width'] . 'px">' );
  2228. $screenshot->setAfter( '</span></span>' );
  2229.  
  2230. $replace[] = $screenshot->render();
  2231.  
  2232. } else {
  2233.  
  2234. $replace[] = '';
  2235. }
  2236.  
  2237. $replace[] = '<span class="link-icon"><a class="url" title="' . $link->title . '" href="' . $url . '" target="' . $target . '" ' . $follow . '><img src="' . $icon['src'] . '" height="' . $icon['height'] . '" width="' . $icon['width'] . '"/></a></span>';
  2238.  
  2239. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  2240.  
  2241. $row = "\t" . '<span class="link ' . $link->type . ' cn-link' . ( $link->preferred ? ' cn-preferred cn-link-preferred' : '' ) . '">';
  2242.  
  2243. $row .= str_ireplace(
  2244. $search,
  2245. $replace,
  2246. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label%%separator% %title%' : $defaults['format'] ) : $atts['format']
  2247. );
  2248.  
  2249. $row .= '</span>';
  2250.  
  2251. $rows[] = apply_filters( 'cn_output_link', cnString::replaceWhatWith( $row, ' ' ), $link, $this, $atts );
  2252. }
  2253.  
  2254. $block = '<span class="link-block">' . PHP_EOL . implode( PHP_EOL, $rows ) . PHP_EOL .'</span>';
  2255.  
  2256. $block = apply_filters( 'cn_output_links', $block, $links, $this, $atts );
  2257.  
  2258. $html = $atts['before'] . $block . $atts['after'] . PHP_EOL;
  2259.  
  2260. return $this->echoOrReturn( $atts['return'], $html );
  2261. }
  2262.  
  2263.  
  2264. /**
  2265. * Echo or return the entry's dates in a HTML string.
  2266. *
  2267. * Accepted options for the $atts property are:
  2268. * preferred (bool) Retrieve the preferred entry date.
  2269. * type (array) || (string) Retrieve specific date types.
  2270. * Permitted Types:
  2271. * baptism
  2272. * certification
  2273. * employment
  2274. * membership
  2275. * graduate_high_school
  2276. * graduate_college
  2277. * ordination
  2278. *
  2279. * format (string) The tokens to use to display the date block parts.
  2280. * Permitted Tokens:
  2281. * %label%
  2282. * %date%
  2283. * %separator%
  2284. * name_format (string) Tokens for the parts of the name. See cnOutput::getNameBlock
  2285. * date_format (string) See http://php.net/manual/en/function.date.php
  2286. * separator (string) The separator to use between the label and date.
  2287. * before (string) HTML to output before the dates.
  2288. * after (string) HTML to after before the dates.
  2289. * return (bool) Return string if set to TRUE instead of echo string.
  2290. *
  2291. * Filters:
  2292. * cn_output_default_atts_date => (array) Register the methods default attributes.
  2293. *
  2294. * @access public
  2295. * @since 0.7.3
  2296. *
  2297. * @param array $atts Accepted values as noted above.
  2298. * @param bool $cached Returns the cached data rather than querying the db.
  2299. *
  2300. * @return string
  2301. */
  2302. public function getDateBlock( $atts = array(), $cached = TRUE ) {
  2303.  
  2304. $defaults = array(
  2305. 'preferred' => NULL,
  2306. 'type' => NULL,
  2307. 'format' => '',
  2308. 'name_format' => '',
  2309. 'date_format' => cnSettingsAPI::get( 'connections', 'display_general', 'date_format' ),
  2310. 'separator' => ':',
  2311. 'before' => '',
  2312. 'after' => '',
  2313. 'return' => FALSE,
  2314. );
  2315.  
  2316. /**
  2317. * All extensions to filter the method default and supplied args.
  2318. *
  2319. * @since 8.5.18
  2320. */
  2321. $atts = cnSanitize::args(
  2322. apply_filters( 'cn_output_atts_date', $atts ),
  2323. apply_filters( 'cn_output_default_atts_date', $defaults )
  2324. );
  2325.  
  2326. $atts['id'] = $this->getId();
  2327.  
  2328. $dates = $this->getDates( $atts , $cached );
  2329. $search = array( '%label%' , '%date%' , '%separator%' );
  2330.  
  2331. if ( empty( $dates ) ) return '';
  2332.  
  2333. $out = '<span class="date-block">' . PHP_EOL;
  2334.  
  2335. foreach ( $dates as $date ) {
  2336.  
  2337. try {
  2338.  
  2339. // Go thru the formatting acrobats to make sure DateTime is feed a valid date format
  2340. // just in case a user manages to input an incorrect date or date format.
  2341. $dateObject = new DateTime( date( 'm/d/Y', strtotime( $date->date ) ) );
  2342.  
  2343. } catch ( Exception $e ) {
  2344.  
  2345. continue;
  2346. }
  2347.  
  2348. $replace = array();
  2349.  
  2350. $out .= "\t" . '<span class="vevent cn-date' . ( $date->preferred ? ' cn-preferred cn-date-preferred' : '' ) . '">';
  2351.  
  2352. // Hidden elements are to maintain hCalendar spec compatibility
  2353. $replace[] = ( empty( $date->name ) ) ? '' : '<span class="date-name">' . $date->name . '</span>';
  2354. //$replace[] = ( empty($date->date) ) ? '' : '<span class="dtstart"><span class="value" style="display: none;">' . $dateObject->format( 'Y-m-d' ) . '</span><span class="date-displayed">' . $dateObject->format( $atts['date_format'] ) . '</span></span>';
  2355. $replace[] = ( empty( $date->date ) ) ? '' : '<abbr class="dtstart" title="' . $dateObject->format( 'Ymd' ) .'">' . date_i18n( $atts['date_format'] , strtotime( $date->date ) , FALSE ) /*$dateObject->format( $atts['date_format'] )*/ . '</abbr><span class="summary" style="display:none">' . $date->name . ' - ' . $this->getName( array( 'format' => $atts['name_format'] ) ) . '</span><span class="uid" style="display:none">' . $dateObject->format( 'YmdHis' ) . '</span>';
  2356. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  2357.  
  2358. $out .= str_ireplace(
  2359. $search,
  2360. $replace,
  2361. empty( $atts['format'] ) ? ( empty( $defaults['format'] ) ? '%label%%separator% %date%' : $defaults['format'] ) : $atts['format']
  2362. );
  2363.  
  2364. $out .= '</span>' . PHP_EOL;
  2365. }
  2366.  
  2367. $out .= '</span>' . PHP_EOL;
  2368.  
  2369. $out = cnString::replaceWhatWith( $out, ' ' );
  2370.  
  2371. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  2372.  
  2373. return $this->echoOrReturn( $atts['return'], $out );
  2374. }
  2375.  
  2376. /**
  2377. * Echo or return the entry's birthday in a HTML string.
  2378. *
  2379. * Accepted options for the $atts property are:
  2380. * format (string) The tokens to use to display the date block parts.
  2381. * Permitted Tokens:
  2382. * %label%
  2383. * %date%
  2384. * %separator%
  2385. * name_format (string) Tokens for the parts of the name. See cnOutput::getNameBlock
  2386. * date_format (string) See http://php.net/manual/en/function.date.php
  2387. * separator (string) The separator to use between the label and date.
  2388. * before (string) HTML to output before the dates.
  2389. * after (string) HTML to after before the dates.
  2390. * return (bool) Return string if set to TRUE instead of echo string.
  2391. *
  2392. * @access public
  2393. * @since 0.7.3
  2394. *
  2395. * @param string $format deprecated since 0.7.3
  2396. * @param array $atts
  2397. *
  2398. * @return string
  2399. */
  2400. public function getBirthdayBlock( $format = '', $atts = array() ) {
  2401. /*
  2402. * // START -- Set the default attributes array. \\
  2403. */
  2404. $defaults = array();
  2405. $defaults['format'] = '';
  2406. $defaults['name_format'] = '';
  2407.  
  2408. // The $format option has been deprecated since 0.7.3. If it has been supplied override the $defaults['date_format] value.
  2409. $defaults['date_format'] = empty( $format ) ? 'F jS' : $format;
  2410.  
  2411. $defaults['separator'] = ':';
  2412. $defaults['before'] = '';
  2413. $defaults['after'] = '';
  2414. $defaults['return'] = FALSE;
  2415.  
  2416. $atts = cnSanitize::args( $atts, $defaults );
  2417. /*
  2418. * // END -- Set the default attributes array if not supplied. \\
  2419. */
  2420.  
  2421. $out = '';
  2422. $search = array( '%label%' , '%date%' , '%separator%' );
  2423. $replace = array();
  2424.  
  2425. if ( ! $this->getBirthday() ) return '';
  2426.  
  2427. /*
  2428. * NOTE: The vevent span is for hCalendar compatibility.
  2429. * NOTE: The second birthday span [hidden] is for hCard compatibility.
  2430. * NOTE: The third span series [hidden] is for hCalendar compatibility.
  2431. */
  2432. $out .= '<div class="vevent"><span class="birthday">';
  2433.  
  2434. $replace[] = '<span class="date-name">' . __( 'Birthday', 'connections' ) . '</span>';
  2435. $replace[] = '<abbr class="dtstart" title="' . $this->getBirthday( 'Ymd' ) .'">' . date_i18n( $atts['date_format'] , strtotime( $this->getBirthday( 'Y-m-d' ) ) , FALSE ) . '</abbr>';
  2436. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  2437.  
  2438. $out .= str_ireplace(
  2439. $search,
  2440. $replace,
  2441. empty( $atts['format'] ) ? '%label%%separator% %date%' : $atts['format']
  2442. );
  2443.  
  2444. $out .= '<span class="bday" style="display:none">' . $this->getBirthday( 'Y-m-d' ) . '</span>';
  2445. $out .= '<span class="summary" style="display:none">' . __( 'Birthday', 'connections' ) . ' - ' . $this->getName( array( 'format' => $atts['name_format'] ) ) . '</span><span class="uid" style="display:none">' . $this->getBirthday( 'YmdHis' ) . '</span>';
  2446.  
  2447. $out .= '</div>';
  2448.  
  2449. $out = cnString::replaceWhatWith( $out, ' ' );
  2450.  
  2451. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  2452.  
  2453. return $this->echoOrReturn( $atts['return'], $out );
  2454. }
  2455.  
  2456. /**
  2457. * Echo or return the entry's anniversary in a HTML string.
  2458. *
  2459. * Accepted options for the $atts property are:
  2460. * format (string) The tokens to use to display the date block parts.
  2461. * Permitted Tokens:
  2462. * %label%
  2463. * %date%
  2464. * %separator%
  2465. * name_format (string) Tokens for the parts of the name. See cnOutput::getNameBlock
  2466. * date_format (string) See http://php.net/manual/en/function.date.php
  2467. * separator (string) The separator to use between the label and date.
  2468. * before (string) HTML to output before the dates.
  2469. * after (string) HTML to after before the dates.
  2470. * return (bool) Return string if set to TRUE instead of echo string.
  2471. *
  2472. * @access public
  2473. * @since 0.7.3
  2474. *
  2475. * @param string $format deprecated since 0.7.3
  2476. * @param array $atts
  2477. *
  2478. * @return string
  2479. */
  2480. public function getAnniversaryBlock( $format = '', $atts = array() ) {
  2481. /*
  2482. * // START -- Set the default attributes array. \\
  2483. */
  2484. $defaults = array();
  2485. $defaults['format'] = '';
  2486. $defaults['name_format'] = '';
  2487.  
  2488. // The $format option has been deprecated since 0.7.3. If it has been supplied override the $defaults['date_format] value.
  2489. $defaults['date_format'] = empty( $format ) ? 'F jS' : $format;
  2490. $defaults['separator'] = ':';
  2491. $defaults['before'] = '';
  2492. $defaults['after'] = '';
  2493. $defaults['return'] = FALSE;
  2494.  
  2495. $atts = cnSanitize::args( $atts, $defaults );
  2496. /*
  2497. * // END -- Set the default attributes array if not supplied. \\
  2498. */
  2499.  
  2500. $out = '';
  2501. $search = array( '%label%' , '%date%' , '%separator%' );
  2502. $replace = array();
  2503.  
  2504. if ( ! $this->getAnniversary() ) return '';
  2505.  
  2506. /*
  2507. * NOTE: The vevent span is for hCalendar compatibility.
  2508. * NOTE: The second birthday span [hidden] is for hCard compatibility.
  2509. * NOTE: The third span series [hidden] is for hCalendar compatibility.
  2510. */
  2511. $out .= '<div class="vevent"><span class="anniversary">';
  2512.  
  2513. $replace[] = '<span class="date-name">' . __( 'Anniversary', 'connections' ) . '</span>';
  2514. $replace[] = '<abbr class="dtstart" title="' . $this->getAnniversary( 'Ymd' ) .'">' . date_i18n( $atts['date_format'] , strtotime( $this->getAnniversary( 'Y-m-d' ) ) , FALSE ) . '</abbr>';
  2515. $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
  2516.  
  2517. $out .= str_ireplace(
  2518. $search,
  2519. $replace,
  2520. empty( $atts['format'] ) ? '%label%%separator% %date%' : $atts['format']
  2521. );
  2522.  
  2523. $out = cnString::replaceWhatWith( $out, ' ' );
  2524.  
  2525. $out .= '<span class="bday" style="display:none">' . $this->getAnniversary( 'Y-m-d' ) . '</span>';
  2526. $out .= '<span class="summary" style="display:none">' . __( 'Anniversary', 'connections' ) . ' - ' . $this->getName( array( 'format' => $atts['name_format'] ) ) . '</span><span class="uid" style="display:none">' . $this->getAnniversary( 'YmdHis' ) . '</span>';
  2527.  
  2528. $out .= '</div>';
  2529.  
  2530. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  2531.  
  2532. return $this->echoOrReturn( $atts['return'], $out );
  2533. }
  2534.  
  2535. /**
  2536. * Echo or returns the entry Notes.
  2537. *
  2538. * Registers the global $wp_embed because the run_shortcode method needs
  2539. * to run before the do_shortcode function for the [embed] shortcode to fire
  2540. *
  2541. * @access public
  2542. * @since unknown
  2543. *
  2544. * @param array
  2545. *
  2546. * @return string
  2547. */
  2548. public function getNotesBlock( $atts = array() ) {
  2549.  
  2550. $defaults = array(
  2551. 'before' => '',
  2552. 'after' => '',
  2553. 'return' => FALSE
  2554. );
  2555.  
  2556. /**
  2557. * Allow extensions to filter the method default and supplied args.
  2558. *
  2559. * @since 8.5.18
  2560. */
  2561. $atts = cnSanitize::args(
  2562. apply_filters( 'cn_output_atts_notes', $atts ),
  2563. apply_filters( 'cn_output_default_atts_notes', $defaults )
  2564. );
  2565.  
  2566. $out = apply_filters( 'cn_output_notes', $this->getNotes() );
  2567.  
  2568. $out = '<div class="cn-notes">' . $atts['before'] . $out . $atts['after'] . '</div>' . PHP_EOL;
  2569.  
  2570. return $this->echoOrReturn( $atts['return'], $out );
  2571. }
  2572.  
  2573. /**
  2574. * Echo or returns the entry Bio.
  2575. *
  2576. * Registers the global $wp_embed because the run_shortcode method needs
  2577. * to run before the do_shortcode function for the [embed] shortcode to fire
  2578. *
  2579. * @access public
  2580. * @since unknown
  2581. *
  2582. * @param array
  2583. *
  2584. * @return string
  2585. */
  2586. public function getBioBlock( $atts = array() ) {
  2587.  
  2588. $defaults = array(
  2589. 'before' => '',
  2590. 'after' => '',
  2591. 'return' => FALSE
  2592. );
  2593.  
  2594. /**
  2595. * All extensions to filter the method default and supplied args.
  2596. *
  2597. * @since 8.5.18
  2598. */
  2599. $atts = cnSanitize::args(
  2600. apply_filters( 'cn_output_atts_bio', $atts ),
  2601. apply_filters( 'cn_output_default_atts_bio', $defaults )
  2602. );
  2603.  
  2604. $out = apply_filters( 'cn_output_bio', $this->getBio() );
  2605.  
  2606. $out = '<div class="cn-biography">' . $atts['before'] . $out . $atts['after'] . '</div>' . PHP_EOL;
  2607.  
  2608. return $this->echoOrReturn( $atts['return'], $out );
  2609. }
  2610.  
  2611. /**
  2612. * Renders an excerpt of the bio or supplied string.
  2613. *
  2614. * @access public
  2615. * @since 8.5.19
  2616. *
  2617. * @param array $atts
  2618. * @param string $text
  2619. *
  2620. * @return string
  2621. */
  2622. public function excerpt( $atts = array(), $text = '' ) {
  2623.  
  2624. $defaults = array(
  2625. 'before' => '',
  2626. 'after' => '',
  2627. 'length' => apply_filters( 'cn_excerpt_length', 55 ),
  2628. 'more' => apply_filters( 'cn_excerpt_more', __( '&hellip;', 'connections' ) ),
  2629. 'return' => FALSE
  2630. );
  2631.  
  2632. /**
  2633. * All extensions to filter the method default and supplied args.
  2634. *
  2635. * @since 8.5.19
  2636. */
  2637. $atts = cnSanitize::args(
  2638. apply_filters( 'cn_output_atts_excerpt', $atts ),
  2639. apply_filters( 'cn_output_default_atts_excerpt', $defaults )
  2640. );
  2641.  
  2642. $text = 0 < strlen( $text ) ? $text : $this->getBio();
  2643.  
  2644. /**
  2645. * Apply the default filters.
  2646. *
  2647. * @since 8.5.19
  2648. */
  2649. $text = apply_filters( 'cn_output_excerpt', $text );
  2650. $html = cnString::excerpt( $text, $atts );
  2651.  
  2652. return $this->echoOrReturn( $atts['return'], $html );
  2653. }
  2654.  
  2655. /**
  2656. * Displays the category list in a HTML list or custom format.
  2657. *
  2658. * NOTE: This is the Connections equivalent of @see get_the_category_list() in WordPress core ../wp-includes/category-template.php
  2659. *
  2660. * @access public
  2661. * @since unknown
  2662. *
  2663. * @param array $atts {
  2664. * Optional. An array of arguments.
  2665. *
  2666. * @type string $container_tag The HTML tag to be used for the container element.
  2667. * Default: div
  2668. * @type string $label_tag The HTML tag to be used for the category label element.
  2669. * Default: span
  2670. * @type string $item_tag The HTML tag to be used for the category element.
  2671. * Default: span
  2672. * @type string $type The display type to be used to display the categories.
  2673. * Accepts: block|list
  2674. * Default: block
  2675. * @type string $list If the $type is list, which type?
  2676. * Accepts: ordered|unordered
  2677. * Default: unordered
  2678. * @type string $label The label to be displayed before the categories.
  2679. * Default: Categories:
  2680. * @type string $separator The category separator used when separating categories when $type == list
  2681. * Default: ', '
  2682. * @type string $parent_separator The separator to be used when displaying the category's hierarchy.
  2683. * Default: ' &raquo; '
  2684. * @type string $before String content to display before the categories.
  2685. * @type string $after String content to display after the categories.
  2686. * @type bool $link Whether or not render the categories as permalinks.
  2687. * Default: false
  2688. * @type bool $parents Whether or not to display the category hierarchy.
  2689. * Default: false
  2690. * @type bool $return Whether or not to echo or return the HTML.
  2691. * Default: false
  2692. * }
  2693. *
  2694. * @return string
  2695. */
  2696. public function getCategoryBlock( $atts = array() ) {
  2697.  
  2698. global $wp_rewrite;
  2699.  
  2700. $defaults = array(
  2701. 'container_tag' => 'div',
  2702. 'label_tag' => 'span',
  2703. 'item_tag' => 'span',
  2704. 'type' => 'block',
  2705. 'list' => 'unordered',
  2706. 'label' => __( 'Categories:', 'connections' ) . ' ',
  2707. 'separator' => ', ',
  2708. 'parent_separator' => ' &raquo; ',
  2709. 'before' => '',
  2710. 'after' => '',
  2711. 'link' => FALSE,
  2712. 'parents' => FALSE,
  2713. 'return' => FALSE,
  2714. );
  2715.  
  2716. /**
  2717. * All extensions to filter the method default and supplied args.
  2718. *
  2719. * @since 8.5.18
  2720. */
  2721. $atts = cnSanitize::args(
  2722. apply_filters( 'cn_output_atts_category', $atts ),
  2723. apply_filters( 'cn_output_default_atts_category', $defaults )
  2724. );
  2725.  
  2726. $categories = $this->getCategory();
  2727. $count = count( $categories );
  2728. $html = '';
  2729. $label = '';
  2730. $items = array();
  2731.  
  2732. if ( empty( $categories ) ) {
  2733.  
  2734. return $html;
  2735. }
  2736.  
  2737. if ( 'list' == $atts['type'] ) {
  2738.  
  2739. $atts['item_tag'] = 'li';
  2740. }
  2741.  
  2742. if ( 0 < strlen( $atts['label'] ) ) {
  2743.  
  2744. $label = sprintf(
  2745. '<%1$s class="cn_category_label">%2$s</%1$s> ',
  2746. $atts['label_tag'],
  2747. esc_html( $atts['label'] )
  2748. );
  2749. }
  2750.  
  2751. $i = 1;
  2752.  
  2753. foreach ( $categories as $category ) {
  2754.  
  2755. $text = '';
  2756.  
  2757. if ( $atts['parents'] ) {
  2758.  
  2759. // If the term is a root parent, skip.
  2760. if ( 0 !== $category->parent ) {
  2761.  
  2762. $text .= cnTemplatePart::getCategoryParents(
  2763. $category->parent,
  2764. array(
  2765. 'link' => $atts['link'],
  2766. 'separator' => $atts['parent_separator'],
  2767. 'force_home' => $this->directoryHome['force_home'],
  2768. 'home_id' => $this->directoryHome['page_id'],
  2769. )
  2770. );
  2771. }
  2772. }
  2773.  
  2774. if ( $atts['link'] ) {
  2775.  
  2776. $rel = is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ? 'rel="category tag"' : 'rel="category"';
  2777.  
  2778. $url = cnTerm::permalink(
  2779. $category,
  2780. 'category',
  2781. array(
  2782. 'force_home' => $this->directoryHome['force_home'],
  2783. 'home_id' => $this->directoryHome['page_id'],
  2784. )
  2785. );
  2786.  
  2787. $text .= '<a href="' . $url . '" ' . $rel . '>' . esc_html( $category->name ) . '</a>';
  2788.  
  2789. } else {
  2790.  
  2791. $text .= esc_html( $category->name );
  2792. }
  2793.  
  2794. $items[] = apply_filters(
  2795. 'cn_entry_output_category_item',
  2796. sprintf(
  2797. '<%1$s class="cn-category-name cn_category cn-category-%2$d">%3$s%4$s</%1$s>', // The `cn_category` class is named with an underscore for backward compatibility.
  2798. $atts['item_tag'],
  2799. $category->term_id,
  2800. $text,
  2801. $count > $i && 'list' !== $atts['type'] ? esc_html( $atts['separator'] ) : ''
  2802. ),
  2803. $category,
  2804. $count,
  2805. $i,
  2806. $atts,
  2807. $this
  2808. );
  2809.  
  2810. $i++; // Increment here so the correct value is passed to the filter.
  2811. }
  2812.  
  2813. /*
  2814. * Remove NULL, FALSE and empty strings (""), but leave values of 0 (zero).
  2815. * Filter our these in case someone hooks into the `cn_entry_output_category_item` filter and removes a category
  2816. * by returning an empty value.
  2817. */
  2818. $items = array_filter( $items, 'strlen' );
  2819.  
  2820. if ( 'list' == $atts['type'] ) {
  2821.  
  2822. $html .= sprintf(
  2823. '<%1$s class="cn-category-list">%2$s</%1$s>',
  2824. 'unordered' === $atts['list'] ? 'ul' : 'ol',
  2825. implode( '', $items )
  2826. );
  2827.  
  2828. } else {
  2829.  
  2830. $html .= implode( '', $items );
  2831. }
  2832.  
  2833. $html = apply_filters(
  2834. 'cn_entry_output_category_container',
  2835. sprintf(
  2836. '<%1$s class="cn-categories">%2$s</%1$s>' . PHP_EOL,
  2837. $atts['container_tag'],
  2838. $atts['before'] . $label . $html . $atts['after']
  2839. ),
  2840. $atts
  2841. );
  2842.  
  2843. return $this->echoOrReturn( $atts['return'], $html );
  2844. }
  2845.  
  2846. /**
  2847. * Renders the custom meta data fields assigned to the entry.
  2848. *
  2849. * This will also run any actions registered for a custom metaboxes
  2850. * and its fields. The actions should hook into `cn_output_meta_field-{key}`
  2851. * to be rendered.
  2852. *
  2853. * Accepted option for the $atts property are:
  2854. * key (string) The meta key to retrieve.
  2855. * single (bool) Whether or not to return a single value
  2856. * if multiple values exists for the supplied `key`.
  2857. * NOTE: The `key` attribute must be supplied.
  2858. * NOTE: If multiple values exist for a given `key` only first found will be returned.
  2859. * display_custom (bool) Whether or not to display any custom content meta blocks via their registered callbacks.
  2860. * If any are registered the callback output will be rendered before the custom fields meta block @see cnOutput::renderMetaBlock().
  2861. * For better control @see cnOutput::getContentBlock() can be used.
  2862. *
  2863. * @access public
  2864. * @since 0.8
  2865. * @uses wp_parse_args()
  2866. * @uses apply_filters()
  2867. * @uses has_action()
  2868. * @uses do_action()
  2869. * @param array $atts The attributes array.
  2870. * @param array $shortcode_atts If this is used within the shortcode template loop, the shortcode atts
  2871. * should be passed so the shortcode atts can be passed by do_action() to allow access to the action callback.
  2872. * @param cnTemplate|null $template If this is used within the shortcode template loop, the template object
  2873. * should be passed so the template object can be passed by do_action() to allow access to the action callback.
  2874. */
  2875. public function getMetaBlock( $atts, $shortcode_atts, $template ) {
  2876.  
  2877. // @todo Implement 'merge_keys'.
  2878. //
  2879. // Whether or not to merge duplicate keys and their respective value.
  2880. // Expected result of a merge would be would be an indexed array:
  2881. //
  2882. // array(
  2883. // array(
  2884. // 'meta_key' => 'the-duplicate-key',
  2885. // 'meta_value' => array(
  2886. // 'meta_id' => 'value 1',
  2887. // 'meta_id' => 'value 2',
  2888. // 'meta_id' => 'and so on ...',
  2889. // )
  2890. // )
  2891. // )
  2892. //
  2893. // $this->renderMetablock() would have to be updated to account for the
  2894. // 'meta_value' array, I think.
  2895. //
  2896. // NOTE: This should actually be done in cnEntry::getMeta and not here.
  2897. $defaults = array(
  2898. 'key' => '',
  2899. 'single' => FALSE,
  2900. 'merge_keys' => FALSE,
  2901. 'display_custom' => FALSE,
  2902. );
  2903.  
  2904. $atts = wp_parse_args( apply_filters( 'cn_output_meta_block_atts', $atts ), $defaults );
  2905.  
  2906. $results = $this->getMeta( $atts );
  2907.  
  2908. if ( ! empty( $results ) ) {
  2909.  
  2910. if ( empty( $atts['key'] ) ) {
  2911.  
  2912. $metadata = $results;
  2913.  
  2914. } else {
  2915.  
  2916. // Rebuild the results array for consistency in for the output methods/actions.
  2917.  
  2918. $metadata = array();
  2919.  
  2920. foreach ( $results as $key => $value ) {
  2921.  
  2922. $metadata[] = array( 'meta_key' => $key, 'meta_value' => $value );
  2923. }
  2924. }
  2925.  
  2926. foreach ( $metadata as $key => $value ) {
  2927.  
  2928. if ( $atts['display_custom'] && has_action( 'cn_output_meta_field-' . $key ) ) {
  2929.  
  2930. do_action( 'cn_output_meta_field-' . $key, $key, $value, $this, $shortcode_atts, $template );
  2931.  
  2932. unset( $metadata[ $key ] );
  2933. }
  2934. }
  2935.  
  2936. $this->renderMetaBlock( $metadata );
  2937. }
  2938. }
  2939.  
  2940. /**
  2941. * Outputs the data saved in the "Custom Fields" entry metabox.
  2942. * This should not be confused with the fields registered with
  2943. * cnMetaboxAPI. Those fields should be output using a registered
  2944. * action which runs in $this->getMetaBlock().
  2945. *
  2946. * @access private
  2947. * @since 0.8
  2948. * @uses wp_parse_args()
  2949. * @uses apply_filters()
  2950. * @param array $metadata The metadata array passed from $this->getMetaBlock(). @see self::getMetaBlock().
  2951. *
  2952. * @return string
  2953. */
  2954. private function renderMetaBlock( $metadata ) {
  2955.  
  2956. $out = '';
  2957.  
  2958. $defaults = array(
  2959. 'container_tag' => 'ul',
  2960. 'item_tag' => 'li',
  2961. 'key_tag' => 'span',
  2962. 'value_tag' => 'span',
  2963. 'separator' => ': ',
  2964. 'before' => '',
  2965. 'after' => '',
  2966. );
  2967.  
  2968. $atts = wp_parse_args( apply_filters( 'cn_output_meta_atts', $defaults ), $defaults );
  2969.  
  2970. foreach ( (array) $metadata as $key => $value ) {
  2971.  
  2972. // Do not render any private keys; ie. ones that begin with an underscore
  2973. // or any fields registered as part of a custom metabox.
  2974. if ( cnMeta::isPrivate( $key, 'entry' ) ) continue;
  2975.  
  2976. $out .= apply_filters(
  2977. 'cn_entry_output_meta_key',
  2978. sprintf(
  2979. '<%1$s><%2$s class="cn-entry-meta-key">%3$s%4$s</%2$s><%5$s class="cn-entry-meta-value">%6$s</%5$s></%1$s>' . PHP_EOL,
  2980. $atts['item_tag'],
  2981. $atts['key_tag'],
  2982. trim( $key ),
  2983. $atts['separator'],
  2984. $atts['value_tag'],
  2985. implode( ', ', (array) $value )
  2986. ),
  2987. $atts,
  2988. $key,
  2989. $value
  2990. );
  2991. }
  2992.  
  2993. if ( empty( $out ) ) return '';
  2994.  
  2995. $out = apply_filters(
  2996. 'cn_entry_output_meta_container',
  2997. sprintf(
  2998. '<%1$s class="cn-entry-meta">%2$s</%1$s>' . PHP_EOL,
  2999. $atts['container_tag'],
  3000. $out
  3001. ),
  3002. $atts,
  3003. $metadata
  3004. );
  3005.  
  3006. echo $atts['before'] . $out . $atts['after'] . PHP_EOL;
  3007. }
  3008.  
  3009. /**
  3010. * Run the actions registered to custom content blocks.
  3011. *
  3012. * Render any custom content blocks registered to the `cn_entry_output_content-{id}` action hook.
  3013. *
  3014. * This will also run any actions registered for a custom metaboxes and its fields.
  3015. * The actions should hook into `cn_output_meta_field-{key}` to be rendered.
  3016. *
  3017. * Accepted option for the $atts property are:
  3018. * id (string) The custom block ID to render.
  3019. * order (mixed) array | string An indexed array of custom content block IDs that should be rendered in the order in the array.
  3020. * If a string is provided, it should be a comma delimited string containing the content block IDs. It will be converted to an array.
  3021. * exclude (array) An indexed array of custom content block IDs that should be excluded from being rendered.
  3022. * include (array) An indexed array of custom content block IDs that should be rendered.
  3023. * NOTE: Custom content block IDs in `exclude` outweigh custom content block IDs in include. Meaning if the
  3024. * same custom content block ID exists in both, the custom content block will be excluded.
  3025. *
  3026. * @access public
  3027. * @since 0.8
  3028. * @uses do_action()
  3029. * @uses wp_parse_args()
  3030. * @uses apply_filters()
  3031. * @uses has_action()
  3032. * @param mixed $atts array | string [optional] The custom content block(s) to render.
  3033. * @param array $shortcode_atts [optional] If this is used within the shortcode template loop, the shortcode atts
  3034. * should be passed so the shortcode atts can be passed by do_action() to allow access to the action callback.
  3035. * @param cnTemplate|null $template [optional] If this is used within the shortcode template loop, the template object
  3036. * should be passed so the template object can be passed by do_action() to allow access to the action callback.
  3037. *
  3038. * @return string The HTML output of the custom content blocks.
  3039. */
  3040. public function getContentBlock( $atts = array(), $shortcode_atts = array(), $template = NULL ) {
  3041.  
  3042. $blockContainerContent = '';
  3043.  
  3044. if ( cnQuery::getVar( 'cn-entry-slug' ) ) {
  3045.  
  3046. $settings = cnSettingsAPI::get( 'connections', 'connections_display_single', 'content_block' );
  3047.  
  3048. } else {
  3049.  
  3050. $settings = cnSettingsAPI::get( 'connections', 'connections_display_list', 'content_block' );
  3051. }
  3052.  
  3053. $order = isset( $settings['order'] ) ? $settings['order'] : array();
  3054. $include = isset( $settings['active'] ) ? $settings['active'] : array();
  3055. $exclude = empty( $include ) ? $order : array();
  3056. $titles = array();
  3057.  
  3058. $defaults = array(
  3059. 'id' => '',
  3060. 'order' => is_string( $atts ) && ! empty( $atts ) ? $atts : $order,
  3061. 'exclude' => is_string( $atts ) && ! empty( $atts ) ? '' : $exclude,
  3062. 'include' => is_string( $atts ) && ! empty( $atts ) ? '' : $include,
  3063. 'layout' => 'list',
  3064. 'container_tag' => 'div',
  3065. 'block_tag' => 'div',
  3066. 'header_tag' => 'h3',
  3067. 'before' => '',
  3068. 'after' => '',
  3069. 'return' => FALSE
  3070. );
  3071.  
  3072. $atts = wp_parse_args( apply_filters( 'cn_output_content_block_atts', $atts ), $defaults );
  3073.  
  3074. if ( ! empty( $atts['id'] ) ) {
  3075.  
  3076. $blocks = array( $atts['id'] );
  3077.  
  3078. } elseif ( ! empty( $atts['order'] ) ) {
  3079.  
  3080. $blocks = cnFunction::parseStringList( $atts['order'], ',' );
  3081. }
  3082.  
  3083. // Nothing to render, exit.
  3084. if ( empty( $blocks ) ) return '';
  3085.  
  3086. // Cleanup user input. Trim whitespace and convert to lowercase.
  3087. $blocks = array_map( 'strtolower', array_map( 'trim', $blocks ) );
  3088.  
  3089. // Output the registered action in the order supplied by the user.
  3090. foreach ( $blocks as $key ) {
  3091.  
  3092. isset( $blockNumber ) ? $blockNumber++ : $blockNumber = 1;
  3093.  
  3094. // Exclude/Include the metaboxes that have been requested to exclude/include.
  3095. if ( ! empty( $atts['exclude'] ) ) {
  3096.  
  3097. if ( in_array( $key, $atts['exclude'] ) ) continue;
  3098.  
  3099. } else {
  3100.  
  3101. if ( ! empty( $atts['include'] ) ) {
  3102.  
  3103. if ( ! in_array( $key, $atts['include'] ) ) continue;
  3104. }
  3105. }
  3106.  
  3107. ob_start();
  3108.  
  3109. // If the hook has a registered meta data output callback registered, lets run it.
  3110. if ( has_action( 'cn_output_meta_field-' . $key ) ) {
  3111.  
  3112. // Grab the meta.
  3113. $results = $this->getMeta( array( 'key' => $key, 'single' => TRUE ) );
  3114.  
  3115. if ( ! empty( $results ) ) {
  3116.  
  3117. do_action( "cn_output_meta_field-$key", $key, $results, $this, $shortcode_atts, $template );
  3118. }
  3119. }
  3120.  
  3121. // Render the "Custom Fields" meta block content.
  3122. if ( 'meta' == $key ) {
  3123.  
  3124. $this->getMetaBlock( array(), $shortcode_atts, $template );
  3125. }
  3126.  
  3127. $hook = "cn_entry_output_content-$key";
  3128.  
  3129. if ( has_action( $hook ) ) do_action( $hook, $this, $shortcode_atts, $template );
  3130.  
  3131. $blockContent = ob_get_clean();
  3132.  
  3133. if ( empty( $blockContent ) ) continue;
  3134.  
  3135. $blockID = $this->getSlug() . '-' . $blockNumber;
  3136.  
  3137. // Store the title in an array that can be accessed/passed from outside the content block loop.
  3138. // And if there is no title for some reason, create one from the key.
  3139. if ( $name = cnOptions::getContentBlocks( $key ) ) {
  3140.  
  3141. $titles[ $blockID ] = $name;
  3142.  
  3143. } elseif ( $name = cnOptions::getContentBlocks( $key, 'single' ) ) {
  3144.  
  3145. $titles[ $blockID ] = $name;
  3146.  
  3147. } else {
  3148.  
  3149. $titles[ $blockID ] = ucwords( str_replace( array( '-', '_' ), ' ', $key ) );
  3150. }
  3151.  
  3152. //$titles[ $blockID ] = cnOptions::getContentBlocks( $key ) ? cnOptions::getContentBlocks( $key ) : ucwords( str_replace( array( '-', '_' ), ' ', $key ) );
  3153.  
  3154. $blockContainerContent .= apply_filters(
  3155. 'cn_entry_output_content_block',
  3156. sprintf(
  3157. '<%2$s class="cn-entry-content-block cn-entry-content-block-%3$s" id="cn-entry-content-block-%4$s">%1$s%5$s</%2$s>' . PHP_EOL,
  3158. sprintf(
  3159. '<%1$s>%2$s</%1$s>',
  3160. $atts['header_tag'],
  3161. $titles[ $blockID ]
  3162. ),
  3163. $atts['block_tag'],
  3164. $key,
  3165. $blockID,
  3166. $blockContent
  3167. ),
  3168. $this,
  3169. $key,
  3170. $blockID,
  3171. $titles[ $blockID ],
  3172. $blockContent,
  3173. $atts,
  3174. $shortcode_atts
  3175. );
  3176. }
  3177.  
  3178. if ( empty( $blockContainerContent ) ) return '';
  3179.  
  3180. $out = apply_filters(
  3181. 'cn_entry_output_content_block_container',
  3182. sprintf(
  3183. '<%1$s class="cn-entry-content-block-%2$s">%3$s</%1$s>' . PHP_EOL,
  3184. $atts['container_tag'],
  3185. $atts['layout'],
  3186. $blockContainerContent
  3187. ),
  3188. $this,
  3189. $blockContainerContent,
  3190. $titles,
  3191. $atts,
  3192. $shortcode_atts
  3193. );
  3194.  
  3195. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  3196.  
  3197. return $this->echoOrReturn( $atts['return'], $out );
  3198. }
  3199.  
  3200. /**
  3201. * Displays the category list for use in the class tag.
  3202. *
  3203. * @access public
  3204. * @since unknown
  3205. * @version 1.0
  3206. * @param bool $return [optional] Return instead of echo.
  3207. * @return string
  3208. */
  3209. public function getCategoryClass( $return = FALSE ) {
  3210.  
  3211. $categories = $this->getCategory();
  3212. $out = array();
  3213.  
  3214. if ( empty( $categories ) ) return '';
  3215.  
  3216. foreach ( $categories as $category ) {
  3217. $out[] = $category->slug;
  3218. }
  3219.  
  3220. return $this->echoOrReturn( $return, implode( ' ', $out ) );
  3221. }
  3222.  
  3223. /**
  3224. *
  3225. *
  3226. * @access public
  3227. * @since unknown
  3228. * @version 1.0
  3229. * @return string
  3230. */
  3231. public function getRevisionDateBlock() {
  3232. return '<span class="rev">' . date( 'Y-m-d', strtotime( $this->getUnixTimeStamp() ) ) . 'T' . date( 'H:i:s', strtotime( $this->getUnixTimeStamp() ) ) . 'Z' . '</span>' . "\n";
  3233. }
  3234.  
  3235. /**
  3236. *
  3237. *
  3238. * @access private
  3239. * @since unknown
  3240. * @version 1.0
  3241. * @return string
  3242. */
  3243. public function getLastUpdatedStyle() {
  3244. $age = (int) abs( time() - strtotime( $this->getUnixTimeStamp() ) );
  3245. if ( $age < 657000 ) // less than one week: red
  3246. $ageStyle = ' color:red; ';
  3247. elseif ( $age < 1314000 ) // one-two weeks: maroon
  3248. $ageStyle = ' color:maroon; ';
  3249. elseif ( $age < 2628000 ) // two weeks to one month: green
  3250. $ageStyle = ' color:green; ';
  3251. elseif ( $age < 7884000 ) // one - three months: blue
  3252. $ageStyle = ' color:blue; ';
  3253. elseif ( $age < 15768000 ) // three to six months: navy
  3254. $ageStyle = ' color:navy; ';
  3255. elseif ( $age < 31536000 ) // six months to a year: black
  3256. $ageStyle = ' color:black; ';
  3257. else // more than one year: don't show the update age
  3258. $ageStyle = ' display:none; ';
  3259. return $ageStyle;
  3260. }
  3261.  
  3262. /**
  3263. *
  3264. *
  3265. * @access public
  3266. * @since unknown
  3267. * @version 1.0
  3268. * @deprecated
  3269. * @return string|null
  3270. */
  3271. public function returnToTopAnchor() {
  3272.  
  3273. cnTemplatePart::returnToTop();
  3274. }
  3275.  
  3276. /**
  3277. * Outputs the vCard download permalink.
  3278. *
  3279. * Accepted attributes for the $atts array are:
  3280. * class (string) The link class attribute.
  3281. * text (string) The anchor text.
  3282. * title (string) The link title attribute.
  3283. * format (string) The tokens to use to display the vcard link block parts.
  3284. * Permitted Tokens:
  3285. * %text%
  3286. * %icon%
  3287. * follow (bool) Add add the rel="nofollow" attribute if set to FALSE
  3288. * size (int) The icon size. Valid values are: 16, 24, 32, 48
  3289. * slug (string) The entry's slug ID.
  3290. * before (string) HTML to output before the email addresses.
  3291. * after (string) HTML to after before the email addresses.
  3292. * return (bool) Return string if set to TRUE instead of echo string.
  3293. *
  3294. * @access public
  3295. * @since 0.7.3
  3296. * @version 1.0
  3297. * @uses wp_parse_args()
  3298. * @param array $atts [optional]
  3299. * @return string
  3300. */
  3301. public function vcard( $atts = array() ) {
  3302.  
  3303. /**
  3304. * @var wp_rewrite $wp_rewrite
  3305. * @var connectionsLoad $connections
  3306. */
  3307. global $wp_rewrite, $connections;
  3308.  
  3309. // The class.seo.file is only loaded in the frontend; do not attempt to remove the filter
  3310. // otherwise it'll cause an error.
  3311. if ( ! is_admin() ) cnSEO::doFilterPermalink( FALSE );
  3312.  
  3313. $base = get_option( 'connections_permalink' );
  3314. $name = $base['name_base'];
  3315. $homeID = $connections->settings->get( 'connections', 'home_page', 'page_id' ); // Get the directory home page ID.
  3316. $piece = array();
  3317. $id = FALSE;
  3318. $token = FALSE;
  3319. $iconSizes = array( 16, 24, 32, 48 );
  3320. $search = array( '%text%', '%icon%' );
  3321. $replace = array();
  3322.  
  3323. // These are values will need to be added to the query string in order to download unlisted entries from the admin.
  3324. if ( 'unlisted' === $this->getVisibility() ) {
  3325. $id = $this->getId();
  3326. $token = wp_create_nonce( 'download_vcard_' . $this->getId() );
  3327. }
  3328.  
  3329. $defaults = array(
  3330. 'class' => '',
  3331. 'text' => __( 'Add to Address Book.', 'connections' ),
  3332. 'title' => __( 'Download vCard', 'connections' ),
  3333. 'format' => '',
  3334. 'size' => 24,
  3335. 'follow' => FALSE,
  3336. 'slug' => '',
  3337. 'before' => '',
  3338. 'after' => '',
  3339. 'return' => FALSE
  3340. );
  3341.  
  3342. $atts = wp_parse_args( $atts , $defaults );
  3343.  
  3344. /*
  3345. * Ensure the supplied size is valid, if not reset to the default value.
  3346. */
  3347. $iconSize = in_array( $atts['size'], $iconSizes ) ? $atts['size'] : 32;
  3348.  
  3349. // Create the permalink base based on context where the entry is being displayed.
  3350. if ( in_the_loop() && is_page() ) {
  3351.  
  3352. $permalink = trailingslashit( get_permalink() );
  3353.  
  3354. } else {
  3355.  
  3356. $permalink = trailingslashit( get_permalink( $homeID ) );
  3357. }
  3358.  
  3359. if ( ! empty( $atts['class'] ) ) $piece[] = 'class="' . $atts['class'] .'"';
  3360. if ( ! empty( $atts['slug'] ) ) $piece[] = 'id="' . $atts['slug'] .'"';
  3361. if ( ! empty( $atts['title'] ) ) $piece[] = 'title="' . $atts['title'] .'"';
  3362. if ( ! empty( $atts['target'] ) ) $piece[] = 'target="' . $atts['target'] .'"';
  3363. if ( ! $atts['follow'] ) $piece[] = 'rel="nofollow"';
  3364.  
  3365. if ( $wp_rewrite->using_permalinks() ) {
  3366.  
  3367. $piece[] = 'href="' . esc_url( add_query_arg( array( 'cn-id' => $id, 'cn-token' => $token ), $permalink . $name . '/' . $this->getSlug() . '/vcard/' ) ) . '"';
  3368.  
  3369. } else {
  3370.  
  3371. $piece[] = 'href="' . esc_url( add_query_arg( array( 'cn-entry-slug' => $this->getSlug(), 'cn-process' => 'vcard', 'cn-id' => $id, 'cn-token' => $token ), $permalink ) ) . '"';
  3372. }
  3373.  
  3374. $out = '<span class="vcard-block">';
  3375.  
  3376. $replace[] = '<a ' . implode( ' ', $piece ) . '>' . $atts['text'] . '</a>';
  3377.  
  3378. $replace[] = '<a ' . implode( ' ', $piece ) . '><image src="' . esc_url( CN_URL . 'assets/images/icons/vcard/vcard_' . $iconSize . '.png' ) . '" height="' . $iconSize . 'px" width="' . $iconSize . 'px"/></a>';
  3379.  
  3380. $out .= str_ireplace(
  3381. $search,
  3382. $replace,
  3383. empty( $atts['format'] ) ? '%text%' : $atts['format']
  3384. );
  3385.  
  3386. $out .= '</span>';
  3387.  
  3388. // The class.seo.file is only loaded in the frontend; do not attempt to add the filter
  3389. // otherwise it'll cause an error.
  3390. if ( ! is_admin() ) cnSEO::doFilterPermalink();
  3391.  
  3392. $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
  3393.  
  3394. return $this->echoOrReturn( $atts['return'], $out );
  3395. }
  3396. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement