/**
  * Returns $description.
  *
  * @see cnCategory::$description
  */
 public function getDescription()
 {
     return $this->format->sanitizeString($this->description, TRUE);
 }
 /**
  * Renders a HTML tag attribute.
  *
  * @access public
  * @since  0.8
  *
  * @uses   sanitize_html_class()
  * @uses   esc_attr()
  *
  * @param  string       $type  The attribute name.
  * @param  array|string $value The attribute value.
  *
  * @return string        The rendered attribute.
  */
 public static function attribute($type, $value)
 {
     switch ($type) {
         case 'class':
             if (is_array($value) && !empty($value)) {
                 array_walk($value, 'sanitize_html_class');
                 return $value ? ' class="' . implode($value, ' ') . '" ' : '';
             } elseif (!empty($value)) {
                 return ' class="' . sanitize_html_class((string) $value) . '" ';
             } else {
                 return '';
             }
             break;
         case 'id':
             if (!empty($value)) {
                 return ' id="' . esc_attr((string) $value) . '" ';
             } else {
                 return '';
             }
             break;
         case 'style':
             if (is_array($value) && !empty($value)) {
                 array_walk($value, create_function('&$i, $property', '$i = "$property: $i";'));
                 return $value ? ' style="' . implode($value, '; ') . '"' : '';
             }
             return '';
             break;
         case 'value':
             return ' value="' . esc_attr((string) $value) . '" ';
             break;
         case 'data':
             $data = array();
             /**
              * Create valid HTML5 data attributes.
              *
              * @link http://stackoverflow.com/a/22753630/5351316
              * @link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
              */
             if (cnFunction::isDimensionalArray($value)) {
                 foreach ($value as $_value) {
                     if (isset($_value['name']) && 0 < strlen($_value['name'])) {
                         $name = 'data-' . cnFormatting::toCamelCase($_value['name']);
                         $data[$name] = $_value['value'];
                     }
                 }
             } else {
                 if (isset($value['name']) && 0 < strlen($value['name'])) {
                     $name = 'data-' . cnFormatting::toCamelCase($value['name']);
                     $data[$name] = $value['value'];
                 }
             }
             if (!empty($data)) {
                 array_walk($data, create_function('&$i, $name', '$i = $name . \'="\' . esc_attr( $i ) . \'"\';'));
                 return ' ' . implode($data, ' ');
             }
             return '';
             break;
         default:
             if (is_array($value) && !empty($value)) {
                 array_walk($value, 'esc_attr');
                 return $value ? ' ' . esc_attr($type) . '="' . implode($value, ' ') . '" ' : '';
             } elseif (!empty($value)) {
                 return ' ' . esc_attr($type) . '="' . esc_attr((string) $value) . '" ';
             } else {
                 return '';
             }
     }
 }
 /**
  * @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);
 }
Example #4
0
 /**
  * Uses WP's Image Editor Class to crop and resize images.
  *
  * Derived from bfithumb.
  * @link https://github.com/bfintal/bfi_thumb
  * Incorporated crop only from Github pull request 13
  * @link https://github.com/bfintal/bfi_thumb/pull/13
  * Also incorporates positional cropping and image quality change from the Dominic Whittle bfithumb fork:
  * @link https://github.com/dominicwhittle/bfi_thumb
  * Crop mode support was inspired by TimThumb.
  * @link http://www.binarymoon.co.uk/projects/timthumb/
  *
  * bfiThumb was inspired by Aqua Resizer
  * @url https://github.com/syamilmj/Aqua-Resizer
  *
  * @todo  Should an option be added to control the order filters should be applied be added? Filter order can affect result...
  *
  * Accepted option for the $atts property are:
  * 	width (int|string) Width in pixels or percentage. If using percentage, the percentage symbol must be included, example `50%`.
  * 	height (int|string) Height in pixels or percentage. If using percentage, the percentage symbol must be included, example `50%`.
  *
  * 	negate (bool) Whether or not to apply the negate filter. Default: FALSE
  * 	grayscale (bool) Whether or not to apply the grayscale filter. Default: FALSE
  * 	brightness (int) Adjust the image brightness. Valid range is -255–255 (-255 = min brightness, 0 = no change, +255 = max brightness). Default: 0
  * 	colorize (string) Colorize the image. Either a valid hex-color #000000–#ffffff or a HTML named color like `red` can be supplied. Default: NULL
  * 		@see  cnColor::$colors for a list of valid named colors.
  * 	contrast (int) Ajust the image contrast. Valid range is -100–100 (-100 = max contrast, 0 = no change, +100 = min contrast [note the direction]) Default: 0
  * 	detect_edges (bool) Whether of not to apply the detect edges filter. Default: FALSE
  * 	emboss (bool) Whether or not to apply the emboss filter. Default: FALSE
  * 	gassian_blur (bool) Whether of not to apply a gaussian blur. Default: FALSE
  * 	blur (bool) Whether or not to apply the blur filter. Default: FALSE
  * 	sketchy (bool) Whether or not to apply the the skethy filter. Default: FALSE
  * 	sharpen (bool) Whether or not to apply the sharpen filter. Default: FALSE
  * 	smooth (int) Apply the smooth filter. Valid range is -100–100 (-100 = max smooth, 100 = min smooth). Default: NULL
  * 	opacity (int) Set the image opacity. Valid range is 0–100 (0 = fully transparent, 100 = fully opaque). Default: 100
  *
  * 	crop_mode (int) Which crop mode to utilize when rescaling the image. Valid range is 0–3. Default: 1
  * 		0 == Resize to Fit specified dimensions with no cropping. Aspect ratio will not be maintained.
  * 		1 == Crop and resize to best fit dimensions maintaining aspect ration. Default.
  * 		2 == Resize proportionally to fit entire image into specified dimensions, and add margins if required.
  * 			Use the canvas_color option to set the color to be used when adding margins.
  * 		3 == Resize proportionally adjusting size of scaled image so there are no margins added.
  * 	crop_focus (array|string) The crop focus/positional cropping is used to determine the center origin of a crop when crop_mode is set 1.
  * 		Valid range is (float) 0.0–1.0
  * 		Default: array( .5, .5)
  * 		Text options are also supported:
  * 			'left,top' | array( 'left', 'top' ) == array( 0, 0 )
  * 			'center,top' | array( 'center', 'top' ) == array( .5, 0 )
  * 			'right,top' | array( 'right', 'top' ) == array( 1, 0 )
  * 			'left,center' | array( 'left', 'center' )  == array( 0, .5 )
  * 			'center,center' | array( 'center', 'center' ) == array( .5, .5) [the default crop focus].
  * 			'right,center' | array( 'right', 'center' ) == array( 1, .5 )
  * 			'left,bottom' | array( 'left', 'bottom' ) == array( 0, 1 )
  * 			'center,bottom' | array( 'center', 'bottom' ) == array( .5, 1 )
  * 			'right,bottom' | array( 'right', 'bottom' ) == array( 1, 1 )
  *
  * 	crop_only (bool) Whether or not to just crop the image.
  * 		If set to TRUE, crop_x, crop_y, crop_width, crop_height must be supplied.
  * 		This overrides crop_mode.
  * 		Default: FALSE
  * 	crop_x (int|string) The x-axis crop origin start in pixels or percentage. If using percentage, the percentage symbol must be included, example `50%`.
  * 	crop_y (int|string) The y-axis crop origin start in pixels or percentage. If using percentage, the percentage symbol must be included, example `50%`.
  * 	crop_width (int|string) The resize width of the crop in pixels or percentage. If using percentage, the percentage symbol must be included, example `50%`.
  * 		The width option can be set to determine the final scaled width.
  * 	crop_height (int|string) The resize height of the crop in pixels or percentage. If using percentage, the percentage symbol must be included, example `50%`.
  * 		The height option can be set to determine the final scaled height.
  *
  * 	canvas_color (string) Either a valid hex-color #000000–#ffffff or a HTML named color like `red` can be supplied or set to 'transparent'.
  * 		The canvas_color is only used when using crop_mode=2. This will be the color of the margins.
  * 		Default: #FFFFFF
  * 		@see  cnColor::$colors for a list of valid named colors.
  *
  * 	quality (int) The image quality to be used when saving the image. Valid range is 1–100. Default: 90
  *
  * @param  string $source The local image path or URL to process. The image must be in the upload folder or the theme folder.
  * @param  array  $atts   An associative array containing the options used to process the image.
  * @param  string $return
  *
  * @return mixed  array | object | string | stream
  *                If $return is `base64` then base64 encoded image data URI will be returned. Suitable for use in CSS or img src attribute.
  *                If $return is `data` and array of the image meta is returned.
  *                If $return is `editor` an instance if the WP_Image_Editor is returned.
  *                If $return is `stream` the image resource will be streamed to the browser with the correct headers set.
  *                If $return is `url` the image URL will be returned. [Default]
  */
 public static function get($source, $atts = array(), $return = 'url')
 {
     global $wp_filter;
     // Increase PHP script execution by 60. This should help on hosts
     // that permit this change from page load timeouts from occurring
     // due to large number of images that might have to be created and cached.
     @set_time_limit(60);
     // Set artificially high because GD uses uncompressed images in memory.
     // Even though Imagick uses less PHP memory than GD, set higher limit for users that have low PHP.ini limits.
     @ini_set('memory_limit', apply_filters('image_memory_limit', WP_MAX_MEMORY_LIMIT));
     $filter = array();
     $methods = array();
     $log = new cnLog_Stateless();
     /*
      * Temporarily store the filters hooked to the image editor filters.
      */
     $filter['editors'] = isset($wp_filter['wp_image_editors']) ? $wp_filter['wp_image_editors'] : '';
     $filter['resize'] = isset($wp_filter['image_resize_dimensions']) ? $wp_filter['image_resize_dimensions'] : '';
     /*
      * Remove all filters hooked into the the image editor filters to prevent conflicts.
      */
     remove_all_filters('wp_image_editors');
     remove_all_filters('image_resize_dimensions');
     /*
      * Start an instance of the logger if WP_DEBUG is defind and TRUE.
      */
     $log->add('image_process_start', __('Image processing started.', 'connections'));
     /*
      * Use the cnImage editors.
      */
     add_filter('wp_image_editors', array(__CLASS__, 'imageEditors'));
     /*
      * Do not use the default resizer since we want to allow resizing to larger sizes than the original image.
      * Parts are borrowed from media.php file in WordPress core.
      */
     add_filter('image_resize_dimensions', array(__CLASS__, 'resize_dimensions'), 10, 6);
     $defaults = array('width' => 0, 'height' => 0, '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, 'sub_dir' => '');
     $atts = wp_parse_args(apply_filters('cn_get_image_atts', $atts, $source, $return), $defaults);
     do_action('cn_image_get', $atts, $source, $return);
     /**
      * @var $width
      * @var $height
      * @var $negate
      * @var $grayscale
      * @var $brightness
      * @var $colorize
      * @var $contrast
      * @var $detect_edges
      * @var $emboss
      * @var $gaussian_blur
      * @var $blur
      * @var $sketchy
      * @var $sharpen
      * @var $smooth
      * @var $opacity
      * @var $crop_mode
      * @var $crop_focus
      * @var $crop_only
      * @var $canvas_color
      * @var $quality
      * @var $sub_dir
      */
     extract($atts);
     /*
      * --> START <-- Sanitize/Validate $atts values.
      */
     if (path_is_absolute($source)) {
         $log->add('image_path', __(sprintf('Supplied Source Path: %s', $source), 'connections'));
     } else {
         $source = esc_url($source);
         $log->add('image_url', __(sprintf('Supplied Source URL: %s', $source), 'connections'));
     }
     if (empty($source)) {
         return new WP_Error('no_path_or_url_provided', __('No image path or URL supplied.', 'connections'), $source);
     }
     if (!is_bool($negate)) {
         $negate = FALSE;
     }
     if (!is_bool($grayscale)) {
         $grayscale = FALSE;
     }
     if (!is_numeric($brightness) || empty($brightness)) {
         unset($brightness);
     }
     if (!is_numeric($contrast) || empty($contrast)) {
         unset($contrast);
     }
     if (!is_null($colorize)) {
         // If $colorize is a HEX color, ensure it is hashed.
         $colorize = cnFormatting::maybeHashHEXColor($colorize);
         // Check to see if $colorize is a valid HEX color.
         if (!cnSanitize::hexColor($colorize)) {
             // Since $colorize is not a valid HEX color, check to see if it is a named color.
             $colorize = cnColor::name2hex($colorize);
             // If $colorize is not a named color, unset it.
             if ($colorize === FALSE) {
                 unset($colorize);
             }
         }
     } else {
         unset($colorize);
     }
     if (!is_bool($detect_edges)) {
         $detect_edges = FALSE;
     }
     if (!is_bool($emboss)) {
         $emboss = FALSE;
     }
     if (!is_bool($gaussian_blur)) {
         $gaussian_blur = FALSE;
     }
     if (!is_bool($blur)) {
         $blur = FALSE;
     }
     if (!is_bool($sketchy)) {
         $sketchy = FALSE;
     }
     if (!is_bool($sharpen)) {
         $sharpen = FALSE;
     }
     if (!is_numeric($smooth) || is_null($smooth)) {
         unset($smooth);
     }
     // Ensure valid value for opacity.
     if (!is_numeric($opacity)) {
         $opacity = 100;
     }
     // Ensure valid value for crop mode.
     if (filter_var((int) $crop_mode, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 3))) === FALSE) {
         $crop_mode = 1;
     }
     $log->add('image_crop_mode', __(sprintf('Crop Mode: %d', $crop_mode), 'connections'));
     // Crop can be defined as either an array or string, sanitized/validate both.
     if (is_array($crop_focus) || is_string($crop_focus)) {
         // If $crop_focus is a string, lets check if is a positional crop and convert to an array.
         if (is_string($crop_focus) && stripos($crop_focus, ',') !== FALSE) {
             $crop_focus = explode(',', $crop_focus);
             array_walk($crop_focus, 'trim');
         }
         // Convert the string values to their float equivalents.
         if (is_string($crop_focus[0])) {
             switch ($crop_focus[0]) {
                 case 'left':
                     $crop_focus[0] = 0;
                     break;
                 case 'right':
                     $crop_focus[0] = 1;
                     break;
                 default:
                     $crop_focus[0] = 0.5;
                     break;
             }
         }
         if (is_string($crop_focus[1])) {
             switch ($crop_focus[1]) {
                 case 'top':
                     $crop_focus[1] = 0;
                     break;
                 case 'bottom':
                     $crop_focus[1] = 1;
                     break;
                 default:
                     $crop_focus[1] = 0.5;
                     break;
             }
         }
         // Ensure if an array was supplied, that there are only two keys, if not, set the default positional crop.
         if (count($crop_focus) !== 2) {
             $crop_focus = array(0.5, 0.5);
             // Values must be a float within the range of 0–1, if is not, set the default positional crop.
         } else {
             if ((!$crop_focus[0] >= 0 || !$crop_focus <= 1) && filter_var((double) $crop_focus[0], FILTER_VALIDATE_FLOAT) === FALSE) {
                 $crop_focus[0] = 0.5;
             }
             if ((!$crop_focus[1] >= 0 || !$crop_focus <= 1) && filter_var((double) $crop_focus[1], FILTER_VALIDATE_FLOAT) === FALSE) {
                 $crop_focus[1] = 0.5;
             }
         }
         $log->add('image_crop_focus', 'Crop Focus: ' . implode(',', $crop_focus));
     } else {
         // If $crop_focus is not an array, it must be a (bool) FALSE and if it is not, set $crop_focus to FALSE.
         $crop_focus = FALSE;
     }
     if (!is_bool($crop_only)) {
         $crop_only = FALSE;
     }
     // If $canvas_color is a HEX color, ensure it is hashed.
     $canvas_color = cnFormatting::maybeHashHEXColor($canvas_color);
     // Check to see if $canvas_color is a valid HEX color.
     if (!cnSanitize::hexColor($canvas_color)) {
         // Check to see if it is `transparent`, if not, check if it is a named color.
         if (strtolower($canvas_color) === 'transparent') {
             $canvas_color = 'transparent';
         } else {
             // Check to see if it is a named color.
             $canvas_color = cnColor::name2hex($canvas_color);
             // Not a named color, set the default.
             if ($canvas_color === FALSE) {
                 $canvas_color = '#FFFFFF';
             }
         }
     }
     // Ensure valid value for $quality. If invalid valid is supplied reset to the default of 90, matching WP core.
     if (filter_var((int) $quality, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 100))) === FALSE) {
         $quality = 90;
     }
     /*
      * --> END <-- Sanitize/Validate $atts values.
      */
     // Define upload path & dir.
     $upload_dir = CN_IMAGE_PATH;
     $upload_url = CN_IMAGE_BASE_URL;
     // Get image info or return WP_Error.
     if (is_wp_error($image_info = self::info($source))) {
         return $image_info;
     }
     $log->add('image_path', __(sprintf('Verified Source Path: %s', $image_info['path']), 'connections'));
     // This is the filename.
     $basename = $image_info['basename'];
     $log->add('image_base_filename', 'Original filename: ' . $basename);
     // Path/File info.
     $ext = $image_info['extension'];
     // Image info.
     $orig_w = $image_info[0];
     $orig_h = $image_info[1];
     $orig_mime_type = $image_info['mime'];
     $log->add('image_original_info', 'Original width: ' . $orig_w);
     $log->add('image_original_info', 'Original height: ' . $orig_h);
     $log->add('image_original_info', 'Original mime: ' . $orig_mime_type);
     // Support percentage dimensions. Compute percentage based on the original dimensions.
     if (is_string($width) && !is_numeric($width)) {
         if (stripos($width, '%') !== FALSE) {
             $log->add('image_width_percentage', 'Width set as percentage.');
             $width = (int) ((double) str_replace('%', '', $width) / 100 * $orig_w);
             $log->add('image_width', 'Width: ' . $width);
         }
     } else {
         $width = absint($width);
         $log->add('image_width', 'Width: ' . ($width === 0 ? '0' : $width));
     }
     if (is_string($height) && !is_numeric($height)) {
         if (stripos($height, '%') !== FALSE) {
             $log->add('image_height_percentage', 'Height set as percentage.');
             $height = (int) ((double) str_replace('%', '', $height) / 100 * $orig_h);
             $log->add('image_height', 'Height: ' . $height);
         }
     } else {
         $height = absint($height);
         $log->add('image_height', 'Height: ' . ($height === 0 ? '0' : $height));
     }
     // The only purpose of this is to determine the final width and height
     // without performing any actual image manipulation. This will be used
     // to check whether a resize was done previously.
     if ((!empty($width) || !empty($height)) && $crop_only === FALSE) {
         switch ($crop_mode) {
             case 0:
                 $dims = image_resize_dimensions($orig_w, $orig_h, empty($width) ? NULL : $width, empty($height) ? NULL : $height, FALSE);
                 $dst_w = $dims[4];
                 $dst_h = $dims[5];
                 break;
             case 1:
                 $dims = image_resize_dimensions($orig_w, $orig_h, empty($width) ? NULL : $width, empty($height) ? NULL : $height, is_array($crop_focus) ? $crop_focus : TRUE);
                 $dst_w = $dims[4];
                 $dst_h = $dims[5];
                 break;
             case 2:
                 $canvas_w = $width;
                 $canvas_h = $height;
                 // generate new w/h if not provided
                 if ($width && !$height) {
                     $height = floor($orig_h * ($width / $orig_w));
                     $canvas_h = $height;
                 } else {
                     if ($height && !$width) {
                         $width = floor($orig_w * ($height / $orig_h));
                         $canvas_w = $width;
                     }
                 }
                 $final_height = $orig_h * ($width / $orig_w);
                 if ($final_height > $height) {
                     $origin_x = $width / 2;
                     $width = $orig_w * ($height / $orig_h);
                     $origin_x = round($origin_x - $width / 2);
                 } else {
                     $origin_y = $height / 2;
                     $height = $final_height;
                     $origin_y = round($origin_y - $height / 2);
                 }
                 $dst_w = $canvas_w;
                 $dst_h = $canvas_h;
                 break;
             case 3:
                 // generate new w/h if not provided
                 if ($width && !$height) {
                     $height = floor($orig_h * ($width / $orig_w));
                 } else {
                     if ($height && !$width) {
                         $width = floor($orig_w * ($height / $orig_h));
                     }
                 }
                 $final_height = $orig_h * ($width / $orig_w);
                 if ($final_height > $height) {
                     $width = $orig_w * ($height / $orig_h);
                 } else {
                     $height = $final_height;
                 }
                 $dims = image_resize_dimensions($orig_w, $orig_h, empty($width) ? NULL : $width, empty($height) ? NULL : $height, FALSE);
                 $dst_w = $dims[4];
                 $dst_h = $dims[5];
                 break;
         }
         $log->add('image_resize_width', 'Resize width: ' . ($dst_w === 0 ? '0' : $dst_w));
         $log->add('image_resize_height', 'Resize height: ' . ($dst_h === 0 ? '0' : $dst_h));
         // Do not resize, only a crop in the image.
     } elseif ($crop_only === TRUE) {
         // get x position to start cropping
         $src_x = isset($crop_x) ? $crop_x : 0;
         // get y position to start cropping
         $src_y = isset($crop_y) ? $crop_y : 0;
         // width of the crop
         if (isset($crop_width)) {
             $src_w = $crop_width;
         } else {
             if (isset($width)) {
                 $src_w = $width;
             } else {
                 $src_w = $orig_w;
             }
         }
         // height of the crop
         if (isset($crop_height)) {
             $src_h = $crop_height;
         } else {
             if (isset($height)) {
                 $src_h = $height;
             } else {
                 $src_h = $orig_h;
             }
         }
         // set the width resize with the crop
         if (isset($crop_width) && isset($width)) {
             $dst_w = $width;
         } else {
             $dst_w = NULL;
         }
         // set the height resize with the crop
         if (isset($crop_height) && isset($height)) {
             $dst_h = $height;
         } else {
             $dst_h = NULL;
         }
         // allow percentages
         if (isset($dst_w)) {
             if (stripos($dst_w, '%') !== FALSE) {
                 $dst_w = (int) ((double) str_replace('%', '', $dst_w) / 100 * $orig_w);
             }
         }
         if (isset($dst_h)) {
             if (stripos($dst_h, '%') !== FALSE) {
                 $dst_h = (int) ((double) str_replace('%', '', $dst_h) / 100 * $orig_h);
             }
         }
         $dims = image_resize_dimensions($src_w, $src_h, $dst_w, $dst_h, FALSE);
         $dst_w = $dims[4];
         $dst_h = $dims[5];
         // Make the pos x and pos y work with percentages
         if (stripos($src_x, '%') !== FALSE) {
             $src_x = (int) ((double) str_replace('%', '', $width) / 100 * $orig_w);
         }
         if (stripos($src_y, '%') !== FALSE) {
             $src_y = (int) ((double) str_replace('%', '', $height) / 100 * $orig_h);
         }
         // allow center to position crop start
         if ($src_x === 'center') {
             $src_x = ($orig_w - $src_w) / 2;
         }
         if ($src_y === 'center') {
             $src_y = ($orig_h - $src_h) / 2;
         }
     }
     // Create the hash for the saved file.
     // This to check whether we need to create a new file or use an existing file.
     $hash = (string) $image_info['modified'] . (empty($width) ? str_pad((string) $width, 5, '0', STR_PAD_LEFT) : '00000') . (empty($height) ? str_pad((string) $height, 5, '0', STR_PAD_LEFT) : '00000') . ($negate ? '1' : '0') . ($grayscale ? '1' : '0') . (isset($brightness) ? str_pad((string) ((int) $brightness >= 0 ? '1' . (string) $brightness : str_replace('-', '0', (string) $brightness)), 4, '0', STR_PAD_LEFT) : '0000') . (isset($colorize) ? str_pad(preg_replace('#^\\##', '', $colorize), 8, '0', STR_PAD_LEFT) : '00000000') . (isset($contrast) ? str_pad((string) ((int) $contrast >= 0 ? '1' . (string) $contrast : str_replace('-', '0', (string) $contrast)), 4, '0', STR_PAD_LEFT) : '0000') . ($detect_edges ? '1' : '0') . ($emboss ? '1' : '0') . ($gaussian_blur ? '1' : '0') . ($blur ? '1' : '0') . ($sketchy ? '1' : '0') . ($sharpen ? '1' : '0') . (isset($smooth) ? str_pad((string) ((double) $smooth >= 0 ? '1' . (string) $smooth : str_replace('-', '0', (string) $smooth)), 4, '0', STR_PAD_LEFT) : '0000') . str_pad((string) $opacity, 3, '0', STR_PAD_LEFT) . ($crop_focus ? is_array($crop_focus) ? str_replace('.', '', join('', $crop_focus)) : '1' : '0') . $crop_mode . ($crop_only ? '1' : '0') . (isset($src_x) ? str_pad((string) $src_x, 5, '0', STR_PAD_LEFT) : '00000') . (isset($src_y) ? str_pad((string) $src_y, 5, '0', STR_PAD_LEFT) : '00000') . (isset($src_w) ? str_pad((string) $src_w, 5, '0', STR_PAD_LEFT) : '00000') . (isset($src_h) ? str_pad((string) $src_h, 5, '0', STR_PAD_LEFT) : '00000') . (isset($dst_w) ? str_pad((string) $dst_w, 5, '0', STR_PAD_LEFT) : '00000') . (isset($dst_h) ? str_pad((string) $dst_h, 5, '0', STR_PAD_LEFT) : '00000') . str_pad(preg_replace('#^\\##', '', $canvas_color), 8, '0', STR_PAD_LEFT) . str_pad((string) $quality, 3, '0', STR_PAD_LEFT);
     $log->add('image_file_hash', 'Hash: ' . $hash);
     // Hash the filename suffix.
     $suffix = md5($hash);
     $log->add('image_base_name_suffix', 'Base filename suffix: ' . $suffix);
     // Use this to check if cropped image already exists, so we can return that instead.
     $dst_rel_path = str_replace('.' . $ext, '', $image_info['basename']);
     // Set file ext to `png` if the opacity has been set less than 100 or if the crop mode is `2` and the canvas color was set to transparent.
     if ($opacity < 100 || $canvas_color === 'transparent' && $crop_mode == 2) {
         $ext = 'png';
     }
     // Create the upload subdirectory, this is where the generated images are saved.
     $upload_dir = is_string($atts['sub_dir']) && !empty($atts['sub_dir']) ? trailingslashit(CN_IMAGE_PATH . $atts['sub_dir']) : CN_IMAGE_PATH;
     $upload_url = is_string($atts['sub_dir']) && !empty($atts['sub_dir']) ? trailingslashit(CN_IMAGE_BASE_URL . $atts['sub_dir']) : CN_IMAGE_BASE_URL;
     cnFileSystem::mkdir($upload_dir);
     // Destination paths and URL.
     $destfilename = "{$upload_dir}{$dst_rel_path}-{$suffix}." . strtolower($ext);
     $img_url = "{$upload_url}{$dst_rel_path}-{$suffix}." . strtolower($ext);
     // If file exists, just return it.
     if (@file_exists($destfilename) && ($image_info = getimagesize($destfilename))) {
         $mime_type = $image_info['mime'];
         $log->add('image_serve_from_cache', 'Image found in cache, no processing required.');
         $editor = wp_get_image_editor($destfilename);
         // If there is an error, return WP_Error object.
         if (is_wp_error($editor)) {
             return $editor;
         }
         $log->add('image_editor_engine', __(sprintf('Image processing parent class is %s', get_parent_class($editor)), 'connections'));
         $log->add('image_editor_engine', __(sprintf('Image processing class is %s', get_class($editor)), 'connections'));
     } else {
         // Setup the $methods var to be passed to wp_get_image_editor()
         // so the correct image editor engine can be chosen for processing the image.
         if ($negate) {
             $methods['methods'][] = 'negate';
         }
         if ($grayscale) {
             $methods['methods'][] = 'grayscale';
         }
         if (isset($brightness)) {
             $methods['methods'][] = 'brightness';
         }
         if (isset($colorize)) {
             $methods['methods'][] = 'colorize';
         }
         if (isset($contrast)) {
             $methods['methods'][] = 'contrast';
         }
         if ($detect_edges) {
             $methods['methods'][] = 'detect_edges';
         }
         if ($emboss) {
             $methods['methods'][] = 'emboss';
         }
         if ($gaussian_blur) {
             $methods['methods'][] = 'gaussian_blur';
         }
         if ($blur) {
             $methods['methods'][] = 'blur';
         }
         if ($sketchy) {
             $methods['methods'][] = 'sketchy';
         }
         if ($sharpen) {
             $methods['methods'][] = 'sharpen';
         }
         if (isset($smooth)) {
             $methods['methods'][] = 'smooth';
         }
         if (isset($opacity)) {
             $methods['methods'][] = 'opacity';
         }
         if ($crop_focus) {
             $methods['methods'][] = 'crop';
         }
         if ($crop_mode == 2) {
             $methods['methods'][] = 'resize_padded';
         }
         if ($crop_only) {
             $methods['methods'][] = 'resize';
         }
         $methods['methods'][] = 'set_quality';
         // Perform resizing and other filters.
         /** @var CN_Image_Editor_GD $editor */
         $editor = wp_get_image_editor($image_info['path'], $methods);
         // If there is an error, return WP_Error object.
         if (is_wp_error($editor)) {
             return $editor;
         }
         $log->add('image_editor_engine', __(sprintf('Image processing parent class is %s', get_parent_class($editor)), 'connections'));
         $log->add('image_editor_engine', __(sprintf('Image processing class is %s', get_class($editor)), 'connections'));
         /*
          * Perform image manipulations.
          */
         if ($crop_only === FALSE) {
             if (!empty($width) && $width || !empty($height) && $height) {
                 switch ($crop_mode) {
                     case 0:
                         if (is_wp_error($result = $editor->resize(empty($width) ? NULL : $width, empty($height) ? NULL : $height, FALSE))) {
                             return $result;
                         }
                         $log->add('image_resized', __('Image successfully resized to fit new width and height without maintaining proportion.', 'connections'));
                         break;
                     case 1:
                         if (is_wp_error($result = $editor->resize(empty($width) ? NULL : $width, empty($height) ? NULL : $height, is_array($crop_focus) ? $crop_focus : TRUE))) {
                             return $result;
                         }
                         if (is_bool($crop_focus)) {
                             $log->add('image_resized', __('Image successfully resized with cropping.', 'connections'));
                         } elseif (is_array($crop_focus)) {
                             $log->add('image_resized', __(sprintf('Image successfully resized with cropping from origin %s,%s.', $crop_focus[0], $crop_focus[1]), 'connections'));
                         }
                         break;
                     case 2:
                         if (is_wp_error($result = $editor->resize_padded($canvas_w, $canvas_h, $canvas_color, empty($width) ? NULL : $width, empty($height) ? NULL : $height, $orig_w, $orig_h, empty($origin_x) ? 0 : $origin_x, empty($origin_y) ? 0 : $origin_y))) {
                             return $result;
                         }
                         $log->add('image_resized', __('Image successfully resized proportionally with padding.', 'connections'));
                         break;
                     case 3:
                         if (is_wp_error($result = $editor->resize(empty($width) ? NULL : $width, empty($height) ? NULL : $height, FALSE))) {
                             return $result;
                         }
                         $log->add('image_resized', __('Image successfully resized proportionally with no padding.', 'connections'));
                         break;
                 }
             }
         } else {
             if (is_wp_error($result = $editor->crop($src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h))) {
                 return $result;
             }
         }
         if ($negate) {
             if (is_wp_error($result = $editor->negate())) {
                 return $result;
             }
             $log->add('image_filter_negate', __('Negate filter applied.', 'connections'));
         }
         if ($grayscale) {
             if (is_wp_error($result = $editor->grayscale())) {
                 return $result;
             }
             $log->add('image_filter_grayscale', __('Grayscale filter applied.', 'connections'));
         }
         if (isset($brightness)) {
             if (is_wp_error($result = $editor->brightness($brightness))) {
                 return $result;
             }
             $log->add('image_filter_brightnes', __(sprintf('Brightness level %s applied.', $brightness), 'connections'));
         }
         if (isset($contrast)) {
             if (is_wp_error($result = $editor->contrast($contrast))) {
                 return $result;
             }
             $log->add('image_filter_contrast', __(sprintf('Contrast level %s applied.', $contrast), 'connections'));
         }
         if (isset($colorize)) {
             if (is_wp_error($result = $editor->colorize($colorize))) {
                 return $result;
             }
             $log->add('image_filter_colorize', __(sprintf('Colorized using %s.', $colorize), 'connections'));
         }
         if ($detect_edges) {
             if (is_wp_error($result = $editor->detect_edges())) {
                 return $result;
             }
             $log->add('image_filter_edge_detect', __('Edge Detect filter applied.', 'connections'));
         }
         if ($emboss) {
             if (is_wp_error($result = $editor->emboss())) {
                 return $result;
             }
             $log->add('image_filter_emboss', __('Emboss filter applied.', 'connections'));
         }
         if ($gaussian_blur) {
             if (is_wp_error($result = $editor->gaussian_blur())) {
                 return $result;
             }
             $log->add('image_filter_gaussian_blur', __('Gaussian Blur filter applied.', 'connections'));
         }
         if ($blur) {
             if (is_wp_error($result = $editor->blur())) {
                 return $result;
             }
             $log->add('image_filter_blur', __('Blur filter applied.', 'connections'));
         }
         if ($sketchy) {
             if (is_wp_error($result = $editor->sketchy())) {
                 return $result;
             }
             $log->add('image_filter_sketchy', __('Sketchy filter applied.', 'connections'));
         }
         if ($sharpen) {
             if (is_wp_error($result = $editor->sharpen($sharpen))) {
                 return $result;
             }
             $log->add('image_filter_sharpen', __('Sharpen filter applied.', 'connections'));
         }
         if (isset($smooth)) {
             if (is_wp_error($result = $editor->smooth($smooth))) {
                 return $result;
             }
             $log->add('image_filter_smooth', __(sprintf('Smooth filter applied with level %s.', $smooth), 'connections'));
         }
         if ($opacity < 100) {
             if (is_wp_error($result = $editor->opacity($opacity))) {
                 return $result;
             }
         }
         $log->add('image_filter_opacity', __(sprintf('Opacity set at %d.', $opacity), 'connections'));
         // Set image save quality.
         $editor->set_quality($quality);
         $log->add('image_save_quality', __(sprintf('Saving quality set at %s.', $editor->get_quality()), 'connections'));
         // Save the new image, set file type to PNG if the opacity has been set less than 100 or if the crop mode is `2` and the canvas color was set to transparent.
         if ($opacity < 100 || $canvas_color === 'transparent' && $crop_mode == 2 || $orig_mime_type == 'image/png') {
             $mime_type = 'image/png';
         } elseif ($orig_mime_type == 'image/jpeg') {
             $mime_type = 'image/jpeg';
         } elseif ($orig_mime_type == 'image/gif') {
             $mime_type = 'image/gif';
         }
         $log->add('image_save_mime_type', __(sprintf('Saving file as %s.', $mime_type), 'connections'));
         $log->add('image_save_file_path', __(sprintf('Saving file in path: %s', $destfilename), 'connections'));
         $resized_file = $editor->save($destfilename, $mime_type);
         $log->add('image_save', __('File saved successfully.', 'connections'));
     }
     $log->add('image_cache_url', __(sprintf('Cache URL: %s', $img_url), 'connections'));
     /*
      * Remove the cnImage filters.
      */
     remove_filter('wp_image_editors', array(__CLASS__, 'imageEditors'));
     remove_filter('image_resize_dimensions', array(__CLASS__, 'resize_dimensions'), 10);
     /*
      * Be a good citizen and add the filters that were hooked back to image editor filters.
      */
     if (!empty($filter['editors'])) {
         $wp_filter['wp_image_editors'] = $filter['editors'];
     }
     if (!empty($filter['resize'])) {
         $wp_filter['image_resize_dimensions'] = $filter['resize'];
     }
     switch ($return) {
         case 'base64':
             $image = 'data:image/' . (isset($mime_type) ? $mime_type : $orig_mime_type) . ';base64,' . base64_encode(file_get_contents($destfilename));
             break;
         case 'data':
             $image = array('name' => "{$dst_rel_path}-{$suffix}.{$ext}", 'path' => $destfilename, 'url' => $img_url, 'width' => isset($dst_w) ? $dst_w : $orig_w, 'height' => isset($dst_h) ? $dst_h : $orig_h, 'size' => 'height="' . (isset($dst_h) ? $dst_h : $orig_h) . '" width="' . (isset($dst_w) ? $dst_w : $orig_w) . '"', 'mime' => isset($mime_type) ? $mime_type : $orig_mime_type, 'type' => $image_info[2], 'log' => defined('WP_DEBUG') && WP_DEBUG === TRUE ? $log : __('WP_DEBUG is not defined or set to FALSE, set to TRUE to enable image processing log.', 'connections'));
             break;
         case 'editor':
             $image = $editor;
             break;
         case 'stream':
             $image = $editor->stream();
             break;
         default:
             $image = $img_url;
             break;
     }
     return $image;
 }
 /**
  * Returns an indexed array of objects the addresses per the defined options.
  *
  * @param $atts {
  *     @type string       $fields    The fields to return.
  *                                   Default: all
  *                                   Accepts: all, ids, locality, regions, postal-code, country
  *     @type int          $id        The entry ID in which to retrieve the addresses for.
  *     @type bool         $preferred Whether or not to return only the preferred address.
  *                                   Default: false
  *     @type array|string $type      The address types to return.
  *                                   Default: array() which will return all registered address types.
  *                                   Accepts: home, work, school, other and any other registered types.
  *     @type array|string $city      Return address in the defined cities.
  *     @type array|string $state     Return address in the defined states.
  *     @type array|string $country   Return address in the defined countries.
  *     @type array        $coordinates {
  *         Return the addresses at the specific coordinates.
  *         @type float $latitude
  *         @type float $longitude
  *     }
  * }
  *
  * @return array
  */
 public function addresses($atts = array())
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     $where = array('WHERE 1=1');
     /*
      * // START -- Set the default attributes array. \\
      */
     $defaults = array('fields' => 'all', 'id' => NULL, 'preferred' => FALSE, 'type' => array(), 'city' => array(), 'state' => array(), 'zipcode' => array(), 'country' => array(), 'coordinates' => array(), 'limit' => NULL);
     $atts = cnSanitize::args($atts, $defaults);
     /*
      * // END -- Set the default attributes array if not supplied. \\
      */
     /**
      * @var int          $id
      * @var bool         $preferred
      * @var array|string $type
      * @var array|string $city
      * @var array|string $state
      * @var array|string $zipcode
      * @var array|string $country
      * @var array        $coordinates
      * @var null|int     $limit
      */
     extract($atts);
     /*
      * Convert these to values to an array if they were supplied as a comma delimited string
      */
     /** @var array $type */
     cnFunction::parseStringList($type);
     /** @var array $city */
     cnFunction::parseStringList($city);
     /** @var array $state */
     cnFunction::parseStringList($state);
     /** @var array $zipcode */
     cnFunction::parseStringList($zipcode);
     /** @var array $country */
     cnFunction::parseStringList($country);
     switch ($atts['fields']) {
         case 'ids':
             $select = array('a.id', 'a.entry_id');
             break;
         case 'locality':
             $select = array('a.city');
             break;
         case 'region':
             $select = array('a.state');
             break;
         case 'postal-code':
             $select = array('a.zipcode');
             break;
         case 'country':
             $select = array('a.country');
             break;
         default:
             $select = array('a.*');
     }
     if (!empty($id)) {
         $where[] = $wpdb->prepare('AND `entry_id` = %d', $id);
     }
     if (!empty($preferred)) {
         $where[] = $wpdb->prepare('AND `preferred` = %d', (bool) $preferred);
     }
     if (!empty($type)) {
         $where[] = $wpdb->prepare('AND `type` IN (' . cnFormatting::prepareINPlaceholders($type) . ')', $type);
     }
     if (!empty($city)) {
         $where[] = $wpdb->prepare('AND `city` IN (' . cnFormatting::prepareINPlaceholders($city) . ')', $city);
     }
     if (!empty($state)) {
         $where[] = $wpdb->prepare('AND `state` IN (' . cnFormatting::prepareINPlaceholders($state) . ')', $state);
     }
     if (!empty($zipcode)) {
         $where[] = $wpdb->prepare('AND `zipcode` IN (' . cnFormatting::prepareINPlaceholders($zipcode) . ')', $zipcode);
     }
     if (!empty($country)) {
         $where[] = $wpdb->prepare('AND `country` IN (' . cnFormatting::prepareINPlaceholders($country) . ')', $country);
     }
     if (!empty($coordinates)) {
         if (!empty($coordinates['latitude']) && !empty($coordinates['longitude'])) {
             $where[] = $wpdb->prepare('AND `latitude` = %f', $coordinates['latitude']);
             $where[] = $wpdb->prepare('AND `longitude` = %f', $coordinates['longitude']);
         }
     }
     // Limit the characters that are queried based on if the current user can view public, private or unlisted entries.
     $where = self::setQueryVisibility($where, array('table' => 'a'));
     $limit = is_null($atts['limit']) ? '' : sprintf(' LIMIT %d', $atts['limit']);
     $sql = sprintf('SELECT %1$s FROM %2$s AS a %3$s ORDER BY `order`%4$s', implode(', ', $select), CN_ENTRY_ADDRESS_TABLE, implode(' ', $where), $limit);
     $results = $wpdb->get_results($sql);
     return $results;
 }
 /**
  * Returns as an array of objects containing the dates per the defined options.
  *
  * @param array $atts {
  *     Optional. An array of arguments.
  *
  *     @type int          $id        The entry ID in which to retrieve the dates for.
  *     @type bool         $preferred Whether or not to return only the preferred dates.
  *                                   Default: false
  *     @type array|string $type      The types to return.
  *                                   Default: array() which will return all registered types.
  *                                   Accepts: Any other registered types.
  *     @type int          $limit     The number to limit the results to.
  * }
  * @param bool $saving Set as TRUE if adding a new entry or updating an existing entry.
  *
  * @return array
  */
 public static function dates($atts = array(), $saving = FALSE)
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     $where = array('WHERE 1=1');
     $defaults = array('fields' => 'all', 'id' => NULL, 'preferred' => FALSE, 'type' => array(), 'limit' => NULL);
     $atts = cnSanitize::args($atts, $defaults);
     /**
      * @var string       $fields
      * @var int          $id
      * @var bool         $preferred
      * @var array|string $type
      * @var null|int     $limit
      */
     extract($atts);
     /*
      * Convert these to values to an array if they were supplied as a comma delimited string
      */
     cnFunction::parseStringList($type);
     switch ($atts['fields']) {
         case 'ids':
             $select = array('d.id', 'd.entry_id');
             break;
         case 'date':
             $select = array('d.date');
             break;
         default:
             $select = array('d.*');
     }
     if (is_numeric($id) && !empty($id)) {
         $where[] = $wpdb->prepare('AND `entry_id` = "%d"', $id);
     }
     if ($preferred) {
         $where[] = $wpdb->prepare('AND `preferred` = %d', (bool) $preferred);
     }
     if (!empty($type)) {
         $where[] = $wpdb->prepare('AND `type` IN (' . cnFormatting::prepareINPlaceholders($type) . ')', $type);
     }
     if (!$saving) {
         $where = self::setQueryVisibility($where, array('table' => 'd'));
     }
     $limit = is_null($atts['limit']) ? '' : sprintf(' LIMIT %d', $atts['limit']);
     $sql = sprintf('SELECT %1$s FROM %2$s AS d %3$s ORDER BY `order`%4$s', implode(', ', $select), CN_ENTRY_DATE_TABLE, implode(' ', $where), $limit);
     $results = $wpdb->get_results($sql);
     return $results;
 }
    /**
     * Callback to render the "Custom Fields" metabox.
     *
     * @access private
     * @since 0.8
     * @param  cnEntry $entry   An instance of the cnEntry object.
     * @param  array  $metabox The metabox attributes array set in self::register().
     * @return void
     */
    public static function meta($entry, $metabox)
    {
        /** @var wpdb $wpdb */
        global $wpdb;
        $results = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value, meta_id, entry_id\n\t\t\tFROM " . CN_ENTRY_TABLE_META . " WHERE entry_id = %d\n\t\t\tORDER BY meta_key,meta_id", $entry->getId()), ARRAY_A);
        $metabox = $metabox['args'];
        $keys = cnMeta::key('entry');
        $options = array();
        // Toss the meta that is saved as part of a custom field.
        if (!empty($results)) {
            foreach ($results as $metaID => $meta) {
                if (cnMeta::isPrivate($meta['meta_key'])) {
                    unset($results[$metaID]);
                }
            }
        }
        // Build the meta key select drop down options.
        if (!empty($keys)) {
            $options = array_combine(array_map('esc_attr', array_keys($keys)), array_map('esc_html', $keys));
            array_walk($options, create_function('&$key', '$key = "<option value=\\"$key\\">$key</option>";'));
        }
        array_unshift($options, '<option value="-1">&mdash; ' . __('Select', 'connections') . ' &mdash;</option>');
        $options = implode($options, PHP_EOL);
        // echo '<input type="hidden" name="wp_meta_box_nonce" value="', wp_create_nonce( basename(__FILE__) ), '" />';
        echo '<div class="cn-metabox-section" id="meta-fields">';
        ?>

		<table id="list-table" style="<?php 
        echo empty($results) ? 'display: none;' : 'display: table;';
        ?>
">
			<thead>
				<tr>
					<th class="left"><?php 
        _e('Name', 'connections');
        ?>
</th>
					<th><?php 
        _e('Value', 'connections');
        ?>
</th>
				</tr>
			</thead>

			<tbody id="the-list">

			<?php 
        if (!empty($results)) {
            foreach ($results as $metaID => $meta) {
                // Class added to alternate tr rows for CSS styling.
                $alternate = !isset($alternate) || $alternate == '' ? 'alternate' : '';
                ?>

					<tr id="meta-<?php 
                echo $meta['meta_id'];
                ?>
" class="<?php 
                echo $alternate;
                ?>
">

						<td class="left">
							<label class="screen-reader-text" for='meta[<?php 
                echo $meta['meta_id'];
                ?>
][key]'><?php 
                _e('Key', 'connections');
                ?>
</label>
							<input name='meta[<?php 
                echo $meta['meta_id'];
                ?>
][key]' id='meta[<?php 
                echo $meta['meta_id'];
                ?>
][key]' type="text" size="20" value="<?php 
                echo esc_textarea($meta['meta_key']);
                ?>
" />
							<div class="submit">
								<input type="submit" name="deletemeta[<?php 
                echo $meta['meta_id'];
                ?>
]" id="deletemeta[<?php 
                echo $meta['meta_id'];
                ?>
]" class="button deletemeta button-small" value="<?php 
                _e('Delete', 'connections');
                ?>
