Merge branch 'develop' into 1.8

Signed-off-by: Andy Miller <rhuk@mac.com>
This commit is contained in:
Andy Miller
2025-03-31 19:32:54 -06:00
5 changed files with 71 additions and 36 deletions

View File

@@ -10,20 +10,18 @@ permissions:
contents: read # to fetch code (actions/checkout)
jobs:
unit-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
php: [8.4, 8.3, 8.2]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
runs-on: ${{ matrix.os }}
- name: Setup PHP
steps:
- uses: actions/checkout@v4
- name: Setup PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
@@ -31,17 +29,11 @@ jobs:
tools: composer:v2
coverage: none
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Update composer
# run: composer update
#
# - name: Validate composer.json and composer.lock
# run: composer validate
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v4

View File

@@ -196,6 +196,38 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
$messages += Validation::validate($child, $rule);
if (isset($rule['validate']['match']) || isset($rule['validate']['match_exact']) || isset($rule['validate']['match_any'])) {
$ruleKey = current(array_intersect(['match', 'match_exact', 'match_any'], array_keys($rule['validate'])));
$otherKey = $rule['validate'][$ruleKey] ?? null;
$otherVal = $data[$otherKey] ?? null;
$otherLabel = $this->items[$otherKey]['label'] ?? $otherKey;
$currentVal = $data[$key] ?? null;
$currentLabel = $this->items[$key]['label'] ?? $key;
// Determine comparison type (loose, strict, substring)
// Perform comparison:
$isValid = false;
if ($ruleKey === 'match') {
$isValid = ($currentVal == $otherVal);
} elseif ($ruleKey === 'match_exact') {
$isValid = ($currentVal === $otherVal);
} elseif ($ruleKey === 'match_any') {
// If strings:
if (is_string($currentVal) && is_string($otherVal)) {
$isValid = (strlen($currentVal) && strlen($otherVal) && (str_contains($currentVal,
$otherVal) || strpos($otherVal, $currentVal) !== false));
}
// If arrays:
if (is_array($currentVal) && is_array($otherVal)) {
$common = array_intersect($currentVal, $otherVal);
$isValid = !empty($common);
}
}
if (!$isValid) {
$messages[$rule['name']][] = sprintf(Grav::instance()['language']->translate('PLUGIN_FORM.VALIDATION_MATCH'), $currentLabel, $otherLabel);
}
}
} elseif (is_array($child) && is_array($val)) {
// Array has been defined in blueprints.
$messages += $this->validateArray($child, $val, $strict);

View File

@@ -47,12 +47,14 @@ class Validation
}
$validate = (array)($field['validate'] ?? null);
$type = $validate['type'] ?? $field['type'];
$validate_type = $validate['type'] ?? null;
$required = $validate['required'] ?? false;
$type = $validate_type ?? $field['type'];
$required = $required && ($validate_type !== 'ignore');
// If value isn't required, we will stop validation if empty value is given.
if ($required !== true && ($value === null || $value === '' || (($field['type'] === 'checkbox' || $field['type'] === 'switch') && $value == false))
) {
if ($required !== true && ($value === null || $value === '' || empty($value) || (($field['type'] === 'checkbox' || $field['type'] === 'switch') && $value == false))) {
return [];
}

View File

@@ -26,7 +26,7 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme
* @par ArrayCollection
* @phpstan-var ArrayCollection<TKey,T>
*/
protected ?\Doctrine\Common\Collections\Collection $collection = null;
protected $collection;
/**
* {@inheritDoc}

View File

@@ -16,11 +16,14 @@ use InvalidArgumentException;
use JsonSerializable;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
use ReturnTypeWillChange;
use RuntimeException;
use function copy;
use function fopen;
use function is_string;
use function sprintf;
use const UPLOAD_ERR_NO_FILE;
use const UPLOAD_ERR_OK;
/**
* Class FormFlashFile
@@ -29,11 +32,15 @@ use function sprintf;
class FormFlashFile implements UploadedFileInterface, JsonSerializable
{
/** @var string */
private $id;
private string $id;
/** @var string */
private string $field;
/** @var bool */
private $moved = false;
private bool $moved = false;
/** @var array */
private array $upload;
/** @var FormFlash */
private $flash;
private FormFlash $flash;
/**
* FormFlashFile constructor.
@@ -41,14 +48,16 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
* @param array $upload
* @param FormFlash $flash
*/
public function __construct(private readonly string $field, private array $upload, FormFlash $flash)
public function __construct(string $field, array $upload, FormFlash $flash)
{
$this->id = $flash->getId() ?: $flash->getUniqueId();
$this->field = $field;
$this->upload = $upload;
$this->flash = $flash;
$tmpFile = $this->getTmpFile();
if (!$tmpFile && $this->isOk()) {
$this->upload['error'] = \UPLOAD_ERR_NO_FILE;
$this->upload['error'] = UPLOAD_ERR_NO_FILE;
}
if (!isset($this->upload['size'])) {
@@ -59,7 +68,7 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return StreamInterface
*/
public function getStream()
public function getStream(): StreamInterface
{
$this->validateActive();
@@ -80,7 +89,7 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
* @param string $targetPath
* @return void
*/
public function moveTo($targetPath)
public function moveTo($targetPath): void
{
$this->validateActive();
@@ -120,7 +129,7 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return int
*/
public function getSize()
public function getSize(): int
{
return $this->upload['size'];
}
@@ -128,15 +137,15 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return int
*/
public function getError()
public function getError(): int
{
return $this->upload['error'] ?? \UPLOAD_ERR_OK;
return $this->upload['error'] ?? UPLOAD_ERR_OK;
}
/**
* @return string
*/
public function getClientFilename()
public function getClientFilename(): string
{
return $this->upload['name'] ?? 'unknown';
}
@@ -144,7 +153,7 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return string
*/
public function getClientMediaType()
public function getClientMediaType(): string
{
return $this->upload['type'] ?? 'application/octet-stream';
}
@@ -172,7 +181,7 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return string
*/
public function getDestination()
public function getDestination(): string
{
return $this->upload['path'] ?? '';
}
@@ -180,8 +189,8 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return array
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
#[ReturnTypeWillChange]
public function jsonSerialize(): array
{
return $this->upload;
}
@@ -220,7 +229,7 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
/**
* @return array
*/
#[\ReturnTypeWillChange]
#[ReturnTypeWillChange]
public function __debugInfo()
{
return [
@@ -255,6 +264,6 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
*/
private function isOk(): bool
{
return \UPLOAD_ERR_OK === $this->getError();
return UPLOAD_ERR_OK === $this->getError();
}
}