Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mdevoldere #1

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*.user
*.userosscache
*.sln.docstates
/vendor/

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
Expand Down Expand Up @@ -348,3 +349,5 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/

/vendor/
101 changes: 101 additions & 0 deletions Http/Http.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace Md\Http;


use function array_map, header, http_response_code, preg_match;

/**
* HTTP Operations
*/
class Http
{
/** Current */
static private RequestInterface $request;

static public function getRequest()
{
return self::$request = self::$request ?? new Request();
}

static public function setRequest($_request)
{
self::$request = $_request;
}

static public function getResponse()
{
return self::getRequest()->getResponse();
}


/**
* Secure data in array
* Accept alphanumerics characters only
* @return array the input array whitout
* @todo Move method outside this class
*/
static public function secure(array $_data = []): array
{
return array_filter(array_map(function ($v) {
$v = basename($v);
if(!preg_match("/^[A-Za-z0-9\.\-]*$/", $v)) {
self::badRequest('Invalid data');
}
return $v;
// return \preg_replace("/[^a-zA-Z0-9]/", "", \basename(\strip_tags($v), '.php'));
}, $_data));
}

static public function end(int $_code = 500, string $data = 'Internal Error'): void
{
http_response_code($_code);
exit($data);
}

static public function response(ResponseInterface $response): void
{
header('Content-Type: ' . $response->getContentType());
self::end($response->getCode(), $response->getBody());
}

static public function ok(string $data): void
{
self::end(200, $data);
}

static public function accepted(string $data): void
{
self::end(202, $data);
}

static public function badRequest(string $msg = 'Invalid message received'): void
{
self::end(400, $msg);
}

static public function unauthorized(string $msg = 'Invalid Token'): void
{
self::end(401, $msg);
}

static public function forbidden(string $msg = 'You are not allowed to access this resource'): void
{
self::end(403, $msg);
}

static public function notFound(string $msg = 'Not found'): void
{
self::end(404, ('No route for '.$_SERVER['REQUEST_URI']. ' ('.$msg.')'));
}

static public function notAllowed(): void
{
self::end(405, ('No route for '.$_SERVER['REQUEST_METHOD'].' '.$_SERVER['REQUEST_URI']));
}

static public function notImplemented(): void
{
self::end(501, 'Not implemented');
}
}
17 changes: 17 additions & 0 deletions Http/HttpFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php


namespace Md\Http;

class HttpFactory
{
static public function createRequest(string $_method, string $_url): RequestInterface
{
return new Request();
}

static public function createResponse(): ResponseInterface
{
return new Response();
}
}
103 changes: 103 additions & 0 deletions Http/Message.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace Md\Http;

use function implode, json_encode, mb_convert_case, trim;

/**
* Class Message
* Represents a HTTP Message
*/
class Message implements MessageInterface
{
/** Define a Generic message type */
public const DEFAULT = 'application/octet-stream';

/** Define a JSON message type */
public const JSON = 'application/json';

/** Define a HTML message type */
public const HTML = 'text/html';

/** Define a XML message type */
public const XML = 'application/xml';

/** @var string $contentType The current message content-type */
private string $contentType;

/** @var string $body The current message body */
private string $body;

/** @var string $data The current message body as array */
private array $data;

/**
* Initialize a new HTTP Message with specified content-type and empty body
* @param string $_contentType The message content-type or Message::DEFAULT if not defined
* @param string $_body The message body or empty if not defined
*/
public function __construct(string $_contentType = Message::DEFAULT, string $_body = '')
{
$this->withContentType($_contentType)->withBody($_body);
}

/**
* Get the current message content-type
* @return string The message content-type
*/
public function getContentType(): string
{
return $this->contentType;
}

/**
* Set the current message content-type
* @param string $_contentType The content-type to apply
* @return self
*/
public function withContentType(string $_contentType): MessageInterface
{
$this->contentType = mb_convert_case($_contentType, MB_CASE_LOWER);
return $this;
}

/**
* Get the current message body
* @return string The message body
*/
public function getBody(): string
{
return $this->body;
}


/**
* Set the current message body
* @param string $_body The message body
* @return self
*/
public function withBody(string $_body): MessageInterface
{
$this->body = trim($_body);
return $this;
}


/*public function getData(): array
{
return [$this->body];
}
public function withData(array $_data): MessageInterface
{
if($this->contentType === Message::JSON) {
return $this->withBody(json_encode($_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
}

$s = [];
foreach($_data as $k => $v) {
$s[] = ($k.'='.$v);
}

return $this->withBody(implode(";", $s));
}*/
}
50 changes: 50 additions & 0 deletions Http/MessageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Md\Http;

/**
* Interface MessageInterface
* Represents a HTTP Message
*
*/
interface MessageInterface
{
/**
* Get the current message content-type
* @return string The message content-type
*/
public function getContentType(): string;

/**
* Set the current message content-type
* @param string $_contentType The content-type to apply
* @return MessageInterface
*/
public function withContentType(string $_contentType): MessageInterface;

/**
* Get the current message body
* @return string The message body
*/
public function getBody(): string;

/**
* Set the current message body
* @param string $_body The message body
* @return MessageInterface
*/
public function withBody(string $_body): MessageInterface;


/**
* Get the current message body as array
* @return string The message body
*/
//public function getData(): array;
/**
* Set the current message body
* @param array $_data The message body to parse.
* @return MessageInterface
*/
//public function withData(array $_data): MessageInterface;
}
69 changes: 69 additions & 0 deletions Http/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Md\Http;

use function explode, parse_str, file_get_contents;

class Request extends Message implements RequestInterface
{
private UriInterface $uri;
//private array $route;
private string $method;


public function __construct(?UriInterface $_uri = null)
{
parent::__construct(explode(',', $_SERVER['HTTP_ACCEPT'] ?? Message::HTML)[0] ?? Message::HTML);
$this->setMethod($_SERVER['REQUEST_METHOD'] ?? 'GET');
$this->uri = $_uri ?? new Uri($_SERVER['REQUEST_URI'] ?? '/');
//$this->route = $this->uri->getParts();
}

public function setMethod(string $_method): RequestInterface
{
$this->method = $_method;
return $this;
}

public function getMethod(): string
{
return $this->method;
}

public function getUri(): UriInterface
{
return $this->uri;
}

/*public function getRoute(int $_pos): ?string
{
return $this->route[$_pos] ?? null;
}*/

public function getData(): array
{
switch($this->method)
{
case 'GET':
case 'DELETE':
return $this->uri->getQueryArray();
break;
case 'POST':
$a = Uri::secure($_POST ?? []);
if(!empty($_FILES)) {
$a['_files'] = $_FILES;
}
return $a;
break;
case 'PATCH':
case 'PUT':
$a = [];
parse_str(file_get_contents('php://input'), $a);
return Uri::secure($a);
break;
default:
return [];
break;
}
}
}
36 changes: 36 additions & 0 deletions Http/RequestInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Md\Http;

/**
* Interface RequestInterface
* Represents the current Incoming HTTP Request (IHR)
*
*/
interface RequestInterface extends MessageInterface
{
/**
* Get current HTTP Message method
* @return string the current request method
*/
public function getMethod(): string;

/**
* Get the Uri used by the current request
* @return UriInterface the Uri used by the current request
*/
public function getUri(): UriInterface;

/**
* Get the Uri path as array
* @return array the Uri path as array
*/
//public function getRoute(int $_pos): ?string;

/**
* Get current Request HTTP data (get params, post form etc...)
* Data depends on the HTTP method used
* @return array the current request data
*/
public function getData(): array;
}
Loading