Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/initial implementation #6

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

Copy link

codecov bot commented Sep 25, 2024

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

Copy link
Member

@sitepark-schaeper sitepark-schaeper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all - I had to finish this up since it's getting late and github unfortunatly does not save pending comments. So some methods might not have gotten the attention they deserve, but with the rather architectual concerns I address here I think it's not worth investing too much time in these smaller chunks before those are settled.
With that out of the way, I wrote some (unstructured) thoughts down that I had while reading through your code and would like to discuss them with you:

I've ignored the translations so far, but is the .translation-cach directory intended to be checked in?

Why are Layouts Elements?

The names of email specific classes are a bit wordy in my opinon. For example, Dto/Email/EmailHtmlMessageRendererResult could just be Dto/Email/RenderingResult, right?

A few classes here include the term Model, which I don't quite understand what it means in this context. May it just be a Dto?

There are a lot of mutable properties in the Dtos which I did not find why. Do we really need to expose these (and if so, can we properly differentiate them)?

We might have gone a little bit overboard with the array typing here. It's really hard to review it and figure out what is a class, what is just an array structure and which of their properties are actually gurantieed to be typed as defined and which might not. As such I did "skip" some of the implementations (like FormDataModelFactory) because I did not have the time to comprehend them. I feel like this complexity and mental overhead is not neccessary and we could just type out most of these as classes.
This also applies to all the $options (for which it is also difficult to figure out what exactly is beeing configured and from where). I get that it's hard to declare these but having it as just array<string, mixed> but checking for explicit values seems like a red flag.

Another reoccuring theme seem to be nullable array types. I don't think there is a reason for an array that is allowed to be empty to also be nullable. an alternative would be something like ?non-empty-array<string, string> but that is even less intuitive.

Then there are classes with comments saying "not yet implemented". I get that creating them helps development but do they need to be checked in?

Lastly a couple of class comments could be nice. For example the Constraint interface might profit from a small sentence explaining what it is, why it exists and what it's used for. To be clear - I don't want to be pedantic and don't think it's too big of a deal, I just think someone that does not happen to have the context could have a hard time figuring this out where all it takes are 20ish words.

Comment on lines +15 to +16
with:
phpVersions: '["8.2","8.3"]'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we verify with 8.2 and 8.3 but release with 8.4?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One dependency is not yet PHP 8.4 ready. I'll change this when it's solved, see: phpro/api-problem-bundle#27

src/Dto/FormSubmission.php Outdated Show resolved Hide resolved
* } $options
* @throws Html2TextException
* @throws TransportExceptionInterface
* @throws Exception
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what Exception? under what circumstances?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/Processor/EmailSender.php Outdated Show resolved Hide resolved
src/Processor/EmailSender.php Show resolved Hide resolved
Comment on lines +145 to +180
private function identifyType(Control $control, array $schema): string
{

$type = $schema['type'] ?? '';
$format = $schema['format'] ?? '';

if ($type === 'string' && $format === 'data-url') {
return 'file';
}

if ($type === 'string' && $format === 'html') {
return 'html';
}

if ($type === 'boolean') {
return 'checkbox';
}

if ($type === 'array' && isset($schema['items']['oneOf'])) {
return 'checkbox-group';
}

if (
$type === 'string'
&& isset($schema['oneOf'])
&& ($control->options['format'] ?? '') === 'radio') {
return 'radio-buttons';
}

if ($type === 'string' && isset($schema['oneOf'])
) {
return 'select';
}

return 'text';
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know the values $schema can contain, but this implementation would return 'text' for basically anything since there is no validation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, text is the fallback.

UISchema and Json schema are used to identify which UI component is to be used.

See https://sitepark.github.io/atoolo-docs/develop/form/controls/#json-schema

Without fallback, it would mean that new components can only be generated once the FEDS module has been updated. With fallback, it makes the system more stable during an update process.

Comment on lines 39 to 41
if ($control->scope === null) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean for a Control not to have a $scope? Why are we not processing these cases? Or should this just straight up not be possible?

Copy link
Member Author

@sitepark-veltrup sitepark-veltrup Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +62 to +64
function ($data, $schema) use ($constraint) {
return $constraint->check($data, $schema);
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function does not need to bind $this, it should probably be static.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I don't understand what you mean. Where is $this bind.

Comment on lines +33 to +35
if (!is_string($value)) {
throw new CustomError('Value is not a string');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be something that is cought by the JsonSchemaValidator? I mean we don't also check weather or not a field expecting a number actually is one right? so why do we need to check if a data-url is a string? or could this constraint technically be configured to any field? if so, is that not validated either? does this have to err at runtime?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be that the JsonSchemaValidator already checks this beforehand, since we have defined String as the type.
But since the method is passed a mixed, I have to check that anyway, so that phpstan is satisfied.

Comment on lines +17 to +48
/**
* @param array<mixed>|object $array
* @return array<string,mixed>|array<mixed> $array
*/
public function objectToArrayRecursive(mixed $array): array
{
if (is_array($array)) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = $this->objectToArrayRecursive($value);
}
if ($value instanceof stdClass) {
$array[$key] = $this->objectToArrayRecursive((array) $value);
}
}
}
if ($array instanceof stdClass) {
return $this->objectToArrayRecursive((array) $array);
}
/** @var array<string,mixed>|array<mixed> $array */
return $array;
}

/**
* @param array<mixed>|array<string,mixed> $array
* @throws \JsonException
*/
public function arrayToObjectRecursive(array $array): object
{
$json = json_encode($array, JSON_THROW_ON_ERROR);
return (object) json_decode($json, false, 512, JSON_THROW_ON_ERROR);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These don't seem like Platform reliant functions; It looks a bit like this is beeing (ab)used as a Util class.
Are these functions really that commonly required? if so - why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The methods are only used once. I have pulled them out so that I can test them individually.
I don't want an Util class. What could I call them?

@sitepark-veltrup
Copy link
Member Author

Why are Layouts Elements?

https://jsonforms.io/docs/uischema/layouts#elements

Layouts can be nested.

Layouts have an elements attribute in which further layouts or controls can be contained. Both are elements of the elements list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants