/**
  * Process the content adding the entry address details in place of the shortcode.
  *
  * @access  private
  * @since  0.8
  * @param  array  $atts    The shortcode attributes array.
  * @param  string $content The content captured between an open/close shortcode tag.
  * @param  string $tag     The shortcode tag.
  *
  * @return string          The processed content.
  */
 public function address($atts, $content = '', $tag = 'cn_address')
 {
     $out = '';
     $defaults = array('preferred' => FALSE, 'type' => NULL, 'city' => NULL, 'state' => NULL, 'zipcode' => NULL, 'country' => NULL);
     $atts = shortcode_atts($defaults, $atts, $tag);
     $search = array('%type%', '%line_1%', '%line_2%', '%line_3%', '%locality%', '%region%', '%postal-code%', '%country%', '%latitude%', '%longitude%');
     $addresses = $this->entry->getAddresses($atts);
     foreach ($addresses as $address) {
         $replace = array('type' => $address->name, 'line_1' => $address->line_1, 'line_2' => $address->line_2, 'line_3' => $address->line_3, 'locality' => $address->city, 'region' => $address->state, 'postal_code' => $address->zipcode, 'country' => $address->country, 'latitude' => $address->latitude, 'longitude' => $address->longitude);
         $out .= str_ireplace($search, $replace, $content);
     }
     return $out;
 }
 /**
  * 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);
 }
 /**
  * Prepare a single address output for response.
  *
  * @param cnEntry         $entry   Post object.
  * @param WP_REST_Request $request Request object.
  * @param array           $data
  *
  * @return array $data
  */
 private function prepare_address_for_response($entry, $request, $data)
 {
     $data['adr'] = array();
     $display = $entry->getAddresses();
     $raw = $entry->getAddresses(array(), TRUE, FALSE, 'raw');
     if (empty($addresses)) {
         return $data;
     }
     foreach ($addresses as $address) {
         $item = array('street_address' => array('raw' => '', 'rendered' => ''), 'extended_address' => array('raw' => '', 'rendered' => ''), 'street_address_3' => array('raw' => '', 'rendered' => ''), 'street_address_4' => array('raw' => '', 'rendered' => ''), 'locality' => array('raw' => '', 'rendered' => ''), 'region' => array('raw' => '', 'rendered' => ''), 'district' => array('raw' => '', 'rendered' => ''), 'county' => array('raw' => '', 'rendered' => ''), 'postal_code' => array('raw' => '', 'rendered' => ''), 'country_name' => array('raw' => '', 'rendered' => ''));
         $data['adr'] = $item;
     }
     return $data;
 }
 /**
  * Sort the entries by the user set attributes.
  *
  * $object -- syntax is field|SORT_ASC(SORT_DESC)|SORT_REGULAR(SORT_NUMERIC)(SORT_STRING)
  *
  * example  -- 'state|SORT_ASC|SORT_STRING, last_name|SORT_DESC|SORT_REGULAR
  *
  *
  * Available order_by fields:
  *  id
  *  date_added
  *  date_modified
  *  first_name
  *  last_name
  *  organization
  *  department
  *  city
  *  state
  *  zipcode
  *  country
  *  birthday
  *  anniversary
  *
  * Order Flags:
  *  SORT_ACS
  *  SORT_DESC
  *  SPECIFIED**
  *  RANDOM**
  *
  * Sort Types:
  *  SORT_REGULAR
  *  SORT_NUMERIC
  *  SORT_STRING
  *
  * **NOTE: The SPECIFIED and RANDOM Order Flags can only be used
  * with the id field. The SPECIFIED flag must be used in conjunction
  * with $suppliedIDs which can be either a comma delimited sting or
  * an indexed array of entry IDs. If this is set, other sort fields/flags
  * are ignored.
  *
  * @access private
  * @since  unknown
  * @deprecated since unknown
  *
  * @param array   $entries A reference to an array of object $entries
  * @param string  $orderBy
  * @param mixed   array|string|NULL [optional]
  *
  * @return array of objects
  */
 private function orderBy(&$entries, $orderBy, $suppliedIDs = NULL)
 {
     if (empty($entries) || empty($orderBy)) {
         return $entries;
     }
     $orderFields = array('id', 'date_added', 'date_modified', 'first_name', 'last_name', 'title', 'organization', 'department', 'city', 'state', 'zipcode', 'country', 'birthday', 'anniversary');
     $sortFlags = array('SPECIFIED' => 'SPECIFIED', 'RANDOM' => 'RANDOM', 'SORT_ASC' => SORT_ASC, 'SORT_DESC' => SORT_DESC, 'SORT_REGULAR' => SORT_REGULAR, 'SORT_NUMERIC' => SORT_NUMERIC, 'SORT_STRING' => SORT_STRING);
     $specifiedIDOrder = FALSE;
     // Build an array of each field to sort by and attributes.
     $sortFields = explode(',', $orderBy);
     // For each field the sort order can be defined as well as the sort type
     foreach ($sortFields as $sortField) {
         $sortAtts[] = explode('|', $sortField);
     }
     /*
      * Dynamically build the variables that will be used for the array_multisort.
      *
      * The field type should be the first item in the array if the user
      * constructed the shortcode attribute correctly.
      */
     foreach ($sortAtts as $field) {
         // Trim any spaces the user might have added to the shortcode attribute.
         $field[0] = strtolower(trim($field[0]));
         // If a user included a sort field that is invalid/mis-spelled it is skipped since it can not be used.
         if (!in_array($field[0], $orderFields)) {
             continue;
         }
         // The dynamic variable are being created and populated.
         foreach ($entries as $key => $row) {
             $entry = new cnEntry($row);
             switch ($field[0]) {
                 case 'id':
                     ${$field[0]}[$key] = $entry->getId();
                     break;
                 case 'date_added':
                     ${$field[0]}[$key] = $entry->getDateAdded('U');
                     break;
                 case 'date_modified':
                     ${$field[0]}[$key] = $entry->getUnixTimeStamp();
                     break;
                 case 'first_name':
                     ${$field[0]}[$key] = $entry->getFirstName();
                     break;
                 case 'last_name':
                     ${$field[0]}[$key] = $entry->getLastName();
                     break;
                 case 'title':
                     ${$field[0]}[$key] = $entry->getTitle();
                     break;
                 case 'organization':
                     ${$field[0]}[$key] = $entry->getOrganization();
                     break;
                 case 'department':
                     ${$field[0]}[$key] = $entry->getDepartment();
                     break;
                 case $field[0] === 'city' || $field[0] === 'state' || $field[0] === 'zipcode' || $field[0] === 'country':
                     if ($entry->getAddresses()) {
                         $addresses = $entry->getAddresses();
                         foreach ($addresses as $address) {
                             //${$field[0]}[$key] = $address[$field[0]];
                             ${$field[0]}[$key] = $address->{$field}[0];
                             // Only set the data from the first address.
                             break;
                         }
                     } else {
                         ${$field[0]}[$key] = NULL;
                     }
                     break;
                 case 'birthday':
                     ${$field[0]}[$key] = strtotime($entry->getBirthday());
                     break;
                 case 'anniversary':
                     ${$field[0]}[$key] = strtotime($entry->getAnniversary());
                     break;
             }
         }
         // The sorting order to be determined by a lowercase copy of the original array.
         ${$field}[0] = array_map('strtolower', ${$field}[0]);
         // The arrays to be sorted must be passed by reference or it won't work.
         $sortParams[] =& ${$field}[0];
         // Add the flag and sort type to the sort parameters if they were supplied in the shortcode attribute.
         foreach ($field as $key => $flag) {
             // Trim any spaces the user might have added and change the string to uppercase..
             $flag = strtoupper(trim($flag));
             // If a user included a sort tag that is invalid/mis-spelled it is skipped since it can not be used.
             if (!array_key_exists($flag, $sortFlags)) {
                 continue;
             }
             /*
              * If the order is specified set the variable to true and continue
              * because SPECIFIED should not be added to the $sortParams array
              * as that would be an invalid argument for the array multisort.
              */
             if ($flag === 'SPECIFIED' || $flag === 'RANDOM') {
                 $idOrder = $flag;
                 continue;
             }
             // Must be pass as reference or the multisort will fail.
             $sortParams[] =& $sortFlags[$flag];
             unset($flag);
         }
     }
     /*
      *
      */
     if (isset($id) && isset($idOrder)) {
         switch ($idOrder) {
             case 'SPECIFIED':
                 $sortedEntries = array();
                 /*
                  * Convert the supplied IDs value to an array if it is not.
                  */
                 if (!is_array($suppliedIDs) && !empty($suppliedIDs)) {
                     // Trim the space characters if present.
                     $suppliedIDs = str_replace(' ', '', $suppliedIDs);
                     // Convert to array.
                     $suppliedIDs = explode(',', $suppliedIDs);
                 }
                 foreach ($suppliedIDs as $entryID) {
                     $sortedEntries[] = $entries[array_search($entryID, $id)];
                 }
                 $entries = $sortedEntries;
                 return $entries;
                 break;
             case 'RANDOM':
                 shuffle($entries);
                 return $entries;
                 break;
         }
     }
     /*print_r($sortParams);
     		print_r($first_name);
     		print_r($last_name);
     		print_r($state);
     		print_r($zipcode);
     		print_r($organization);
     		print_r($department);
     		print_r($birthday);
     		print_r($anniversary);*/
     // Must be pass as reference or the multisort will fail.
     $sortParams[] =& $entries;
     //$sortParams = array(&$state, SORT_ASC, SORT_REGULAR, &$zipcode, SORT_DESC, SORT_STRING, &$entries);
     call_user_func_array('array_multisort', $sortParams);
     return $entries;
 }
 /**
  * Renders the address metabox.
  *
  * @access public
  * @since  0.8
  *
  * @param  cnEntry $entry An instance of the cnEntry object.
  * @param  array   $atts  The metabox options array from self::register().
  *
  * @return string The address metabox.
  */
 public static function address($entry, $atts)
 {
     echo '<div class="widgets-sortables ui-sortable" id="addresses">', PHP_EOL;
     // --> Start template <-- \\
     echo '<textarea id="address-template" style="display: none;">', PHP_EOL;
     self::addressField(new stdClass());
     echo '</textarea>', PHP_EOL;
     // --> End template <-- \\
     $addresses = $entry->getAddresses(array(), FALSE, FALSE, 'edit');
     //print_r($addresses);
     if (!empty($addresses)) {
         foreach ($addresses as $address) {
             $token = str_replace('-', '', cnUtility::getUUID());
             echo '<div class="widget address" id="address-row-' . $token . '">', PHP_EOL;
             self::addressField($address, $token);
             echo '</div>', PHP_EOL;
         }
     }
     echo '</div>', PHP_EOL;
     echo '<p class="add"><a href="#" class="cn-add cn-button button" data-type="address" data-container="addresses">', __('Add Address', 'connections'), '</a></p>', PHP_EOL;
 }
 /**
  * Renders the address metabox.
  *
  * @access public
  * @since  0.8
  *
  * @param  cnEntry $entry An instance of the cnEntry object.
  * @param  array   $atts  The metabox options array from self::register().
  *
  * @return string The address metabox.
  */
 public static function address($entry, $atts)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     // This array will store field group IDs as the fields are registered.
     // This array will be checked for an existing ID before rendering
     // a field to prevent multiple field group IDs from being rendered.
     $groupIDs = array();
     // This array will store field IDs as the fields are registered.
     // This array will be checked for an existing ID before rendering
     // a field to prevent multiple field IDs from being rendered.
     $fieldIDs = array();
     // Grab the address types.
     $addressTypes = $instance->options->getDefaultAddressValues();
     // $defaults = array(
     // 	// Define the entry type so the correct fields will be rendered. If an entry type is all registered entry types, render all fields assuming this is new entry.
     // 	'type'  => $entry->getEntryType() ? $entry->getEntryType() : array( 'individual', 'organization', 'family'),
     // 	// The entry type to which the meta fields are being registered.
     // 	'individual' => array(
     // 		'type'          => $addressTypes,
     // 		'preferred'     => TRUE,
     // 		'visibility'    => $visibiltyOptions,
     // 		// The entry type field meta. Contains the arrays that define the field groups and their respective fields.
     // 		'meta'   => array(
     // 			// This key is the field group ID and it must be unique. Duplicates will be discarded.
     // 			'address-local' => array(
     // 				// Whether or not to render the field group.
     // 				'show'  => TRUE,
     // 				// The fields within the field group.
     // 				'field' => array(
     // 					// This key is the field ID.
     // 					'line_1' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'line_1',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'Address Line 1', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'line_1',
     // 						'before'    => '<div class="address-line">',
     // 						'after'     => '</div>',
     // 						),
     // 					'line_2' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'line_2',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'Address Line 2', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'line_2',
     // 						'before'    => '<div class="address-line">',
     // 						'after'     => '</div>',
     // 						),
     // 					'line_3' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'line_3',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'Address Line 3', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'line_3',
     // 						'before'    => '<div class="address-line">',
     // 						'after'     => '</div>',
     // 						),
     // 					),
     // 				),
     // 			'address-region' => array(
     // 				// Whether or not to render the field group.
     // 				'show'  => TRUE,
     // 				// The fields within the field group.
     // 				'field' => array(
     // 					// This key is the field ID.
     // 					'city' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'city',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'City', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'city',
     // 						'before'    => '<span class="address-city">',
     // 						'after'     => '</span>',
     // 						),
     // 					'state' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'state',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'State', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'state',
     // 						'before'    => '<span class="address-state">',
     // 						'after'     => '</span>',
     // 						),
     // 					'zipcode' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'zipcode',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'Zipcode', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'zipcode',
     // 						'before'    => '<span class="address-zipcode">',
     // 						'after'     => '</span>',
     // 						),
     // 					),
     // 				),
     // 			'address-country' => array(
     // 				// Whether or not to render the field group.
     // 				'show'  => TRUE,
     // 				// The fields within the field group.
     // 				'field' => array(
     // 					// This key is the field ID.
     // 					'country' => array(
     // 						// Each field must have an unique ID. Duplicates will be discarded.
     // 						'id'        => 'country',
     // 						// Whether or not to render the field.
     // 						'show'      => TRUE,
     // 						// The field label if supplied.
     // 						'label'     => __( 'Country', 'connections' ),
     // 						// Whether or not the field is required. If it is required 'class="required"' will be added to the field.
     // 						// This will be used by jQuery Validate.
     // 						'required'  => FALSE,
     // 						// The field type.
     // 						'type'      => 'text',
     // 						// The field value.
     // 						'value'     => 'country',
     // 						'before'    => '<span class="address-country">',
     // 						'after'     => '</span>',
     // 						),
     // 					),
     // 				),
     // 			),
     // 		),
     // 	);
     // $atts = wp_parse_args( apply_filters( 'cn_metabox_name_atts', $atts ), $defaults );
     echo '<div class="widgets-sortables ui-sortable" id="addresses">', PHP_EOL;
     // --> Start template <-- \\
     echo '<textarea id="address-template" style="display: none;">', PHP_EOL;
     echo '<div class="widget-top">', PHP_EOL;
     echo '<div class="widget-title-action"><a class="widget-action"></a></div>', PHP_EOL;
     echo '<div class="widget-title"><h4>', PHP_EOL;
     cnHTML::field(array('type' => 'select', 'class' => '', 'id' => 'address[::FIELD::][type]', 'options' => $addressTypes, 'required' => FALSE, 'before' => '<span class="adddress-type">', 'label' => __('Address Type', 'connections'), 'return' => FALSE));
     cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'address[preferred]', 'options' => array('::FIELD::' => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</span></span>', 'return' => FALSE));
     // Only show this if there are visibility options that the user is permitted to see.
     if (!empty(self::$visibility)) {
         cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'address[::FIELD::][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), 'public');
     }
     echo '</h4></div>', PHP_EOL;
     echo '</div>', PHP_EOL;
     echo '<div class="widget-inside">';
     echo '<div class="address-local">';
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][line_1]', 'required' => FALSE, 'label' => __('Address Line 1', 'connections'), 'before' => '<div class="address-line">', 'after' => '</div>', 'return' => FALSE));
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][line_2]', 'required' => FALSE, 'label' => __('Address Line 2', 'connections'), 'before' => '<div class="address-line">', 'after' => '</div>', 'return' => FALSE));
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][line_3]', 'required' => FALSE, 'label' => __('Address Line 3', 'connections'), 'before' => '<div class="address-line">', 'after' => '</div>', 'return' => FALSE));
     echo '</div>';
     echo '<div class="address-region">';
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][city]', 'required' => FALSE, 'label' => __('City', 'connections'), 'before' => '<div class="address-city">', 'after' => '</div>', 'return' => FALSE));
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][state]', 'required' => FALSE, 'label' => __('State', 'connections'), 'before' => '<div class="address-state">', 'after' => '</div>', 'return' => FALSE));
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][zipcode]', 'required' => FALSE, 'label' => __('Zipcode', 'connections'), 'before' => '<div class="address-zipcode">', 'after' => '</div>', 'return' => FALSE));
     echo '</div>';
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][country]', 'required' => FALSE, 'label' => __('Country', 'connections'), 'before' => '<div class="address-country">', 'after' => '</div>', 'return' => FALSE));
     echo '<div class="address-geo">';
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][latitude]', 'required' => FALSE, 'label' => __('Latitude', 'connections'), 'before' => '<div class="address-latitude">', 'after' => '</div>', 'return' => FALSE));
     cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[::FIELD::][longitude]', 'required' => FALSE, 'label' => __('Longitude', 'connections'), 'before' => '<div class="address-longitude">', 'after' => '</div>', 'return' => FALSE));
     echo '</div>', PHP_EOL;
     if (is_admin()) {
         echo '<a class="geocode button" data-uid="::FIELD::" href="#">', __('Geocode', 'connections'), '</a>';
     }
     echo '<div class="clear"></div>';
     if (is_admin()) {
         echo '<div class="map" id="map-::FIELD::" data-map-id="::FIELD::" style="display: none; height: 400px;">', __('Geocoding Address.', 'connections'), '</div>';
     }
     echo '<br>';
     echo '<p class="cn-remove-button"><a href="#" class="cn-remove cn-button button cn-button-warning" data-type="address" data-token="::FIELD::">', __('Remove', 'connections'), '</a></p>';
     echo '</div>', PHP_EOL;
     echo '</textarea>', PHP_EOL;
     // --> End template <-- \\
     $addresses = $entry->getAddresses(array(), FALSE, FALSE, 'edit');
     //print_r($addresses);
     if (!empty($addresses)) {
         foreach ($addresses as $address) {
             $token = str_replace('-', '', cnUtility::getUUID());
             $selectName = 'address[' . $token . '][type]';
             $preferred = $address->preferred ? $token : '';
             echo '<div class="widget address" id="address-row-' . $token . '">', PHP_EOL;
             echo '<div class="widget-top">', PHP_EOL;
             echo '<div class="widget-title-action"><a class="widget-action"></a></div>', PHP_EOL;
             echo '<div class="widget-title"><h4>', PHP_EOL;
             cnHTML::field(array('type' => 'select', 'class' => '', 'id' => $selectName, 'options' => $addressTypes, 'required' => FALSE, 'before' => '<span class="adddress-type">', 'label' => __('Address Type', 'connections'), 'return' => FALSE), $address->type);
             cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'address[preferred]', 'options' => array($token => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</span></span>', 'return' => FALSE), $preferred);
             // Only show this if there are visibility options that the user is permitted to see.
             if (!empty(self::$visibility)) {
                 cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'address[' . $token . '][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), $address->visibility);
             }
             echo '</h4></div>', PHP_EOL;
             echo '</div>', PHP_EOL;
             echo '<div class="widget-inside">', PHP_EOL;
             echo '<div class="address-local">', PHP_EOL;
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][line_1]', 'required' => FALSE, 'label' => __('Address Line 1', 'connections'), 'before' => '<div class="address-line">', 'after' => '</div>', 'return' => FALSE), $address->line_1);
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][line_2]', 'required' => FALSE, 'label' => __('Address Line 2', 'connections'), 'before' => '<div class="address-line">', 'after' => '</div>', 'return' => FALSE), $address->line_2);
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][line_3]', 'required' => FALSE, 'label' => __('Address Line 3', 'connections'), 'before' => '<div class="address-line">', 'after' => '</div>', 'return' => FALSE), $address->line_3);
             echo '</div>', PHP_EOL;
             echo '<div class="address-region">', PHP_EOL;
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][city]', 'required' => FALSE, 'label' => __('City', 'connections'), 'before' => '<div class="address-city">', 'after' => '</div>', 'return' => FALSE), $address->city);
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][state]', 'required' => FALSE, 'label' => __('State', 'connections'), 'before' => '<div class="address-state">', 'after' => '</div>', 'return' => FALSE), $address->state);
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][zipcode]', 'required' => FALSE, 'label' => __('Zipcode', 'connections'), 'before' => '<div class="address-zipcode">', 'after' => '</div>', 'return' => FALSE), $address->zipcode);
             echo '</div>', PHP_EOL;
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][country]', 'required' => FALSE, 'label' => __('Country', 'connections'), 'before' => '<div class="address-country">', 'after' => '</div>', 'return' => FALSE), $address->country);
             echo '<div class="address-geo">', PHP_EOL;
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][latitude]', 'required' => FALSE, 'label' => __('Latitude', 'connections'), 'before' => '<div class="address-latitude">', 'after' => '</div>', 'return' => FALSE), $address->latitude);
             cnHTML::field(array('type' => 'text', 'class' => '', 'id' => 'address[' . $token . '][longitude]', 'required' => FALSE, 'label' => __('Longitude', 'connections'), 'before' => '<div class="address-longitude">', 'after' => '</div>', 'return' => FALSE), $address->longitude);
             echo '</div>', PHP_EOL;
             if (is_admin()) {
                 echo '<a class="geocode button" data-uid="', $token, '" href="#">', __('Geocode', 'connections'), '</a>';
             }
             echo '<div class="clear"></div>', PHP_EOL;
             if (is_admin()) {
                 echo '<div class="map" id="map-', $token, '" data-map-id="', $token, '" style="display: none; height: 400px;">', __('Geocoding Address.', 'connections'), '</div>', PHP_EOL;
             }
             echo '<input type="hidden" name="address[', $token, '][id]" value="', $address->id, '">', PHP_EOL;
             echo '<br>';
             echo '<p class="cn-remove-button"><a href="#" class="cn-remove cn-button button cn-button-warning" data-type="address" data-token="' . $token . '">', __('Remove', 'connections'), '</a></p>', PHP_EOL;
             echo '</div>', PHP_EOL;
             echo '</div>', PHP_EOL;
         }
     }
     // foreach ( (array) $atts['type'] as $entryType ) {
     // 	if ( array_key_exists( $entryType, $atts ) ) {
     // 		if ( isset( $atts[ $entryType ]['callback'] ) ) {
     // 			call_user_func( $atts[ $entryType ]['callback'], $entry, $atts[ $entryType ]['meta'] );
     // 			continue;
     // 		}
     // 		$selectName = 'address['  . $token . '][type]';
     // 		echo '<div class="widget address" id="address-row-'  . $token . '">' , PHP_EOL;
     // 			echo '<div class="widget-top">' , PHP_EOL;
     // 				echo '<div class="widget-title-action"><a class="widget-action"></a></div>' , PHP_EOL;
     // 				echo '<div class="widget-title"><h4>' , PHP_EOL;
     // 					if ( isset( $atts[ $entryType ]['type'] ) ) {
     // 						cnHTML::field(
     // 							array(
     // 								'type'     => 'select',
     // 								'class'    => '',
     // 								'id'       => $selectName,
     // 								'options'  => $addressTypes,
     // 								'required' => FALSE,
     // 								'label'    => __( 'Address Type', 'connections' ),
     // 								'return'   => FALSE,
     // 							),
     // 							$address->type
     // 						);
     // 					}
     // 					if ( isset( $atts[ $entryType ]['preferred'] ) ) {
     // 						cnHTML::field(
     // 							array(
     // 								'type'     => 'radio',
     // 								'format'   => 'inline',
     // 								'class'    => '',
     // 								'id'       => 'address[preferred]',
     // 								'options'  => array( $token => __( 'Preferred', 'connections' ) ),
     // 								'required' => FALSE,
     // 								'before'   => '<span class="preferred">',
     // 								'after'    => '</span>',
     // 								'return'   => FALSE,
     // 							),
     // 							$preferred
     // 						);
     // 					}
     // 					if ( isset( $atts[ $entryType ]['visibility'] ) ) {
     // 						cnHTML::field(
     // 							array(
     // 								'type'     => 'radio',
     // 								'format'   => 'inline',
     // 								'class'    => '',
     // 								'id'       => 'address[' . $token . '][visibility]',
     // 								'options'  => $visibiltyOptions,
     // 								'required' => FALSE,
     // 								'before'   => '<span class="visibility">' . __( 'Visibility', 'connections' ) . ' ',
     // 								'after'    => '</span>',
     // 								'return'   => FALSE,
     // 							),
     // 							'public'
     // 						);
     // 					}
     // 				echo '</h4></div>'  , PHP_EOL; // END .widget-title
     // 			echo '</div>' , PHP_EOL; // END .widget-top
     // 			echo '<div class="widget-inside">';
     // 				/*
     // 				 * Dump the output in a var that way it can mre more easily broke up and filters added later.
     // 				 */
     // 				$out = '';
     // 				foreach ( $atts[ $entryType ]['meta'] as $type => $meta ) {
     // 					if ( in_array( $type, $groupIDs ) ) {
     // 						continue;
     // 					} else {
     // 						$groupIDs[] = $type;
     // 					}
     // 					$out .= '<div class="cn-metabox" id="cn-metabox-section-' . $type . '">' . PHP_EOL;
     // 					if ( $meta['show'] == TRUE ) {
     // 						foreach( $meta['field'] as $field ) {
     // 							if ( in_array( $field['id'], $fieldIDs ) ) {
     // 								continue;
     // 							} else {
     // 								$fieldIDs[] = $field['id'];
     // 							}
     // 							if ( $field['show'] ) {
     // 								$defaults = array(
     // 									'type'     => '',
     // 									'class'    => array(),
     // 									'id'       => '',
     // 									'style'    => array(),
     // 									'options'  => array(),
     // 									'value'    => '',
     // 									'required' => FALSE,
     // 									'label'    => '',
     // 									'before'   => '',
     // 									'after'    => '',
     // 									'return'   => TRUE,
     // 									);
     // 								$field = wp_parse_args( $field, $defaults );
     // 								$out .= cnHTML::field(
     // 									array(
     // 										'type'     => $field['type'],
     // 										'class'    => $field['class'],
     // 										'id'       => $field['id'],
     // 										'style'    => $field['style'],
     // 										'options'  => $field['options'],
     // 										'required' => $field['required'],
     // 										'label'    => $field['label'],
     // 										'before'   => $field['before'],
     // 										'after'    => $field['after'],
     // 										'return'   => TRUE,
     // 									),
     // 									$field['value']
     // 								);
     // 							}
     // 						}
     // 					}
     // 					$out .= '</div>' . PHP_EOL;
     // 				}
     // 				echo $out;
     // 			echo '</div>' , PHP_EOL; // END .widget-inside
     // 		echo '</div>' , PHP_EOL; // END .widget
     // 	}
     // }
     echo '</div>', PHP_EOL;
     echo '<p class="add"><a href="#" class="cn-add cn-button button" data-type="address" data-container="addresses">', __('Add Address', 'connections'), '</a></p>', PHP_EOL;
 }