/** * Builds the Swiper Carousel shortcode output. * * @since 1.0.0 * @param array $atts Attributes of the swiper carousel shortcode. * @param string $content Shortcode content. * @return string HTML content to display the swiper carousel. */ public static function swiper_carousel($atts = null, $content = null) { static $instance = 0; $instance++; // Parse attributes. $atts = shortcode_atts(array('id' => false, 'posts_per_page' => get_option('posts_per_page'), 'post_type' => 'post', 'taxonomy' => 'category', 'tax_term' => false, 'tax_operator' => 'IN', 'author' => '', 'offset' => 0, 'order' => 'DESC', 'orderby' => 'date', 'post_parent' => false, 'post_status' => 'publish', 'ignore_sticky_posts' => 'no', 'linked_title' => 'yes', 'linked_image' => 'yes', 'content_type' => 'part', 'content_length' => 55, 'button_text' => __('read more', 'cherry-shortcodes'), 'class' => '', 'template' => 'default.tmpl', 'crop_image' => 'no', 'crop_width' => 540, 'crop_height' => 320, 'slides_per_view' => 3, 'slides_per_group' => 1, 'slides_per_column' => 1, 'space_between_slides' => 10, 'swiper_duration_speed' => 300, 'swiper_loop' => 'yes', 'swiper_free_mode' => 'no', 'swiper_grab_cursor' => 'yes', 'swiper_mouse_wheel' => 'no', 'swiper_centered_slide' => 'no', 'swiper_effect' => 'slide', 'swiper_pagination' => 'yes', 'swiper_navigation' => 'yes', 'swiper_navigation_position' => 'inner'), $atts, 'swiper_carousel'); $id = $atts['id']; $posts_per_page = intval($atts['posts_per_page']); $post_type = sanitize_text_field($atts['post_type']); $post_type = explode(',', $post_type); $taxonomy = sanitize_key($atts['taxonomy']); $tax_term = sanitize_text_field($atts['tax_term']); $tax_operator = $atts['tax_operator']; $author = sanitize_text_field($atts['author']); $offset = intval($atts['offset']); $order = sanitize_key($atts['order']); $orderby = sanitize_key($atts['orderby']); $post_parent = $atts['post_parent']; $post_status = $atts['post_status']; $ignore_sticky_posts = (bool) ($atts['ignore_sticky_posts'] === 'yes') ? true : false; $template_name = sanitize_file_name($atts['template']); $crop_image = (bool) ($atts['crop_image'] === 'yes') ? true : false; $crop_width = intval($atts['crop_width']); $crop_height = intval($atts['crop_height']); $slides_per_view = intval($atts['slides_per_view']); $slides_per_group = intval($atts['slides_per_group']); $slides_per_column = intval($atts['slides_per_column']); $space_between_slides = intval($atts['space_between_slides']); $swiper_duration_speed = intval($atts['swiper_duration_speed']); $swiper_loop = (bool) ($atts['swiper_loop'] === 'yes') ? true : false; $swiper_free_mode = (bool) ($atts['swiper_free_mode'] === 'yes') ? true : false; $swiper_grab_cursor = (bool) ($atts['swiper_grab_cursor'] === 'yes') ? true : false; $swiper_mouse_wheel = (bool) ($atts['swiper_mouse_wheel'] === 'yes') ? true : false; $swiper_centered_slide = (bool) ($atts['swiper_centered_slide'] === 'yes') ? true : false; $swiper_effect = sanitize_text_field($atts['swiper_effect']); $swiper_pagination = (bool) ($atts['swiper_pagination'] === 'yes') ? true : false; $swiper_navigation = (bool) ($atts['swiper_navigation'] === 'yes') ? true : false; $swiper_navigation_position = $atts['swiper_navigation_position']; // Set up initial query for post. $args = array('category_name' => '', 'order' => $order, 'orderby' => $orderby, 'post_type' => $post_type, 'posts_per_page' => $posts_per_page); // Ignore Sticky Posts. if ($ignore_sticky_posts) { $args['ignore_sticky_posts'] = true; } // If Post IDs if ($id) { $posts_in = array_map('intval', explode(',', $id)); $args['post__in'] = $posts_in; } // Post Author if (!empty($author)) { $args['author'] = $author; } // Offset if (!empty($offset)) { $args['offset'] = $offset; } // Post Status $post_status = explode(', ', $post_status); $validated = array(); $available = array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash', 'any'); foreach ($post_status as $unvalidated) { if (in_array($unvalidated, $available)) { $validated[] = $unvalidated; } } if (!empty($validated)) { $args['post_status'] = $validated; $args['perm'] = 'readable'; } // If taxonomy attributes, create a taxonomy query. if (!empty($taxonomy) && !empty($tax_term)) { // Term string to array. $tax_term = explode(',', $tax_term); // Validate operator. if (!in_array($tax_operator, array('IN', 'NOT IN', 'AND'))) { $tax_operator = 'IN'; } $tax_args = array('tax_query' => array(array('taxonomy' => $taxonomy, 'field' => is_numeric($tax_term[0]) ? 'id' : 'slug', 'terms' => $tax_term, 'operator' => $tax_operator))); // Check for multiple taxonomy queries. $count = 2; $more_tax_queries = false; while (isset($original_atts['taxonomy_' . $count]) && !empty($original_atts['taxonomy_' . $count]) && isset($original_atts['tax_' . $count . '_term']) && !empty($original_atts['tax_' . $count . '_term'])) { // Sanitize values. $more_tax_queries = true; $taxonomy = sanitize_key($original_atts['taxonomy_' . $count]); $terms = explode(', ', sanitize_text_field($original_atts['tax_' . $count . '_term'])); $tax_operator = isset($original_atts['tax_' . $count . '_operator']) ? $original_atts['tax_' . $count . '_operator'] : 'IN'; $tax_operator = in_array($tax_operator, array('IN', 'NOT IN', 'AND')) ? $tax_operator : 'IN'; $tax_args['tax_query'][] = array('taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => $terms, 'operator' => $tax_operator); $count++; } if ($more_tax_queries) { $tax_relation = 'AND'; if (isset($original_atts['tax_relation']) && in_array($original_atts['tax_relation'], array('AND', 'OR'))) { $tax_relation = $original_atts['tax_relation']; } $args['tax_query']['relation'] = $tax_relation; } $args = array_merge($args, $tax_args); } // If post parent attribute, set up parent. if ($post_parent) { if ('current' == $post_parent) { global $post; $post_parent = $post->ID; } $args['post_parent'] = intval($post_parent); } // Exclude current post/page (fix aborting). if (in_array(get_post_type(), (array) $post_type) && 'full' === $atts['content_type']) { $args['post__not_in'] = array(get_the_ID()); } /** * Filter the array of arguments for query. * * @since 1.0.0 * @param array $args Query arguments. * @param array $atts Shortcode attributes. */ $args = apply_filters('cherry_shortcode_swiper_carousel_query_args', $args, $atts); // Query posts. $posts_query = new WP_Query($args); // Prepare string for outputing. $output = ''; if ($posts_query->have_posts()) { // Item template's file. $template_file = self::get_template_path($template_name, 'swiper_carousel'); if (false == $template_file) { return '<h4>' . __('Template file (*.tmpl) not found', 'cherry-shortcodes') . '</h4>'; } ob_start(); require $template_file; $template = ob_get_contents(); ob_end_clean(); // Default macros-array. $data = array('image', 'title', 'date', 'author', 'comments', 'taxonomy', 'excerpt', 'content', 'button', 'permalink'); self::setup_template_data($data, $atts); self::$post_data = array_merge(array('tag' => 'swiper_carousel'), self::$post_data); while ($posts_query->have_posts()) { $posts_query->the_post(); // Prepare a data. $tpl = $template; $post_id = get_the_ID(); $post_type = get_post_type($post_id); // If post is set to private, only show to logged in users. if ('private' == get_post_status($post_id) && !current_user_can('read_private_posts')) { continue; } /** * Filters the array with a current post data. * * @since 1.0.0 * @param array $_postdata Array with a current post data. * @param int $post_id Post ID. * @param array $atts Shortcode attributes. */ self::$post_data = apply_filters('cherry-shortcode-swiper-carousel-postdata', self::$post_data, $post_id, $atts); // Perform a regular expression. $tpl = preg_replace_callback(self::$macros_pattern, array('self', 'replace_callback'), $tpl); // Prepare the CSS classes for item's. $item_classes = array(); $item_classes[] = 'cherry-swiper-carousel-slide'; $item_classes[] = 'swiper-slide'; $item_classes[] = 'post-item'; $item_classes[] = $post_type . '-item'; $item_classes[] = 'item-' . $posts_query->current_post; $item_classes[] = $posts_query->current_post % 2 ? 'even' : 'odd'; /** * Filters the CSS classes for item's. * * @since 1.0.0 * @param array $item_classes An array of classes. * @param array $atts Shortcode attributes. * @param int $post_id Post ID. */ $item_classes = apply_filters('cherry_shortcode_swiper_carousel_item_classes', $item_classes, $atts, $post_id); $item_classes = array_unique($item_classes); $item_classes = array_map('sanitize_html_class', $item_classes); /** * Filters the HTML-wrap with item's content. * * @since 1.0.0 * @param string $item HTML-formatted item's wrapper. * @param int $current_post Index of the post currently being displayed. * @param array $atts Shortcode attributes. * @param int $post_id Post ID. */ $item = apply_filters('cherry_shortcode_swiper_carousel_slide', '<article class="%1$s"><div class="inner clearfix">%2$s</div></article>', $posts_query->current_post, $atts, $post_id); $output .= sprintf($item, join(' ', $item_classes), $tpl); $output .= '<!--/.cherry-swiper-carousel-item-->'; } // Prepare the CSS classes for list. $wrap_classes = array(); $wrap_classes[] = 'cherry-swiper-carousel'; $wrap_classes[] = 'swiper-container'; $wrap_classes[] = Cherry_Shortcodes_Tools::get_template_class($atts['template']); if ($atts['class']) { $wrap_classes[] = esc_attr($atts['class']); } /** * Filters the CSS classes for list. * * @since 1.0.0 * @param array $wrap_classes An array of classes. * @param array $atts Shortcode attributes. */ $wrap_classes = apply_filters('cherry_shortcode_posts_list_classes', $wrap_classes, $atts); $wrap_classes = array_unique($wrap_classes); $wrap_classes = array_map('sanitize_html_class', $wrap_classes); $data_attr_line = ''; $data_attr_line .= 'data-post-per-page="' . $posts_per_page . '"'; $data_attr_line .= 'data-slides-per-view="' . $slides_per_view . '"'; $data_attr_line .= 'data-slides-per-group="' . $slides_per_group . '"'; $data_attr_line .= 'data-slides-per-column="' . $slides_per_column . '"'; $data_attr_line .= 'data-space-between-slides="' . $space_between_slides . '"'; $data_attr_line .= 'data-duration-speed="' . $swiper_duration_speed . '"'; $data_attr_line .= 'data-swiper-loop="' . $swiper_loop . '"'; $data_attr_line .= 'data-free-mode="' . $swiper_free_mode . '"'; $data_attr_line .= 'data-grab-cursor="' . $swiper_grab_cursor . '"'; $data_attr_line .= 'data-mouse-wheel="' . $swiper_mouse_wheel . '"'; $data_attr_line .= 'data-centered-slide="' . $swiper_centered_slide . '"'; $data_attr_line .= 'data-swiper-effect="' . $swiper_effect . '"'; $data_attr_line .= 'data-uniq-id="swiper-carousel-' . $instance . '"'; $swiper_navigation_position == 'outer' ? $outer_class = 'outer' : ($outer_class = ''); $swiper_pagination_html = true == $swiper_pagination ? '<div id="swiper-carousel-' . $instance . '-pagination" class="swiper-pagination"></div>' : ''; $swiper_navigation_html = true == $swiper_navigation ? '<div id="swiper-carousel-' . $instance . '-next" class="swiper-button-next ' . $outer_class . '"></div><div id="swiper-carousel-' . $instance . '-prev" class="swiper-button-prev ' . $outer_class . '"></div>' : ''; /** * Filters the HTML-wrap with list content. * * @since 1.0.0 * @param string $wrap HTML-formatted list wrapper. * @param array $atts Shortcode attributes. */ $wrap = apply_filters('cherry_shortcode_swiper_carousel_list', '<div class="cherry-swiper-carousel-container"><section id="cherry-swiper-carousel-%1$d" class="%2$s" %3$s><div class="swiper-wrapper">%4$s</div>%5$s</section>%6$s</div>', $atts); $output = sprintf($wrap, $instance, join(' ', $wrap_classes), $data_attr_line, $output, $swiper_pagination_html, $swiper_navigation_html); } else { return '<h4>' . __('Posts not found', 'cherry-shortcodes') . '</h4>'; } // Reset the query. wp_reset_postdata(); cherry_query_asset('js', array('swiper', 'cherry-shortcodes-init')); $output = apply_filters('cherry_shortcodes_output', $output, $atts, 'swiper_carousel'); return $output; }