Invision Power Services, Inc. * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 3 Dec 2015 */ namespace IPS\Api; /* To prevent PHP errors (extending class does not exist) revealing path */ use IPS\Db; use IPS\Db\Select; use IPS\Member; use IPS\Patterns\ActiveRecordIterator; use Iterator; use function defined; if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * API Response */ class PaginatedResponse extends Response { /** * @brief HTTP Response Code */ public int $httpCode = 200; /** * @brief Iterator (usually a select query) */ protected Iterator|array|null $iterator = null; /** * @brief Current page */ protected int $page = 1; /** * @brief Results per page */ protected int $resultsPerPage = 25; /** * @brief ActiveRecord class */ protected string $activeRecordClass = ''; /** * @brief Total Count */ protected int $count = 0; /** * @brief The member making the API request or NULL for API Key / client_credentials */ protected ?Member $authorizedMember = null; /** * Constructor * * @param int $httpCode HTTP Response code * @param Iterator|array $iterator Select query or \IPS\Patterns\ActiveRecordIterator instance * @param int $page Current page * @param string $activeRecordClass ActiveRecord class * @param int|NULL $count Total Count * @param Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials * @param int|null $perPage Number of results per page * @return void */ public function __construct( int $httpCode, Iterator|array $iterator, int $page, string $activeRecordClass, ?int $count, ?Member $authorizedMember = NULL, ?int $perPage=NULL ) { $this->httpCode = $httpCode; $this->page = $page > 0 ? $page : 1; $this->iterator = $iterator; $this->activeRecordClass = $activeRecordClass; $this->count = (int) $count; $this->resultsPerPage = $perPage ?: 25; $this->authorizedMember = $authorizedMember; if( $this->iterator instanceof Select ) { /* Limit the query before calling count(), as this runs the query so it cannot be modified after */ $this->iterator->query .= Db::i()->compileLimitClause( array( ( $this->page - 1 ) * $this->resultsPerPage, $this->resultsPerPage ) ); if ( $count === NULL ) { $this->count = $iterator->count(); } } } /** * Data to output * * @return array */ public function getOutput() : array { $results = array(); if ( $this->activeRecordClass ) { if( $this->iterator instanceof ActiveRecordIterator ) { foreach ( $this->iterator as $result ) { $results[] = $result->apiOutput( $this->authorizedMember ); } } else { foreach ( new ActiveRecordIterator( $this->iterator, $this->activeRecordClass ) as $result ) { $results[] = $result->apiOutput( $this->authorizedMember ); } } } else { foreach ( $this->iterator as $result ) { $results[] = $result; } } return array( 'page' => $this->page, 'perPage' => $this->resultsPerPage, 'totalResults' => $this->count, 'totalPages' => ceil( $this->count / $this->resultsPerPage ), 'results' => $results ); } }