Skip to content

Commit

Permalink
fetch user preferences via API (#2905)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpapst committed Nov 15, 2021
1 parent 5896ae2 commit a199249
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 1 deletion.
1 change: 1 addition & 0 deletions config/packages/nelmio_api_doc.yaml
Expand Up @@ -32,6 +32,7 @@ nelmio_api_doc:
- { alias: UserCreateForm, type: App\Form\API\UserApiCreateForm, groups: [Default, Entity, User, User_Entity] }
- { alias: UserEditForm, type: App\Form\API\UserApiEditForm, groups: [Default, Entity, User, User_Entity] }
- { alias: User, type: App\Entity\User, groups: [Default] }
- { alias: UserPreference, type: App\Entity\UserPreference, groups: [Default, User_Entity] }
- { alias: UserEntity, type: App\Entity\User, groups: [Default, Entity, User, User_Entity] }
- { alias: UserCollection, type: App\Entity\User, groups: [Default, Collection, User] }
- { alias: TeamEditForm, type: App\Form\API\TeamApiEditForm, groups: [Default, Entity, Team, Team_Entity] }
Expand Down
8 changes: 7 additions & 1 deletion src/API/UserController.php
Expand Up @@ -13,6 +13,7 @@

use App\Configuration\SystemConfiguration;
use App\Entity\User;
use App\Event\PrepareUserEvent;
use App\Form\API\UserApiCreateForm;
use App\Form\API\UserApiEditForm;
use App\Repository\Query\UserQuery;
Expand All @@ -26,6 +27,7 @@
use Nelmio\ApiDocBundle\Annotation\Security as ApiSecurity;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Swagger\Annotations as SWG;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
Expand Down Expand Up @@ -137,7 +139,7 @@ public function cgetAction(ParamFetcherInterface $paramFetcher): Response
* @ApiSecurity(name="apiUser")
* @ApiSecurity(name="apiToken")
*/
public function getAction(int $id): Response
public function getAction(int $id, EventDispatcherInterface $dispatcher): Response
{
$user = $this->repository->find($id);

Expand All @@ -149,6 +151,10 @@ public function getAction(int $id): Response
throw new AccessDeniedHttpException('You are not allowed to view this profile');
}

// we need to prepare the user preferences, which is done via an EventSubscriber
$event = new PrepareUserEvent($user);
$dispatcher->dispatch($event);

$view = new View($user, 200);
$view->getContext()->setGroups(self::GROUPS_ENTITY);

Expand Down
39 changes: 39 additions & 0 deletions src/Entity/User.php
Expand Up @@ -373,6 +373,45 @@ public function setPlainApiToken(?string $plainApiToken): User
return $this;
}

/**
* Read-only list of of all visible user preferences.
*
* @Serializer\VirtualProperty
* @Serializer\SerializedName("preferences"),
* @Serializer\Groups({"User_Entity"})
* @SWG\Property(type="array", @SWG\Items(ref="#/definitions/UserPreference"))
*
* @internal only for API usage
* @return UserPreference[]
*/
public function getVisiblePreferences(): array
{
// hide all internal preferences, which are either available in other fields
// or which are only used within the Kimai UI
$skip = [
UserPreference::TIMEZONE,
UserPreference::LOCALE,
UserPreference::SKIN,
'calendar.initial_view',
'login.initial_view',
'reporting.initial_view',
'theme.collapsed_sidebar',
'theme.layout',
'theme.update_browser_title',
'timesheet.daily_stats',
'timesheet.export_decimal',
];

$all = [];
foreach ($this->preferences as $preference) {
if ($preference->isEnabled() && !\in_array($preference->getName(), $skip)) {
$all[] = $preference;
}
}

return $all;
}

/**
* @return Collection<UserPreference>
*/
Expand Down
9 changes: 9 additions & 0 deletions src/Entity/UserPreference.php
Expand Up @@ -11,6 +11,7 @@

use App\Form\Type\YesNoType;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Validator\Constraint;
Expand All @@ -23,6 +24,8 @@
* @ORM\UniqueConstraint(columns={"user_id", "name"})
* }
* )
*
* @Serializer\ExclusionPolicy("all")
*/
class UserPreference
{
Expand Down Expand Up @@ -53,6 +56,9 @@ class UserPreference
/**
* @var string
*
* @Serializer\Expose()
* @Serializer\Groups({"Default"})
*
* @ORM\Column(name="name", type="string", length=50, nullable=false)
* @Assert\NotNull()
* @Assert\Length(min=2, max=50, allowEmptyString=false)
Expand All @@ -61,6 +67,9 @@ class UserPreference
/**
* @var string
*
* @Serializer\Expose()
* @Serializer\Groups({"Default"})
*
* @ORM\Column(name="value", type="string", length=255, nullable=true)
*/
private $value;
Expand Down
7 changes: 7 additions & 0 deletions tests/API/APIControllerBaseTest.php
Expand Up @@ -283,6 +283,12 @@ protected static function getExpectedResponseStructure(string $type): array
];

// embedded meta data
case 'UserPreference':
return [
'name' => 'string',
'value' => '@string',
];

case 'CustomerMeta':
case 'ProjectMeta':
case 'ActivityMeta':
Expand Down Expand Up @@ -321,6 +327,7 @@ protected static function getExpectedResponseStructure(string $type): array
'timezone' => 'string',
'accountNumber' => '@string',
'memberships' => ['result' => 'array', 'type' => 'TeamMembership'],
'preferences' => ['result' => 'array', 'type' => 'UserPreference'],
];

// if a team is embedded
Expand Down

0 comments on commit a199249

Please sign in to comment.