/**
  * Prepare a single post output for response.
  *
  * @param cnEntry         $entry   Post object.
  * @param WP_REST_Request $request Request object.
  *
  * @return WP_REST_Response $data
  */
 public function prepare_item_for_response($entry, $request)
 {
     //$entry->directoryHome(
     //	array(
     //		'page_id'    => $homeID,
     //		'force_home' => $forceHome,
     //	)
     //);
     $addresses = $entry->getAddresses();
     /**
      * NOTES:
      *
      *  - The `coordinates` index array value must not have indexes otherwise it'll be converted to an object
      * which is invalid geoJSON.
      *  - The `coordinates` must but cast as floats otherwise they'll be converted to strings.
      *  - The `coordinates` must be longitude, latitude order per the geoJSON spec.
      *
      * @todo Loop thu each address within an entry so a geoJSON `feature` is added for each address the entry may have.
      * @todo The entry only needs to be added to $entries if it has at least one address and those address has both a latitude and longitude.
      *
      * @link http://connections-pro.com/support/topic/map-view/#post-319981
      */
     if ((!isset($addresses[0]->latitude) || empty($addresses[0]->latitude)) && (!isset($addresses[0]->longitude) || empty($addresses[0]->longitude))) {
         //return;
     }
     switch ($entry->getEntryType()) {
         case 'individual':
             $type = 'Person';
             break;
         case 'organization':
             $type = 'Organization';
             break;
         case 'family':
             $type = 'Family';
             break;
         default:
             $type = NULL;
     }
     $data = array('type' => 'Feature', 'geometry' => array('type' => 'Point', 'coordinates' => array((double) $addresses[0]->longitude, (double) $addresses[0]->latitude)), 'properties' => array('id' => $entry->getId(), 'type' => $type, 'slug' => $entry->getSlug(), 'permalink' => $entry->getPermalink(), 'name' => $entry->getName(), 'title' => $entry->getTitle(), 'department' => $entry->getDepartment() ? array('@type' => 'Organization', 'name' => $entry->getDepartment()) : NULL, 'organization' => $entry->getOrganization() ? array('@type' => 'Organization', 'name' => $entry->getOrganization()) : NULL, 'bio' => $entry->getBio(), 'notes' => $entry->getNotes()));
     // Wrap the data in a response object.
     $response = rest_ensure_response($data);
     return $response;
 }
 /**
  * Outputs entry data JSON encoded in HTML data attribute.
  * This is an action called by the `cn_action_entry_after` hook.
  *
  * @access public
  * @since  0.8
  *
  * @param array   $atts  Shortcode $atts passed by the `cn_action_entry_after` action hook.
  * @param cnEntry $entry An instance the the cnEntry object.
  *
  * @return string
  */
 public static function JSON($atts, $entry)
 {
     $defaults = array('tag' => 'div', 'before' => '', 'after' => '', 'return' => FALSE, 'show_addresses' => TRUE, 'show_phone_numbers' => TRUE, 'show_email' => TRUE, 'show_im' => TRUE, 'show_social_media' => TRUE, 'show_links' => TRUE, 'show_dates' => TRUE, 'show_bio' => TRUE, 'show_notes' => TRUE);
     $atts = wp_parse_args($atts, $defaults);
     $data = array('type' => $entry->getEntryType(), 'id' => $entry->getId(), 'ruid' => $entry->getRuid(), 'slug' => $entry->getSlug(), 'name' => array('full' => $entry->getName($atts), 'prefix' => $entry->getHonorificPrefix(), 'first' => $entry->getFirstName(), 'middle' => $entry->getMiddleName(), 'last' => $entry->getLastName(), 'suffix' => $entry->getHonorificSuffix()), 'title' => $entry->getTitle(), 'organization' => $entry->getOrganization(), 'department' => $entry->getDepartment(), 'contact_name' => array('full' => $entry->getContactName(), 'first' => $entry->getContactFirstName(), 'last' => $entry->getContactLastName()), 'family_name' => $entry->getFamilyName(), 'family_members' => $entry->getFamilyMembers(), 'categories' => $entry->getCategory(), 'meta' => $entry->getMeta($atts));
     if ($atts['show_addresses']) {
         $data['addresses'] = $entry->getAddresses($atts);
     }
     if ($atts['show_phone_numbers']) {
         $data['phone_numbers'] = $entry->getPhoneNumbers($atts);
     }
     if ($atts['show_email']) {
         $data['email_addresses'] = $entry->getEmailAddresses($atts);
     }
     if ($atts['show_im']) {
         $data['im'] = $entry->getIm($atts);
     }
     if ($atts['show_social_media']) {
         $data['social_media'] = $entry->getSocialMedia($atts);
     }
     if ($atts['show_links']) {
         $data['links'] = $entry->getLinks($atts);
     }
     if ($atts['show_dates']) {
         $data['dates'] = $entry->getDates($atts);
     }
     if ($atts['show_bio']) {
         $data['bio'] = $entry->getBio();
     }
     if ($atts['show_notes']) {
         $data['notes'] = $entry->getNotes();
     }
     $out = sprintf('<%1$s class="cn-entry-data-json" data-entry-data-json=\'%2$s\'></%1$s>', $atts['tag'], htmlspecialchars(json_encode($data), ENT_QUOTES, 'UTF-8'));
     $out = (empty($atts['before']) ? '' : $atts['before']) . $out . (empty($atts['after']) ? '' : $atts['after']) . PHP_EOL;
     return self::echoOrReturn($atts['return'], $out);
 }
 /**
  * The core method that processes the content according to the
  * entry part that the shortcode should add to the content.
  *
  * @access private
  * @since 0.8
  * @param  array  $atts    The shortcode attributes array.
  * @param  string $content The content captured between an open/close shortcode.
  * @param  string $tag     The shortcode tag.
  *
  * @return string          The processed content.
  */
 public function shortcode($atts, $content = '', $tag = 'cn_entry')
 {
     // Bail if self::$entry is not set because an instance of the cnEntry object is required.
     if (is_null($this->entry)) {
         return '';
     }
     $defaults = array('part' => '');
     // Normally we'd use shortcode_atts, but that strips keys from $atts that do not exist in $defaults.
     // Since $atts can contain various option for the different callback methods, we'll use wp_parse_args()
     // which leaves keys that do not exist in $atts.
     $atts = wp_parse_args($atts, $defaults);
     // All the core methods in the cnEntry_HTML class echo by default, make sure to return instead.
     $atts['return'] = TRUE;
     switch ($atts['part']) {
         case 'name':
             $out = $this->entry->getName($atts);
             break;
         case 'title':
             $out = $this->entry->getTitle();
             break;
         case 'organization':
             $out = $this->entry->getOrganization();
             break;
         case 'department':
             $out = $this->entry->getDepartment();
             break;
         case 'contact':
             $out = $this->entry->getContactName($atts);
             break;
         case 'family_relationships':
             $out = $this->entry->getFamilyMembers();
             break;
         case 'addresses':
             add_shortcode('cn_address', array($this, 'address'));
             $out = has_shortcode($content, 'cn_address') ? do_shortcode($content) : '';
             remove_shortcode('cn_address');
             break;
         case 'phone_numbers':
             add_shortcode('cn_phone', array($this, 'phone'));
             $out = has_shortcode($content, 'cn_phone') ? do_shortcode($content) : '';
             remove_shortcode('cn_phone');
             break;
         case 'email':
             add_shortcode('cn_email', array($this, 'email'));
             $out = has_shortcode($content, 'cn_email') ? do_shortcode($content) : '';
             remove_shortcode('cn_email');
             break;
         case 'im':
             add_shortcode('cn_im', array($this, 'im'));
             $out = has_shortcode($content, 'cn_im') ? do_shortcode($content) : '';
             remove_shortcode('cn_im');
             break;
         case 'social_networks':
             add_shortcode('cn_social_network', array($this, 'socialNetwork'));
             $out = has_shortcode($content, 'cn_social_network') ? do_shortcode($content) : '';
             remove_shortcode('cn_social_network');
             break;
         case 'links':
             add_shortcode('cn_link', array($this, 'link'));
             $out = has_shortcode($content, 'cn_link') ? do_shortcode($content) : '';
             remove_shortcode('cn_link');
             break;
         case 'dates':
             add_shortcode('cn_date', array($this, 'date'));
             $out = has_shortcode($content, 'cn_date') ? do_shortcode($content) : '';
             remove_shortcode('cn_date');
             break;
         case 'bio':
             $out = $this->entry->getBio();
             break;
         case 'notes':
             $out = $this->entry->getNotes();
             break;
         default:
             // Custom shortcodes can be applied to the content using this filter.
             $out = apply_filters('cn_entry_part-' . $atts['part'], $content, $atts, $this->entry);
             break;
     }
     return $out;
 }