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
5 changes: 4 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
run: vendor/bin/rector process --dry-run --ansi

tests:
name: Unit tests
name: Unit tests & PHPStan static analysis
runs-on: "ubuntu-22.04"
timeout-minutes: 15

Expand Down Expand Up @@ -87,6 +87,9 @@ jobs:
- name: Run unit test suite
run: composer test

- name: Run PHPStan analysis
run: composer run-script phpstan

integration-tests:
name: Runs integration tests
runs-on: "ubuntu-22.04"
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
"ibexa/rest": "~5.0.x-dev",
"ibexa/test-core": "~5.0.x-dev",
"matthiasnoback/symfony-dependency-injection-test": "^5.0",
"phpunit/phpunit": "^9.6"
"phpunit/phpunit": "^9.6",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-symfony": "^2.0"
},
"autoload": {
"psr-4": {
Expand Down Expand Up @@ -65,6 +68,7 @@
"scripts": {
"fix-cs": "php-cs-fixer fix --config=.php-cs-fixer.php -v --show-progress=dots",
"check-cs": "@fix-cs --dry-run",
"phpstan": "phpstan analyse",
"test": "phpunit -c phpunit.xml.dist",
"test-integration": "phpunit -c phpunit.integration.xml.dist"
}
Expand Down
1,441 changes: 1,441 additions & 0 deletions phpstan-baseline.neon

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-symfony/extension.neon
- phpstan-baseline.neon

parameters:
level: 8
treatPhpDocTypesAsCertain: false
paths:
- src
- tests
4 changes: 2 additions & 2 deletions src/lib/Behat/Context/FieldTypeFormContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ final class FieldTypeFormContext extends RawMinkContext implements SnippetAccept
{
private static string $fieldIdentifier = 'field';

/** @var array<string, string> */
private static array $fieldTypeIdentifierMap = [
'user' => 'ezuser',
'textline' => 'ezstring',
'selection' => 'ezselection',
];

/** @var \Ibexa\ContentForms\Behat\Context\ContentTypeContext */
private $contentTypeContext;
private ContentTypeContext $contentTypeContext;

/** @BeforeScenario */
public function gatherContexts(BeforeScenarioScope $scope): void
Expand Down
8 changes: 8 additions & 0 deletions src/lib/Behat/Context/UserRegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ public function iSeeARegistrationConfirmationMessage(): void
*/
public function theUserAccountHasBeenCreated(): void
{
if (null === $this->registrationUsername) {
throw new \LogicException('You need to call iFillInTheFormWithValidValues before this step');
}

$this->userService->loadUserByLogin($this->registrationUsername);
}

Expand Down Expand Up @@ -324,6 +328,10 @@ public function iRegisterAUserAccount(): void
*/
public function theUserIsCreatedInThisUserGroup(string $userGroupName): void
{
if (null === $this->registrationUsername) {
throw new \LogicException('You need to call iFillInTheFormWithValidValues before this step');
}

$user = $this->userService->loadUserByLogin($this->registrationUsername);
$userGroups = $this->userService->loadUserGroupsOfUser($user);

Expand Down
6 changes: 2 additions & 4 deletions src/lib/Data/Content/ContentCreateData.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ContentCreateData extends ContentCreateStruct implements NewnessCheckable
/**
* @var \Ibexa\Contracts\Core\Repository\Values\Content\LocationCreateStruct[]
*/
private ?array $locationStructs = null;
private array $locationStructs = [];

public function isNew(): bool
{
Expand All @@ -32,16 +32,14 @@ public function isNew(): bool
/**
* @return \Ibexa\Contracts\Core\Repository\Values\Content\LocationCreateStruct[]
*/
public function getLocationStructs()
public function getLocationStructs(): array
{
return $this->locationStructs;
}

/**
* Adds a location struct.
* A location will be created out of it, bound to the created content.
*
* @param \Ibexa\Contracts\Core\Repository\Values\Content\LocationCreateStruct $locationStruct
*/
public function addLocationStruct(LocationCreateStruct $locationStruct): void
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Data/Mapper/UserUpdateMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function mapToFormData(User $user, ContentType $contentType, array $param

$filter = $params['filter'];

$fields = $user->getFieldsByLanguage($params['languageCode']);
$fields = iterator_to_array($user->getFieldsByLanguage($params['languageCode']));
foreach ($contentType->fieldDefinitions as $fieldDef) {
$field = $fields[$fieldDef->identifier];

Expand Down
4 changes: 2 additions & 2 deletions src/lib/Data/User/UserCreateData.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class UserCreateData extends UserCreateStruct implements NewnessCheckable
/**
* @var \Ibexa\Contracts\Core\Repository\Values\User\UserGroup[]
*/
private ?array $parentGroups = null;
private array $parentGroups = [];

private ?Role $role = null;

Expand All @@ -39,7 +39,7 @@ public function isNew(): bool
/**
* @return \Ibexa\Contracts\Core\Repository\Values\User\UserGroup[]
*/
public function getParentGroups()
public function getParentGroups(): array
{
return $this->parentGroups;
}
Expand Down
74 changes: 25 additions & 49 deletions src/lib/Event/FormActionEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,54 @@ class FormActionEvent extends FormEvent
{
/**
* Name of the button used to submit the form.
*
* @var string
*/
private $clickedButton;
private string $clickedButton;

/**
* Hash of options.
*
* @var array<string, mixed>
*/
private array $options;

/**
* Response to return after form post-processing. Typically a RedirectResponse.
* Response to return after form post-processing. Typically, a RedirectResponse.
*/
private ?Response $response = null;

/**
* Additional payload populated for event listeners next in priority.
*
* @var array<string, mixed>
*/
private array $payloads;

/**
* @param \Symfony\Component\Form\FormInterface $form
* @param $data
* @param $clickedButton
* @param array $options
* @param array $payloads
* @param array<string, mixed> $options
* @param array<string, mixed> $payloads
*/
public function __construct(FormInterface $form, mixed $data, $clickedButton, array $options = [], array $payloads = [])
{
public function __construct(
FormInterface $form,
mixed $data,
string $clickedButton,
array $options = [],
array $payloads = []
) {
parent::__construct($form, $data);
$this->clickedButton = $clickedButton;
$this->options = $options;
$this->payloads = $payloads;
}

/**
* @return string
*/
public function getClickedButton()
public function getClickedButton(): string
{
return $this->clickedButton;
}

/**
* @return array
* @return array<string, mixed>
*/
public function getOptions()
public function getOptions(): array
{
return $this->options;
}
Expand All @@ -73,7 +74,7 @@ public function getOptions()
*
* @return mixed
*/
public function getOption($optionName, $defaultValue = null)
public function getOption(string $optionName, mixed $defaultValue = null): mixed
{
if (!isset($this->options[$optionName])) {
return $defaultValue;
Expand All @@ -82,27 +83,16 @@ public function getOption($optionName, $defaultValue = null)
return $this->options[$optionName];
}

/**
* @param string $optionName
*
* @return bool
*/
public function hasOption($optionName): bool
public function hasOption(string $optionName): bool
{
return isset($this->options[$optionName]);
}

/**
* @return \Symfony\Component\HttpFoundation\Response
*/
public function getResponse()
public function getResponse(): ?Response
{
return $this->response;
}

/**
* @param \Symfony\Component\HttpFoundation\Response $response
*/
public function setResponse(Response $response): void
{
$this->response = $response;
Expand All @@ -114,46 +104,32 @@ public function hasResponse(): bool
}

/**
* @return array
* @return array<string, mixed>
*/
public function getPayloads(): array
{
return $this->payloads;
}

/**
* @param array $payloads
* @param array<string, mixed> $payloads
*/
public function setPayloads(array $payloads): void
{
$this->payloads = $payloads;
}

/**
* @param string $name
*
* @return bool
*/
public function hasPayload(string $name): bool
{
return isset($this->payloads[$name]);
}

/**
* @param string $name
*
* @return mixed
*/
public function getPayload(string $name)
public function getPayload(string $name): mixed
{
return $this->payloads[$name];
}

/**
* @param string $name
* @param mixed $payload
*/
public function setPayload(string $name, $payload): void
public function setPayload(string $name, mixed $payload): void
{
$this->payloads[$name] = $payload;
}
Expand Down
31 changes: 10 additions & 21 deletions src/lib/FieldType/DataTransformer/AbstractBinaryBaseTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,33 @@

use Ibexa\Contracts\Core\Repository\FieldType;
use Ibexa\Core\FieldType\Value;
use Symfony\Component\Form\Exception\TransformationFailedException;

/**
* Base transformer for binary file based field types.
*
* {@inheritdoc}
* Base transformer for binary file-based field types.
*/
abstract class AbstractBinaryBaseTransformer
{
protected FieldType $fieldType;

protected Value $initialValue;

/** @var string */
protected $valueClass;
/** @phpstan-var class-string */
protected string $valueClass;

/**
* @param \Ibexa\Contracts\Core\Repository\FieldType $fieldType
* @param \Ibexa\Core\FieldType\Value $initialValue
* @param string $valueClass
* @phpstan-param class-string $valueClass
*/
public function __construct(FieldType $fieldType, Value $initialValue, $valueClass)
public function __construct(FieldType $fieldType, Value $initialValue, string $valueClass)
{
$this->fieldType = $fieldType;
$this->initialValue = $initialValue;
$this->valueClass = $valueClass;
}

/**
* @return array|null
* @return array{file: string|null, remove: bool}
*/
public function getDefaultProperties()
public function getDefaultProperties(): array
{
return [
'file' => null,
Expand All @@ -50,23 +45,17 @@ public function getDefaultProperties()
}

/**
* @param array $value
*
* @return \Ibexa\Core\FieldType\Value
* @param array<string, mixed> $value
*
* @throws \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function getReverseTransformedValue($value)
public function getReverseTransformedValue(array $value): Value
{
if (!is_array($value)) {
throw new TransformationFailedException(sprintf('Received %s instead of an array', gettype($value)));
}

if ($value['remove']) {
return $this->fieldType->getEmptyValue();
}

/* in case file is not modified, overwrite settings only */
/* in case the file is not modified, overwrite settings only */
if (null === $value['file']) {
return clone $this->initialValue;
}
Expand Down
Loading
Loading