Skip to content

Commit

Permalink
Add PhpService so we can mock/test calles to ini_get(), etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
fisharebest committed Jan 6, 2025
1 parent 24cb754 commit cba20eb
Show file tree
Hide file tree
Showing 25 changed files with 144 additions and 455 deletions.
10 changes: 7 additions & 3 deletions app/Factories/ImageFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use Fisharebest\Webtrees\MediaFile;
use Fisharebest\Webtrees\Mime;
use Fisharebest\Webtrees\Registry;
use Fisharebest\Webtrees\Services\PhpService;
use Fisharebest\Webtrees\Webtrees;
use Imagick;
use Intervention\Gif\Exceptions\NotReadableException;
Expand All @@ -44,7 +45,6 @@

use function addcslashes;
use function basename;
use function extension_loaded;
use function get_class;
use function implode;
use function pathinfo;
Expand Down Expand Up @@ -76,6 +76,10 @@ class ImageFactory implements ImageFactoryInterface
'image/webp' => 'webp',
];

public function __construct(private PhpService $php_service)

Check failure on line 79 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Parameter $php_service of method Fisharebest\Webtrees\Factories\ImageFactory::__construct() has invalid type Fisharebest\Webtrees\Services\PhpService.

Check failure on line 79 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Property Fisharebest\Webtrees\Factories\ImageFactory::$php_service has unknown class Fisharebest\Webtrees\Services\PhpService as its type.

Check failure on line 79 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Parameter $php_service of method Fisharebest\Webtrees\Factories\ImageFactory::__construct() has invalid type Fisharebest\Webtrees\Services\PhpService.

Check failure on line 79 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Property Fisharebest\Webtrees\Factories\ImageFactory::$php_service has unknown class Fisharebest\Webtrees\Services\PhpService as its type.
{
}

