/**
  * @param WP_REST_Request $request Full details about the request.
  *
  * @return array
  */
 protected function get_entries($request)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $atts = array('limit' => $request['per_page'], 'offset' => $request['offset']);
     $results = $instance->retrieve->entries($atts);
     return $results;
 }
 /**
  * Get the system info.
  *
  * @access private
  * @since  8.3
  * @static
  *
  * @global wpdb $wpdb
  *
  * @uses   Browser()
  * @uses   Connections_Directory()
  * @uses   wp_get_theme()
  * @uses   cnSystem_Info::getHost()
  *
  * @return string
  */
 public static function get()
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     if (!class_exists('Browser')) {
         require_once CN_PATH . 'vendor/browser/Browser.php';
     }
     $browser = new Browser();
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     // Get theme info
     $theme_data = wp_get_theme();
     $theme = $theme_data->Name . ' ' . $theme_data->Version;
     // Try to identify the hosting provider
     $host = self::getHost();
     ob_start();
     require_once CN_PATH . 'includes/system-info/inc.system-info.php';
     return ob_get_clean();
 }
 /**
  * Function for displaying the widget on the page.
  *
  * @access  private
  * @since   1.0
  *
  * @param  array $args
  * @param  array $option
  *
  * @return string
  */
 public function widget($args, $option)
 {
     // Only process and display the widget if displaying a single entry.
     if (get_query_var('cn-entry-slug')) {
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         // Query the entry.
         $result = $instance->retrieve->entries(array('slug' => urldecode(get_query_var('cn-entry-slug'))));
         // Setup the entry object
         $entry = new cnEntry($result[0]);
         // Query the entry meta.
         $metadata = $entry->getMeta(array('key' => 'hobbies', 'single' => TRUE));
         // If there is no meta; bail.
         if (empty($metadata)) {
             return;
         }
         /**
          * Extract $before_widget, $after_widget, $before_title and $after_title.
          *
          * @var $before_widget
          * @var $after_widget
          * @var $before_title
          * @var $after_title
          */
         extract($args);
         // Setup the default widget options if they were not set when they were added to the sidebar;
         // ie. the user did not click the "Save" button on the widget.
         $title = strlen($option['title']) > 0 ? $option['title'] : __('Hobbies', 'connections_hobbies');
         // Setup the atts to be passed to the method that displays the data.
         $atts = array();
         echo $before_widget;
         echo $before_title . $title . $after_title;
         // Display the income level.
         Connections_Hobbies::block('hobbies', $metadata, NULL, $atts);
         echo $after_widget;
     }
 }
 public static function shortcode($atts, $content = '', $tag = 'cn_thumbr')
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $log = array();
     $srcset = array();
     $permitted = array('attachment', 'featured', 'path', 'url', 'logo', 'photo');
     $defaults = array('type' => 'url', 'source' => NULL, 'negate' => FALSE, 'grayscale' => FALSE, 'brightness' => 0, 'colorize' => NULL, 'contrast' => 0, 'detect_edges' => FALSE, 'emboss' => FALSE, 'gaussian_blur' => FALSE, 'blur' => FALSE, 'sketchy' => FALSE, 'sharpen' => FALSE, 'smooth' => NULL, 'opacity' => 100, 'crop_mode' => 1, 'crop_focus' => array(0.5, 0.5), 'crop_only' => FALSE, 'canvas_color' => '#FFFFFF', 'quality' => 90, 'sizes' => '1024|640|320');
     $defaults = apply_filters('cn_thumbr_shortcode_atts', $defaults);
     $atts = shortcode_atts($defaults, $atts, $tag);
     if (!in_array($atts['type'], $permitted)) {
         return __('Valid image source type not supplied.', 'connections');
     }
     /*
      * Convert some of the $atts values in the array to boolean because the Shortcode API passes all values as strings.
      */
     cnFormatting::toBoolean($atts['negate']);
     cnFormatting::toBoolean($atts['grayscale']);
     cnFormatting::toBoolean($atts['detect_edges']);
     cnFormatting::toBoolean($atts['emboss']);
     cnFormatting::toBoolean($atts['gaussian_blur']);
     cnFormatting::toBoolean($atts['blur']);
     cnFormatting::toBoolean($atts['sketchy']);
     cnFormatting::toBoolean($atts['sharpen']);
     // cnFormatting::toBoolean( $atts['crop'] );
     cnFormatting::toBoolean($atts['crop_only']);
     $atts['sizes'] = explode('|', $atts['sizes']);
     array_map('trim', $atts['sizes']);
     array_map('absint', $atts['sizes']);
     if (empty($atts['sizes'])) {
         return __('No image sizes were supplied or supplied values were invalid.', 'connections');
     }
     switch ($atts['type']) {
         case 'attachment':
             $source = wp_get_attachment_url(absint($atts['source']));
             break;
         case 'featured':
             $source = wp_get_attachment_url(get_post_thumbnail_id());
             break;
         case 'path':
             $source = $atts['source'];
             break;
         case 'url':
             $source = esc_url($atts['source']);
             break;
         case 'logo':
             $result = $instance->retrieve->entry(absint($atts['source']));
             $entry = new cnEntry($result);
             $meta = $entry->getImageMeta(array('type' => 'logo'));
             if (is_wp_error($meta)) {
                 // Display the error messages.
                 return implode(PHP_EOL, $meta->get_error_messages());
             }
             $source = $meta['url'];
             break;
         case 'photo':
             $result = $instance->retrieve->entry(absint($atts['source']));
             $entry = new cnEntry($result);
             $meta = $entry->getImageMeta(array('type' => 'photo'));
             if (is_wp_error($meta)) {
                 // Display the error messages.
                 return implode(PHP_EOL, $meta->get_error_messages());
             }
             $source = $meta['url'];
             break;
     }
     // Unset $atts['source'] because passing that $atts to cnImage::get() extracts and overwrite the $source var.
     unset($atts['source']);
     foreach ($atts['sizes'] as $width) {
         $atts['width'] = $width;
         $image = cnImage::get($source, $atts, 'data');
         if (is_wp_error($image)) {
             // Display the error messages.
             return implode(PHP_EOL, $image->get_error_messages());
         } elseif ($image === FALSE) {
             return __('An error has occured while creating the thumbnail.', 'connections');
         }
         if (defined('WP_DEBUG') && WP_DEBUG === TRUE) {
             $log[] = '<pre>' . $image['log'] . '</pre>';
         }
         $srcset[] = $image['url'] . ' ' . $width . 'w';
     }
     $out = sprintf('<img class="cn-image" srcset="%1$s" sizes="100vw"%2$s />', implode(',', $srcset), empty($content) ? '' : ' alt="' . esc_attr($content) . '"');
     if (defined('WP_DEBUG') && WP_DEBUG === TRUE) {
         $out .= implode('', $log);
     }
     return $out;
 }
 /**
  * Will return TRUE?FALSE based on current user capability or privacy setting if the user is not logged in to
  * WordPress.
  *
  * @access public
  * @since  0.7.2.0
  * @static
  *
  * @uses   is_user_logged_in()
  * @uses   current_user_can()
  * @uses   is_admin()
  * @uses   cnOptions::loginRequired()
  * @uses   cnOptions::getAllowPublicOverride()
  * @uses   cnOptions::getAllowPrivateOverride()
  *
  * @param string $visibility
  *
  * @return bool
  */
 public static function userPermitted($visibility)
 {
     // Ensure a valid option for $visibility.
     if (!in_array($visibility, array('public', 'private', 'unlisted'))) {
         return FALSE;
     }
     if (is_user_logged_in()) {
         switch ($visibility) {
             case 'public':
                 return current_user_can('connections_view_public');
             case 'private':
                 return current_user_can('connections_view_private');
             case 'unlisted':
                 return is_admin() && current_user_can('connections_view_unlisted');
             default:
                 return FALSE;
         }
     } else {
         // Unlisted entries are not shown on the frontend.
         if ('unlisted' == $visibility) {
             return FALSE;
         }
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         if (cnOptions::loginRequired()) {
             switch ($visibility) {
                 case 'public':
                     return $instance->options->getAllowPublicOverride();
                 case 'private':
                     return $instance->options->getAllowPrivateOverride();
                 default:
                     return FALSE;
             }
         } else {
             if ('public' == $visibility) {
                 return TRUE;
             }
         }
         // If we get here, return FALSE
         return FALSE;
     }
 }
