Compare commits

..

15 Commits

Author SHA1 Message Date
Andrei V. Goryunov ca3bb2cb0a upgrade to wellrested v5.1.1, fix 2022-07-29 09:51:37 +03:00
Andrei V. Goryunov c5f49214b5 upgrade to wellrested 5.1.1 2022-07-27 11:32:47 +03:00
Basemaster c153bc0028
provide interfaces prs/http-*-implementation 2021-04-11 14:04:34 +03:00
Andy Green e22d5889b0 back to php 7.2 - remove CI environment 2021-04-11 11:56:55 +03:00
Basemaster fb2b2ab527
Update composer.json 2021-04-11 11:47:52 +03:00
Andy Green 00ea49ded6 remove require-dev dependency 2021-04-11 11:45:07 +03:00
Basemaster 4c4b6104e4
Update README.md 2021-04-11 11:36:14 +03:00
Basemaster 6b31620314
Update README.md 2021-04-11 11:34:37 +03:00
Andy Green e6bb814a76 back to php 7.2 2021-04-11 11:30:03 +03:00
PJ Dietz 19c03b9b8b
Merge pull request #22 from wellrestedphp/fix-travis
Add xdebug.ini for Travis
2021-01-24 14:46:29 -05:00
PJ Dietz b94b01453a Add xdebug.ini for Travis 2021-01-24 14:09:01 -05:00
PJ Dietz 9db267c427 Update XDebug configuration 2021-01-22 15:56:32 -05:00
PJ Dietz 8379dd69a0 Fix copyright date in docs 2021-01-22 14:06:56 -05:00
PJ Dietz 9a4b78b84a
Merge pull request #21 from wellrestedphp/fix-extra-leading-slash-in-path
Fix issue in Router with paths beginning with multiple slashes
2020-08-27 12:41:51 -04:00
PJ Dietz 2c80da2f79 Fix issue in Router with paths beginning with multiple slashes 2020-08-27 12:29:25 -04:00
22 changed files with 110 additions and 4744 deletions

View File

@ -1,59 +0,0 @@
<?php
$finder = PhpCsFixer\Finder::create()
->files()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests');
return PhpCsFixer\Config::create()
->setFinder($finder)
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'align_multiline_comment' => true,
'array_syntax' => ['syntax' => 'short'],
'blank_line_after_opening_tag' => true,
'cast_spaces' => true,
'class_attributes_separation' => ['elements' => ['method']],
'global_namespace_import' => [
'import_classes' => true,
'import_constants' => true,
'import_functions' => true,
],
'linebreak_after_opening_tag' => true,
'lowercase_cast' => true,
'lowercase_static_reference' => true,
'method_chaining_indentation' => true,
'modernize_types_casting' => true,
'multiline_comment_opening_closing' => true,
'multiline_whitespace_before_semicolons' => true,
'native_function_casing' => true,
'no_alternative_syntax' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_mixed_echo_print' => ['use' => 'print'],
'no_short_bool_cast' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_around_offset' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unneeded_control_parentheses' => true,
'no_unused_imports' => true,
'no_useless_return' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'normalize_index_brace' => true,
'nullable_type_declaration_for_default_null_value' => true,
'ordered_imports' => [
'sort_algorithm' => 'alpha'
],
'ordered_interfaces' => [
'direction' => 'ascend',
'order' => 'alpha',
],
'single_quote' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'ternary_to_null_coalescing' => true
]);

View File

@ -1,11 +0,0 @@
language: php
php:
- "7.3"
- "7.4"
before_script:
- composer selfupdate
- composer install --prefer-source
script:
- vendor/bin/phpunit

View File

