<?php
/**
 * Category widget.
 *
 * @package    ShoBe
 * @author     Boby Hermez
 * @copyright  Copyright (c) 2025, Boby Hermez
 * @license    http://www.gnu.org/licenses/gpl-2.0.html
 * @since      1.0.0
 */
class shobe_categories_Widget extends WP_Widget {

	/**
	 * Sets up the widgets.
	 *
	 * @since 1.0.0
	 */
	function __construct() {

		// Set up the widget options.
		$shobe_widget_options = array(
			'classname'   => 'widget-categories widget_custom_categories',
			'description' => __( 'Display Custom Categories.', 'shobe' )
		);

		// Create the widget.
		parent::__construct(
			'custom_categories',                                   // $this->id_base
			__( '&raquo; ShoBe Custom Categories', 'shobe' ), // $this->name
			$shobe_widget_options                                      // $this->shobe_widget_options
		);


	}

	/**
	 * Outputs the widget based on the arguments input through the widget controls.
	 *
	 * @since 1.0.0
	 */
	function widget( $args, $instance ) {
		extract( $args );

		// Output the theme's $before_widget wrapper.
		echo $before_widget;        
        
        $instance =  wp_parse_args( $instance, array(
            'title'         => '',
            'orderby'       => 'count',
            'order'         => 'desc',
            'depth'         => '1',
            'show_count'    => 0,
            'item_per_row'  => 2,
        ) );
        echo $before_title;
		echo empty( $instance['title'] ) ? _e( 'Categories', 'shobe' ) : apply_filters( 'widget_title', $instance['title'] );
        echo $after_title;

        $_args = array(
            'show_option_all'    => '',
            'orderby'            => 'name',
            'order'              => 'ASC',
            'style'              => 'list',
            'show_count'         => 1,
            'hide_empty'         => 0,
            'use_desc_for_title' => 1,
            'child_of'           => 0,
            'feed'               => '',
            'feed_type'          => '',
            'feed_image'         => '',
            'exclude'            => '',
            'exclude_tree'       => '',
            'include'            => '',
            'hierarchical'       => 1,
            'title_li'           => false,
            'show_option_none'   => false,
            'echo'               => 1,
            'depth'              => 1,
            'current_category'   => 0,
            'pad_counts'         => 0,
            'walker'             =>  new ShoBe_Walker_Category()
        );

        $_args =  wp_parse_args( $instance , $_args );
        ?>
       <ul class="list-unstyled ms-3 my-3">
            <?php wp_list_categories( $_args ); ?>
        </ul>
        <?php 
		// Close the theme's widget wrapper.
		echo $after_widget;

	}

	/**
	 * Updates the widget control options for the particular instance of the widget.
	 *
	 * @since 1.0.0
	 */
	function update( $new_instance, $old_instance ) {

	 //$instance = array();
     $new_instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( strip_tags( $new_instance['title'] ) ): '';
     return $new_instance;
     // return $instance;
	}


	/**
	 * Displays the widget control options in the Widgets admin screen.
	 *
	 * @since 1.0.0
	 */
	function form( $instance ) {

		// Default value.
		$instance =  wp_parse_args( $instance, array(
            'title'         => '',
            
            'orderby'       => 'count',
            'order'         => 'desc',
            'depth'         => '1',
            'show_count'    => 0,
            'item_per_row'  => 2,
        ) );

        $title = ! empty( $instance['title'] ) ? $instance['title'] : '';

 
	?>

		<p>
			<label for="<?php echo $this->get_field_id( 'title' ); ?>">
				<?php _e( 'Title', 'shobe' ); ?>
			</label>
			<input type="text" class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $instance['title'] ); ?>" />
		</p>

        <div>
            <label for="<?php echo $this->get_field_id( 'depth' ); ?>"><?php esc_html_e( 'Depth:', 'shobe' ); ?></label>
            <?php

            $depth = array(
                '0' => '<code>0</code> - ' . esc_html__( 'All Categories and child Categories', 'shobe' ),
                '-1' => '<code>-1</code> -' . esc_html__('All Categories displayed in flat (no indent) form (overrides hierarchical)', 'shobe' ),
                '1' => '<code>1</code> - ' . esc_html__( 'Show only top level Categories', 'shobe' ),
                'n' => '<code>n</code> - ' . esc_html__( 'Value of n (a number) specifies the depth (or level) to descend in displaying Categories', 'shobe' ),
            );

            ?>

            <input class="widefat" id="<?php echo $this->get_field_id( 'depth' ); ?>" name="<?php echo $this->get_field_name( 'depth' ); ?>" type="text" value="<?php echo esc_attr( $instance['depth'] ); ?>">
            <br/>

            <p class="description"><?php echo join( "<br/>", $depth ); ?></p>
        </div>

