| @@ -49,12 +49,19 @@ | ||
| 49 | 49 | public function get_styles() |
| 50 | 50 | { |
| 51 | 51 | $styles = [ |
| 52 | 52 | 'advanced-post-grid', |
| 53 | + 'legacy-grid', | |
| 54 | + 'post-meta', | |
| 55 | + 'filters' => [ | |
| 56 | + 'condition' => [ | |
| 57 | + 'post_filtering' => 'yes', | |
| 58 | + ], | |
| 59 | + ], | |
| 53 | 60 | 'animation', // hover animations |
| 54 | 61 | 'entrance', // entrance basic style |
| 55 | 62 | ]; |
| 56 | - if(!class_exists('\UiCore\Core') && !class_exists('\UiCoreAnimate\Base')){ | |
| 63 | + if (!class_exists('\UiCore\Core') && !class_exists('\UiCoreAnimate\Base')) { | |
| 57 | 64 | $styles['e-animations'] = [ // entrance animations |
| 58 | 65 | 'external' => true, |
| 59 | 66 | ]; |
| 60 | 67 | } |
| @@ -59,12 +66,38 @@ | ||
| 59 | 66 | ]; |
| 60 | 67 | } |
| 61 | 68 | return $styles; |
| 62 | 69 | } |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Adds `woocommerce` classname so rating can inherit woo styles and | |
| 73 | + * also follow theme option styles instead of plain text. | |
| 74 | + */ | |
| 75 | + protected function add_render_attributes() | |
| 76 | + { | |
| 77 | + parent::add_render_attributes(); | |
| 78 | + | |
| 79 | + if (class_exists('WooCommerce') && \is_woocommerce()) { | |
| 80 | + return; | |
| 81 | + } | |
| 82 | + | |
| 83 | + $this->add_render_attribute( | |
| 84 | + '_wrapper', | |
| 85 | + 'class', | |
| 86 | + [ | |
| 87 | + 'woocommerce', | |
| 88 | + $this->get_html_wrapper_class(), | |
| 89 | + ] | |
| 90 | + ); | |
| 91 | + } | |
| 63 | 92 | public function get_scripts() |
| 64 | 93 | { |
| 65 | 94 | return [ |
| 66 | - 'advanced-post-grid', | |
| 95 | + 'masonry' => [ | |
| 96 | + 'condition' => [ | |
| 97 | + 'masonry' => 'ui-e-maso' | |
| 98 | + ], | |
| 99 | + ], | |
| 67 | 100 | 'entrance' => [ |
| 68 | 101 | 'condition' => [ |
| 69 | 102 | 'animate_items' => 'ui-e-grid-animate' |
| 70 | 103 | ], |
| @@ -75,16 +108,26 @@ | ||
| 75 | 108 | ] |
| 76 | 109 | ] |
| 77 | 110 | ]; |
| 78 | 111 | } |
| 112 | + public function has_widget_inner_wrapper(): bool | |
| 113 | + { | |
| 114 | + // TODO: remove after Optmized Markup experiment is merged to the core | |
| 115 | + return ! \Elementor\Plugin::$instance->experiments->is_feature_active('e_optimized_markup'); | |
| 116 | + } | |
| 79 | 117 | |
| 80 | 118 | private function filter_missing_taxonomies($settings) |
| 81 | 119 | { |
| 120 | + // Check if is an "Advanced Product.." widget, since this widget is extended by other(s) | |
| 121 | + $slug = strpos($this->get_name(), 'product') !== false ? | |
| 122 | + 'product-filter_post_type' : | |
| 123 | + 'posts-filter_post_type'; | |
| 124 | + | |
| 82 | 125 | $taxonomy_filter_args = [ |
| 83 | 126 | 'show_in_nav_menus' => true, |
| 84 | 127 | ]; |
| 85 | - if (!empty($settings['posts-filter_post_type'])) { | |
| 86 | - $taxonomy_filter_args['object_type'] = [$settings['posts-filter_post_type']]; | |
| 128 | + if (!empty($settings[$slug])) { | |
| 129 | + $taxonomy_filter_args['object_type'] = [$settings[$slug]]; | |
| 87 | 130 | } |
| 88 | 131 | |
| 89 | 132 | $taxonomies = get_taxonomies($taxonomy_filter_args, 'objects'); |
| 90 | 133 | |
| @@ -89,10 +132,10 @@ | ||
| 89 | 132 | $taxonomies = get_taxonomies($taxonomy_filter_args, 'objects'); |
| 90 | 133 | |
| 91 | 134 | foreach ($taxonomies as $taxonomy => $object) { |
| 92 | 135 | $controll_id = 'posts-filter_' . $taxonomy . '_ids'; |
| 93 | - \error_log($controll_id); | |
| 94 | - \error_log(print_r($settings[$controll_id], true)); | |
| 136 | + //error_log($controll_id); | |
| 137 | + //error_log(print_r($settings[$controll_id], true)); | |
| 95 | 138 | |
| 96 | 139 | if (!isset($settings[$controll_id]) || empty($settings[$controll_id])) { |
| 97 | 140 | continue; |
| 98 | 141 | } |
| @@ -132,15 +175,15 @@ | ||
| 132 | 175 | [ |
| 133 | 176 | 'label' => esc_html__('Grid', 'uicore-elements'), |
| 134 | 177 | ] |
| 135 | 178 | ); |
| 136 | - $this->TRAIT_register_grid_layout_controls(); | |
| 179 | + $this->TRAIT_register_grid_layout_controls(); | |
| 137 | 180 | $this->end_controls_section(); |
| 138 | 181 | |
| 139 | 182 | $this->TRAIT_register_post_item_controls(); |
| 140 | 183 | $this->TRAIT_register_post_button_controls(); |
| 141 | 184 | $this->TRAIT_register_post_meta_controls(); |
| 142 | - $this->TRAIT_register_post_query_controls(); | |
| 185 | + $this->TRAIT_register_post_query_controls(true, $this->get_name()); | |
| 143 | 186 | $this->TRAIT_register_filter_controls(); |
| 144 | 187 | $this->TRAIT_register_pagination_controls(); |
| 145 | 188 | |
| 146 | 189 | // Styles |
| @@ -157,25 +200,26 @@ | ||
| 157 | 200 | 'label' => __('Animations', 'uicore-elements'), |
| 158 | 201 | 'tab' => Controls_Manager::TAB_STYLE, |
| 159 | 202 | ] |
| 160 | 203 | ); |
| 161 | - $this->TRAIT_register_entrance_animations_controls(); | |
| 162 | - $this->TRAIT_register_hover_animation_control( | |
| 163 | - 'Item Hover Animation', | |
| 164 | - [], | |
| 165 | - ['underline'], | |
| 166 | - 'anim_item' | |
| 167 | - ); | |
| 168 | - $this->TRAIT_register_post_animation_controls(); | |
| 204 | + $this->TRAIT_register_entrance_animations_controls(); | |
| 205 | + $this->TRAIT_register_hover_animation_control( | |
| 206 | + 'Item Hover Animation', | |
| 207 | + [], | |
| 208 | + ['underline'], | |
| 209 | + 'anim_item' | |
| 210 | + ); | |
| 211 | + $this->TRAIT_register_post_animation_controls(); | |
| 169 | 212 | $this->end_controls_section(); |
| 170 | 213 | |
| 171 | 214 | // Update masonry from component to a legacy version |
| 172 | 215 | $this->update_control('masonry', [ |
| 173 | - 'label' => __( 'Masonry', 'uicore-elements' ), | |
| 216 | + 'label' => __('Masonry', 'uicore-elements'), | |
| 174 | 217 | 'type' => Controls_Manager::SWITCHER, |
| 175 | 218 | 'frontend_available' => true, |
| 176 | 219 | 'default' => 'no', |
| 177 | 220 | 'return_value' => 'ui-e-maso', |
| 221 | + 'render_type' => 'template', | |
| 178 | 222 | // reset values from component |
| 179 | 223 | 'prefix_class' => '', |
| 180 | 224 | 'condition' => [], |
| 181 | 225 | 'selectors' => [], |
| @@ -181,52 +225,59 @@ | ||
| 181 | 225 | 'selectors' => [], |
| 182 | 226 | ]); |
| 183 | 227 | } |
| 184 | 228 | |
| 185 | - function content_template() | |
| 186 | - { | |
| 187 | - } | |
| 229 | + function content_template() {} | |
| 188 | 230 | |
| 189 | 231 | /** |
| 190 | 232 | * Renders the widget content using AJAX. |
| 191 | 233 | * |
| 192 | - * This method retrieves the query arguments and widget settings, sets up the query, and renders each post item. | |
| 234 | + * This method retrieves the widget settings; set up the query, and renders each post item. | |
| 193 | 235 | * If no posts are found, it returns false. After rendering, it resets the query and returns the output. |
| 194 | 236 | * |
| 237 | + * @param array|false $current_query The current query args, or false if the widget isn't set to use the current query. | |
| 238 | + * @param int $pageID The ID of the page where the widget is located. | |
| 239 | + * | |
| 195 | 240 | * @return string|false The rendered widget content or false if no posts are found. |
| 196 | 241 | */ |
| 197 | - public function render_ajax() | |
| 242 | + public function render_ajax($current_query) | |
| 198 | 243 | { |
| 199 | - // Get query args and widget settings | |
| 200 | - global $wp_query; | |
| 201 | - $default_query = $wp_query; | |
| 244 | + // Get settings and post type | |
| 202 | 245 | $settings = $this->get_settings(); |
| 203 | - $this->TRAIT_query_posts($settings); | |
| 246 | + $loop = 0; | |
| 247 | + | |
| 248 | + $this->TRAIT_query_posts($settings, $current_query); | |
| 204 | 249 | $wp_query = $this->get_query(); |
| 205 | 250 | |
| 206 | - //return false if no post found | |
| 207 | - if (!$wp_query->have_posts()) { | |
| 208 | - return false; | |
| 251 | + if (!$wp_query || !$wp_query->have_posts()) { | |
| 252 | + $markup = ''; | |
| 209 | 253 | } |
| 210 | 254 | |
| 211 | 255 | \ob_start(); |
| 212 | 256 | while ($wp_query->have_posts()) { |
| 213 | 257 | $wp_query->the_post(); |
| 214 | - $this->TRAIT_render_item(false, true); | |
| 258 | + $this->TRAIT_render_item($loop, false, true); | |
| 259 | + $loop++; | |
| 215 | 260 | } |
| 216 | - wp_reset_query(); | |
| 217 | - $wp_query = $default_query; | |
| 218 | - return \ob_get_clean(); | |
| 261 | + $markup = \ob_get_clean(); | |
| 262 | + | |
| 263 | + return [ | |
| 264 | + 'markup' => $markup, | |
| 265 | + ]; | |
| 219 | 266 | } |
| 220 | 267 | |
| 221 | 268 | protected function render() |
| 222 | 269 | { |
| 270 | + // Get current post ID | |
| 271 | + $post_id = get_the_ID(); | |
| 223 | 272 | |
| 224 | - // Get query args and widget settings | |
| 225 | - global $wp_query; | |
| 273 | + // Get query args, settings and post type slug | |
| 274 | + global $wp_query; | |
| 226 | 275 | $default_query = $wp_query; |
| 227 | 276 | $settings = $this->get_settings(); |
| 228 | - $this->TRAIT_query_posts($settings); | |
| 277 | + | |
| 278 | + // Build query | |
| 279 | + $this->TRAIT_query_posts($settings, $wp_query->query); | |
| 229 | 280 | $wp_query = $this->get_query(); |
| 230 | 281 | |
| 231 | 282 | // Store widget settings in a transient |
| 232 | 283 | $ID = strval($this->get_ID()); |
| @@ -235,33 +286,57 @@ | ||
| 235 | 286 | // Get the quantity of items and creates a loop control |
| 236 | 287 | $items = $settings['item_limit']['size']; |
| 237 | 288 | $loops = 0; |
| 238 | 289 | |
| 239 | - $this->TRAIT_render_filters(); | |
| 290 | + // Set masonry class | |
| 291 | + $masonry = $this->is_option('masonry', 'yes') | |
| 292 | + ? 'ui-e-maso' | |
| 293 | + : ''; | |
| 240 | 294 | |
| 295 | + $this->TRAIT_render_filters($settings); | |
| 296 | + | |
| 241 | 297 | // No posts found |
| 242 | 298 | if (!$wp_query->have_posts()) { |
| 243 | - echo '<p style="text-align:center">' . __('No posts found.', 'uicore-elements') . '</p>'; | |
| 299 | + echo '<p style="text-align:center">' . esc_html__('No posts found.', 'uicore-elements') . '</p>'; | |
| 244 | 300 | } else { |
| 245 | 301 | |
| 246 | - ?> | |
| 247 | - <div class="ui-e-adv-grid"> | |
| 302 | +?> | |
| 303 | + <div class="ui-e-adv-grid <?php echo esc_attr($masonry); ?>"> | |
| 248 | 304 | <?php |
| 249 | 305 | while ($wp_query->have_posts()) { |
| 250 | 306 | |
| 307 | + // sticky posts disregards posts per page, so ending the loop if $items == $loop forces the query respects the users item limit | |
| 251 | 308 | if ($settings['sticky'] && $items == $loops) { |
| 252 | - break; // sticky posts disregards posts per page, so ending the loop if $items == $loop forces the query respects the users item limit | |
| 309 | + break; | |
| 253 | 310 | } |
| 254 | 311 | |
| 255 | 312 | $wp_query->the_post(); |
| 256 | - $this->TRAIT_render_item(false, true); | |
| 313 | + $this->TRAIT_render_item($loops, false, true); | |
| 257 | 314 | |
| 258 | 315 | $loops++; |
| 259 | 316 | } |
| 260 | 317 | ?> |
| 261 | 318 | </div> |
| 262 | - <?php | |
| 263 | - $this->TRAIT_render_pagination(); | |
| 319 | +<?php | |
| 320 | + | |
| 321 | + $this->TRAIT_render_pagination($settings, $post_id); | |
| 322 | + | |
| 323 | + if ( | |
| 324 | + $this->is_option('pagination', 'yes') && | |
| 325 | + $this->is_option('pagination_type', 'load_more') && | |
| 326 | + $this->is_option('posts-filter_post_type', 'current') | |
| 327 | + ) { | |
| 328 | + | |
| 329 | + // Build the public query args the ajax request script passes to rest api | |
| 330 | + $public_query = array(); | |
| 331 | + $public_query['query']['post_type'] = get_post_type(); | |
| 332 | + $public_query['query_vars'] = $wp_query->query_vars; | |
| 333 | + | |
| 334 | + echo '<script>'; | |
| 335 | + echo 'window.ui_total_pages_' . esc_html($ID) . ' = "none";'; // add none to avoid ajax errors for lack of value, but posts don't need it | |
| 336 | + echo 'window.ui_query_' . esc_html($ID) . ' = ' . \json_encode($public_query) . ';'; | |
| 337 | + echo '</script>'; | |
| 338 | + } | |
| 264 | 339 | } |
| 265 | 340 | |
| 266 | 341 | //reset query |
| 267 | 342 | wp_reset_query(); |