====== SearchApiController ====== **Layer:** ''Controller'' · **Source:** ''lib/controller/api/SearchApiController.php:26'' (lines 26–311) ---- class SearchApiController extends ApiController Search API Controller Handles API requests for search functionality ======= Docblock Metadata ======= ^ Tag ^ Value ^ | ''@category'' | Controller Class | | ''@author'' | Blogware Team | | ''@license'' | MIT | | ''@version'' | 1.0 | | ''@since'' | Since Release 1.0 | ======= Inheritance ======= ^ Relation ^ Type ^ Meaning ^ | extends | [[scriptlog:lib:controller:apicontroller|''ApiController'']] | parent class/interface | ======= Constants (0) ======= //None.// ======= Properties (2) ======= ^ Visibility ^ Type ^ Name ^ Default ^ Line ^ | ''private'' | ''(untyped)'' | ''$searchFinder'' | | 31 | | ''private'' | ''(untyped)'' | ''$hateoas'' | | 36 | ======= Methods (9) ======= ^ Visibility ^ Method ^ Summary ^ Line ^ | public | ''__construct()'' | Constructor | 41 | | public | ''index()'' | Search posts and pages (public endpoint) | 61 | | private | ''checkRateLimit()'' | Check rate limit for search endpoint. | 143 | | public | ''posts()'' | Search posts only | 163 | | public | ''pages()'' | Search pages only | 177 | | private | ''buildResponseData()'' | Build the search API response payload. | 197 | | private | ''transformResults()'' | Transform search results for API response | 228 | | private | ''generateExcerpt()'' | Generate excerpt from content | 261 | | private | ''getContentUrl()'' | Get content URL based on type | 293 | ======== __construct() ======== public function __construct() //lines 41–49 (9)// Constructor //Takes no parameters.// ======== index() ======== public function index($_params = []) //lines 61–136 (76)// Search posts and pages (public endpoint) GET /api/v1/search?q=keyword GET /api/v1/search/posts?q=keyword GET /api/v1/search/pages?q=keyword ^ Parameter ^ Type ^ Default ^ Description ^ | ''$_params'' | ''(untyped)'' | ''[]'' | //none// | **Returns:** ''(none declared)'' — void ======== checkRateLimit() ======== private function checkRateLimit(): bool //lines 143–153 (11)// Check rate limit for search endpoint. //Takes no parameters.// **Returns:** ''bool'' — bool ======== posts() ======== public function posts($params = []) //lines 163–167 (5)// Search posts only GET /api/v1/search/posts?q=keyword ^ Parameter ^ Type ^ Default ^ Description ^ | ''$params'' | ''(untyped)'' | ''[]'' | //none// | **Returns:** ''(none declared)'' — void ======== pages() ======== public function pages($params = []) //lines 177–181 (5)// Search pages only GET /api/v1/search/pages?q=keyword ^ Parameter ^ Type ^ Default ^ Description ^ | ''$params'' | ''(untyped)'' | ''[]'' | //none// | **Returns:** ''(none declared)'' — void ======== buildResponseData() ======== private function buildResponseData($results, $transformedResults, $type, $keyword, $totalPages, $hateoasLinks) //lines 197–219 (23)// Build the search API response payload. The top-level "total" field is what the sidebar widget reads to render the result count without reaching into pagination.total_items. ^ Parameter ^ Type ^ Default ^ Description ^ | ''$results'' | ''(untyped)'' | //required// | Raw SearchFinder result (page, perPage, totalRows) | | ''$transformedResults'' | ''(untyped)'' | //required// | Normalized results for the API consumer | | ''$type'' | ''(untyped)'' | //required// | Requested search scope (all|posts|pages) | | ''$keyword'' | ''(untyped)'' | //required// | Sanitized search keyword | | ''$totalPages'' | ''(untyped)'' | //required// | Total number of result pages | | ''$hateoasLinks'' | ''(untyped)'' | //required// | Optional HATEOAS pagination links | **Returns:** ''(none declared)'' — array ======== transformResults() ======== private function transformResults($results, $_type) //lines 228–246 (19)// Transform search results for API response ^ Parameter ^ Type ^ Default ^ Description ^ | ''$results'' | ''(untyped)'' | //required// | //none// | | ''$_type'' | ''(untyped)'' | //required// | //none// | **Returns:** ''(none declared)'' — array ======== generateExcerpt() ======== private function generateExcerpt($content, $length = 150) //lines 261–283 (23)// Generate excerpt from content Post content is stored double-encoded in the database (e.g. "<p>"), so HTML entities MUST be decoded before tags are stripped; doing it the other way round leaks raw HTML into the excerpt (the "Found undefined result(s)" / raw-

widget bug). Whitespace is then collapsed so the truncated excerpt reads cleanly. ^ Parameter ^ Type ^ Default ^ Description ^ | ''$content'' | ''(untyped)'' | //required// | //none// | | ''$length'' | ''(untyped)'' | ''150'' | //none// | **Returns:** ''(none declared)'' — string ======== getContentUrl() ======== private function getContentUrl($id, $slug, $type) //lines 293–310 (18)// Get content URL based on type ^ Parameter ^ Type ^ Default ^ Description ^ | ''$id'' | ''(untyped)'' | //required// | //none// | | ''$slug'' | ''(untyped)'' | //required// | //none// | | ''$type'' | ''(untyped)'' | //required// | //none// | **Returns:** ''(none declared)'' — string ======= Imports ======= ^ Alias ^ Fully-qualified name ^ | ''ApiController'' | [[scriptlog:lib:controller:apicontroller|''Scriptlog\Controller\ApiController'']] | | ''ApiHateoas'' | [[scriptlog:lib:core:apihateoas|''Scriptlog\Core\ApiHateoas'']] | | ''ApiResponse'' | [[scriptlog:lib:core:apiresponse|''Scriptlog\Core\ApiResponse'']] | | ''SearchFinder'' | [[scriptlog:lib:core:searchfinder|''Scriptlog\Core\SearchFinder'']] | ---- //This page is generated from source by 'tools/gendoc'. Edits will be overwritten.//