        <p>
            <label for="<?php echo $this->get_field_id( 'orderby' ); ?>"><?php esc_html_e( 'Order by:', 'shobe' ); ?></label>
            <select name="<?php echo $this->get_field_name( 'orderby' ); ?>">
                <?php
                $a = array(
                    'count' => esc_html__( 'Count', 'shobe' ),
                    'name'  => esc_html__( 'Name', 'shobe' ),
                ) ;
                foreach ( $a as $k => $v ) {
                    echo '<option value="'.$k.'" '.selected( $instance['orderby'], $k, false ).' >'.$v.'</option>';
                } ?>
            </select>
        </p>

        <p>
            <label for="<?php echo $this->get_field_id( 'order' ); ?>"><?php esc_html_e( 'Order:', 'shobe' ); ?></label>
            <select name="<?php echo $this->get_field_name( 'order' ); ?>">
                <?php
                $a = array(
                    'desc' => esc_html__( 'Desc', 'shobe' ),
                    'asc'  => esc_html__( 'Asc', 'shobe' ),
                );
                foreach (  $a as $k => $v ) {
                    echo '<option value="'.$k.'" '.selected( $instance['order'], $k, false ).' >'.$v.'</option>';
                } ?>
            </select>
        </p>

        <p>
            <label for="<?php echo $this->get_field_id( 'show_count' ); ?>"><?php esc_html_e( 'Show count ?', 'shobe' ); ?></label>
            <input class="widefat" <?php checked( $instance['show_count'], 1 ); ?> id="<?php echo $this->get_field_id( 'show_count' ); ?>" name="<?php echo $this->get_field_name( 'show_count' ); ?>" type="checkbox" value="1">
        </p>

        <p>
            <label for="<?php echo $this->get_field_id( 'item_per_row' ); ?>"><?php esc_html_e( 'Number item per row:', 'shobe' ); ?></label>
            <select name="<?php echo $this->get_field_name( 'item_per_row' ); ?>">
                <?php for (  $i = 1; $i <=16 ; $i++ ) {
                    echo '<option value="'.$i.'" '.selected( $instance['item_per_row'], $i, false ).' >'.$i.'</option>';
                } ?>
            </select>

        </p>

	<?php

	}

}

function register_shobe_categories_Widget() {
	register_widget( 'shobe_categories_Widget' );
}
add_action( 'widgets_init', 'register_shobe_categories_Widget' );

class ShoBe_Walker_Category extends Walker_Category{

    /**
     * Start the element output.
     *
     * @see Walker::start_el()
     *
     * @since 2.1.0
     *
     * @param string $output   Passed by reference. Used to append additional content.
     * @param object $category Category data object.
     * @param int    $depth    Depth of category in reference to parents. Default 0.
     * @param array  $args     An array of arguments. @see wp_list_categories()
     * @param int    $id       ID of the current category.
     */
    public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
        /** This filter is documented in wp-includes/category-template.php */
        $cat_name = apply_filters(
            'list_cats',
            esc_attr( $category->name ),
            $category
        );

        // Don't generate an element if the category name is empty.
        if ( ! $cat_name ) {
            return;
        }

        $link = '<a class="me-2 text-dark" href="' . esc_url( get_term_link( $category ) ) . '" ';
        if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) {
            /**
             * Filter the category description for display.
             *
             * @since 1.2.0
             *
             * @param string $description Category description.
             * @param object $category    Category object.
             */
            $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
        }

        $link .= '>';

        $link .= $cat_name . '</a>';

        if ( ! empty( $args['show_count'] ) ) {
            $link .= ' <span class=" text-dark">(' . number_format_i18n( $category->count ) . ')</span> ';
        }

        if ( 'list' == $args['style'] ) {
            $output .= "\t<li";
            $css_classes = array(
                'py-1',
                'text-primary',
                'cat-item',
                'cat-item-' . $category->term_id,
            );

            if ( ! empty( $args['current_category'] ) ) {
                $_current_category = get_term( $args['current_category'], $category->taxonomy );
                if ( $category->term_id == $args['current_category'] ) {
                    $css_classes[] = 'current-cat';
                } elseif ( $category->term_id == $_current_category->parent ) {
                    $css_classes[] = 'current-cat-parent';
                }
            }

            /**
             * Filter the list of CSS classes to include with each category in the list.
             *
             * @since 4.2.0
             *
             * @see wp_list_categories()
             *
             * @param array  $css_classes An array of CSS classes to be applied to each list item.
             * @param object $category    Category data object.
             * @param int    $depth       Depth of page, used for padding.
             * @param array  $args        An array of wp_list_categories() arguments.
             */
            $css_classes = implode( ' ', apply_filters( 'category_css_class', $css_classes, $category, $depth, $args ) );

            $output .=  ' class="' . $css_classes . '"';
            $output .= ">$link\n";
        } else {
            $output .= "\t$link<br />\n";
        }
    }

}