Beispiel #6
0
 /**
  * This action will handle frontend process requests, currently only creating the vCard for download.
  *
  * @TODO If no vcard is found should redirect to an error message.
  * @access private
  * @since 0.7.3
  * @return void
  */
 public static function frontendActions()
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $process = get_query_var('cn-process');
     $token = get_query_var('cn-token');
     $id = (int) get_query_var('cn-id');
     if ('vcard' === $process) {
         $slug = get_query_var('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;
     }
 }
 /**
  * Display results based on qurey var `cn-view`.
  *
  * @access public
  * @since  0.7.3
  * @static
  * @uses   get_query_var()
  * @param  array $atts
  * @param  string $content [optional]
  *
  * @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 = get_query_var('cn-view');
     switch ($view) {
         case 'submit':
             if (has_action('cn_submit_entry_form')) {
                 ob_start();
                 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 (get_query_var('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') || $entryID == $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);
 }
 /**
  * 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 core template Customizer control string.
  *
  * @access private
  * @since  8.4
  *
  * @uses   Connections_Directory()
  * @uses   apply_filters()
  *
  * @return array
  */
 private function controlStrings()
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $addressTypes = array_keys($instance->options->getDefaultAddressValues());
     $phoneTypes = array_keys($instance->options->getDefaultPhoneNumberValues());
     $emailTypes = array_keys($instance->options->getDefaultEmailValues());
     $dateTypes = array_keys($instance->options->getDateOptions());
     $linkTypes = array_keys($instance->options->getDefaultLinkValues());
     $strings = array('title' => array('label' => __('Show the entry title.', 'connections'), 'desc' => __('Whether or not to display the Title field.', 'connections')), 'org' => array('label' => __('Show the entry organization.', 'connections'), 'desc' => __('Whether or not to display the Organization field.', 'connections')), 'dept' => array('label' => __('Show the entry department.', 'connections'), 'desc' => __('Whether or not to display the Department field.', 'connections')), 'contact_name' => array('label' => __('Show the entry contact name.', 'connections'), 'desc' => __('Whether or not to display the Contact First and Last Name fields.', 'connections')), 'family' => array('label' => __('Show the entry family members.', 'connections'), 'desc' => __('Whether or not to display the family members.', 'connections')), 'addresses' => array('label' => __('Show the addresses.', 'connections'), 'desc' => __('Whether or not to display the addresses.', 'connections')), 'phone_numbers' => array('label' => __('Show the phone numbers.', 'connections'), 'desc' => __('Whether or not to display the phone numbers.', 'connections')), 'email' => array('label' => __('Show the email addresses.', 'connections'), 'desc' => __('Whether or not to display the email addresses.', 'connections')), 'im' => array('label' => __('Show the IM addresses.', 'connections'), 'desc' => __('Whether or not to display the IM addresses.', 'connections')), 'social_media' => array('label' => __('Show the social networks.', 'connections'), 'desc' => __('Whether or not to display the social networks.', 'connections')), 'links' => array('label' => __('Show the links.', 'connections'), 'desc' => __('Whether or not to display the links.', 'connections')), 'dates' => array('label' => __('Show the dates.', 'connections'), 'desc' => __('Whether or not to display the dates.', 'connections')), 'bio' => array('label' => __('Show the bio.', 'connections'), 'desc' => __('Whether or not to display the bio field.', 'connections')), 'notes' => array('label' => __('Show the notes.', 'connections'), 'desc' => __('Whether or not to display the notes field.', 'connections')), 'categories' => array('label' => __('Show the categories assigned to the entry.', 'connections'), 'desc' => __('Whether or not to display the categories.', 'connections')), 'last_updated' => array('label' => __('Show the last updated message.', 'connections'), 'desc' => __('Whether or not to display the last updated message.', 'connections')), 'return_to_top' => array('label' => __('Show display to top.', 'connections'), 'desc' => __('Whether or not to display the return to top arrow.', 'connections')), 'name_format' => array('label' => __('Name Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%prefix% %first% %middle% %last% %suffix%</code>'), 'connections')), 'contact_name_format' => array('label' => __('Contact Name Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%label%%separator% %first% %last%</code>'), 'connections')), 'address_format' => array('label' => __('Address Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%label% %line1% %line2% %line3% %city% %state%  %zipcode% %country%</code>'), 'connections')), 'email_format' => array('label' => __('Email Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%label%%separator% %address%</code>'), 'connections')), 'phone_format' => array('label' => __('Phone Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%label%%separator% %number%</code>'), 'connections')), 'link_format' => array('label' => __('Link Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%label%%separator% %title%</code>'), 'connections')), 'date_format' => array('label' => __('Date Format', 'connections'), 'desc' => __(sprintf('Default: %s', '<code>%label%%separator% %date%</code>'), 'connections')), 'address_types' => array('label' => __('Display Address Types', 'connections'), 'desc' => __(sprintf('Valid: %s', '<code>' . implode('</code>, <code>', $addressTypes)) . '</code>', 'connections')), 'phone_types' => array('label' => __('Display Phone Types', 'connections'), 'desc' => __(sprintf('Valid: %s', '<code>' . implode('</code>, <code>', $phoneTypes)) . '</code>', 'connections')), 'email_types' => array('label' => __('Display Email Types', 'connections'), 'desc' => __(sprintf('Valid: %s', '<code>' . implode('</code>, <code>', $emailTypes)) . '</code>', 'connections')), 'date_types' => array('label' => __('Display Date Types', 'connections'), 'desc' => __(sprintf('Valid: %s', '<code>' . implode('</code>, <code>', $dateTypes)) . '</code>', 'connections')), 'link_types' => array('label' => __('Display Link Types', 'connections'), 'desc' => __(sprintf('Valid: %s', '<code>' . implode('</code>, <code>', $linkTypes)) . '</code>', 'connections')));
     /**
      * An associative array of core strings used by the Template Customizer.
      *
      * The array key is the string ID. The value is an associative array with two keys.
      * The `label` key is the Customizer control label.
      * The `desc` key is the Customizer control description.
      *
      * @since 8.4
      *
      * @param array $strings
      */
     return apply_filters('cn_template_customizer_strings', $strings);
 }
            remove_filter('page_rewrite_rules', array('cnRewrite', 'addPageRewriteRules'));
            // Flush so they are rebuilt.
            flush_rewrite_rules();
        }
    }
    /**
     * The main function responsible for returning the Connections instance
     * to functions everywhere.
     *
     * Use this function like you would a global variable, except without needing
     * to declare the global.
     *
     * NOTE: Declaring an instance in the global @var $connections connectionsLoad to provide backward
     * compatibility with many internal methods, template and extensions that expect it.
     *
     * Example: <?php $instance = Connections_Directory(); ?>
     *
     * @access public
     * @since  0.7.9
     * @global $connections
     * @return connectionsLoad
     */
    function Connections_Directory()
    {
        global $connections;
        $connections = connectionsLoad::instance();
        return $connections;
    }
    // Start Connections.
    Connections_Directory();
}
 /**
  * Update the entry in the db.
  *
  * @access public
  * @since  unknown
  *
  * @return false|int
  */
 public function update()
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $this->serializeOptions();
     $this->setPropertyDefaultsByEntryType();
     do_action('cn_update-entry', $this);
     $result = $wpdb->update(CN_ENTRY_TABLE, array('ts' => current_time('mysql'), 'ordo' => $this->getOrder(), 'entry_type' => $this->entryType, 'visibility' => $this->getVisibility(), 'slug' => $this->getSlug(), 'honorific_prefix' => $this->honorificPrefix, 'first_name' => $this->firstName, 'middle_name' => $this->middleName, 'last_name' => $this->lastName, 'honorific_suffix' => $this->honorificSuffix, 'title' => $this->title, 'organization' => $this->organization, 'department' => $this->department, 'contact_first_name' => $this->contactFirstName, 'contact_last_name' => $this->contactLastName, 'family_name' => $this->familyName, 'birthday' => $this->birthday, 'anniversary' => $this->anniversary, 'addresses' => $this->addresses, 'phone_numbers' => $this->phoneNumbers, 'email' => $this->emailAddresses, 'im' => $this->im, 'social' => $this->socialMedia, 'links' => $this->links, 'dates' => $this->dates, 'options' => $this->options, 'bio' => $this->bio, 'notes' => $this->notes, 'edited_by' => $instance->currentUser->getID(), 'user' => $this->getUser(), 'status' => $this->status), array('id' => $this->id), array('%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s'), array('%d'));
     //print_r($wpdb->last_query);
     /*
      * Only update the rest of the entry's data if the update to the ENTRY TABLE was successful.
      */
     if (FALSE !== $result) {
         require_once CN_PATH . 'includes/entry/class.entry-db.php';
         $cnDb = new cnEntry_DB($this->getId());
         $cnDb->upsert(CN_ENTRY_ADDRESS_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'line_1' => array('key' => 'line_1', 'format' => '%s'), 'line_2' => array('key' => 'line_2', 'format' => '%s'), 'line_3' => array('key' => 'line_3', 'format' => '%s'), 'line_4' => array('key' => 'line_4', 'format' => '%s'), 'district' => array('key' => 'district', 'format' => '%s'), 'county' => array('key' => 'county', 'format' => '%s'), 'city' => array('key' => 'city', 'format' => '%s'), 'state' => array('key' => 'state', 'format' => '%s'), 'zipcode' => array('key' => 'zipcode', 'format' => '%s'), 'country' => array('key' => 'country', 'format' => '%s'), 'latitude' => array('key' => 'latitude', 'format' => '%s'), 'longitude' => array('key' => 'longitude', 'format' => '%s'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getAddresses(array(), TRUE, TRUE, 'db'), array('id' => array('key' => 'id', 'format' => '%d')));
         $cnDb->upsert(CN_ENTRY_PHONE_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'number' => array('key' => 'number', 'format' => '%s'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getPhoneNumbers(array(), TRUE, TRUE), array('id' => array('key' => 'id', 'format' => '%d')));
         $cnDb->upsert(CN_ENTRY_EMAIL_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'address' => array('key' => 'address', 'format' => '%s'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getEmailAddresses(array(), TRUE, TRUE), array('id' => array('key' => 'id', 'format' => '%d')));
         $cnDb->upsert(CN_ENTRY_MESSENGER_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'uid' => array('key' => 'id', 'format' => '%s'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getIm(array(), TRUE, TRUE), array('id' => array('key' => 'uid', 'format' => '%d')));
         $cnDb->upsert(CN_ENTRY_SOCIAL_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'url' => array('key' => 'url', 'format' => '%s'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getSocialMedia(array(), TRUE, TRUE), array('id' => array('key' => 'id', 'format' => '%d')));
         $cnDb->upsert(CN_ENTRY_LINK_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'title' => array('key' => 'title', 'format' => '%s'), 'url' => array('key' => 'url', 'format' => '%s'), 'target' => array('key' => 'target', 'format' => '%s'), 'follow' => array('key' => 'follow', 'format' => '%d'), 'image' => array('key' => 'image', 'format' => '%d'), 'logo' => array('key' => 'logo', 'format' => '%d'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getLinks(array(), TRUE, TRUE), array('id' => array('key' => 'id', 'format' => '%d')));
         $cnDb->upsert(CN_ENTRY_DATE_TABLE, array('order' => array('key' => 'order', 'format' => '%d'), 'preferred' => array('key' => 'preferred', 'format' => '%d'), 'type' => array('key' => 'type', 'format' => '%s'), 'date' => array('key' => 'date', 'format' => '%s'), 'visibility' => array('key' => 'visibility', 'format' => '%s')), $this->getDates(array(), TRUE, TRUE), array('id' => array('key' => 'id', 'format' => '%d')));
         $this->updateObjectCaches();
     }
     do_action('cn_updated-entry', $this);
     return $result;
 }
 /**
  * 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 (get_query_var('cn-entry-slug')) {
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         $entry = $instance->retrieve->entries(array('slug' => rawurldecode(get_query_var('cn-entry-slug')), 'status' => 'approved,pending'));
         // 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'))));
         }
     }
 }
 /**
  * Renders the dates metabox.
  *
  * @access public
  * @since  0.8
  * @param  object $entry   An instance of the cnEntry object.
  * @param  array  $metabox The metabox options array from self::register().
  * @return string          The dates metabox.
  */
 public static function date($entry, $metabox)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     // Grab the email types.
     $dateTypes = $instance->options->getDateOptions();
     echo '<div class="widgets-sortables ui-sortable" id="dates">', PHP_EOL;
     // --> Start template <-- \\
     echo '<textarea id="date-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' => 'date[::FIELD::][type]', 'options' => $dateTypes, 'required' => FALSE, 'label' => __('Type', 'connections'), 'return' => FALSE));
     cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[preferred]', 'options' => array('::FIELD::' => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</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' => 'date[::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">';
     cnHTML::field(array('type' => 'text', 'class' => 'datepicker', 'id' => 'date[::FIELD::][date]', 'required' => FALSE, 'label' => __('Date', 'connections'), 'before' => '', 'after' => '', 'return' => FALSE));
     echo '<p class="cn-remove-button"><a href="#" class="cn-remove cn-button button cn-button-warning" data-type="date" data-token="::FIELD::">', __('Remove', 'connections'), '</a></p>';
     echo '</div>', PHP_EOL;
     echo '</textarea>', PHP_EOL;
     // --> End template <-- \\
     $dates = $entry->getDates(array(), FALSE);
     //print_r($dates);
     if (!empty($dates)) {
         foreach ($dates as $date) {
             $token = str_replace('-', '', cnUtility::getUUID());
             $selectName = 'date[' . $token . '][type]';
             $preferred = $date->preferred ? $token : '';
             echo '<div class="widget date" id="date-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' => 'date[' . $token . '][type]', 'options' => $dateTypes, 'required' => FALSE, 'label' => __('Type', 'connections'), 'return' => FALSE), $date->type);
             cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[preferred]', 'options' => array($token => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</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' => 'date[' . $token . '][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), $date->visibility);
             }
             echo '</h4></div>', PHP_EOL;
             echo '</div>', PHP_EOL;
             echo '<div class="widget-inside">', PHP_EOL;
             cnHTML::field(array('type' => 'text', 'class' => 'datepicker', 'id' => 'date[' . $token . '][date]', 'required' => FALSE, 'label' => __('Date', 'connections'), 'before' => '', 'after' => '', 'return' => FALSE), date('m/d/Y', strtotime($date->date)));
             echo '<input type="hidden" name="date[', $token, '][id]" value="', $date->id, '">', PHP_EOL;
             echo '<p class="cn-remove-button"><a href="#" class="cn-remove cn-button button cn-button-warning" data-type="date" data-token="' . $token . '">', __('Remove', 'connections'), '</a></p>', PHP_EOL;
             echo '</div>', PHP_EOL;
             echo '</div>', PHP_EOL;
         }
     }
     echo '</div>', PHP_EOL;
     echo '<p class="add"><a href="#" class="cn-add cn-button button" data-type="date" data-container="dates">', __('Add Date', 'connections'), '</a></p>', PHP_EOL;
 }
 /**
  * Add count of children to parent count.
  *
  * Recalculates term counts by including items from child terms. Assumes all
  * relevant children are already in the $terms argument.
  *
  * NOTE: This is the Connections equivalent of @see _pad_term_counts() in WordPress core ../wp-includes/taxonomy.php
  *
  * @access private
  * @since  8.1
  * @static
  *
  * @global $wpdb
  *
  * @uses   childrenIDs()
  * @uses   is_user_logged_in()
  * @uses   current_user_can()
  * @uses   wpdb::get_results()
  *
  * @param  array $terms List of Term IDs
  * @param  string $taxonomy Term Context
  *
  * @return null Will break from function if conditions are not met.
  */
 private static function padCounts(&$terms, $taxonomy)
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     $term_ids = array();
     $visibility = array();
     // Grab an instance of the Connections object.
     /** @var connectionsLoad $instance */
     $instance = Connections_Directory();
     // This function only works for hierarchical taxonomies like post categories.
     // if ( !is_taxonomy_hierarchical( $taxonomy ) )
     // 	return;
     $term_hier = self::childrenIDs($taxonomy);
     if (empty($term_hier)) {
         return;
     }
     $term_items = array();
     foreach ((array) $terms as $key => $term) {
         $terms_by_id[$term->term_id] =& $terms[$key];
         $term_ids[$term->term_taxonomy_id] = $term->term_id;
     }
     /*
      * // START --> Set up the query to only return the entries based on user permissions.
      */
     if (is_user_logged_in()) {
         if (current_user_can('connections_view_public')) {
             $visibility[] = 'public';
         }
         if (current_user_can('connections_view_private')) {
             $visibility[] = 'private';
         }
         if (current_user_can('connections_view_unlisted') && is_admin()) {
             $visibility[] = 'unlisted';
         }
     } else {
         // Display the 'public' entries if the user is not required to be logged in.
         $visibility[] = $instance->options->getAllowPublic() ? 'public' : '';
     }
     /*
      * // END --> Set up the query to only return the entries based on user permissions.
      */
     // Get the object and term ids and stick them in a lookup table
     // $tax_obj      = get_taxonomy( $taxonomy );
     $entry_types = array('individual', 'organization', 'family');
     $results = $wpdb->get_results("SELECT entry_id, term_taxonomy_id FROM " . CN_TERM_RELATIONSHIP_TABLE . " INNER JOIN " . CN_ENTRY_TABLE . " ON entry_id = id WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND entry_type IN ('" . implode("', '", $entry_types) . "') AND visibility IN ('" . implode("', '", (array) $visibility) . "')");
     foreach ($results as $row) {
         $id = $term_ids[$row->term_taxonomy_id];
         $term_items[$id][$row->entry_id] = isset($term_items[$id][$row->entry_id]) ? ++$term_items[$id][$row->entry_id] : 1;
     }
     // Touch every ancestor's lookup row for each post in each term
     foreach ($term_ids as $term_id) {
         $child = $term_id;
         while (!empty($terms_by_id[$child]) && ($parent = $terms_by_id[$child]->parent)) {
             if (!empty($term_items[$term_id])) {
                 foreach ($term_items[$term_id] as $item_id => $touches) {
                     $term_items[$parent][$item_id] = isset($term_items[$parent][$item_id]) ? ++$term_items[$parent][$item_id] : 1;
                 }
             }
             $child = $parent;
         }
     }
     // Transfer the touched cells
     foreach ((array) $term_items as $id => $items) {
         if (isset($terms_by_id[$id])) {
             $terms_by_id[$id]->count = count($items);
         }
     }
 }
 /**
  * Echo or return the entry's phone numbers in a HTML hCard compliant string.
  *
  * Accepted options for the $atts property are:
  *  preferred (bool) Retrieve the preferred entry phone number.
  *  type (array) || (string) Retrieve specific phone number types.
  *   Permitted Types:
  *    homephone
  *    homefax
  *    cellphone
  *    workphone
  *    workfax
  *  format (string) The tokens to use to display the phone number block parts.
  *   Permitted Tokens:
  *    %label%
  *    %number%
  *    %separator%
  *  separator (string) The separator to use.
  *  before (string) HTML to output before the phone numbers.
  *  after (string) HTML to after before the phone numbers.
  *  return (bool) Return string if set to TRUE instead of echo string.
  *
  * Filters:
  *  cn_output_default_atts_phone => (array) Register the methods default attributes.
  *
  * @access public
  * @since unknown
  *
  * @param array $atts   Accepted values as noted above.
  * @param bool  $cached Returns the cached data rather than querying the db.
  *
  * @return string
  */
 public function getPhoneNumberBlock($atts = array(), $cached = TRUE)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     /*
      * // START -- Set the default attributes array. \\
      */
     $defaults = array('preferred' => NULL, 'type' => NULL, 'limit' => NULL, 'format' => '', 'separator' => ':', 'before' => '', 'after' => '', 'return' => FALSE);
     $defaults = apply_filters('cn_output_default_atts_phone', $defaults);
     $atts = cnSanitize::args($atts, $defaults);
     $atts['id'] = $this->getId();
     /*
      * // END -- Set the default attributes array if not supplied. \\
      */
     $rows = array();
     $phoneNumbers = $this->getPhoneNumbers($atts, $cached);
     $search = array('%label%', '%number%', '%separator%');
     if (empty($phoneNumbers)) {
         return '';
     }
     foreach ($phoneNumbers as $phone) {
         $replace = array();
         $row = "\t" . '<span class="tel">';
         $replace[] = empty($phone->name) ? '' : '<span class="phone-name">' . $phone->name . '</span>';
         if (empty($phone->number)) {
             $replace[] = '';
         } else {
             if ($instance->settings->get('connections', 'link', 'phone')) {
                 $replace[] = '<a class="value" href="tel:' . $phone->number . '" value="' . preg_replace('/[^0-9]/', '', $phone->number) . '">' . $phone->number . '</a>';
             } else {
                 $replace[] = '<span class="value">' . $phone->number . '</span>';
             }
         }
         $replace[] = '<span class="cn-separator">' . $atts['separator'] . '</span>';
         $row .= str_ireplace($search, $replace, empty($atts['format']) ? empty($defaults['format']) ? '%label%%separator% %number%' : $defaults['format'] : $atts['format']);
         // Set the hCard Phone Number Type.
         $row .= $this->gethCardTelType($phone->type);
         $row .= '</span>' . PHP_EOL;
         $rows[] = apply_filters('cn_output_phone_number', cnString::replaceWhatWith($row, ' '), $phone, $this, $atts);
     }
     $block = '<span class="phone-number-block">' . PHP_EOL . implode(PHP_EOL, $rows) . PHP_EOL . '</span>';
     $block = apply_filters('cn_output_phone_numbers', $block, $phoneNumbers, $this, $atts);
     $html = $atts['before'] . $block . $atts['after'] . PHP_EOL;
     return $this->echoOrReturn($atts['return'], $html);
 }
 /**
  * Register the user friendly column header names.
  *
  * @access private
  * @since  8.5.1
  *
  * @return array
  */
 private function setHeaderNames()
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     // Core fields.
     $fields = array('id' => 'Entry ID', 'entry_type' => 'Entry Type', 'visibility' => 'Visibility', 'family_name' => 'Family Name', 'honorific_prefix' => 'Honorific Prefix', 'first_name' => 'First Name', 'middle_name' => 'Middle Name', 'last_name' => 'Last Name', 'honorific_suffix' => 'Honorific Suffix', 'title' => 'Title', 'organization' => 'Organization', 'department' => 'Department', 'contact_first_name' => 'Contact First Name', 'contact_last_name' => 'Contact Last Name', 'bio' => 'Biography', 'notes' => 'Notes');
     $fields['category'] = 'Categories';
     /*
      * Build the array of core and extended address fields for mapping during import.
      */
     $coreAddressTypes = $instance->options->getDefaultAddressValues();
     $addressFields = array('line_1' => 'Line One', 'line_2' => 'Line Two', 'line_3' => 'Line Three', 'line_4' => 'Line Four', 'district' => 'District', 'county' => 'County', 'city' => 'City', 'state' => 'State', 'zipcode' => 'Zipcode', 'country' => 'Country', 'latitude' => 'Latitude', 'longitude' => 'Longitude', 'visibility' => 'Visibility');
     /*
      * Add the core address types to the field array.
      */
     foreach ($coreAddressTypes as $addressType => $addressName) {
         foreach ($addressFields as $addressFieldType => $addressFieldName) {
             $key = 'address_' . $addressType . '_' . $addressFieldType;
             $fields[$key] = $addressName . ' Address | ' . $addressFieldName;
         }
     }
     /*
      * Build the array of core phone fields for mapping during import.
      */
     $corePhoneTypes = $instance->options->getDefaultPhoneNumberValues();
     $phoneFields = array('number' => 'Number', 'visibility' => 'Visibility');
     // Add the core phone types to the field array.
     foreach ($corePhoneTypes as $phoneType => $phoneName) {
         foreach ($phoneFields as $phoneFieldType => $phoneFieldName) {
             $key = 'phone_' . $phoneType . '_' . $phoneFieldType;
             $fields[$key] = 'Phone | ' . $phoneName . ' | ' . $phoneFieldName;
         }
     }
     /*
      * Build the array of core email fields for mapping during import.
      */
     $coreEmailTypes = $instance->options->getDefaultEmailValues();
     $emailFields = array('address' => 'Address', 'visibility' => 'Visibility');
     // Add the core email types to the field array.
     foreach ($coreEmailTypes as $emailType => $emailName) {
         foreach ($emailFields as $emailFieldType => $emailFieldName) {
             $key = 'email_' . $emailType . '_' . $emailFieldType;
             $fields[$key] = 'Email | ' . $emailName . ' | ' . $emailFieldName;
         }
     }
     /*
      * Build the array of core IM fields for mapping during import.
      */
     $coreIMTypes = $instance->options->getDefaultIMValues();
     $IMFields = array('uid' => 'User ID', 'visibility' => 'Visibility');
     // Add the core IM types to the field array.
     foreach ($coreIMTypes as $IMType => $IMName) {
         foreach ($IMFields as $IMFieldType => $IMFieldName) {
             $key = 'im_' . $IMType . '_' . $IMFieldType;
             $fields[$key] = 'Messenger | ' . $IMName . ' | ' . $IMFieldName;
         }
     }
     /*
      * Build the array of core social media fields for mapping during import.
      */
     $coreSocialTypes = $instance->options->getDefaultSocialMediaValues();
     $socialFields = array('url' => 'URL', 'visibility' => 'Visibility');
     // Add the core email types to the field array.
     foreach ($coreSocialTypes as $socialType => $socialName) {
         foreach ($socialFields as $socialFieldType => $socialFieldName) {
             $key = 'social_' . $socialType . '_' . $socialFieldType;
             $fields[$key] = 'Social Network | ' . $socialName . ' | ' . $socialFieldName;
         }
     }
     /*
      * Build the array of core link fields for mapping during import.
      */
     $coreLinkTypes = $instance->options->getDefaultLinkValues();
     $linkFields = array('url' => 'URL', 'visibility' => 'Visibility');
     // Add the core email types to the field array.
     foreach ($coreLinkTypes as $linkType => $linkName) {
         foreach ($linkFields as $linkFieldType => $linkFieldName) {
             $key = 'links_' . $linkType . '_' . $linkFieldType;
             $fields[$key] = 'Link | ' . $linkName . ' | ' . $linkFieldName;
         }
     }
     /*
      * Build the array of core date fields for mapping during import.
      */
     $coreDateTypes = $instance->options->getDateOptions();
     $dateFields = array('date' => 'Date', 'visibility' => 'Visibility');
     // Add the core date types to the field array.
     foreach ($coreDateTypes as $dateType => $dateName) {
         foreach ($dateFields as $dateFieldType => $dateFieldName) {
             $key = 'dates_' . $dateType . '_' . $dateFieldType;
             $fields[$key] = 'Date | ' . $dateName . ' | ' . $dateFieldName;
         }
     }
     $fields['options_image_url'] = 'Photo URL';
     $fields['options_logo_url'] = 'Logo URL';
     $this->headerNames = apply_filters('cn_csv_export_fields', $fields);
 }
 /**
  * The dashboard widget used to display the recently added/modified entries.
  *
  * @access public
  * @since  0.8
  * @param  object $null    Generally a $post or $entry object. Not used in Connections core.
  * @param  array  $metabox The metabox options array from self::register().
  * @return string          The recently added/modifed entries.
  */
 public static function recent($null, $metabox)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     add_filter('cn_list_results', array($instance->retrieve, 'removeUnknownDateAdded'), 9);
     remove_action('cn_list_actions', array('cnTemplatePart', 'listActions'));
     $atts = array('order_by' => $metabox['args']['order_by'], 'template' => $metabox['args']['template'], 'show_alphaindex' => FALSE, 'show_alphahead' => FALSE, 'limit' => $metabox['args']['limit'], 'status' => $metabox['args']['status']);
     connectionsEntryList($atts);
     remove_filter('cn_list_results', array($instance->retrieve, 'removeUnknownDateAdded'), 9);
 }
    /**
     * Renders the social media network field.
     *
     * @access private
     * @since  8.5.11
     *
     * @param stdClass $date
     * @param string   $token
     */
    private static function dateField($date, $token = '::FIELD::')
    {
        // Grab an instance of the Connections object.
        $instance = Connections_Directory();
        // Grab the date types.
        $dateTypes = $instance->options->getDateOptions();
        ?>

		<div class="widget-top">
			<div class="widget-title-action"><a class="widget-action"></a></div>

			<div class="widget-title">
				<h4>

					<?php 
        cnHTML::field(array('type' => 'select', 'class' => '', 'id' => 'date[' . $token . '][type]', 'options' => $dateTypes, 'required' => FALSE, 'label' => __('Type', 'connections'), 'return' => FALSE), isset($date->type) ? $date->type : '');
        cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[preferred]', 'options' => array($token => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</span>', 'return' => FALSE), isset($date->preferred) && $date->preferred ? $token : '');
        // 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' => 'date[' . $token . '][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), isset($date->visibility) ? $date->visibility : 'public');
        }
        ?>

				</h4>
			</div>

		</div>

		<div class="widget-inside">

			<?php 
        cnHTML::field(array('type' => 'text', 'class' => 'datepicker', 'id' => 'date[' . $token . '][date]', 'required' => FALSE, 'label' => __('Date', 'connections'), 'before' => '', 'after' => '', 'return' => FALSE), isset($date->date) ? date('m/d/Y', strtotime($date->date)) : '');
        ?>

			<?php 
        if (isset($date->id)) {
            ?>
				<input type="hidden" name="date[<?php 
            echo $token;
            ?>
][id]" value="<?php 
            echo $date->id;
            ?>
