PluginProbe
Easy Elements for Elementor – Addons & Website Templates / 1.5.0
Easy Elements for Elementor – Addons & Website Templates v1.5.0
1.5.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.6 1.4.7 1.4.8 1.4.5 1.4.4 1.4.3 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 All 47 releases
easy-elements / widgets / copyright / copyright.php

copyright.php in Easy Elements for Elementor – Addons & Website Templates 1.5.0, at widgets/copyright/copyright.php

498 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright Widget for Easy Elements.
4 *
5 * Displays a copyright notice with an auto-updating year, optional year range,
6 * site name placeholder support, and an optional link.
7 *
8 * @package Easyel\EasyElements\Widgets
9 * @since 1.0.0
10 */
11
12 namespace Easyel\EasyElements\Widgets;
13
14 use Elementor\Controls_Manager;
15 use Elementor\Group_Control_Typography;
16 use Elementor\Group_Control_Text_Shadow;
17 use Elementor\Widget_Base;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit; // Exit if accessed directly.
21 }
22
23 /**
24 * Class Easyel_Copyright_Widget
25 *
26 * Renders a footer-friendly copyright string with placeholders.
27 */
28 class Easyel_Copyright_Widget extends Widget_Base {
29
30 /**
31 * Get widget name.
32 *
33 * @return string
34 */
35 public function get_name() {
36 return 'eel-copyright';
37 }
38
39 /**
40 * Get widget title.
41 *
42 * @return string
43 */
44 public function get_title() {
45 return esc_html__( 'Copyright', 'easy-elements' );
46 }
47
48 /**
49 * Get widget icon.
50 *
51 * @return string
52 */
53 public function get_icon() {
54 return 'easyicon easyelIcon-copyright';
55 }
56
57 /**
58 * Get widget categories.
59 *
60 * @return array
61 */
62 public function get_categories() {
63 return array( 'easyelements_category' );
64 }
65
66 /**
67 * Get widget keywords (for search inside Elementor panel).
68 *
69 * @return array
70 */
71 public function get_keywords() {
72 return array( 'copyright', 'footer', 'year', 'company', 'rights', 'reserved' );
73 }
74
75 /**
76 * Style assets the widget depends on.
77 *
78 * @return array
79 */
80 public function get_style_depends() {
81 return array( 'eel-copyright' );
82 }
83
84 /**
85 * Register Elementor controls.
86 *
87 * @return void
88 */
89 protected function register_controls() {
90
91 /* ---------- Content Tab ---------- */
92 $this->start_controls_section(
93 'content_section',
94 array(
95 'label' => esc_html__( 'Copyright Settings', 'easy-elements' ),
96 'tab' => Controls_Manager::TAB_CONTENT,
97 )
98 );
99
100 $this->add_control(
101 'copyright_text',
102 array(
103 'label' => esc_html__( 'Copyright Text', 'easy-elements' ),
104 'type' => Controls_Manager::TEXTAREA,
105 'rows' => 3,
106 'label_block' => true,
107 'default' => __( '&copy; {year} {site_title}. All Rights Reserved.', 'easy-elements' ),
108 'description' => esc_html__( 'Available placeholders: {year} {site_title} {site_url}', 'easy-elements' ),
109 'dynamic' => array(
110 'active' => true,
111 ),
112 )
113 );
114
115 $this->add_control(
116 'year_format',
117 array(
118 'label' => esc_html__( 'Year Format', 'easy-elements' ),
119 'type' => Controls_Manager::SELECT,
120 'default' => 'current',
121 'options' => array(
122 'current' => esc_html__( 'Current Year (e.g. 2026)', 'easy-elements' ),
123 'range' => esc_html__( 'Year Range (e.g. 2020 - 2026)', 'easy-elements' ),
124 ),
125 'description' => esc_html__( 'Choose how the {year} placeholder is replaced.', 'easy-elements' ),
126 )
127 );
128
129 $this->add_control(
130 'start_year',
131 array(
132 'label' => esc_html__( 'Start Year', 'easy-elements' ),
133 'type' => Controls_Manager::NUMBER,
134 'min' => 1900,
135 'max' => (int) gmdate( 'Y' ),
136 'step' => 1,
137 'default' => (int) gmdate( 'Y' ),
138 'placeholder' => '2020',
139 'condition' => array(
140 'year_format' => 'range',
141 ),
142 )
143 );
144
145 $this->add_control(
146 'year_separator',
147 array(
148 'label' => esc_html__( 'Year Separator', 'easy-elements' ),
149 'type' => Controls_Manager::TEXT,
150 'default' => ' - ',
151 'placeholder' => ' - ',
152 'condition' => array(
153 'year_format' => 'range',
154 ),
155 )
156 );
157
158 $this->add_control(
159 'enable_link',
160 array(
161 'label' => esc_html__( 'Link Site Name', 'easy-elements' ),
162 'type' => Controls_Manager::SWITCHER,
163 'label_on' => esc_html__( 'Yes', 'easy-elements' ),
164 'label_off' => esc_html__( 'No', 'easy-elements' ),
165 'default' => '',
166 'description' => esc_html__( 'Wrap the {site_title} placeholder with a link.', 'easy-elements' ),
167 'return_value' => 'yes',
168 )
169 );
170
171 $this->add_control(
172 'link_url',
173 array(
174 'label' => esc_html__( 'Custom Link', 'easy-elements' ),
175 'type' => Controls_Manager::URL,
176 'placeholder' => esc_html__( 'Leave empty to use Site URL', 'easy-elements' ),
177 'default' => array(
178 'url' => '',
179 'is_external' => false,
180 'nofollow' => false,
181 ),
182 'condition' => array(
183 'enable_link' => 'yes',
184 ),
185 'dynamic' => array(
186 'active' => true,
187 ),
188 )
189 );
190
191 $this->add_responsive_control(
192 'text_align',
193 array(
194 'label' => esc_html__( 'Alignment', 'easy-elements' ),
195 'type' => Controls_Manager::CHOOSE,
196 'options' => array(
197 'left' => array(
198 'title' => esc_html__( 'Left', 'easy-elements' ),
199 'icon' => 'eicon-text-align-left',
200 ),
201 'center' => array(
202 'title' => esc_html__( 'Center', 'easy-elements' ),
203 'icon' => 'eicon-text-align-center',
204 ),
205 'right' => array(
206 'title' => esc_html__( 'Right', 'easy-elements' ),
207 'icon' => 'eicon-text-align-right',
208 ),
209 ),
210 'default' => 'center',
211 'toggle' => true,
212 'selectors' => array(
213 '{{WRAPPER}} .eel-copyright' => 'text-align: {{VALUE}};',
214 ),
215 )
216 );
217
218 $this->add_control(
219 'html_tag',
220 array(
221 'label' => esc_html__( 'HTML Tag', 'easy-elements' ),
222 'type' => Controls_Manager::SELECT,
223 'default' => 'p',
224 'options' => array(
225 'p' => 'P',
226 'div' => 'DIV',
227 'span' => 'SPAN',
228 'h1' => 'H1',
229 'h2' => 'H2',
230 'h3' => 'H3',
231 'h4' => 'H4',
232 'h5' => 'H5',
233 'h6' => 'H6',
234 ),
235 )
236 );
237
238 $this->end_controls_section();
239
240 /* ---------- Style Tab ---------- */
241 $this->start_controls_section(
242 'style_section',
243 array(
244 'label' => esc_html__( 'Copyright Style', 'easy-elements' ),
245 'tab' => Controls_Manager::TAB_STYLE,
246 )
247 );
248
249 $this->add_control(
250 'text_color',
251 array(
252 'label' => esc_html__( 'Text Color', 'easy-elements' ),
253 'type' => Controls_Manager::COLOR,
254 'default' => '',
255 'selectors' => array(
256 '{{WRAPPER}} .eel-copyright' => 'color: {{VALUE}};',
257 ),
258 )
259 );
260
261 $this->add_group_control(
262 Group_Control_Typography::get_type(),
263 array(
264 'name' => 'typography',
265 'selector' => '{{WRAPPER}} .eel-copyright',
266 )
267 );
268
269 $this->add_control(
270 'link_heading',
271 array(
272 'label' => esc_html__( 'Link', 'easy-elements' ),
273 'type' => Controls_Manager::HEADING,
274 'separator' => 'before',
275 'condition' => array(
276 'enable_link' => 'yes',
277 ),
278 )
279 );
280
281 $this->start_controls_tabs(
282 'link_color_tabs',
283 array(
284 'condition' => array(
285 'enable_link' => 'yes',
286 ),
287 )
288 );
289
290 $this->start_controls_tab(
291 'link_normal_tab',
292 array(
293 'label' => esc_html__( 'Normal', 'easy-elements' ),
294 'condition' => array(
295 'enable_link' => 'yes',
296 ),
297 )
298 );
299
300 $this->add_control(
301 'link_color',
302 array(
303 'label' => esc_html__( 'Link Color', 'easy-elements' ),
304 'type' => Controls_Manager::COLOR,
305 'selectors' => array(
306 '{{WRAPPER}} .eel-copyright a' => 'color: {{VALUE}};',
307 ),
308 )
309 );
310
311 $this->end_controls_tab();
312
313 $this->start_controls_tab(
314 'link_hover_tab',
315 array(
316 'label' => esc_html__( 'Hover', 'easy-elements' ),
317 'condition' => array(
318 'enable_link' => 'yes',
319 ),
320 )
321 );
322
323 $this->add_control(
324 'link_hover_color',
325 array(
326 'label' => esc_html__( 'Link Hover Color', 'easy-elements' ),
327 'type' => Controls_Manager::COLOR,
328 'selectors' => array(
329 '{{WRAPPER}} .eel-copyright a:hover' => 'color: {{VALUE}};',
330 ),
331 )
332 );
333
334 $this->end_controls_tab();
335 $this->end_controls_tabs();
336
337 $this->add_group_control(
338 Group_Control_Text_Shadow::get_type(),
339 array(
340 'name' => 'text_shadow',
341 'label' => esc_html__( 'Text Shadow', 'easy-elements' ),
342 'selector' => '{{WRAPPER}} .eel-copyright',
343 'separator' => 'before',
344 )
345 );
346
347 $this->add_responsive_control(
348 'padding',
349 array(
350 'label' => esc_html__( 'Padding', 'easy-elements' ),
351 'type' => Controls_Manager::DIMENSIONS,
352 'size_units' => array( 'px', 'em', '%' ),
353 'selectors' => array(
354 '{{WRAPPER}} .eel-copyright' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
355 ),
356 'separator' => 'before',
357 )
358 );
359
360 $this->add_responsive_control(
361 'margin',
362 array(
363 'label' => esc_html__( 'Margin', 'easy-elements' ),
364 'type' => Controls_Manager::DIMENSIONS,
365 'size_units' => array( 'px', 'em', '%' ),
366 'selectors' => array(
367 '{{WRAPPER}} .eel-copyright' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
368 ),
369 )
370 );
371
372 $this->end_controls_section();
373 }
374
375 /**
376 * Build the year string based on settings.
377 *
378 * Uses date_i18n() so the year flips at midnight in the site's
379 * configured timezone, not UTC.
380 *
381 * @param array $settings Widget settings.
382 * @return string
383 */
384 private function get_year_string( $settings ) {
385 $current_year = (int) date_i18n( 'Y' );
386 $format = isset( $settings['year_format'] ) ? $settings['year_format'] : 'current';
387
388 if ( 'range' === $format ) {
389 $start_year = isset( $settings['start_year'] ) ? absint( $settings['start_year'] ) : $current_year;
390 $separator = isset( $settings['year_separator'] ) && '' !== $settings['year_separator']
391 ? sanitize_text_field( $settings['year_separator'] )
392 : ' - ';
393
394 if ( $start_year > 0 && $start_year < $current_year ) {
395 return $start_year . $separator . $current_year;
396 }
397 }
398
399 return (string) $current_year;
400 }
401
402 /**
403 * Resolve the link URL — falls back to home_url() when none provided.
404 *
405 * @param array $settings Widget settings.
406 * @return string
407 */
408 private function get_link_url( $settings ) {
409 $url = isset( $settings['link_url']['url'] ) ? trim( (string) $settings['link_url']['url'] ) : '';
410 if ( '' === $url ) {
411 $url = home_url( '/' );
412 }
413 return $url;
414 }
415
416 /**
417 * Render widget output on the frontend.
418 *
419 * @return void
420 */
421 protected function render() {
422 $settings = $this->get_settings_for_display();
423
424 $raw_text = isset( $settings['copyright_text'] ) ? $settings['copyright_text'] : '';
425 $year_str = $this->get_year_string( $settings );
426 $site_title = get_bloginfo( 'name' );
427 $site_url = home_url( '/' );
428
429 // Build site title — optionally wrapped in a link.
430 $site_title_html = esc_html( $site_title );
431
432 if ( ! empty( $settings['enable_link'] ) && 'yes' === $settings['enable_link'] ) {
433 $href = esc_url( $this->get_link_url( $settings ) );
434 $is_external = ! empty( $settings['link_url']['is_external'] );
435 $nofollow = ! empty( $settings['link_url']['nofollow'] );
436
437 $rel_parts = array();
438 if ( $is_external ) {
439 $rel_parts[] = 'noopener';
440 $rel_parts[] = 'noreferrer';
441 }
442 if ( $nofollow ) {
443 $rel_parts[] = 'nofollow';
444 }
445
446 $target = $is_external ? '_blank' : '_self';
447 $rel_str = ! empty( $rel_parts ) ? ' rel="' . esc_attr( implode( ' ', $rel_parts ) ) . '"' : '';
448
449 $site_title_html = sprintf(
450 '<a href="%1$s" target="%2$s"%3$s>%4$s</a>',
451 $href,
452 esc_attr( $target ),
453 $rel_str,
454 esc_html( $site_title )
455 );
456 }
457
458 // Allow a small subset of safe inline HTML inside the user-supplied text.
459 $allowed_html = array(
460 'a' => array(
461 'href' => true,
462 'target' => true,
463 'rel' => true,
464 'title' => true,
465 ),
466 'br' => array(),
467 'span' => array( 'class' => true ),
468 'strong' => array(),
469 'em' => array(),
470 'b' => array(),
471 'i' => array(),
472 );
473
474 $safe_text = wp_kses( (string) $raw_text, $allowed_html );
475
476 // Replace placeholders AFTER kses so the generated link tag is preserved.
477 $replacements = array(
478 '{year}' => esc_html( $year_str ),
479 '{site_title}' => $site_title_html,
480 '{site_url}' => esc_url( $site_url ),
481 );
482
483 $output = strtr( $safe_text, $replacements );
484
485 // Whitelist HTML tag.
486 $allowed_tags = array( 'p', 'div', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' );
487 $tag = isset( $settings['html_tag'] ) && in_array( $settings['html_tag'], $allowed_tags, true )
488 ? $settings['html_tag']
489 : 'p';
490
491 printf(
492 '<%1$s class="eel-copyright">%2$s</%1$s>',
493 esc_attr( $tag ),
494 wp_kses( $output, $allowed_html ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
495 );
496 }
497 }
498