Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Categories
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 4
132
0.00% covered (danger)
0.00%
0 / 1
 get
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
12
 sort_categories
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
30
 add_featured_category
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 generate_uuid_v4
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace NewfoldLabs\WP\Module\Patterns\Library;
4
5use NewfoldLabs\WP\Module\Patterns\SiteClassification;
6use NewfoldLabs\WP\Module\Data\WonderBlocks\Requests\Fetch as WonderBlocksFetchRequest;
7use NewfoldLabs\WP\Module\Data\WonderBlocks\WonderBlocks;
8
9/**
10 * Library for categories.
11 */
12class Categories {
13
14    /**
15     * Get the categories from transient or the remote API.
16     *
17     * @param string $type Type of categories to get.
18     * @param string $orderby Attribute of the category to sort by. Default is 'order'.
19     * @param string $order  Specifies the order of sorting. Acceptable values are 'ASC' for ascending order or 'DESC' for descending order. Default is 'ASC'.
20     *
21     * @return array|WP_Error Array of categories or WP_Error if there was an error fetching the data.
22     */
23    public static function get( $type = 'patterns', $orderby = 'order', $order = 'ASC' ) {
24
25        // Ensure we only get templates or patterns.
26        $type = 'templates' === $type ? 'templates' : 'patterns';
27
28        $request = new WonderBlocksFetchRequest(
29            array(
30                'endpoint'       => 'categories',
31                'slug'           => $type,
32                'primary_type'   => SiteClassification::get_primary_type(),
33                'secondary_type' => SiteClassification::get_secondary_type(),
34            )
35        );
36
37        $data = WonderBlocks::fetch( $request );
38
39        if ( ! $data ) {
40            return new \WP_Error(
41                'nfd_wonder_blocks_error',
42                __( 'Error fetching data from the platform.', 'nfd-wonder-blocks' )
43            );
44        }
45
46        // Sort categories.
47        $data = self::sort_categories( $data, $orderby, $order );
48
49        $data = self::add_featured_category( $data, $type );
50
51        // Return the categories.
52        return $data;
53    }
54
55    /**
56     * Sorts an array of categories based on a specified order and ordering attribute.
57     * By default, it sorts by 'order' in ascending ('ASC') order. The function
58     * currently only applies sorting if the 'order' attribute is specified for ordering.
59     * If 'order' is used, categories without a specified 'order' are placed at the end.
60     *
61     * @param array  $data    The array of categories to sort. Each category should be an associative array that potentially includes the 'order' key.
62     * @param string $orderby Attribute of the category to sort by. Default is 'order'.
63     * @param string $order   Specifies the order of sorting. Acceptable values are 'ASC' for ascending order or 'DESC' for descending order. Default is 'ASC'.
64     *
65     * @return array Returns the sorted array of categories. If 'order' is not the sorting attribute, returns the input array without changes.
66     */
67    private static function sort_categories( $data, $orderby = 'order', $order = 'ASC' ) {
68
69        if ( 'order' === $orderby ) {
70            usort(
71                $data,
72                function ( $a, $b ) use ( $orderby, $order ) {
73                    $value_a = isset( $a[ $orderby ] ) ? $a[ $orderby ] : PHP_INT_MAX;
74                    $value_b = isset( $b[ $orderby ] ) ? $b[ $orderby ] : PHP_INT_MAX;
75
76                    if ( 'ASC' === $order ) {
77                        return $value_a <=> $value_b;
78                    } else {
79                        return $value_b <=> $value_a;
80                    }
81                }
82            );
83        }
84
85        return $data;
86    }
87
88    /**
89     * Manually add the featured category to the categories array.
90     * This is a temporary solution until HIIVE returns the actual data.
91     *
92     * @param array  $data Array of categories.
93     * @param string $type Type of categories to get.
94     * @return array $data Array of categories with the featured category.
95     */
96    private static function add_featured_category( $data, $type ) {
97
98        $data = array_filter(
99            $data,
100            function ( $category ) {
101                return 'featured' !== $category['title'];
102            }
103        );
104
105        $id = self::generate_uuid_v4();
106
107        $featured_category = array(
108            'id'    => $id,
109            'title' => 'featured',
110            'label' => 'Featured',
111            'count' => 'templates' === $type ? 4 : 11,
112        );
113
114        $data = array_merge( array( $featured_category ), $data );
115
116        return $data;
117    }
118
119    /**
120     * Temporary solution to add UUIDs to manual categories.
121     */
122    private static function generate_uuid_v4() {
123        return sprintf(
124            '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
125            wp_rand( 0, 0xffff ),
126            wp_rand( 0, 0xffff ),
127            wp_rand( 0, 0xffff ),
128            wp_rand( 0, 0x0fff ) | 0x4000,
129            wp_rand( 0, 0x3fff ) | 0x8000,
130            wp_rand( 0, 0xffff ),
131            wp_rand( 0, 0xffff ),
132            wp_rand( 0, 0xffff )
133        );
134    }
135}