Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c93b37b20 | ||
|
|
accda2f356 |
@@ -0,0 +1,152 @@
|
|||||||
|
# Infor-Request-Response
|
||||||
|
|
||||||
|
PHP library for HTTP request/response abstraction. Provides clean, static-style APIs for reading request parameters, building responses, and managing session flash messages.
|
||||||
|
|
||||||
|
**Package:** `inforsistemas/rr`
|
||||||
|
**Namespace:** `RR`
|
||||||
|
**Requires:** PHP 8.1+
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require inforsistemas/rr
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Classes
|
||||||
|
|
||||||
|
### `Request` — Reading input parameters
|
||||||
|
|
||||||
|
Fully static class. POST always takes precedence over GET.
|
||||||
|
|
||||||
|
```php
|
||||||
|
use RR\Request;
|
||||||
|
use RR\ParamType;
|
||||||
|
|
||||||
|
// Required param — throws Exception if missing
|
||||||
|
$id = Request::requiredParam('id', ParamType::INT);
|
||||||
|
|
||||||
|
// Optional param — returns default if missing
|
||||||
|
$search = Request::optionalParam('q', ParamType::ALPHA, '');
|
||||||
|
|
||||||
|
// Required array param — throws Exception if missing
|
||||||
|
$items = Request::requiredParamArray('items');
|
||||||
|
|
||||||
|
// Detect AJAX/fetch/API client requests
|
||||||
|
if (Request::detectAjaxRequest()) {
|
||||||
|
// respond with JSON
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**`ParamType` enum values:** `INT`, `DOUBLE`, `ALPHA`, `ALPHANUM`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `Response` — Building and sending responses
|
||||||
|
|
||||||
|
Singleton accessed via `Response::getInstance()`. All builder methods are chainable and static.
|
||||||
|
|
||||||
|
```php
|
||||||
|
use RR\Response;
|
||||||
|
|
||||||
|
// Send a plain HTML response
|
||||||
|
Response::body('<h1>Hello</h1>')->send();
|
||||||
|
|
||||||
|
// Append/prepend to the body buffer
|
||||||
|
Response::bodyPrepend('<header>...</header>');
|
||||||
|
Response::bodyAppend('<footer>...</footer>');
|
||||||
|
Response::send();
|
||||||
|
|
||||||
|
// Set a custom header
|
||||||
|
Response::header('X-Custom', 'value')->send();
|
||||||
|
|
||||||
|
// Send a JSON response
|
||||||
|
Response::json(['status' => 'ok', 'data' => $result])->send();
|
||||||
|
|
||||||
|
// JSONP response
|
||||||
|
Response::json($data, 'myCallback')->send();
|
||||||
|
|
||||||
|
// Redirect (303 by default)
|
||||||
|
// Automatically returns JSON {"location": "..."} for AJAX requests
|
||||||
|
Response::redirect('/dashboard');
|
||||||
|
Response::redirect('/login', 302);
|
||||||
|
|
||||||
|
// Redirect back to the previous page (HTTP_REFERER)
|
||||||
|
Response::back();
|
||||||
|
|
||||||
|
// Terminate execution after sending
|
||||||
|
Response::send()->done();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `Flash` — Session-based flash messages
|
||||||
|
|
||||||
|
Singleton accessed via `Flash::getInstance()`. Messages are written to the session and available on the **next** request.
|
||||||
|
|
||||||
|
```php
|
||||||
|
use RR\Flash;
|
||||||
|
use RR\MessageType;
|
||||||
|
|
||||||
|
// Add messages (shorthand methods)
|
||||||
|
Flash::addInfo('Profile updated.');
|
||||||
|
Flash::addSuccess('Order placed successfully!');
|
||||||
|
Flash::addWarning('Your session will expire soon.');
|
||||||
|
Flash::addError('Invalid credentials.');
|
||||||
|
|
||||||
|
// Add a message with an explicit type
|
||||||
|
Flash::addMessage('Something happened.', MessageType::INFO);
|
||||||
|
|
||||||
|
// Read messages on the next request
|
||||||
|
if (Flash::hasMessageType(MessageType::ERROR)) {
|
||||||
|
$errors = Flash::getError();
|
||||||
|
}
|
||||||
|
|
||||||
|
$infos = Flash::getInfos();
|
||||||
|
$successes = Flash::getSuccess();
|
||||||
|
$warnings = Flash::getWarning();
|
||||||
|
$errors = Flash::getError();
|
||||||
|
|
||||||
|
// Get all messages of any type
|
||||||
|
$messages = Flash::getMessages(MessageType::SUCCESS);
|
||||||
|
```
|
||||||
|
|
||||||
|
**`MessageType` enum values:** `INFO`, `SUCCESS`, `WARNING`, `ERROR`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typical usage pattern
|
||||||
|
|
||||||
|
```php
|
||||||
|
use RR\Request;
|
||||||
|
use RR\Response;
|
||||||
|
use RR\Flash;
|
||||||
|
use RR\ParamType;
|
||||||
|
|
||||||
|
// Controller action
|
||||||
|
function store(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$name = Request::requiredParam('name', ParamType::ALPHA);
|
||||||
|
$price = Request::requiredParam('price', ParamType::DOUBLE);
|
||||||
|
|
||||||
|
// ... save to DB ...
|
||||||
|
|
||||||
|
Flash::addSuccess('Item created successfully.');
|
||||||
|
Response::redirect('/items');
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Flash::addError('Missing required fields.');
|
||||||
|
Response::back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [composer.json](composer.json) for author information.
|
||||||
+165
-83
@@ -1,51 +1,47 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace RR;
|
namespace RR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to handle flash messages.
|
||||||
|
* A Flash message is a message registered in this request and
|
||||||
|
* it's shown in the next request
|
||||||
|
*/
|
||||||
class Flash{
|
class Flash{
|
||||||
|
|
||||||
private static $_instance;
|
private static $_instance;
|
||||||
|
|
||||||
// Message types and shortcuts
|
const FLASH_SESSION_NAME = 'flashes';
|
||||||
const FLASH_INFO = 'i';
|
|
||||||
const FLASH_SUCCESS = 's';
|
|
||||||
const FLASH_WARNING = 'w';
|
|
||||||
const FLASH_ERROR = 'e';
|
|
||||||
|
|
||||||
const FLASH_SESSION_NAME = 'flashes';
|
public $flashes = Array();
|
||||||
|
public $nextFlashes = Array();
|
||||||
const defaultType = self::INFO;
|
|
||||||
|
|
||||||
protected $msgTypes = [
|
|
||||||
self::ERROR => 'error',
|
|
||||||
self::WARNING => 'warning',
|
|
||||||
self::SUCCESS => 'success',
|
|
||||||
self::INFO => 'info',
|
|
||||||
];
|
|
||||||
|
|
||||||
public $oldMessages = Array();
|
|
||||||
public $newMessages = Array();
|
|
||||||
public $_flashes = Array();
|
|
||||||
|
|
||||||
//SINGLETON==============================================
|
//SINGLETON==============================================
|
||||||
|
|
||||||
private function __construct(){
|
private function __construct(): void
|
||||||
|
{
|
||||||
if(session_id() == '' || !isset($_SESSION)) {
|
if(session_id() == '' || !isset($_SESSION)) {
|
||||||
session_start();
|
session_start();
|
||||||
}
|
}
|
||||||
if( isset($_SESSION['flashes']) ){
|
|
||||||
$this->oldMessages = $_SESSION['flashes'];
|
if( isset($_SESSION[self::FLASH_SESSION_NAME]) ){
|
||||||
|
$this->flashes = $_SESSION[self::FLASH_SESSION_NAME];
|
||||||
}
|
}
|
||||||
unset( $_SESSION[self::SESSION_NAME] );
|
|
||||||
|
// The messages are in memory. So clear the $_SESSION
|
||||||
|
$_SESSION[self::FLASH_SESSION_NAME] = Array();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function newObj(){
|
private static function newObj(): Flash
|
||||||
|
{
|
||||||
if (!isset( self::$_instance )) {
|
if (!isset( self::$_instance )) {
|
||||||
self::$_instance = new Flash();
|
self::$_instance = new Flash();
|
||||||
}
|
}
|
||||||
return self::$_instance;
|
return self::$_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getInstance(){
|
public static function getInstance(): Flash
|
||||||
|
{
|
||||||
if (!isset(self::$_instance)) {
|
if (!isset(self::$_instance)) {
|
||||||
return self::newObj();
|
return self::newObj();
|
||||||
}
|
}
|
||||||
@@ -54,103 +50,189 @@ class Flash{
|
|||||||
|
|
||||||
//=======================================================
|
//=======================================================
|
||||||
|
|
||||||
public function merge(){
|
|
||||||
$this->_flashes = array_merge_recursive($this->newMessages, $this->oldMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadToSession(){
|
|
||||||
$_SESSION[self::SESSION_NAME] = $this->newMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* @ctag Flash:addMessage();
|
|
||||||
* @ctag Flash:addMessage(Flash::FLASH_INFO, '');
|
|
||||||
* @ctag Flash:addMessage(Flash::FLASH_SUCCESS, '');
|
|
||||||
* @ctag Flash:addMessage(Flash::FLASH_WARNING, '');
|
|
||||||
* @ctag Flash:addMessage(Flash::FLASH_ERROR, '');
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static function addMessage($type = self::defaultType, $message){
|
|
||||||
$instance = self::getInstance();
|
|
||||||
$instance->newMessages[$type] = $message;
|
|
||||||
$instance->loadToSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Load the stored messages for this session to the $_SESSION varible
|
||||||
|
* to be used on the next request
|
||||||
*
|
*
|
||||||
* @ctag Flash::addInfo('');
|
* @return Flash
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function addInfo($message){
|
private function loadToSession(): Flash
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
$instance->newMessages[self::INFO] = $message;
|
$_SESSION[self::FLASH_SESSION_NAME] = array_merge_recursive($_SESSION[self::FLASH_SESSION_NAME], $instance->nextFlashes);
|
||||||
$instance->loadToSession();
|
$instance->nextFlashes = Array();
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add a message to the session with the INFO type
|
||||||
*
|
*
|
||||||
* @ctag Flash::addError('');
|
* @param string $message
|
||||||
*
|
*
|
||||||
|
* @return Flash
|
||||||
*/
|
*/
|
||||||
public static function addError($message){
|
public static function addInfo(string $message): Flash
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
$instance->newMessages[self::ERROR] = $message;
|
$instance->nextFlashes[MessageType::INFO->value][] = $message;
|
||||||
$instance->loadToSession();
|
$instance->loadToSession();
|
||||||
|
|
||||||
|
return $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add a message from a specific type on the session
|
||||||
*
|
*
|
||||||
* @ctag Flash::getErrors();
|
* @param MessageType $type
|
||||||
|
* @param string $message
|
||||||
*
|
*
|
||||||
|
* @return Flash
|
||||||
*/
|
*/
|
||||||
public static function getErrors(){
|
public static function addMessage(string $message, MessageType $type = MessageType::INFO): Flash
|
||||||
if(!self::hasErrors()){
|
{
|
||||||
|
$instance = self::getInstance();
|
||||||
|
$instance->nextFlashes[$type->value][] = $message;
|
||||||
|
$instance->loadToSession();
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a message to the session with the SUCCESS type
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
* @return Flash
|
||||||
|
*/
|
||||||
|
public static function addSuccess(string $message): Flash
|
||||||
|
{
|
||||||
|
$instance = self::getInstance();
|
||||||
|
$instance->nextFlashes[MessageType::SUCCESS->value][] = $message;
|
||||||
|
$instance->loadToSession();
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a message to the session with the WARNING type
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
* @return Flash
|
||||||
|
*/
|
||||||
|
public static function addWarning(string $message): Flash
|
||||||
|
{
|
||||||
|
$instance = self::getInstance();
|
||||||
|
$instance->nextFlashes[MessageType::WARNING->value][] = $message;
|
||||||
|
$instance->loadToSession();
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a message to the session with the ERROR type
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
* @return Flash
|
||||||
|
*/
|
||||||
|
public static function addError(string $message): Flash
|
||||||
|
{
|
||||||
|
$instance = self::getInstance();
|
||||||
|
$instance->nextFlashes[MessageType::ERROR->value][] = $message;
|
||||||
|
$instance->loadToSession();
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there is messages from a type on the collection
|
||||||
|
*
|
||||||
|
* @param MessageType $type
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function hasMessageType(MessageType $type = MessageType::INFO): bool
|
||||||
|
{
|
||||||
|
$instance = self::getInstance();
|
||||||
|
|
||||||
|
if(array_key_exists($type->value, $instance->flashes)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all messages from a type
|
||||||
|
*
|
||||||
|
* @param MessageType $type
|
||||||
|
*/
|
||||||
|
public static function getMessages(MessageType $type = MessageType::INFO): Array
|
||||||
|
{
|
||||||
|
if(!self::hasMessageType($type)){
|
||||||
return Array();
|
return Array();
|
||||||
}
|
}
|
||||||
return self::getInstance()->_flashes[self::ERROR];
|
|
||||||
|
return self::getInstance()->flashes[$type->value];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Return all info messages registered on the collection
|
||||||
*
|
*
|
||||||
* @ctag Flash::addInfos();
|
* @return Array
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function getInfos(){
|
public static function getInfos(): Array
|
||||||
if(!self::hasInfo()){
|
{
|
||||||
|
if(!self::hasMessageType(MessageType::INFO)){
|
||||||
return Array();
|
return Array();
|
||||||
}
|
}
|
||||||
return self::getInstance()->_flashes[self::INFO];
|
|
||||||
|
return self::getInstance()->flashes[MessageType::INFO->value];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Return all success messages registered on the collection
|
||||||
*
|
*
|
||||||
* @ctag Flash::addErrors();
|
* @return Array
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function hasErrors(){
|
public static function getSuccess(): Array
|
||||||
$instance = self::getInstance();
|
{
|
||||||
$instance->merge();
|
if(!self::hasMessageType(MessageType::SUCCESS)){
|
||||||
if( array_key_exists(self::ERROR, $instance->_flashes ) ){
|
return Array();
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self::getInstance()->flashes[MessageType::SUCCESS->value];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Return all warning messages registered on the collection
|
||||||
*
|
*
|
||||||
* @ctag Flash::hasInfo();
|
* @return Array
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function hasInfo(){
|
public static function getWarning(): Array
|
||||||
$instance = self::getInstance();
|
{
|
||||||
$instance->merge();
|
if(!self::hasMessageType(MessageType::WARNING)){
|
||||||
if( array_key_exists(self::INFO, $instance->_flashes ) ){
|
return Array();
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self::getInstance()->flashes[MessageType::WARNING->value];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all error messages registered on the collection
|
||||||
|
*
|
||||||
|
* @return Array
|
||||||
|
*/
|
||||||
|
public static function getError(): Array
|
||||||
|
{
|
||||||
|
if(!self::hasMessageType(MessageType::ERROR)){
|
||||||
|
return Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::getInstance()->flashes[MessageType::ERROR->value];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RR;
|
||||||
|
|
||||||
|
enum MessageType: string
|
||||||
|
{
|
||||||
|
case INFO = 'info';
|
||||||
|
case SUCCESS = 'success';
|
||||||
|
case WARNING = 'warning';
|
||||||
|
case ERROR = 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MessageTypeShort: string
|
||||||
|
{
|
||||||
|
case INFO = 'i';
|
||||||
|
case SUCCESS = 's';
|
||||||
|
case WARNING = 'w';
|
||||||
|
case ERROR = 'e';
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RR;
|
||||||
|
|
||||||
|
enum ParamType
|
||||||
|
{
|
||||||
|
case INT; // integer
|
||||||
|
case DOUBLE; // double
|
||||||
|
case ALPHA; // alpha
|
||||||
|
case ALPHANUM; // alphanum
|
||||||
|
}
|
||||||
+180
-39
@@ -2,33 +2,92 @@
|
|||||||
|
|
||||||
namespace RR;
|
namespace RR;
|
||||||
|
|
||||||
class Request{
|
use RR\ParamType;
|
||||||
|
|
||||||
const PARAM_ALPHA = 'alpha';
|
/**
|
||||||
const PARAM_ALPHANUM = 'alphanum';
|
* Class to abstract the input (GET PARAMS, POST, etc...) value grabbing
|
||||||
|
* POST always have precedence
|
||||||
|
*/
|
||||||
|
class Request
|
||||||
|
{
|
||||||
|
|
||||||
const PARAM_INT = 'integer';
|
/**
|
||||||
const PARAM_DOUBLE = 'double';
|
* Search a param on the GET/POST array
|
||||||
|
* If the key is not found we throw a `required_param_not_found` Exception
|
||||||
public static function requiredParam($parname, $type, $default = '', $options = Array()){
|
*
|
||||||
// POST has precedence.
|
* @param strig $paramname
|
||||||
|
* @param ParamType $type
|
||||||
|
* @param Array $options
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function requiredParam(
|
||||||
|
string $parname,
|
||||||
|
ParamType $type = ParamType::INT,
|
||||||
|
$options = Array()
|
||||||
|
): mixed {
|
||||||
if (isset($_POST[$parname])) {
|
if (isset($_POST[$parname])) {
|
||||||
$param = $_POST[$parname];
|
$param = $_POST[$parname];
|
||||||
} else if (isset($_GET[$parname])) {
|
} else if (isset($_GET[$parname])) {
|
||||||
$param = $_GET[$parname];
|
$param = $_GET[$parname];
|
||||||
} else {
|
} else {
|
||||||
return $default;
|
throw new \Exception('required_param_not_found');
|
||||||
}
|
}
|
||||||
/*$param = self::filter($type, $param);
|
/*$param = self::filter($type, $param);
|
||||||
|
|
||||||
foreach ($options as $key => $option){
|
foreach ($options as $key => $option){
|
||||||
self::$key($param, $option);
|
self::$key($param, $option);
|
||||||
}*/
|
}*/
|
||||||
return $param;
|
return $param;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function requiredParamArray($parname, $type, $default = '', $options = Array() ){
|
/**
|
||||||
// POST has precedence.
|
* Search a array param on the GET/POST array
|
||||||
|
* If the key is not found, we throw a `required_param_not_found` Exception
|
||||||
|
*
|
||||||
|
* @param strig $paramname
|
||||||
|
* @param ParamType $type
|
||||||
|
* @param Array $options
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function requiredParamArray(
|
||||||
|
string $parname,
|
||||||
|
$options = Array()
|
||||||
|
): mixed {
|
||||||
|
if (isset($_POST[$parname])) {
|
||||||
|
$param = $_POST[$parname];
|
||||||
|
} else if (isset($_GET[$parname])) {
|
||||||
|
$param = $_GET[$parname];
|
||||||
|
} else {
|
||||||
|
throw new \Exception('required_param_not_found');
|
||||||
|
}
|
||||||
|
return $param;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search a array param on the GET/POST array
|
||||||
|
* If the key is not found we return the default value
|
||||||
|
*
|
||||||
|
* If the default $value type is not the same of the $type
|
||||||
|
* Wwe throw a `default_value_type_missmatch` Exception
|
||||||
|
*
|
||||||
|
* @param strig $paramname
|
||||||
|
* @param ParamType $type
|
||||||
|
* @param mixed $default
|
||||||
|
* @param Array $options
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function optionalParam(
|
||||||
|
string $parname,
|
||||||
|
ParamType $type = ParamType::INT,
|
||||||
|
mixed $default = "",
|
||||||
|
$options = Array(),
|
||||||
|
): mixed {
|
||||||
if (isset($_POST[$parname])) {
|
if (isset($_POST[$parname])) {
|
||||||
$param = $_POST[$parname];
|
$param = $_POST[$parname];
|
||||||
} else if (isset($_GET[$parname])) {
|
} else if (isset($_GET[$parname])) {
|
||||||
@@ -39,52 +98,134 @@ class Request{
|
|||||||
return $param;
|
return $param;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function optionalParam($parname, $type, $default = '', $options = Array()){
|
/**
|
||||||
// POST has precedence.
|
* NOT IMPLEMENTED YET
|
||||||
if (isset($_POST[$parname])) {
|
* Search a array param on the GET/POST array
|
||||||
$param = $_POST[$parname];
|
*
|
||||||
} else if (isset($_GET[$parname])) {
|
* @param strig $paramname
|
||||||
$param = $_GET[$parname];
|
* @param Array $default
|
||||||
} else {
|
* @param Array $options
|
||||||
return $default;
|
*
|
||||||
|
* @todo Implement
|
||||||
|
*
|
||||||
|
* @return Array
|
||||||
|
*/
|
||||||
|
public static function optionalParamArray(
|
||||||
|
string $parname,
|
||||||
|
Array $default = Array(),
|
||||||
|
$options = Array()
|
||||||
|
): Array{
|
||||||
|
// Not implemented yet
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to detect if the request came from AJAX/FETCH/POSTMAN
|
||||||
|
* in this cases, we might want to return something else
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function detectAjaxRequest(): bool
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||||
|
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return $param;
|
|
||||||
|
if (
|
||||||
|
isset($_SERVER['CONTENT_TYPE']) &&
|
||||||
|
str_contains(
|
||||||
|
strtolower($_SERVER['CONTENT_TYPE']),
|
||||||
|
'application/json'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detecta ferramentas conhecidas
|
||||||
|
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
|
||||||
|
|
||||||
|
if (
|
||||||
|
str_contains($userAgent, 'postman') ||
|
||||||
|
str_contains($userAgent, 'curl') ||
|
||||||
|
str_contains($userAgent, 'insomnia') ||
|
||||||
|
str_contains($userAgent, 'python') ||
|
||||||
|
str_contains($userAgent, 'java')
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headers comuns de navegadores modernos
|
||||||
|
if (
|
||||||
|
isset($_SERVER['HTTP_SEC_FETCH_SITE']) ||
|
||||||
|
isset($_SERVER['HTTP_SEC_FETCH_MODE']) ||
|
||||||
|
isset($_SERVER['HTTP_REFERER'])
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function optionalParamArray(){
|
/**
|
||||||
|
*
|
||||||
}
|
* @param string $paramname
|
||||||
|
* @param ParamType $type
|
||||||
private static function filter($type, $paramname){
|
* @param bool $cast
|
||||||
|
*
|
||||||
|
* @todo Implement casting
|
||||||
|
* @todo Review this logic, I don'r remember what it does
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
private static function filter(
|
||||||
|
$paramname = "",
|
||||||
|
ParamType $type = ParamType::INT,
|
||||||
|
$cast = true
|
||||||
|
): mixed {
|
||||||
switch ($type){
|
switch ($type){
|
||||||
case 'integer':
|
case ParamType::INT:
|
||||||
if(is_integer($paramname)){
|
if(is_integer($paramname)){
|
||||||
return $paramname;
|
return $paramname;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'double':
|
case ParamType::DOUBLE:
|
||||||
if(is_double($paramname)){
|
if(is_double($paramname)){
|
||||||
return $paramname;
|
return $paramname;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'alpha':
|
case ParamType::ALPHA:
|
||||||
return $paramname;
|
return $paramname;
|
||||||
break;
|
break;
|
||||||
case 'alphanum':
|
case ParamType::ALPHANUM:
|
||||||
return $paramname;
|
return $paramname;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Validations
|
* NOT IMPLEMENTED YET
|
||||||
|
* Check if the numeric value is in a number range
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* From 10 to 35 = inRange($value, "10-35")
|
||||||
|
* From 45 to infinity = inRange($value, "45-")
|
||||||
|
* All numbers below 0 = inRange($value, "-0")
|
||||||
|
*
|
||||||
|
* @todo Not Implemented yet
|
||||||
|
*
|
||||||
|
* @param int|float $value
|
||||||
|
* @param string $range
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private static function minVal(){
|
private static function inRange(
|
||||||
|
int|float $value,
|
||||||
|
string $range
|
||||||
|
): bool {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function maxVal(){
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
+111
-59
@@ -1,42 +1,35 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace RR;
|
namespace RR;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
*
|
* Class to handle the return the content/buffer and properties of a request
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class Response{
|
class Response{
|
||||||
|
|
||||||
private static $_instance;
|
private static $_instance;
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public $_headers = Array();
|
public $_headers = Array();
|
||||||
|
|
||||||
/*
|
public $_body = "";
|
||||||
*
|
|
||||||
*/
|
|
||||||
public $_body = Array();
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public $_code = 200;
|
public $_code = 200;
|
||||||
|
|
||||||
//SINGLETON==============================================
|
//SINGLETON==============================================
|
||||||
|
|
||||||
private function __construct(){
|
private function __construct()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function newObj() : Response {
|
private static function newObj() : Response
|
||||||
|
{
|
||||||
if (!isset( self::$_instance )) {
|
if (!isset( self::$_instance )) {
|
||||||
self::$_instance = new Response();
|
self::$_instance = new Response();
|
||||||
}
|
}
|
||||||
return self::$_instance;
|
return self::$_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getInstance() : Response {
|
public static function getInstance() : Response
|
||||||
|
{
|
||||||
if (!isset(self::$_instance)) {
|
if (!isset(self::$_instance)) {
|
||||||
return self::newObj();
|
return self::newObj();
|
||||||
}
|
}
|
||||||
@@ -46,22 +39,29 @@ class Response{
|
|||||||
//=======================================================
|
//=======================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add a parameter to what would be sent on the PHP header response
|
||||||
*
|
*
|
||||||
* @ctag Response::header($key, $value);
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
*
|
*
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public static function header($key, $value){
|
public static function header(string $key, string $value): Response
|
||||||
$istance = self::getInstance();
|
{
|
||||||
$istance->_headers[$key] = $value;
|
$instance = self::getInstance();
|
||||||
return $istance;
|
$instance->_headers[$key] = $value;
|
||||||
|
return $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add content before the current content buffer
|
||||||
*
|
*
|
||||||
* @ctag Response::bodyPrepend($value);
|
* @param string|null $body
|
||||||
*
|
*
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public static function bodyPrepend($body = null){
|
public static function bodyPrepend(string|null $body = null): Response
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
if (null !== $body) {
|
if (null !== $body) {
|
||||||
$instance->_body = (string) $body . $instance->_body;
|
$instance->_body = (string) $body . $instance->_body;
|
||||||
@@ -71,11 +71,14 @@ class Response{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set or replace the body content buffer
|
||||||
*
|
*
|
||||||
* @ctag Response::body($value);
|
* @param string|null $body
|
||||||
*
|
*
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public static function body($body = null){
|
public static function body(string|null $body = ""): Response
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
if (null !== $body) {
|
if (null !== $body) {
|
||||||
$instance->_body = (string) $body;
|
$instance->_body = (string) $body;
|
||||||
@@ -85,11 +88,14 @@ class Response{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add content on the end of the body buffer
|
||||||
*
|
*
|
||||||
* @ctag Response::bodyAppend($value);
|
* @param string|null $body
|
||||||
*
|
*
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public static function bodyAppend($body = null){
|
public static function bodyAppend(string|null $body = null): Response
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
if (null !== $body) {
|
if (null !== $body) {
|
||||||
$instance->_body .= (string) $body;
|
$instance->_body .= (string) $body;
|
||||||
@@ -98,14 +104,26 @@ class Response{
|
|||||||
return $instance;
|
return $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sendHeaders(){
|
/**
|
||||||
|
* Send the header properties to the browser
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
private function sendHeaders(): Response
|
||||||
|
{
|
||||||
foreach ($this->_headers as $key => $value) {
|
foreach ($this->_headers as $key => $value) {
|
||||||
header($key .': '. $value, true);
|
header($key .': '. $value, true);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sendBody(){
|
/**
|
||||||
|
* Print the body buffer to the browser
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
private function sendBody(): Response
|
||||||
|
{
|
||||||
if(!empty($this->_body)){
|
if(!empty($this->_body)){
|
||||||
echo (string) $this->_body;
|
echo (string) $this->_body;
|
||||||
}
|
}
|
||||||
@@ -114,25 +132,15 @@ class Response{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Formats and print a json object/array with the adequate headers
|
||||||
*
|
*
|
||||||
* @ctag Response::bodySend();
|
* @param mixed $object
|
||||||
|
* @param string|null $jsonPrefix
|
||||||
*
|
*
|
||||||
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public static function send(){
|
public static function json(mixed $object = Array(), string|null $jsonPrefix = null): Response
|
||||||
$instance = self::getInstance();
|
{
|
||||||
$instance->sendHeaders();
|
|
||||||
$instance->sendBody();
|
|
||||||
http_response_code($instance->_code);
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @ctag Response::json($object);
|
|
||||||
* @ctag Response::json($object, $prefix);
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static function json($object, $jsonPrefix = null): Response{
|
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
|
|
||||||
$instance->body('');
|
$instance->body('');
|
||||||
@@ -154,45 +162,89 @@ class Response{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Redirect the request to another URL
|
||||||
*
|
*
|
||||||
* @ctag Response::redirect($url);
|
* @param string $url
|
||||||
* @ctag Response::redirect($url, $code);
|
* @param int $code
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function redirect($url, $code = 303){
|
public static function redirect(string $url, int $code = 303): void
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
|
|
||||||
$instance->_code = $code;
|
$instance->_code = $code;
|
||||||
|
|
||||||
if(is_ajax_request()){
|
if(Request::detectAjaxRequest()){
|
||||||
return $instance->json(['location' => $url])->send();
|
$instance->json(['location' => $url])->send();
|
||||||
|
die;
|
||||||
}
|
}
|
||||||
|
|
||||||
## TODO
|
## TODO - Try to use the header location with the class dispatch method
|
||||||
header("Location: $url");
|
header("Location: $url");
|
||||||
die;
|
die;
|
||||||
|
|
||||||
$instance->header('Location: ', $url)->send();
|
//$instance->header('Location: ', $url)->send();
|
||||||
|
//$instance->send()->done();
|
||||||
return $instance->send()->done();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Try to return to the previos page (HTTP_REFERER)
|
||||||
*
|
*
|
||||||
* @ctag Response::back();
|
* I don't think is working, and might not make sense, return to a post endpoint with GET?
|
||||||
*
|
*
|
||||||
|
* @param int $code
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function back(){
|
public static function back(int $code = 303): void
|
||||||
|
{
|
||||||
$instance = self::getInstance();
|
$instance = self::getInstance();
|
||||||
|
|
||||||
$instance->header('Location: ', $_SERVER['HTTP_REFERER']);
|
$instance->_code = $code;
|
||||||
|
|
||||||
|
if(isset($_SERVER['HTTP_REFERER'])){
|
||||||
|
$instance->header('Location', $_SERVER['HTTP_REFERER']);
|
||||||
|
} else {
|
||||||
|
$instance->header(
|
||||||
|
'Location',
|
||||||
|
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']
|
||||||
|
=== 'on' ? "https" : "http") .
|
||||||
|
"://" . $_SERVER['HTTP_HOST'] .
|
||||||
|
$_SERVER['REQUEST_URI']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$instance->body('');
|
$instance->body('');
|
||||||
$instance->send();
|
$instance->send();
|
||||||
|
die;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function done(){
|
/**
|
||||||
|
* Send all the info stored on the object
|
||||||
|
* - Send headers
|
||||||
|
* - Send body
|
||||||
|
* - Set response code
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public static function send(): Response
|
||||||
|
{
|
||||||
|
$instance = self::getInstance();
|
||||||
|
http_response_code($instance->_code);
|
||||||
|
$instance->sendHeaders();
|
||||||
|
$instance->sendBody();
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kill the current execution.
|
||||||
|
*
|
||||||
|
* After all the content is sent, there is no sense on keep the process
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function done(): void
|
||||||
|
{
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user