@ -1,12 +1,13 @@
WellRESTed
==========
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.3-8892BF.svg?style=flat-square)](https://php.net/)
[![Build Status](https://travis-ci.org/wellrestedphp/wellrested.svg?branch=master)](https://travis-ci.org/wellrestedphp/wellrested)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D7.2-blue)](https://php.net/)
[![Documentation Status](https://readthedocs.org/projects/wellrested/badge/?version=latest)](http://wellrested.readthedocs.org/en/latest/)
WellRESTed is a library for creating RESTful APIs and websites in PHP that provides abstraction for HTTP messages, a powerful handler and middleware system, and a flexible router.
This fork (basemaster/wellrested) is back to php 7.2 release.
### Features
- Uses [PSR-7](https://www.php-fig.org/psr/psr-7/) interfaces for requests, responses, and streams. This lets you use other PSR-7 compatable libraries seamlessly with WellRESTed.

View File

@ -1,8 +1,7 @@
{
"name": "wellrested/wellrested",
"description": "Simple PHP Library for RESTful APIs",
"name": "basemaster/wellrested",
"description": "Clone for Simple PHP Library for RESTful APIs (wellrested.org)",
"keywords": ["rest", "restful", "api", "http", "psr7", "psr-7", "psr15", "psr-15", "psr17", "psr-17"],
"homepage": "https://www.wellrested.org",
"license": "MIT",
"type": "library",
"authors": [
@ -12,27 +11,19 @@
}
],
"require": {
"php": ">=7.3",
"php": ">=7.2",
"psr/http-factory": "~1.0",
"psr/http-message": "~1.0",
"psr/http-server-handler": "~1.0",
"psr/http-server-middleware": "~1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9",
"vimeo/psalm": "^3.4"
"provide": {
"psr/http-message-implementation": "1.0",
"psr/http-factory-implementation": "1.0"
},
"autoload": {
"psr-4": {
"WellRESTed\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"WellRESTed\\": "tests",
"WellRESTed\\Test\\": "tests"
}
}
}

4452
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
version: '3.7'
services:
# PHPUnit and Composer
php:
build:
context: .
dockerfile: ./docker/php/Dockerfile
volumes:
- .:/usr/local/src/wellrested
# Documentation generator
docs:
build:
context: .
dockerfile: ./docker/docs/Dockerfile
volumes:
- .:/usr/local/src/wellrested
# Local development site
nginx:
image: nginx:1.15
ports:
- ${PORT:-8080}:80
volumes:
- .:/usr/local/src/wellrested
- ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf

View File

@ -1,7 +0,0 @@
FROM python:3-jessie
RUN pip install sphinx sphinx_rtd_theme
WORKDIR /usr/local/src/wellrested
CMD ["make", "html", "-C", "docs"]

View File

@ -1,36 +0,0 @@
server {
listen 80;
root /usr/local/src/wellrested/public;
index index.php index.html;
charset utf-8;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Front Controller
location / {
try_files $uri $uri/ /index.php?$args;
}
# Generated Code Coverage Report
location /coverage {
alias /usr/local/src/wellrested/coverage;
}
# Generated Documentation
location /docs {
alias /usr/local/src/wellrested/docs/build/html;
}
# PHP
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_buffers 8 8k;
fastcgi_buffer_size 16k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME index.php;
}
}

View File

@ -1,44 +0,0 @@
FROM php:7.3-fpm
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && \
apt-get -y install \
gettext \
libssl-dev \
unzip \
wget \
zip \
&& rm -rf /var/lib/apt/lists/*
# Install Xdebug
RUN yes | pecl install xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini
# Install Composer.
RUN curl -sS https://getcomposer.org/installer | php -- \
--filename=composer --install-dir=/usr/local/bin
# Install dumb-init.
RUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.1/dumb-init_1.2.1_amd64
RUN chmod +x /usr/local/bin/dumb-init
# Create a directory for project sources and user's home directory
RUN mkdir /usr/local/src/wellrested && \
chown -R www-data:www-data /usr/local/src/wellrested && \
chown -R www-data:www-data /var/www
# Copy entrypoint script
COPY docker/php/entrypoint /usr/local/bin
# Add symlinks for php-cs-fixer, phpunit, and psalm for easier running
RUN ln -s /usr/local/src/wellrested/vendor/bin/php-cs-fixer /usr/local/bin/php-cs-fixer
RUN ln -s /usr/local/src/wellrested/vendor/bin/phpunit /usr/local/bin/phpunit
RUN ln -s /usr/local/src/wellrested/vendor/bin/psalm /usr/local/bin/psalm
ENTRYPOINT ["entrypoint"]
CMD ["php-fpm"]
WORKDIR /usr/local/src/wellrested
USER www-data

View File

@ -1,10 +0,0 @@
#!/usr/bin/env bash
# Run CLI commands with dumb-init to allow better signal handling.
# Run PHP-FPM as PID 1.
# https://engineeringblog.yelp.com/2016/01/dumb-init-an-init-for-docker.html
if [ "$1" == 'php-fpm' ] ; then
exec php-fpm
else
exec dumb-init -- "$@"
fi

View File

@ -1,16 +0,0 @@
#!/usr/bin/env bash
EXPECTED_SIGNATURE=$(wget https://composer.github.io/installer.sig -O - -q)
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then
>&2 echo 'ERROR: Invalid installer signature'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet --filename=composer --install-dir=/usr/local/bin
RESULT=$?
rm composer-setup.php
exit $RESULT

View File

@ -25,7 +25,7 @@ master_doc = 'index'
# General information about the project.
project = u'WellRESTed'
copyright = u'202, PJ Dietz'
copyright = u'2021, PJ Dietz'
version = '5.0.0'
release = '5.0.0'

View File

@ -26,7 +26,7 @@ Licensed using the `MIT license <http://opensource.org/licenses/MIT>`_.
The MIT License (MIT)
Copyright (c) 2018 PJ Dietz
Copyright (c) 2021 PJ Dietz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
verbose="true"
>
<testsuites>
<testsuite name="unit">
<directory>./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="./coverage" />
</logging>
</phpunit>

View File

@ -1,29 +0,0 @@
<?xml version="1.0"?>
<psalm
errorLevel="2"
resolveFromConfigFile="true"
allowStringToStandInForClass="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<DocblockTypeContradiction>
<errorLevel type="suppress">
<file name="src/Message/ServerRequest.php" />
<file name="src/Message/Uri.php" />
</errorLevel>
</DocblockTypeContradiction>
<MissingClosureParamType>
<errorLevel type="suppress">
<file name="src/Message/Message.php" />
</errorLevel>
</MissingClosureParamType>
</issueHandlers>
</psalm>

View File

@ -7,7 +7,7 @@ use Iterator;
/**
* HeaderCollection provides case-insensitive access to lists of header values.
**
*
* HeaderCollection preserves the cases of keys as they are set, but treats key
* access case insensitively.
*
@ -51,7 +51,7 @@ class HeaderCollection implements ArrayAccess, Iterator
* @param string $offset
* @return bool
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return isset($this->values[strtolower($offset)]);
}
@ -60,7 +60,7 @@ class HeaderCollection implements ArrayAccess, Iterator
* @param mixed $offset
* @return string[]
*/
public function offsetGet($offset)
public function offsetGet($offset): array
{
return $this->values[strtolower($offset)];
}
@ -69,7 +69,7 @@ class HeaderCollection implements ArrayAccess, Iterator
* @param string $offset
* @param string $value
*/
public function offsetSet($offset, $value)
public function offsetSet($offset, $value): void
{
$normalized = strtolower($offset);
@ -92,7 +92,7 @@ class HeaderCollection implements ArrayAccess, Iterator
/**
* @param string $offset
*/
public function offsetUnset($offset)
public function offsetUnset($offset): void
{
$normalized = strtolower($offset);
unset($this->fields[$normalized]);
@ -107,27 +107,30 @@ class HeaderCollection implements ArrayAccess, Iterator
// -------------------------------------------------------------------------
// Iterator
public function current()
/**
* @return string[]
*/
public function current(): array
{
return $this->values[$this->keys[$this->position]];
}
public function next()
public function next(): void
{
++$this->position;
}
public function key()
public function key(): string
{
return $this->fields[$this->keys[$this->position]];
}
public function valid()
public function valid(): bool
{
return isset($this->keys[$this->position]);
}
public function rewind()
public function rewind(): void
{
$this->position = 0;
}

View File

@ -195,7 +195,7 @@ class Request extends Message implements RequestInterface
$request = clone $this;
$newHost = $uri->getHost();
$oldHost = isset($request->headers['Host']) ? $request->headers['Host'] : '';
$oldHost = $request->headers['Host'] ?? '';
if ($preserveHost === false) {
// Update Host

View File

@ -0,0 +1,25 @@
<?php
namespace WellRESTed\Message;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
class RequestFactory implements RequestFactoryInterface
{
/**
* Create a new request.
*
* @param string $method The HTTP method associated with the request.
* @param UriInterface|string $uri The URI associated with the request. If
* the value is a string, the factory MUST create a UriInterface
* instance based on it.
*
* @return RequestInterface
*/
public function createRequest(string $method, $uri): RequestInterface
{
return new Request($method, $uri);
}
}

View File

@ -117,21 +117,21 @@ class UploadedFile implements UploadedFileInterface
*
* @see http://php.net/is_uploaded_file
* @see http://php.net/move_uploaded_file
* @param string $path Path to which to move the uploaded file.
* @param string $targetPath Path to which to move the uploaded file.
* @return void
* @throws InvalidArgumentException if the $path specified is invalid.
* @throws RuntimeException on any error during the move operation, or on
* the second or subsequent call to the method.
*/
public function moveTo($path)
public function moveTo($targetPath)
{
if ($this->tmpName === null || !file_exists($this->tmpName)) {
throw new RuntimeException("File {$this->tmpName} does not exist.");
}
if (php_sapi_name() === 'cli') {
rename($this->tmpName, $path);
rename($this->tmpName, $targetPath);
} else {
move_uploaded_file($this->tmpName, $path);
move_uploaded_file($this->tmpName, $targetPath);
}
$this->moved = true;
}

View File

@ -292,7 +292,7 @@ class Uri implements UriInterface
*/
public function withScheme($scheme)
{
$scheme = $scheme ? strtolower($scheme) : '';
$scheme = strtolower($scheme ?? '');
if (!in_array($scheme, ['', 'http', 'https'])) {
throw new InvalidArgumentException('Scheme must be http, https, or empty.');
}
@ -446,7 +446,7 @@ class Uri implements UriInterface
public function withFragment($fragment)
{
$uri = clone $this;
$uri->fragment = $fragment;
$uri->fragment = $fragment ?? '';
return $uri;
}
@ -520,7 +520,7 @@ class Uri implements UriInterface
* @param string $subject
* @return string
*/
private function percentEncode($subject)
private function percentEncode(string $subject)
{
$reserved = ':/?#[]@!$&\'()*+,;=';
$reserved = preg_quote($reserved);

View File

@ -78,22 +78,21 @@ class Router implements MiddlewareInterface
ResponseInterface $response,
$next
): ResponseInterface {
// Use only the path for routing.
$requestTarget = parse_url($request->getRequestTarget(), PHP_URL_PATH);
$path = $this->getPath($request->getRequestTarget());
$route = $this->getStaticRoute($requestTarget);
$route = $this->getStaticRoute($path);
if ($route) {
return $this->dispatch($route, $request, $response, $next);
}
$route = $this->getPrefixRoute($requestTarget);
$route = $this->getPrefixRoute($path);
if ($route) {
return $this->dispatch($route, $request, $response, $next);
}
// Try each of the routes.
foreach ($this->patternRoutes as $route) {
if ($route->matchesRequestTarget($requestTarget)) {
if ($route->matchesRequestTarget($path)) {
$pathVariables = $route->getPathVariables();
if ($this->pathVariablesAttributeName) {
$request = $request->withAttribute($this->pathVariablesAttributeName, $pathVariables);
@ -113,6 +112,15 @@ class Router implements MiddlewareInterface
return $next($request, $response);
}
private function getPath(string $requestTarget): string
{
$queryStart = strpos($requestTarget, '?');
if ($queryStart === false) {
return $requestTarget;
}
return substr($requestTarget, 0, $queryStart);
}
private function dispatch(
callable $route,
ServerRequestInterface $request,
@ -270,7 +278,7 @@ class Router implements MiddlewareInterface
usort($matches, $compareByLength);
}
$bestMatch = $matches[0];
$bestMatch = array_values($matches)[0];
return $this->prefixRoutes[$bestMatch];
}

View File

@ -291,7 +291,8 @@ class RouterTest extends TestCase
public function testMatchesPathAgainstRouteWithoutQuery(): void
{
$target = '/my/path?cat=molly&dog=bear';
$path = '/my/path';
$target = $path . '?cat=molly&dog=bear';
$this->request = $this->request->withRequestTarget($target);
@ -299,11 +300,28 @@ class RouterTest extends TestCase
$this->route->getType()->willReturn(Route::TYPE_PATTERN);
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
$this->router->register('GET', $target, 'middleware');
$this->router->register('GET', $path, 'middleware');
$this->dispatch();
$this->route->matchesRequestTarget('/my/path')->shouldHaveBeenCalled();
$this->route->matchesRequestTarget($path)->shouldHaveBeenCalled();
}
public function testMatchesPathWithDuplicateLeadingSlashes(): void
{
$path = '//my/path';
$this->request = $this->request->withRequestTarget($path);
$this->route->getTarget()->willReturn($path);
$this->route->getType()->willReturn(Route::TYPE_PATTERN);
$this->route->matchesRequestTarget(Argument::cetera())->willReturn(true);
$this->router->register('GET', $path, 'middleware');
$this->dispatch();
$this->route->matchesRequestTarget($path)->shouldHaveBeenCalled();
}
// -------------------------------------------------------------------------