/**
 * Ensure WPSEO header items are not added to internal Connections pages.
 * @todo Should add Connections related header items to mimic WPSEO.
 *
 * @access private
 * @since  8.1.1
 * @return void
 */
function cn_remove_wpseo_head()
{
    if (cnQuery::getVar('cn-entry-slug') || cnQuery::getVar('cn-cat-slug') || cnQuery::getVar('cn-cat')) {
        if (isset($GLOBALS['wpseo_front'])) {
            remove_action('wp_head', array($GLOBALS['wpseo_front'], 'head'), 1);
        }
    }
}
Esempio n. 2
0
 /**
  * Initiate the template options using the option values.
  *
  * @access private
  * @since  3.0
  *
  * @param  array $atts The shortcode $atts array.
  *
  * @return array
  */
 public static function initOptions($atts)
 {
     if (cnQuery::getVar('cn-entry-slug')) {
         /**
          * @var cnOutput $entry
          * @var array $option
          */
         $options = cnSettingsAPI::get('connections_template', self::SLUG, 'single');
     } else {
         /**
          * @var cnOutput $entry
          * @var array $option
          */
         $options = cnSettingsAPI::get('connections_template', self::SLUG, 'card');
         $style = array('background-color' => '#FFF', 'border' => $options['border_width'] . 'px solid ' . $options['border_color'], 'border-radius' => $options['border_radius'] . 'px', 'color' => '#000', 'margin' => '8px 0', 'padding' => '10px', 'position' => 'relative');
         if (is_array($style)) {
             $atts = wp_parse_args($style, $atts);
         }
     }
     if (is_array($options)) {
         $atts = wp_parse_args($options, $atts);
     }
     return $atts;
 }
 /**
  * Returns the current category being viewed.
  *
  * @access public
  * @since  8.5.18
  * @static
  *
  * @return false|cnTerm_Object
  */
 public static function getCurrent()
 {
     $current = FALSE;
     if (cnQuery::getVar('cn-cat-slug')) {
         $slug = explode('/', cnQuery::getVar('cn-cat-slug'));
         // If the category slug is a descendant, use the last slug from the URL for the query.
         $current = end($slug);
     } elseif ($catIDs = cnQuery::getVar('cn-cat')) {
         if (is_array($catIDs)) {
             // If value is a string, strip the white space and covert to an array.
             $catIDs = wp_parse_id_list($catIDs);
             // Use the first element
             $current = reset($catIDs);
         } else {
             $current = $catIDs;
         }
     }
     if (!empty($current)) {
         if (ctype_digit((string) $current)) {
             $field = 'id';
         } else {
             $field = 'slug';
         }
         $current = cnTerm::getBy($field, $current, 'category');
         // cnTerm::getBy() can return NULL || an instance of WP_Error, so, lets check for that.
         if (!is_a($current, 'cnTerm_Object')) {
             $current = FALSE;
         }
     }
     return $current;
 }
 /**
  * Add the the current Connections category description or entry bio excerpt as the page meta description.
  *
  * @access private
  * @since  0.7.8
  * @static
  *
  * @uses   cnQuery::getVar()
  * @uses   esc_attr()
  * @uses   strip_shortcodes()
  */
 public static function metaDesc()
 {
     // Whether or not to filter the page title with the current directory location.
     if (!cnSettingsAPI::get('connections', 'seo_meta', 'page_desc')) {
         return;
     }
     $description = '';
     if (cnQuery::getVar('cn-cat-slug')) {
         // If the category slug is a descendant, use the last slug from the URL for the query.
         $categorySlug = explode('/', cnQuery::getVar('cn-cat-slug'));
         if (isset($categorySlug[count($categorySlug) - 1])) {
             $categorySlug = $categorySlug[count($categorySlug) - 1];
         }
         $term = cnTerm::getBy('slug', $categorySlug, 'category');
         $category = new cnCategory($term);
         $description = $category->getExcerpt(array('length' => 160));
     }
     if (cnQuery::getVar('cn-cat')) {
         if (is_array(cnQuery::getVar('cn-cat'))) {
             return;
         }
         $categoryID = cnQuery::getVar('cn-cat');
         $term = cnTerm::getBy('id', $categoryID, 'category');
         $category = new cnCategory($term);
         $description = $category->getExcerpt(array('length' => 160));
     }
     if (cnQuery::getVar('cn-entry-slug')) {
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         $result = $instance->retrieve->entries(array('slug' => urldecode(cnQuery::getVar('cn-entry-slug'))));
         // Make sure an entry is returned and then echo the meta desc.
         if (!empty($result)) {
             $entry = new cnEntry($result[0]);
             $description = $entry->getExcerpt(array('length' => 160));
         }
     }
     if (0 == strlen($description)) {
         return;
     }
     echo '<meta name="description" content="' . esc_attr(trim(strip_shortcodes(strip_tags(stripslashes($description))))) . '"/>' . "\n";
 }
 /**
  * The private recursive function to build the category link item.
  *
  * Accepted option for the $atts property are:
  * 	type (string)
  * 	show_empty (bool) Whether or not to display empty categories.
  * 	show_count (bool) Whether or not to display the category count.
  *
  * @param object $category A category object.
  * @param int $level The current category level.
  * @param int $depth The depth limit.
  * @param array $slug An array of the category slugs to be used to build the permalink.
  * @param array $atts
  * @return string
  */
 private static function categoryLinkDescendant($category, $level, $depth, $slug, $atts)
 {
     /**
      * @var WP_Rewrite $wp_rewrite
      * @var connectionsLoad $connections
      */
     global $wp_rewrite;
     $out = '';
     $defaults = array('show_empty' => TRUE, 'show_count' => TRUE, 'exclude' => array(), 'force_home' => FALSE, 'home_id' => cnSettingsAPI::get('connections', 'connections_home_page', 'page_id'));
     $atts = wp_parse_args($atts, $defaults);
     // Do not show the excluded category as options.
     if (!empty($atts['exclude']) && in_array($category->term_id, $atts['exclude'])) {
         return $out;
     }
     if ($atts['show_empty'] || !empty($category->count) || !empty($category->children)) {
         $count = $atts['show_count'] ? ' (' . $category->count . ')' : '';
         /*
          * Determine of pretty permalink is enabled.
          * If it is, add the category slug to the array which will be imploded to be used to build the URL.
          * If it is not, set the $slug to the category term ID.
          */
         if ($wp_rewrite->using_permalinks()) {
             $slug[] = $category->slug;
         } else {
             $slug = array($category->slug);
         }
         /*
          * Get tge current category from the URL / query string.
          */
         if (cnQuery::getVar('cn-cat-slug')) {
             // Category slug
             $queryCategorySlug = cnQuery::getVar('cn-cat-slug');
             if (!empty($queryCategorySlug)) {
                 // If the category slug is a descendant, use the last slug from the URL for the query.
                 $queryCategorySlug = explode('/', $queryCategorySlug);
                 if (isset($queryCategorySlug[count($queryCategorySlug) - 1])) {
                     $currentCategory = $queryCategorySlug[count($queryCategorySlug) - 1];
                 }
             }
         } elseif (cnQuery::getVar('cn-cat')) {
             $currentCategory = cnQuery::getVar('cn-cat');
         } else {
             $currentCategory = '';
         }
         $out .= '<li class="cat-item cat-item-' . $category->term_id . ($currentCategory == $category->slug || $currentCategory == $category->term_id ? ' current-cat' : '') . ' cn-cat-parent">';
         // Create the permalink anchor.
         $out .= cnURL::permalink(array('type' => 'category', 'slug' => implode('/', $slug), 'title' => $category->name, 'text' => $category->name . $count, 'home_id' => $atts['home_id'], 'force_home' => $atts['force_home'], 'return' => TRUE));
         /*
          * Only show the descendants based on the following criteria:
          * 	- There are descendant categories.
          * 	- The descendant depth is < than the current $level
          *
          * When descendant depth is set to 0, show all descendants.
          * When descendant depth is set to < $level, call the recursive function.
          */
         if (!empty($category->children) && ($depth <= 0 ? -1 : $level) < $depth) {
             $out .= '<ul class="children cn-cat-children">';
             foreach ($category->children as $child) {
                 $out .= self::categoryLinkDescendant($child, $level + 1, $depth, $slug, $atts);
             }
             $out .= '</ul>';
         }
         $out .= '</li>';
     }
     return $out;
 }
    /**
     * Render the note informing the user that the category select drop down is for customization/display purposes only,
     * that is non-functional.
     *
     * @access private
     * @since  8.4
     *
     * @uses   cnTemplate_Customizer::supports()
     */
    public function categoryMessage()
    {
        if ($this->supports('category-select') && !cnQuery::getVar('cn-entry-slug')) {
            ?>

			<div id="cn-customizer-messages">
				<ul id="cn-customizer-message-list">
					<li class="cn-customizer-message"><?php 
            _e('<strong>NOTE:</strong> Category select is for customization purposes only. It will not filter the results.', 'connections');
            ?>
</li>
				</ul>
			</div>

			<?php 
        }
    }
 /**
  * Retrieve all connected logs.
  *
  * Used for retrieving logs related to particular items, such as a specific error.
  *
  * @access private
  * @since  8.2.10
  * @static
  *
  * @uses   wp_parse_args()
  * @uses   get_posts()
  * @uses   cnQuery::getVar()
  * @uses   cnLog::valid()
  *
  * @param array $atts
  *
  * @return array|false An indexed array of logs or false if none were found.
  */
 public static function getConnected($atts = array())
 {
     $defaults = array('post_parent' => 0, 'post_type' => self::POST_TYPE, 'posts_per_page' => 20, 'post_status' => 'publish', 'paged' => cnQuery::getVar('paged'), 'type' => FALSE);
     $query = wp_parse_args($atts, $defaults);
     if ($query['type']) {
         if (is_array($query['type'])) {
             $types = array();
             foreach ($query['type'] as $type) {
                 if (self::valid($type)) {
                     $types[] = $type;
                 }
             }
         } else {
             $types = '';
             if (self::valid($query['type'])) {
                 $types = $query['type'];
             }
         }
         if (!empty($types)) {
             $query['tax_query'] = array(array('taxonomy' => self::TAXONOMY, 'field' => 'slug', 'terms' => $types));
         }
     }
     $logs = get_posts($query);
     if ($logs) {
         return $logs;
     }
     // No logs found.
     return FALSE;
 }
 /**
  * An indexed array of file names to be searched for.
  *
  * The file names is an index array of file names where the
  * highest priority is first and the lowest priority is last.
  *
  * @access public
  * @since  0.8
  * @static
  * @uses   apply_filters()
  * @uses   cnQuery::getVar()
  * @param  string $base The base file name. Typically `card` for a template file and the template slug for CSS and JS files.
  * @param  string $name The template part name; such as `single` or `category`.
  * @param  string $slug The template part slug; such as an entry slug or category slug.
  * @param  string $ext  [optional] The template file name extension. Defaults to `php`.
  *
  * @return array        An indexed array of file names to search for.
  */
 public static function fileNames($base, $name = NULL, $slug = NULL, $ext = 'php')
 {
     $files = array();
     if (cnQuery::getVar('cn-cat')) {
         $categoryID = cnQuery::getVar('cn-cat');
         // Since the `cn-cat` query var can be an array, we'll only add the category slug
         // template name when querying a single category.
         if (!is_array($categoryID)) {
             $term = cnTerm::getBy('id', $categoryID, 'category');
             $files[] = self::fileName($base, 'category', $term->slug, $ext);
         }
         $files[] = self::fileName($base, 'category', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-cat-slug')) {
         $files[] = self::fileName($base, 'category', cnQuery::getVar('cn-cat-slug'), $ext);
         $files[] = self::fileName($base, 'category', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-country')) {
         $country = self::queryVarSlug(cnQuery::getVar('cn-country'));
         $files[] = self::fileName($base, 'country', $country, $ext);
         $files[] = self::fileName($base, 'country', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-region')) {
         $region = self::queryVarSlug(cnQuery::getVar('cn-region'));
         $files[] = self::fileName($base, 'region', $region, $ext);
         $files[] = self::fileName($base, 'region', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-postal-code')) {
         $zipcode = self::queryVarSlug(cnQuery::getVar('cn-postal-code'));
         $files[] = self::fileName($base, 'postal-code', $zipcode, $ext);
         $files[] = self::fileName($base, 'postal-code', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-locality')) {
         $locality = self::queryVarSlug(cnQuery::getVar('cn-locality'));
         $files[] = self::fileName($base, 'locality', $locality, $ext);
         $files[] = self::fileName($base, 'locality', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-organization')) {
         $organization = self::queryVarSlug(cnQuery::getVar('cn-organization'));
         $files[] = self::fileName($base, 'organization', $organization, $ext);
         $files[] = self::fileName($base, 'organization', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-department')) {
         $department = self::queryVarSlug(cnQuery::getVar('cn-department'));
         $files[] = self::fileName($base, 'department', $department, $ext);
         $files[] = self::fileName($base, 'department', NULL, $ext);
         // var_dump( $files );
     }
     if (cnQuery::getVar('cn-entry-slug')) {
         $files[] = self::fileName($base, NULL, cnQuery::getVar('cn-entry-slug'), $ext);
         $files[] = self::fileName($base, 'single', NULL, $ext);
         // var_dump( $files );
     }
     // If `$name` was supplied, add it to the files to search for.
     if (!is_null($name)) {
         $files[] = self::fileName($base, $name, NULL, $ext);
     }
     // Add the base as the least priority, since it is required.
     $files[] = self::fileName($base, NULL, NULL, $ext);
     /**
      * Allow template choices to be filtered.
      *
      * The resulting array should be in the order of most specific first, least specific last.
      * e.g. 0 => card-single.php, 1 => card.php
      */
     $files = apply_filters('cn_locate_file_names', $files, $base, $name, $slug, $ext);
     // var_dump( $files );
     // Sort the files based on priority
     ksort($files, SORT_NUMERIC);
     // var_dump( $files );
     return array_filter($files);
 }
 /**
  * Render an unordered list of categories.
  *
  * This is the Connections equivalent of @see wp_list_categories() in WordPress core ../wp-includes/category-template.php
  *
  * @access public
  * @since  8.1.6
  * @static
  *
  * @uses   wp_parse_args()
  * @uses   cnTerm::getTaxonomyTerms()
  * @uses   cnURL::permalink()
  * @uses   Walker::walk()
  *
  * @param array $atts {
  *     Optional. An array of arguments.
  *     NOTE: Additionally, all valid options as supported in @see cnTerm::getTaxonomyTerms().
  *
  * @type string $show_option_all  A non-blank value causes the display of a link to the directory home page.
  *                                Default: ''. The default is not to display a link.
  *                                Accepts: Any valid string.
  * @type string $show_option_none Set the text to show when no categories are listed.
  *                                Default: 'No Categories'
  *                                Accepts: Any valid string.
  * @type bool   $show_count       Whether or not to display the category count.
  *                                Default: FALSE
  * @type int    $depth            Controls how many levels in the hierarchy of categories are to be included in the list.
  *                                Default: 0
  *                                Accepts: 0  - All categories and child categories.
  *                                         -1 - All Categories displayed  flat, not showing the parent/child relationships.
  *                                         1  - Show only top level/root parent categories.
  *                                         n  - Value of n (int) specifies the depth (or level) to descend in displaying the categories.
  * @type string $taxonomy         The taxonomy tree to display.
  *                                Default: 'category'
  *                                Accepts: Any registered taxonomy.
  * @type bool   $return           Whether or not to return or echo the resulting HTML.
  *                                Default: FALSE
  * }
  *
  * @return string
  */
 public static function render($atts = array())
 {
     $out = '';
     $defaults = array('show_option_all' => '', 'show_option_none' => __('No categories', 'connections'), 'orderby' => 'name', 'order' => 'ASC', 'show_count' => FALSE, 'hide_empty' => FALSE, 'child_of' => 0, 'exclude' => array(), 'hierarchical' => TRUE, 'depth' => 0, 'parent_id' => array(), 'taxonomy' => 'category', 'force_home' => FALSE, 'home_id' => cnSettingsAPI::get('connections', 'connections_home_page', 'page_id'), 'return' => FALSE);
     $atts = wp_parse_args($atts, $defaults);
     $atts['parent_id'] = wp_parse_id_list($atts['parent_id']);
     $walker = new self();
     if (empty($atts['parent_id'])) {
         $terms = cnTerm::getTaxonomyTerms($atts['taxonomy'], array_merge($atts, array('name' => '')));
     } else {
         $terms = cnTerm::getTaxonomyTerms($atts['taxonomy'], array_merge($atts, array('include' => $atts['parent_id'], 'child_of' => 0, 'name' => '')));
         // If any of the `parent_id` is not a root parent (where $term->parent = 0) set it parent ID to `0`
         // so the term tree will be properly constructed.
         foreach ($terms as $term) {
             if (0 !== $term->parent) {
                 $term->parent = 0;
             }
         }
         foreach ($atts['parent_id'] as $termID) {
             $children = cnTerm::getTaxonomyTerms($atts['taxonomy'], array_merge($atts, array('child_of' => $termID, 'name' => '')));
             if (!is_wp_error($children)) {
                 $terms = array_merge($terms, $children);
             }
         }
     }
     /**
      * Allows extensions to add/remove class names to the term tree list.
      *
      * @since 8.5.18
      *
      * @param array $class The array of class names.
      * @param array $terms The array of terms.
      * @param array $atts  The method attributes.
      */
     $class = apply_filters('cn_term_list_class', array('cn-cat-tree'), $terms, $atts);
     $class = cnSanitize::htmlClass($class);
     $out .= '<ul class="' . cnFunction::escAttributeDeep($class) . '">' . PHP_EOL;
     if (empty($terms)) {
         $out .= '<li class="cat-item-none">' . $atts['show_option_none'] . '</li>';
     } else {
         if (cnQuery::getVar('cn-cat-slug')) {
             $slug = explode('/', cnQuery::getVar('cn-cat-slug'));
             // If the category slug is a descendant, use the last slug from the URL for the query.
             $atts['current_category'] = end($slug);
         } elseif ($catIDs = cnQuery::getVar('cn-cat')) {
             if (is_array($catIDs)) {
                 // If value is a string, strip the white space and covert to an array.
                 $catIDs = wp_parse_id_list($catIDs);
                 // Use the first element
                 $atts['current_category'] = reset($catIDs);
             } else {
                 $atts['current_category'] = $catIDs;
             }
         } else {
             $atts['current_category'] = 0;
         }
         if (!empty($atts['show_option_all'])) {
             $out .= '<li class="cat-item-all"><a href="' . cnURL::permalink(array('type' => 'home', 'data' => 'url', 'return' => TRUE)) . '">' . $atts['show_option_all'] . '</a></li>';
         }
         $out .= $walker->walk($terms, $atts['depth'], $atts);
     }
     $out .= '</ul>' . PHP_EOL;
     if ($atts['return']) {
         return $out;
     }
     echo $out;
 }
 /**
  * Checks the requested URL for Connections' query vars and if found rewrites the URL
  * and passes the new URL back to finish being processed by the redirect_canonical() function.
  *
  * Hooks into the redirect_canonical filter.
  *
  * @access private
  * @since 0.7.3.2
  * @uses cnQuery::getVar()
  * @uses remove_query_arg()
  * @uses user_trailingslashit()
  * @param string  $redirectURL
  * @param string  $requestedURL
  * @return string
  */
 public function canonicalRedirectFilter($redirectURL, $requestedURL)
 {
     $originalURL = $redirectURL;
     $parsedURL = @parse_url($requestedURL);
     $redirectURL = explode('?', $redirectURL);
     $redirectURL = $redirectURL[0];
     // Ensure array index is set, prevent PHP error notice.
     if (!isset($parsedURL['query'])) {
         $parsedURL['query'] = '';
     }
     // If paged, append pagination
     if (cnQuery::getVar('cn-pg')) {
         $page = (int) cnQuery::getVar('cn-pg');
         $parsedURL['query'] = remove_query_arg('cn-pg', $parsedURL['query']);
         if ($page > 1 && !stripos($redirectURL, "pg/{$page}")) {
             $redirectURL .= user_trailingslashit("pg/{$page}", 'page');
         }
         // var_dump( $redirectURL );
         // exit();
     }
     // Add back on to the URL any remaining query string values.
     $parsedURL['query'] = preg_replace('#^\\??&*?#', '', $parsedURL['query']);
     if ($redirectURL && !empty($parsedURL['query'])) {
         parse_str($parsedURL['query'], $_parsed_query);
         $_parsed_query = array_map('rawurlencode', $_parsed_query);
         $redirectURL = add_query_arg($_parsed_query, $redirectURL);
     }
     return $redirectURL;
 }
 /**
  * Add the entry actions to the admin bar
  *
  * @access private
  * @static
  * @since  8.2
  * @uses   cnURL::permalink()
  * @uses   current_user_can()
  * @param  $admin_bar object
  *
  * @return void
  */
 public static function adminBarMenuItems($admin_bar)
 {
     if (cnQuery::getVar('cn-entry-slug')) {
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         $entry = $instance->retrieve->entries(array('slug' => rawurldecode(cnQuery::getVar('cn-entry-slug')), 'status' => 'approved,pending'));
         // Make sure an entry is returned and if not, return $title unaltered.
         if (empty($entry)) {
             return;
         }
         // preg_match( '/href="(.*?)"/', cnURL::permalink( array( 'slug' => $entry->slug, 'return' => TRUE ) ), $matches );
         // $permalink = $matches[1];
         if (current_user_can('connections_manage') && current_user_can('connections_view_menu') && (current_user_can('connections_edit_entry_moderated') || current_user_can('connections_edit_entry'))) {
             $admin_bar->add_node(array('parent' => FALSE, 'id' => 'cn-edit-entry', 'title' => __('Edit Entry', 'connections'), 'href' => admin_url(wp_nonce_url('admin.php?page=connections_manage&cn-action=edit_entry&id=' . $entry[0]->id, 'entry_edit_' . $entry[0]->id)), 'meta' => array('title' => __('Edit Entry', 'connections'))));
         }
     }
 }
 /**
  * Parses a TimThumb compatible URL via the CN_IMAGE_ENDPOINT root rewrite endpoint
  * and stream the image to the browser with the correct headers for the image type being served.
  *
  * Streams an image resource to the browser or a error message.
  *
  * @access private
  * @since  8.1
  * @static
  *
  * @uses   cnQuery::getVar()
  * @uses   path_is_absolute()
  * @uses   cnColor::rgb2hex2rgb()
  * @uses   self::get()
  * @uses   is_wp_error()
  */
 public static function query()
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     if (cnQuery::getVar(CN_IMAGE_ENDPOINT)) {
         if (path_is_absolute(cnQuery::getVar('src'))) {
             header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
             echo '<h1>ERROR/s:</h1><ul><li>Source is file path. Source must be a local file URL.</li></ul>';
             exit;
         }
         $atts = array();
         if (cnQuery::getVar('cn-entry-slug')) {
             $sql = $wpdb->prepare('SELECT slug FROM ' . CN_ENTRY_TABLE . ' WHERE slug=%s', cnQuery::getVar('cn-entry-slug'));
             $result = $wpdb->get_var($sql);
             if (is_null($result)) {
                 header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
                 echo '<h1>ERROR/s:</h1><ul><li>Cheating?</li></ul>';
                 exit;
             } else {
                 $atts['sub_dir'] = $result;
             }
         }
         if (cnQuery::getVar('w')) {
             $atts['width'] = cnQuery::getVar('w');
         }
         if (cnQuery::getVar('h')) {
             $atts['height'] = cnQuery::getVar('h');
         }
         if (cnQuery::getVar('zc') || cnQuery::getVar('zc') === '0') {
             $atts['crop_mode'] = cnQuery::getVar('zc');
         }
         if (cnQuery::getVar('a')) {
             $atts['crop_focus'] = array('center', 'center');
             if (strpos(cnQuery::getVar('a'), 't') !== FALSE) {
                 $atts['crop_focus'][1] = 'top';
             }
             if (strpos(cnQuery::getVar('a'), 'r') !== FALSE) {
                 $atts['crop_focus'][0] = 'right';
             }
             if (strpos(cnQuery::getVar('a'), 'b') !== FALSE) {
                 $atts['crop_focus'][1] = 'bottom';
             }
             if (strpos(cnQuery::getVar('a'), 'l') !== FALSE) {
                 $atts['crop_focus'][0] = 'left';
             }
             $atts['crop_focus'] = implode(',', $atts['crop_focus']);
         }
         if (cnQuery::getVar('f')) {
             $filters = explode('|', cnQuery::getVar('f'));
             foreach ($filters as $filter) {
                 $param = explode(',', $filter);
                 for ($i = 0; $i < 4; $i++) {
                     if (!isset($param[$i])) {
                         $param[$i] = NULL;
                     } else {
                         $param[$i] = $param[$i];
                     }
                 }
                 switch ($param[0]) {
                     case '1':
                         $atts['negate'] = TRUE;
                         break;
                     case '2':
                         $atts['grayscale'] = TRUE;
                         break;
                     case '3':
                         $atts['brightness'] = $param[1];
                         break;
                     case '4':
                         $atts['contrast'] = $param[1];
                         break;
                     case '5':
                         $atts['colorize'] = cnColor::rgb2hex2rgb($param[1] . ',' . $param[2] . ',' . $param[3]);
                         break;
                     case '6':
                         $atts['detect_edges'] = TRUE;
                         break;
                     case '7':
                         $atts['emboss'] = TRUE;
                         break;
                     case '8':
                         $atts['gaussian_blur'] = TRUE;
                         break;
                     case '9':
                         $atts['blur'] = TRUE;
                         break;
                     case '10':
                         $atts['sketchy'] = TRUE;
                         break;
                     case '11':
                         $atts['smooth'] = $param[1];
                 }
             }
         }
         if (cnQuery::getVar('s') && cnQuery::getVar('s') === '1') {
             $atts['sharpen'] = TRUE;
         }
         if (cnQuery::getVar('o')) {
             $atts['opacity'] = cnQuery::getVar('o');
         }
         if (cnQuery::getVar('q')) {
             $atts['quality'] = cnQuery::getVar('q');
         }
         if (cnQuery::getVar('cc')) {
             $atts['canvas_color'] = cnQuery::getVar('cc');
         }
         // This needs to be set after the `cc` query var because it should override any value set using the `cc` query var, just like TimThumb.
         if (cnQuery::getVar('ct') && cnQuery::getVar('ct') === '1') {
             $atts['canvas_color'] = 'transparent';
         }
         // Process the image.
         $image = self::get(cnQuery::getVar('src'), $atts, 'editor');
         // If there been an error
         if (is_wp_error($image)) {
             $errors = implode('</li><li>', $image->get_error_messages());
             // Display the error messages.
             header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
             echo '<h1>ERROR/s:</h1><ul><li>' . wp_kses_post($errors) . '</li></ul>';
             exit;
         }
         // Ensure a stream quality is set otherwise we get a block mess as an image when serving a cached image.
         $quality = cnQuery::getVar('q') ? cnQuery::getVar('q') : 90;
         // Ensure valid value for $quality. If invalid valid is supplied reset to the default of 90, matching WP core.
         if (filter_var((int) $quality, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 100))) === FALSE) {
             $quality = 90;
         }
         $image->set_quality($quality);
         $image->stream();
         exit;
     }
 }
    /**
     *
     * The $atts['meta_query'] can have two different structures when passed to
     * @see cnMeta_Query::parse_query_vars(), they are:
     *
     * array(
     *     'meta_key'     => (string),
     *     'meta_value    => (string|array),
     *     'meta_type     => (string),
     *     'meta_compare' => (string)
     * )
     *
     * OR
     *
     * array(
     *     'meta_query' =>
     *         array(
     *             'key'     => (string),
     *             'value'   => (string|array),
     *             'compare' => (string),
     *             'type'    => (string)
     *         ),
     *         [array(...),]
     * )
     *
     * The later, 'meta_query', can have multiple arrays.
     *
     * @access public
     * @since unknown
     * @version 1.0
     * @param array
     * @return array
     */
    public function entries($atts = array())
    {
        /** @var $wpdb wpdb */
        global $wpdb;
        // Grab an instance of the Connections object.
        $instance = Connections_Directory();
        $select[] = CN_ENTRY_TABLE . '.*';
        $from[] = CN_ENTRY_TABLE;
        $join = array();
        $where[] = 'WHERE 1=1';
        $having = array();
        $orderBy = array();
        $random = FALSE;
        $visibility = array();
        /*
         * // START -- Set the default attributes array. \\
         */
        $defaults['list_type'] = NULL;
        $defaults['category'] = NULL;
        $defaults['category_in'] = NULL;
        $defaults['exclude_category'] = NULL;
        $defaults['category_name'] = NULL;
        $defaults['category_slug'] = NULL;
        $defaults['wp_current_category'] = FALSE;
        $defaults['char'] = '';
        $defaults['id'] = NULL;
        $defaults['slug'] = NULL;
        $defaults['family_name'] = NULL;
        $defaults['last_name'] = NULL;
        $defaults['title'] = NULL;
        $defaults['organization'] = NULL;
        $defaults['department'] = NULL;
        $defaults['district'] = NULL;
        $defaults['county'] = NULL;
        $defaults['city'] = NULL;
        $defaults['state'] = NULL;
        $defaults['zip_code'] = NULL;
        $defaults['country'] = NULL;
        $defaults['visibility'] = NULL;
        $defaults['status'] = array('approved');
        $defaults['order_by'] = array('sort_column', 'last_name', 'first_name');
        $defaults['limit'] = NULL;
        $defaults['offset'] = 0;
        $defaults['meta_query'] = array();
        $defaults['allow_public_override'] = FALSE;
        $defaults['private_override'] = FALSE;
        $defaults['search_terms'] = NULL;
        // $atts vars to support showing entries within a specified radius.
        $defaults['near_addr'] = NULL;
        $defaults['latitude'] = NULL;
        $defaults['longitude'] = NULL;
        $defaults['radius'] = 10;
        $defaults['unit'] = 'mi';
        $defaults['lock'] = FALSE;
        $atts = cnSanitize::args($atts, $defaults);
        /*
         * // END -- Set the default attributes array if not supplied. \\
         */
        /*
         * // START -- Process the query vars. \\
         * NOTE: these will override any values supplied via $atts, which include via the shortcode.
         */
        if ((defined('DOING_AJAX') && DOING_AJAX || !is_admin()) && !$atts['lock']) {
            // Category slug
            $queryCategorySlug = cnQuery::getVar('cn-cat-slug');
            if (!empty($queryCategorySlug)) {
                // If the category slug is a descendant, use the last slug from the URL for the query.
                $queryCategorySlug = explode('/', $queryCategorySlug);
                if (isset($queryCategorySlug[count($queryCategorySlug) - 1])) {
                    $atts['category_slug'] = $queryCategorySlug[count($queryCategorySlug) - 1];
                }
            }
            // Category ID
            $queryCategoryID = cnQuery::getVar('cn-cat');
            if (!empty($queryCategoryID)) {
                $atts['category'] = $queryCategoryID;
            }
            // Category in
            $queryCategoryIn = cnQuery::getVar('cn-cat-in');
            if (!empty($queryCategoryIn)) {
                $atts['category_in'] = cnQuery::getVar('cn-cat-in');
            }
            // Country
            $queryCountry = cnQuery::getVar('cn-country');
            if (!empty($queryCountry)) {
                $atts['country'] = urldecode($queryCountry);
            }
            // Postal Code
            $queryPostalCode = cnQuery::getVar('cn-postal-code');
            if (!empty($queryPostalCode)) {
                $atts['zip_code'] = urldecode($queryPostalCode);
            }
            // Region [State]
            $queryRegion = cnQuery::getVar('cn-region');
            if (!empty($queryRegion)) {
                $atts['state'] = urldecode($queryRegion);
            }
            // Locality [City]
            $queryLocality = cnQuery::getVar('cn-locality');
            if (!empty($queryLocality)) {
                $atts['city'] = urldecode($queryLocality);
            }
            // County
            $queryCounty = cnQuery::getVar('cn-county');
            if (!empty($queryCounty)) {
                $atts['county'] = urldecode($queryCounty);
            }
            // District
            $queryDistrict = cnQuery::getVar('cn-district');
            if (!empty($queryDistrict)) {
                $atts['district'] = urldecode($queryDistrict);
            }
            // Organization
            $queryOrganization = cnQuery::getVar('cn-organization');
            if (!empty($queryOrganization)) {
                $atts['organization'] = urldecode($queryOrganization);
            }
            // Department
            $queryDeparment = cnQuery::getVar('cn-department');
            if (!empty($queryDeparment)) {
                $atts['department'] = urldecode($queryDeparment);
            }
            // Entry slug
            // NOTE: The entry slug is saved in the DB URL encoded, so there's no need to urldecode().
            $queryEntrySlug = cnQuery::getVar('cn-entry-slug');
            if (!empty($queryEntrySlug)) {
                $atts['slug'] = $queryEntrySlug;
            }
            // Initial character.
            $queryInitialChar = cnQuery::getVar('cn-char');
            if (!empty($queryInitialChar)) {
                $atts['char'] = urldecode($queryInitialChar);
            }
            // Pagination
            $queryPage = cnQuery::getVar('cn-pg');
            $atts['offset'] = !empty($queryPage) ? ($queryPage - 1) * $atts['limit'] : $atts['offset'];
            $atts['offset'] = $atts['offset'] > 0 ? $atts['offset'] : NULL;
            // Search terms
            $searchTerms = cnQuery::getVar('cn-s');
            if (!empty($searchTerms)) {
                $atts['search_terms'] = $searchTerms;
            }
            // Geo-location
            $queryCoord = cnQuery::getVar('cn-near-coord');
            if (!empty($queryCoord)) {
                $queryCoord = explode(',', $queryCoord);
                $atts['latitude'] = $wpdb->prepare('%f', $queryCoord[0]);
                $atts['longitude'] = $wpdb->prepare('%f', $queryCoord[1]);
                // Get the radius, otherwise the default of 10.
                if (cnQuery::getVar('cn-radius')) {
                    $atts['radius'] = $wpdb->prepare('%d', cnQuery::getVar('cn-radius'));
                }
                // Sanitize and set the unit.
                $atts['unit'] = cnQuery::getVar('cn-unit') ? sanitize_key(cnQuery::getVar('cn-unit')) : sanitize_key($atts['unit']);
            }
        }
        /*
         * // END -- Process the query vars. \\
         */
        /*
         * // START -- Reset some of the $atts based if category_slug or entry slug
         * is being used. This is done to prevent query conflicts. This should be safe because
         * if a specific entry or category is being queried the other $atts can be discarded.
         * This has to be done in order to reconcile values passed via the shortcode and the
         * query string values.
         *
         * @TODO I know there are more scenarios to consider ... but this is all I can think of at the moment.
         * Thought --- maybe resetting to the default $atts should be done --- something to consider.
         */
        if (!empty($atts['slug']) || !empty($atts['category_slug'])) {
            $atts['list_type'] = NULL;
            $atts['category'] = NULL;
            $atts['category_in'] = NULL;
            $atts['category_exclude'] = NULL;
            $atts['wp_current_category'] = NULL;
        }
        if (!empty($atts['slug'])) {
            $atts['near_addr'] = NULL;
            $atts['latitude'] = NULL;
            $atts['longitude'] = NULL;
            $atts['radius'] = 10;
            $atts['unit'] = 'mi';
        }
        /*
         * // END -- Reset.
         */
        /*
         * If in a post get the category names assigned to the post.
         */
        if ($atts['wp_current_category'] && !is_page()) {
            // Get the current post categories.
            $wpCategories = get_the_category();
            // Build an array of the post categories.
            foreach ($wpCategories as $wpCategory) {
                $categoryNames[] = $wpdb->prepare('%s', $wpCategory->cat_name);
            }
        }
        /*
         * Build and array of the supplied category names and their children.
         */
        if (!empty($atts['category_name'])) {
            cnFunction::parseStringList($atts['category_name'], ',');
            foreach ($atts['category_name'] as $categoryName) {
                // Add the parent category to the array and remove any whitespace from the beginning/end of the name just in case the user added it when using the shortcode.
                $categoryNames[] = $wpdb->prepare('%s', htmlspecialchars($categoryName));
                // Retrieve the children categories
                $results = $this->categoryChildren('name', $categoryName);
                foreach ((array) $results as $term) {
                    // Only add the name if it doesn't already exist. If it doesn't sanitize and add to the array.
                    if (!in_array($term->name, $categoryNames)) {
                        $categoryNames[] = $wpdb->prepare('%s', $term->name);
                    }
                }
            }
        }
        /*
         * Build and array of the supplied category slugs and their children.
         */
        if (!empty($atts['category_slug'])) {
            $categorySlugs = array();
            cnFunction::parseStringList($atts['category_slug'], ',');
            foreach ($atts['category_slug'] as $categorySlug) {
                // Add the parent category to the array and remove any whitespace from the beginning/end of the name in case the user added it when using the shortcode.
                $categorySlugs[] = sanitize_title($categorySlug);
                // Retrieve the children categories.
                $results = $this->categoryChildren('slug', $categorySlug);
                foreach ((array) $results as $term) {
                    // Only add the slug if it doesn't already exist. If it doesn't sanitize and add to the array.
                    if (!in_array($term->name, $categorySlugs)) {
                        $categorySlugs[] = sanitize_title($term->slug);
                    }
                }
            }
        }
        /*
         * Build an array of all the categories and their children based on the supplied category IDs.
         */
        if (!empty($atts['category'])) {
            $categoryIDs = array();
            $atts['category'] = wp_parse_id_list($atts['category']);
            foreach ($atts['category'] as $categoryID) {
                // Add the parent category ID to the array.
                $categoryIDs[] = absint($categoryID);
                // Retrieve the children categories
                $termChildren = cnTerm::children($categoryID, 'category');
                if (!is_a($termChildren, 'WP_Error') && !empty($termChildren)) {
                    $categoryIDs = array_merge($categoryIDs, $termChildren);
                }
            }
        }
        /*
         * Exclude the specified categories by ID.
         */
        if (!empty($atts['exclude_category'])) {
            if (!isset($categoryIDs)) {
                $categoryIDs = array();
            }
            $categoryExcludeIDs = array();
            $atts['exclude_category'] = wp_parse_id_list($atts['exclude_category']);
            $categoryIDs = array_diff($categoryIDs, $atts['exclude_category']);
            foreach ($atts['exclude_category'] as $categoryID) {
                // Add the parent category ID to the array.
                $categoryExcludeIDs[] = absint($categoryID);
                // Retrieve the children categories
                $termChildren = cnTerm::children($categoryID, 'category');
                if (!is_a($termChildren, 'WP_Error') && !empty($termChildren)) {
                    $categoryExcludeIDs = array_merge($categoryExcludeIDs, $termChildren);
                }
            }
            $atts['exclude_category'] = array_unique($categoryExcludeIDs);
            $sql = 'SELECT tr.entry_id FROM ' . CN_TERM_RELATIONSHIP_TABLE . ' AS tr
					INNER JOIN ' . CN_TERM_TAXONOMY_TABLE . ' AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
					WHERE 1=1 AND tt.term_id IN (' . implode(", ", $atts['exclude_category']) . ')';
            // Store the entryIDs that are to be excluded.
            $results = $wpdb->get_col($sql);
            //print_r($results);
            if (!empty($results)) {
                $where[] = 'AND ' . CN_ENTRY_TABLE . '.id NOT IN (' . implode(", ", $results) . ')';
            }
        }
        // Convert the supplied category IDs $atts['category_in'] to an array.
        if (!empty($atts['category_in'])) {
            $atts['category_in'] = wp_parse_id_list($atts['category_in']);
            // Remove empty values from the array.
            $atts['category_in'] = array_filter($atts['category_in']);
            // Ensure there is something to query after filtering the array.
            if (!empty($atts['category_in'])) {
                // Exclude any category IDs that may have been set.
                $atts['category_in'] = array_diff($atts['category_in'], (array) $atts['exclude_category']);
                // Build the query to retrieve entry IDs that are assigned to all the supplied category IDs; operational AND.
                $sql = 'SELECT DISTINCT tr.entry_id FROM ' . CN_TERM_RELATIONSHIP_TABLE . ' AS tr
						INNER JOIN ' . CN_TERM_TAXONOMY_TABLE . ' AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
						WHERE 1=1 AND tt.term_id IN (' . implode(", ", $atts['category_in']) . ') GROUP BY tr.entry_id HAVING COUNT(*) = ' . count($atts['category_in']) . ' ORDER BY tr.entry_id';
                // Store the entryIDs that exist on all of the supplied category IDs
                $results = $wpdb->get_col($sql);
                //print_r($results);
                if (!empty($results)) {
                    $where[] = 'AND ' . CN_ENTRY_TABLE . '.id IN (' . implode(", ", $results) . ')';
                } else {
                    $where[] = 'AND 1=2';
                }
            }
            /*
            * This is the query to use to return entry IDs that are in the same categories. The COUNT value
            * should equal the number of category IDs in the IN() statement.
            
              SELECT DISTINCT tr.entry_id FROM `wp_connections_term_relationships` AS tr
              INNER JOIN `wp_connections_term_taxonomy` AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
              WHERE 1=1 AND tt.term_id IN ('51','73','76') GROUP BY tr.entry_id HAVING COUNT(*) = 3 ORDER BY tr.entry_id
            */
        }
        if (!empty($categoryIDs) || !empty($categoryExcludeIDs) || !empty($categoryNames) || !empty($categorySlugs)) {
            // Set the query string to INNER JOIN the term relationship and taxonomy tables.
            $join[] = 'INNER JOIN ' . CN_TERM_RELATIONSHIP_TABLE . ' ON ( ' . CN_ENTRY_TABLE . '.id = ' . CN_TERM_RELATIONSHIP_TABLE . '.entry_id )';
            $join[] = 'INNER JOIN ' . CN_TERM_TAXONOMY_TABLE . ' ON ( ' . CN_TERM_RELATIONSHIP_TABLE . '.term_taxonomy_id = ' . CN_TERM_TAXONOMY_TABLE . '.term_taxonomy_id )';
            $join[] = 'INNER JOIN ' . CN_TERMS_TABLE . ' ON ( ' . CN_TERMS_TABLE . '.term_id = ' . CN_TERM_TAXONOMY_TABLE . '.term_id )';
            // Set the query string to return entries within the category taxonomy.
            $where[] = 'AND ' . CN_TERM_TAXONOMY_TABLE . '.taxonomy = \'category\'';
            if (!empty($categoryIDs)) {
                $where[] = 'AND ' . CN_TERM_TAXONOMY_TABLE . '.term_id IN (' . implode(", ", $categoryIDs) . ')';
                unset($categoryIDs);
            }
            if (!empty($categoryExcludeIDs)) {
                $where[] = 'AND ' . CN_TERM_TAXONOMY_TABLE . '.term_id NOT IN (' . implode(", ", $categoryExcludeIDs) . ')';
                unset($categoryExcludeIDs);
            }
            if (!empty($categoryNames)) {
                $where[] = 'AND ' . CN_TERMS_TABLE . '.name IN (' . implode(", ", (array) $categoryNames) . ')';
                unset($categoryNames);
            }
            if (!empty($categorySlugs)) {
                $where[] = 'AND ' . CN_TERMS_TABLE . '.slug IN (\'' . implode("', '", (array) $categorySlugs) . '\')';
                unset($categorySlugs);
            }
        }
        /*
         * // START --> Set up the query to only return the entries that match the supplied IDs.
         *    NOTE: This includes the entry IDs returned for category_in.
         */
        if (!empty($atts['id'])) {
            $atts['id'] = wp_parse_id_list($atts['id']);
            // Set query string to return specific entries.
            $where[] = 'AND ' . CN_ENTRY_TABLE . '.id IN (\'' . implode("', '", $atts['id']) . '\')';
        }
        /*
         * // END --> Set up the query to only return the entries that match the supplied IDs.
         */
        /*
         * // START --> Set up the query to only return the entries that match the supplied search terms.
         */
        if (!empty($atts['search_terms'])) {
            $searchResults = $this->search(array('terms' => $atts['search_terms']));
            //print_r($searchResults);
            // If there were no results, add a WHERE clause that will not return results when performing the whole query.
            if (empty($searchResults)) {
                $where[] = 'AND 1=2';
            } else {
                // Set $atts['order_by'] to the order the entry IDs were returned.
                // This is to support the relevancy order results being returned by self::search().
                $atts['order_by'] = 'id|SPECIFIED';
                $atts['id'] = $searchResults;
                // Set the entry IDs to be the search results.
                $where[] = 'AND ' . CN_ENTRY_TABLE . '.id IN (\'' . implode("', '", $searchResults) . '\')';
            }
        }
        /*
         * // END --> Set up the query to only return the entries that match the supplied search terms.
         */
        /*
         * // START --> Set up the query to only return the entry that matches the supplied slug.
         */
        if (!empty($atts['slug'])) {
            // Trim the white space from the ends.
            $atts['slug'] = trim($atts['slug']);
            $where[] = $wpdb->prepare('AND ' . CN_ENTRY_TABLE . '.slug = %s', $atts['slug']);
        }
        /*
         * // END --> Set up the query to only return the entry that matches the supplied slug.
         */
        /*
         * // START --> Set up the query to only return the entries that match the supplied entry type.
         */
        if (!empty($atts['list_type'])) {
            cnFunction::parseStringList($atts['list_type'], ',');
            $permittedEntryTypes = array('individual', 'organization', 'family', 'connection_group');
            // Set query string for entry type.
            if ((bool) array_intersect($atts['list_type'], $permittedEntryTypes)) {
                // Compatibility code to make sure any occurrences of the deprecated entry type connections_group
                // is changed to entry type family
                $atts['list_type'] = str_replace('connection_group', 'family', $atts['list_type']);
                $where[] = cnQuery::where(array('field' => 'entry_type', 'value' => $atts['list_type']));
            }
        }
        /*
         * // END --> Set up the query to only return the entries that match the supplied entry type.
         */
        /*
         * // START --> Set up the query to only return the entries that match the supplied filters.
         */
        $where[] = cnQuery::where(array('field' => 'family_name', 'value' => $atts['family_name']));
        $where[] = cnQuery::where(array('field' => 'last_name', 'value' => $atts['last_name']));
        $where[] = cnQuery::where(array('field' => 'title', 'value' => $atts['title']));
        $where[] = cnQuery::where(array('field' => 'organization', 'value' => $atts['organization']));
        $where[] = cnQuery::where(array('field' => 'department', 'value' => $atts['department']));
        if (!empty($atts['district']) || !empty($atts['county']) || !empty($atts['city']) || !empty($atts['state']) || !empty($atts['zip_code']) || !empty($atts['country'])) {
            if (!isset($join['address'])) {
                $join['address'] = 'INNER JOIN ' . CN_ENTRY_ADDRESS_TABLE . ' ON ( ' . CN_ENTRY_TABLE . '.id = ' . CN_ENTRY_ADDRESS_TABLE . '.entry_id )';
            }
            $where[] = cnQuery::where(array('table' => CN_ENTRY_ADDRESS_TABLE, 'field' => 'district', 'value' => $atts['district']));
            $where[] = cnQuery::where(array('table' => CN_ENTRY_ADDRESS_TABLE, 'field' => 'county', 'value' => $atts['county']));
            $where[] = cnQuery::where(array('table' => CN_ENTRY_ADDRESS_TABLE, 'field' => 'city', 'value' => $atts['city']));
            $where[] = cnQuery::where(array('table' => CN_ENTRY_ADDRESS_TABLE, 'field' => 'state', 'value' => $atts['state']));
            $where[] = cnQuery::where(array('table' => CN_ENTRY_ADDRESS_TABLE, 'field' => 'zipcode', 'value' => $atts['zip_code']));
            $where[] = cnQuery::where(array('table' => CN_ENTRY_ADDRESS_TABLE, 'field' => 'country', 'value' => $atts['country']));
        }
        if (0 < strlen($atts['char'])) {
            $having[] = $wpdb->prepare('HAVING sort_column LIKE %s', $wpdb->esc_like($atts['char']) . '%');
        }
        /*
         * // END --> Set up the query to only return the entries that match the supplied filters.
         */
        /*
         * // START --> Set up the query to only return the entries based on user permissions.
         */
        $where = self::setQueryVisibility($where, $atts);
        /*
         * // END --> Set up the query to only return the entries based on user permissions.
         */
        /*
         * // START --> Set up the query to only return the entries based on status.
         */
        $where = self::setQueryStatus($where, $atts);
        /*
         * // END --> Set up the query to only return the entries based on status.
         */
        /*
         * // START --> Geo-limit the query.
         */
        //$atts['latitude'] = 40.3663671;
        //$atts['longitude'] = -75.8876941;
        if (!empty($atts['latitude']) && !empty($atts['longitude'])) {
            $earthRadius = 6371;
            // Earth's radius in (SI) km.
            // Convert the supplied radius from the supplied unit to (SI) km.
            $atts['radius'] = cnGeo::convert(array('value' => $atts['radius'], 'from' => $atts['unit'], 'to' => 'km', 'format' => FALSE, 'return' => TRUE));
            // Limiting bounding box (in degrees).
            $minLat = $atts['latitude'] - rad2deg($atts['radius'] / $earthRadius);
            $maxLat = $atts['latitude'] + rad2deg($atts['radius'] / $earthRadius);
            $minLng = $atts['longitude'] - rad2deg($atts['radius'] / $earthRadius / cos(deg2rad($atts['latitude'])));
            $maxLng = $atts['longitude'] + rad2deg($atts['radius'] / $earthRadius / cos(deg2rad($atts['latitude'])));
            // Convert origin of geographic circle to radians.
            $atts['latitude'] = deg2rad($atts['latitude']);
            $atts['longitude'] = deg2rad($atts['longitude']);
            // Add the SELECT statement that adds the `radius` column.
            $select[] = $wpdb->prepare('acos(sin(%f)*sin(radians(latitude)) + cos(%f)*cos(radians(latitude))*cos(radians(longitude)-%f))*6371 AS distance', $atts['latitude'], $atts['latitude'], $atts['longitude']);
            // Create a subquery that will limit the rows that have the cosine law applied to within the bounding box.
            $geoSubselect = $wpdb->prepare('(SELECT entry_id FROM ' . CN_ENTRY_ADDRESS_TABLE . ' WHERE latitude>%f AND latitude<%f AND longitude>%f AND longitude<%f) AS geo_bound', $minLat, $maxLat, $minLng, $maxLng);
            // The subquery needs to be added to the beginning of the array so the inner joins on the other tables are joined to the CN_ENTRY_TABLE
            array_unshift($from, $geoSubselect);
            // Add the JOIN for the address table. NOTE: This JOIN is also set in the ORDER BY section. The 'address' index is to make sure it doea not get added to the query twice.
            if (!isset($join['address'])) {
                $join['address'] = 'INNER JOIN ' . CN_ENTRY_ADDRESS_TABLE . ' ON ( ' . CN_ENTRY_TABLE . '.id = ' . CN_ENTRY_ADDRESS_TABLE . '.entry_id )';
            }
            // Add the WHERE statement to limit the query to a geographic circle per the defined radius.
            $where[] = $wpdb->prepare('AND acos(sin(%f)*sin(radians(latitude)) + cos(%f)*cos(radians(latitude))*cos(radians(longitude)-%f))*6371 < %f', $atts['latitude'], $atts['latitude'], $atts['longitude'], $atts['radius']);
            // This is required otherwise addresses the user may not have permissions to view will be included in the query
            // which could be confusing since entries could appear to be outside of the search radius when in fact the entry
            // is within the search radius, it is just the address used to determine that is not viewable to the user.
            //$where[] = 'AND ' . CN_ENTRY_ADDRESS_TABLE . '.visibility IN (\'' . implode( "', '", (array) $visibility ) . '\')';
            $where = self::setQueryVisibility($where, array('table' => CN_ENTRY_ADDRESS_TABLE));
            // Temporarily set the sort order to 'radius' for testing.
            //$atts['order_by'] = array('radius');
        }
        /*
         * // END --> Geo-limit the query.
         */
        /*
         * // START --> Build the ORDER BY query segment.
         */
        //if ( empty($atts['order_by']) )
        //{
        // Setup the default sort order if none were supplied.
        //$orderBy = array('sort_column', 'last_name', 'first_name');
        //}
        //else
        //{
        $orderFields = array('id', 'date_added', 'date_modified', 'first_name', 'last_name', 'title', 'organization', 'department', 'city', 'state', 'zipcode', 'country', 'birthday', 'anniversary', 'sort_column');
        $orderFlags = array('SPECIFIED' => 'SPECIFIED', 'RANDOM' => 'RANDOM', 'ASC' => 'ASC', 'SORT_ASC' => 'ASC', 'DESC' => 'DESC', 'SORT_DESC' => 'DESC', 'NUMERIC' => '+0', 'SORT_NUMERIC' => '+0', 'SORT_NUMERIC_ASC' => '+0', 'NUMERIC_DESC' => '+0 DESC', 'SORT_NUMERIC_DESC' => '+0 DESC');
        // If a geo-bound query is being performed the `radius` order field can be used.
        if (!empty($atts['latitude']) && !empty($atts['longitude'])) {
            array_push($orderFields, 'distance');
        }
        // Get registered date types.
        $dateTypes = array_keys($instance->options->getDateOptions());
        // Convert to an array
        if (!is_array($atts['order_by'])) {
            // Trim the space characters if present.
            $atts['order_by'] = str_replace(' ', '', $atts['order_by']);
            // Build an array of each field to order by and its sort order.
            $atts['order_by'] = explode(',', $atts['order_by']);
        }
        // For each field the sort order can be defined.
        foreach ($atts['order_by'] as $orderByField) {
            $orderByAtts[] = explode('|', $orderByField);
        }
        // Build the ORDER BY query segment
        foreach ($orderByAtts as $field) {
            // Trim any spaces the user may have supplied and set it to be lowercase.
            $field[0] = strtolower(trim($field[0]));
            // Check to make sure the supplied field is one of the valid fields to order by.
            if (in_array($field[0], $orderFields) || cnString::startsWith('meta_key:', $field[0])) {
                // The date_modified actually maps to the `ts` column in the db.
                if ($field[0] == 'date_modified') {
                    $field[0] = 'ts';
                }
                // If one of the order fields is an address region add the INNER JOIN to the CN_ENTRY_ADDRESS_TABLE
                if ($field[0] == 'city' || $field[0] == 'state' || $field[0] == 'zipcode' || $field[0] == 'country') {
                    if (!isset($join['address'])) {
                        $join['address'] = 'INNER JOIN ' . CN_ENTRY_ADDRESS_TABLE . ' ON ( ' . CN_ENTRY_TABLE . '.id = ' . CN_ENTRY_ADDRESS_TABLE . '.entry_id )';
                    }
                }
                if (cnString::startsWith('meta_key:', $field[0])) {
                    // Extract the meta key name from $field[0].
                    $meta = explode(':', $field[0]);
                    // Ensure the meta key does exist and is not empty before altering the query.
                    if (isset($meta[1]) && !empty($meta[1])) {
                        $atts['meta_query']['meta_query'][] = array('key' => $meta[1]);
                        if (1 < count($atts['meta_query']['meta_query'])) {
                            $field[0] = 'mt' . (count($atts['meta_query']['meta_query']) - 1) . '.meta_value';
                        } else {
                            $field[0] = CN_ENTRY_TABLE_META . '.meta_value';
                        }
                    }
                }
                // If we're ordering by anniversary or birthday, we need to convert the string to a UNIX timestamp so it is properly ordered.
                // Otherwise, it is sorted as a string which can give some very odd results compared to what is expected.
                //if ( $field[0] == 'anniversary' || $field[0] == 'birthday' ) {
                //
                //	$field[0] = 'FROM_UNIXTIME( ' . $field[0] . ' )';
                //}
                if (in_array($field[0], $dateTypes)) {
                    if (!isset($join['date'])) {
                        $join['date'] = 'INNER JOIN ' . CN_ENTRY_DATE_TABLE . ' ON ( ' . CN_ENTRY_TABLE . '.id = ' . CN_ENTRY_DATE_TABLE . '.entry_id )';
                    }
                    $where[] = $wpdb->prepare('AND ' . CN_ENTRY_DATE_TABLE . '.type = %s', $field[0]);
                    $field[0] = 'date';
                }
                // Check to see if an order flag was set and is a valid order flag.
                if (isset($field[1])) {
                    // Trim any spaces the user might have added and change the string to uppercase..
                    $field[1] = strtoupper(trim($field[1]));
                    // If a user included a sort flag that is invalid/mis-spelled it is skipped since it can not be used.
                    if (array_key_exists($field[1], $orderFlags)) {
                        /*
                         * The SPECIFIED and RANDOM order flags are special use and should only be used with the id sort field.
                         * Set the default sort flag if it was use on any other sort field than id.
                         */
                        if (($orderFlags[$field[1]] == 'SPECIFIED' || $orderFlags[$field[1]] == 'RANDOM') && $field[0] != 'id') {
                            $field[1] = 'SORT_ASC';
                        }
                        switch ($orderFlags[$field[1]]) {
                            /*
                             * Order the results based on the order of the supplied entry IDs
                             */
                            case 'SPECIFIED':
                                if (!empty($atts['id'])) {
                                    $orderBy = array('FIELD( ' . CN_ENTRY_TABLE . '.id, ' . implode(', ', (array) $atts['id']) . ' )');
                                }
                                break;
                                /*
                                 * Randomize the order of the results.
                                 */
                            /*
                             * Randomize the order of the results.
                             */
                            case 'RANDOM':
                                $random = TRUE;
                                break;
                                /*
                                 * Return the results in ASC or DESC order.
                                 */
                            /*
                             * Return the results in ASC or DESC order.
                             */
                            default:
                                $orderBy[] = $field[0] . ' ' . $orderFlags[$field[1]];
                                break;
                        }
                    } else {
                        $orderBy[] = $field[0];
                    }
                } else {
                    $orderBy[] = $field[0];
                }
            }
        }
        //}
        if (!empty($atts['meta_query'])) {
            $metaQuery = new cnMeta_Query();
            $metaQuery->parse_query_vars($atts['meta_query']);
            $metaClause = $metaQuery->get_sql('entry', CN_ENTRY_TABLE, 'id');
            $join['meta'] = $metaClause['join'];
            $where['meta'] = $metaClause['where'];
        }
        $orderBy = empty($orderBy) ? 'ORDER BY sort_column, last_name, first_name' : 'ORDER BY ' . implode(', ', $orderBy);
        /*
         * // END --> Build the ORDER BY query segment.
         */
        /*
         * // START --> Set up the query LIMIT and OFFSET.
         */
        $limit = empty($atts['limit']) ? '' : $wpdb->prepare(' LIMIT %d ', $atts['limit']);
        $offset = empty($atts['offset']) ? '' : $wpdb->prepare(' OFFSET %d ', $atts['offset']);
        /*
         * // END --> Set up the query LIMIT and OFFSET.
         */
        /*
         * // START --> Build the SELECT query segment.
         */
        $select[] = 'CASE `entry_type`
						  WHEN \'individual\' THEN `last_name`
						  WHEN \'organization\' THEN `organization`
						  WHEN \'connection_group\' THEN `family_name`
						  WHEN \'family\' THEN `family_name`
						END AS `sort_column`';
        /*
         * // END --> Build the SELECT query segment.
         */
        $pieces = array('select', 'from', 'join', 'where', 'having', 'orderBy', 'limit', 'offset');
        /**
         * Filter the query SQL clauses.
         *
         * @since 8.5.14
         *
         * @param array $pieces Terms query SQL clauses.
         */
        $clauses = apply_filters('cn_entry_query_clauses', compact($pieces));
        foreach ($pieces as $piece) {
            ${$piece} = isset($clauses[$piece]) ? $clauses[$piece] : '';
        }
        /**
         * NOTES:
         *
         * Many queries can produce multiple results per entry ID when we really only want it once.
         * For example an entry maybe return once for each category it is assigned or once for each
         * address an entry has that is within the search radius.
         *
         * Simply adding `GROUP BY CN_ENTRY_TABLE.id seems to fix this, but may be incorrect and might fail
         * on db/s other than MySQL such as Oracle.
         *
         * Very useful links that provide more details that require further study:
         *
         * @link http://www.psce.com/blog/2012/05/15/mysql-mistakes-do-you-use-group-by-correctly/
         * @link http://rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html
         */
        if ($random) {
            $seed = cnFormatting::stripNonNumeric(cnUtility::getIP()) . date('Hdm', current_time('timestamp', 1));
            $sql = 'SELECT SQL_CALC_FOUND_ROWS *, RAND(' . $seed . ') AS random FROM ( SELECT DISTINCT ' . implode(', ', $select) . ' FROM ' . implode(', ', $from) . ' ' . implode(' ', $join) . ' ' . implode(' ', $where) . ' GROUP BY ' . CN_ENTRY_TABLE . '.id ' . implode(' ', $having) . ') AS T ORDER BY random' . $limit . $offset;
            // print_r($sql);
        } else {
            $sql = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT ' . implode(', ', $select) . ' FROM ' . implode(', ', $from) . ' ' . implode(' ', $join) . ' ' . implode(' ', $where) . ' GROUP BY ' . CN_ENTRY_TABLE . '.id ' . implode(' ', $having) . ' ' . $orderBy . ' ' . $limit . $offset;
            // print_r($sql);
        }
        if (!($results = $this->results($sql))) {
            $results = $wpdb->get_results($sql);
            $this->cache($sql, $results);
            // The most recent query to have been executed by cnRetrieve::entries
            $instance->lastQuery = $wpdb->last_query;
            // The most recent query error to have been generated by cnRetrieve::entries
            $instance->lastQueryError = $wpdb->last_error;
            // ID generated for an AUTO_INCREMENT column by the most recent INSERT query.
            $instance->lastInsertID = $wpdb->insert_id;
            // The number of rows returned by the last query.
            $instance->resultCount = $wpdb->num_rows;
            // The number of rows returned by the last query without the limit clause set
            $foundRows = $wpdb->get_results('SELECT FOUND_ROWS()');
            $instance->resultCountNoLimit = $foundRows[0]->{'FOUND_ROWS()'};
            $this->resultCountNoLimit = $foundRows[0]->{'FOUND_ROWS()'};
        }
        // The total number of entries based on user permissions.
        // $instance->recordCount         = self::recordCount( array( 'public_override' => $atts['allow_public_override'], 'private_override' => $atts['private_override'] ) );
        // The total number of entries based on user permissions with the status set to 'pending'
        // $instance->recordCountPending  = self::recordCount( array( 'public_override' => $atts['allow_public_override'], 'private_override' => $atts['private_override'], 'status' => array( 'pending' ) ) );
        // The total number of entries based on user permissions with the status set to 'approved'
        // $instance->recordCountApproved = self::recordCount( array( 'public_override' => $atts['allow_public_override'], 'private_override' => $atts['private_override'], 'status' => array( 'approved' ) ) );
        /*
         * ONLY in the admin.
         *
         * Reset the pagination filter for the current user, remove the offset from the query and re-run the
         * query if the offset for the query is greater than the record count with no limit set in the query.
         *
         */
        if (is_admin() && $atts['offset'] > $instance->resultCountNoLimit) {
            $instance->currentUser->resetFilterPage('manage');
            unset($atts['offset']);
            $results = $this->entries($atts);
        } elseif ($atts['offset'] > $instance->resultCountNoLimit) {
            /*
             * This is for the front end, reset the page and offset and re-run the query if the offset
             * is greater than the record count with no limit.
             *
             * @TODO  this should somehow be precessed in the parse_request action hook so the URL
             * permalink and query vars can be properly updated.
             */
            set_query_var('cn-pg', 0);
            $atts['offset'] = 0;
            $results = $this->entries($atts);
        }
        return $results;
    }
 public static function download()
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $process = cnQuery::getVar('cn-process');
     $token = cnQuery::getVar('cn-token');
     $id = absint(cnQuery::getVar('cn-id'));
     if ('vcard' === $process) {
         $slug = cnQuery::getVar('cn-entry-slug');
         //var_dump($slug);
         /*
          * If the token and id values were set, the link was likely from the admin.
          * Check for those values and validate the token. The primary reason for this
          * to be able to download vCards of entries that are set to "Unlisted".
          */
         if (!empty($id) && !empty($token)) {
             if (!wp_verify_nonce($token, 'download_vcard_' . $id)) {
                 wp_die('Invalid vCard Token');
             }
             $entry = $instance->retrieve->entry($id);
             // Die if no entry was found.
             if (empty($entry)) {
                 wp_die(__('vCard not available for download.', 'connections'));
             }
             $vCard = new cnvCard($entry);
             //var_dump($vCard);die;
         } else {
             $entry = $instance->retrieve->entries(array('slug' => $slug));
             //var_dump($entry);die;
             // Die if no entry was found.
             if (empty($entry)) {
                 wp_die(__('vCard not available for download.', 'connections'));
             }
             $vCard = new cnvCard($entry[0]);
             //var_dump($vCard);die;
         }
         $filename = sanitize_file_name($vCard->getName());
         //var_dump($filename);
         $data = $vCard->getvCard();
         //var_dump($data);die;
         header('Content-Description: File Transfer');
         header('Content-Type: application/octet-stream');
         header('Content-Disposition: attachment; filename=' . $filename . '.vcf');
         header('Content-Length: ' . strlen($data));
         header('Pragma: public');
         header("Pragma: no-cache");
         //header( "Expires: 0" );
         header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
         header('Cache-Control: private');
         // header( 'Connection: close' );
         //ob_clean();
         flush();
         echo $data;
         exit;
     }
 }
 /**
  * Run the actions registered to custom content blocks.
  *
  * Render any custom content blocks registered to the `cn_entry_output_content-{id}` action hook.
  *
  * This will also run any actions registered for a custom metaboxes and its fields.
  * The actions should hook into `cn_output_meta_field-{key}` to be rendered.
  *
  * Accepted option for the $atts property are:
  * 	id (string) The custom block ID to render.
  * 	order (mixed) array | string  An indexed array of custom content block IDs that should be rendered in the order in the array.
  * 		If a string is provided, it should be a comma delimited string containing the content block IDs. It will be converted to an array.
  * 	exclude (array) An indexed array of custom content block IDs that should be excluded from being rendered.
  * 	include (array) An indexed array of custom content block IDs that should be rendered.
  * 		NOTE: Custom content block IDs in `exclude` outweigh custom content block IDs in include. Meaning if the
  * 		same custom content block ID exists in both, the custom content block will be excluded.
  *
  * @access public
  * @since 0.8
  * @uses do_action()
  * @uses wp_parse_args()
  * @uses apply_filters()
  * @uses has_action()
  * @param  mixed  $atts array | string [optional] The custom content block(s) to render.
  * @param  array  $shortcode_atts [optional] If this is used within the shortcode template loop, the shortcode atts
  * 		should be passed so the shortcode atts can be passed by do_action() to allow access to the action callback.
  * @param  cnTemplate|null $template [optional] If this is used within the shortcode template loop, the template object
  * 		should be passed so the template object can be passed by do_action() to allow access to the action callback.
  *
  * @return string The HTML output of the custom content blocks.
  */
 public function getContentBlock($atts = array(), $shortcode_atts = array(), $template = NULL)
 {
     $blockContainerContent = '';
     if (cnQuery::getVar('cn-entry-slug')) {
         $settings = cnSettingsAPI::get('connections', 'connections_display_single', 'content_block');
     } else {
         $settings = cnSettingsAPI::get('connections', 'connections_display_list', 'content_block');
     }
     $order = isset($settings['order']) ? $settings['order'] : array();
     $include = isset($settings['active']) ? $settings['active'] : array();
     $exclude = empty($include) ? $order : array();
     $titles = array();
     $defaults = array('id' => '', 'order' => is_string($atts) && !empty($atts) ? $atts : $order, 'exclude' => is_string($atts) && !empty($atts) ? '' : $exclude, 'include' => is_string($atts) && !empty($atts) ? '' : $include, 'layout' => 'list', 'container_tag' => 'div', 'block_tag' => 'div', 'header_tag' => 'h3', 'before' => '', 'after' => '', 'return' => FALSE);
     $atts = wp_parse_args(apply_filters('cn_output_content_block_atts', $atts), $defaults);
     if (!empty($atts['id'])) {
         $blocks = array($atts['id']);
     } elseif (!empty($atts['order'])) {
         $blocks = cnFunction::parseStringList($atts['order'], ',');
     }
     // Nothing to render, exit.
     if (empty($blocks)) {
         return '';
     }
     // Cleanup user input. Trim whitespace and convert to lowercase.
     $blocks = array_map('strtolower', array_map('trim', $blocks));
     // Output the registered action in the order supplied by the user.
     foreach ($blocks as $key) {
         isset($blockNumber) ? $blockNumber++ : ($blockNumber = 1);
         // Exclude/Include the metaboxes that have been requested to exclude/include.
         if (!empty($atts['exclude'])) {
             if (in_array($key, $atts['exclude'])) {
                 continue;
             }
         } else {
             if (!empty($atts['include'])) {
                 if (!in_array($key, $atts['include'])) {
                     continue;
                 }
             }
         }
         ob_start();
         // If the hook has a registered meta data output callback registered, lets run it.
         if (has_action('cn_output_meta_field-' . $key)) {
             // Grab the meta.
             $results = $this->getMeta(array('key' => $key, 'single' => TRUE));
             if (!empty($results)) {
                 do_action("cn_output_meta_field-{$key}", $key, $results, $this, $shortcode_atts, $template);
             }
         }
         // Render the "Custom Fields" meta block content.
         if ('meta' == $key) {
             $this->getMetaBlock(array(), $shortcode_atts, $template);
         }
         $hook = "cn_entry_output_content-{$key}";
         if (has_action($hook)) {
             do_action($hook, $this, $shortcode_atts, $template);
         }
         $blockContent = ob_get_clean();
         if (empty($blockContent)) {
             continue;
         }
         $blockID = $this->getSlug() . '-' . $blockNumber;
         // Store the title in an array that can be accessed/passed from outside the content block loop.
         // And if there is no title for some reason, create one from the key.
         if ($name = cnOptions::getContentBlocks($key)) {
             $titles[$blockID] = $name;
         } elseif ($name = cnOptions::getContentBlocks($key, 'single')) {
             $titles[$blockID] = $name;
         } else {
             $titles[$blockID] = ucwords(str_replace(array('-', '_'), ' ', $key));
         }
         //$titles[ $blockID ] = cnOptions::getContentBlocks( $key ) ? cnOptions::getContentBlocks( $key ) : ucwords( str_replace( array( '-', '_' ), ' ', $key ) );
         $blockContainerContent .= apply_filters('cn_entry_output_content_block', sprintf('<%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, sprintf('<%1$s>%2$s</%1$s>', $atts['header_tag'], $titles[$blockID]), $atts['block_tag'], $key, $blockID, $blockContent), $this, $key, $blockID, $titles[$blockID], $blockContent, $atts, $shortcode_atts);
     }
     if (empty($blockContainerContent)) {
         return '';
     }
     $out = apply_filters('cn_entry_output_content_block_container', sprintf('<%1$s class="cn-entry-content-block-%2$s">%3$s</%1$s>' . PHP_EOL, $atts['container_tag'], $atts['layout'], $blockContainerContent), $this, $blockContainerContent, $titles, $atts, $shortcode_atts);
     $out = $atts['before'] . $out . $atts['after'] . PHP_EOL;
     return $this->echoOrReturn($atts['return'], $out);
 }
 /**
  * Display results based on query var `cn-view`.
  *
  * @access public
  * @since  0.7.3
  * @static
  *
  * @uses   cnQuery::getVar()
  *
  * @param array  $atts
  * @param string $content [optional]
  * @param string $tag
  *
  * @return string
  */
 public static function view($atts, $content = '', $tag = 'connections')
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     /*$getAllowPublic = $instance->options->getAllowPublic();
     		var_dump($getAllowPublic);
     		$getAllowPublicOverride = $instance->options->getAllowPublicOverride();
     		var_dump($getAllowPublicOverride);
     		$getAllowPrivateOverride = $instance->options->getAllowPrivateOverride();
     		var_dump($getAllowPrivateOverride);*/
     /*
      * Only show this message under the following condition:
      * - ( The user is not logged in AND the 'Login Required' is checked ) AND ( neither of the shortcode visibility overrides are enabled ).
      */
     if (!is_user_logged_in() && !$instance->options->getAllowPublic() && !($instance->options->getAllowPublicOverride() || $instance->options->getAllowPrivateOverride())) {
         $message = $instance->settings->get('connections', 'connections_login', 'message');
         // Format and texturize the message.
         $message = wptexturize(wpautop($message));
         // Make any links and such clickable.
         $message = make_clickable($message);
         // Apply the shortcodes.
         $message = do_shortcode($message);
         return $message;
     }
     $view = cnQuery::getVar('cn-view');
     switch ($view) {
         case 'submit':
             if (has_action('cn_submit_entry_form')) {
                 ob_start();
                 /**
                  * @todo There s/b capability checks just like when editing an entry so users can only submit when they have the permissions.
                  */
                 do_action('cn_submit_entry_form', $atts, $content, $tag);
                 return ob_get_clean();
             } else {
                 return '<p>' . __('Future home of front end submissions.', 'connections') . '</p>';
             }
             break;
         case 'landing':
             return '<p>' . __('Future home of the landing pages, such a list of categories.', 'connections') . '</p>';
             break;
         case 'search':
             if (has_action('cn_submit_search_form')) {
                 ob_start();
                 do_action('cn_submit_search_form', $atts, $content, $tag);
                 return ob_get_clean();
             } else {
                 return '<p>' . __('Future home of the search page.', 'connections') . '</p>';
             }
             break;
         case 'results':
             if (has_action('cn_submit_search_results')) {
                 ob_start();
                 do_action('cn_submit_search_results', $atts, $content, $tag);
                 return ob_get_clean();
             } else {
                 return '<p>' . __('Future home of the search results landing page.', 'connections') . '</p>';
             }
             break;
             // Show the standard result list.
         // Show the standard result list.
         case 'card':
             return cnShortcode_Connections::shortcode($atts, $content);
             break;
             // Show the "View All" result list using the "Names" template.
         // Show the "View All" result list using the "Names" template.
         case 'all':
             // Disable the output of the repeat character index.
             $atts['repeat_alphaindex'] = FALSE;
             // Force the use of the Names template.
             $atts['template'] = 'names';
             return cnShortcode_Connections::shortcode($atts, $content);
             break;
             // Show the entry detail using a template based on the entry type.
         // Show the entry detail using a template based on the entry type.
         case 'detail':
             switch (cnQuery::getVar('cn-process')) {
                 case 'edit':
                     if (has_action('cn_edit_entry_form')) {
                         // Check to see if the entry has been linked to a user ID.
                         $entryID = get_user_meta(get_current_user_id(), 'connections_entry_id', TRUE);
                         // var_dump( $entryID );
                         $results = $instance->retrieve->entries(array('status' => 'approved,pending'));
                         // var_dump( $results );
                         /*
                          * The `cn_edit_entry_form` action should only be executed if the user is
                          * logged in and they have the `connections_manage` capability and either the
                          * `connections_edit_entry` or `connections_edit_entry_moderated` capability.
                          */
                         if (is_user_logged_in() && (current_user_can('connections_manage') || (int) $entryID == (int) $results[0]->id) && (current_user_can('connections_edit_entry') || current_user_can('connections_edit_entry_moderated'))) {
                             ob_start();
                             if (!current_user_can('connections_edit_entry') && $results[0]->status == 'pending') {
                                 echo '<p>' . __('Your entry submission is currently under review, however, you can continue to make edits to your entry submission while your submission is under review.', 'connections') . '</p>';
                             }
                             do_action('cn_edit_entry_form', $atts, $content, $tag);
                             return ob_get_clean();
                         } else {
                             return __('You are not authorized to edit entries. Please contact the admin if you received this message in error.', 'connections');
                         }
                     }
                     break;
                 default:
                     // Ensure an array is passed the the cnRetrieve::entries method.
                     if (!is_array($atts)) {
                         $atts = (array) $atts;
                     }
                     $results = $instance->retrieve->entries($atts);
                     //var_dump($results);
                     $atts['list_type'] = $instance->settings->get('connections', 'connections_display_single', 'template') ? $results[0]->entry_type : NULL;
                     // Disable the output of the following because they do no make sense to display for a single entry.
                     $atts['show_alphaindex'] = FALSE;
                     $atts['repeat_alphaindex'] = FALSE;
                     $atts['show_alphahead'] = FALSE;
                     return cnShortcode_Connections::shortcode($atts, $content);
                     break;
             }
             break;
             // Show the standard result list.
         // Show the standard result list.
         default:
             //return cnShortcode_Connections::shortcode( $atts, $content );
             if (has_action("cn_view_{$view}")) {
                 ob_start();
                 do_action("cn_view_{$view}", $atts, $content, $tag);
                 return ob_get_clean();
             }
             break;
     }
     return cnShortcode_Connections::shortcode($atts, $content);
 }