">
			<?php 
        }
        ?>

			<p class="cn-remove-button">
				<a href="#" class="cn-remove cn-button button cn-button-warning"
				   data-type="date"
				   data-token="<?php 
        echo $token;
        ?>
"><?php 
        esc_html_e('Remove', 'connections');
        ?>
</a>
			</p>

		</div>

		<?php 
    }
 /**
  * Add rating links to the admin dashboard
  *
  * @access private
  * @since  8.2.9
  *
  * @param  string $text The existing footer text
  *
  * @return string
  */
 public static function rateUs($text)
 {
     if (defined('DOING_AJAX') && DOING_AJAX) {
         return $text;
     }
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     //var_dump( get_current_screen()->id );
     //var_dump( $instance->pageHook );
     if (in_array(get_current_screen()->id, get_object_vars($instance->pageHook))) {
         //if ( in_array( get_current_screen()->id, (array) $instance->pageHook ) ) {
         $rate_text = sprintf(__('Thank you for using <a href="%1$s" target="_blank">Connections Business Directory</a>! Please <a href="%2$s" target="_blank">rate us</a> on <a href="%2$s" target="_blank">WordPress.org</a>', 'connections'), 'http://connections-pro.com', 'https://wordpress.org/support/view/plugin-reviews/connections?filter=5#postform');
         return str_replace('</span>', '', $text) . ' | ' . $rate_text . '</span>';
     } else {
         return $text;
     }
 }
