Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
PatternIndexController
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 2
90
0.00% covered (danger)
0.00%
0 / 1
 index
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
6
 getBySlug
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3namespace NewfoldLabs\WP\Module\Patterns\Api\Controllers;
4
5use NewfoldLabs\WP\Module\Patterns\Library\Items;
6use NewfoldLabs\WP\Module\Patterns\Api\RemoteRequest;
7
8/**
9 * Controller for pattern index and pattern-by-slug endpoints.
10 *
11 * Provides lightweight access to the pattern library for AI editor chat integration.
12 */
13class PatternIndexController {
14
15    /**
16     * Return all patterns with content stripped (lightweight index for search).
17     *
18     * @param \WP_REST_Request $request Request object.
19     * @return \WP_REST_Response
20     */
21    public static function index( $request ) {
22        $data = Items::get( 'patterns' );
23
24        if ( \is_wp_error( $data ) ) {
25            return new \WP_REST_Response( RemoteRequest::format_error_data( $data ), 503 );
26        }
27
28        // Strip content field to keep the index lightweight
29        $index = array_map(
30            function ( $pattern ) {
31                return array(
32                    'slug'        => $pattern['slug'] ?? '',
33                    'title'       => $pattern['title'] ?? '',
34                    'description' => $pattern['description'] ?? '',
35                    'categories'  => $pattern['categories'] ?? array(),
36                    'tags'        => $pattern['tags'] ?? array(),
37                );
38            },
39            $data
40        );
41
42        $index = array_values( $index );
43
44        // Persist for MCP ability fallback when the external API is unreachable.
45        update_option( 'blu_pattern_index', $index, false );
46
47        return new \WP_REST_Response( $index );
48    }
49
50    /**
51     * Return a single pattern by slug, including full content markup.
52     *
53     * @param \WP_REST_Request $request Request object.
54     * @return \WP_REST_Response
55     */
56    public static function getBySlug( $request ) {
57        $slug = $request->get_param( 'slug' );
58
59        if ( empty( $slug ) ) {
60            return new \WP_REST_Response(
61                array( 'error' => 'Missing required parameter: slug' ),
62                400
63            );
64        }
65
66        $data = Items::get( 'patterns' );
67
68        if ( \is_wp_error( $data ) ) {
69            return new \WP_REST_Response( RemoteRequest::format_error_data( $data ), 503 );
70        }
71
72        // Find the pattern matching the slug
73        $match = null;
74        foreach ( $data as $pattern ) {
75            if ( isset( $pattern['slug'] ) && $pattern['slug'] === $slug ) {
76                $match = $pattern;
77                break;
78            }
79        }
80
81        if ( ! $match ) {
82            return new \WP_REST_Response(
83                array( 'error' => 'Pattern not found: ' . $slug ),
84                404
85            );
86        }
87
88        return new \WP_REST_Response(
89            array(
90                'slug'        => $match['slug'] ?? '',
91                'title'       => $match['title'] ?? '',
92                'content'     => $match['content'] ?? '',
93                'categories'  => $match['categories'] ?? array(),
94                'tags'        => $match['tags'] ?? array(),
95                'description' => $match['description'] ?? '',
96            )
97        );
98    }
99}