" />
							</div>
						</td>

						<td>
							<label class="screen-reader-text" for='meta[<?php 
                echo $meta['meta_id'];
                ?>
][value]'><?php 
                _e('Value', 'connections');
                ?>
</label>
							<textarea name='meta[<?php 
                echo $meta['meta_id'];
                ?>
][value]' id='meta[<?php 
                echo $meta['meta_id'];
                ?>
][value]' rows="2" cols="30"><?php 
                echo esc_textarea(cnFormatting::maybeJSONencode($meta['meta_value']));
                ?>
</textarea>
						</td>

					</tr>

					<?php 
            }
            ?>

			<?php 
        }
        ?>

			<!-- This is the row that will be cloned via JS when adding a new Custom Field. -->
			<tr style="display: none;">

				<td class="left">
					<label class="screen-reader-text" for='newmeta[0][key]'><?php 
        _e('Key', 'connections');
        ?>
</label>
					<input name='newmeta[0][key]' id='newmeta[0][key]' type="text" size="20" value=""/>
					<div class="submit">
						<input type="submit" name="deletemeta[0]" id="deletemeta[0]" class="button deletemeta button-small" value="<?php 
        _e('Delete', 'connections');
        ?>
" />
						<!-- <input type="submit" name="newmeta-0-submit" id="newmeta-0-submit" class="button updatemeta button-small" value="Update" /> -->
					</div>
					<!-- <input type="hidden" id="_ajax_nonce" name="_ajax_nonce" value="0db0025bba" /> -->
				</td>
				<td>
					<label class="screen-reader-text" for='newmeta[0][value]'><?php 
        _e('Value', 'connections');
        ?>
