diff --git a/.gitignore b/.gitignore
index de025d7..594e91d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@ php-cs-fixer-v2.phar
.idea/*
php-cs-fixer.phar
.php-cs-fixer.cache
+*.Identifier
diff --git a/README.md b/README.md
index 9fdd534..a31cf08 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# WebFiori HTTP
-A simple library for creating RESTful web APIs in adition to providing utilities for handling HTTP request and response.
-It includes inputs feltering and data validation in addion to creating user-defined inputs filters.
+
+A powerful and flexible PHP library for creating RESTful web APIs with built-in input filtering, data validation, and comprehensive HTTP utilities. The library provides a clean, object-oriented approach to building web services with automatic parameter validation, authentication support, and JSON response handling.
+## Table of Contents
+
+- [Supported PHP Versions](#supported-php-versions)
+- [Key Features](#key-features)
+- [Installation](#installation)
+- [Quick Start](#quick-start)
+- [Core Concepts](#core-concepts)
+- [Creating Web Services](#creating-web-services)
+- [Parameter Management](#parameter-management)
+- [Authentication & Authorization](#authentication--authorization)
+- [Request & Response Handling](#request--response-handling)
+- [Advanced Features](#advanced-features)
+- [Testing](#testing)
+- [Examples](#examples)
+- [API Documentation](#api-documentation)
+
## Supported PHP Versions
+
| Build Status |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| |
@@ -28,42 +45,722 @@ It includes inputs feltering and data validation in addion to creating user-defi
| |
| |
-## API Docs
-This library is a part of WebFiori Framework. To access API docs of the library, you can visid the following link: https://webfiori.com/docs/webfiori/http .
+## Key Features
-## Terminology
+- **RESTful API Development**: Full support for creating REST services with JSON request/response handling
+- **Automatic Input Validation**: Built-in parameter validation with support for multiple data types
+- **Custom Filtering**: Ability to create user-defined input filters and validation rules
+- **Authentication Support**: Built-in support for various authentication schemes (Basic, Bearer, etc.)
+- **HTTP Method Support**: Support for all standard HTTP methods (GET, POST, PUT, DELETE, etc.)
+- **Content Type Handling**: Support for `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data`
+- **Object Mapping**: Automatic mapping of request parameters to PHP objects
+- **Comprehensive Testing**: Built-in testing utilities with `APITestCase` class
+- **Error Handling**: Structured error responses with appropriate HTTP status codes
+- **Stream Support**: Custom input/output stream handling for advanced use cases
-Following terminology is used by the library:
-| Term | Definition|
-|:------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
-| Web Service | A single end pont that implements a REST service. It is represented as an instance of the class `AbstractWebService`. |
-| Services Manager | An entity which is used to manage a set of web services. Represented by the class `WebServicesManager`. |
-| Request Parameter | A way to pass values from a client such as a web browser to the server. Represented by the class `RequestParameter`. |
+## Installation
-## The Idea
+### Using Composer (Recommended)
-The idea of the library is as follows, when a client performs a request to a web service, he is usually intersted in performing specific action. Related actions are kept in one place as a set of web services (e.g. CRUD operations on a reasorce). The client can pass arguments (or parameters) to the end point in request body as `POST` or `PUT` request method or as a query string when using `GET` or `DELETE`.
+```bash
+composer require webfiori/http
+```
-An end point is represented by the class [`AbstractWebService`](https://webfiori.com/docs/webfiori/http/AbstractWebService) and a set of web service (or end ponts) are grouped using the class [`WebServicesManager`](https://webfiori.com/docs/webfiori/http/WebServicesManager). Also, body parameters represented by the class [`RequestParameter`](https://webfiori.com/docs/webfiori/http/RequestParameter).
+### Manual Installation
-## Features
-* Full support for creating REST services that supports JSON as request and response.
-* Support for basic data filtering and validation.
-* The ability to create custom filters based on the need.
+Download the latest release from [GitHub Releases](https://github.com/WebFiori/http/releases) and include the autoloader:
-## Installation
-If you are using composer to collect your dependencies, you can simply include the following entry in your 'composer.json' file to get the latest release of the library:
+```php
+require_once 'path/to/webfiori-http/vendor/autoload.php';
+```
+
+## Quick Start
+
+Here's a simple example to get you started:
+
+```php
+setRequestMethods([RequestMethod::GET]);
+
+ $this->addParameters([
+ 'name' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+
+ public function isAuthorized() {
+ // No authentication required
+ return true;
+ }
+
+ public function processRequest() {
+ $name = $this->getParamVal('name');
+
+ if ($name !== null) {
+ $this->sendResponse("Hello, $name!");
+ } else {
+ $this->sendResponse("Hello, World!");
+ }
+ }
+}
+
+// Set up the services manager
+$manager = new WebServicesManager();
+$manager->addService(new HelloService());
+$manager->process();
+```
+
+## Core Concepts
+
+### Terminology
+
+| Term | Definition |
+|:-----|:-----------|
+| **Web Service** | A single endpoint that implements a REST service, represented by `AbstractWebService` |
+| **Services Manager** | An entity that manages multiple web services, represented by `WebServicesManager` |
+| **Request Parameter** | A way to pass values from client to server, represented by `RequestParameter` |
+| **API Filter** | A component that validates and sanitizes request parameters |
+
+### Architecture Overview
+
+The library follows a service-oriented architecture:
+
+1. **AbstractWebService**: Base class for all web services
+2. **WebServicesManager**: Manages multiple services and handles request routing
+3. **RequestParameter**: Defines and validates individual parameters
+4. **APIFilter**: Handles parameter filtering and validation
+5. **Request/Response**: Utilities for handling HTTP requests and responses
+
+## Creating Web Services
+
+### Basic Service Structure
+
+Every web service must extend `AbstractWebService` and implement the `processRequest()` method:
+
+```php
+setRequestMethods([RequestMethod::GET, RequestMethod::POST]);
+ $this->setDescription('A sample web service');
+ }
+
+ public function isAuthorized() {
+ // Implement authorization logic
+ return true;
+ }
+
+ public function processRequest() {
+ // Implement service logic
+ $this->sendResponse('Service executed successfully');
+ }
+}
+```
+
+### Service Configuration
+
+#### Setting Request Methods
+
+```php
+// Single method
+$this->addRequestMethod(RequestMethod::POST);
+
+// Multiple methods
+$this->setRequestMethods([
+ RequestMethod::GET,
+ RequestMethod::POST,
+ RequestMethod::PUT
+]);
+```
+
+#### Service Metadata
+
+```php
+$this->setDescription('Creates a new user profile');
+$this->setSince('1.2.0');
+$this->addResponseDescription('Returns user profile data on success');
+$this->addResponseDescription('Returns error message on failure');
+```
+
+## Parameter Management
-``` json
-{
- "require": {
- "webfiori/http":"*"
+### Parameter Types
+
+The library supports various parameter types through `ParamType`:
+
+```php
+ParamType::STRING // String values
+ParamType::INT // Integer values
+ParamType::DOUBLE // Float/double values
+ParamType::BOOL // Boolean values
+ParamType::EMAIL // Email addresses (validated)
+ParamType::URL // URLs (validated)
+ParamType::ARR // Arrays
+ParamType::JSON_OBJ // JSON objects
+```
+
+### Adding Parameters
+
+#### Simple Parameter Addition
+
+```php
+use WebFiori\Http\RequestParameter;
+
+$param = new RequestParameter('username', ParamType::STRING);
+$this->addParameter($param);
+```
+
+#### Batch Parameter Addition
+
+```php
+$this->addParameters([
+ 'username' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => false
+ ],
+ 'age' => [
+ ParamOption::TYPE => ParamType::INT,
+ ParamOption::OPTIONAL => true,
+ ParamOption::MIN => 18,
+ ParamOption::MAX => 120,
+ ParamOption::DEFAULT => 25
+ ],
+ 'email' => [
+ ParamOption::TYPE => ParamType::EMAIL,
+ ParamOption::OPTIONAL => false
+ ]
+]);
+```
+
+### Parameter Options
+
+Available options through `ParamOption`:
+
+```php
+ParamOption::TYPE // Parameter data type
+ParamOption::OPTIONAL // Whether parameter is optional
+ParamOption::DEFAULT // Default value for optional parameters
+ParamOption::MIN // Minimum value (numeric types)
+ParamOption::MAX // Maximum value (numeric types)
+ParamOption::MIN_LENGTH // Minimum length (string types)
+ParamOption::MAX_LENGTH // Maximum length (string types)
+ParamOption::EMPTY // Allow empty strings
+ParamOption::FILTER // Custom filter function
+ParamOption::DESCRIPTION // Parameter description
+```
+
+### Custom Validation
+
+```php
+$this->addParameters([
+ 'password' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::MIN_LENGTH => 8,
+ ParamOption::FILTER => function($original, $basic) {
+ // Custom validation logic
+ if (strlen($basic) < 8) {
+ return APIFilter::INVALID;
+ }
+ // Additional password strength checks
+ return $basic;
+ }
+ ]
+]);
+```
+
+### Retrieving Parameter Values
+
+```php
+public function processRequest() {
+ $username = $this->getParamVal('username');
+ $age = $this->getParamVal('age');
+ $email = $this->getParamVal('email');
+
+ // Get all inputs as array
+ $allInputs = $this->getInputs();
+}
+```
+
+## Authentication & Authorization
+
+### Basic Authentication Implementation
+
+```php
+public function isAuthorized() {
+ $authHeader = $this->getAuthHeader();
+
+ if ($authHeader === null) {
+ return false;
}
+
+ $scheme = $authHeader->getScheme();
+ $credentials = $authHeader->getCredentials();
+
+ if ($scheme === 'basic') {
+ // Decode base64 credentials
+ $decoded = base64_decode($credentials);
+ list($username, $password) = explode(':', $decoded);
+
+ // Validate credentials
+ return $this->validateUser($username, $password);
+ }
+
+ return false;
+}
+```
+
+### Bearer Token Authentication
+
+```php
+public function isAuthorized() {
+ $authHeader = $this->getAuthHeader();
+
+ if ($authHeader === null) {
+ return false;
+ }
+
+ if ($authHeader->getScheme() === 'bearer') {
+ $token = $authHeader->getCredentials();
+ return $this->validateToken($token);
+ }
+
+ return false;
+}
+```
+
+### Skipping Authentication
+
+```php
+public function __construct() {
+ parent::__construct('public-service');
+ $this->setIsAuthRequired(false); // Skip authentication
}
```
-Note that the WebFiori Json library will be included with the installation files as this library is depending on it.
-Another option is to download the latest release manually from Release.
+### Custom Error Messages
+
+```php
+use WebFiori\Http\ResponseMessage;
+
+public function isAuthorized() {
+ ResponseMessage::set('401', 'Custom unauthorized message');
+
+ // Your authorization logic
+ return false;
+}
+```
+
+## Request & Response Handling
+
+### Sending JSON Responses
+
+```php
+// Simple message response
+$this->sendResponse('Operation completed successfully');
+
+// Response with type and status code
+$this->sendResponse('User created', 'success', 201);
+
+// Response with additional data
+$userData = ['id' => 123, 'name' => 'John Doe'];
+$this->sendResponse('User retrieved', 'success', 200, $userData);
+```
+
+### Custom Content Type Responses
+
+```php
+// Send XML response
+$xmlData = '123John Doe';
+$this->send('application/xml', $xmlData, 200);
+
+// Send plain text
+$this->send('text/plain', 'Hello, World!', 200);
+
+// Send file download
+$this->send('application/octet-stream', $fileContent, 200);
+```
+
+### Handling Different Request Methods
+
+```php
+public function processRequest() {
+ $method = $this->getManager()->getRequestMethod();
+
+ switch ($method) {
+ case RequestMethod::GET:
+ $this->handleGet();
+ break;
+ case RequestMethod::POST:
+ $this->handlePost();
+ break;
+ case RequestMethod::PUT:
+ $this->handlePut();
+ break;
+ case RequestMethod::DELETE:
+ $this->handleDelete();
+ break;
+ }
+}
+```
+
+### JSON Request Handling
+
+The library automatically handles JSON requests when `Content-Type: application/json`:
+
+```php
+public function processRequest() {
+ $inputs = $this->getInputs();
+
+ if ($inputs instanceof \WebFiori\Json\Json) {
+ // Handle JSON input
+ $name = $inputs->get('name');
+ $email = $inputs->get('email');
+ } else {
+ // Handle form data
+ $name = $inputs['name'] ?? null;
+ $email = $inputs['email'] ?? null;
+ }
+}
+```
+
+## Advanced Features
+
+### Object Mapping
+
+Automatically map request parameters to PHP objects:
+
+```php
+class User {
+ private $name;
+ private $email;
+ private $age;
+
+ public function setName($name) { $this->name = $name; }
+ public function setEmail($email) { $this->email = $email; }
+ public function setAge($age) { $this->age = $age; }
+
+ // Getters...
+}
+
+public function processRequest() {
+ // Automatic mapping
+ $user = $this->getObject(User::class);
+
+ // Custom setter mapping
+ $user = $this->getObject(User::class, [
+ 'full-name' => 'setName',
+ 'email-address' => 'setEmail'
+ ]);
+}
+```
+
+### Services Manager Configuration
+
+```php
+$manager = new WebServicesManager();
+
+// Set API version and description
+$manager->setVersion('2.1.0');
+$manager->setDescription('User Management API');
+
+// Add multiple services
+$manager->addService(new CreateUserService());
+$manager->addService(new GetUserService());
+$manager->addService(new UpdateUserService());
+$manager->addService(new DeleteUserService());
+
+// Custom input/output streams
+$manager->setInputStream('php://input');
+$manager->setOutputStream(fopen('api-log.txt', 'a'));
+
+// Process requests
+$manager->process();
+```
+
+### Error Handling
+
+```php
+public function processRequest() {
+ try {
+ // Service logic
+ $result = $this->performOperation();
+ $this->sendResponse('Success', 'success', 200, $result);
+ } catch (ValidationException $e) {
+ $this->sendResponse($e->getMessage(), 'error', 400);
+ } catch (AuthenticationException $e) {
+ $this->sendResponse('Unauthorized', 'error', 401);
+ } catch (Exception $e) {
+ $this->sendResponse('Internal server error', 'error', 500);
+ }
+}
+```
+
+### Custom Filters
+
+```php
+use WebFiori\Http\APIFilter;
+
+$customFilter = function($original, $filtered) {
+ // Custom validation logic
+ if (strlen($filtered) < 3) {
+ return APIFilter::INVALID;
+ }
+
+ // Additional processing
+ return strtoupper($filtered);
+};
+
+$this->addParameters([
+ 'code' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::FILTER => $customFilter
+ ]
+]);
+```
+
+## Testing
+
+### Using APITestCase
+
+```php
+addService(new MyService());
+
+ $response = $this->getRequest($manager, 'my-service', [
+ 'param1' => 'value1',
+ 'param2' => 'value2'
+ ]);
+
+ $this->assertJson($response);
+ $this->assertContains('success', $response);
+ }
+
+ public function testPostRequest() {
+ $manager = new WebServicesManager();
+ $manager->addService(new MyService());
+
+ $response = $this->postRequest($manager, 'my-service', [
+ 'name' => 'John Doe',
+ 'email' => 'john@example.com'
+ ]);
+
+ $this->assertJson($response);
+ }
+}
+```
+
+### Manual Testing
+
+```php
+// Set up test environment
+$_GET['service'] = 'my-service';
+$_GET['param1'] = 'test-value';
+$_SERVER['REQUEST_METHOD'] = 'GET';
+
+$manager = new WebServicesManager();
+$manager->addService(new MyService());
+$manager->process();
+```
+
+## Examples
+
+### Complete CRUD Service Example
+
+```php
+setRequestMethods([
+ RequestMethod::GET,
+ RequestMethod::POST,
+ RequestMethod::PUT,
+ RequestMethod::DELETE
+ ]);
+
+ $this->addParameters([
+ 'id' => [
+ ParamOption::TYPE => ParamType::INT,
+ ParamOption::OPTIONAL => true
+ ],
+ 'name' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true,
+ ParamOption::MIN_LENGTH => 2
+ ],
+ 'email' => [
+ ParamOption::TYPE => ParamType::EMAIL,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+
+ public function isAuthorized() {
+ return true; // Implement your auth logic
+ }
+
+ public function processRequest() {
+ $method = $this->getManager()->getRequestMethod();
+
+ switch ($method) {
+ case RequestMethod::GET:
+ $this->getUser();
+ break;
+ case RequestMethod::POST:
+ $this->createUser();
+ break;
+ case RequestMethod::PUT:
+ $this->updateUser();
+ break;
+ case RequestMethod::DELETE:
+ $this->deleteUser();
+ break;
+ }
+ }
+
+ private function getUser() {
+ $id = $this->getParamVal('id');
+
+ if ($id) {
+ // Get specific user
+ $user = $this->findUserById($id);
+ $this->sendResponse('User found', 'success', 200, $user);
+ } else {
+ // Get all users
+ $users = $this->getAllUsers();
+ $this->sendResponse('Users retrieved', 'success', 200, $users);
+ }
+ }
+
+ private function createUser() {
+ $name = $this->getParamVal('name');
+ $email = $this->getParamVal('email');
+
+ $user = $this->createNewUser($name, $email);
+ $this->sendResponse('User created', 'success', 201, $user);
+ }
+
+ private function updateUser() {
+ $id = $this->getParamVal('id');
+ $name = $this->getParamVal('name');
+ $email = $this->getParamVal('email');
+
+ $user = $this->updateExistingUser($id, $name, $email);
+ $this->sendResponse('User updated', 'success', 200, $user);
+ }
+
+ private function deleteUser() {
+ $id = $this->getParamVal('id');
+
+ $this->removeUser($id);
+ $this->sendResponse('User deleted', 'success', 200);
+ }
+}
+```
+
+### File Upload Service
+
+```php
+setRequestMethods([RequestMethod::POST]);
+
+ $this->addParameters([
+ 'file' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => false
+ ],
+ 'description' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+
+ public function isAuthorized() {
+ return true;
+ }
+
+ public function processRequest() {
+ if (isset($_FILES['file'])) {
+ $file = $_FILES['file'];
+
+ if ($file['error'] === UPLOAD_ERR_OK) {
+ $uploadPath = 'uploads/' . basename($file['name']);
+
+ if (move_uploaded_file($file['tmp_name'], $uploadPath)) {
+ $this->sendResponse('File uploaded successfully', 'success', 200, [
+ 'filename' => $file['name'],
+ 'size' => $file['size'],
+ 'path' => $uploadPath
+ ]);
+ } else {
+ $this->sendResponse('Failed to move uploaded file', 'error', 500);
+ }
+ } else {
+ $this->sendResponse('File upload error', 'error', 400);
+ }
+ } else {
+ $this->sendResponse('No file uploaded', 'error', 400);
+ }
+ }
+}
+```
+
+For more examples, check the [examples](examples/) directory in this repository.
+
+## API Documentation
+
+This library is part of the WebFiori Framework. For complete API documentation, visit: https://webfiori.com/docs/webfiori/http
+
+### Key Classes Documentation
+
+- [`AbstractWebService`](https://webfiori.com/docs/webfiori/http/AbstractWebService) - Base class for web services
+- [`WebServicesManager`](https://webfiori.com/docs/webfiori/http/WebServicesManager) - Services management
+- [`RequestParameter`](https://webfiori.com/docs/webfiori/http/RequestParameter) - Parameter definition and validation
+- [`APIFilter`](https://webfiori.com/docs/webfiori/http/APIFilter) - Input filtering and validation
+- [`Request`](https://webfiori.com/docs/webfiori/http/Request) - HTTP request utilities
+- [`Response`](https://webfiori.com/docs/webfiori/http/Response) - HTTP response utilities
+
+## Contributing
+
+Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
+
+## License
+
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+
+## Support
+
+- **Issues**: [GitHub Issues](https://github.com/WebFiori/http/issues)
+- **Documentation**: [WebFiori Docs](https://webfiori.com/docs/webfiori/http)
+- **Examples**: [Examples Directory](examples/)
+
+## Changelog
-## Usage
-For more information on how to use the library, [check here](https://github.com/WebFiori/wf-docs/blob/main/web-services.md)
+See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.
diff --git a/webfiori/http/APIFilter.php b/WebFiori/Http/APIFilter.php
similarity index 98%
rename from webfiori/http/APIFilter.php
rename to WebFiori/Http/APIFilter.php
index 1b6bbc6..67e63f0 100644
--- a/webfiori/http/APIFilter.php
+++ b/WebFiori/Http/APIFilter.php
@@ -7,10 +7,10 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use Exception;
-use webfiori\json\Json;
+use WebFiori\Json\Json;
/**
* A class used to validate and sanitize request parameters.
*
@@ -19,7 +19,6 @@
*
* @author Ibrahim
*
- * @version 1.2.3
*/
class APIFilter {
/**
@@ -27,7 +26,6 @@ class APIFilter {
*
* @var string A string that indicates a given value is invalid.
*
- * @since 1.2.2
*/
const INVALID = 'INV';
@@ -36,16 +34,19 @@ class APIFilter {
*
* @var array
*
- * @since 1.0
*/
private $inputs = [];
+ /**
+ * The path to the input stream.
+ *
+ * @var string
+ */
private $inputStreamPath;
/**
* The non-filtered data (original).
*
* @var mixed
*
- * @since 1.2
*/
private $nonFilteredInputs;
/**
@@ -53,7 +54,6 @@ class APIFilter {
*
* @var array
*
- * @since 1.0
*/
private $paramDefs = [];
/**
@@ -61,7 +61,6 @@ class APIFilter {
*
* @param RequestParameter $reqParam The request parameter that will be added.
*
- * @since 1.1
*/
public function addRequestParameter(RequestParameter $reqParam) {
$paramIdx = 'parameter';
@@ -108,7 +107,6 @@ public function addRequestParameter(RequestParameter $reqParam) {
/**
* Clears the arrays that are used to store filtered and not-filtered variables.
*
- * @since 1.2.2
*/
public function clearInputs() {
$this->inputs = [];
@@ -117,7 +115,6 @@ public function clearInputs() {
/**
* Clears filter parameters.
*
- * @since 1.1
*/
public function clearParametersDef() {
$this->paramDefs = [];
@@ -148,7 +145,6 @@ public function clearParametersDef() {
* has all values filtered. The index which has the key 'non-filtered'
* will contain the original values.
*
- * @since 1.2.2
*/
public static function filter(APIFilter $apiFilter, array $arr): array {
$filteredIdx = 'filtered';
@@ -226,7 +222,6 @@ private static function decodeArray(array $array) {
*
*
*
- * @since 1.0
*/
public final function filterGET() {
$this->clearInputs();
@@ -254,7 +249,6 @@ public final function filterGET() {
*
*
* @throws Exception
- * @since 1.0
*/
public final function filterPOST() {
$this->clearInputs();
@@ -279,7 +273,6 @@ public final function filterPOST() {
*
* @return array An array that contains filter constraints.
*
- * @since 1.2.2
*/
public function getFilterDef() : array {
return $this->paramDefs;
@@ -297,7 +290,6 @@ public function getFilterDef() : array {
* 'application/json', the method will return an instance of the class
* 'Json' that has all JSON information.
*
- * @since 1.0
*/
public function getInputs() {
return $this->inputs;
@@ -307,7 +299,6 @@ public function getInputs() {
*
* @return string|null
*
- * @since 1.2.3
*/
public function getInputStreamPath() {
return $this->inputStreamPath;
@@ -320,7 +311,6 @@ public function getInputStreamPath() {
* type is 'application/json', the method will return an object of type
* 'Json'.
*
- * @since 1.2
*/
public final function getNonFiltered() {
return $this->nonFilteredInputs;
@@ -337,7 +327,6 @@ public final function getNonFiltered() {
* @return bool If input stream is successfully set, the method will
* return true. False otherwise.
*
- * @since 1.2.3
*/
public function setInputStream($pathOrResource) : bool {
if (is_resource($pathOrResource)) {
@@ -571,7 +560,6 @@ private function cleanJsonStr($extraClean, $def, $toBeFiltered) {
* which contains the values is returned. If it has invalid syntax, the
* method will return the string 'APIFilter::INVALID'.
*
- * @since 1.2.1
*/
private static function filterArray($arr) {
if (gettype($arr) == 'array') {
@@ -672,7 +660,6 @@ private static function filterArray($arr) {
*
* @return bool|string
*
- * @since 1.1
*/
private static function filterBoolean($boolean) {
if (gettype($boolean) == 'boolean') {
@@ -911,7 +898,6 @@ private function parseJsonBody() {
* @param string $stringEndChar
* @return array
*
- * @since 1.2.1
*/
private static function parseStringFromArray(string $stringAsArr,int $start,int $len, string $stringEndChar) : array {
$retVal = [
diff --git a/webfiori/http/APITestCase.php b/WebFiori/Http/APITestCase.php
similarity index 98%
rename from webfiori/http/APITestCase.php
rename to WebFiori/Http/APITestCase.php
index 5e5f2f4..77bcfc5 100644
--- a/webfiori/http/APITestCase.php
+++ b/WebFiori/Http/APITestCase.php
@@ -7,11 +7,11 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use PHPUnit\Framework\TestCase;
-use webfiori\json\Json;
-use webfiori\json\JsonException;
+use WebFiori\Json\Json;
+use WebFiori\Json\JsonException;
/**
* A helper class which is used to implement test cases for API calls.
*
@@ -24,6 +24,11 @@
class APITestCase extends TestCase {
const NL = "\r\n";
const DEFAULT_OUTPUT_STREAM = __DIR__.DIRECTORY_SEPARATOR.'outputStream.txt';
+ /**
+ * The path to the output stream file.
+ *
+ * @var string
+ */
private $outputStreamPath;
/**
* Sets the path to the file which is used to store API output temporarily.
diff --git a/webfiori/http/AbstractWebService.php b/WebFiori/Http/AbstractWebService.php
similarity index 97%
rename from webfiori/http/AbstractWebService.php
rename to WebFiori/Http/AbstractWebService.php
index 3529966..25eae1f 100644
--- a/webfiori/http/AbstractWebService.php
+++ b/WebFiori/Http/AbstractWebService.php
@@ -7,10 +7,10 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
-use webfiori\json\Json;
-use webfiori\json\JsonI;
+use WebFiori\Json\Json;
+use WebFiori\Json\JsonI;
/**
* A class that represents one web service.
*
@@ -21,23 +21,19 @@
*
* @author Ibrahim
*
- * @version 1.0.3
*
- * @since 1.5.0
*/
abstract class AbstractWebService implements JsonI {
/**
* A constant which is used to indicate that the message that will be
* sent is of type error.
*
- * @since 1.0.2
*/
const E = 'error';
/**
* A constant which is used to indicate that the message that will be
* sent is of type info.
*
- * @since 1.0.2
*/
const I = 'info';
@@ -46,7 +42,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var string
*
- * @since 1.0
*/
private $name;
/**
@@ -54,7 +49,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var WebServicesManager
*
- * @since 1.0.1
*/
private $owner;
/**
@@ -62,7 +56,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var array
*
- * @since 1.0
*/
private $parameters;
/**
@@ -70,7 +63,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var array
*
- * @since 1.0
*/
private $reqMethods;
/**
@@ -79,7 +71,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var bool
*
- * @since 1.0.1
*/
private $requireAuth;
/**
@@ -88,7 +79,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var array
*
- * @since 1.0
*/
private $responses;
/**
@@ -96,7 +86,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var string
*
- * @since 1.0
*/
private $serviceDesc;
/**
@@ -105,7 +94,6 @@ abstract class AbstractWebService implements JsonI {
*
* @var string
*
- * @since 1.0
*/
private $sinceVersion;
/**
@@ -146,7 +134,6 @@ public function __construct(string $name) {
* @return array An array that contains all possible requests methods at which the
* service can be called using.
*
- * @since 1.0
*/
public function &getRequestMethods() : array {
return $this->reqMethods;
@@ -156,7 +143,6 @@ public function &getRequestMethods() : array {
*
* @return array an array that contains an objects of type RequestParameter.
*
- * @since 1.0
*/
public final function &getParameters() : array {
return $this->parameters;
@@ -165,7 +151,6 @@ public final function &getParameters() : array {
*
* @return string
*
- * @since 1.0
*/
public function __toString() {
$retVal = "APIAction[\n";
@@ -257,7 +242,6 @@ public function __toString() {
* return true. If it was not added for any reason, the method will return
* false.
*
- * @since 1.0
*/
public function addParameter($param) : bool {
if (gettype($param) == 'array') {
@@ -280,7 +264,6 @@ public function addParameter($param) : bool {
* then the key will represent the name of the web service and the value of the
* key should be a sub-associative array that holds parameter options.
*
- * @since 1.0.3
*/
public function addParameters(array $params) {
foreach ($params as $paramIndex => $param) {
@@ -305,7 +288,6 @@ public function addParameters(array $params) {
* request method is already added or the method is unknown, the method
* will return false.
*
- * @since 1.0
*/
public final function addRequestMethod(string $method) : bool {
$uMethod = strtoupper(trim($method));
@@ -327,7 +309,6 @@ public final function addRequestMethod(string $method) : bool {
* @param string $description A paragraph that describes one of
* the possible responses due to calling the service.
*
- * @since 1.0
*/
public final function addResponseDescription(string $description) {
$trimmed = trim($description);
@@ -355,7 +336,6 @@ public function getAuthHeader() {
*
* @return string The description of the service. Default is empty string.
*
- * @since 1.0
*/
public final function getDescription() : string {
return $this->serviceDesc;
@@ -375,7 +355,6 @@ public final function getDescription() : string {
* be an object of type 'Json' if request content type was 'application/json'.
* If no manager was associated with the service, the method will return null.
*
- * @since 1.0.1
*/
public function getInputs() {
$manager = $this->getManager();
@@ -400,7 +379,6 @@ public function getManager() {
*
* @return string The name of the service.
*
- * @since 1.0
*/
public final function getName() : string {
return $this->name;
@@ -440,7 +418,6 @@ public function getObject(string $clazz, array $settersMap = []) {
* @return RequestParameter|null Returns an objects of type RequestParameter if
* a parameter with the given name was found. null if nothing is found.
*
- * @since 1.0
*/
public final function getParameterByName(string $paramName) {
$trimmed = trim($paramName);
@@ -466,7 +443,6 @@ public final function getParameterByName(string $paramName) {
* For optional parameters, if a default value is set for it, the method will
* return that value.
*
- * @since 1.0.1
*/
public function getParamVal(string $paramName) {
$inputs = $this->getInputs();
@@ -490,7 +466,6 @@ public function getParamVal(string $paramName) {
*
* @return array An array that contains information about possible responses.
*
- * @since 1.0
*/
public final function getResponsesDescriptions() : array {
return $this->responses;
@@ -504,7 +479,6 @@ public final function getResponsesDescriptions() : array {
* @return string The version number at which the service was added to the API.
* Default is '1.0.0'.
*
- * @since 1.0
*/
public final function getSince() : string {
return $this->sinceVersion;
@@ -521,7 +495,6 @@ public final function getSince() : string {
* to the service, the method will return true. Otherwise, the method will return
* false.
*
- * @since 1.0
*/
public function hasParameter(string $name) : bool {
$trimmed = trim($name);
@@ -546,7 +519,6 @@ public function hasParameter(string $name) : bool {
* user is authorized to call the API. If WebFiori framework is used, it is
* possible to perform the functionality of this method using middleware.
*
- * @since 1.0.1
*/
public function isAuthorized() {
}
@@ -559,7 +531,6 @@ public function isAuthorized() {
* @return bool The method will return true if authorization step required.
* False if the authorization step will be skipped. Default return value is true.
*
- * @since 1.0.1
*/
public function isAuthRequired() : bool {
return $this->requireAuth;
@@ -596,7 +567,6 @@ public static function isValidName(string $name): bool {
* This method must be implemented in a way it sends back a response after
* processing the request.
*
- * @since 1.0.1
*/
abstract function processRequest();
/**
@@ -609,7 +579,6 @@ abstract function processRequest();
* that represents the removed parameter. If nothing is removed, the
* method will return null.
*
- * @since 1.0
*/
public function removeParameter(string $paramName) {
$trimmed = trim($paramName);
@@ -647,7 +616,6 @@ public function removeParameter(string $paramName) {
* @return bool If the given request method is remove, the method will
* return true. Other than that, the method will return true.
*
- * @since 1.0
*/
public function removeRequestMethod(string $method): bool {
$uMethod = strtoupper(trim($method));
@@ -686,7 +654,6 @@ public function removeRequestMethod(string $method): bool {
* @param int $code HTTP response code that will be used to send the data.
* Default is HTTP code 200 - Ok.
*
- * @since 1.0.1
*/
public function send(string $contentType, $data, int $code = 200) {
$manager = $this->getManager();
@@ -722,7 +689,6 @@ public function send(string $contentType, $data, int $code = 200) {
* string, an object... . If null is given, the parameter 'more-info'
* will be not included in response. Default is empty string. Default is null.
*
- * @since 1.0.1
*/
public function sendResponse(string $message, string $type = '', int $code = 200, mixed $otherInfo = '') {
$manager = $this->getManager();
@@ -738,7 +704,6 @@ public function sendResponse(string $message, string $type = '', int $code = 200
*
* @param string $desc Action description.
*
- * @since 1.0
*/
public final function setDescription(string $desc) {
$this->serviceDesc = trim($desc);
@@ -752,7 +717,6 @@ public final function setDescription(string $desc) {
* @param bool $bool True to make authorization step required. False to
* skip the authorization step.
*
- * @since 1.0.1
*/
public function setIsAuthRequired(bool $bool) {
$this->requireAuth = $bool;
@@ -791,7 +755,6 @@ public function setManager(?WebServicesManager $manager) {
* true once the name is set. false is returned if the given
* name is invalid.
*
- * @since 1.0
*/
public final function setName(string $name) : bool {
if (self::isValidName($name)) {
@@ -820,7 +783,6 @@ public function setRequestMethods(array $methods) {
*
* @param string $sinceAPIv The version number at which the service was added to the API.
*
- * @since 1.0
*/
public final function setSince(string $sinceAPIv) {
$this->sinceVersion = $sinceAPIv;
@@ -843,7 +805,6 @@ public final function setSince(string $sinceAPIv) {
*
* @return Json an object of type Json.
*
- * @since 1.0
*/
public function toJSON() : Json {
$json = new Json();
diff --git a/webfiori/http/AuthHeader.php b/WebFiori/Http/AuthHeader.php
similarity index 86%
rename from webfiori/http/AuthHeader.php
rename to WebFiori/Http/AuthHeader.php
index 7cf979f..a0b4aab 100644
--- a/webfiori/http/AuthHeader.php
+++ b/WebFiori/Http/AuthHeader.php
@@ -1,7 +1,7 @@
getHeaderAsObj($name);
diff --git a/webfiori/http/HttpCookie.php b/WebFiori/Http/HttpCookie.php
similarity index 96%
rename from webfiori/http/HttpCookie.php
rename to WebFiori/Http/HttpCookie.php
index dfc84ca..babfff0 100644
--- a/webfiori/http/HttpCookie.php
+++ b/WebFiori/Http/HttpCookie.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
/**
* A class which is used to represent Http cookies.
@@ -23,20 +23,37 @@ class HttpCookie {
'Strict',
'None'
];
+ /**
+ * The name of the cookie.
+ *
+ * @var string
+ */
private $cookieName;
private $domain;
+ /**
+ * The domain of the cookie.
+ *
+ * @var string
+ */
private $expires;
private $httpOnly;
+ /**
+ * The expiration time of the cookie.
+ *
+ * @var int
+ */
private $path;
private $sameSite;
+ /**
+ * A boolean value that indicates if the cookie is HTTP only.
+ *
+ * @var bool
+ */
private $secure;
private $val;
/**
* Creates new instance of the class with default properties.
- *
* A newly created cookie will have the following properties by default:
- *
- *
name: new-cookie
*
path: /
*
secure: true
*
http only: true
diff --git a/webfiori/http/HttpHeader.php b/WebFiori/Http/HttpHeader.php
similarity index 94%
rename from webfiori/http/HttpHeader.php
rename to WebFiori/Http/HttpHeader.php
index d4f0207..58dccaf 100644
--- a/webfiori/http/HttpHeader.php
+++ b/WebFiori/Http/HttpHeader.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
/**
* A class that represents HTTP request or response header.
@@ -18,8 +18,18 @@
* @author Ibrahim
*/
class HttpHeader {
+ /**
+ * The name of the HTTP header.
+ *
+ * @var string
+ */
private $headerName;
private $headerValue;
+ /**
+ * The value of the HTTP header.
+ *
+ * @var string
+ */
/**
* Creates new instance of the class.
*
diff --git a/webfiori/http/ManagerInfoService.php b/WebFiori/Http/ManagerInfoService.php
similarity index 96%
rename from webfiori/http/ManagerInfoService.php
rename to WebFiori/Http/ManagerInfoService.php
index f0ba60c..44c98d6 100644
--- a/webfiori/http/ManagerInfoService.php
+++ b/WebFiori/Http/ManagerInfoService.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
/**
* A service which can be used to display information about services manager.
@@ -17,13 +17,11 @@
*
* @author Ibrahim
*
- * @version 1.0
*/
abstract class ManagerInfoService extends AbstractWebService {
/**
* Creates new instance of the class.
*
- * @since 1.0
*/
public function __construct() {
parent::__construct('api-info');
diff --git a/webfiori/http/ObjectMapper.php b/WebFiori/Http/ObjectMapper.php
similarity index 95%
rename from webfiori/http/ObjectMapper.php
rename to WebFiori/Http/ObjectMapper.php
index 23fdc09..4f69c7e 100644
--- a/webfiori/http/ObjectMapper.php
+++ b/WebFiori/Http/ObjectMapper.php
@@ -8,11 +8,11 @@
* https://github.com/WebFiori/.github/blob/main/LICENSE
*
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use Exception;
use Throwable;
-use webfiori\json\Json;
+use WebFiori\Json\Json;
/**
* A class which is used to map API parameters to PHP class object.
@@ -20,8 +20,18 @@
* @author Ibrahim
*/
class ObjectMapper {
+ /**
+ * The name of the class to map to.
+ *
+ * @var string
+ */
private $clazzName;
private $settersMap;
+ /**
+ * An array that maps parameter names to setter methods.
+ *
+ * @var array
+ */
/**
* Creates new instance of the class.
diff --git a/webfiori/http/ParamOption.php b/WebFiori/Http/ParamOption.php
similarity index 98%
rename from webfiori/http/ParamOption.php
rename to WebFiori/Http/ParamOption.php
index a9609c2..e27529f 100644
--- a/webfiori/http/ParamOption.php
+++ b/WebFiori/Http/ParamOption.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
/**
* A class which holds the names of allowed options in request parameter.
diff --git a/webfiori/http/ParamType.php b/WebFiori/Http/ParamType.php
similarity index 91%
rename from webfiori/http/ParamType.php
rename to WebFiori/Http/ParamType.php
index 5a44a2d..2b4e684 100644
--- a/webfiori/http/ParamType.php
+++ b/WebFiori/Http/ParamType.php
@@ -7,64 +7,54 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
/**
* A class that contains constants for representing request parameters types.
*
* @author Ibrahim
*
- * @version 1.0
*
- * @since 1.5.2
*/
class ParamType {
/**
* A constant to indicate that a parameter is of type array.
*
- * @since 1.0
*/
const ARR = 'array';
/**
* A constant to indicate that a parameter is of type boolean.
*
- * @since 1.0
*/
const BOOL = 'boolean';
/**
* A constant to indicate that a parameter is of type float or double.
*
- * @since 1.0
*/
const DOUBLE = 'double';
/**
* A constant to indicate that a parameter is of type email.
*
- * @since 1.0
*/
const EMAIL = 'email';
/**
* A constant to indicate that a parameter is of type integer.
*
- * @since 1.0
*/
const INT = 'integer';
/**
* A constant to indicate that a parameter is of type JSON object.
*
- * @since 1.0
*/
const JSON_OBJ = 'json-obj';
/**
* A constant to indicate that a parameter is of type string.
*
- * @since 1.0
*/
const STRING = 'string';
/**
* A constant to indicate that a parameter is of type url.
*
- * @since 1.0
*/
const URL = 'url';
/**
@@ -99,7 +89,6 @@ public static function getStringTypes() : array {
*
* @return array An array that contains all supported parameters types.
*
- * @since 1.0
*/
public static function getTypes() : array {
return [
diff --git a/webfiori/http/Request.php b/WebFiori/Http/Request.php
similarity index 97%
rename from webfiori/http/Request.php
rename to WebFiori/Http/Request.php
index cfd207a..9b56778 100644
--- a/webfiori/http/Request.php
+++ b/WebFiori/Http/Request.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use InvalidArgumentException;
@@ -17,7 +17,6 @@
* request. Note that it does not comply with PSR-7 in all aspects.
* @author Ibrahim
*
- * @version 1.0.1
*/
class Request {
/**
@@ -38,7 +37,6 @@ class Request {
*
* @var array An array that contains the names of request methods.
*
- * @since 1.0
*/
const METHODS = [
'GET',
@@ -55,14 +53,12 @@ class Request {
*
* @var HeadersPool
*
- * @since 1.0
*/
private $headersPool;
/**
*
* @var Response
*
- * @since 1.0
*/
private static $inst;
@@ -74,7 +70,6 @@ private function __construct() {
*
* @return Request
*
- * @since 1.0
*/
public static function get() {
if (self::$inst === null) {
@@ -110,7 +105,6 @@ public static function getAuthHeader() {
* The value is taken from the array $_SERVER at index 'REMOTE_ADDR'.
* If the IP address is invalid, empty string is returned.
*
- * @since 1.0
*/
public static function getClientIP() : string {
if (!isset($_SERVER['REMOTE_ADDR'])) {
@@ -129,7 +123,6 @@ public static function getClientIP() : string {
*
* @return string|null The value of the header 'content-type' in the request.
*
- * @since 1.0
*/
public static function getContentType() {
$c = isset($_SERVER['CONTENT_TYPE']) ? filter_var($_SERVER['CONTENT_TYPE']) : null;
@@ -166,10 +159,9 @@ public static function getHeader(string $name) : array {
* @return array An array of request headers. Each header is represented
* as an object of type HttpHeader.
*
- * @since 1.0
*/
public static function getHeaders() : array {
- if (defined('__PHPUNIT_PHAR__') || self::get()->headersPool === null || http_response_code() === false) {
+ if (defined('__PHPUNIT_PHAR__') || self::get()->headersPool->getHeaders() == [] || http_response_code() === false) {
//Always Refresh headers if in testing environment.
self::extractHeaders();
}
@@ -213,7 +205,6 @@ public static function getHeadersPool() : HeadersPool {
* in CLI environment to something like 'POST' for testing, use the
* function putenv('REQUEST_METHOD=POST').
*
- * @since 1.0
*/
public static function getMethod() : string {
$meth = getenv('REQUEST_METHOD');
@@ -243,7 +234,6 @@ public static function getMethod() : string {
* @return string|null The method will return the value of the parameter if
* set as a string. Other than that, the method will return null.
*
- * @since 1.0.1
*/
public static function getParam(string $paramName) {
$trimmed = trim($paramName);
@@ -343,7 +333,6 @@ private static function getPathHelper(string $header) {
* @return string The URI of the requested resource
* (e.g. http://example.com/get-random?range=[1,100]).
*
- * @since 1.0
*/
public static function getRequestedURI(string $pathToAppend = '') : string {
$base = Uri::getBaseURL();
@@ -378,7 +367,6 @@ public static function getRequestedURI(string $pathToAppend = '') : string {
*
* @return Uri an object that holds all information about requested URI.
*
- * @since 1.0
*/
public static function getUri() : Uri {
return new Uri(self::getRequestedURI());
diff --git a/webfiori/http/RequestMethod.php b/WebFiori/Http/RequestMethod.php
similarity index 98%
rename from webfiori/http/RequestMethod.php
rename to WebFiori/Http/RequestMethod.php
index 281dbb6..98c701a 100644
--- a/webfiori/http/RequestMethod.php
+++ b/WebFiori/Http/RequestMethod.php
@@ -1,5 +1,5 @@
* If any of the values is null, the value will be shown as 'null'.
*
- * @since 1.2.2
*/
public function __toString() {
$retVal = "RequestParameter[\n";
@@ -236,7 +224,6 @@ public function __toString() {
* the method will return an object of type 'RequestParameter'.
* If it was not created for any reason, the method will return null.
*
- * @since 1.2.3
*/
public static function create(array $options) {
if (isset($options['name'])) {
@@ -256,7 +243,6 @@ public static function create(array $options) {
* @return callback|null The function that is used as a custom filter
* for the parameter. If not set, the method will return null.
*
- * @since 1.2
*/
public function getCustomFilterFunction() {
return $this->customFilterFunc;
@@ -269,7 +255,6 @@ public function getCustomFilterFunction() {
* not provided. If no default value is provided, the method will
* return null.
*
- * @since 1.1
*/
public function getDefault() {
return $this->default;
@@ -280,7 +265,6 @@ public function getDefault() {
* @return string|null The description of the parameter. If the description is
* not set, the method will return null.
*
- * @since 1.1
*/
public function getDescription() {
return $this->desc;
@@ -307,7 +291,6 @@ public function getMaxLength() {
* If the request parameter type is not numeric, the method will return
* null.
*
- * @since 1.1
*/
public function getMaxValue() {
return $this->maxVal;
@@ -321,7 +304,6 @@ public function getMaxValue() {
* If the request parameter type is not string, the method will return
* null.
*
- * @since 1.1
*/
public function getMinLength() {
return $this->minLength;
@@ -335,7 +317,6 @@ public function getMinLength() {
* If the request parameter type is not numeric, the method will return
* null.
*
- * @since 1.1
*/
public function getMinValue() {
return $this->minVal;
@@ -345,7 +326,6 @@ public function getMinValue() {
*
* @return string The name of the parameter.
*
- * @since 1.0
*/
public function getName() : string {
return $this->name;
@@ -355,7 +335,6 @@ public function getName() : string {
*
* @return string The type of the parameter (Such as 'string', 'email', 'integer').
*
- * @since 1.0
*/
public function getType() : string {
return $this->type;
@@ -368,7 +347,6 @@ public function getType() : string {
* if the basic filter will be applied before applying custom filter. If no custom
* filter is set, the method will return true by default.
*
- * @since 1.2
*/
public function isBasicFilter() : bool {
return $this->applyBasicFilter;
@@ -383,7 +361,6 @@ public function isBasicFilter() : bool {
* @return bool true if empty strings are allowed as values for the parameter.
* false if not.
*
- * @since 1.2.1
*/
public function isEmptyStringAllowed() : bool {
return $this->isEmptyStrAllowed;
@@ -395,7 +372,6 @@ public function isEmptyStringAllowed() : bool {
* @return bool true if the parameter is optional and false
* if not.
*
- * @since 1.0
*/
public function isOptional() : bool {
return $this->isOptional;
@@ -425,7 +401,6 @@ public function isOptional() : bool {
* is true.
*
*
- * @since 1.2
*/
public function setCustomFilterFunction(callable $function, bool $applyBasicFilter = true) {
$this->customFilterFunc = $function;
@@ -444,7 +419,6 @@ public function setCustomFilterFunction(callable $function, bool $applyBasicFilt
* @return bool If the default value is set, the method will return true.
* If it is not set, the method will return false.
*
- * @since 1.1
*/
public function setDefault($val) : bool {
$valType = gettype($val);
@@ -469,7 +443,6 @@ public function setDefault($val) : bool {
*
* @param string $desc Parameter description.
*
- * @since 1.1
*/
public function setDescription(string $desc) {
$this->desc = trim($desc);
@@ -487,7 +460,6 @@ public function setDescription(string $desc) {
* If datatype of the request parameter is not string, The method will
* not update the property value and will return false.
*
- * @since 1.2.1
*/
public function setIsEmptyStringAllowed(bool $bool) : bool {
if ($this->getType() == ParamType::STRING) {
@@ -505,7 +477,6 @@ public function setIsEmptyStringAllowed(bool $bool) : bool {
*
* @param bool $bool True to make the parameter optional. False to make it mandatory.
*
- * @since 1.2.2
*/
public function setIsOptional(bool $bool) {
$this->isOptional = $bool === true;
@@ -722,7 +693,6 @@ public function setType(string $type) : bool {
*
* @return Json An object of type Json.
*
- * @since 1.0
*/
public function toJSON() : Json {
$json = new Json();
diff --git a/webfiori/http/Response.php b/WebFiori/Http/Response.php
similarity index 96%
rename from webfiori/http/Response.php
rename to WebFiori/Http/Response.php
index e0bd18c..204f393 100644
--- a/webfiori/http/Response.php
+++ b/WebFiori/Http/Response.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
/**
* A class that represents HTTP response.
@@ -19,7 +19,6 @@
*
* @author Ibrahim
*
- * @version 1.0.1
*
*/
class Response {
@@ -27,54 +26,52 @@ class Response {
*
* @var array
*
- * @since 1.0
*/
private $beforeSendCalls;
/**
*
* @var string
*
- * @since 1.0
*/
private $body;
+ /**
+ * An array that contains response cookies.
+ *
+ * @var array
+ *
+ */
private $cookies;
/**
*
* @var HeadersPool
*
- * @since 1.0
*/
private $headersPool;
/**
*
* @var Response
*
- * @since 1.0
*/
private static $inst;
/**
*
* @var boolean
*
- * @since 1.0.1
*/
private $isSent;
/**
*
* @var boolean
*
- * @since 1.0
*/
private $lock;
/**
*
* @var int
*
- * @since 1.0
*/
private $responseCode;
/**
- * @since 1.0
*/
private function __construct() {
$this->headersPool = new HeadersPool();
@@ -108,7 +105,6 @@ public static function addCookie(HttpCookie $cookie) {
* @return bool If the header is added, the method will return true. If
* not added, the method will return false.
*
- * @since 1.0
*/
public static function addHeader(string $headerName, string $headerVal, ?string $replaceValue = '') : bool {
return self::getHeadersPool()->addHeader($headerName, $headerVal, $replaceValue);
@@ -120,7 +116,6 @@ public static function addHeader(string $headerName, string $headerVal, ?string
*
* @param callable $func A PHP callable.
*
- * @since 1.0
*/
public static function beforeSend(callable $func) {
self::get()->beforeSendCalls[] = $func;
@@ -130,7 +125,6 @@ public static function beforeSend(callable $func) {
*
* @return Response
*
- * @since 1.0
*/
public static function clear() : Response {
self::clearBody()->clearHeaders();
@@ -142,7 +136,6 @@ public static function clear() : Response {
*
* @return Response
*
- * @since 1.0
*/
public static function clearBody() : Response {
self::get()->body = '';
@@ -154,7 +147,6 @@ public static function clearBody() : Response {
*
* @return Response
*
- * @since 1.0
*/
public static function clearHeaders() : Response {
self::get()->headersPool = new HeadersPool();
@@ -202,7 +194,6 @@ public static function get() : Response {
*
* @return string A string that represents response body that will be sent.
*
- * @since 1.0
*/
public static function getBody() : string {
return self::get()->body;
@@ -212,7 +203,6 @@ public static function getBody() : string {
*
* @return int HTTP response code. Default value is 200.
*
- * @since 1.0
*/
public static function getCode() : int {
return self::get()->responseCode;
@@ -252,7 +242,6 @@ public static function getCookies() : array {
* that contains the values of the header. If the header does not exist, the
* method will return an empty array.
*
- * @since 1.0
*/
public static function getHeader(string $headerName) : array {
return self::getHeadersPool()->getHeader($headerName);
@@ -262,7 +251,6 @@ public static function getHeader(string $headerName) : array {
*
* @return array An array that contains response headers as object.
*
- * @since 1.0
*/
public static function getHeaders() : array {
return self::getHeadersPool()->getHeaders();
@@ -302,7 +290,6 @@ public static function hasCookie(string $cookieName) : bool {
* will return true. If a value is specified and a match is fond, the
* method will return true. Other than that, the method will return true.
*
- * @since 1.0
*/
public static function hasHeader(string $headerName, ?string $headerVal = '') : bool {
return self::getHeadersPool()->hasHeader($headerName, $headerVal);
@@ -313,7 +300,6 @@ public static function hasHeader(string $headerName, ?string $headerVal = '') :
* @return bool The method will return true if output is sent. False
* if not.
*
- * @since 1.0.1
*/
public static function isSent() : bool {
return self::get()->isSent;
@@ -330,7 +316,6 @@ public static function isSent() : bool {
* @return bool If the header is removed, the method will return true.
* Other than that, the method will return true.
*
- * @since 1.0
*/
public static function removeHeader(string $headerName, ?string $headerVal = '') : bool {
return self::getHeadersPool()->removeHeader($headerName, $headerVal);
@@ -343,7 +328,6 @@ public static function removeHeader(string $headerName, ?string $headerVal = '')
* it will terminate the execution of code once the output is sent. In terminal
* environment, calling it will have no effect.
*
- * @since 1.0
*/
public static function send() {
if (!self::isSent()) {
@@ -392,7 +376,6 @@ public static function send() {
* @param int $code HTTP response code. The value must be between 100 and
* 599 inclusive.
*
- * @since 1.0
*/
public static function setCode(int $code) {
if ($code >= 100 && $code <= 599) {
@@ -409,7 +392,6 @@ public static function setCode(int $code) {
*
* @return Response
*
- * @since 1.0
*/
public static function write($value, bool $sendResponse = false) : Response {
$type = gettype($value);
diff --git a/webfiori/http/ResponseMessage.php b/WebFiori/Http/ResponseMessage.php
similarity index 95%
rename from webfiori/http/ResponseMessage.php
rename to WebFiori/Http/ResponseMessage.php
index 860c323..333e151 100644
--- a/webfiori/http/ResponseMessage.php
+++ b/WebFiori/Http/ResponseMessage.php
@@ -1,5 +1,5 @@
messages = [
'401' => 'Not Authorized.',
diff --git a/webfiori/http/Uri.php b/WebFiori/Http/Uri.php
similarity index 97%
rename from webfiori/http/Uri.php
rename to WebFiori/Http/Uri.php
index bad0a25..6139074 100644
--- a/webfiori/http/Uri.php
+++ b/WebFiori/Http/Uri.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use InvalidArgumentException;
/**
@@ -27,21 +27,18 @@
*
* @author Ibrahim
*
- * @version 1.0.1
*/
class Uri {
/**
*
* @var array
*
- * @since 1.0.1
*/
private $allowedRequestMethods;
/**
* The URI broken into its subcomponents (scheme, authority ...) as an associative
* array.
* @var array
- * @since 1.0
*/
private $uriBroken;
/**
@@ -74,7 +71,6 @@ public function __construct(string $requestedUri) {
* @param string $method A string such as 'GET' or 'POST'. Note that the
* value must exist in the array Request::METHODS, or it will be not added.
*
- * @since 1.0.1
*/
public function addRequestMethod(string $method) {
if (in_array($method, Request::METHODS)) {
@@ -92,7 +88,6 @@ public function addRequestMethod(string $method) {
* @param string $varValue The value of the parameter. Note that any extra spaces
* in the value will be trimmed.
*
- * @since 1.0
*/
public function addVarValue(string $varName, string $varValue) {
$trimmed = trim($varName);
@@ -112,7 +107,6 @@ public function addVarValue(string $varName, string $varValue) {
* @param array $arrayOfValues An array that contains all possible values for
* the parameter.
*
- * @since 1.0
*/
public function addVarValues(string $varName, array $arrayOfValues) {
if (gettype($arrayOfValues) == 'array') {
@@ -132,7 +126,6 @@ public function addVarValues(string $varName, array $arrayOfValues) {
* @return boolean The method will return true if the URIs are
* equal.
*
- * @since 1.0
*/
public function equals(Uri $otherUri) : bool {
$isEqual = true;
@@ -165,7 +158,6 @@ public function equals(Uri $otherUri) : bool {
* @return string The authority part of the URI. Usually,
* it is a string in the form '//www.example.com:80'.
*
- * @since 1.0
*/
public function getAuthority() : string {
return $this->uriBroken['authority'];
@@ -183,7 +175,6 @@ public function getAuthority() : string {
*
* @return string The base URL (such as 'http//www.example.com/')
*
- * @since 0.2
*/
public static function getBaseURL() : string {
$tempHost = $_SERVER['HTTP_HOST'] ?? '127.0.0.1';
@@ -255,7 +246,6 @@ public static function getBaseURL() : string {
*
uri-vars: An array that contains URI path parameter and values.
*
*
- * @since 1.0
*/
public function getComponents() : array {
return $this->uriBroken;
@@ -266,7 +256,6 @@ public function getComponents() : array {
* @return string Fragment part of the URI. The fragment in the URI is
* any string that comes after the character '#'.
*
- * @since 1.0
*/
public function getFragment() : string {
return $this->uriBroken['fragment'];
@@ -276,7 +265,6 @@ public function getFragment() : string {
*
* @return string The host name such as 'www.webfiori.com'.
*
- * @since 1.0
*/
public function getHost() : string {
return $this->uriBroken['host'];
@@ -304,7 +292,6 @@ public function getParameter(string $name) {
* @return array An indexed array which contains URI parameters as
* objects of type UriParameter.
*
- * @since 1.0
*/
public function getParameters() : array {
return $this->uriBroken['uri-vars'];
@@ -331,7 +318,6 @@ public function getParametersNames() : array {
* parameter if found. If the parameter is not set or the parameter
* does not exist, the method will return null.
*
- * @since 1.0
*/
public function getParameterValue(string $varName) {
$param = $this->getParameter($varName);
@@ -351,7 +337,6 @@ public function getParameterValue(string $varName) {
* values for the parameter which was added using the method Router::addUriVarValue().
* If the parameter does not exist, the array will be empty.
*
- * @since 1.3.6
*/
public function getParameterValues(string $varName) : array {
$trimmed = trim($varName);
@@ -367,7 +352,6 @@ public function getParameterValues(string $varName) : array {
*
* @return string A string such as '/path1/path2/path3'.
*
- * @since 1.0
*/
public function getPath() : string {
$retVal = '';
@@ -385,7 +369,6 @@ public function getPath() : string {
* For example, if the path part of the URI is '/path1/path2', the
* array will contain the value 'path1' at index 0 and 'path2' at index 1.
*
- * @since 1.0
*/
public function getPathArray() : array {
return $this->uriBroken['path'];
@@ -396,7 +379,6 @@ public function getPathArray() : array {
* @return string Port number of the authority part of the URI. If
* port number was not specified, the method will return empty string.
*
- * @since 1.0
*/
public function getPort() : string {
return $this->uriBroken['port'];
@@ -408,7 +390,6 @@ public function getPort() : string {
* If the URI has no query string, the method will return empty
* string.
*
- * @since 1.0
*/
public function getQueryString() : string {
return $this->uriBroken['query-string'];
@@ -420,7 +401,6 @@ public function getQueryString() : string {
* the keys will be acting as the names of the parameters and the values
* of each parameter will be in its key.
*
- * @since 1.0
*/
public function getQueryStringVars() : array {
return $this->uriBroken['query-string-vars'];
@@ -431,7 +411,6 @@ public function getQueryStringVars() : array {
*
* @return array An array that holds strings such as 'GET' or 'POST'.
*
- * @since 1.0.1
*/
public function getRequestMethods() : array {
return $this->allowedRequestMethods;
@@ -442,7 +421,6 @@ public function getRequestMethods() : array {
* @return string The scheme part of the URI. Usually, it is called protocol
* (like http, ftp).
*
- * @since 1.0
*/
public function getScheme() : string {
return $this->uriBroken['scheme'];
@@ -458,7 +436,6 @@ public function getScheme() : string {
*
* @return string The original requested URI.
*
- * @since 1.0
*/
public function getUri(bool $incQueryStr = false, bool $incFragment = false) : string {
$retVal = $this->getScheme().':'.$this->getAuthority().$this->getPath();
@@ -505,7 +482,6 @@ public function getUri(bool $incQueryStr = false, bool $incFragment = false) : s
* @return boolean If the given parameter name is exist, the method will
* return true. Other than that, the method will return false.
*
- * @since 1.0
*/
public function hasParameter(string $varName) : bool {
return in_array($varName, $this->getParametersNames());
@@ -519,7 +495,6 @@ public function hasParameter(string $varName) : bool {
* @return bool If the URI has any parameters, the method will
* return true.
*
- * @since 1.0
*/
public function hasParameters() : bool {
return count($this->getParameters()) != 0;
@@ -530,7 +505,6 @@ public function hasParameters() : bool {
* @return bool The method will return true if all non-optional URI
* parameters have a value other than null.
*
- * @since 1.0
*/
public function isAllParametersSet() : bool {
$canRoute = true;
@@ -550,7 +524,6 @@ public function isAllParametersSet() : bool {
* in the allowed request methods. Other than that, the method will return
* false.
*
- * @since 1.0.1
*/
public function isRequestMethodAllowed() : bool {
$methods = $this->getRequestMethods();
@@ -571,7 +544,6 @@ public function isRequestMethodAllowed() : bool {
* @return bool The method will return true if the parameter
* was set. If the parameter does not exist, the method will return false.
*
- * @since 1.0
*/
public function setParameterValue(string $varName, string $value) : bool {
$param = $this->getParameter($varName);
@@ -590,7 +562,6 @@ public function setParameterValue(string $varName, string $value) : bool {
*
* @param array $methods An array that holds strings such as 'GET' or 'POST'.
*
- * @since 1.0.1
*/
public function setRequestMethods(array $methods) {
foreach ($methods as $m) {
@@ -619,7 +590,6 @@ public function setRequestMethods(array $methods) {
*
uri-vars: An array that contains URI path parameters and values.
*
*
- * @since 1.0
*/
public static function splitURI(string $uri) {
$validate = filter_var(str_replace(' ', '%20', $uri),FILTER_VALIDATE_URL);
diff --git a/webfiori/http/UriParameter.php b/WebFiori/Http/UriParameter.php
similarity index 91%
rename from webfiori/http/UriParameter.php
rename to WebFiori/Http/UriParameter.php
index 9d42ca9..8e27fb2 100644
--- a/webfiori/http/UriParameter.php
+++ b/WebFiori/Http/UriParameter.php
@@ -7,7 +7,7 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use InvalidArgumentException;
@@ -17,8 +17,18 @@
* @author Ibrahim
*/
class UriParameter {
+ /**
+ * A boolean value that indicates if the parameter is optional or not.
+ *
+ * @var bool
+ */
private $isOptional;
private $name;
+ /**
+ * The name of the parameter.
+ *
+ * @var string
+ */
private $value;
/**
* Creates new instance of the class.
diff --git a/webfiori/http/WebServicesManager.php b/WebFiori/Http/WebServicesManager.php
similarity index 97%
rename from webfiori/http/WebServicesManager.php
rename to WebFiori/Http/WebServicesManager.php
index f388e93..bd08008 100644
--- a/webfiori/http/WebServicesManager.php
+++ b/WebFiori/Http/WebServicesManager.php
@@ -7,11 +7,11 @@
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
-namespace webfiori\http;
+namespace WebFiori\Http;
use Exception;
-use webfiori\json\Json;
-use webfiori\json\JsonI;
+use WebFiori\Json\Json;
+use WebFiori\Json\JsonI;
/**
* A class that is used to manage multiple web services.
*
@@ -22,7 +22,6 @@
* When a request is made to the services set, An instance of the class must be created
* and the method WebServicesManager::process() must be called.
*
- * @version 1.4.8
*/
class WebServicesManager implements JsonI {
/**
@@ -47,7 +46,6 @@ class WebServicesManager implements JsonI {
*
* @var array An array that contains the supported 'POST' and 'PUT' request content types.
*
- * @since 1.1
*/
const POST_CONTENT_TYPES = [
'application/x-www-form-urlencoded',
@@ -59,7 +57,6 @@ class WebServicesManager implements JsonI {
*
* @var string
*
- * @since 1.3
*/
private $apiDesc;
/**
@@ -67,7 +64,6 @@ class WebServicesManager implements JsonI {
*
* @var string
*
- * @since 1.0
*/
private $apiVersion;
/**
@@ -75,7 +71,6 @@ class WebServicesManager implements JsonI {
*
* @var APIFilter
*
- * @since 1.0
*/
private $filter;
/**
@@ -83,7 +78,6 @@ class WebServicesManager implements JsonI {
*
* @var array
*
- * @since 1.4.1
*/
private $invParamsArr;
/**
@@ -91,7 +85,6 @@ class WebServicesManager implements JsonI {
*
* @var array
*
- * @since 1.4.1
*/
private $missingParamsArr;
/**
@@ -111,7 +104,6 @@ class WebServicesManager implements JsonI {
*
* @var array
*
- * @since 1.0
*/
private $services;
/**
@@ -147,7 +139,6 @@ public function __construct(string $version = '1.0.0') {
* @param AbstractWebService $service The web service that will be added.
*
*
- * @since 1.0
*/
public function addService(AbstractWebService $service) {
$this->addAction($service);
@@ -169,7 +160,6 @@ public function addService(AbstractWebService $service) {
* @param string $cType The value of the header 'content-type' taken from
* request header.
*
- * @since 1.1
*/
public function contentTypeNotSupported(string $cType = '') {
$j = new Json();
@@ -186,7 +176,6 @@ public function contentTypeNotSupported(string $cType = '') {
* @return string|null The name of the service that was requested. If the name
* of the service is not set, the method will return null.
*
- * @since 1.0
*
*/
public function getCalledServiceName() {
@@ -199,7 +188,6 @@ public function getCalledServiceName() {
* useful to describe what does the set of services can do. If the description is
* not set, the method will return null.
*
- * @since 1.3
*/
public function getDescription() {
return $this->apiDesc;
@@ -218,7 +206,6 @@ public function getDescription() {
* @return array|Json An array of filtered request inputs. This also can
* be an object of type 'Json' if request content type was 'application/json'.
*
- * @since 1.0
*/
public function getInputs() {
return $this->filter->getInputs();
@@ -228,7 +215,6 @@ public function getInputs() {
*
* @return array An array that contains the names of request parameters which have invalid values.
*
- * @since 1.4.1
*/
public function getInvalidParameters() : array {
return $this->invParamsArr;
@@ -239,7 +225,6 @@ public function getInvalidParameters() : array {
*
* @return array An array that contains the names of missing required parameters.
*
- * @since 1.4.1
*/
public function getMissingParameters() : array {
return $this->missingParamsArr;
@@ -254,7 +239,6 @@ public function getMissingParameters() : array {
*
* @return array An array of request parameters.
*
- * @since 1.4.3
*/
public function getNonFiltered() : array {
return $this->filter->getNonFiltered();
@@ -267,7 +251,6 @@ public function getNonFiltered() : array {
* resource. The resource will be still open. If no custom stream is set,
* the method will return null.
*
- * @since 1.4.7
*/
public function getOutputStream() {
return $this->outputStream;
@@ -278,7 +261,6 @@ public function getOutputStream() {
* @return string|null A string that represents the path of the custom output stream.
* If no custom output stream is set, the method will return null.
*
- * @since 1.4.7
*/
public function getOutputStreamPath() {
return $this->outputStreamPath;
@@ -292,7 +274,6 @@ public function getOutputStreamPath() {
* if the service is found. If no service was found which has the given name,
* The method will return null.
*
- * @since 1.3
*/
public function getServiceByName(string $serviceName) {
$trimmed = trim($serviceName);
@@ -310,7 +291,6 @@ public function getServiceByName(string $serviceName) {
* The indices of the array are services names and the values are objects
* of type 'WebService'.
*
- * @since 1.0
*/
public final function getServices() : array {
return $this->services;
@@ -320,7 +300,6 @@ public final function getServices() : array {
*
* @return string A string in the format 'X.X.X'.
*
- * @since 1.0
*/
public final function getVersion() : string {
return $this->apiVersion;
@@ -337,7 +316,6 @@ public final function getVersion() : string {
*
* In addition to the message, The response will send HTTP code 404 - Not Found.
*
- * @since 1.3
*/
public function invParams() {
$val = '';
@@ -366,7 +344,6 @@ public function invParams() {
* PUT and POST), the method will return true, false if not. Other than that, the method
* will return true.
*
- * @since 1.1
*/
public final function isContentTypeSupported() : bool {
$c = Request::getContentType();
@@ -392,7 +369,6 @@ public final function isContentTypeSupported() : bool {
*
* In addition to the message, The response will send HTTP code 404 - Not Found.
*
- * @since 1.3
*/
public function missingParams() {
$val = '';
@@ -425,7 +401,6 @@ public function missingParams() {
*
* In addition to the message, The response will send HTTP code 404 - Not Found.
*
- * @since 1.3.1
*/
public function missingServiceName() {
$this->sendResponse(ResponseMessage::get('404-3'), self::E, 404);
@@ -443,7 +418,6 @@ public function missingServiceName() {
*
* In addition to the message, The response will send HTTP code 401 - Not Authorized.
*
- * @since 1.0
*/
public function notAuth() {
$this->sendResponse(ResponseMessage::get('401'), self::E, 401);
@@ -456,7 +430,6 @@ public function notAuth() {
* new instance of the class in order to process user request.
*
* @throws Exception
- * @since 1.0
*/
public final function process() {
$this->invParamsArr = [];
@@ -499,7 +472,6 @@ public final function process() {
* @return string|null If the content was taken from the stream, the method
* will return it as a string. Other than that, the method will return null.
*
- * @since 1.4.7
*/
public function readOutputStream() {
$path = $this->getOutputStreamPath();
@@ -519,7 +491,6 @@ public function readOutputStream() {
* and removed, the method will return an object that represent the removed
* service. Other than that, the method will return null.
*
- * @since 1.4.8
*/
public function removeService(string $name) {
$trimmed = trim($name);
@@ -538,7 +509,6 @@ public function removeService(string $name) {
* This method will simply re-initialize the arrays that holds all web
* services.
*
- * @since 1.4.5
*/
public function removeServices() {
$this->services = [];
@@ -556,7 +526,6 @@ public function removeServices() {
*
* In addition to the message, The response will send HTTP code 405 - Method Not Allowed.
*
- * @since 1.0
*/
public function requestMethodNotAllowed() {
$this->sendResponse(ResponseMessage::get('405'), self::E, 405);
@@ -589,7 +558,6 @@ public function send(string $contentType, $data, int $code = 200) {
* and the value of each key will represent the value
* of the header.
*
- * @since 1.4.3
*/
public function sendHeaders(array $headersArr) {
foreach ($headersArr as $header => $val) {
@@ -623,7 +591,6 @@ public function sendHeaders(array $headersArr) {
* string, an object... . If null is given, the parameter 'more-info'
* will be not included in response. Default is empty string. Default is null.
*
- * @since 1.0
*/
public function sendResponse(string $message, string $type = '', int $code = 200, mixed $otherInfo = '') {
$json = new Json();
@@ -663,7 +630,6 @@ public function sendResponse(string $message, string $type = '', int $code = 200
*
* In addition to the message, The response will send HTTP code 404 - Not Found.
*
- * @since 1.0
*/
public function serviceNotImplemented() {
$this->sendResponse(ResponseMessage::get('404-4'), self::E, 404);
@@ -680,7 +646,6 @@ public function serviceNotImplemented() {
*
* In addition to the message, The response will send HTTP code 404 - Not Found.
*
- * @since 1.0
*/
public function serviceNotSupported() {
$this->sendResponse(ResponseMessage::get('404-5'), self::E, 404);
@@ -691,7 +656,6 @@ public function serviceNotSupported() {
* @param string $desc Set description. Used to help front-end to identify
* the use of the services set.
*
- * @since 1.3
*/
public function setDescription(string $desc) {
$this->apiDesc = $desc;
@@ -708,7 +672,6 @@ public function setDescription(string $desc) {
* @return bool If input stream is successfully set, the method will
* return true. False otherwise.
*
- * @since 1.4.8
*/
public function setInputStream($pathOrResource) : bool {
return $this->filter->setInputStream($pathOrResource);
@@ -727,7 +690,6 @@ public function setInputStream($pathOrResource) : bool {
* @param bool $new If set to true and the resource does not exist, the
* method will attempt to create it.
*
- * @since 1.4.7
*/
public function setOutputStream($stream, bool $new = false): bool {
if (is_resource($stream)) {
@@ -762,7 +724,6 @@ public function setOutputStream($stream, bool $new = false): bool {
*
* @return bool true if set. false otherwise.
*
- * @since 1.0
*/
public final function setVersion(string $val) : bool {
$nums = explode('.', $val);
@@ -789,7 +750,6 @@ public final function setVersion(string $val) : bool {
*
* @return Json An object of type Json.
*
- * @since 1.0
*/
public function toJSON() : Json {
$json = new Json();
@@ -848,7 +808,6 @@ private function _AfterParamsCheck($processReq) {
*
* @return bool true if called service is valid.
*
- * @since 1.0
*/
private function _checkAction(): bool {
$serviceName = $this->getCalledServiceName();
@@ -921,7 +880,6 @@ private function _processNonJson($params) {
*
* @param AbstractWebService $service The web service that will be added.
*
- * @since 1.0
*
* @deprecated since version 1.4.7 Use WebservicesSet::addService()
*/
@@ -957,7 +915,6 @@ private function filterInputsHelper() {
* @return string|null The name of the service that was requested. If the name
* of the service is not set, the method will return null.
*
- * @since 1.0
*
* @deprecated since version 1.4.6 Use WebServicesManager::getCalledServiceName() instead.
*/
diff --git a/composer.json b/composer.json
index 0ca9364..09d3f9a 100644
--- a/composer.json
+++ b/composer.json
@@ -16,14 +16,25 @@
"license": "MIT",
"require": {
"php": ">=7.0",
- "webfiori/jsonx": "3.3.x",
+ "webfiori/jsonx": "4.0.x",
"ext-json": "*",
"ext-mbstring": "*"
},
"autoload": {
"psr-4": {
- "webfiori\\http\\": "webfiori\\http"
+ "WebFiori\\Http\\": "WebFiori/Http"
}
},
- "require-dev": {}
+ "autoload-dev": {
+ "psr-4": {
+ "WebFiori\\Tests\\Http\\": "tests/WebFiori/Tests/Http/"
+ }
+ },
+ "scripts": {
+ "test": "phpunit --configuration tests/phpunit.xml",
+ "test-10": "phpunit --configuration tests/phpunit10.xml"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.0"
+ }
}
diff --git a/examples/GetRandomService.php b/examples/GetRandomService.php
index 99a2e24..ae48520 100644
--- a/examples/GetRandomService.php
+++ b/examples/GetRandomService.php
@@ -2,19 +2,42 @@
require 'loader.php';
-use webfiori\http\AbstractWebService;
-use webfiori\http\RequestParameter;
+use WebFiori\Http\AbstractWebService;
+use WebFiori\Http\ParamOption;
+use WebFiori\Http\ParamType;
+use WebFiori\Http\RequestMethod;
class GetRandomService extends AbstractWebService {
public function __construct() {
parent::__construct('get-random-number');
- $this->setRequestMethods(['get', 'post']);
-
- $this->addParameter(new RequestParameter('min', 'integer', true));
- $this->addParameter(new RequestParameter('max', 'integer', true));
+ $this->setRequestMethods([
+ RequestMethod::GET,
+ RequestMethod::POST
+ ]);
+
+ $this->addParameters([
+ 'min' => [
+ ParamOption::TYPE => ParamType::INT,
+ ParamOption::OPTIONAL => true
+ ],
+ 'max' => [
+ ParamOption::TYPE => ParamType::INT,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
}
public function isAuthorized() {
+// $authHeader = $this->getAuthHeader();
+//
+// if ($authHeader === null) {
+// return false;
+// }
+//
+// $scheme = $authHeader->getScheme();
+// $credentials = $authHeader->getCredentials();
+
+ //Verify credentials based on auth scheme (e.g. 'Basic', 'Barear'
}
public function processRequest() {
diff --git a/examples/HelloWithAuthService.php b/examples/HelloWithAuthService.php
new file mode 100644
index 0000000..40fdd2a
--- /dev/null
+++ b/examples/HelloWithAuthService.php
@@ -0,0 +1,51 @@
+setRequestMethods([RequestMethod::GET]);
+
+ $this->addParameters([
+ 'my-name' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+ public function isAuthorized() {
+ //Change default response message to custom one
+ ResponseMessage::set('401', 'Not authorized to use this API.');
+
+ $authHeader = $this->getAuthHeader();
+
+ if ($authHeader === null) {
+ return false;
+ }
+
+ $scheme = $authHeader->getScheme();
+ $credentials = $authHeader->getCredentials();
+
+ if ($scheme != 'bearer') {
+ return false;
+ }
+
+ return $credentials == 'abc123trX';
+ }
+
+ public function processRequest() {
+ $name = $this->getParamVal('my-name');
+
+ if ($name !== null) {
+ $this->sendResponse("Hello '$name'.");
+ }
+ $this->sendResponse('Hello World!');
+ }
+}
diff --git a/examples/HelloWorldService.php b/examples/HelloWorldService.php
index 4cd4ef2..44233e8 100644
--- a/examples/HelloWorldService.php
+++ b/examples/HelloWorldService.php
@@ -2,22 +2,32 @@
require 'loader.php';
-use webfiori\http\AbstractWebService;
+use WebFiori\Http\AbstractWebService;
+use WebFiori\Http\ParamOption;
+use WebFiori\Http\ParamType;
+use WebFiori\Http\RequestMethod;
-/**
- * Description of HelloWorldService
- *
- * @author Ibrahim
- */
class HelloWorldService extends AbstractWebService {
public function __construct() {
parent::__construct('hello');
- $this->addRequestMethod('get');
+ $this->setRequestMethods([RequestMethod::GET]);
+
+ $this->addParameters([
+ 'my-name' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
}
public function isAuthorized() {
}
public function processRequest() {
- $this->getManager()->sendResponse('Hello World!');
+ $name = $this->getParamVal('my-name');
+
+ if ($name !== null) {
+ $this->sendResponse("Hello '$name'.");
+ }
+ $this->sendResponse('Hello World!');
}
}
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..1b22b36
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,337 @@
+# WebFiori HTTP Examples
+
+This folder contains practical examples demonstrating how to use the WebFiori HTTP library to create RESTful web services. The examples showcase different features including basic services, parameter handling, and authentication.
+
+## Table of Contents
+
+- [Prerequisites](#prerequisites)
+- [Setup](#setup)
+- [Available Services](#available-services)
+ - [1. Hello World Service](#1-hello-world-service-helloworldservicephp)
+ - [2. Random Number Service](#2-random-number-service-getrandomservicephp)
+ - [3. Hello with Authentication Service](#3-hello-with-authentication-service-hellowithAuthservicephp)
+- [Main Application](#main-application-indexphp)
+- [Loader Configuration](#loader-configuration-loaderphp)
+- [Key Concepts Demonstrated](#key-concepts-demonstrated)
+- [Testing All Services](#testing-all-services)
+- [Notes](#notes)
+
+## Prerequisites
+
+- PHP 8.1 or higher
+- Composer installed
+- WebFiori HTTP library dependencies
+
+## Setup
+
+1. **Install dependencies** (run from the project root directory):
+ ```bash
+ composer install
+ ```
+
+2. **Navigate to the examples directory**:
+ ```bash
+ cd examples
+ ```
+
+3. **Start the PHP development server**:
+ ```bash
+ php -S localhost:8989
+ ```
+
+## Available Services
+
+### 1. Hello World Service (`HelloWorldService.php`)
+
+A basic service that demonstrates simple parameter handling.
+
+**Service Name**: `hello`
+**HTTP Methods**: GET
+**Parameters**:
+- `my-name` (optional, string): Name to include in greeting
+
+**Code Example**:
+```php
+setRequestMethods([RequestMethod::GET]);
+
+ $this->addParameters([
+ 'my-name' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+ public function isAuthorized() {
+ }
+
+ public function processRequest() {
+ $name = $this->getParamVal('my-name');
+
+ if ($name !== null) {
+ $this->sendResponse("Hello '$name'.");
+ }
+ $this->sendResponse('Hello World!');
+ }
+}
+```
+
+**Test URLs**:
+```bash
+# Basic hello
+curl "http://localhost:8989?service=hello"
+# Response: {"message":"Hello World!","http-code":200}
+
+# Hello with name
+curl "http://localhost:8989?service=hello&my-name=ibrahim"
+# Response: {"message":"Hello 'ibrahim'.","http-code":200}
+```
+
+### 2. Random Number Service (`GetRandomService.php`)
+
+Demonstrates parameter validation and processing with optional integer parameters.
+
+**Service Name**: `get-random-number`
+**HTTP Methods**: GET, POST
+**Parameters**:
+- `min` (optional, integer): Minimum value for random number
+- `max` (optional, integer): Maximum value for random number
+
+**Code Example**:
+```php
+setRequestMethods([
+ RequestMethod::GET,
+ RequestMethod::POST
+ ]);
+
+ $this->addParameters([
+ 'min' => [
+ ParamOption::TYPE => ParamType::INT,
+ ParamOption::OPTIONAL => true
+ ],
+ 'max' => [
+ ParamOption::TYPE => ParamType::INT,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+
+ public function isAuthorized() {
+// $authHeader = $this->getAuthHeader();
+//
+// if ($authHeader === null) {
+// return false;
+// }
+//
+// $scheme = $authHeader->getScheme();
+// $credentials = $authHeader->getCredentials();
+
+ //Verify credentials based on auth scheme (e.g. 'Basic', 'Barear'
+ }
+
+ public function processRequest() {
+ $max = $this->getParamVal('max');
+ $min = $this->getParamVal('min');
+
+ if ($max !== null && $min !== null) {
+ $random = rand($min, $max);
+ } else {
+ $random = rand();
+ }
+ $this->sendResponse($random);
+ }
+}
+```
+
+**Test URLs**:
+```bash
+# Random number without bounds
+curl "http://localhost:8989?service=get-random-number"
+# Response: {"message":"1255598581","http-code":200}
+
+# Random number between 1 and 10
+curl "http://localhost:8989?service=get-random-number&min=1&max=10"
+# Response: {"message":"7","http-code":200}
+
+# Random number between -4 and 0
+curl "http://localhost:8989?service=get-random-number&min=-4&max=0"
+# Response: {"message":"-1","http-code":200}
+
+# Invalid parameter type (demonstrates validation)
+curl "http://localhost:8989?service=get-random-number&min=-4&max=Super"
+# Response: {"message":"The following parameter(s) has invalid values: 'max'.","type":"error","http-code":404,"more-info":{"invalid":["max"]}}
+```
+
+### 3. Hello with Authentication Service (`HelloWithAuthService.php`)
+
+Demonstrates Bearer token authentication implementation.
+
+**Service Name**: `hello-with-auth`
+**HTTP Methods**: GET
+**Authentication**: Bearer token required (`abc123trX`)
+**Parameters**:
+- `my-name` (optional, string): Name to include in greeting
+
+**Code Example**:
+```php
+setRequestMethods([RequestMethod::GET]);
+
+ $this->addParameters([
+ 'my-name' => [
+ ParamOption::TYPE => ParamType::STRING,
+ ParamOption::OPTIONAL => true
+ ]
+ ]);
+ }
+ public function isAuthorized() {
+ //Change default response message to custom one
+ ResponseMessage::set('401', 'Not authorized to use this API.');
+
+ $authHeader = $this->getAuthHeader();
+
+ if ($authHeader === null) {
+ return false;
+ }
+
+ $scheme = $authHeader->getScheme();
+ $credentials = $authHeader->getCredentials();
+
+ if ($scheme != 'bearer') {
+ return false;
+ }
+
+ return $credentials == 'abc123trX';
+ }
+
+ public function processRequest() {
+ $name = $this->getParamVal('my-name');
+
+ if ($name !== null) {
+ $this->sendResponse("Hello '$name'.");
+ }
+ $this->sendResponse('Hello World!');
+ }
+}
+```
+
+**Test URLs**:
+```bash
+# Without authorization (will fail)
+curl "http://localhost:8989?service=hello-with-auth&my-name=ibrahim"
+# Response: {"message":"Not authorized to use this API.","type":"error","http-code":401}
+
+# With correct Bearer token
+curl -H "Authorization: Bearer abc123trX" "http://localhost:8989?service=hello-with-auth&my-name=ibrahim"
+# Response: {"message":"Hello 'ibrahim'.","http-code":200}
+```
+
+## Main Application (`index.php`)
+
+The main entry point that registers all services with the WebServicesManager:
+
+```php
+addService(new HelloWorldService());
+$manager->addService(new GetRandomService());
+$manager->addService(new HelloWithAuthService());
+$manager->process();
+```
+
+## Loader Configuration (`loader.php`)
+
+Sets up error reporting and autoloading:
+
+```php
+addService(new GetRandomService());
- }
-}
-
-$manager = new RandomGenerator();
-$manager->process();
diff --git a/examples/ServicesManager.php b/examples/ServicesManager.php
deleted file mode 100644
index 72afbc1..0000000
--- a/examples/ServicesManager.php
+++ /dev/null
@@ -1,11 +0,0 @@
-addService(new HelloWorldService());
-$manager->process();
diff --git a/examples/index.php b/examples/index.php
new file mode 100644
index 0000000..0bbe98e
--- /dev/null
+++ b/examples/index.php
@@ -0,0 +1,17 @@
+addService(new HelloWorldService());
+$manager->addService(new GetRandomService());
+$manager->addService(new HelloWithAuthService());
+$manager->process();
diff --git a/examples/loader.php b/examples/loader.php
index d3162b3..3290d0c 100644
--- a/examples/loader.php
+++ b/examples/loader.php
@@ -4,16 +4,4 @@
ini_set('display_errors', 1);
error_reporting(-1);
-require_once '../vendor/webfiori/jsonx/src/JsonI.php';
-require_once '../vendor/webfiori/jsonx/src/JsonTypes.php';
-require_once '../vendor/webfiori/jsonx/src/Json.php';
-require_once '../src/ParamTypes.php';
-require_once '../src/AbstractWebService.php';
-require_once '../src/APIFilter.php';
-require_once '../src/WebServicesManager.php';
-require_once '../src/RequestParameter.php';
-require_once '../src/Request.php';
-require_once '../src/Response.php';
-require_once '../src/ParamOption.php';
-require_once '../src/Uri.php';
-require_once 'GetRandomService.php';
+require_once '../vendor/autoload.php';
diff --git a/tests/webfiori/tests/http/APIFilterTest.php b/tests/WebFiori/Tests/Http/APIFilterTest.php
similarity index 99%
rename from tests/webfiori/tests/http/APIFilterTest.php
rename to tests/WebFiori/Tests/Http/APIFilterTest.php
index 989e704..bf96056 100644
--- a/tests/webfiori/tests/http/APIFilterTest.php
+++ b/tests/WebFiori/Tests/Http/APIFilterTest.php
@@ -1,11 +1,11 @@
- ../webfiori/http/AbstractWebService.php
- ../webfiori/http/APIFilter.php
- ../webfiori/http/RequestParameter.php
- ../webfiori/http/WebServicesManager.php
- ../webfiori/http/Request.php
- ../webfiori/http/Response.php
- ../webfiori/http/Uri.php
- ../webfiori/http/HttpHeader.php
- ../webfiori/http/HttpCookie.php
- ../webfiori/http/HeadersPool.php
- ../webfiori/http/UriParameter.php
- ../webfiori/http/ObjectMapper.php
- ../webfiori/http/AuthHeader.php
+ ../WebFiori/Http/AbstractWebService.php
+ ../WebFiori/Http/APIFilter.php
+ ../WebFiori/Http/RequestParameter.php
+ ../WebFiori/Http/WebServicesManager.php
+ ../WebFiori/Http/Request.php
+ ../WebFiori/Http/Response.php
+ ../WebFiori/Http/Uri.php
+ ../WebFiori/Http/HttpHeader.php
+ ../WebFiori/Http/HttpCookie.php
+ ../WebFiori/Http/HeadersPool.php
+ ../WebFiori/Http/UriParameter.php
+ ../WebFiori/Http/ObjectMapper.php
+ ../WebFiori/Http/AuthHeader.php
@@ -24,7 +24,7 @@
- ./webfiori/tests/http
+ ./WebFiori/Tests/Http
\ No newline at end of file
diff --git a/tests/phpunit10.xml b/tests/phpunit10.xml
index 4214706..c6ee333 100644
--- a/tests/phpunit10.xml
+++ b/tests/phpunit10.xml
@@ -10,24 +10,24 @@
- ./webfiori/tests/http
+ ./WebFiori/Tests/Http
- ../webfiori/http/AbstractWebService.php
- ../webfiori/http/APIFilter.php
- ../webfiori/http/RequestParameter.php
- ../webfiori/http/WebServicesManager.php
- ../webfiori/http/Request.php
- ../webfiori/http/Response.php
- ../webfiori/http/Uri.php
- ../webfiori/http/HttpHeader.php
- ../webfiori/http/HttpCookie.php
- ../webfiori/http/HeadersPool.php
- ../webfiori/http/UriParameter.php
- ../webfiori/http/ObjectMapper.php
- ../webfiori/http/AuthHeader.php
+ ../WebFiori/Http/AbstractWebService.php
+ ../WebFiori/Http/APIFilter.php
+ ../WebFiori/Http/RequestParameter.php
+ ../WebFiori/Http/WebServicesManager.php
+ ../WebFiori/Http/Request.php
+ ../WebFiori/Http/Response.php
+ ../WebFiori/Http/Uri.php
+ ../WebFiori/Http/HttpHeader.php
+ ../WebFiori/Http/HttpCookie.php
+ ../WebFiori/Http/HeadersPool.php
+ ../WebFiori/Http/UriParameter.php
+ ../WebFiori/Http/ObjectMapper.php
+ ../WebFiori/Http/AuthHeader.php