PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.83
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / widgets / TB_Post_Meta / TB_Post_Meta.php

TB_Post_Meta.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.83, at includes/widgets/TB_Post_Meta/TB_Post_Meta.php

512 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Theme Builder Post Meta widget (Free).
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Group_Control_Typography;
12 use Elementor\Repeater;
13 use Elementor\Widget_Base;
14
15 if (!defined('ABSPATH')) {
16 exit;
17 }
18
19 /**
20 * Displays post meta items such as date, author, categories, and comments.
21 */
22 class TB_Post_Meta extends Widget_Base
23 {
24 /**
25 * Widget slug.
26 *
27 * @return string
28 */
29 public function get_name(): string
30 {
31 return 'king-addons-tb-post-meta';
32 }
33
34 /**
35 * Widget title.
36 *
37 * @return string
38 */
39 public function get_title(): string
40 {
41 return esc_html__('TB - Post Meta', 'king-addons');
42 }
43
44 /**
45 * Widget icon.
46 *
47 * @return string
48 */
49 public function get_icon(): string
50 {
51 return 'king-addons-icon king-addons-tb-post-meta';
52 }
53
54 /**
55 * Style dependencies.
56 *
57 * @return array<int, string>
58 */
59 public function get_style_depends(): array
60 {
61 return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-tb-post-meta-style'];
62 }
63
64 /**
65 * Script dependencies.
66 *
67 * @return array<int, string>
68 */
69 public function get_script_depends(): array
70 {
71 return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-tb-post-meta-script'];
72 }
73
74 /**
75 * Categories.
76 *
77 * @return array<int, string>
78 */
79 public function get_categories(): array
80 {
81 return ['king-addons-theme-builder'];
82 }
83
84 /**
85 * Keywords.
86 *
87 * @return array<int, string>
88 */
89 public function get_keywords(): array
90 {
91 return ['meta', 'author', 'date', 'categories', 'tags', 'king-addons'];
92 }
93
94 public function get_custom_help_url()
95 {
96 return 'mailto:bug@kingaddons.com?subject=Bug Report - King Addons&body=Please describe the issue';
97 }
98
99 /**
100 * Register controls.
101 *
102 * @return void
103 */
104 public function register_controls(): void
105 {
106 $this->register_content_controls(false);
107 $this->register_style_controls(false);
108 $this->register_pro_notice_controls();
109 }
110
111 /**
112 * Render widget output.
113 *
114 * @return void
115 */
116 public function render(): void
117 {
118 $settings = $this->get_settings_for_display();
119 $this->render_output($settings, false);
120 }
121
122 /**
123 * Content controls.
124 *
125 * @param bool $is_pro Whether Pro controls are enabled.
126 *
127 * @return void
128 */
129 protected function register_content_controls(bool $is_pro): void
130 {
131 $repeater = new Repeater();
132 $repeater->add_control(
133 'kng_meta_type',
134 [
135 'label' => esc_html__('Meta Item', 'king-addons'),
136 'type' => Controls_Manager::SELECT,
137 'options' => [
138 'date' => esc_html__('Date', 'king-addons'),
139 'author' => esc_html__('Author', 'king-addons'),
140 'categories' => esc_html__('Categories', 'king-addons'),
141 'tags' => esc_html__('Tags', 'king-addons'),
142 'comments' => esc_html__('Comments Count', 'king-addons'),
143 'reading_time' => $is_pro ?
144 esc_html__('Reading Time', 'king-addons') :
145 sprintf(__('Reading Time %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
146 ],
147 'default' => 'date',
148 ]
149 );
150
151 $this->start_controls_section(
152 'kng_content_section',
153 [
154 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
155 'tab' => Controls_Manager::TAB_CONTENT,
156 ]
157 );
158
159 $this->add_control(
160 'kng_layout',
161 [
162 'label' => esc_html__('Layout', 'king-addons'),
163 'type' => Controls_Manager::SELECT,
164 'default' => 'inline',
165 'options' => [
166 'inline' => esc_html__('Inline', 'king-addons'),
167 'stacked' => esc_html__('Stacked', 'king-addons'),
168 ],
169 ]
170 );
171
172 $this->add_control(
173 'kng_separator',
174 [
175 'label' => esc_html__('Separator', 'king-addons'),
176 'type' => Controls_Manager::TEXT,
177 'dynamic' => ['active' => true],
178 'default' => '',
179 'condition' => [
180 'kng_layout' => 'inline',
181 ],
182 ]
183 );
184
185 $this->add_control(
186 'kng_date_format',
187 [
188 'label' => esc_html__('Date Format', 'king-addons'),
189 'type' => Controls_Manager::SELECT,
190 'options' => [
191 'default' => esc_html__('Default', 'king-addons'),
192 'medium' => esc_html__('Medium', 'king-addons'),
193 'custom' => esc_html__('Custom', 'king-addons'),
194 ],
195 'default' => 'default',
196 ]
197 );
198
199 $this->add_control(
200 'kng_date_format_custom',
201 [
202 'label' => esc_html__('Custom Date Format', 'king-addons'),
203 'type' => Controls_Manager::TEXT,
204 'placeholder' => esc_html__('F j, Y', 'king-addons'),
205 'condition' => [
206 'kng_date_format' => 'custom',
207 ],
208 ]
209 );
210
211 $this->add_control(
212 'kng_author_link',
213 [
214 'label' => esc_html__('Link Author to Archive', 'king-addons'),
215 'type' => Controls_Manager::SWITCHER,
216 'return_value' => 'yes',
217 'default' => 'yes',
218 ]
219 );
220
221 $this->add_control(
222 'kng_terms_link',
223 [
224 'label' => esc_html__('Link Categories/Tags', 'king-addons'),
225 'type' => Controls_Manager::SWITCHER,
226 'return_value' => 'yes',
227 'default' => 'yes',
228 ]
229 );
230
231 $this->add_control(
232 'kng_meta_items',
233 [
234 'label' => esc_html__('Meta Items', 'king-addons'),
235 'type' => Controls_Manager::REPEATER,
236 'fields' => $repeater->get_controls(),
237 'title_field' => '{{ kng_meta_type }}',
238 'default' => [
239 ['kng_meta_type' => 'date'],
240 ['kng_meta_type' => 'author'],
241 ['kng_meta_type' => 'categories'],
242 ['kng_meta_type' => 'tags'],
243 ['kng_meta_type' => 'comments'],
244 ],
245 ]
246 );
247
248 $this->end_controls_section();
249 }
250
251 /**
252 * Style controls.
253 *
254 * @param bool $is_pro Whether Pro controls are enabled.
255 *
256 * @return void
257 */
258 protected function register_style_controls(bool $is_pro): void
259 {
260 $this->start_controls_section(
261 'kng_style_section',
262 [
263 'label' => esc_html__('Style', 'king-addons'),
264 'tab' => Controls_Manager::TAB_STYLE,
265 ]
266 );
267
268 $this->add_group_control(
269 Group_Control_Typography::get_type(),
270 [
271 'name' => 'kng_typography',
272 'selector' => '{{WRAPPER}} .king-addons-tb-post-meta, {{WRAPPER}} .king-addons-tb-post-meta a',
273 ]
274 );
275
276 $this->add_control(
277 'kng_text_color',
278 [
279 'label' => esc_html__('Text Color', 'king-addons'),
280 'type' => Controls_Manager::COLOR,
281 'selectors' => [
282 '{{WRAPPER}} .king-addons-tb-post-meta' => 'color: {{VALUE}};',
283 '{{WRAPPER}} .king-addons-tb-post-meta a' => 'color: {{VALUE}};',
284 ],
285 ]
286 );
287
288 $this->add_control(
289 'kng_text_color_hover',
290 [
291 'label' => esc_html__('Link Hover Color', 'king-addons'),
292 'type' => Controls_Manager::COLOR,
293 'selectors' => [
294 '{{WRAPPER}} .king-addons-tb-post-meta a:hover' => 'color: {{VALUE}};',
295 ],
296 ]
297 );
298
299 $this->add_responsive_control(
300 'kng_gap',
301 [
302 'label' => esc_html__('Gap', 'king-addons'),
303 'type' => Controls_Manager::SLIDER,
304 'size_units' => ['px'],
305 'range' => [
306 'px' => ['min' => 0, 'max' => 40],
307 ],
308 'default' => [
309 'size' => 8,
310 'unit' => 'px',
311 ],
312 'selectors' => [
313 '{{WRAPPER}} .king-addons-tb-post-meta' => '--kng-meta-gap: {{SIZE}}{{UNIT}};',
314 ],
315 ]
316 );
317
318 $this->end_controls_section();
319 }
320
321 /**
322 * Pro upsell section.
323 *
324 * @return void
325 */
326 protected function register_pro_notice_controls(): void
327 {
328 if (king_addons_freemius()->can_use_premium_code__premium_only()) {
329 return;
330 }
331
332 Core::renderProFeaturesSection(
333 $this,
334 '',
335 Controls_Manager::RAW_HTML,
336 'tb-post-meta',
337 [
338 'Reading time meta item',
339 'Icons and badge styles for taxonomies',
340 'Separate typography for labels and values',
341 ]
342 );
343 }
344
345 /**
346 * Render output helper.
347 *
348 * @param array<string, mixed> $settings Widget settings.
349 * @param bool $is_pro Whether Pro is enabled.
350 *
351 * @return void
352 */
353 protected function render_output(array $settings, bool $is_pro): void
354 {
355 $post = get_post();
356 if (!$post instanceof \WP_Post) {
357 return;
358 }
359
360 $items = $settings['kng_meta_items'] ?? [];
361 if (empty($items)) {
362 $items = [
363 ['kng_meta_type' => 'date'],
364 ['kng_meta_type' => 'author'],
365 ['kng_meta_type' => 'categories'],
366 ['kng_meta_type' => 'tags'],
367 ['kng_meta_type' => 'comments'],
368 ];
369 }
370
371 $output = [];
372 $separator = isset($settings['kng_separator']) ? (string) $settings['kng_separator'] : '';
373 $terms_link = 'yes' === ($settings['kng_terms_link'] ?? 'yes');
374 $author_link = 'yes' === ($settings['kng_author_link'] ?? 'yes');
375
376 foreach ($items as $item) {
377 $type = $item['kng_meta_type'] ?? '';
378 switch ($type) {
379 case 'date':
380 $output[] = esc_html($this->get_formatted_date($settings, $post));
381 break;
382 case 'author':
383 $author = get_the_author_meta('display_name', $post->post_author);
384 if ($author) {
385 if ($author_link) {
386 $url = get_author_posts_url($post->post_author);
387 $output[] = sprintf(
388 '<a href="%1$s">%2$s</a>',
389 esc_url($url),
390 esc_html($author)
391 );
392 } else {
393 $output[] = esc_html($author);
394 }
395 }
396 break;
397 case 'categories':
398 $cats = get_the_category($post->ID);
399 if (!empty($cats)) {
400 $cat_parts = [];
401 foreach ($cats as $cat) {
402 $name = esc_html($cat->name);
403 if ($terms_link) {
404 $cat_parts[] = '<a href="' . esc_url(get_category_link($cat)) . '">' . $name . '</a>';
405 } else {
406 $cat_parts[] = $name;
407 }
408 }
409 $output[] = implode(', ', $cat_parts);
410 }
411 break;
412 case 'tags':
413 $tags = get_the_tags($post->ID);
414 if (!empty($tags)) {
415 $tag_parts = [];
416 foreach ($tags as $tag) {
417 $name = esc_html($tag->name);
418 if ($terms_link) {
419 $tag_parts[] = '<a href="' . esc_url(get_tag_link($tag)) . '">' . $name . '</a>';
420 } else {
421 $tag_parts[] = $name;
422 }
423 }
424 $output[] = implode(', ', $tag_parts);
425 }
426 break;
427 case 'comments':
428 $count = get_comments_number($post);
429 $output[] = sprintf(
430 _n('%s comment', '%s comments', $count, 'king-addons'),
431 number_format_i18n($count)
432 );
433 break;
434 case 'reading_time':
435 if ($is_pro) {
436 $output[] = esc_html($this->calculate_reading_time($post));
437 }
438 break;
439 default:
440 break;
441 }
442 }
443
444 $output = array_filter($output);
445 if (empty($output)) {
446 return;
447 }
448
449 $layout = $settings['kng_layout'] ?? 'inline';
450 $wrapper_classes = ['king-addons-tb-post-meta', 'king-addons-tb-post-meta--' . $layout];
451
452 echo '<div class="' . esc_attr(implode(' ', $wrapper_classes)) . '">';
453
454 if ('stacked' === $layout) {
455 foreach ($output as $part) {
456 echo '<div class="king-addons-tb-post-meta__item">' . wp_kses_post($part) . '</div>';
457 }
458 } else {
459 $last_index = count($output) - 1;
460 foreach ($output as $index => $part) {
461 echo '<span class="king-addons-tb-post-meta__item">' . wp_kses_post($part) . '</span>';
462 if ($index !== $last_index) {
463 echo '<span class="king-addons-tb-post-meta__separator">' . esc_html($separator) . '</span>';
464 }
465 }
466 }
467
468 echo '</div>';
469 }
470
471 /**
472 * Get formatted date.
473 *
474 * @param array<string, mixed> $settings Settings.
475 * @param \WP_Post $post Post instance.
476 *
477 * @return string
478 */
479 protected function get_formatted_date(array $settings, \WP_Post $post): string
480 {
481 $format = $settings['kng_date_format'] ?? 'default';
482 if ('custom' === $format && !empty($settings['kng_date_format_custom'])) {
483 return get_the_date(sanitize_text_field($settings['kng_date_format_custom']), $post);
484 }
485
486 if ('medium' === $format) {
487 return get_the_date('M j, Y', $post);
488 }
489
490 return get_the_date('', $post);
491 }
492
493 /**
494 * Calculate reading time.
495 *
496 * @param \WP_Post $post Post instance.
497 *
498 * @return string
499 */
500 protected function calculate_reading_time(\WP_Post $post): string
501 {
502 $content = wp_strip_all_tags((string) $post->post_content);
503 $words = str_word_count($content);
504 $minutes = max(1, (int) ceil($words / 200));
505
506 return sprintf(
507 _n('%s min read', '%s mins read', $minutes, 'king-addons'),
508 number_format_i18n($minutes)
509 );
510 }
511 }
512