</label>
					<textarea name='newmeta[0][value]' id='newmeta[0][value]' rows="2" cols="30"></textarea>
				</td>

			</tr>

			</tbody>
		</table>

		<p><strong><?php 
        _e('Add New Custom Field:', 'connections');
        ?>
</strong></p>

		<table id="newmeta">
			<thead>
				<tr>
					<th class="left"><label for="metakeyselect"><?php 
        _e('Name', 'connections');
        ?>
</label></th>
					<th><label for="metavalue"><?php 
        _e('Value', 'connections');
        ?>
</label></th>
				</tr>
			</thead>
			<tbody>

				<tr>

					<td id="newmetaleft" class="left">
						<select id="metakeyselect" name="metakeyselect">
							<?php 
        echo $options;
        ?>
						</select>
						<input class="hide-if-js" type=text id="metakeyinput" name="newmeta[99][key]" value=""/>
						<a href="#postcustomstuff" class="postcustomstuff hide-if-no-js"> <span id="enternew"><?php 
        _e('Enter New', 'connections');
        ?>
</span> <span id="cancelnew" class="hidden"><?php 
        _e('Cancel', 'connections');
        ?>
</span></a>
					</td>

					<td>
						<textarea id="metavalue" name="newmeta[99][value]" rows="2" cols="25"></textarea>
					</td>

				</tr>



			</tbody>
			<tfoot>
				<td colspan="2">
					<div class="submit">
						<input type="submit" name="addmeta" id="newmeta-submit" class="button" value="<?php 
        _e('Add Custom Field', 'connections');
        ?>