Beispiel #20
0
function connectionsShowCategoriesPage()
{
    /*
     * Check whether user can edit categories.
     */
    if (!current_user_can('connections_edit_categories')) {
        wp_die('<p id="error-page" style="-moz-background-clip:border;
				-moz-border-radius:11px;
				background:#FFFFFF none repeat scroll 0 0;
				border:1px solid #DFDFDF;
				color:#333333;
				display:block;
				font-size:12px;
				line-height:18px;
				margin:25px auto 20px;
				padding:1em 2em;
				text-align:center;
				width:700px">' . __('You do not have sufficient permissions to access this page.', 'connections') . '</p>');
    } else {
        // Grab an instance of the Connections object.
        $instance = Connections_Directory();
        $form = new cnFormObjects();
        $taxonomy = 'category';
        $action = '';
        if (isset($_GET['cn-action'])) {
            $action = $_GET['cn-action'];
        }
        if ($action === 'edit_category') {
            $id = absint($_GET['id']);
            check_admin_referer('category_edit_' . $id);
            $term = $instance->retrieve->category($id);
            $category = new cnCategory($term);
            /**
             * Fires before the Edit Term form for all taxonomies.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to
             * the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param object $tag      Current taxonomy term object.
             * @param string $taxonomy Current $taxonomy slug.
             */
            do_action("cn_{$taxonomy}_pre_edit_form", $term, $taxonomy);
            ?>

			<div class="wrap">
				<div class="form-wrap" style="width:600px; margin: 0 auto;">
					<h2><a name="new"></a><?php 
            _e('Edit Category', 'connections');
            ?>
</h2>

					<?php 
            $attr = array('action' => '', 'method' => 'post', 'id' => 'addcat', 'name' => 'updatecategory');
            $form->open($attr);
            $form->tokenField('update_category');
            /**
             * Fires inside the Edit Term form tag.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to
             * the taxonomy slug.
             *
             * @since 3.7.0
             */
            do_action("cn_{$taxonomy}_term_edit_form_tag");
            ?>

					<div class="form-field form-required term-name-wrap">
						<label for="category_name"><?php 
            _e('Name', 'connections');
            ?>
</label>
						<input type="text" aria-required="true" size="40" value="<?php 
            echo esc_attr($category->getName());
            ?>
" id="category_name" name="category_name"/>
						<input type="hidden" value="<?php 
            echo esc_attr($category->getID());
            ?>
" id="category_id" name="category_id"/>

						<p><?php 
            _e('The name is how it appears on your site.', 'connections');
            ?>
</p>
					</div>

					<div class="form-field term-slug-wrap">
						<label for="category_slug"><?php 
            _e('Slug', 'connections');
            ?>
 </label>
						<input type="text" size="40" value="<?php 
            echo esc_attr($category->getSlug());
            ?>
" id="category_slug" name="category_slug"/>

						<p><?php 
            _e('The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens.', 'connections');
            ?>
</p>
					</div>

					<div class="form-field term-parent-wrap">
						<label for="category_parent"><?php 
            _e('Parent', 'connections');
            ?>
</label>

						<?php 
            cnTemplatePart::walker('term-select', array('hide_empty' => 0, 'hide_if_empty' => FALSE, 'name' => 'category_parent', 'orderby' => 'name', 'taxonomy' => 'category', 'selected' => $category->getParent(), 'exclude_tree' => $category->getID(), 'hierarchical' => TRUE, 'show_option_none' => __('None', 'connections')));
            ?>
						<p><?php 
            _e('Categories can have a hierarchy. You might have a Jazz category, and under that have children categories for Bebop and Big Band. Totally optional.', 'connections');
            ?>
</p>
					</div>


					<div class="form-field term-description-wrap">
						<?php 
            ob_start();
            /*
             * Now we're going to have to keep track of which TinyMCE plugins
             * WP core supports based on version, sigh.
             */
            if (version_compare($GLOBALS['wp_version'], '3.8.999', '<')) {
                $tinymcePlugins = array('inlinepopups', 'tabfocus', 'paste', 'wordpress', 'wplink', 'wpdialogs');
            } else {
                $tinymcePlugins = array('tabfocus', 'paste', 'wordpress', 'wplink', 'wpdialogs');
            }
            wp_editor(wp_kses_post($category->getDescription()), 'category_description', array('media_buttons' => FALSE, 'tinymce' => array('editor_selector' => 'tinymce', 'toolbar1' => 'bold, italic, underline, |, bullist, numlist, |, justifyleft, justifycenter, justifyright, alignleft, aligncenter, alignright, |, link, unlink, |, pastetext, pasteword, removeformat, |, undo, redo', 'toolbar2' => '', 'inline_styles' => TRUE, 'relative_urls' => FALSE, 'remove_linebreaks' => FALSE, 'plugins' => implode(',', $tinymcePlugins))));
            echo ob_get_clean();
            ?>
					</div>

					<?php 
            /**
             * Fires after the Edit Term form fields are displayed.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to
             * the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param object $tag      Current taxonomy term object.
             * @param string $taxonomy Current taxonomy slug.
             */
            do_action("cn_{$taxonomy}_edit_form_fields", $term, $taxonomy);
            /**
             * Fires at the end of the Edit Term form for all taxonomies.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param object $tag      Current taxonomy term object.
             * @param string $taxonomy Current taxonomy slug.
             */
            do_action("{$taxonomy}_edit_form", $term, $taxonomy);
            ?>

					<input type="hidden" name="cn-action" value="update_category"/>

					<p class="submit">
						<a class="button button-warning" href="admin.php?page=connections_categories"><?php 
            _e('Cancel', 'connections');
            ?>
</a>
						<input type="submit" name="update" id="update" class="button button-primary" value="<?php 
            _e('Update Category', 'connections');
            ?>
"/>
					</p>

					<?php 
            $form->close();
            ?>

				</div>
			</div>
		<?php 
        } else {
            /**
             * @var CN_Terms_List_Table $table
             */
            $table = cnTemplatePart::table('term-admin', array('screen' => get_current_screen()->id));
            $table->prepare_items();
            ?>
			<div class="wrap nosubsub">

				<h2>Connections : <?php 
            _e('Categories', 'connections');
            ?>
</h2>

				<form class="search-form" action="" method="get">

					<input type="hidden" name="page" value="<?php 
            echo esc_attr($_REQUEST['page']);
            ?>
"/>
					<?php 
            $table->search_box(__('Search Categories', 'connections'), 'category');
            ?>

				</form>
				<br class="clear"/>

				<div id="col-container">

					<div id="col-right">
						<div class="col-wrap">
							<?php 
            $attr = array('action' => '', 'method' => 'post');
            $form->open($attr);
            //$form->tokenField( 'bulk_delete_category' );
            ?>
							<input type="hidden" name="cn-action" value="category_bulk_actions"/>
							<?php 
            $table->display();
            $form->close();
            ?>

							<br class="clear" />

							<script type="text/javascript">
								/* <![CDATA[ */
								(function ($) {
									$(document).ready(function () {
										$('#doaction, #doaction2').click(function () {
											if ($('select[name^="action"]').val() == 'delete') {
												var m = 'You are about to delete the selected category(ies).\n  \'Cancel\' to stop, \'OK\' to delete.';
												return showNotice.warn(m);
											}
										});
									});
								})(jQuery);
								/* ]]> */
							</script>

							<div class="form-wrap">
								<p><?php 
            _e('<strong>Note:</strong><br/>Deleting a category which has been assigned to an entry will reassign that entry as <strong>Uncategorized</strong>.', 'connections');
            ?>
</p>
							</div>

							<?php 
            /**
             * Fires after the taxonomy list table.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param string $taxonomy The taxonomy name.
             */
            do_action("cn_after-{$taxonomy}-table", $taxonomy);
            ?>

						</div>
					</div>
					<!-- right column -->

					<div id="col-left">
						<div class="col-wrap">

							<?php 
            /**
             * Fires before the Add Term form for all taxonomies.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param string $taxonomy The taxonomy slug.
             */
            do_action("cn_{$taxonomy}_pre_add_form", $taxonomy);
            ?>

							<div class="form-wrap">
								<h3><?php 
            _e('Add New Category', 'connections');
            ?>
</h3>

								<?php 
            $attr = array('action' => '', 'method' => 'post');
            $form->open($attr);
            $form->tokenField('add_category');
            /**
             * Fires at the beginning of the Add Tag form.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
             *
             * @since 3.7.0
             */
            do_action("cn_{$taxonomy}_term_new_form_tag");
            ?>
								<div class="form-field form-required term-name-wrap">
									<label for="category_name"><?php 
            _e('Name', 'connections');
            ?>
</label>
									<input type="text" aria-required="true" size="40" value="" id="category_name" name="category_name"/>
									<input type="hidden" value="" id="category_id" name="category_id"/>

									<p><?php 
            _e('The name is how it appears on your site.', 'connections');
            ?>
</p>
								</div>

								<div class="form-field term-slug-wrap">
									<label for="category_slug"><?php 
            _e('Slug', 'connections');
            ?>
</label>
									<input type="text" size="40" value="" id="category_slug" name="category_slug"/>

									<p><?php 
            _e('The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens.', 'connections');
            ?>
</p>
								</div>

								<div class="form-field term-parent-wrap">
									<label for="category_parent"><?php 
            _e('Parent', 'connections');
            ?>
</label>

									<?php 
            $dropdown_args = array('hide_empty' => 0, 'hide_if_empty' => FALSE, 'taxonomy' => 'category', 'name' => 'category_parent', 'orderby' => 'name', 'hierarchical' => TRUE, 'show_option_none' => __('None', 'connections'));
            /**
             * Filter the taxonomy parent drop-down on the Edit Term page.
             *
             * @since 3.7.0
             *
             * @param array   $dropdown_args    {
             *                                  An array of taxonomy parent drop-down arguments.
             *
             * @type int|bool $hide_empty       Whether to hide terms not attached to any posts. Default 0|false.
             * @type bool     $hide_if_empty    Whether to hide the drop-down if no terms exist. Default false.
             * @type string   $taxonomy         The taxonomy slug.
             * @type string   $name             Value of the name attribute to use for the drop-down select element.
             *                                      Default 'parent'.
             * @type string   $orderby          The field to order by. Default 'name'.
             * @type bool     $hierarchical     Whether the taxonomy is hierarchical. Default true.
             * @type string   $show_option_none Label to display if there are no terms. Default 'None'.
             * }
             *
             * @param string  $taxonomy         The taxonomy slug.
             */
            $dropdown_args = apply_filters('cn_taxonomy_parent_dropdown_args', $dropdown_args, 'category');
            cnTemplatePart::walker('term-select', $dropdown_args);
            ?>

									<p><?php 
            _e('Categories can have a hierarchy. You might have a Jazz category, and under that have children categories for Bebop and Big Band. Totally optional.', 'connections');
            ?>
</p>
								</div>

								<div class="form-field term-description-wrap">
									<?php 
            ob_start();
            /*
             * Now we're going to have to keep track of which TinyMCE plugins
             * WP core supports based on version, sigh.
             */
            if (version_compare($GLOBALS['wp_version'], '3.8.999', '<')) {
                $tinymcePlugins = array('inlinepopups', 'tabfocus', 'paste', 'wordpress', 'wplink', 'wpdialogs');
            } else {
                $tinymcePlugins = array('tabfocus', 'paste', 'wordpress', 'wplink', 'wpdialogs');
            }
            wp_editor('', 'category_description', array('media_buttons' => FALSE, 'tinymce' => array('editor_selector' => 'tinymce', 'toolbar1' => 'bold, italic, underline, |, bullist, numlist, |, justifyleft, justifycenter, justifyright, alignleft, aligncenter, alignright, |, link, unlink, |, pastetext, pasteword, removeformat, |, undo, redo', 'toolbar2' => '', 'inline_styles' => TRUE, 'relative_urls' => FALSE, 'remove_linebreaks' => FALSE, 'plugins' => implode(',', $tinymcePlugins))));
            echo ob_get_clean();
            ?>

								</div>

								<input type="hidden" name="cn-action" value="add_category"/>

								<?php 
            /**
             * Fires after the Add Term form fields for hierarchical taxonomies.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param string $taxonomy The taxonomy slug.
             */
            do_action("cn_{$taxonomy}_add_form_fields", $taxonomy);
            submit_button(__('Add New Category', 'connections'), 'primary', 'add');
            /**
             * Fires at the end of the Add Term form for all taxonomies.
             *
             * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
             *
             * @since 3.0.0
             *
             * @param string $taxonomy The taxonomy slug.
             */
            do_action("cn_{$taxonomy}_add_form", $taxonomy);
            ?>

								<?php 
            $form->close();
            ?>
							</div>
						</div>
					</div>
					<!-- left column -->

				</div>
				<!-- Column container -->
			</div>
		<?php 
        }
    }
}
 /**
  * @param array  $atts
  * @param string $content
  * @param string $tag
  *
  * @return string
  */
 public static function shortcode($atts, $content = '', $tag = 'connections')
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $html = '';
     if (is_customize_preview()) {
         /**
          * Hook to allow the active template to be overridden and set to the current template being customized.
          *
          * @since 8.4
          *
          * @param array $atts {
          *     @type string $template The template slug of the template being customized.
          * }
          */
         $atts = apply_filters('cn_template_customizer_template', $atts);
     }
     /** @var cnTemplate $template */
     $template = cnTemplateFactory::loadTemplate($atts);
     if ($template === FALSE) {
         return cnTemplatePart::loadTemplateError($atts);
     }
     /*
      * This filter adds the current template paths to cnLocate so when template
      * part file overrides are being searched for, it'll also search in template
      * specific paths. This filter is then removed at the end of the shortcode.
      */
     add_filter('cn_locate_file_paths', array($template, 'templatePaths'));
     self::addFilterRegistry('cn_locate_file_paths');
     do_action('cn_template_include_once-' . $template->getSlug());
     do_action('cn_template_enqueue_js-' . $template->getSlug());
     /*
      * Now that the template has been loaded, Validate the user supplied shortcode atts.
      */
     $defaults = array('id' => NULL, 'slug' => NULL, 'category' => NULL, 'category_in' => NULL, 'exclude_category' => NULL, 'category_name' => NULL, 'category_slug' => NULL, 'wp_current_category' => FALSE, 'allow_public_override' => FALSE, 'private_override' => FALSE, 'show_alphaindex' => cnSettingsAPI::get('connections', 'display_results', 'index'), 'repeat_alphaindex' => cnSettingsAPI::get('connections', 'display_results', 'index_repeat'), 'show_alphahead' => cnSettingsAPI::get('connections', 'display_results', 'show_current_character'), 'list_type' => NULL, 'order_by' => NULL, 'limit' => NULL, 'offset' => NULL, 'family_name' => NULL, 'last_name' => NULL, 'title' => NULL, 'organization' => NULL, 'department' => NULL, 'district' => NULL, 'county' => NULL, 'city' => NULL, 'state' => NULL, 'zip_code' => NULL, 'country' => NULL, 'meta_query' => '', 'content' => '', 'near_addr' => NULL, 'latitude' => NULL, 'longitude' => NULL, 'radius' => 10, 'unit' => 'mi', 'template' => NULL, 'width' => NULL, 'lock' => FALSE, 'force_home' => FALSE, 'home_id' => in_the_loop() && is_page() ? get_the_ID() : cnSettingsAPI::get('connections', 'home_page', 'page_id'));
     $defaults = apply_filters('cn_list_atts_permitted', $defaults);
     $defaults = apply_filters('cn_list_atts_permitted-' . $template->getSlug(), $defaults);
     $atts = shortcode_atts($defaults, $atts, $tag);
     $atts = apply_filters('cn_list_atts', $atts);
     $atts = apply_filters('cn_list_atts-' . $template->getSlug(), $atts);
     /*
      * Convert some of the $atts values in the array to boolean.
      */
     cnFormatting::toBoolean($atts['allow_public_override']);
     cnFormatting::toBoolean($atts['private_override']);
     cnFormatting::toBoolean($atts['show_alphaindex']);
     cnFormatting::toBoolean($atts['repeat_alphaindex']);
     cnFormatting::toBoolean($atts['show_alphahead']);
     cnFormatting::toBoolean($atts['wp_current_category']);
     cnFormatting::toBoolean($atts['lock']);
     cnFormatting::toBoolean($atts['force_home']);
     // var_dump( $atts );
     /*
      * The post editor entity encodes the post text we have to decode it
      * so a match can be made when the query is run.
      */
     $atts['family_name'] = html_entity_decode($atts['family_name']);
     $atts['last_name'] = html_entity_decode($atts['last_name']);
     $atts['title'] = html_entity_decode($atts['title']);
     $atts['organization'] = html_entity_decode($atts['organization']);
     $atts['department'] = html_entity_decode($atts['department']);
     $atts['city'] = html_entity_decode($atts['city']);
     $atts['state'] = html_entity_decode($atts['state']);
     $atts['zip_code'] = html_entity_decode($atts['zip_code']);
     $atts['country'] = html_entity_decode($atts['country']);
     $atts['category_name'] = html_entity_decode($atts['category_name']);
     if (0 < strlen($atts['meta_query'])) {
         // The meta query syntax follows the JSON standard, except, the WordPress Shortcode API does not allow
         // brackets within shortcode options, so parenthesis have to be used instead, so, lets swap them
         // that was json_decode can be ran and the resulting array used in cnRetrieve::entries().
         $atts['meta_query'] = str_replace(array('(', ')'), array('[', ']'), $atts['meta_query']);
         $metaQuery = cnFormatting::maybeJSONdecode($atts['meta_query']);
         $atts['meta_query'] = is_array($metaQuery) ? $metaQuery : array();
     }
     $atts = apply_filters('cn_list_retrieve_atts', $atts);
     $atts = apply_filters('cn_list_retrieve_atts-' . $template->getSlug(), $atts);
     $results = $instance->retrieve->entries($atts);
     // $html .= print_r( $instance->lastQuery, TRUE );
     // Apply any registered filters to the results.
     if (!empty($results)) {
         $results = apply_filters('cn_list_results', $results);
         $results = apply_filters('cn_list_results-' . $template->getSlug(), $results);
         self::addFilterRegistry('cn_list_results-' . $template->getSlug());
     }
     ob_start();
     // Prints the template's CSS file.
     // NOTE: This is primarily to support legacy templates which included a CSS
     // file which was not enqueued in the page header.
     do_action('cn_template_inline_css-' . $template->getSlug(), $atts);
     // The return to top anchor
     do_action('cn_list_return_to_target', $atts);
     $html .= ob_get_clean();
     $html .= sprintf('<div class="cn-list" id="cn-list" data-connections-version="%1$s-%2$s"%3$s>', $instance->options->getVersion(), $instance->options->getDBVersion(), empty($atts['width']) ? '' : ' style="width: ' . $atts['width'] . 'px;"');
     $html .= sprintf('<div class="cn-template cn-%1$s" id="cn-%1$s" data-template-version="%2$s">', $template->getSlug(), $template->getVersion());
     // The filter should check $content that content is not empty before processing $content.
     // And if it is empty the filter should return (bool) FALSE, so the core template parts can be executed.
     $content = apply_filters("cn_shortcode_content-{$tag}", FALSE, $content, $atts, $results, $template);
     if ($content === FALSE) {
         ob_start();
         // Render the core result list header.
         cnTemplatePart::header($atts, $results, $template);
         // Render the core result list body.
         cnTemplatePart::body($atts, $results, $template);
         // Render the core result list footer.
         cnTemplatePart::footer($atts, $results, $template);
         $html .= ob_get_clean();
     } else {
         $html .= $content;
     }
     $html .= PHP_EOL . '</div>' . (WP_DEBUG ? '<!-- END #cn-' . $template->getSlug() . ' -->' : '') . PHP_EOL;
     $html .= PHP_EOL . '</div>' . (WP_DEBUG ? '<!-- END #cn-list -->' : '') . PHP_EOL;
     // Clear any filters that have been added.
     // This allows support using the shortcode multiple times on the same page.
     cnShortcode::clearFilterRegistry();
     // @todo This should be run via a filter.
     return self::removeEOL($html);
 }
 /**
  * This is the registered function calls for the Connections admin pages as registered
  * using the add_menu_page() and add_submenu_page() WordPress functions.
  *
  * @access private
  * @since unknown
  */
 public static function showPage()
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     if ($instance->dbUpgrade) {
         include_once CN_PATH . 'includes/inc.upgrade.php';
         connectionsShowUpgradePage();
         return;
     }
     switch ($_GET['page']) {
         case 'connections_dashboard':
             include_once CN_PATH . 'includes/admin/pages/dashboard.php';
             connectionsShowDashboardPage();
             break;
         case 'connections_manage':
             include_once CN_PATH . 'includes/admin/pages/manage.php';
             $action = isset($_GET['cn-action']) && !empty($_GET['cn-action']) ? $_GET['cn-action'] : '';
             connectionsShowViewPage(esc_attr($action));
             break;
         case 'connections_add':
             include_once CN_PATH . 'includes/admin/pages/manage.php';
             connectionsShowViewPage('add_entry');
             break;
         case 'connections_categories':
             include_once CN_PATH . 'includes/admin/pages/categories.php';
             connectionsShowCategoriesPage();
             break;
         case 'connections_settings':
             include_once CN_PATH . 'includes/admin/pages/settings.php';
             connectionsShowSettingsPage();
             break;
         case 'connections_tools':
             include_once CN_PATH . 'includes/admin/pages/tools.php';
             connectionsShowToolsPage();
             break;
         case 'connections_templates':
             include_once CN_PATH . 'includes/admin/pages/templates.php';
             connectionsShowTemplatesPage();
             break;
         case 'connections_roles':
             include_once CN_PATH . 'includes/admin/pages/roles.php';
             connectionsShowRolesPage();
             break;
     }
 }
 /**
  * Register the metaboxes.
  *
  * @access private
  * @since 0.8
  *
  * @global string $hook_suffix The current admin page hook.
  *
  * @return void
  */
 public static function register()
 {
     global $hook_suffix;
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     // The metaboxes only need to be added on the manage page if performing an action to an entry.
     // This is to prevent the metaboxes from showing on the Screen Option tab on the Manage
     // admin page when viewing the manage entries table.
     if ($hook_suffix == $instance->pageHook->manage && !isset($_GET['cn-action'])) {
         return;
     }
     foreach (self::$metaboxes as $metabox) {
         if (in_array($hook_suffix, $metabox['pages'])) {
             cnMetabox_Render::add($hook_suffix, $metabox);
         }
     }
 }
    /**
     * Return an array of entry ID/s found with the supplied search terms.
     *
     * @todo Allow the fields for each table to be defined as a comma delimited list, convert an array and validate against of list of valid table fields.
     * @todo Add a filter to allow the search fields to be changed.
     *
     * Resources used:
     *  http://devzone.zend.com/26/using-mysql-full-text-searching/
     *  http://onlamp.com/onlamp/2003/06/26/fulltext.html
     *
     * @since  0.7.2.0
     * @param  array   $atts [optional]
     *
     * @return array
     */
    public function search($atts = array())
    {
        /** @var wpdb $wpdb */
        global $wpdb;
        // Grab an instance of the Connections object.
        $instance = Connections_Directory();
        $results = array();
        $scored = array();
        $fields = $instance->options->getSearchFields();
        $fields = apply_filters('cn_search_fields', $fields);
        // If no search search fields are set, return an empty array.
        if (empty($fields)) {
            return array();
        }
        /*
         * // START -- Set the default attributes array. \\
         */
        $defaults['terms'] = array();
        if (in_array('family_name', $fields)) {
            $defaults['fields']['entry'][] = 'family_name';
        }
        if (in_array('first_name', $fields)) {
            $defaults['fields']['entry'][] = 'first_name';
        }
        if (in_array('middle_name', $fields)) {
            $defaults['fields']['entry'][] = 'middle_name';
        }
        if (in_array('last_name', $fields)) {
            $defaults['fields']['entry'][] = 'last_name';
        }
        if (in_array('title', $fields)) {
            $defaults['fields']['entry'][] = 'title';
        }
        if (in_array('organization', $fields)) {
            $defaults['fields']['entry'][] = 'organization';
        }
        if (in_array('department', $fields)) {
            $defaults['fields']['entry'][] = 'department';
        }
        if (in_array('contact_first_name', $fields)) {
            $defaults['fields']['entry'][] = 'contact_first_name';
        }
        if (in_array('contact_last_name', $fields)) {
            $defaults['fields']['entry'][] = 'contact_last_name';
        }
        if (in_array('bio', $fields)) {
            $defaults['fields']['entry'][] = 'bio';
        }
        if (in_array('notes', $fields)) {
            $defaults['fields']['entry'][] = 'notes';
        }
        if (in_array('address_line_1', $fields)) {
            $defaults['fields']['address'][] = 'line_1';
        }
        if (in_array('address_line_2', $fields)) {
            $defaults['fields']['address'][] = 'line_2';
        }
        if (in_array('address_line_3', $fields)) {
            $defaults['fields']['address'][] = 'line_3';
        }
        if (in_array('address_city', $fields)) {
            $defaults['fields']['address'][] = 'city';
        }
        if (in_array('address_state', $fields)) {
            $defaults['fields']['address'][] = 'state';
        }
        if (in_array('address_zipcode', $fields)) {
            $defaults['fields']['address'][] = 'zipcode';
        }
        if (in_array('address_country', $fields)) {
            $defaults['fields']['address'][] = 'country';
        }
        if (in_array('phone_number', $fields)) {
            $defaults['fields']['phone'][] = 'number';
        }
        $atts = wp_parse_args($atts, apply_filters('cn_search_atts', $defaults));
        // @todo Validate each fiels array to ensure only permitted fields will be used.
        /*
         * // END -- Set the default attributes array if not supplied. \\
         */
        // If no search terms were entered, return an empty array.
        if (empty($atts['terms'])) {
            return array();
        }
        // If value is a string, stripe the white space and covert to an array.
        if (!is_array($atts['terms'])) {
            $atts['terms'] = explode(' ', trim($atts['terms']));
        }
        // Trim any white space from around the terms in the array.
        array_walk($atts['terms'], 'trim');
        $atts['terms'] = apply_filters('cn_search_terms', $atts['terms']);
        // Remove any single characters and stop words from terms.
        $atts['terms'] = $this->parse_search_terms($atts['terms']);
        // If no search terms are left after removing stop words, return an empty array.
        if (empty($atts['terms'])) {
            return array();
        }
        /*
         * Perform search using FULLTEXT if enabled.
         *
         * Perform the search on each table individually because joining the tables doesn't scale when
         * there are a large number of entries.
         *
         * NOTES:
         * 	The following is the error reported by MySQL when DB does not support FULLTEXT:  'The used table type doesn't support FULLTEXT indexes'
         * 	If DB does not support FULLTEXT the query will fail and the $results will be an empty array.
         *
         * 	FULLTEXT Restrictions as noted here: http://onlamp.com/onlamp/2003/06/26/fulltext.html
         *
         * 		Some of the default behaviors of these restrictions can be changed in your my.cnf or using the SET command
         *
         * 		FULLTEXT indices are NOT supported in InnoDB tables.
         * 		MySQL requires that you have at least three rows of data in your result set before it will return any results.
         * 		By default, if a search term appears in more than 50% of the rows then MySQL will not return any results.
         * 		By default, your search query must be at least four characters long and may not exceed 254 characters.
         * 		MySQL has a default stopwords file that has a list of common words (i.e., the, that, has) which are not returned in your search. In other words, searching for the will return zero rows.
         * 		According to MySQL's manual, the argument to AGAINST() must be a constant string. In other words, you cannot search for values returned within the query.
         */
        if (cnSettingsAPI::get('connections', 'search', 'fulltext_enabled')) {
            $terms = array();
            $shortwords = array();
            /*
             * Remove any shortwords from the FULLTEXT query since the db will drop them anyway.
             * Add the shortwords to a separate array to be used to do a LIKE query.
             */
            foreach ($atts['terms'] as $key => $term) {
                if (strlen($term) >= 2 && strlen($term) <= 3) {
                    unset($atts['terms'][$key]);
                    $shortwords[] = $term;
                }
            }
            if (!empty($atts['terms'])) {
                // Make each term required, functional AND query.
                $terms = apply_filters('cn_search_fulltext_terms', '+' . implode(' +', $atts['terms']));
            }
            /*
             * Only search the primary records if at least one fields is selected to be searched.
             */
            if (!empty($atts['fields']['entry'])) {
                $select = array();
                $from = array();
                $where = array();
                $like = array();
                $select[] = 'SELECT ' . CN_ENTRY_TABLE . '.id';
                /*
                 * Set up the SELECT to return the results scored by relevance.
                 */
                if (!empty($terms)) {
                    $select[] = $wpdb->prepare('MATCH (' . implode(', ', $atts['fields']['entry']) . ') AGAINST (%s) AS score', $terms);
                }
                $from[] = CN_ENTRY_TABLE;
                /*
                 * If there are long word terms, perform a FULLTEXT query.
                 */
                if (!empty($terms)) {
                    $where[] = $wpdb->prepare('MATCH (' . implode(', ', $atts['fields']['entry']) . ') AGAINST (%s IN BOOLEAN MODE)', $terms);
                }
                /*
                 * If there are no long words and there are short words, perform a LIKE query for the short words.
                 */
                if (empty($terms) && !empty($shortwords)) {
                    foreach ($shortwords as $word) {
                        $like[] = $wpdb->prepare(implode(' LIKE %s OR ', $atts['fields']['entry']) . ' LIKE %s ', array_fill(0, count($atts['fields']['entry']), $wpdb->esc_like($word) . '%'));
                    }
                    $where[] = '( ' . implode(') OR (', $like) . ')';
                }
                /*
                 * Return the query results ordered by the relevance score.
                 */
                $orderBy = empty($terms) ? '' : ' ORDER BY score';
                $sql = implode(', ', $select) . ' FROM ' . implode(',', $from) . ' WHERE ' . implode(' AND ', $where) . $orderBy;
                $scored = $wpdb->get_results($sql, ARRAY_A);
            }
            /*
             * Only search the address records if at least one fields is selected to be searched.
             */
            if (!empty($atts['fields']['address'])) {
                $select = array();
                $from = array();
                $where = array();
                $like = array();
                $select[] = 'SELECT ' . CN_ENTRY_ADDRESS_TABLE . '.entry_id';
                /*
                 * Set up the SELECT to return the results scored by relevance.
                 */
                if (!empty($terms)) {
                    $select[] = $wpdb->prepare('MATCH (' . implode(', ', $atts['fields']['address']) . ') AGAINST (%s) AS score', $terms);
                }
                $from[] = CN_ENTRY_ADDRESS_TABLE;
                /*
                 * If there are long word terms, perform a FULLTEXT query.
                 */
                if (!empty($terms)) {
                    $where[] = $wpdb->prepare('MATCH (' . implode(', ', $atts['fields']['address']) . ') AGAINST (%s IN BOOLEAN MODE)', $terms);
                }
                /*
                 * If there are no long words and there are short words, perform a LIKE query for the short words.
                 */
                if (empty($terms) && !empty($shortwords)) {
                    foreach ($shortwords as $word) {
                        $like[] = $wpdb->prepare(implode(' LIKE %s OR ', $atts['fields']['address']) . ' LIKE %s ', array_fill(0, count($atts['fields']['address']), $wpdb->esc_like($word) . '%'));
                    }
                    $where[] = '( ' . implode(') OR (', $like) . ')';
                }
                /*
                 * Return the query results ordered by the relevance score.
                 */
                $orderBy = empty($terms) ? '' : ' ORDER BY score';
                $sql = implode(', ', $select) . ' FROM ' . implode(',', $from) . ' WHERE ' . implode(' AND ', $where) . $orderBy;
                $ids = $wpdb->get_results($sql, ARRAY_A);
                /*
                 * If any results are returned merge them in to the $scored results.
                 */
                if (!empty($ids)) {
                    $scored = array_merge($scored, $ids);
                }
            }
            /*
             * Only search the phone records if thefield is selected to be search.
             */
            if (!empty($atts['fields']['phone'])) {
                $select = array();
                $from = array();
                $where = array();
                $like = array();
                $select[] = 'SELECT ' . CN_ENTRY_PHONE_TABLE . '.entry_id';
                /*
                 * Set up the SELECT to return the results scored by relevance.
                 */
                if (!empty($terms)) {
                    $select[] = $wpdb->prepare('MATCH (' . implode(', ', $atts['fields']['phone']) . ') AGAINST (%s) AS score', $terms);
                }
                $from[] = CN_ENTRY_PHONE_TABLE;
                /*
                 * If there are long word terms, perform a FULLTEXT query.
                 */
                if (!empty($terms)) {
                    $where[] = $wpdb->prepare('MATCH (' . implode(', ', $atts['fields']['phone']) . ') AGAINST (%s IN BOOLEAN MODE)', $terms);
                }
                /*
                 * If there are no long words and there are short words, perform a LIKE query for the short words.
                 */
                if (empty($terms) && !empty($shortwords)) {
                    foreach ($shortwords as $word) {
                        $like[] = $wpdb->prepare(implode(' LIKE %s OR ', $atts['fields']['phone']) . ' LIKE %s ', array_fill(0, count($atts['fields']['phone']), $wpdb->esc_like($word) . '%'));
                    }
                    $where[] = '( ' . implode(') OR (', $like) . ')';
                }
                /*
                 * Return the query results ordered by the relevance score.
                 */
                $orderBy = empty($terms) ? '' : ' ORDER BY score';
                $sql = implode(', ', $select) . ' FROM ' . implode(',', $from) . ' WHERE ' . implode(' AND ', $where) . $orderBy;
                $ids = $wpdb->get_results($sql, ARRAY_A);
                /*
                 * If any results are returned merge them in to the $scored results.
                 */
                if (!empty($ids)) {
                    $scored = array_merge($scored, $ids);
                }
            }
            $scored = apply_filters('cn_search_scored_results', $scored, $terms);
            /*
             * The query results are stored in the $scored array ordered by relevance.
             * Only the entry ID/s are needed to be returned. Setup the $results array
             * with only the entry ID/s in the same order as returned by the relevance score.
             */
            foreach ($scored as $entry) {
                $results[] = isset($entry['id']) ? $entry['id'] : $entry['entry_id'];
            }
        }
        /*
         * If no results are found, perhaps to the way MySQL performs FULLTEXT queries, FULLTEXT search being disabled
         * or the DB not supporting FULLTEXT, run a LIKE query.
         *
         * Perform the search on each table individually because joining the tables doesn't scale when
         * there are a large number of entries.
         */
        if ((cnSettingsAPI::get('connections', 'search', 'keyword_enabled') && empty($results) || cnSettingsAPI::get('connections', 'search', 'fulltext_enabled') && empty($results)) && !empty($atts['terms'])) {
            /*
             * Only search the primary records if at least one fields is selected to be searched.
             */
            if (!empty($atts['fields']['entry'])) {
                $like = array();
                // Reset the like array.
                foreach ($atts['terms'] as $term) {
                    /*
                     * Attempt to secure the query using $wpdb->prepare() and like_escape()
                     *
                     * Since $wpdb->prepare() required var for each directive in the query string we'll use array_fill
                     * where the count based on the number of columns that will be searched.
                     */
                    $like[] = $wpdb->prepare(implode(' LIKE %s OR ', $atts['fields']['entry']) . ' LIKE %s ', array_fill(0, count($atts['fields']['entry']), '%' . $wpdb->esc_like($term) . '%'));
                }
                $sql = 'SELECT ' . CN_ENTRY_TABLE . '.id
									FROM ' . CN_ENTRY_TABLE . '
									WHERE (' . implode(') OR (', $like) . ')';
                //print_r($sql);
                $results = array_merge($results, $wpdb->get_col($sql));
                //print_r($results);die;
            }
            /*
             * Only search the address records if at least one fields is selected to be searched.
             */
            if (!empty($atts['fields']['address'])) {
                $like = array();
                // Reset the like array.
                foreach ($atts['terms'] as $term) {
                    /*
                     * Attempt to secure the query using $wpdb->prepare() and like_escape()
                     *
                     * Since $wpdb->prepare() required var for each directive in the query string we'll use array_fill
                     * where the count based on the number of columns that will be searched.
                     */
                    $like[] = $wpdb->prepare(implode(' LIKE %s OR ', $atts['fields']['address']) . ' LIKE %s ', array_fill(0, count($atts['fields']['address']), '%' . $wpdb->esc_like($term) . '%'));
                }
                $sql = 'SELECT ' . CN_ENTRY_ADDRESS_TABLE . '.entry_id
									FROM ' . CN_ENTRY_ADDRESS_TABLE . '
									WHERE (' . implode(') OR (', $like) . ')';
                //print_r($sql);
                $results = array_merge($results, $wpdb->get_col($sql));
                //print_r($results);
            }
            /*
             * Only search the phone records if the field is selected to be search.
             */
            if (!empty($atts['fields']['phone'])) {
                $like = array();
                // Reset the like array.
                foreach ($atts['terms'] as $term) {
                    /*
                     * Attempt to secure the query using $wpdb->prepare() and like_escape()
                     *
                     * Since $wpdb->prepare() required var for each directive in the query string we'll use array_fill
                     * where the count based on the number of columns that will be searched.
                     */
                    $like[] = $wpdb->prepare(implode(' LIKE %s OR ', $atts['fields']['phone']) . ' LIKE %s ', array_fill(0, count($atts['fields']['phone']), '%' . $wpdb->esc_like($term) . '%'));
                }
                $sql = 'SELECT ' . CN_ENTRY_PHONE_TABLE . '.entry_id
									FROM ' . CN_ENTRY_PHONE_TABLE . '
									WHERE (' . implode(') OR (', $like) . ')';
                //print_r($sql);
                $results = array_merge($results, $wpdb->get_col($sql));
                //print_r($results);
            }
        }
        return apply_filters('cn_search_results', $results, $atts);
    }
 /**
  * Enqueues the Connections CSS on the required admin pages.
  *
  * @access private
  * @since  0.7.3.2
  * @static
  *
  * @uses   Connections_Directory()
  * @uses   wp_enqueue_style()
  * @uses   do_action()
  * @uses   apply_filters()
  *
  * @param  string $pageHook The current admin page hook.
  *
  * @return void
  */
 public static function enqueueAdminStyles($pageHook)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     // Load on all the Connections admin pages.
     if (in_array($pageHook, get_object_vars($instance->pageHook))) {
         wp_enqueue_style('cn-admin');
         wp_enqueue_style('cn-admin-jquery-ui');
         wp_enqueue_style('cn-admin-jquery-datepicker');
         wp_enqueue_style('cn-font-awesome');
         if (is_rtl()) {
             wp_enqueue_style('cn-admin-rtl');
         }
         do_action('cn_admin_enqueue_styles', $pageHook);
     }
     $editPages = apply_filters('cn_admin_required_edit_scripts', array($instance->pageHook->manage, $instance->pageHook->add));
     if (in_array($pageHook, $editPages)) {
         wp_enqueue_style('cn-chosen');
         do_action('cn_admin_enqueue_edit_styles', $pageHook);
     }
 }
Beispiel #26
0
 /**
  * Update the post date and post modified date to reflect the current entry being viewed.
  *
  * @access private
  * @since  8.1
  * @static
  *
  * @uses   is_main_query()
  * @uses   get_query_var()
  * @uses   get_gmt_from_date()
  *
  * @param  array  $posts    An array of WP_Post objects.
  * @param  object $wp_query A reference to the WP_Query object
  *
  * @return array
  */
 public static function postDates($posts, $wp_query)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     if ($wp_query->is_main_query() && get_query_var('cn-entry-slug')) {
         $result = $instance->retrieve->entries(array('slug' => urldecode(get_query_var('cn-entry-slug'))));
         $modified = $result[0]->ts;
         $created = $result[0]->date_added ? date('Y-m-d H:i:s', $result[0]->date_added) : $result[0]->ts;
         if (isset($posts[0])) {
             if (isset($posts[0]->post_date)) {
                 $posts[0]->post_date = $created;
                 $posts[0]->post_date_gmt = get_gmt_from_date($created);
             }
             if (isset($posts[0]->post_modified)) {
                 $posts[0]->post_modified = $modified;
                 $posts[0]->post_modified_gmt = get_gmt_from_date($modified);
             }
         }
     }
     return $posts;
 }
 /**
  * Bulk category actions.
  *
  * @access public
  * @since 0.7.7
  * @uses current_user_can()
  * @uses check_admin_referer()
  * @uses wp_redirect()
  * @uses get_admin_url()
  * @uses get_current_blog_id()
  * @return void
  */
 public static function categoryManagement()
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $action = '';
     if (isset($_REQUEST['action']) && '-1' !== $_REQUEST['action']) {
         $action = $_REQUEST['action'];
     } elseif (isset($_REQUEST['action2']) && '-1' !== $_REQUEST['action2']) {
         $action = $_REQUEST['action2'];
     }
     /*
      * Check whether user can edit Settings
      */
     if (current_user_can('connections_edit_categories')) {
         switch ($action) {
             case 'delete':
                 check_admin_referer('bulk-terms');
                 foreach ((array) $_POST['category'] as $id) {
                     $result = $instance->retrieve->category(absint($id));
                     $category = new cnCategory($result);
                     $category->delete();
                 }
                 break;
         }
         $url = get_admin_url(get_current_blog_id(), 'admin.php?page=connections_categories');
         if (isset($_REQUEST['paged']) && !empty($_REQUEST['paged'])) {
             $page = absint($_REQUEST['paged']);
             $url = add_query_arg(array('paged' => $page), $url);
         }
         wp_redirect($url);
         exit;
     } else {
         cnMessage::set('error', 'capability_categories');
     }
 }