/**
* Send the original file - either inline or as a download.
*/
Expand Down Expand Up @@ -305,11 +309,11 @@ protected function imageResponse(string $data, string $mime_type, string $filena
*/
protected function imageManager(): ImageManager
{
if (extension_loaded(extension: 'imagick')) {
if ($this->php_service->extensionLoaded(extension: 'imagick')) {

Check failure on line 312 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.

Check failure on line 312 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.
return new ImageManager(driver: new ImagickDriver());
}

if (extension_loaded(extension: 'gd')) {
if ($this->php_service->extensionLoaded(extension: 'gd')) {

Check failure on line 316 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.

Check failure on line 316 in app/Factories/ImageFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.
return new ImageManager(driver: new GdDriver());
}

Expand Down
11 changes: 3 additions & 8 deletions app/Factories/SlugFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

use Fisharebest\Webtrees\Contracts\SlugFactoryInterface;
use Fisharebest\Webtrees\GedcomRecord;
use Fisharebest\Webtrees\Services\PhpService;
use Transliterator;

use function extension_loaded;
use function in_array;
use function preg_replace;
use function strip_tags;
Expand All @@ -36,9 +36,9 @@ class SlugFactory implements SlugFactoryInterface
{
private Transliterator|null $transliterator = null;

public function __construct()
public function __construct(private PhpService $php_service)

Check failure on line 39 in app/Factories/SlugFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Parameter $php_service of method Fisharebest\Webtrees\Factories\SlugFactory::__construct() has invalid type Fisharebest\Webtrees\Services\PhpService.

Check failure on line 39 in app/Factories/SlugFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Property Fisharebest\Webtrees\Factories\SlugFactory::$php_service has unknown class Fisharebest\Webtrees\Services\PhpService as its type.

Check failure on line 39 in app/Factories/SlugFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Parameter $php_service of method Fisharebest\Webtrees\Factories\SlugFactory::__construct() has invalid type Fisharebest\Webtrees\Services\PhpService.

Check failure on line 39 in app/Factories/SlugFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Property Fisharebest\Webtrees\Factories\SlugFactory::$php_service has unknown class Fisharebest\Webtrees\Services\PhpService as its type.
{
if (extension_loaded('intl')) {
if ($this->php_service->extensionLoaded(extension: 'intl')) {

Check failure on line 41 in app/Factories/SlugFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.

Check failure on line 41 in app/Factories/SlugFactory.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.
$ids = Transliterator::listIDs();

if ($ids !== false && in_array('Any-Latin', $ids, true) && in_array('Latin-ASCII', $ids, true)) {
Expand All @@ -47,11 +47,6 @@ public function __construct()
}
}

/**
* @param GedcomRecord $record
*
* @return string
*/
public function make(GedcomRecord $record): string
{
$slug = strip_tags($record->fullName());
Expand Down
12 changes: 3 additions & 9 deletions app/Http/Middleware/CompressResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@

namespace Fisharebest\Webtrees\Http\Middleware;

use Fisharebest\Webtrees\Services\PhpService;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

use function extension_loaded;
use function gzdeflate;
use function gzencode;
use function in_array;
Expand All @@ -50,14 +50,8 @@ class CompressResponse implements MiddlewareInterface
'image/svg+xml',
];

protected StreamFactoryInterface $stream_factory;

/**
* @param StreamFactoryInterface $stream_factory
*/
public function __construct(StreamFactoryInterface $stream_factory)
public function __construct(private PhpService $php_service, private StreamFactoryInterface $stream_factory)

Check failure on line 53 in app/Http/Middleware/CompressResponse.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Parameter $php_service of method Fisharebest\Webtrees\Http\Middleware\CompressResponse::__construct() has invalid type Fisharebest\Webtrees\Services\PhpService.

Check failure on line 53 in app/Http/Middleware/CompressResponse.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Property Fisharebest\Webtrees\Http\Middleware\CompressResponse::$php_service has unknown class Fisharebest\Webtrees\Services\PhpService as its type.

Check failure on line 53 in app/Http/Middleware/CompressResponse.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Parameter $php_service of method Fisharebest\Webtrees\Http\Middleware\CompressResponse::__construct() has invalid type Fisharebest\Webtrees\Services\PhpService.

Check failure on line 53 in app/Http/Middleware/CompressResponse.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Property Fisharebest\Webtrees\Http\Middleware\CompressResponse::$php_service has unknown class Fisharebest\Webtrees\Services\PhpService as its type.
{
$this->stream_factory = $stream_factory;
}

/**
Expand Down Expand Up @@ -103,7 +97,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
protected function compressionMethod(RequestInterface $request): string|null
{
$accept_encoding = strtolower($request->getHeaderLine('accept-encoding'));
$zlib_available = extension_loaded('zlib');
$zlib_available = $this->php_service->extensionLoaded(extension: 'zlib');

Check failure on line 100 in app/Http/Middleware/CompressResponse.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.3)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.

Check failure on line 100 in app/Http/Middleware/CompressResponse.php

View workflow job for this annotation

GitHub Actions / phpstan (ubuntu-latest, 8.4)

Call to method extensionLoaded() on an unknown class Fisharebest\Webtrees\Services\PhpService.

if ($zlib_available) {
if (str_contains($accept_encoding, 'gzip')) {
Expand Down
41 changes: 6 additions & 35 deletions app/Http/Middleware/EmitResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace Fisharebest\Webtrees\Http\Middleware;

use Fisharebest\Webtrees\Services\PhpService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
Expand All @@ -27,7 +28,6 @@

use function connection_status;
use function fastcgi_finish_request;
use function function_exists;
use function header;
use function header_remove;
use function headers_sent;
Expand All @@ -46,12 +46,10 @@ class EmitResponse implements MiddlewareInterface
// Stream the output in chunks.
private const int CHUNK_SIZE = 65536;

/**
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
*
* @return ResponseInterface
*/
public function __construct(private PhpService $php_service)
{
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
Expand All @@ -73,11 +71,6 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $response;
}

/**
* Remove the default PHP header.
*
* @return void
*/
private function removeDefaultPhpHeaders(): void
{
header_remove('X-Powered-By');
Expand All @@ -86,10 +79,6 @@ private function removeDefaultPhpHeaders(): void
header_remove('Pragma');
}

/**
* @return void
* @throws RuntimeException
*/
private function assertHeadersNotEmitted(): void
{
if (headers_sent($file, $line)) {
Expand All @@ -99,10 +88,6 @@ private function assertHeadersNotEmitted(): void
}
}

/**
* @return void
* @throws RuntimeException
*/
private function assertBodyNotEmitted(): void
{
if (ob_get_level() > 0 && ob_get_length() > 0) {
Expand All @@ -113,9 +98,6 @@ private function assertBodyNotEmitted(): void
}
}

/**
* @param ResponseInterface $response
*/
private function emitStatusLine(ResponseInterface $response): void
{
http_response_code($response->getStatusCode());
Expand All @@ -128,9 +110,6 @@ private function emitStatusLine(ResponseInterface $response): void
));
}

/**
* @param ResponseInterface $response
*/
private function emitHeaders(ResponseInterface $response): void
{
foreach ($response->getHeaders() as $name => $values) {
Expand All @@ -144,11 +123,6 @@ private function emitHeaders(ResponseInterface $response): void
}
}

/**
* @param ResponseInterface $response
*
* @return void
*/
private function emitBody(ResponseInterface $response): void
{
$body = $response->getBody();
Expand All @@ -162,12 +136,9 @@ private function emitBody(ResponseInterface $response): void
}
}

/**
* @return void
*/
private function closeConnection(): void
{
if (function_exists('fastcgi_finish_request')) {
if ($this->php_service->functionExists(function: 'fastcgi_finish_request')) {
fastcgi_finish_request();
}
}
Expand Down
21 changes: 10 additions & 11 deletions app/Http/Middleware/HandleExceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Fisharebest\Webtrees\Http\ViewResponseTrait;
use Fisharebest\Webtrees\Log;
use Fisharebest\Webtrees\Registry;
use Fisharebest\Webtrees\Services\PhpService;
use Fisharebest\Webtrees\Services\TreeService;
use Fisharebest\Webtrees\Site;
use Fisharebest\Webtrees\Validator;
Expand All @@ -37,7 +38,6 @@

use function dirname;
use function error_get_last;
use function ini_get;
use function nl2br;
use function ob_end_clean;
use function ob_get_level;
Expand All @@ -56,14 +56,8 @@ class HandleExceptions implements MiddlewareInterface, StatusCodeInterface
{
use ViewResponseTrait;

private TreeService $tree_service;

/**
* @param TreeService $tree_service
*/
public function __construct(TreeService $tree_service)
public function __construct(private PhpService $php_service, private TreeService $tree_service)
{
$this->tree_service = $tree_service;
}

/**
Expand All @@ -76,11 +70,16 @@ public function __construct(TreeService $tree_service)
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// Fatal errors. We may be out of memory, so do not create any variables.
register_shutdown_function(static function (): void {
register_shutdown_function(callback: function (): void {
if (error_get_last() !== null && error_get_last()['type'] & E_ERROR) {
// If PHP does not display the error, then we must display it.
if (ini_get('display_errors') !== '1') {
echo error_get_last()['message'], '<br><br>', error_get_last()['file'], ': ', error_get_last()['line'];
if (!$this->php_service->displayErrors()) {
echo
error_get_last()['message'],
'<br><br>',
error_get_last()['file'],
': ',
error_get_last()['line'];
}
}
});
Expand Down
15 changes: 7 additions & 8 deletions app/Http/RequestHandlers/ExportGedcomPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,31 @@

use Fisharebest\Webtrees\Http\ViewResponseTrait;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Services\PhpService;
use Fisharebest\Webtrees\Validator;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

use function date;
use function e;
use function extension_loaded;
use function pathinfo;
use function strtolower;
use function substr;

use const PATHINFO_EXTENSION;

/**
* Show download forms/optiosn.
* Show download forms/options.
*/
class ExportGedcomPage implements RequestHandlerInterface
{
use ViewResponseTrait;

/**
* @param ServerRequestInterface $request
*
* @return ResponseInterface
*/
public function __construct(private PhpService $php_service)
{
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$tree = Validator::attributes($request)->tree();
Expand All @@ -73,7 +72,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
'filename' => $filename,
'title' => $title,
'tree' => $tree,
'zip_available' => extension_loaded('zip'),
'zip_available' => $this->php_service->extensionLoaded('zip'),
]);
}
}
Loading

0 comments on commit cba20eb

Please sign in to comment.