Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.83% covered (warning)
70.83%
34 / 48
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ShowProfile
70.83% covered (warning)
70.83%
34 / 48
33.33% covered (danger)
33.33%
1 / 3
20.58
0.00% covered (danger)
0.00%
0 / 1
 buildFields
47.83% covered (danger)
47.83%
11 / 23
0.00% covered (danger)
0.00%
0 / 1
24.20
 canBeDisplayed
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
5.02
 __construct
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\HtmlBuilders\Components\Layout;
3
4use Apie\Core\Context\ApieContext;
5use Apie\Core\ContextConstants;
6use Apie\Core\Entities\EntityInterface;
7use Apie\Core\ValueObjects\Utils;
8use Apie\HtmlBuilders\Components\BaseComponent;
9use Apie\HtmlBuilders\Configuration\CurrentConfiguration;
10use Apie\Serializer\Serializer;
11use DateTimeInterface;
12use ReflectionClass;
13use Stringable;
14use Symfony\Component\PropertyAccess\PropertyAccessorBuilder;
15
16class ShowProfile extends BaseComponent
17{
18    private const PROFILE_FIELDS = [
19        ['email', 'username', 'id'],
20        ['fullName', 'name', 'firstName', 'lastName'],
21    ];
22
23    /**
24     * @return array<string, string>
25     */
26    private function buildFields(EntityInterface $user, ApieContext $apieContext): array
27    {
28        $fields = [];
29        if ($apieContext->hasContext(Serializer::class)) {
30            $serializer = $apieContext->getContext(Serializer::class);
31            assert($serializer instanceof Serializer);
32            $allFields = Utils::toArray(
33                $serializer->normalize($user, $apieContext->withContext(ContextConstants::SHOW_PROFILE, true))
34            );
35            foreach (self::PROFILE_FIELDS as $profileFieldList) {
36                foreach ($profileFieldList as $profileField) {
37                    if (isset($allFields[$profileField])) {
38                        if ($this->canBeDisplayed($allFields[$profileField])) {
39                            $fields[$profileField] = Utils::toString($allFields[$profileField]);
40                        }
41                        break;
42                    }
43                }
44            }
45            return $fields;
46        }
47        $propertyAccess = (new PropertyAccessorBuilder())->getPropertyAccessor();
48        foreach (self::PROFILE_FIELDS as $profileFieldList) {
49            foreach ($profileFieldList as $profileField) {
50                if ($propertyAccess->isReadable($user, $profileField)) {
51                    $fieldValue = $propertyAccess->getValue($user, $profileField);
52                    if ($this->canBeDisplayed($fieldValue)) {
53                        $fields[$profileField] = Utils::toString($fieldValue);
54                    }
55                    break;
56                }
57            }
58        }
59        return $fields;
60    }
61
62    private function canBeDisplayed(mixed $value): bool
63    {
64        if (!is_object($value)) {
65            return true;
66        }
67        if ($value instanceof Stringable || $value instanceof DateTimeInterface) {
68            return true;
69        }
70        return ((new ReflectionClass($value))->isEnum());
71    }
72
73    public function __construct(
74        CurrentConfiguration $currentConfiguration,
75        EntityInterface $user
76    ) {
77        $fields = $this->buildFields($user, $currentConfiguration->getApieContext());
78        $baseClass = $user->getId()::getReferenceFor();
79        $boundedContextId = $currentConfiguration->getSelectedBoundedContextId();
80        $boundedContextId = $currentConfiguration->getBoundedContextHashmap()->getBoundedContextFromClassName(
81            new ReflectionClass($user),
82            $boundedContextId
83        )?->getId() ?? $boundedContextId;
84        
85        $profileUrl = $currentConfiguration->getGlobalUrl(
86            $boundedContextId . '/resource/' . $baseClass->getShortName() . '/' . $user->getId()->toNative()
87        );
88        parent::__construct(
89            [
90                'user' => $user,
91                'email' => $fields['email'] ?? null,
92                'profileUrl' => $profileUrl,
93                'gravatarUrl' => 'https://gravatar.com/avatar/' . md5(strtolower($fields['email'] ?? '')),
94                'fieldNames' => array_keys($fields),
95                'fields' => $fields,
96            ]
97        );
98    }
99}