Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/fix-style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
php-version: 8.1

- name: Install dependencies
run: composer install
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"require": {
"php": "^8.0",
"guzzlehttp/guzzle": "^7.3",
"guzzlehttp/guzzle": "^7.4.5",
"jakeasmith/http_build_url": "^1.0.1",
"league/container": "^4.2",
"monolog/monolog": "^2.3",
Expand All @@ -35,7 +35,7 @@
"slim/slim": "^4.8",
"spatie/browsershot": "^3.52",
"spatie/phpunit-watcher": "^1.23",
"vimeo/psalm": "^4.22"
"vimeo/psalm": "^4.23"
},
"suggest": {
"spatie/browsershot": "Required to execute Javascript in spiders"
Expand Down
59 changes: 30 additions & 29 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Downloader/Downloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ public function prepare(Request $request): void
}
}

/** @var RequestSending $event */
/**
* @psalm-suppress UnnecessaryVarAnnotation
*
* @var RequestSending $event
*/
$event = $this->eventDispatcher->dispatch(
new RequestSending($request),
RequestSending::NAME,
Expand Down
126 changes: 126 additions & 0 deletions src/ItemPipeline/AbstractItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2022 Kai Sassnowski
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @see https://github.com/roach-php/roach
*/

namespace RoachPHP\ItemPipeline;

use InvalidArgumentException;
use ReflectionClass;
use ReflectionException;
use ReflectionProperty;
use RoachPHP\Support\Droppable;
use RuntimeException;

abstract class AbstractItem implements ItemInterface
{
use Droppable;

final public function all(): array
{
$reflectionClass = new ReflectionClass($this);
$properties = $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC);

return \array_reduce(
$properties,
function (array $data, ReflectionProperty $property): array {
/** @psalm-suppress MixedAssignment */
$data[$property->getName()] = $property->getValue($this);

return $data;
},
[],
);
}

final public function get(string $key, mixed $default = null): mixed
{
$reflectionClass = new ReflectionClass($this);

try {
$property = $reflectionClass->getProperty($key);
} catch (ReflectionException) {
return $default;
}

if (!$property->isPublic()) {
return $default;
}

return $property->getValue($this) ?: $default;
}

final public function set(string $key, mixed $value): ItemInterface
{
$reflectionClass = new ReflectionClass($this);

try {
$property = $reflectionClass->getProperty($key);
} catch (ReflectionException) {
throw new InvalidArgumentException(
\sprintf('No public property %s exists on class %s', $key, static::class),
);
}

if (!$property->isPublic()) {
throw new InvalidArgumentException(
\sprintf('No public property %s exists on class %s', $key, static::class),
);
}

$property->setValue($this, $value);

return $this;
}

final public function has(string $key): bool
{
$reflectionClass = new ReflectionClass($this);

try {
$property = $reflectionClass->getProperty($key);

return $property->isPublic();
} catch (ReflectionException) {
return false;
}
}

final public function offsetExists(mixed $offset): bool
{
return $this->has($offset);
}

final public function offsetGet(mixed $offset): mixed
{
/** @psalm-suppress DocblockTypeContradiction */
if (!\is_string($offset)) {
throw new InvalidArgumentException('Offset needs to be a string');
}

/** @psalm-suppress MixedReturnStatement */
return $this->get($offset);
}

final public function offsetSet(mixed $offset, mixed $value): void
{
if (!\is_string($offset)) {
throw new InvalidArgumentException('Offset needs to be a string');
}

$this->set($offset, $value);
}

final public function offsetUnset(mixed $offset): void
{
throw new RuntimeException('Unsetting properties is not supported for custom item classes');
}
}
9 changes: 5 additions & 4 deletions src/ItemPipeline/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,24 @@ public function has(string $key): bool
return isset($this->data[$key]);
}

public function offsetExists($offset): bool
public function offsetExists(mixed $offset): bool
{
return isset($this->data[$offset]);
}

public function offsetGet($offset): mixed
public function offsetGet(mixed $offset): mixed
{
/** @psalm-suppress MixedReturnStatement */
return $this->data[$offset];
}

public function offsetSet($offset, $value): void
public function offsetSet(mixed $offset, mixed $value): void
{
/** @psalm-suppress PossiblyNullArrayOffset */
$this->data[$offset] = $value;
}

public function offsetUnset($offset): void
public function offsetUnset(mixed $offset): void
{
unset($this->data[$offset]);
}
Expand Down
Loading