Beispiel #28
0
/**
 * Renders the Template admin page.
 *
 * @access private
 * @since  unknown
 */
function connectionsShowTemplatesPage()
{
    /*
     * Check whether user can edit Settings
     */
    if (!current_user_can('connections_manage_template')) {
        wp_die('<p id="error-page" style="-moz-background-clip:border;
				-moz-border-radius:11px;
				background:#FFFFFF none repeat scroll 0 0;
				border:1px solid #DFDFDF;
				color:#333333;
				display:block;
				font-size:12px;
				line-height:18px;
				margin:25px auto 20px;
				padding:1em 2em;
				text-align:center;
				width:700px">' . __('You do not have sufficient permissions to access this page.', 'connections') . '</p>');
    } else {
        // Grab an instance of the Connections object.
        $instance = Connections_Directory();
        $type = isset($_GET['type']) ? esc_attr($_GET['type']) : 'all';
        $templates = cnTemplateFactory::getCatalog($type);
        $adminURL = self_admin_url('admin.php');
        $pageURL = add_query_arg('page', 'connections_templates', $adminURL);
        $homeID = cnSettingsAPI::get('connections', 'connections_home_page', 'page_id');
        $homeURL = get_permalink($homeID);
        $customizerURL = add_query_arg('cn-customize-template', 'true', $homeURL);
        ?>
		<div class="wrap">

			<h1>Connections : <?php 
        _e('Templates', 'connections');
        ?>
				<a class="button add-new-h2" href="http://connections-pro.com/templates/" target="_blank"><?php 
        _e('Get More', 'connections');
        ?>
</a>
			</h1>

			<ul class="subsubsub">
				<li>
					<a <?php 
        if ('all' == $type) {
            echo 'class="current" ';
        }
        ?>
href="<?php 
        echo esc_url(add_query_arg('type', 'all', $pageURL));
        ?>
">
						<?php 
        _e('All', 'connections');
        ?>
					</a> |
				</li>
				<li>
					<a <?php 
        if ('individual' == $type) {
            echo 'class="current" ';
        }
        ?>
href="<?php 
        echo esc_url(add_query_arg('type', 'individual', $pageURL));
        ?>
">
						<?php 
        _e('Individual', 'connections');
        ?>
					</a> |
				</li>
				<li>
					<a <?php 
        if ('organization' == $type) {
            echo 'class="current" ';
        }
        ?>
href="<?php 
        echo esc_url(add_query_arg('type', 'organization', $pageURL));
        ?>
">
						<?php 
        _e('Organization', 'connections');
        ?>
					</a> |
				</li>
				<li>
					<a <?php 
        if ('family' == $type) {
            echo 'class="current" ';
        }
        ?>
href="<?php 
        echo esc_url(add_query_arg('type', 'family', $pageURL));
        ?>
">
						<?php 
        _e('Family', 'connections');
        ?>
					</a> |
				</li>
				<li>
					<a <?php 
        if ('anniversary' == $type) {
            echo 'class="current" ';
        }
        ?>
href="<?php 
        echo esc_url(add_query_arg('type', 'anniversary', $pageURL));
        ?>
">
						<?php 
        _e('Anniversary', 'connections');
        ?>
					</a> |
				</li>
				<li>
					<a <?php 
        if ('birthday' == $type) {
            echo 'class="current" ';
        }
        ?>
href="<?php 
        echo esc_url(add_query_arg('type', 'birthday', $pageURL));
        ?>
">
						<?php 
        _e('Birthday', 'connections');
        ?>
					</a>
				</li>
			</ul>

			<br class="clear">

			<table cellspacing="0" cellpadding="0" id="currenttheme">
				<tbody>
					<tr>
						<td class="current_template">
							<h2><?php 
        _e('Current Template', 'connections');
        ?>
</h2>

							<div id="current-template">
								<?php 
        $slug = $instance->options->getActiveTemplate($type);
        /** @var cnTemplate $activeTemplate */
        $activeTemplate = cnTemplateFactory::getTemplate($slug);
        if ($activeTemplate) {
            cnTemplateThumbnail($activeTemplate);
            cnTemplateAuthor($activeTemplate);
            cnTemplateDescription($activeTemplate);
            cnTemplateCustomizerButton($activeTemplate, $customizerURL, $pageURL);
            // Remove the current template so it does not show in the available templates.
            unset($templates->{$activeTemplate->getSlug()});
        } else {
            echo '<h3 class="error"> Template ', esc_attr($slug), ' can not be found.</h3>';
        }
        ?>
							</div>
							<div class="clear"></div>
						</td>

						<td class="template_instructions" colspan="2">
							<p>
								<strong><?php 
        _e('Instructions', 'connections');
        ?>
:</strong>
							</p>

							<p>
								<?php 
        _e('By default the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/">&#91;connections&#93;</a></code> shortcode will show all entries types. To change the template used when displaying all entry types, select the "All" tab and activate the template. When the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/list_type/">list_type</a></code>shortcode option is used to filter the entries based on the entry type, the template for that entry type will be used. To change the template used for a specific entry type, select the appropriate tab and then activate the template. If multiple entry types are specified in the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/list_type/">list_type</a></code> shortcode option, the template for the entry type listed first will be used to display the entry list.', 'connections');
        ?>
							</p>

							<p>
								<?php 
        _e('The <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-upcoming-list/">[upcoming_list]</a></code> shortcode which displays the upcoming anniversaries and birthdays will be displayed with the template that is activated under their respective tabs.', 'connections');
        ?>
							</p>

							<p>
								<?php 
        _e('The current active template for each template type can be overridden by using the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/template-option/">template</a></code> shortcode option.', 'connections');
        ?>
							</p>
						</td>
					</tr>
				</tbody>
			</table> <!-- /#currenttheme -->

			<table cellspacing="0" cellpadding="0" id="availablethemes">
				<tbody>
					<tr>
						<td class="current_template" colspan="3">
							<h2><?php 
        _e('Available Templates', 'connections');
        ?>
</h2>
						</td>
					</tr>

					<?php 
        $slugs = array_keys((array) $templates);
        natcasesort($slugs);
        $table = array();
        $rows = ceil(count($slugs) / 3);
        for ($row = 1; $row <= $rows; $row++) {
            for ($col = 1; $col <= 3; $col++) {
                $table[$row][$col] = array_shift($slugs);
            }
        }
        foreach ($table as $row => $cols) {
            ?>
						<tr>
							<?php 
            foreach ($cols as $col => $slug) {
                if (!isset($templates->{$slug})) {
                    continue;
                }
                /** @var cnTemplate $template */
                $template = $templates->{$slug};
                $class = array('available-theme');
                if ($row == 1) {
                    $class[] = 'top';
                }
                if ($row == $rows) {
                    $class[] = 'bottom';
                }
                if ($col == 1) {
                    $class[] = 'left';
                }
                if ($col == 3) {
                    $class[] = 'right';
                }
                ?>

								<td <?php 
                echo cnHTML::attribute('class', $class);
                ?>
>

									<?php 
                cnTemplateThumbnail($template);
                cnTemplateAuthor($template);
                cnTemplateDescription($template);
                cnTemplateDeactivateText($template);
                cnTemplateShortcodeOverride($template);
                ?>

									<span class="action-links">
										<?php 
                cntemplateActivateButton($template, $type);
                cnTemplateDeleteButton($template);
                cnTemplateCustomizerButton($template, $customizerURL, $pageURL);
                ?>
									</span>
								</td>
								<?php 
            }
            ?>
						</tr>
						<?php 
        }
        ?>
				</tbody>
			</table> <!-- /#availablethemes -->
		</div> <!-- /.wrap -->
		<?php 
    }
}
 /**
  * Load the template. The template that will be loaded will be
  * determined by the template activated under the `All` template type.
  * Unless overridden by either the `template` or `list_type` shortcode
  * options.
  *
  * @access private
  * @since  0.8
  * @static
  *
  * @param  array $atts The shortcode atts array.
  *
  * @return cnTemplate|FALSE An instance the of cnTemplate object or `FALSE` if the template was not found/loaded.
  */
 public static function loadTemplate($atts)
 {
     $type = 'all';
     $defaults = array('list_type' => NULL, 'template' => NULL);
     /**
      * @since 0.7.9.4
      *
      * @param array $atts {
      *     @type string $list_type The shortcode list_type attribute value.
      *     @type string $template  The template slug.
      * }
      */
     $defaults = apply_filters('cn_load_template', $defaults);
     $atts = shortcode_atts($defaults, $atts);
     if (!empty($atts['list_type'])) {
         $permittedTypes = array('individual', 'organization', 'family', 'connection_group');
         // Convert to array. Trim the space characters if present.
         $atts['list_type'] = explode(',', str_replace(' ', '', $atts['list_type']));
         // Set the template type to the first in the entry type from the supplied if multiple list types are provided.
         if (in_array($atts['list_type'][0], $permittedTypes)) {
             $type = $atts['list_type'][0];
             // Change the list type to family from connection_group to maintain compatibility with versions 0.7.0.4 and earlier.
             if ($type == 'connection_group') {
                 $type = 'family';
             }
         }
     }
     /*
      * If a list type was specified in the shortcode, load the template based on that type.
      * However, if a specific template was specified, that should preempt the template to be loaded based on the list type if it was specified..
      */
     if (!empty($atts['template'])) {
         $template = self::getTemplate($atts['template']);
     } else {
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         $slug = $instance->options->getActiveTemplate($type);
         $template = self::getTemplate($slug);
     }
     // If the template was not located, return FALSE.
     // This will in turn display the template not found error message
     // later in the execution of the shortcode.
     if ($template == FALSE) {
         return FALSE;
     }
     /** @var cnTemplate $template */
     do_action('cn_register_legacy_template_parts');
     do_action('cn_action_include_once-' . $template->getSlug());
     do_action('cn_action_js-' . $template->getSlug());
     return $template;
 }
 /**
  * Echos the family members of the family entry type.
  *
  * @access  public
  * @since   unknown
  *
  * @param array $atts {
  *     Optional.
  *
  *     @type string $container_tag The relationship container tag. Default `ul`. Accepts HTML tag.
  *     @type string $item_tag      The relationship row tag. Default `li`. Accepts HTML tag.
  *     @type string $item_format   The relationship row HTML markup.
  *     @type string $name_format   How the relationship name should be displayed @see cnEntry::getName().
  *     @type string $separator     The string used to separate the relation label from the relation name. Default ':'.
  *     @type string $before        HTML to be displayed before the relations container. Default, empty string.
  *     @type string $after         HTML to be displayed after the relations container. Default, empty string.
  *     @type string $before_item   HTML to be displayed before a relation row. Default, empty string.
  *     @type string $after_item    HTML to be displayed after a relation row. Default, empty string.
  * }
  *
  * @return string
  */
 public function getFamilyMemberBlock($atts = array())
 {
     $defaults = array('container_tag' => 'ul', 'item_tag' => 'li', 'item_format' => '<%1$s class="cn-relation"><span class="cn-relation-label">%relation%</span>%separator% <span class="cn-relation-name notranslate">%name%</span></%1$s>', 'name_format' => '', 'separator' => ':', 'before' => '', 'after' => '', 'before_item' => '', 'after_item' => '', 'return' => FALSE);
     /**
      * Filter the arguments.
      *
      * @since unknown
      *
      * @param array $atts An array of arguments.
      */
     $atts = cnSanitize::args(apply_filters('cn_output_family_atts', $atts), $defaults);
     $html = '';
     $search = array('%relation%', '%name%', '%separator%');
     if ($this->getFamilyMembers()) {
         // Grab an instance of the Connections object.
         $instance = Connections_Directory();
         foreach ($this->getFamilyMembers() as $key => $value) {
             $relation = new cnEntry();
             $replace = array();
             if ($relation->set($key)) {
                 $replace[] = $instance->options->getFamilyRelation($value);
                 $replace[] = cnURL::permalink(array('type' => 'name', 'slug' => $relation->getSlug(), 'title' => $relation->getName(array('format' => $atts['name_format'])), 'text' => $relation->getName(array('format' => $atts['name_format'])), 'home_id' => $this->directoryHome['page_id'], 'force_home' => $this->directoryHome['force_home'], 'return' => TRUE));
                 $replace[] = empty($atts['separator']) ? '' : '<span class="cn-separator">' . $atts['separator'] . '</span>';
                 $row = str_ireplace($search, $replace, empty($atts['item_format']) ? $defaults['item_format'] : $atts['item_format']);
                 $html .= "\t" . sprintf($row, $atts['item_tag']) . PHP_EOL;
             }
         }
         $html = sprintf('<%1$s class="cn-relations">' . PHP_EOL . '%2$s</%1$s>', $atts['container_tag'], $html);
         $html = $atts['before'] . $html . $atts['after'] . PHP_EOL;
     }
     return $this->echoOrReturn($atts['return'], $html);
 }