PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.78
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.78
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.78, at includes/widgets/TB_Post_Meta/TB_Post_Meta.php

511 lines 15.3 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 'eicon-meta-data';
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'];
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 'default' => '',
178 'condition' => [
179 'kng_layout' => 'inline',
180 ],
181 ]
182 );
183
184 $this->add_control(
185 'kng_date_format',
186 [
187 'label' => esc_html__('Date Format', 'king-addons'),
188 'type' => Controls_Manager::SELECT,
189 'options' => [
190 'default' => esc_html__('Default', 'king-addons'),
191 'medium' => esc_html__('Medium', 'king-addons'),
192 'custom' => esc_html__('Custom', 'king-addons'),
193 ],
194 'default' => 'default',
195 ]
196 );
197
198 $this->add_control(
199 'kng_date_format_custom',
200 [
201 'label' => esc_html__('Custom Date Format', 'king-addons'),
202 'type' => Controls_Manager::TEXT,
203 'placeholder' => esc_html__('F j, Y', 'king-addons'),
204 'condition' => [
205 'kng_date_format' => 'custom',
206 ],
207 ]
208 );
209
210 $this->add_control(
211 'kng_author_link',
212 [
213 'label' => esc_html__('Link Author to Archive', 'king-addons'),
214 'type' => Controls_Manager::SWITCHER,
215 'return_value' => 'yes',
216 'default' => 'yes',
217 ]
218 );
219
220 $this->add_control(
221 'kng_terms_link',
222 [
223 'label' => esc_html__('Link Categories/Tags', 'king-addons'),
224 'type' => Controls_Manager::SWITCHER,
225 'return_value' => 'yes',
226 'default' => 'yes',
227 ]
228 );
229
230 $this->add_control(
231 'kng_meta_items',
232 [
233 'label' => esc_html__('Meta Items', 'king-addons'),
234 'type' => Controls_Manager::REPEATER,
235 'fields' => $repeater->get_controls(),
236 'title_field' => '{{ kng_meta_type }}',
237 'default' => [
238 ['kng_meta_type' => 'date'],
239 ['kng_meta_type' => 'author'],
240 ['kng_meta_type' => 'categories'],
241 ['kng_meta_type' => 'tags'],
242 ['kng_meta_type' => 'comments'],
243 ],
244 ]
245 );
246
247 $this->end_controls_section();
248 }
249
250 /**
251 * Style controls.
252 *
253 * @param bool $is_pro Whether Pro controls are enabled.
254 *
255 * @return void
256 */
257 protected function register_style_controls(bool $is_pro): void
258 {
259 $this->start_controls_section(
260 'kng_style_section',
261 [
262 'label' => esc_html__('Style', 'king-addons'),
263 'tab' => Controls_Manager::TAB_STYLE,
264 ]
265 );
266
267 $this->add_group_control(
268 Group_Control_Typography::get_type(),
269 [
270 'name' => 'kng_typography',
271 'selector' => '{{WRAPPER}} .king-addons-tb-post-meta, {{WRAPPER}} .king-addons-tb-post-meta a',
272 ]
273 );
274
275 $this->add_control(
276 'kng_text_color',
277 [
278 'label' => esc_html__('Text Color', 'king-addons'),
279 'type' => Controls_Manager::COLOR,
280 'selectors' => [
281 '{{WRAPPER}} .king-addons-tb-post-meta' => 'color: {{VALUE}};',
282 '{{WRAPPER}} .king-addons-tb-post-meta a' => 'color: {{VALUE}};',
283 ],
284 ]
285 );
286
287 $this->add_control(
288 'kng_text_color_hover',
289 [
290 'label' => esc_html__('Link Hover Color', 'king-addons'),
291 'type' => Controls_Manager::COLOR,
292 'selectors' => [
293 '{{WRAPPER}} .king-addons-tb-post-meta a:hover' => 'color: {{VALUE}};',
294 ],
295 ]
296 );
297
298 $this->add_responsive_control(
299 'kng_gap',
300 [
301 'label' => esc_html__('Gap', 'king-addons'),
302 'type' => Controls_Manager::SLIDER,
303 'size_units' => ['px'],
304 'range' => [
305 'px' => ['min' => 0, 'max' => 40],
306 ],
307 'default' => [
308 'size' => 8,
309 'unit' => 'px',
310 ],
311 'selectors' => [
312 '{{WRAPPER}} .king-addons-tb-post-meta' => '--kng-meta-gap: {{SIZE}}{{UNIT}};',
313 ],
314 ]
315 );
316
317 $this->end_controls_section();
318 }
319
320 /**
321 * Pro upsell section.
322 *
323 * @return void
324 */
325 protected function register_pro_notice_controls(): void
326 {
327 if (king_addons_freemius()->can_use_premium_code__premium_only()) {
328 return;
329 }
330
331 Core::renderProFeaturesSection(
332 $this,
333 '',
334 Controls_Manager::RAW_HTML,
335 'tb-post-meta',
336 [
337 'Reading time meta item',
338 'Icons and badge styles for taxonomies',
339 'Separate typography for labels and values',
340 ]
341 );
342 }
343
344 /**
345 * Render output helper.
346 *
347 * @param array<string, mixed> $settings Widget settings.
348 * @param bool $is_pro Whether Pro is enabled.
349 *
350 * @return void
351 */
352 protected function render_output(array $settings, bool $is_pro): void
353 {
354 $post = get_post();
355 if (!$post instanceof \WP_Post) {
356 return;
357 }
358
359 $items = $settings['kng_meta_items'] ?? [];
360 if (empty($items)) {
361 $items = [
362 ['kng_meta_type' => 'date'],
363 ['kng_meta_type' => 'author'],
364 ['kng_meta_type' => 'categories'],
365 ['kng_meta_type' => 'tags'],
366 ['kng_meta_type' => 'comments'],
367 ];
368 }
369
370 $output = [];
371 $separator = isset($settings['kng_separator']) ? (string) $settings['kng_separator'] : '';
372 $terms_link = 'yes' === ($settings['kng_terms_link'] ?? 'yes');
373 $author_link = 'yes' === ($settings['kng_author_link'] ?? 'yes');
374
375 foreach ($items as $item) {
376 $type = $item['kng_meta_type'] ?? '';
377 switch ($type) {
378 case 'date':
379 $output[] = esc_html($this->get_formatted_date($settings, $post));
380 break;
381 case 'author':
382 $author = get_the_author_meta('display_name', $post->post_author);
383 if ($author) {
384 if ($author_link) {
385 $url = get_author_posts_url($post->post_author);
386 $output[] = sprintf(
387 '<a href="%1$s">%2$s</a>',
388 esc_url($url),
389 esc_html($author)
390 );
391 } else {
392 $output[] = esc_html($author);
393 }
394 }
395 break;
396 case 'categories':
397 $cats = get_the_category($post->ID);
398 if (!empty($cats)) {
399 $cat_parts = [];
400 foreach ($cats as $cat) {
401 $name = esc_html($cat->name);
402 if ($terms_link) {
403 $cat_parts[] = '<a href="' . esc_url(get_category_link($cat)) . '">' . $name . '</a>';
404 } else {
405 $cat_parts[] = $name;
406 }
407 }
408 $output[] = implode(', ', $cat_parts);
409 }
410 break;
411 case 'tags':
412 $tags = get_the_tags($post->ID);
413 if (!empty($tags)) {
414 $tag_parts = [];
415 foreach ($tags as $tag) {
416 $name = esc_html($tag->name);
417 if ($terms_link) {
418 $tag_parts[] = '<a href="' . esc_url(get_tag_link($tag)) . '">' . $name . '</a>';
419 } else {
420 $tag_parts[] = $name;
421 }
422 }
423 $output[] = implode(', ', $tag_parts);
424 }
425 break;
426 case 'comments':
427 $count = get_comments_number($post);
428 $output[] = sprintf(
429 _n('%s comment', '%s comments', $count, 'king-addons'),
430 number_format_i18n($count)
431 );
432 break;
433 case 'reading_time':
434 if ($is_pro) {
435 $output[] = esc_html($this->calculate_reading_time($post));
436 }
437 break;
438 default:
439 break;
440 }
441 }
442
443 $output = array_filter($output);
444 if (empty($output)) {
445 return;
446 }
447
448 $layout = $settings['kng_layout'] ?? 'inline';
449 $wrapper_classes = ['king-addons-tb-post-meta', 'king-addons-tb-post-meta--' . $layout];
450
451 echo '<div class="' . esc_attr(implode(' ', $wrapper_classes)) . '">';
452
453 if ('stacked' === $layout) {
454 foreach ($output as $part) {
455 echo '<div class="king-addons-tb-post-meta__item">' . wp_kses_post($part) . '</div>';
456 }
457 } else {
458 $last_index = count($output) - 1;
459 foreach ($output as $index => $part) {
460 echo '<span class="king-addons-tb-post-meta__item">' . wp_kses_post($part) . '</span>';
461 if ($index !== $last_index) {
462 echo '<span class="king-addons-tb-post-meta__separator">' . esc_html($separator) . '</span>';
463 }
464 }
465 }
466
467 echo '</div>';
468 }
469
470 /**
471 * Get formatted date.
472 *
473 * @param array<string, mixed> $settings Settings.
474 * @param \WP_Post $post Post instance.
475 *
476 * @return string
477 */
478 protected function get_formatted_date(array $settings, \WP_Post $post): string
479 {
480 $format = $settings['kng_date_format'] ?? 'default';
481 if ('custom' === $format && !empty($settings['kng_date_format_custom'])) {
482 return get_the_date(sanitize_text_field($settings['kng_date_format_custom']), $post);
483 }
484
485 if ('medium' === $format) {
486 return get_the_date('M j, Y', $post);
487 }
488
489 return get_the_date('', $post);
490 }
491
492 /**
493 * Calculate reading time.
494 *
495 * @param \WP_Post $post Post instance.
496 *
497 * @return string
498 */
499 protected function calculate_reading_time(\WP_Post $post): string
500 {
501 $content = wp_strip_all_tags((string) $post->post_content);
502 $words = str_word_count($content);
503 $minutes = max(1, (int) ceil($words / 200));
504
505 return sprintf(
506 _n('%s min read', '%s mins read', $minutes, 'king-addons'),
507 number_format_i18n($minutes)
508 );
509 }
510 }
511