mirror of
https://github.com/tchapi/davis.git
synced 2025-01-18 05:18:35 +01:00
Continue to work on templates / object edition
This commit is contained in:
parent
7d6cf16c4d
commit
ebeb304fc1
@ -2,6 +2,7 @@ twig:
|
||||
default_path: '%kernel.project_dir%/templates'
|
||||
debug: '%kernel.debug%'
|
||||
strict_variables: '%kernel.debug%'
|
||||
form_themes: ['bootstrap_4_horizontal_layout.html.twig']
|
||||
globals:
|
||||
invite_from_address: '%env(INVITE_FROM_ADDRESS)%'
|
||||
calDAVEnabled: '%env(CALDAV_ENABLED)%'
|
||||
|
@ -23,11 +23,14 @@ services:
|
||||
resource: '../src/Controller'
|
||||
tags: ['controller.service_arguments']
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
||||
|
||||
App\Controller\DAVController:
|
||||
arguments:
|
||||
$calDAVEnabled: "%env(CALDAV_ENABLED)%"
|
||||
$cardDAVEnabled: "%env(CARDDAV_ENABLED)%"
|
||||
$inviteAddress: '%env(INVITE_FROM_ADDRESS)%'
|
||||
$authRealm: '%env(AUTH_REALM)%'
|
||||
|
||||
App\Controller\AdminController:
|
||||
arguments:
|
||||
$authRealm: '%env(AUTH_REALM)%'
|
@ -1,3 +1,11 @@
|
||||
body {
|
||||
padding-top: calc(56px + 30px);
|
||||
}
|
||||
|
||||
.display-4 {
|
||||
border-bottom: 1px solid #CCC;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 1em;
|
||||
}
|
@ -9,19 +9,34 @@ use App\Entity\CalendarObject;
|
||||
use App\Entity\Card;
|
||||
use App\Entity\Principal;
|
||||
use App\Entity\User;
|
||||
use App\Form\AddressBookType;
|
||||
use App\Form\CalendarInstanceType;
|
||||
use App\Form\UserType;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class AdminController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* HTTP authentication realm.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $authRealm;
|
||||
|
||||
public function __construct(?string $authRealm)
|
||||
{
|
||||
$this->authRealm = $authRealm ?? 'SabreDAV';
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/dashboard", name="dashboard")
|
||||
*/
|
||||
public function dashboard()
|
||||
{
|
||||
$users = $this->get('doctrine')->getRepository(User::class)->findAll();
|
||||
$calendars = $this->get('doctrine')->getRepository(Calendar::class)->findAll();
|
||||
$calendars = $this->get('doctrine')->getRepository(CalendarInstance::class)->findAll();
|
||||
$addressbooks = $this->get('doctrine')->getRepository(AddressBook::class)->findAll();
|
||||
$events = $this->get('doctrine')->getRepository(CalendarObject::class)->findAll();
|
||||
$contacts = $this->get('doctrine')->getRepository(Card::class)->findAll();
|
||||
@ -30,6 +45,8 @@ class AdminController extends AbstractController
|
||||
'users' => $users,
|
||||
'calendars' => $calendars,
|
||||
'addressbooks' => $addressbooks,
|
||||
'events' => $events,
|
||||
'contacts' => $contacts,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -49,21 +66,68 @@ class AdminController extends AbstractController
|
||||
* @Route("/users/new", name="user_create")
|
||||
* @Route("/users/edit/{username}", name="user_edit")
|
||||
*/
|
||||
public function userCreate(?string $username)
|
||||
public function userCreate(Request $request, ?string $username)
|
||||
{
|
||||
if ($username) {
|
||||
$user = $this->get('doctrine')->getRepository(User::class)->findOneByUsername($username);
|
||||
if (!$user) {
|
||||
throw new \Exception('User not found');
|
||||
}
|
||||
$principal = $this->get('doctrine')->getRepository(Principal::class)->findOneByUri(Principal::PREFIX.$username);
|
||||
} else {
|
||||
$user = new User();
|
||||
$principal = new Principal();
|
||||
}
|
||||
|
||||
$form = $this->createForm(UserType::class, $user);
|
||||
$form = $this->createForm(UserType::class, $user, ['new' => !$username]);
|
||||
|
||||
$form->get('displayName')->setData($principal->getDisplayName());
|
||||
$form->get('email')->setData($principal->getEmail());
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$displayName = $form->get('displayName')->getData();
|
||||
$email = $form->get('email')->getData();
|
||||
|
||||
// Create password for user
|
||||
$hash = md5($user->getUsername().':'.$this->authRealm.':'.$user->getPassword());
|
||||
$user->setPassword($hash);
|
||||
|
||||
$entityManager = $this->get('doctrine')->getManager();
|
||||
|
||||
// If it's a new user, create default calendar and address book, and principal
|
||||
if (null === $user->getId()) {
|
||||
$principal->setUri(Principal::PREFIX.$user->getUsername());
|
||||
|
||||
$calendarInstance = new CalendarInstance();
|
||||
$calendar = new Calendar();
|
||||
$calendarInstance->setPrincipalUri(Principal::PREFIX.$user->getUsername())
|
||||
->setDisplayName('Default Calendar')
|
||||
->setDescription('Default Calendar for '.$displayName)
|
||||
->setCalendar($calendar);
|
||||
|
||||
$addressbook = new AddressBook();
|
||||
$addressbook->setPrincipalUri(Principal::PREFIX.$user->getUsername())
|
||||
->setDisplayName('Default Address Book')
|
||||
->setDescription('Default Address book for '.$displayName);
|
||||
$entityManager->persist($calendarInstance);
|
||||
$entityManager->persist($addressbook);
|
||||
$entityManager->persist($principal);
|
||||
}
|
||||
|
||||
$principal->setDisplayName($displayName)
|
||||
->setEmail($email);
|
||||
|
||||
$entityManager->persist($user);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('users');
|
||||
}
|
||||
|
||||
return $this->render('users/edit.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'username' => $username,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -86,6 +150,66 @@ class AdminController extends AbstractController
|
||||
return $this->render('calendars/index.html.twig', [
|
||||
'calendars' => $calendars,
|
||||
'principal' => $principal,
|
||||
'username' => $username,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/calendars/{username}/new", name="calendar_create")
|
||||
* @Route("/calendars/{username}/edit/{id}", name="calendar_edit")
|
||||
*/
|
||||
public function calendarCreate(Request $request, string $username, ?int $id)
|
||||
{
|
||||
$principal = $this->get('doctrine')->getRepository(Principal::class)->findOneByUri(Principal::PREFIX.$username);
|
||||
|
||||
if (!$principal) {
|
||||
throw new \Exception('User not found');
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$calendarInstance = $this->get('doctrine')->getRepository(CalendarInstance::class)->findOneById($id);
|
||||
if (!$calendarInstance) {
|
||||
throw new \Exception('Calendar not found');
|
||||
}
|
||||
} else {
|
||||
$calendarInstance = new CalendarInstance();
|
||||
$calendar = new Calendar();
|
||||
$calendarInstance->setCalendar($calendar);
|
||||
}
|
||||
|
||||
$form = $this->createForm(CalendarInstanceType::class, $calendarInstance, ['new' => !$id]);
|
||||
|
||||
$components = explode(',', $calendarInstance->getCalendar()->getComponents());
|
||||
|
||||
$form->get('todos')->setData(in_array(Calendar::COMPONENT_TODOS, $components));
|
||||
$form->get('notes')->setData(in_array(Calendar::COMPONENT_NOTES, $components));
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$components = [Calendar::COMPONENT_EVENT]; // We always need VEVENT
|
||||
if ($form->get('todos')->getData()) {
|
||||
$components[] = Calendar::COMPONENT_TODOS;
|
||||
}
|
||||
if ($form->get('notes')->getData()) {
|
||||
$components[] = Calendar::COMPONENT_NOTES;
|
||||
}
|
||||
|
||||
$calendarInstance->setPrincipalUri(Principal::PREFIX.$username);
|
||||
$calendarInstance->getCalendar()->setComponents(implode(',', $components));
|
||||
|
||||
$entityManager = $this->get('doctrine')->getManager();
|
||||
|
||||
$entityManager->persist($calendarInstance);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('calendars', ['username' => $username]);
|
||||
}
|
||||
|
||||
return $this->render('calendars/edit.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'principal' => $principal,
|
||||
'calendar' => $calendarInstance,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -100,6 +224,49 @@ class AdminController extends AbstractController
|
||||
return $this->render('addressbooks/index.html.twig', [
|
||||
'addressbooks' => $addressbooks,
|
||||
'principal' => $principal,
|
||||
'username' => $username,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/adressbooks/{username}/new", name="addressbook_create")
|
||||
* @Route("/adressbooks/{username}/edit/{id}", name="addressbook_edit")
|
||||
*/
|
||||
public function addressbookCreate(Request $request, string $username, ?int $id)
|
||||
{
|
||||
$principal = $this->get('doctrine')->getRepository(Principal::class)->findOneByUri(Principal::PREFIX.$username);
|
||||
|
||||
if (!$principal) {
|
||||
throw new \Exception('User not found');
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$addressbook = $this->get('doctrine')->getRepository(AddressBook::class)->findOneById($id);
|
||||
if (!$addressbook) {
|
||||
throw new \Exception('Address book not found');
|
||||
}
|
||||
} else {
|
||||
$addressbook = new AddressBook();
|
||||
}
|
||||
|
||||
$form = $this->createForm(AddressBookType::class, $addressbook, ['new' => !$id]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager = $this->get('doctrine')->getManager();
|
||||
|
||||
$addressbook->setPrincipalUri(Principal::PREFIX.$username);
|
||||
|
||||
$entityManager->persist($addressbook);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('address_books', ['username' => $username]);
|
||||
}
|
||||
|
||||
return $this->render('addressbooks/edit.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'principal' => $principal,
|
||||
'addressbook' => $addressbook,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ class AddressBook
|
||||
*/
|
||||
private $synctoken;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->synctoken = 1;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -49,6 +54,10 @@ class AddressBook
|
||||
|
||||
public function getPrincipalUri(): ?string
|
||||
{
|
||||
if (is_resource($this->principalUri)) {
|
||||
$this->principalUri = stream_get_contents($this->principalUri);
|
||||
}
|
||||
|
||||
return $this->principalUri;
|
||||
}
|
||||
|
||||
@ -73,6 +82,10 @@ class AddressBook
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ class AddressBookChange
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @ORM\Column(type="binary", length=255)
|
||||
*/
|
||||
private $uri;
|
||||
|
||||
@ -45,6 +45,10 @@ class AddressBookChange
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,10 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
*/
|
||||
class Calendar
|
||||
{
|
||||
const COMPONENT_EVENT = 'VEVENT';
|
||||
const COMPONENT_TODOS = 'VTODO';
|
||||
const COMPONENT_NOTES = 'VJOURNAL';
|
||||
|
||||
/**
|
||||
* @ORM\Id()
|
||||
* @ORM\GeneratedValue()
|
||||
@ -27,6 +31,12 @@ class Calendar
|
||||
*/
|
||||
private $components;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->synctoken = 1;
|
||||
$this->components = 'VEVENT,VTODO';
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
|
@ -45,6 +45,9 @@ class CalendarChange
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,15 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
*/
|
||||
class CalendarInstance
|
||||
{
|
||||
const INVITE_STATUS_NORESPONSE = 1;
|
||||
const INVITE_STATUS_ACCEPTED = 2;
|
||||
const INVITE_STATUS_DECLINED = 3;
|
||||
const INVITE_STATUS_INVALID = 4;
|
||||
|
||||
const ACCESS_OWNER = 1;
|
||||
const ACCESS_READ = 2;
|
||||
const ACCESS_READWRITE = 3;
|
||||
|
||||
/**
|
||||
* @ORM\Id()
|
||||
* @ORM\GeneratedValue()
|
||||
@ -18,7 +27,7 @@ class CalendarInstance
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="App\Entity\Calendar")
|
||||
* @ORM\ManyToOne(targetEntity="App\Entity\Calendar", cascade={"persist"})
|
||||
* @ORM\JoinColumn(name="calendarid", nullable=false)
|
||||
*/
|
||||
private $calendar;
|
||||
@ -83,6 +92,14 @@ class CalendarInstance
|
||||
*/
|
||||
private $shareInviteStatus;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->shareInviteStatus = self::INVITE_STATUS_ACCEPTED;
|
||||
$this->transparent = 0;
|
||||
$this->calendarOrder = 0;
|
||||
$this->access = self::ACCESS_OWNER;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@ -102,7 +119,7 @@ class CalendarInstance
|
||||
|
||||
public function getPrincipalUri(): ?string
|
||||
{
|
||||
return $this->principalUri;
|
||||
return stream_get_contents($this->principalUri);
|
||||
}
|
||||
|
||||
public function setPrincipalUri(?string $principalUri): self
|
||||
@ -138,6 +155,10 @@ class CalendarInstance
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
@ -174,6 +195,10 @@ class CalendarInstance
|
||||
|
||||
public function getCalendarColor(): ?string
|
||||
{
|
||||
if (is_resource($this->calendarColor)) {
|
||||
$this->calendarColor = stream_get_contents($this->calendarColor);
|
||||
}
|
||||
|
||||
return $this->calendarColor;
|
||||
}
|
||||
|
||||
@ -210,6 +235,10 @@ class CalendarInstance
|
||||
|
||||
public function getShareHref(): ?string
|
||||
{
|
||||
if (is_resource($this->shareHref)) {
|
||||
$this->shareHref = stream_get_contents($this->shareHref);
|
||||
}
|
||||
|
||||
return $this->shareHref;
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,10 @@ class CalendarObject
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
@ -123,6 +127,10 @@ class CalendarObject
|
||||
|
||||
public function getEtag(): ?string
|
||||
{
|
||||
if (is_resource($this->etag)) {
|
||||
$this->etag = stream_get_contents($this->etag);
|
||||
}
|
||||
|
||||
return $this->etag;
|
||||
}
|
||||
|
||||
@ -147,6 +155,10 @@ class CalendarObject
|
||||
|
||||
public function getComponentType(): ?string
|
||||
{
|
||||
if (is_resource($this->componentType)) {
|
||||
$this->componentType = stream_get_contents($this->componentType);
|
||||
}
|
||||
|
||||
return $this->componentType;
|
||||
}
|
||||
|
||||
@ -183,6 +195,10 @@ class CalendarObject
|
||||
|
||||
public function getUid(): ?string
|
||||
{
|
||||
if (is_resource($this->uid)) {
|
||||
$this->uid = stream_get_contents($this->uid);
|
||||
}
|
||||
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,10 @@ class CalendarSubscription
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
@ -91,6 +95,10 @@ class CalendarSubscription
|
||||
|
||||
public function getPrincipalUri(): ?string
|
||||
{
|
||||
if (is_resource($this->principalUri)) {
|
||||
$this->principalUri = stream_get_contents($this->principalUri);
|
||||
}
|
||||
|
||||
return $this->principalUri;
|
||||
}
|
||||
|
||||
@ -151,6 +159,10 @@ class CalendarSubscription
|
||||
|
||||
public function getCalendarColor(): ?string
|
||||
{
|
||||
if (is_resource($this->calendarColor)) {
|
||||
$this->calendarColor = stream_get_contents($this->calendarColor);
|
||||
}
|
||||
|
||||
return $this->calendarColor;
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,10 @@ class Card
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
@ -103,6 +107,10 @@ class Card
|
||||
|
||||
public function getEtag(): ?string
|
||||
{
|
||||
if (is_resource($this->etag)) {
|
||||
$this->etag = stream_get_contents($this->etag);
|
||||
}
|
||||
|
||||
return $this->etag;
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,10 @@ class Lock
|
||||
|
||||
public function getToken(): ?string
|
||||
{
|
||||
if (is_resource($this->token)) {
|
||||
$this->token = stream_get_contents($this->token);
|
||||
}
|
||||
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
@ -131,6 +135,10 @@ class Lock
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,12 @@ class Principal
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @ORM\Column(type="binary", length=255)
|
||||
*/
|
||||
private $uri;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @ORM\Column(type="binary", length=255, nullable=true)
|
||||
*/
|
||||
private $email;
|
||||
|
||||
@ -41,6 +41,10 @@ class Principal
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
@ -53,11 +57,15 @@ class Principal
|
||||
|
||||
public function getUsername(): ?string
|
||||
{
|
||||
return str_replace(self::PREFIX, '', $this->uri);
|
||||
return str_replace(self::PREFIX, '', $this->getUri());
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
if (is_resource($this->email)) {
|
||||
$this->email = stream_get_contents($this->email);
|
||||
}
|
||||
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,10 @@ class PropertyStorage
|
||||
|
||||
public function getPath(): ?string
|
||||
{
|
||||
if (is_resource($this->path)) {
|
||||
$this->path = stream_get_contents($this->path);
|
||||
}
|
||||
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
@ -56,6 +60,10 @@ class PropertyStorage
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
if (is_resource($this->name)) {
|
||||
$this->name = stream_get_contents($this->name);
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,10 @@ class SchedulingObject
|
||||
|
||||
public function getPrincipalUri(): ?string
|
||||
{
|
||||
if (is_resource($this->principalUri)) {
|
||||
$this->principalUri = stream_get_contents($this->principalUri);
|
||||
}
|
||||
|
||||
return $this->principalUri;
|
||||
}
|
||||
|
||||
@ -78,6 +82,10 @@ class SchedulingObject
|
||||
|
||||
public function getUri(): ?string
|
||||
{
|
||||
if (is_resource($this->uri)) {
|
||||
$this->uri = stream_get_contents($this->uri);
|
||||
}
|
||||
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
@ -102,6 +110,10 @@ class SchedulingObject
|
||||
|
||||
public function getEtag(): ?string
|
||||
{
|
||||
if (is_resource($this->etag)) {
|
||||
$this->etag = stream_get_contents($this->etag);
|
||||
}
|
||||
|
||||
return $this->etag;
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,12 @@ class User
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @ORM\Column(type="binary", length=255)
|
||||
*/
|
||||
private $username;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="digesta1", type="string", length=255)
|
||||
* @ORM\Column(name="digesta1", type="binary", length=255)
|
||||
*/
|
||||
private $password;
|
||||
|
||||
@ -34,6 +34,10 @@ class User
|
||||
|
||||
public function getUsername(): ?string
|
||||
{
|
||||
if (is_resource($this->username)) {
|
||||
$this->username = stream_get_contents($this->username);
|
||||
}
|
||||
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
@ -46,6 +50,10 @@ class User
|
||||
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
if (is_resource($this->password)) {
|
||||
$this->password = stream_get_contents($this->password);
|
||||
}
|
||||
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
|
30
src/Form/AddressBookType.php
Normal file
30
src/Form/AddressBookType.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\AddressBook;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class AddressBookType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('uri', TextType::class, ['disabled' => !$options['new'], 'help' => "Allowed characters are digits, lowercase letters and the dash symbol '-'."])
|
||||
->add('displayName')
|
||||
->add('description')
|
||||
->add('save', SubmitType::class);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'new' => false,
|
||||
'data_class' => AddressBook::class,
|
||||
]);
|
||||
}
|
||||
}
|
40
src/Form/CalendarInstanceType.php
Normal file
40
src/Form/CalendarInstanceType.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\CalendarInstance;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class CalendarInstanceType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('uri', TextType::class, ['disabled' => !$options['new'], 'help' => "Allowed characters are digits, lowercase letters and the dash symbol '-'."])
|
||||
->add('displayName')
|
||||
->add('description')
|
||||
->add('calendarColor')
|
||||
->add('todos', CheckboxType::class, [
|
||||
'mapped' => false,
|
||||
'help' => "If checked, todos will be enabled on this calendar.",
|
||||
])
|
||||
->add('notes', CheckboxType::class, [
|
||||
'mapped' => false,
|
||||
'help' => "If checked, notes will be enabled on this calendar.",
|
||||
])
|
||||
->add('save', SubmitType::class);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'new' => false,
|
||||
'data_class' => CalendarInstance::class,
|
||||
]);
|
||||
}
|
||||
}
|
@ -4,6 +4,11 @@ namespace App\Form;
|
||||
|
||||
use App\Entity\User;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
@ -12,13 +17,28 @@ class UserType extends AbstractType
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('username')
|
||||
->add('password');
|
||||
->add('username', TextType::class, ['disabled' => !$options['new'], 'help' => "May be an email, but not forcibly."])
|
||||
->add('displayName', TextType::class, [
|
||||
'mapped' => false,
|
||||
])
|
||||
->add('email', EmailType::class, [
|
||||
'mapped' => false,
|
||||
])
|
||||
->add('password', RepeatedType::class, [
|
||||
'type' => PasswordType::class,
|
||||
'invalid_message' => 'The password fields must match.',
|
||||
'options' => ['attr' => ['class' => 'password-field']],
|
||||
'required' => true,
|
||||
'first_options' => ['label' => 'Password'],
|
||||
'second_options' => ['label' => 'Repeat Password'],
|
||||
])
|
||||
->add('save', SubmitType::class);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'new' => false,
|
||||
'data_class' => User::class,
|
||||
]);
|
||||
}
|
||||
|
14
templates/addressbooks/edit.html.twig
Normal file
14
templates/addressbooks/edit.html.twig
Normal file
@ -0,0 +1,14 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% set menu = 'resources' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% if addressbook.id %}
|
||||
<h1 class="display-4">Editing Address Book {{ addressbook.displayName }}</h1>
|
||||
{% else %}
|
||||
<h1 class="display-4">New Address Book <small class="text-muted">for {{ principal.displayName }}</small></h1>
|
||||
{% endif %}
|
||||
|
||||
{{ form(form) }}
|
||||
|
||||
{% endblock %}
|
@ -3,9 +3,10 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1>Address books for {{ principal.displayName }}</h1>
|
||||
<h1 class="display-4">Address books <small class="text-muted">for {{ principal.displayName }}</small></h1>
|
||||
|
||||
<a href="{{ path('users') }}">Users</a>
|
||||
<a href="{{ path('addressbook_create', {username: username}) }}" class="btn btn-primary">New address book</a>
|
||||
<ul>
|
||||
{% for addressbook in addressbooks %}
|
||||
<li>{{ addressbook.displayName }} {{ addressbook.description }}</li>
|
||||
|
14
templates/calendars/edit.html.twig
Normal file
14
templates/calendars/edit.html.twig
Normal file
@ -0,0 +1,14 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% set menu = 'resources' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% if calendar.id %}
|
||||
<h1 class="display-4">Editing calendar {{ calendar.displayName }} <small class="text-muted">for {{ principal.displayName }}</small></h1>
|
||||
{% else %}
|
||||
<h1 class="display-4">New calendar <small class="text-muted">for {{ principal.displayName }}</small></h1>
|
||||
{% endif %}
|
||||
|
||||
{{ form(form) }}
|
||||
|
||||
{% endblock %}
|
@ -3,9 +3,10 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1>Calendars for {{ principal.displayName }}</h1>
|
||||
<h1 class="display-4">Calendars <small class="text-muted">for {{ principal.displayName }}</small></h1>
|
||||
|
||||
<a href="{{ path('users') }}">Users</a>
|
||||
<a href="{{ path('calendar_create', {username: username}) }}" class="btn btn-primary">New calendar</a>
|
||||
<ul>
|
||||
{% for calendar in calendars %}
|
||||
<li>{{ calendar.displayName }} {{ calendar.description }}</li>
|
||||
|
@ -3,16 +3,53 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1>Dashboard</h1>
|
||||
<h1 class="display-4">Dashboard</h1>
|
||||
|
||||
<h3>Configured environment</h3>
|
||||
|
||||
Users : {{ users|length }}
|
||||
Calendars : {{ calendars|length }}
|
||||
Address books : {{ addressbooks|length }}
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item list-group-item-secondary">Auth Realm : <code>{{ authRealm }}</code></li>
|
||||
<li class="list-group-item list-group-item-secondary">Invite from address : <code>{{ invite_from_address|default('Not set') }}</code></li>
|
||||
{% if calDAVEnabled %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center list-group-item-success">CalDAV
|
||||
<span class="badge badge-success badge-pill">enabled</span></li>
|
||||
{% else %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center list-group-item-danger">CalDAV
|
||||
<span class="badge badge-danger badge-pill">enabled</span></li>
|
||||
{% endif %}
|
||||
|
||||
Auth realm : {{ authRealm }}
|
||||
Invite from address : {{ invite_from_address }}
|
||||
Cal dav : {{ calDAVEnabled }}
|
||||
Card dav : {{ cardDAVEnabled }}
|
||||
{% if cardDAVEnabled %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center list-group-item-success">CardDAV
|
||||
<span class="badge badge-success badge-pill">enabled</span></li>
|
||||
{% else %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center list-group-item-danger">CardDAV
|
||||
<span class="badge badge-danger badge-pill">disabled</span></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<h3>Objects</h3>
|
||||
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
Users
|
||||
<span class="badge badge-primary badge-pill">{{ users|length }}</span>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
Calendars
|
||||
<span class="badge badge-primary badge-pill">{{ calendars|length }}</span>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
↳ Events
|
||||
<span class="badge badge-secondary badge-pill">{{ events|length }}</span>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
Address books
|
||||
<span class="badge badge-primary badge-pill">{{ addressbooks|length }}</span>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
↳ Contacts
|
||||
<span class="badge badge-secondary badge-pill">{{ contacts|length }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -3,6 +3,12 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% if username %}
|
||||
<h1 class="display-4">Editing user {{ username }}</h1>
|
||||
{% else %}
|
||||
<h1 class="display-4">New user</h1>
|
||||
{% endif %}
|
||||
|
||||
{{ form(form) }}
|
||||
|
||||
{% endblock %}
|
@ -3,7 +3,7 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1>Users</h1>
|
||||
<h1 class="display-4">Users</h1>
|
||||
|
||||
<a href="{{ path('user_create') }}" class="btn btn-primary">New user</a>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user