" />
					</div>
					<!-- <input type="hidden" id="_ajax_nonce-add-meta" name="_ajax_nonce-add-meta" value="a7f70d2878" /> -->
				</td>
			</tfoot>
		</table>

		<?php 
        if (isset($metabox['desc']) && !empty($metabox['desc'])) {
            printf('<p>%1$s</p>', esc_html($metabox['desc']));
        }
        echo '</div>';
    }
/**
 * Display the upcoming list.
 *
 * @access public
 * @since  unknown
 *
 * @param array  $atts
 * @param string $content [optional]
 * @param string $tag     [optional] When called as the callback for add_shortcode, the shortcode tag is passed
 *                        automatically. Manually setting the shortcode tag so the function can be called
 *                        independently.
 *
 * @return string
 */
function _upcoming_list($atts, $content = NULL, $tag = 'upcoming_list')
{
    global $connections, $wpdb;
    // $template =& $connections->template;
    $out = '';
    $alternate = '';
    $atts = shortcode_atts(array('list_type' => 'birthday', 'days' => '30', 'include_today' => TRUE, 'private_override' => FALSE, 'date_format' => 'F jS', 'show_lastname' => FALSE, 'show_title' => TRUE, 'list_title' => NULL, 'template' => NULL), $atts, $tag);
    /*
     * Convert some of the $atts values in the array to boolean.
     */
    cnFormatting::toBoolean($atts['include_today']);
    cnFormatting::toBoolean($atts['private_override']);
    cnFormatting::toBoolean($atts['show_lastname']);
    cnFormatting::toBoolean($atts['repeat_alphaindex']);
    cnFormatting::toBoolean($atts['show_title']);
    /*
     * 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 = cnTemplateFactory::getTemplate($atts['template']);
    } else {
        $templateSlug = $connections->options->getActiveTemplate($atts['list_type']);
        $template = cnTemplateFactory::getTemplate($templateSlug);
    }
    // No template found return error message.
    if ($template == FALSE) {
        return '<p style="color:red; font-weight:bold; text-align:center;">' . sprintf(__('ERROR: Template %1$s not found.', 'connections'), $atts['template']) . '</p>';
    }
    do_action('cn_template_include_once-' . $template->getSlug());
    do_action('cn_template_enqueue_js-' . $template->getSlug());
    /*
     * Set the query vars and run query.
     */
    // Show only public or private [if permitted] entries.
    if (is_user_logged_in() || $atts['private_override'] != FALSE) {
        $visibilityfilter = " AND (visibility='private' OR visibility='public') AND (" . $atts['list_type'] . " != '')";
    } else {
        $visibilityfilter = " AND (visibility='public') AND (`" . $atts['list_type'] . "` != '')";
    }
    // Get the current date from WP which should have the current time zone offset.
    $wpCurrentDate = date('Y-m-d', $connections->options->wpCurrentTime);
    // Whether or not to include the event occurring today or not.
    $atts['include_today'] ? $includeToday = '<=' : ($includeToday = '<');
    $newSQL = "SELECT * FROM " . CN_ENTRY_TABLE . " WHERE" . "  (YEAR(DATE_ADD('{$wpCurrentDate}', INTERVAL " . $atts['days'] . " DAY))" . " - YEAR(DATE_ADD(FROM_UNIXTIME(`" . $atts['list_type'] . "`), INTERVAL " . $connections->options->sqlTimeOffset . " SECOND)) )" . " - ( MID(DATE_ADD('{$wpCurrentDate}', INTERVAL " . $atts['days'] . " DAY),5,6)" . " < MID(DATE_ADD(FROM_UNIXTIME(`" . $atts['list_type'] . "`), INTERVAL " . $connections->options->sqlTimeOffset . " SECOND),5,6) )" . " > ( YEAR('{$wpCurrentDate}')" . " - YEAR(DATE_ADD(FROM_UNIXTIME(`" . $atts['list_type'] . "`), INTERVAL " . $connections->options->sqlTimeOffset . " SECOND)) )" . " - ( MID('{$wpCurrentDate}',5,6)" . " " . $includeToday . " MID(DATE_ADD(FROM_UNIXTIME(`" . $atts['list_type'] . "`), INTERVAL " . $connections->options->sqlTimeOffset . " SECOND),5,6) )" . $visibilityfilter;
    //$out .= print_r($newSQL , TRUE);
    $results = $wpdb->get_results($newSQL);
    //$out .= print_r($results , TRUE);
    // If there are no results no need to proceed and output message.
    if (empty($results)) {
        $noResultMessage = __('No results.', 'connections');
        $noResultMessage = apply_filters('cn_upcoming_no_result_message', $noResultMessage);
        $out .= '<p class="cn-upcoming-no-results">' . $noResultMessage . '</p>';
    } else {
        /*The SQL returns an array sorted by the birthday and/or anniversary date. However the year end wrap needs to be accounted for.
        		Otherwise earlier months of the year show before the later months in the year. Example Jan before Dec. The desired output is to show
        		Dec then Jan dates.  This function checks to see if the month is a month earlier than the current month. If it is the year is changed to the following year rather than the current.
        		After a new list is built, it is resorted based on the date.*/
        foreach ($results as $key => $row) {
            if (gmmktime(23, 59, 59, gmdate('m', $row->{$atts}['list_type']), gmdate('d', $row->{$atts}['list_type']), gmdate('Y', $connections->options->wpCurrentTime)) < $connections->options->wpCurrentTime) {
                $dateSort[] = $row->{$atts}['list_type'] = gmmktime(0, 0, 0, gmdate('m', $row->{$atts}['list_type']), gmdate('d', $row->{$atts}['list_type']), gmdate('Y', $connections->options->wpCurrentTime) + 1);
            } else {
                $dateSort[] = $row->{$atts}['list_type'] = gmmktime(0, 0, 0, gmdate('m', $row->{$atts}['list_type']), gmdate('d', $row->{$atts}['list_type']), gmdate('Y', $connections->options->wpCurrentTime));
            }
        }
        array_multisort($dateSort, SORT_ASC, $results);
        if (empty($atts['list_title'])) {
            switch ($atts['list_type']) {
                case 'birthday':
                    if ($atts['days'] >= 1) {
                        $list_title = 'Upcoming Birthdays the next ' . $atts['days'] . ' days';
                    } else {
                        $list_title = 'Today\'s Birthdays';
                    }
                    break;
                case 'anniversary':
                    if ($atts['days'] >= 1) {
                        $list_title = 'Upcoming Anniversaries the next ' . $atts['days'] . ' days';
                    } else {
                        $list_title = 'Today\'s Anniversaries';
                    }
                    break;
            }
        } else {
            $list_title = $atts['list_title'];
        }
        ob_start();
        // Prints the template's CSS file.
        do_action('cn_template_inline_css-' . $template->getSlug(), $atts);
        $out .= ob_get_contents();
        ob_end_clean();
        $out .= '<div class="connections-list cn-upcoming cn-' . $atts['list_type'] . '" id="cn-list" data-connections-version="' . $connections->options->getVersion() . '-' . $connections->options->getDBVersion() . '">' . "\n";
        $out .= "\n" . '<div class="cn-template cn-' . $template->getSlug() . '" id="cn-' . $template->getSlug() . '">' . "\n";
        $out .= "\n" . '<div class="cn-clear" id="cn-list-head">' . "\n";
        if ($atts['show_title']) {
            $out .= '<div class="cn-upcoming-title">' . $list_title . '</div>';
        }
        $out .= "\n" . '</div>' . "\n";
        $out .= '<div class="cn-clear" id="cn-list-body">' . "\n";
        foreach ($results as $row) {
            $entry = new cnvCard($row);
            $vCard =& $entry;
            $entry->name = '';
            $alternate == '' ? $alternate = '-alternate' : ($alternate = '');
            /*
             * Whether or not to show the last name.
             * Setting $entry->name is for compatibility to versions prior to 0.7.1.6
             */
            !$atts['show_lastname'] ? $entry->name = $entry->getFirstName() : ($entry->name = $entry->getFullFirstLastName());
            if (!$atts['show_lastname']) {
                $entry->setLastName('');
            }
            $out .= '<div class="cn-upcoming-row' . $alternate . ' vcard ' . '">' . "\n";
            ob_start();
            do_action('cn_action_card-' . $template->getSlug(), $entry, $template, $atts);
            $out .= ob_get_contents();
            ob_end_clean();
            $out .= '</div>' . "\n";
        }
        $out .= "\n" . '</div>' . "\n";
        $out .= "\n" . '<div class="cn-clear" id="cn-list-foot">' . "\n";
        $out .= "\n" . '</div>' . "\n";
        $out .= "\n" . '</div>' . "\n";
        $out .= "\n" . '</div>' . "\n";
    }
    if (cnSettingsAPI::get('connections', 'connections_compatibility', 'strip_rnt')) {
        $search = array("\r\n", "\r", "\n", "\t");
        $replace = array('', '', '', '');
        $out = str_replace($search, $replace, $out);
    }
    return $out;
}
Example #9
0
function processUpdateCategory()
{
	$category = new cnCategory();
	$format = new cnFormatting();
				
	$category->setID($format->sanitizeString($_POST['category_id']));
	$category->setName($format->sanitizeString($_POST['category_name']));
	$category->setParent($format->sanitizeString($_POST['category_parent']));
	$category->setSlug($format->sanitizeString($_POST['category_slug']));
	$category->setDescription($format->sanitizeString($_POST['category_description']));
	
	$category->update();
}
Example #10
0
/** @since version 0.7.1.0 */
function _connections_list($atts, $content = null)
{
    global $wpdb, $connections, $current_user;
    $form = new cnFormObjects();
    $convert = new cnFormatting();
    $format =& $convert;
    $template = new stdClass();
    $atts = shortcode_atts(array('id' => NULL, 'category' => NULL, 'exclude_category' => NULL, 'category_name' => NULL, 'wp_current_category' => 'false', 'allow_public_override' => 'false', 'private_override' => 'false', 'show_alphaindex' => 'false', 'repeat_alphaindex' => 'false', 'show_alphahead' => 'false', 'list_type' => NULL, 'limit' => NULL, 'offset' => NULL, 'order_by' => NULL, 'group_name' => NULL, 'last_name' => NULL, 'title' => NULL, 'organization' => NULL, 'department' => NULL, 'city' => NULL, 'state' => NULL, 'zip_code' => NULL, 'country' => NULL, 'template' => NULL, 'template_name' => NULL), $atts);
    /*
     * Convert some of the $atts values in the array to boolean.
     */
    $convert->toBoolean(&$atts['allow_public_override']);
    $convert->toBoolean(&$atts['private_override']);
    $convert->toBoolean(&$atts['show_alphaindex']);
    $convert->toBoolean(&$atts['repeat_alphaindex']);
    $convert->toBoolean(&$atts['show_alphahead']);
    $convert->toBoolean(&$atts['wp_current_category']);
    $permittedListTypes = array('individual', 'organization', 'family', 'connection_group');
    // Convert the supplied entry types $atts['list_type'] to an array.
    if (!empty($atts['list_type'])) {
        // Trim the space characters if present.
        $atts['list_type'] = str_replace(' ', '', $atts['list_type']);
        // Convert to array.
        $atts['list_type'] = explode(',', $atts['list_type']);
    }
    // Set the template type to the first in the entry type from the supplied if multiple list types are provided.
    if (!empty($atts['list_type']) && (bool) array_intersect((array) $atts['list_type'], $permittedListTypes)) {
        $templateType = $atts['list_type'][0];
    }
    /*
     * As of version 0.7.0.5 the $atts['template_name'] is deprecated.
     */
    if (isset($atts['template_name'])) {
        // First check to see if the template is in the custom template folder.
        if (is_dir(CN_CUSTOM_TEMPLATE_PATH) && is_readable(CN_CUSTOM_TEMPLATE_PATH)) {
            if (file_exists(CN_CUSTOM_TEMPLATE_PATH . '/' . $atts['template_name'] . '.php')) {
                $template->file = CN_CUSTOM_TEMPLATE_PATH . '/' . $atts['template_name'] . '.php';
            }
        }
        // If the template is not in the custom template folder, check for it in the default template folder.
        if (!isset($template->file)) {
            if (file_exists(CN_BASE_PATH . '/templates/' . $atts['template_name'] . '.php')) {
                $template->file = CN_BASE_PATH . '/templates/' . $atts['template_name'] . '.php';
            }
        }
    } else {
        $template = new cnTemplate();
        // Change the list type to family from connection_group to maintain compatibility with versions .0.7.0.4 and earlier.
        if ($atts['list_type'] === 'connection_group') {
            $atts['list_type'] = 'family';
        }
        /*
         * $atts['template'] can be either a string or an object. It is a string when set
         * with the shortcode attribute. If it is a string, the template will be loaded
         * via the cnTemplate class.
         * 
         * If the attribute is not set, it will be the object returned from the
         * cnOptions::getActiveTemplate() method which stores the default template
         * per list style.
         */
        if (isset($atts['template']) && !is_object($atts['template'])) {
            $template->load($atts['template']);
            $template->includeFunctions();
        } else {
            if (empty($templateType)) {
                $templateType = 'all';
            }
            // If no list type was specified, set the default ALL template.
            $template->init($connections->options->getActiveTemplate($templateType));
            $template->includeFunctions();
        }
    }
    // If no template is found, return an error message.
    if (!isset($template->file)) {
        return '<p style="color:red; font-weight:bold; text-align:center;">ERROR: Template "' . $atts['template_name'] . $atts['template'] . '" not found.</p>';
    }
    $atts = apply_filters('cn_list_atts', $atts);
    $results = $connections->retrieve->entries($atts);
    //print_r($connections->lastQuery);
    if (!empty($results)) {
        $results = apply_filters('cn_list_results', $results);
    }
    // Prints the template's CSS file.
    if (method_exists($template, 'printCSS')) {
        $out .= $template->printCSS();
    }
    // Prints the javascript tag in the footer if $template->js path is set
    if (method_exists($template, 'printJS')) {
        $template->printJS();
    }
    $out = apply_filters('cn_list_before', $out, $results);
    // If there are no results no need to proceed and output message.
    if (empty($results)) {
        $noResultMessage = 'No results';
        $noResultMessage = apply_filters('cn_no_result_message', $noResultMessage);
        return $out . '<p class="cn-no-results">' . $noResultMessage . '</p>';
    }
    $out .= '<a name="connections-list-head" style="float: left;"></a>' . "\n";
    /*
     * The alpha index is only displayed if set set to true and not set to repeat using the shortcode attributes.
     * If a alpha index is set to repeat, that is handled down separately.
     */
    if ($atts['show_alphaindex'] && !$atts['repeat_alphaindex']) {
        $index = "<div class='cn-alphaindex' style='text-align:right;font-size:larger;font-weight:bold'>" . $form->buildAlphaIndex() . "</div>";
        $out .= apply_filters('cn_list_index', $index, $results);
    }
    $out .= '<div class="connections-list">' . "\n";
    foreach ((array) $results as $row) {
        //$entry = new cnOutput($row);
        $entry = new cnvCard($row);
        //$vCard = new cnvCard($row);
        $vCard =& $entry;
        if (isset($continue)) {
            unset($continue);
        }
        if (isset($cities)) {
            unset($cities);
        }
        if (isset($states)) {
            unset($states);
        }
        if (isset($zipcodes)) {
            unset($zipcodes);
        }
        if (isset($countries)) {
            unset($countries);
        }
        if (isset($setAnchor)) {
            unset($setAnchor);
        }
        /*
         * Check to make sure there is data stored in the address array.
         * Cycle thru each address, building separate arrays for city, state, zip and country.
         */
        if ($entry->getAddresses()) {
            foreach ($entry->getAddresses() as $address) {
                if ($address->city != NULL) {
                    $cities[] = $address->city;
                }
                if ($address->state != NULL) {
                    $states[] = $address->state;
                }
                if ($address->zipcode != NULL) {
                    $zipcodes[] = $address->zipcode;
                }
                if ($address->country != NULL) {
                    $countries[] = $address->country;
                }
            }
        }
        /*
         * Filter out the entries that are wanted based on the
         * filter attributes that may have been used in the shortcode.
         * 
         * NOTE: The '@' operator is used to suppress PHP generated errors. This is done
         * because not every entry will have addresses to populate the arrays created above.
         * 
         * NOTE: Since the entry class returns all fields escaped, the shortcode filter
         * attribute needs to be escaped as well so the comparason between the two functions
         * as expected.
         */
        $atts['group_name'] = esc_attr($atts['group_name']);
        $atts['last_name'] = esc_attr($atts['last_name']);
        $atts['title'] = esc_attr($atts['title']);
        $atts['organization'] = esc_attr($atts['organization']);
        $atts['department'] = esc_attr($atts['department']);
        if ($entry->getFamilyName() != $atts['group_name'] && $atts['group_name'] != null) {
            $continue = true;
        }
        if ($entry->getLastName() != $atts['last_name'] && $atts['last_name'] != null) {
            $continue = true;
        }
        if ($entry->getTitle() != $atts['title'] && $atts['title'] != null) {
            $continue = true;
        }
        if ($entry->getOrganization() != $atts['organization'] && $atts['organization'] != null) {
            $continue = true;
        }
        if ($entry->getDepartment() != $atts['department'] && $atts['department'] != null) {
            $continue = true;
        }
        if (@(!in_array($atts['city'], $cities)) && $atts['city'] != null) {
            $continue = true;
        }
        if (@(!in_array($atts['state'], $states)) && $atts['state'] != null) {
            $continue = true;
        }
        if (@(!in_array($atts['zip_code'], $zipcodes)) && $atts['zip_code'] != null) {
            $continue = true;
        }
        if (@(!in_array($atts['country'], $countries)) && $atts['country'] != null) {
            $continue = true;
        }
        /*
         * If any of the above filters returned true, the script will continue to the next entry.
         */
        if ($continue == true) {
            continue;
        }
        /*
         * Checks the first letter of the last name to see if it is the next
         * letter in the alpha array and sets the anchor.
         * 
         * If the alpha index is set to repeat it will append to the anchor.
         * 
         * If the alpha head set to true it will append the alpha head to the anchor.
         */
        $currentLetter = strtoupper(mb_substr($entry->getSortColumn(), 0, 1));
        if ($currentLetter != $previousLetter && $atts['id'] == null) {
            if ($atts['show_alphaindex']) {
                $setAnchor = '<a class="cn-index-head" name="' . $currentLetter . '"></a>';
            }
            if ($atts['show_alphaindex'] && $atts['repeat_alphaindex']) {
                $setAnchor .= "<div class='cn-alphaindex' style='text-align:right;font-size:larger;font-weight:bold'>" . $form->buildAlphaIndex() . "</div>";
            }
            if ($atts['show_alphahead']) {
                $setAnchor .= '<h4 class="cn-alphahead">' . $currentLetter . '</h4>';
            }
            $previousLetter = $currentLetter;
        } else {
            $setAnchor = null;
        }
        /*
         * The anchor and/or the alpha head is displayed if set to true using the shortcode attributes.
         */
        if ($atts['show_alphaindex'] || $atts['show_alphahead']) {
            $out .= $setAnchor;
        }
        $alternate == '' ? $alternate = '-alternate' : ($alternate = '');
        $out .= '<div class="cn-list-row' . $alternate . ' vcard ' . $template->slug . ' ' . $entry->getCategoryClass(TRUE) . '">' . "\n";
        $out = apply_filters('cn_entry_before', $out, $entry);
        ob_start();
        include $template->file;
        $out .= ob_get_contents();
        ob_end_clean();
        $out = apply_filters('cn_entry_after', $out, $entry);
        $out .= '</div>' . "\n";
    }
    $out .= '<div class="clear"></div>' . "\n";
    $out .= '</div>' . "\n";
    $out = apply_filters('cn_list_after', $out, $results);
    return $out;
}
 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;
 }
 /**
  * Returns as an array of objects containing the dates per the defined options for the current entry.
  *
  * Accepted options for the $atts property are:
  * preferred (bool) Retrieve the preferred entry date.
  *  type (array) || (string) Retrieve specific date types.
  *   Permitted Types:
  *    baptism
  *    certification
  *    employment
  *    membership
  *    graduate_high_school
  *    graduate_college
  *    ordination
  *
  * Filters:
  *  cn_date_atts => (array) Set the method attributes.
  *  cn_date_cached => (bool) Define if the returned dates should be from the object cache or queried from the db.
  *  cn_date => (object) Individual date as it is processed thru the loop.
  *  cn_dates => (array) All dates before they are returned.
  *
  * @access public
  * @since 0.7.3
  * @version 1.0
  * @param array   $atts         Accepted values as noted above.
  * @param bool    $cached       Returns the cached date data rather than querying the db.
  * @param bool    $saving       Whether or no the data is being saved to the db.
  *
  * @return array
  */
 public function getDates($atts = array(), $cached = TRUE, $saving = FALSE)
 {
     // Grab an instance of the Connections object.
     $instance = Connections_Directory();
     $results = array();
     $atts = apply_filters('cn_date_atts', $atts);
     $cached = apply_filters('cn_date_cached', $cached);
     /*
      * // START -- Set the default attributes array. \\
      */
     $defaults = array('preferred' => FALSE, 'type' => NULL);
     $atts = cnSanitize::args($atts, $defaults);
     $atts['id'] = $this->getId();
     /*
      * // END -- Set the default attributes array if not supplied. \\
      */
     /*
      * Load back into the results the data from the legacy fields, anniversary and birthday,
      * for backward compatibility with versions 0.7.2.6 and older.
      */
     if (!empty($this->anniversary)) {
         $anniversary = new stdClass();
         $anniversary->id = 0;
         $anniversary->order = 0;
         $anniversary->preferred = FALSE;
         $anniversary->type = 'anniversary';
         $anniversary->name = __('Anniversary', 'connections');
         $anniversary->date = $this->getAnniversary('Y-m-d');
         $anniversary->day = $this->getAnniversary('m-d');
         $anniversary->visibility = 'public';
         $results['anniversary'] = $anniversary;
     }
     if (!empty($this->birthday)) {
         $birthday = new stdClass();
         $birthday->id = 0;
         $birthday->order = 0;
         $birthday->preferred = FALSE;
         $birthday->type = 'birthday';
         $birthday->name = __('Birthday', 'connections');
         $birthday->date = $this->getBirthday('Y-m-d');
         $birthday->day = $this->getBirthday('m-d');
         $birthday->visibility = 'public';
         $results['birthday'] = $birthday;
     }
     if ($cached) {
         if (!empty($this->dates)) {
             $dates = unserialize($this->dates);
             if (empty($dates)) {
                 return $results;
             }
             /**
              * @var bool   $preferred
              * @var string $type
              */
             extract($atts);
             /*
              * Covert to an array if it was supplied as a comma delimited string
              */
             cnFunction::parseStringList($type);
             foreach ((array) $dates as $key => $date) {
                 /**
                  * Allow plugins to filter raw data before object is setup.
                  *
                  * @since 8.5.19
                  *
                  * @param array $date
                  */
                 $date = apply_filters('cn_date-pre_setup', $date);
                 $row = new stdClass();
                 isset($date['id']) ? $row->id = (int) $date['id'] : ($row->id = 0);
                 isset($date['order']) ? $row->order = (int) $date['order'] : ($row->order = 0);
                 isset($date['preferred']) ? $row->preferred = (bool) $date['preferred'] : ($row->preferred = FALSE);
                 isset($date['type']) ? $row->type = $this->format->sanitizeString($date['type']) : ($row->type = '');
                 isset($date['date']) ? $row->date = $this->format->sanitizeString($date['date']) : ($row->date = '');
                 isset($date['visibility']) ? $row->visibility = $this->format->sanitizeString($date['visibility']) : ($row->visibility = '');
                 /*
                  * Set the date name based on the type.
                  */
                 $dateTypes = $instance->options->getDateOptions();
                 $row->name = $dateTypes[$row->type];
                 /*
                  * If the date type is anniversary or birthday and the date is equal to the date
                  * saved in the legacy fields, unset the data imported from the legacy field.
                  * This is for compatibility with versions 0.7.2.6 and older.
                  *
                  * NOTE: Only the month and day will be compared because the legacy getAnniversary() and getBirthday() methods
                  * will return the year of the next anniversary or birthday. IE: if that date in the current year has already
                  * passed the year would be the next year.
                  */
                 if ('anniversary' == $row->type && isset($results['anniversary']) && substr($row->date, 5, 5) == $results['anniversary']->day) {
                     unset($results['anniversary']);
                 }
                 if ('birthday' == $row->type && isset($results['birthday']) && substr($row->date, 5, 5) == $results['birthday']->day) {
                     unset($results['birthday']);
                 }
                 /*
                  * // START -- Do not return dates that do not match the supplied $atts.
                  */
                 if ($preferred && !$row->preferred) {
                     continue;
                 }
                 if (!empty($type) && !in_array($row->type, $type)) {
                     continue;
                 }
                 /*
                  * // END -- Do not return dates that do not match the supplied $atts.
                  */
                 /*
                  * // START -- Compatibility for previous versions.
                  */
                 // Versions prior to 8.1.5 may not have visibility set, so we'll assume it was 'public' since it wasn't the option before.
                 if (!isset($date['visibility']) || empty($date['visibility'])) {
                     $row->visibility = 'public';
                 }
                 /*
                  * // END -- Compatibility for previous versions.
                  */
                 // If the user does not have permission to view the address, do not return it.
                 if (!$this->validate->userPermitted($row->visibility) && !$saving) {
                     continue;
                 }
                 $results[] = apply_filters('cn_date', $row);
             }
         }
     } else {
         // Exit right away and return an emtpy array if the entry ID has not been set otherwise all dates will be returned by the query.
         if (!isset($this->id) || empty($this->id)) {
             return array();
         }
         $dates = $instance->retrieve->dates($atts, $saving);
         if (empty($dates)) {
             return $results;
         }
         foreach ($dates as $date) {
             /** This filter is documented in ../includes/entry/class.entry-data.php */
             $date = apply_filters('cn_date-pre_setup', $date);
             $date->id = (int) $date->id;
             $date->order = (int) $date->order;
             $date->preferred = (bool) $date->preferred;
             $date->type = $this->format->sanitizeString($date->type);
             $date->date = $this->format->sanitizeString($date->date);
             $date->visibility = $this->format->sanitizeString($date->visibility);
             /*
              * Set the date name based on the date type.
              */
             $dateTypes = $instance->options->getDateOptions();
             $date->name = $dateTypes[$date->type];
             /*
              * If the date type is anniversary or birthday and the date is equal to the date
              * saved in the legacy fields are the same, unset the data imported from the legacy field.
              * This is for compatibility with versions 0.7.2.6 and older.
              */
             if ('anniversary' == $date->type && isset($results['anniversary']) && $date->date == $results['anniversary']->date) {
                 unset($results['anniversary']);
             }
             if ('birthday' == $date->type && isset($results['birthday']) && $date->date == $results['birthday']->date) {
                 unset($results['birthday']);
             }
             /*
              * If the date type is anniversary or birthday and the date is equal to the date
              * saved in the legacy fields, unset the data imported from the legacy field.
              * This is for compatibility with versions 0.7.2.6 and older.
              *
              * NOTE: Only the month and day will be compared because the legacy getAnniversary() and getBirthday() methods
              * will return the year of the next anniversary or birthday. IE: if that date in the current year has already
              * passed the year would be the next year.
              */
             if ('anniversary' == $date->type && isset($results['anniversary']) && substr($date->date, 5, 5) == $results['anniversary']->day) {
                 unset($results['anniversary']);
             }
             if ('birthday' == $date->type && isset($results['birthday']) && substr($date->date, 5, 5) == $results['birthday']->day) {
                 unset($results['birthday']);
             }
             $results[] = apply_filters('cn_date', $date);
         }
     }
     return apply_filters('cn_dates', $results);
 }
    /**
     * The dashboard widget used to display the systems info.
     *
     * @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 system info.
     */
    public static function system()
    {
        global $wpdb, $wp_version;
        // Grab an instance of the Connections object.
        $instance = Connections_Directory();
        $convert = new cnFormatting();
        // Get MYSQL Version
        $sqlversion = $wpdb->db_version();
        // GET SQL Mode
        $mysqlinfo = $wpdb->get_results("SHOW VARIABLES LIKE 'sql_mode'");
        if (is_array($mysqlinfo)) {
            $sql_mode = $mysqlinfo[0]->Value;
        }
        if (empty($sql_mode)) {
            $sql_mode = __('Not set', 'connections');
        }
        // Get PHP Safe Mode
        if (ini_get('safe_mode')) {
            $safe_mode = __('On', 'connections');
        } else {
            $safe_mode = __('Off', 'connections');
        }
        // Get PHP allow_url_fopen
        if (ini_get('allow_url_fopen')) {
            $allow_url_fopen = __('On', 'connections');
        } else {
            $allow_url_fopen = __('Off', 'connections');
        }
        // Get PHP Max Upload Size
        if (ini_get('upload_max_filesize')) {
            $upload_max = ini_get('upload_max_filesize');
        } else {
            $upload_max = __('N/A', 'connections');
        }
        // Get PHP Output buffer Size
        if (ini_get('pcre.backtrack_limit')) {
            $backtrack_limit = ini_get('pcre.backtrack_limit');
        } else {
            $backtrack_limit = __('N/A', 'connections');
        }
        // Get PHP Max Post Size
        if (ini_get('post_max_size')) {
            $post_max = ini_get('post_max_size');
        } else {
            $post_max = __('N/A', 'connections');
        }
        // Get PHP Max execution time
        if (ini_get('max_execution_time')) {
            $max_execute = ini_get('max_execution_time');
        } else {
            $max_execute = __('N/A', 'connections');
        }
        // Get PHP Memory Limit
        if (ini_get('memory_limit')) {
            $memory_limit = ini_get('memory_limit');
        } else {
            $memory_limit = __('N/A', 'connections');
        }
        // Get actual memory_get_usage
        if (function_exists('memory_get_usage')) {
            $memory_usage = round(memory_get_usage() / 1024 / 1024, 2) . ' ' . __('MByte', 'connections');
        } else {
            $memory_usage = __('N/A', 'connections');
        }
        // required for EXIF read
        if (is_callable('exif_read_data')) {
            $exif = __('Yes', 'connections') . " ( V" . substr(phpversion('exif'), 0, 4) . ")";
        } else {
            $exif = __('No', 'connections');
        }
        // required for meta data
        if (is_callable('iptcparse')) {
            $iptc = __('Yes', 'connections');
        } else {
            $iptc = __('No', 'connections');
        }
        // required for meta data
        if (is_callable('xml_parser_create')) {
            $xml = __('Yes', 'connections');
        } else {
            $xml = __('No', 'connections');
        }
        ?>
		<h4><strong><?php 
        _e('Version Information', 'connections');
        ?>
</strong></h4>

		<ul class="settings">
			<li>WordPress: <?php 
        echo $wp_version;
        ?>
</li>
			<li>Multisite: <?php 
        echo $convert->toYesNo(is_multisite());
        ?>
</li>
			<li>Connections: <?php 
        echo $instance->options->getVersion();
        ?>
</li>
			<li>Database: <?php 
        echo $instance->options->getDBVersion();
        ?>
</li>
		</ul>

		<h4><strong><?php 
        _e('Constants', 'connections');
        ?>
</strong></h4>

		<ul class="settings">
			<li><strong>CN_MULTISITE_ENABLED:</strong> <?php 
        echo CN_MULTISITE_ENABLED ? __('TRUE', 'connections') : __('FALSE', 'connections');
        ?>
</li>
			<li><strong>CN_ENTRY_TABLE:</strong> <?php 
        echo CN_ENTRY_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_ADDRESS_TABLE:</strong> <?php 
        echo CN_ENTRY_ADDRESS_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_PHONE_TABLE:</strong> <?php 
        echo CN_ENTRY_PHONE_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_EMAIL_TABLE:</strong> <?php 
        echo CN_ENTRY_EMAIL_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_MESSENGER_TABLE:</strong> <?php 
        echo CN_ENTRY_MESSENGER_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_SOCIAL_TABLE:</strong> <?php 
        echo CN_ENTRY_SOCIAL_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_LINK_TABLE:</strong> <?php 
        echo CN_ENTRY_LINK_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_DATE_TABLE:</strong> <?php 
        echo CN_ENTRY_DATE_TABLE;
        ?>
</li>
			<li><strong>CN_ENTRY_TABLE_META:</strong> <?php 
        echo CN_ENTRY_TABLE_META;
        ?>
</li>
			<li><strong>CN_TERMS_TABLE:</strong> <?php 
        echo CN_TERMS_TABLE;
        ?>
</li>
			<li><strong>CN_TERM_TAXONOMY_TABLE:</strong> <?php 
        echo CN_TERM_TAXONOMY_TABLE;
        ?>
</li>
			<li><strong>CN_TERM_RELATIONSHIP_TABLE:</strong> <?php 
        echo CN_TERM_RELATIONSHIP_TABLE;
        ?>
</li>
			<li><strong>CN_DIR_NAME:</strong> <?php 
        echo CN_DIR_NAME;
        ?>
</li>
			<li><strong>CN_BASE_NAME:</strong> <?php 
        echo CN_BASE_NAME;
        ?>
</li>
			<li><strong>CN_PATH:</strong> <?php 
        echo CN_PATH;
        ?>
</li>
			<li><strong>CN_URL:</strong> <?php 
        echo CN_URL;
        ?>
</li>
			<li><strong>CN_RELATIVE_URL:</strong> <?php 
        echo CN_RELATIVE_URL;
        ?>
</li>
			<li><strong>CN_IMAGE_PATH:</strong> <?php 
        echo CN_IMAGE_PATH;
        ?>
</li>
			<li><strong>CN_IMAGE_BASE_URL:</strong> <?php 
        echo CN_IMAGE_BASE_URL;
        ?>
</li>
			<li><strong>CN_IMAGE_RELATIVE_URL:</strong> <?php 
        echo CN_IMAGE_RELATIVE_URL;
        ?>
</li>
			<li><strong>CN_TEMPLATE_PATH:</strong> <?php 
        echo CN_TEMPLATE_PATH;
        ?>
</li>
			<li><strong>CN_TEMPLATE_URL:</strong> <?php 
        echo CN_TEMPLATE_URL;
        ?>
</li>
			<li><strong>CN_TEMPLATE_RELATIVE_URL:</strong> <?php 
        echo CN_TEMPLATE_RELATIVE_URL;
        ?>
</li>
			<!-- <li><strong>CN_CUSTOM_TEMPLATE_PATH:</strong> <?php 
        // echo CN_CUSTOM_TEMPLATE_PATH
        ?>
</li>
			<li><strong>CN_CUSTOM_TEMPLATE_URL:</strong> <?php 
        // echo CN_CUSTOM_TEMPLATE_URL
        ?>
</li>
			<li><strong>CN_CUSTOM_TEMPLATE_RELATIVE_URL:</strong> <?php 
        // echo CN_CUSTOM_TEMPLATE_RELATIVE_URL
        ?>
</li>
			<li><strong>CN_CACHE_PATH:</strong> <?php 
        echo CN_CACHE_PATH;
        ?>
</li> -->
		</ul>

		<h4><strong><?php 
        _e('Server Configuration', 'connections');
        ?>
</strong></h4>

		<ul class="settings">
			<li><?php 
        _e('Operating System', 'connections');
        ?>
 : <span><?php 
        echo PHP_OS;
        ?>
&nbsp;(<?php 
        echo PHP_INT_SIZE * 8;
        ?>
&nbsp;Bit)</span></li>
			<li><?php 
        _e('Server', 'connections');
        ?>
 : <span><?php 
        echo $_SERVER["SERVER_SOFTWARE"];
        ?>
</span></li>
			<li><?php 
        _e('Memory usage', 'connections');
        ?>
 : <span><?php 
        echo $memory_usage;
        ?>
</span></li>
			<li><?php 
        _e('MYSQL Version', 'connections');
        ?>
 : <span><?php 
        echo $sqlversion;
        ?>
</span></li>
			<li><?php 
        _e('SQL Mode', 'connections');
        ?>
 : <span><?php 
        echo $sql_mode;
        ?>
</span></li>
			<li><?php 
        _e('PHP Version', 'connections');
        ?>
 : <span><?php 
        echo PHP_VERSION;
        ?>
</span></li>
			<li><?php 
        _e('PHP Safe Mode', 'connections');
        ?>
 : <span><?php 
        echo $safe_mode;
        ?>
</span></li>
			<li><?php 
        _e('PHP Allow URL fopen', 'connections');
        ?>
 : <span><?php 
        echo $allow_url_fopen;
        ?>
</span></li>
			<li><?php 
        _e('PHP Memory Limit', 'connections');
        ?>
 : <span><?php 
        echo $memory_limit;
        ?>
</span></li>
			<li><?php 
        _e('PHP Max Upload Size', 'connections');
        ?>
 : <span><?php 
        echo $upload_max;
        ?>
</span></li>
			<li><?php 
        _e('PHP Max Post Size', 'connections');
        ?>
 : <span><?php 
        echo $post_max;
        ?>
</span></li>
			<li><?php 
        _e('PCRE Backtracking Limit', 'connections');
        ?>
 : <span><?php 
        echo $backtrack_limit;
        ?>
</span></li>
			<li><?php 
        _e('PHP Max Script Execute Time', 'connections');
        ?>
 : <span><?php 
        echo $max_execute;
        ?>
s</span></li>
			<li><?php 
        _e('PHP Exif support', 'connections');
        ?>
 : <span><?php 
        echo $exif;
        ?>
</span></li>
			<li><?php 
        _e('PHP IPTC support', 'connections');
        ?>
 : <span><?php 
        echo $iptc;
        ?>
</span></li>
			<li><?php 
        _e('PHP XML support', 'connections');
        ?>
 : <span><?php 
        echo $xml;
        ?>
</span></li>
		</ul>

		<h4><strong><?php 
        _e('Graphic Library', 'connections');
        ?>
</strong></h4>

		<?php 
        if (function_exists("gd_info")) {
            $info = gd_info();
            $keys = array_keys($info);
            echo '<ul class="settings">';
            for ($i = 0; $i < count($keys); $i++) {
                if (is_bool($info[$keys[$i]])) {
                    echo "<li> " . $keys[$i] . " : <span>" . $convert->toYesNo($info[$keys[$i]]) . "</span></li>\n";
                } else {
                    echo "<li> " . $keys[$i] . " : <span>" . $info[$keys[$i]] . "</span></li>\n";
                }
            }
            echo '</ul>';
        } else {
            echo '<h4>' . __('No GD support', 'connections') . '!</h4>';
        }
        ?>

		<h4><strong><?php 
        _e('Folder Permissions', 'connections');
        ?>
</strong></h4>

		<?php 
        echo '<ul class="settings">';
        echo '<li>', __('Image Path Exists:', 'connections'), ' ', $convert->toYesNo(is_dir(CN_IMAGE_PATH)), '</li>';
        if (is_dir(CN_IMAGE_PATH)) {
            echo '<li>', __('Image Path Writeable:', 'connections'), ' ', $convert->toYesNo(is_writeable(CN_IMAGE_PATH)), '</li>';
        }
        echo '<li>', __('Template Path Exists:', 'connections'), ' ', $convert->toYesNo(is_dir(CN_CUSTOM_TEMPLATE_PATH)), '</li>';
        if (is_dir(CN_CUSTOM_TEMPLATE_PATH)) {
            echo '<li>', __('Template Path Writeable:', 'connections'), ' ', $convert->toYesNo(is_writeable(CN_CUSTOM_TEMPLATE_PATH)), '</li>';
        }
        echo '<li>', __('Cache Path Exists:', 'connections'), ' ', $convert->toYesNo(is_dir(CN_CACHE_PATH)), '</li>';
        if (is_dir(CN_CACHE_PATH)) {
            echo '<li>', __('Cache Path Writeable:', 'connections'), ' ', $convert->toYesNo(is_writeable(CN_CACHE_PATH)), '</li>';
        }
        echo '</ul>';
    }
 /**
  * Update meta by ID.
  *
  * NOTE: This is the Connections equivalent of @see update_metadata_by_mid() in WordPress core ../wp-includes/meta.php
  *
  * @access public
  * @since  8.1.7
  * @static
  *
  * @global wpdb  $wpdb  WordPress database abstraction object.
  *
  * @uses   cnMeta::tableName()
  * @uses   cnMeta::getByID()
  * @uses   sanitize_meta()
  * @uses   cnFormatting::maybeJSONencode()
  * @uses   do_action()
  * @uses   wpdb::update()
  * @uses   wp_cache_delete()
  *
  * @param string $type  Type of object metadata is for (e.g., entry, term).
  * @param int    $id    ID for a specific meta row.
  * @param string $value Metadata value.
  * @param mixed  $key   string|bool Optional, you can provide a meta key to update it.
  *
  * @return bool         TRUE on successful update, FALSE on failure.
  */
 public static function updateByID($type, $id, $value, $key = FALSE)
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     // Make sure everything is valid.
     if (!$type || !is_numeric($id)) {
         return FALSE;
     }
     $id = absint($id);
     if (!$id) {
         return FALSE;
     }
     $table = self::tableName($type);
     $column = sanitize_key($type . '_id');
     $id_column = 'meta_id';
     // Fetch the meta and go on if it's found.
     if ($meta = self::getByID($type, $id)) {
         $original_key = $meta->meta_key;
         $object_id = $meta->{$column};
         // If a new meta_key (last parameter) was specified, change the meta key,
         // otherwise use the original key in the update statement.
         if (FALSE === $key) {
             $key = $original_key;
         } elseif (!is_string($key)) {
             return FALSE;
         }
         // Sanitize the meta
         $_meta_value = $value;
         $value = wp_unslash($value);
         $value = sanitize_meta($key, $value, 'cn_' . $type);
         $value = cnFormatting::maybeJSONencode($value);
         // Format the data query arguments.
         $data = array('meta_key' => $key, 'meta_value' => $value);
         // Format the where query arguments.
         $where = array();
         $where[$id_column] = $id;
         /** This action is documented in includes/class.meta.php */
         do_action("cn_update_{$type}_meta", $id, $object_id, $key, $_meta_value);
         // Run the update query, all fields in $data are %s, $where is a %d.
         $result = $wpdb->update($table, $data, $where, '%s', '%d');
         if (!$result) {
             return FALSE;
         }
         // Clear the caches.
         wp_cache_delete($object_id, 'cn_' . $type . '_meta');
         /** This action is documented in includes/class.meta.php */
         do_action("cn_updated_{$type}_meta", $id, $object_id, $key, $_meta_value);
         return TRUE;
     }
     // And if the meta was not found.
     return FALSE;
 }
