HEX
Server: nginx/1.24.0
System: Linux DGT-WORDPRESS-VM-SERVER 6.14.0-1017-azure #17~24.04.1-Ubuntu SMP Mon Dec 1 20:10:50 UTC 2025 x86_64
User: ubuntu (1000)
PHP: 8.4.12
Disabled: NONE
Upload Files
File: /mnt/data/dreamssalon-wp/wp-content/plugins/dreamsalon-widgets/widgets/class-about-five.php
<?php
/**
 * DS About Five Widget
 */
namespace dreamsalonelementor\Widgets;

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;

if (!defined('ABSPATH')) { exit; }

class DSAboutFive extends Widget_Base {
    public function get_name() { return 'dreamsalon-about-five'; }
    public function get_title() { return __('DS About Five', 'dreamsalon_elementor'); }
    public function get_icon() { return 'eicon-info-box'; }
    public function get_categories() { return ['dreamsalon']; }

    protected function _register_controls() {
        // Content: Header
        $this->start_controls_section('header_content', [ 'label' => __('Header', 'dreamsalon_elementor') ]);
        $this->add_control('sec_title', [
            'label' => __('Section Title', 'dreamsalon_elementor'),
            'type' => Controls_Manager::TEXT,
            'default' => __('Recent Articles', 'dreamsalon_elementor'),
        ]);
        $this->add_control('sec_subtitle', [
            'label' => __('Section Sub Title', 'dreamsalon_elementor'),
            'type' => Controls_Manager::TEXT,
            'default' => __('Glow Up With Our Latest Articles', 'dreamsalon_elementor'),
        ]);
        $this->end_controls_section();

        // Content: Query
        $this->start_controls_section('query_content', [ 'label' => __('Query', 'dreamsalon_elementor') ]);
        $this->add_control('posts_per_page', [
            'label' => __('Posts Per Page', 'dreamsalon_elementor'),
            'type' => Controls_Manager::NUMBER,
            'min' => 1,
            'step' => 1,
            'default' => 3,
        ]);
        $this->add_control('include_cats', [
            'label' => __('Include Categories (IDs comma separated)', 'dreamsalon_elementor'),
            'type' => Controls_Manager::TEXT,
            'placeholder' => __('e.g. 3,7,12', 'dreamsalon_elementor'),
        ]);
        $this->add_control('orderby', [
            'label' => __('Order By', 'dreamsalon_elementor'),
            'type' => Controls_Manager::SELECT,
            'default' => 'date',
            'options' => [ 'date' => __('Date', 'dreamsalon_elementor'), 'title' => __('Title', 'dreamsalon_elementor'), 'comment_count' => __('Comment Count', 'dreamsalon_elementor'), 'rand' => __('Random', 'dreamsalon_elementor') ],
        ]);
        $this->add_control('order', [
            'label' => __('Order', 'dreamsalon_elementor'),
            'type' => Controls_Manager::SELECT,
            'default' => 'DESC',
            'options' => [ 'DESC' => __('DESC', 'dreamsalon_elementor'), 'ASC' => __('ASC', 'dreamsalon_elementor') ],
        ]);
        $this->end_controls_section();

        // Content: Meta Display
        $this->start_controls_section('meta_content', [ 'label' => __('Meta Display', 'dreamsalon_elementor') ]);
        $this->add_control('show_date', [
            'label' => __('Show Date', 'dreamsalon_elementor'),
            'type' => Controls_Manager::SWITCHER,
            'label_on' => __('Show', 'dreamsalon_elementor'),
            'label_off' => __('Hide', 'dreamsalon_elementor'),
            'return_value' => 'yes',
            'default' => 'yes',
        ]);
        $this->add_control('show_author', [
            'label' => __('Show Author', 'dreamsalon_elementor'),
            'type' => Controls_Manager::SWITCHER,
            'label_on' => __('Show', 'dreamsalon_elementor'),
            'label_off' => __('Hide', 'dreamsalon_elementor'),
            'return_value' => 'yes',
            'default' => 'yes',
        ]);
        $this->end_controls_section();

        // Content: Links & Buttons
        $this->start_controls_section('links_content', [ 'label' => __('Links & Buttons', 'dreamsalon_elementor') ]);
        $this->add_control('read_more_text', [
            'label' => __('Read More Text', 'dreamsalon_elementor'),
            'type' => Controls_Manager::TEXT,
            'default' => __('Read More', 'dreamsalon_elementor'),
        ]);
        $this->add_control('view_more_text', [
            'label' => __('View More Button Text', 'dreamsalon_elementor'),
            'type' => Controls_Manager::TEXT,
            'default' => __('More Articles', 'dreamsalon_elementor'),
        ]);
        $this->add_control('view_more_url', [
            'label' => __('View More URL', 'dreamsalon_elementor'),
            'type' => Controls_Manager::URL,
            'default' => [ 'url' => get_post_type_archive_link('post') ?: home_url('/blog/') ],
        ]);
        $this->end_controls_section();

        // Style: Section
        $this->start_controls_section('section_style', [ 'label' => __('Section', 'dreamsalon_elementor'), 'tab' => Controls_Manager::TAB_STYLE ]);
        $this->add_responsive_control('section_padding', [
            'label' => __('Padding', 'dreamsalon_elementor'),
            'type' => Controls_Manager::DIMENSIONS,
            'size_units' => ['px','%','em','rem'],
            'selectors' => [ '{{WRAPPER}} .blog-section.section' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
        ]);
        $this->end_controls_section();

        // Style: Header
        $this->start_controls_section('header_style', [ 'label' => __('Header', 'dreamsalon_elementor'), 'tab' => Controls_Manager::TAB_STYLE ]);
        $this->add_group_control(Group_Control_Typography::get_type(), [
            'name' => 'title_typo',
            'label' => __('Title Typography', 'dreamsalon_elementor'),
            'selector' => '{{WRAPPER}} .section-header .title',
        ]);
        $this->add_control('title_color', [
            'label' => __('Title Color', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .section-header .title' => 'color: {{VALUE}};' ],
        ]);
        $this->add_group_control(Group_Control_Typography::get_type(), [
            'name' => 'subtitle_typo',
            'label' => __('Subtitle Typography', 'dreamsalon_elementor'),
            'selector' => '{{WRAPPER}} .section-header p',
        ]);
        $this->add_control('subtitle_color', [
            'label' => __('Subtitle Color', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .section-header p' => 'color: {{VALUE}};' ],
        ]);
        $this->end_controls_section();

        // Style: Card
        $this->start_controls_section('card_style', [ 'label' => __('Card', 'dreamsalon_elementor'), 'tab' => Controls_Manager::TAB_STYLE ]);
        $this->add_group_control(Group_Control_Typography::get_type(), [
            'name' => 'card_title_typo',
            'label' => __('Card Title Typography', 'dreamsalon_elementor'),
            'selector' => '{{WRAPPER}} .blog-item .blog-content h3',
        ]);
        $this->add_control('card_title_color', [
            'label' => __('Card Title Color', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .blog-item .blog-content h3 a' => 'color: {{VALUE}};' ],
        ]);
        $this->add_group_control(Group_Control_Typography::get_type(), [
            'name' => 'card_text_typo',
            'label' => __('Card Text Typography', 'dreamsalon_elementor'),
            'selector' => '{{WRAPPER}} .blog-item .blog-content p',
        ]);
        $this->add_control('card_text_color', [
            'label' => __('Card Text Color', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .blog-item .blog-content p' => 'color: {{VALUE}};' ],
        ]);
        $this->end_controls_section();

        // Style: Meta
        $this->start_controls_section('meta_style', [ 'label' => __('Meta', 'dreamsalon_elementor'), 'tab' => Controls_Manager::TAB_STYLE ]);
        $this->add_group_control(Group_Control_Typography::get_type(), [
            'name' => 'meta_typo',
            'label' => __('Meta Typography', 'dreamsalon_elementor'),
            'selector' => '{{WRAPPER}} .blog-meta, {{WRAPPER}} .blog-meta a',
        ]);
        $this->add_control('meta_color', [
            'label' => __('Meta Color', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .blog-meta, {{WRAPPER}} .blog-meta a' => 'color: {{VALUE}};' ],
        ]);
        $this->end_controls_section();

        // Style: Buttons
        $this->start_controls_section('button_style', [ 'label' => __('Buttons', 'dreamsalon_elementor'), 'tab' => Controls_Manager::TAB_STYLE ]);
        $this->add_group_control(Group_Control_Typography::get_type(), [
            'name' => 'btn_typo',
            'label' => __('Button Typography', 'dreamsalon_elementor'),
            'selector' => '{{WRAPPER}} .view-more .btn',
        ]);
        $this->add_control('btn_text_color', [
            'label' => __('Button Text Color', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .view-more .btn' => 'color: {{VALUE}};' ],
        ]);
        $this->add_control('btn_bg_color', [
            'label' => __('Button Background', 'dreamsalon_elementor'),
            'type' => Controls_Manager::COLOR,
            'selectors' => [ '{{WRAPPER}} .view-more .btn' => 'background-color: {{VALUE}};' ],
        ]);
        $this->end_controls_section();
    }

    protected function render() {
        $s = $this->get_settings_for_display();
        $title = !empty($s['sec_title']) ? $s['sec_title'] : '';
        $subtitle = !empty($s['sec_subtitle']) ? $s['sec_subtitle'] : '';
        $ppp = !empty($s['posts_per_page']) ? absint($s['posts_per_page']) : 3;
        $orderby = !empty($s['orderby']) ? $s['orderby'] : 'date';
        $order = !empty($s['order']) ? $s['order'] : 'DESC';
        $show_date = isset($s['show_date']) && $s['show_date'] === 'yes';
        $show_author = isset($s['show_author']) && $s['show_author'] === 'yes';

        $cat_ids = [];
        if (!empty($s['include_cats'])) {
            $parts = array_map('trim', explode(',', $s['include_cats']));
            foreach ($parts as $p) { if ($p !== '') $cat_ids[] = (int)$p; }
        }

        $args = [
            'post_type' => 'post',
            'posts_per_page' => $ppp,
            'orderby' => $orderby,
            'order' => $order,
            'ignore_sticky_posts' => true,
        ];
        if (!empty($cat_ids)) {
            $args['tax_query'] = [[
                'taxonomy' => 'category',
                'field' => 'term_id',
                'terms' => $cat_ids,
            ]];
        }
        $q = new \WP_Query($args);

        $view_more_text = !empty($s['view_more_text']) ? $s['view_more_text'] : '';
        $view_more_url = !empty($s['view_more_url']['url']) ? $s['view_more_url']['url'] : (get_post_type_archive_link('post') ?: '#');
        $read_more_text = !empty($s['read_more_text']) ? $s['read_more_text'] : __('Read More', 'dreamsalon_elementor');

        ?>
        <section class="blog-section section">
            <div class="container">
                <div class="section-header text-center wow fadeInUp" data-wow-duration="3s">
                    <?php if ($title): ?><h2 class="title"><?php echo esc_html($title); ?></h2><?php endif; ?>
                    <?php if ($subtitle): ?><p><?php echo esc_html($subtitle); ?></p><?php endif; ?>
                </div>
                <div class="row row-gap-4 justify-content-between">
                    <?php if ($q->have_posts()): while ($q->have_posts()): $q->the_post();
                        $permalink = get_permalink();
                        $p_title = get_the_title();
                        $thumb = get_the_post_thumbnail_url(get_the_ID(), 'large');
                        $excerpt = wp_trim_words(get_the_excerpt(), 20);
                        $author_id = get_the_author_meta('ID');
                        $author_name = get_the_author();
                        $author_url = get_author_posts_url($author_id);
                        $author_avatar = get_avatar_url($author_id, ['size' => 64]);
                        $cats = get_the_category();
                        $cat = !empty($cats) ? $cats[0] : null;
                        $cat_link = $cat ? get_category_link($cat->term_id) : '#';
                        $cat_name = $cat ? $cat->name : '';
                        $post_date = get_the_date('j M, Y');
                    ?>
                    <div class="col-lg-4 col-md-6 d-flex">
                        <div class="blog-item flex-fill wow fadeInUp" data-wow-duration="3s">
                            <div class="blog-img d-flex align-items-center">
                                <a href="<?php echo esc_url($permalink); ?>">
                                    <?php if ($thumb): ?>
                                        <img src="<?php echo esc_url($thumb); ?>" class="img-fluid" alt="<?php echo esc_attr($p_title); ?>">
                                    <?php endif; ?>
                                </a>
                                <?php if ($cat_name): ?>
                                    <a href="<?php echo esc_url($cat_link); ?>" class="badge bg-dark"><?php echo esc_html($cat_name); ?></a>
                                <?php endif; ?>
                            </div>
                            <div class="blog-content">
                                <h3 class="text-truncate"><a href="<?php echo esc_url($permalink); ?>"><?php echo esc_html($p_title); ?></a></h3>
                                <p class="fs-16"><?php echo esc_html($excerpt); ?></p>
                                <div class="d-flex align-items-center justify-content-between flex-wrap gap-2">
                                    <div class="blog-meta d-flex align-items-center gap-3">
                                        <?php if ($show_author): ?>
                                        <div class="d-flex align-items-center">
                                            <a href="<?php echo esc_url($author_url); ?>" class="avatar avatar-sm me-2">
                                                <img src="<?php echo esc_url($author_avatar); ?>" alt="<?php echo esc_attr($author_name); ?>" class="rounded-circle">
                                            </a>
                                            <a href="<?php echo esc_url($author_url); ?>" class="fs-14 text-capitalize"><?php echo esc_html($author_name); ?></a>
                                        </div>
                                        <?php endif; ?>
                                        
                                        <?php if ($show_date): ?>
                                        <p class="d-inline-flex align-items-center mb-0">
                                            <i class="ti ti-calendar text-dark me-1"></i><?php echo esc_html($post_date); ?>
                                        </p>
                                        <?php endif; ?>
                                    </div>
                                    <a href="<?php echo esc_url($permalink); ?>" class="view-link link-primary fs-14 fw-medium"><?php echo esc_html($read_more_text); ?></a>
                                </div>
                            </div>
                        </div>
                    </div>
                    <?php endwhile; wp_reset_postdata(); endif; ?>
                </div>

                <?php if (!empty($view_more_text)): ?>
                <div class="text-center view-more">
                    <a href="<?php echo esc_url($view_more_url); ?>" class="btn btn-dark d-inline-flex align-items-center"><?php echo esc_html($view_more_text); ?><i class="ti ti-chevron-right ms-1"></i></a>
                </div>
                <?php endif; ?>
            </div>
        </section>
        <?php
    }
}