Image Path Writeable:       <?php 
echo cnFormatting::toYesNo(is_writeable(CN_IMAGE_PATH)) . PHP_EOL;
?>

Template Path Exists:       <?php 
echo cnFormatting::toYesNo(is_dir(CN_CUSTOM_TEMPLATE_PATH)) . PHP_EOL;
?>
Template Path Writeable:    <?php 
echo cnFormatting::toYesNo(is_writeable(CN_CUSTOM_TEMPLATE_PATH)) . PHP_EOL;
?>

Cache Path Exists:          <?php 
echo cnFormatting::toYesNo(is_dir(CN_CACHE_PATH)) . PHP_EOL;
?>
Cache Path Writeable:       <?php 
echo cnFormatting::toYesNo(is_writeable(CN_CACHE_PATH)) . PHP_EOL;
// Get plugins that have an update
$updates = get_plugin_updates();
// Must-use plugins
$muplugins = get_mu_plugins();
if (0 < count($muplugins)) {
    ?>
-- Must-Use Plugins

<?php 
    foreach ($muplugins as $plugin => $plugin_data) {
        echo $plugin_data['Name'] . ': ' . $plugin_data['Version'] . PHP_EOL;
    }
    do_action('cn_sysinfo_after_wordpress_mu_plugins');
}
?>
 /**
  * Write the CSV rows for the current step.
  *
  * @access public
  * @since  8.5.1
  */
 public function writeRows()
 {
     $results = $this->getData();
     $rows = '';
     if (!empty($results)) {
         // Go through each entry...
         foreach ($results as $entry) {
             $fieldCount = count($this->fields);
             $row = '';
             // ...and go through each cell the user wants to export, and match it with the cell in the entry...
             for ($i = 0; $i < $fieldCount; $i++) {
                 // ...then find out if it's a breakout cell and process it properly...
                 switch ($this->fields[$i]['type']) {
                     case 1:
                         // Export a standard breakout; just list them all in the order requested...
                         $row .= $this->exportBreakoutCell($this->fields[$i], $entry->id);
                         break;
                     case 2:
                         // Process category table and list all categories in a single cell...
                         $terms = array();
                         $results = $this->getTerms($entry->id, 'category');
                         foreach ($results as $term) {
                             $terms[] = $term->name;
                         }
                         $row .= $this->escapeAndQuote(implode(',', $terms)) . ',';
                         break;
                     case 3:
                         $count = $this->getTermCount('category');
                         $terms = array();
                         // Process the category table by breaking them out in separate cells,
                         // Prepare an empty frame of the category cells...
                         for ($j = 0; $j < $count + 1; $j++) {
                             // Make an array filled with empty cells
                             $terms[$j] = '"",';
                         }
                         // Now start filling in the empty cells with data...
                         $row = $this->getTerms($entry->id, 'category');
                         $j = 0;
                         foreach ($row as $result) {
                             $terms[$j] = $this->escapeAndQuote($result->name) . ',';
                             $j++;
                         }
                         $row .= implode('', $terms);
                         break;
                     case 4:
                         // Export breakout data from the serialized option cell.
                         $row .= $this->exportBreakoutOptionsCell($this->fields[$i], $entry);
                         break;
                     case 5:
                         $data = '';
                         $meta = cnMeta::get('entry', $entry->id, $this->fields[$i]['field'], TRUE);
                         if (!empty($meta)) {
                             $data = cnFormatting::maybeJSONencode($meta);
                         }
                         $row .= $this->escapeAndQuote($data) . ',';
                         break;
                     case 6:
                         $terms = array();
                         $parent = $this->fields[$i]['child_of'];
                         $results = $this->getTerms($entry->id, 'category');
                         foreach ($results as $term) {
                             $terms[] = $parent . ':' . $term->term_id;
                             if (cnTerm::isAncestorOf($parent, $term->term_id, 'category')) {
                                 $terms[] = $term->name;
                             }
                         }
                         $row .= $this->escapeAndQuote(implode(',', $terms)) . ',';
                         break;
                     default:
                         // If no breakout type is defined, only display the cell data...
                         $row .= $this->escapeAndQuote($entry->{$this->fields[$i]['field']}) . ',';
                         break;
                 }
             }
             // Trim the trailing comma and space, then add newline.
             $rows .= rtrim($row, ',') . "\r\n";
         }
         // Now write the data...
         $this->write($rows);
         return $rows;
     }
     return FALSE;
 }
 /**
  * Update a category.
  *
  * @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 updateCategory()
 {
     $form = new cnFormObjects();
     /*
      * Check whether user can edit Settings
      */
     if (current_user_can('connections_edit_categories')) {
         check_admin_referer($form->getNonce('update_category'), '_cn_wpnonce');
         $category = new cnCategory();
         $format = new cnFormatting();
         $category->setID($format->sanitizeString($_POST['category_id']));
         $category->setName($format->sanitizeString($_POST['category_name']));
         $category->setParent($format->sanitizeString($_POST['category_parent']));
         $category->setSlug($format->sanitizeString($_POST['category_slug']));
         $category->setDescription($format->sanitizeString($_POST['category_description'], TRUE));
         $category->update();
         wp_redirect(get_admin_url(get_current_blog_id(), 'admin.php?page=connections_categories'));
         exit;
     } else {
         cnMessage::set('error', 'capability_categories');
     }
 }
 /**
  * Change the meta values to be human readable.
  *
  * @access private
  * @since  8.2.10
  * @static
  *
  * @param string $value
  * @param string $key
  *
  * @return string
  */
 public static function metaValue($value, $key)
 {
     switch ($key) {
         case 'headers':
             $value = cnFormatting::maybeJSONdecode($value);
             $value = '<ul><li>' . implode('</li><li>', $value) . '</li></ul>';
             break;
         case 'type':
         case 'character_set':
             $value = '<p>' . esc_html($value) . '</p>';
             break;
         case 'from':
             if (empty($value)) {
                 $value = '<p>' . __('None', 'connections') . '</p>';
             } else {
                 $value = '<p>' . esc_html($value) . '</p>';
             }
             break;
         case 'to':
         case 'cc':
         case 'bcc':
         case 'attachments':
             $value = cnFormatting::maybeJSONdecode($value);
             if (empty($value)) {
                 $value = '<p>' . __('None', 'connections') . '</p>';
             } else {
                 if (is_array($value)) {
                     $value = '<ul><li>' . implode('</li><li>', array_map('esc_html', $value)) . '</li></ul>';
                 } else {
                     $value = '<ul><li>' . esc_html($value) . '</li></ul>';
                 }
             }
             break;
         case 'response':
             $value = '<p>' . ('success' == $value ? __('Successfully', 'connections') : __('Failed', 'connections')) . '</p>';
             break;
     }
     return $value;
 }