113
src/Controller/AbstractController.php
Normal file
113
src/Controller/AbstractController.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
/**
|
||||
* The abstract base controller.
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
abstract class AbstractController extends Controller
|
||||
{
|
||||
const FLASH_SUCCESS = 'success';
|
||||
const FLASH_WARNING = 'warning';
|
||||
const FLASH_ERROR = 'error';
|
||||
|
||||
const DOMAIN_FLASH = 'flashmessages';
|
||||
const DOMAIN_ERROR = 'exceptions';
|
||||
|
||||
const ROLE_ADMIN = 'ROLE_ADMIN';
|
||||
|
||||
/**
|
||||
* @return object|\Symfony\Component\Translation\DataCollectorTranslator|\Symfony\Component\Translation\IdentityTranslator
|
||||
*/
|
||||
protected function getTranslator()
|
||||
{
|
||||
return $this->container->get('translator');
|
||||
}
|
||||
|
||||
/**
|
||||
* A translated helper for denyAccessUnlessGranted()
|
||||
*
|
||||
* @param $attributes
|
||||
* @param null $subject
|
||||
* @param string $translation
|
||||
* @param array $parameter
|
||||
* @throws AccessDeniedException
|
||||
*/
|
||||
protected function denyUnlessGranted($attributes, $subject = null, $translation = 'access.denied', $parameter = [])
|
||||
{
|
||||
$error = $this->getTranslator()->trans($translation, $parameter, self::DOMAIN_ERROR);
|
||||
// TODO try & catch and add to audit log?
|
||||
$this->denyAccessUnlessGranted($attributes, $subject, $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a "successful" flash message to the stack.
|
||||
*
|
||||
* @param string $translationKey
|
||||
* @param array $parameter
|
||||
*/
|
||||
protected function flashSuccess($translationKey, $parameter = [])
|
||||
{
|
||||
if (!empty($parameter)) {
|
||||
$translationKey = $this->getTranslator()->trans(
|
||||
$translationKey,
|
||||
$parameter,
|
||||
self::DOMAIN_FLASH
|
||||
);
|
||||
}
|
||||
|
||||
$this->addFlash(self::FLASH_SUCCESS, $translationKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a "warning" flash message to the stack.
|
||||
*
|
||||
* @param $translationKey
|
||||
* @param array $parameter
|
||||
*/
|
||||
protected function flashWarning($translationKey, $parameter = [])
|
||||
{
|
||||
if (!empty($parameter)) {
|
||||
$translationKey = $this->getTranslator()->trans(
|
||||
$translationKey,
|
||||
$parameter,
|
||||
self::DOMAIN_FLASH
|
||||
);
|
||||
}
|
||||
|
||||
$this->addFlash(self::FLASH_WARNING, $translationKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a "error" flash message to the stack.
|
||||
*
|
||||
* @param $translationKey
|
||||
* @param array $parameter
|
||||
*/
|
||||
protected function flashError($translationKey, $parameter = [])
|
||||
{
|
||||
if (!empty($parameter)) {
|
||||
$translationKey = $this->getTranslator()->trans(
|
||||
$translationKey,
|
||||
$parameter,
|
||||
self::DOMAIN_FLASH
|
||||
);
|
||||
}
|
||||
|
||||
$this->addFlash(self::FLASH_ERROR, $translationKey);
|
||||
}
|
||||
}
|
||||
55
src/Controller/ActivityController.php
Normal file
55
src/Controller/ActivityController.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use App\Entity\Activity;
|
||||
use App\Repository\ActivityRepository;
|
||||
|
||||
/**
|
||||
* Controller used to manage activity contents in the public part of the site.
|
||||
*
|
||||
* @Route("/activity")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class ActivityController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @return ActivityRepository
|
||||
*/
|
||||
protected function getRepository()
|
||||
{
|
||||
return $this->getDoctrine()->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The flyout to render recent activities and quick-start new recordings.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function recentActivitiesAction()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
// TODO make days configurable
|
||||
$activeEntries = $this->getRepository()->getRecentActivities($user, new \DateTime('-30 days'));
|
||||
|
||||
return $this->render(
|
||||
'navbar/recent-activities.html.twig',
|
||||
['activities' => $activeEntries]
|
||||
);
|
||||
}
|
||||
}
|
||||
239
src/Controller/Admin/ActivityController.php
Normal file
239
src/Controller/Admin/ActivityController.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Controller\AbstractController;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Entity\Activity;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Form\ActivityEditForm;
|
||||
use App\Form\Toolbar\ActivityToolbarForm;
|
||||
use App\Repository\Query\ActivityQuery;
|
||||
|
||||
/**
|
||||
* Controller used to manage activities in the admin part of the site.
|
||||
*
|
||||
* @Route("/admin/activity")
|
||||
* @Security("has_role('ROLE_ADMIN')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class ActivityController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \App\Repository\ActivityRepository
|
||||
*/
|
||||
protected function getRepository()
|
||||
{
|
||||
return $this->getDoctrine()->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return ActivityQuery
|
||||
*/
|
||||
protected function getQueryForRequest(Request $request)
|
||||
{
|
||||
$visibility = $request->get('visibility', ActivityQuery::SHOW_VISIBLE);
|
||||
if (strlen($visibility) == 0 || (int)$visibility != $visibility) {
|
||||
$visibility = ActivityQuery::SHOW_BOTH;
|
||||
}
|
||||
$pageSize = (int) $request->get('pageSize');
|
||||
$customer = $request->get('customer');
|
||||
$customer = !empty(trim($customer)) ? trim($customer) : null;
|
||||
$project = $request->get('project');
|
||||
$project = !empty(trim($project)) ? trim($project) : null;
|
||||
|
||||
if ($project !== null) {
|
||||
$repo = $this->getDoctrine()->getRepository(Project::class);
|
||||
$project = $repo->getById($project);
|
||||
if ($project !== null) {
|
||||
$customer = $project->getCustomer();
|
||||
} else {
|
||||
$customer = null;
|
||||
}
|
||||
} elseif ($customer !== null) {
|
||||
$repo = $this->getDoctrine()->getRepository(Customer::class);
|
||||
$customer = $repo->getById($customer);
|
||||
}
|
||||
|
||||
$query = new ActivityQuery();
|
||||
$query
|
||||
->setPageSize($pageSize)
|
||||
->setVisibility($visibility)
|
||||
->setCustomer($customer)
|
||||
->setProject($project)
|
||||
->setExclusiveVisibility(true)
|
||||
;
|
||||
|
||||
return $query ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="admin_activity")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_activity_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*/
|
||||
public function indexAction($page, Request $request)
|
||||
{
|
||||
$query = $this->getQueryForRequest($request);
|
||||
$query->setPage($page);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $this->getRepository()->findByQuery($query);
|
||||
|
||||
return $this->render('admin/activity.html.twig', [
|
||||
'entries' => $entries,
|
||||
'query' => $query,
|
||||
'toolbarForm' => $this->getToolbarForm($query)->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/create", name="admin_activity_create")
|
||||
* @Method({"GET", "POST"})
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
return $this->renderActivityForm(new Activity(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/edit", name="admin_activity_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('edit', activity)")
|
||||
*/
|
||||
public function editAction(Activity $activity, Request $request)
|
||||
{
|
||||
return $this->renderActivityForm($activity, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to delete an existing entry.
|
||||
*
|
||||
* @Route("/{id}/delete", name="admin_activity_delete")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('delete', activity)")
|
||||
*
|
||||
* @param Activity $activity
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function deleteAction(Activity $activity, Request $request)
|
||||
{
|
||||
$stats = $this->getRepository()->getActivityStatistics($activity);
|
||||
|
||||
$deleteForm = $this->createFormBuilder()
|
||||
->setAction($this->generateUrl('admin_activity_delete', ['id' => $activity->getId()]))
|
||||
->setMethod('POST')
|
||||
->getForm();
|
||||
|
||||
$deleteForm->handleRequest($request);
|
||||
|
||||
if ($stats->getRecordAmount() == 0 || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($activity);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.deleted_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_activity', ['id' => $activity->getId()]);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'admin/activity_delete.html.twig',
|
||||
[
|
||||
'activity' => $activity,
|
||||
'stats' => $stats,
|
||||
'form' => $deleteForm->createView(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity $activity
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function renderActivityForm(Activity $activity, Request $request)
|
||||
{
|
||||
$editForm = $this->createEditForm($activity);
|
||||
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($activity);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_activity', ['id' => $activity->getId()]);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'admin/activity_edit.html.twig',
|
||||
[
|
||||
'activity' => $activity,
|
||||
'form' => $editForm->createView()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ActivityQuery $query
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getToolbarForm(ActivityQuery $query)
|
||||
{
|
||||
return $this->createForm(
|
||||
ActivityToolbarForm::class,
|
||||
$query,
|
||||
[
|
||||
'action' => $this->generateUrl('admin_activity_paginated', [
|
||||
'page' => $query->getPage(),
|
||||
]),
|
||||
'method' => 'GET',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity $activity
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createEditForm(Activity $activity)
|
||||
{
|
||||
if ($activity->getId() === null) {
|
||||
$url = $this->generateUrl('admin_activity_create');
|
||||
} else {
|
||||
$url = $this->generateUrl('admin_activity_edit', ['id' => $activity->getId()]);
|
||||
}
|
||||
|
||||
return $this->createForm(
|
||||
ActivityEditForm::class,
|
||||
$activity,
|
||||
[
|
||||
'action' => $url,
|
||||
'method' => 'POST'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
202
src/Controller/Admin/CustomerController.php
Normal file
202
src/Controller/Admin/CustomerController.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Controller\AbstractController;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Entity\Customer;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use App\Form\CustomerEditForm;
|
||||
use App\Form\Toolbar\CustomerToolbarForm;
|
||||
use App\Repository\Query\CustomerQuery;
|
||||
|
||||
/**
|
||||
* Controller used to manage activities in the admin part of the site.
|
||||
*
|
||||
* @Route("/admin/customer")
|
||||
* @Security("has_role('ROLE_ADMIN')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class CustomerController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \App\Repository\CustomerRepository
|
||||
*/
|
||||
protected function getRepository()
|
||||
{
|
||||
return $this->getDoctrine()->getRepository(Customer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return CustomerQuery
|
||||
*/
|
||||
protected function getQueryForRequest(Request $request)
|
||||
{
|
||||
$visibility = $request->get('visibility', CustomerQuery::SHOW_VISIBLE);
|
||||
if (strlen($visibility) == 0 || (int)$visibility != $visibility) {
|
||||
$visibility = CustomerQuery::SHOW_BOTH;
|
||||
}
|
||||
$pageSize = (int) $request->get('pageSize');
|
||||
|
||||
$query = new CustomerQuery();
|
||||
$query
|
||||
->setPageSize($pageSize)
|
||||
->setVisibility($visibility);
|
||||
|
||||
return $query ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="admin_customer")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_customer_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*/
|
||||
public function indexAction($page, Request $request)
|
||||
{
|
||||
$query = $this->getQueryForRequest($request);
|
||||
$query->setPage($page);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $this->getRepository()->findByQuery($query);
|
||||
|
||||
return $this->render('admin/customer.html.twig', [
|
||||
'entries' => $entries,
|
||||
'query' => $query,
|
||||
'toolbarForm' => $this->getToolbarForm($query)->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/create", name="admin_customer_create")
|
||||
* @Method({"GET", "POST"})
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
return $this->renderCustomerForm(new Customer(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/edit", name="admin_customer_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('edit', customer)")
|
||||
*/
|
||||
public function editAction(Customer $customer, Request $request)
|
||||
{
|
||||
return $this->renderCustomerForm($customer, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer $customer
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function renderCustomerForm(Customer $customer, Request $request)
|
||||
{
|
||||
$editForm = $this->createEditForm($customer);
|
||||
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($customer);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_customer', ['id' => $customer->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('admin/customer_edit.html.twig', [
|
||||
'customer' => $customer,
|
||||
'form' => $editForm->createView()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to delete an existing entry.
|
||||
*
|
||||
* @Route("/{id}/delete", name="admin_customer_delete")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('delete', customer)")
|
||||
*
|
||||
* @param Customer $customer
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function deleteAction(Customer $customer, Request $request)
|
||||
{
|
||||
$stats = $this->getRepository()->getCustomerStatistics($customer);
|
||||
|
||||
$deleteForm = $this->createFormBuilder()
|
||||
->setAction($this->generateUrl('admin_customer_delete', ['id' => $customer->getId()]))
|
||||
->setMethod('POST')
|
||||
->getForm();
|
||||
|
||||
$deleteForm->handleRequest($request);
|
||||
|
||||
if ($stats->getRecordAmount() == 0 || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($customer);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.deleted_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_customer', ['id' => $customer->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('admin/customer_delete.html.twig', [
|
||||
'customer' => $customer,
|
||||
'stats' => $stats,
|
||||
'form' => $deleteForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CustomerQuery $query
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getToolbarForm(CustomerQuery $query)
|
||||
{
|
||||
return $this->createForm(CustomerToolbarForm::class, $query, [
|
||||
'action' => $this->generateUrl('admin_customer_paginated', [
|
||||
'page' => $query->getPage(),
|
||||
]),
|
||||
'method' => 'GET',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer $customer
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createEditForm(Customer $customer)
|
||||
{
|
||||
if ($customer->getId() === null) {
|
||||
$url = $this->generateUrl('admin_customer_create');
|
||||
} else {
|
||||
$url = $this->generateUrl('admin_customer_edit', ['id' => $customer->getId()]);
|
||||
}
|
||||
|
||||
return $this->createForm(CustomerEditForm::class, $customer, [
|
||||
'action' => $url,
|
||||
'method' => 'POST'
|
||||
]);
|
||||
}
|
||||
}
|
||||
220
src/Controller/Admin/ProjectController.php
Normal file
220
src/Controller/Admin/ProjectController.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Controller\AbstractController;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use App\Form\ProjectEditForm;
|
||||
use App\Form\Toolbar\ProjectToolbarForm;
|
||||
use App\Repository\Query\ProjectQuery;
|
||||
|
||||
/**
|
||||
* Controller used to manage projects in the admin part of the site.
|
||||
*
|
||||
* @Route("/admin/project")
|
||||
* @Security("has_role('ROLE_ADMIN')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class ProjectController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \App\Repository\ProjectRepository
|
||||
*/
|
||||
protected function getRepository()
|
||||
{
|
||||
return $this->getDoctrine()->getRepository(Project::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return ProjectQuery
|
||||
*/
|
||||
protected function getQueryForRequest(Request $request)
|
||||
{
|
||||
$visibility = $request->get('visibility', ProjectQuery::SHOW_VISIBLE);
|
||||
if (strlen($visibility) == 0 || (int)$visibility != $visibility) {
|
||||
$visibility = ProjectQuery::SHOW_BOTH;
|
||||
}
|
||||
$pageSize = (int) $request->get('pageSize');
|
||||
$customer = $request->get('customer');
|
||||
$customer = !empty(trim($customer)) ? trim($customer) : null;
|
||||
|
||||
if ($customer !== null) {
|
||||
$repo = $this->getDoctrine()->getRepository(Customer::class);
|
||||
$customer = $repo->getById($customer);
|
||||
}
|
||||
|
||||
$query = new ProjectQuery();
|
||||
$query
|
||||
->setPageSize($pageSize)
|
||||
->setVisibility($visibility)
|
||||
->setCustomer($customer)
|
||||
->setExclusiveVisibility(true)
|
||||
;
|
||||
|
||||
return $query ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="admin_project")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_project_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*/
|
||||
public function indexAction($page, Request $request)
|
||||
{
|
||||
$query = $this->getQueryForRequest($request);
|
||||
$query->setPage($page);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $this->getDoctrine()->getRepository(Project::class)->findByQuery($query);
|
||||
|
||||
return $this->render('admin/project.html.twig', [
|
||||
'entries' => $entries,
|
||||
'query' => $query,
|
||||
'toolbarForm' => $this->getToolbarForm($query)->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/create", name="admin_project_create")
|
||||
* @Method({"GET", "POST"})
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
return $this->renderProjectForm(new Project(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/edit", name="admin_project_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('edit', project)")
|
||||
*/
|
||||
public function editAction(Project $project, Request $request)
|
||||
{
|
||||
return $this->renderProjectForm($project, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to delete an existing entry.
|
||||
*
|
||||
* @Route("/{id}/delete", name="admin_project_delete")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('delete', project)")
|
||||
*
|
||||
* @param Project $project
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function deleteAction(Project $project, Request $request)
|
||||
{
|
||||
$stats = $this->getRepository()->getProjectStatistics($project);
|
||||
|
||||
$deleteForm = $this->createFormBuilder()
|
||||
->setAction($this->generateUrl('admin_project_delete', ['id' => $project->getId()]))
|
||||
->setMethod('POST')
|
||||
->getForm();
|
||||
|
||||
$deleteForm->handleRequest($request);
|
||||
|
||||
if ($stats->getRecordAmount() == 0 || ($deleteForm->isSubmitted() && $deleteForm->isValid())) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($project);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.deleted_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_project', ['id' => $project->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('admin/project_delete.html.twig', [
|
||||
'project' => $project,
|
||||
'stats' => $stats,
|
||||
'form' => $deleteForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project $project
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function renderProjectForm(Project $project, Request $request)
|
||||
{
|
||||
$editForm = $this->createEditForm($project);
|
||||
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($project);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('admin_project', ['id' => $project->getId()]);
|
||||
}
|
||||
|
||||
return $this->render('admin/project_edit.html.twig', [
|
||||
'project' => $project,
|
||||
'form' => $editForm->createView()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ProjectQuery $query
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getToolbarForm(ProjectQuery $query)
|
||||
{
|
||||
return $this->createForm(ProjectToolbarForm::class, $query, [
|
||||
'action' => $this->generateUrl('admin_project_paginated', [
|
||||
'page' => $query->getPage(),
|
||||
]),
|
||||
'method' => 'GET',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project $project
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createEditForm(Project $project)
|
||||
{
|
||||
if ($project->getId() === null) {
|
||||
$url = $this->generateUrl('admin_project_create');
|
||||
$currency = Customer::DEFAULT_CURRENCY;
|
||||
} else {
|
||||
$url = $this->generateUrl('admin_project_edit', ['id' => $project->getId()]);
|
||||
$currency = $project->getCustomer()->getCurrency();
|
||||
}
|
||||
|
||||
return $this->createForm(
|
||||
ProjectEditForm::class,
|
||||
$project,
|
||||
[
|
||||
'action' => $url,
|
||||
'method' => 'POST',
|
||||
'currency' => $currency,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
168
src/Controller/Admin/TimesheetController.php
Normal file
168
src/Controller/Admin/TimesheetController.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Controller\AbstractController;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Controller\TimesheetControllerTrait;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Timesheet;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use App\Form\TimesheetAdminForm;
|
||||
|
||||
/**
|
||||
* Controller used for manage timesheet entries in the admin part of the site.
|
||||
*
|
||||
* @Route("/team/timesheet")
|
||||
* @Security("has_role('ROLE_TEAMLEAD')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class TimesheetController extends AbstractController
|
||||
{
|
||||
use TimesheetControllerTrait;
|
||||
|
||||
/**
|
||||
* This route shows all users timesheet entries.
|
||||
*
|
||||
* @Route("/", defaults={"page": 1}, name="admin_timesheet")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_timesheet_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*
|
||||
* @param $page
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function indexAction($page, Request $request)
|
||||
{
|
||||
$query = $this->getQueryForRequest($request);
|
||||
$query->setPage($page);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $this->getRepository()->findByQuery($query);
|
||||
|
||||
return $this->render('admin/timesheet.html.twig', [
|
||||
'entries' => $entries,
|
||||
'page' => $page,
|
||||
'query' => $query,
|
||||
'toolbarForm' => $this->getToolbarForm($query, 'admin_timesheet')->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to stop a running entry.
|
||||
*
|
||||
* @Route("/{id}/stop", name="admin_timesheet_stop")
|
||||
* @Method({"GET"})
|
||||
* @Security("is_granted('stop', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function stopAction(Timesheet $entry)
|
||||
{
|
||||
return $this->stop($entry, 'admin_timesheet');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to edit an existing entry.
|
||||
*
|
||||
* @Route("/{id}/edit", name="admin_timesheet_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('edit', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function editAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
return $this->edit($entry, $request, 'admin_timesheet_paginated', 'admin/timesheet_edit.html.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to create a new entry by form.
|
||||
*
|
||||
* @Route("/create", name="admin_timesheet_create")
|
||||
* @Method({"GET", "POST"})
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
return $this->create($request, 'admin_timesheet', 'admin/timesheet_edit.html.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to delete an existing entry.
|
||||
*
|
||||
* @Route("/{id}/delete", name="admin_timesheet_delete")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('delete', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function deleteAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($entry);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('admin_timesheet_paginated', ['page' => $request->get('page')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getCreateForm(Timesheet $entry)
|
||||
{
|
||||
return $this->createForm(
|
||||
TimesheetAdminForm::class,
|
||||
$entry,
|
||||
[
|
||||
'action' => $this->generateUrl('admin_timesheet_create'),
|
||||
'method' => 'POST',
|
||||
'currency' => Customer::DEFAULT_CURRENCY,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @param int $page
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getEditForm(Timesheet $entry, $page)
|
||||
{
|
||||
return $this->createForm(
|
||||
TimesheetAdminForm::class,
|
||||
$entry,
|
||||
[
|
||||
'action' => $this->generateUrl('admin_timesheet_edit', [
|
||||
'id' => $entry->getId(),
|
||||
'page' => $page
|
||||
]),
|
||||
'method' => 'POST',
|
||||
'currency' => $entry->getActivity()->getProject()->getCustomer()->getCurrency(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
150
src/Controller/Admin/UserController.php
Normal file
150
src/Controller/Admin/UserController.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Controller\AbstractController;
|
||||
use App\Entity\User;
|
||||
use App\Form\Toolbar\UserToolbarForm;
|
||||
use App\Form\UserCreateType;
|
||||
use App\Repository\Query\UserQuery;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Controller used to manage users in the admin part of the site.
|
||||
*
|
||||
* @Route("/admin/user")
|
||||
* @Security("has_role('ROLE_SUPER_ADMIN')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class UserController extends AbstractController
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return UserQuery
|
||||
*/
|
||||
protected function getQueryForRequest(Request $request)
|
||||
{
|
||||
$visibility = $request->get('visibility', UserQuery::SHOW_VISIBLE);
|
||||
if (strlen($visibility) == 0 || (int)$visibility != $visibility) {
|
||||
$visibility = UserQuery::SHOW_BOTH;
|
||||
}
|
||||
$pageSize = (int) $request->get('pageSize');
|
||||
$userRole = $request->get('role');
|
||||
|
||||
$query = new UserQuery();
|
||||
$query
|
||||
->setPageSize($pageSize)
|
||||
->setVisibility($visibility)
|
||||
->setRole($userRole)
|
||||
;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="admin_user")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_user_paginated")
|
||||
* @Method("GET")
|
||||
* @Security("is_granted('view_all', user)")
|
||||
*/
|
||||
public function indexAction($page, Request $request)
|
||||
{
|
||||
$query = $this->getQueryForRequest($request);
|
||||
$query->setPage($page);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $this->getDoctrine()->getRepository(User::class)->findByQuery($query);
|
||||
|
||||
return $this->render('admin/user.html.twig', [
|
||||
'entries' => $entries,
|
||||
'query' => $query,
|
||||
'toolbarForm' => $this->getToolbarForm($query)->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/create", name="admin_user_create")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('create', user)")
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
$user = new User();
|
||||
$editForm = $this->createEditForm($user);
|
||||
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$password = $this->get('security.password_encoder')
|
||||
->encodePassword($user, $user->getPlainPassword());
|
||||
$user->setPassword($password);
|
||||
$user->setRoles([User::DEFAULT_ROLE]);
|
||||
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($user);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('user_profile_edit', ['username' => $user->getUsername()]);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'admin/user_edit.html.twig',
|
||||
[
|
||||
'user' => $user,
|
||||
'form' => $editForm->createView()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UserQuery $query
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getToolbarForm(UserQuery $query)
|
||||
{
|
||||
return $this->createForm(
|
||||
UserToolbarForm::class,
|
||||
$query,
|
||||
[
|
||||
'action' => $this->generateUrl('admin_user_paginated', [
|
||||
'page' => $query->getPage(),
|
||||
]),
|
||||
'method' => 'GET',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createEditForm(User $user)
|
||||
{
|
||||
return $this->createForm(
|
||||
UserCreateType::class,
|
||||
$user,
|
||||
[
|
||||
'action' => $this->generateUrl('admin_user_create'),
|
||||
'method' => 'POST'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
143
src/Controller/DashboardController.php
Normal file
143
src/Controller/DashboardController.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
|
||||
/**
|
||||
* Dashboard controller for the admin area.
|
||||
*
|
||||
* @Route("/dashboard")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/", defaults={}, name="dashboard")
|
||||
* @Method("GET")
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
$userStats = $this->getDoctrine()->getRepository(User::class)->getGlobalStatistics();
|
||||
|
||||
// FIXME move the other widgets to the Kimai, the inheritence is wrong as Kimai
|
||||
// shouldn't know about Timesheets
|
||||
|
||||
$timesheetRepo = $this->getDoctrine()->getRepository(Timesheet::class);
|
||||
$timesheetUserStats = $timesheetRepo->getUserStatistics($user);
|
||||
$timesheetGlobalStats = $timesheetRepo->getGlobalStatistics();
|
||||
|
||||
$activityStats = $this->getDoctrine()->getRepository(Activity::class)->getGlobalStatistics();
|
||||
$projectStats = $this->getDoctrine()->getRepository(Project::class)->getGlobalStatistics();
|
||||
$customerStats = $this->getDoctrine()->getRepository(Customer::class)->getGlobalStatistics();
|
||||
|
||||
return $this->render('dashboard/index.html.twig', [
|
||||
'dashboard_widgets' => $this->getWidgets(),
|
||||
'timesheetGlobal' => $timesheetGlobalStats,
|
||||
'timesheetUser' => $timesheetUserStats,
|
||||
'activity' => $activityStats,
|
||||
'project' => $projectStats,
|
||||
'customer' => $customerStats,
|
||||
'user' => $userStats,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* colors: blue / yellow / purple / green / black
|
||||
* icons: bar-chart / line-chart / calendar / clock-o
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getWidgets()
|
||||
{
|
||||
// @codingStandardsIgnoreStart
|
||||
$widgets = [
|
||||
/*
|
||||
[
|
||||
'header' => 'dashboard.you',
|
||||
'widgets' => [
|
||||
"{{ widgets.info_box_progress('Bewilligte Stunden', 'Stunden zur Abrechnung bewilligt', 120, 10, 'star-o') }}",
|
||||
"{{ widgets.info_box_progress('Umsatz / Monat', '70% Increase in 30 Days', 6830, 30, 'credit-card', 'black') }}",
|
||||
"{{ widgets.info_box_progress('Stunden persönlich', 'Das ist noch nicht genug', 135, 60, 'hourglass-o') }}",
|
||||
"{{ widgets.info_box_progress('Anzahl Benutzer', 'Mehr ist besser!', 5, 90, 'user') }}",
|
||||
],
|
||||
],
|
||||
*/
|
||||
[
|
||||
'id' => 'profile.stats',
|
||||
'header' => 'dashboard.you',
|
||||
'widgets' => [
|
||||
"{{ widgets.info_box_counter('stats.durationThisMonth', timesheetUser.durationThisMonth|duration(true), 'hourglass-o', 'green') }}",
|
||||
//"{{ widgets.info_box_counter('stats.amountThisMonth', timesheetUser.amountThisMonth|money, 'money', 'blue') }}",
|
||||
"{{ widgets.info_box_counter('stats.durationTotal', timesheetUser.durationTotal|duration(true), 'hourglass-o', 'red') }}",
|
||||
//"{{ widgets.info_box_counter('stats.amountTotal', timesheetUser.amountTotal|money, 'money', 'yellow') }}",
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
if (!$this->isGranted('ROLE_TEAMLEAD', null)) {
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
$widgets[] = [
|
||||
'id' => 'alluser.stats',
|
||||
'header' => 'dashboard.all',
|
||||
'widgets' => [
|
||||
"{{ widgets.info_box_counter('stats.durationThisMonth', timesheetGlobal.durationThisMonth|duration(true), 'hourglass-o', 'blue') }}",
|
||||
//"{{ widgets.info_box_counter('stats.amountThisMonth', timesheetGlobal.amountThisMonth|money, 'money', 'green') }}",
|
||||
"{{ widgets.info_box_counter('stats.durationTotal', timesheetGlobal.durationTotal|duration(true), 'hourglass-o', 'yellow') }}",
|
||||
//"{{ widgets.info_box_counter('stats.amountTotal', timesheetGlobal.amountTotal|money, 'money', 'red') }}",
|
||||
"{{ widgets.info_box_counter('stats.activeRecordings', timesheetGlobal.activeCurrently, 'hourglass-o', 'red', path('admin_timesheet', {'state': 1})) }}",
|
||||
],
|
||||
];
|
||||
|
||||
$widgets[] = [
|
||||
'id' => 'user.stats',
|
||||
'header' => '',
|
||||
'widgets' => [
|
||||
"{{ widgets.info_box_counter('stats.userTotal', user.totalAmount, 'user', 'red') }}",
|
||||
"{{ widgets.info_box_counter('stats.userActiveThisMoth', timesheetGlobal.activeThisMonth, 'user', 'yellow') }}",
|
||||
"{{ widgets.info_box_counter('stats.userActiveEver', timesheetGlobal.activeTotal, 'user', 'blue') }}",
|
||||
],
|
||||
];
|
||||
|
||||
if (!$this->isGranted('ROLE_ADMIN', null)) {
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
$widgets[] = [
|
||||
'id' => 'admin.stats',
|
||||
'header' => 'dashboard.admin',
|
||||
'widgets' => [
|
||||
"{{ widgets.info_box_more('stats.userTotal', user.totalAmount, ' ', path('admin_user'), 'user') }}",
|
||||
"{{ widgets.info_box_more('stats.customerTotal', customer.count, '', path('admin_customer'), 'users', 'blue') }}",
|
||||
"{{ widgets.info_box_more('stats.projectsTotal', project.count, '', path('admin_project'), 'book', 'yellow') }}",
|
||||
"{{ widgets.info_box_more('stats.activitiesTotal', activity.count, '', path('admin_activity'), 'tasks', 'purple') }}",
|
||||
],
|
||||
];
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
return $widgets;
|
||||
}
|
||||
}
|
||||
214
src/Controller/ProfileController.php
Normal file
214
src/Controller/ProfileController.php
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Form\UserEditType;
|
||||
use App\Form\UserPasswordType;
|
||||
use App\Form\UserRolesType;
|
||||
use Symfony\Component\Form\Form;
|
||||
use App\Entity\Timesheet;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* User profile controller
|
||||
*
|
||||
* @Route("/profile")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class ProfileController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Route("/{username}", name="user_profile")
|
||||
* @Method("GET")
|
||||
* @Security("is_granted('view', profile)")
|
||||
*/
|
||||
public function indexAction(User $profile)
|
||||
{
|
||||
return $this->getProfileView($profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{username}/edit", name="user_profile_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('edit', profile)")
|
||||
*/
|
||||
public function editAction(User $profile, Request $request)
|
||||
{
|
||||
$editForm = $this->createEditForm($profile);
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($profile);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('user_profile', ['username' => $profile->getUsername()]);
|
||||
}
|
||||
|
||||
return $this->getProfileView($profile, $editForm, null, null, 'profile');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{username}/password", name="user_profile_password")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('password', profile)")
|
||||
*/
|
||||
public function passwordAction(User $profile, Request $request)
|
||||
{
|
||||
$pwdForm = $this->createPasswordForm($profile);
|
||||
$pwdForm->handleRequest($request);
|
||||
|
||||
if ($pwdForm->isSubmitted() && $pwdForm->isValid()) {
|
||||
$password = $this->get('security.password_encoder')
|
||||
->encodePassword($profile, $profile->getPlainPassword());
|
||||
$profile->setPassword($password);
|
||||
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($profile);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('user_profile', ['username' => $profile->getUsername()]);
|
||||
}
|
||||
|
||||
return $this->getProfileView($profile, null, $pwdForm, null, 'password');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{username}/roles", name="user_profile_roles")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('roles', profile)")
|
||||
*/
|
||||
public function rolesAction(User $profile, Request $request)
|
||||
{
|
||||
$rolesForm = $this->createRolesForm($profile);
|
||||
$rolesForm->handleRequest($request);
|
||||
|
||||
if ($rolesForm->isSubmitted() && $rolesForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($profile);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute('user_profile', ['username' => $profile->getUsername()]);
|
||||
}
|
||||
|
||||
return $this->getProfileView($profile, null, null, $rolesForm, 'roles');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param Form|null $editForm
|
||||
* @param Form|null $pwdForm
|
||||
* @param Form|null $rolesForm
|
||||
* @param string $tab
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \Doctrine\ORM\NonUniqueResultException
|
||||
*/
|
||||
protected function getProfileView(
|
||||
User $user,
|
||||
Form $editForm = null,
|
||||
Form $pwdForm = null,
|
||||
Form $rolesForm = null,
|
||||
$tab = 'charts'
|
||||
) {
|
||||
/* @var $timesheetRepo TimesheetRepository */
|
||||
$timesheetRepo = $this->getDoctrine()->getRepository(Timesheet::class);
|
||||
$userStats = $timesheetRepo->getUserStatistics($user);
|
||||
$monthlyStats = $timesheetRepo->getMonthlyStats($user);
|
||||
|
||||
$viewVars = [
|
||||
'tab' => $tab,
|
||||
'user' => $user,
|
||||
'stats' => $userStats,
|
||||
'years' => $monthlyStats,
|
||||
'form' => null,
|
||||
'form_password' => null,
|
||||
'form_roles' => null,
|
||||
];
|
||||
|
||||
if ($this->isGranted('edit', $user)) {
|
||||
$editForm = $editForm ?: $this->createEditForm($user);
|
||||
$viewVars['form'] = $editForm->createView();
|
||||
}
|
||||
if ($this->isGranted('password', $user)) {
|
||||
$pwdForm = $pwdForm ?: $this->createPasswordForm($user);
|
||||
$viewVars['form_password'] = $pwdForm->createView();
|
||||
}
|
||||
if ($this->isGranted('roles', $user)) {
|
||||
$rolesForm = $rolesForm ?: $this->createRolesForm($user);
|
||||
$viewVars['form_roles'] = $rolesForm->createView();
|
||||
}
|
||||
|
||||
return $this->render('user/profile.html.twig', $viewVars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createEditForm(User $user)
|
||||
{
|
||||
return $this->createForm(
|
||||
UserEditType::class,
|
||||
$user,
|
||||
[
|
||||
'action' => $this->generateUrl('user_profile_edit', ['username' => $user->getUsername()]),
|
||||
'method' => 'POST'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createRolesForm(User $user)
|
||||
{
|
||||
return $this->createForm(
|
||||
UserRolesType::class,
|
||||
$user,
|
||||
[
|
||||
'action' => $this->generateUrl('user_profile_roles', ['username' => $user->getUsername()]),
|
||||
'method' => 'POST',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
private function createPasswordForm(User $user)
|
||||
{
|
||||
return $this->createForm(
|
||||
UserPasswordType::class,
|
||||
$user,
|
||||
[
|
||||
'validation_groups' => array('passwordUpdate'),
|
||||
'action' => $this->generateUrl('user_profile_password', ['username' => $user->getUsername()]),
|
||||
'method' => 'POST'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
47
src/Controller/SecurityController.php
Normal file
47
src/Controller/SecurityController.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
|
||||
/**
|
||||
* Controller used to manage the application security.
|
||||
* See http://symfony.com/doc/current/cookbook/security/form_login_setup.html.
|
||||
*/
|
||||
class SecurityController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @Route("/login", name="security_login")
|
||||
*/
|
||||
public function login(AuthenticationUtils $helper): Response
|
||||
{
|
||||
return $this->render('security/login.html.twig', [
|
||||
'last_username' => $helper->getLastUsername(),
|
||||
'error' => $helper->getLastAuthenticationError(),
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* This is the route the user can use to logout.
|
||||
*
|
||||
* But, this will never be executed. Symfony will intercept this first
|
||||
* and handle the logout automatically. See logout in config/packages/security.yaml
|
||||
*
|
||||
* @Route("/logout", name="security_logout")
|
||||
*/
|
||||
public function logout(): void
|
||||
{
|
||||
throw new \Exception('This should never be reached!');
|
||||
}
|
||||
}
|
||||
204
src/Controller/TimesheetController.php
Normal file
204
src/Controller/TimesheetController.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AbstractController;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Timesheet;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Form\TimesheetEditForm;
|
||||
|
||||
/**
|
||||
* Controller used to manage timesheet contents in the public part of the site.
|
||||
*
|
||||
* @Route("/timesheet")
|
||||
* @Security("has_role('ROLE_USER')")
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
class TimesheetController extends AbstractController
|
||||
{
|
||||
use TimesheetControllerTrait;
|
||||
|
||||
/**
|
||||
* @Route("/", defaults={"page": 1}, name="timesheet")
|
||||
* @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="timesheet_paginated")
|
||||
* @Method("GET")
|
||||
* @Cache(smaxage="10")
|
||||
*/
|
||||
public function indexAction($page, Request $request)
|
||||
{
|
||||
$query = $this->getQueryForRequest($request);
|
||||
$query->setUser($this->getUser());
|
||||
$query->setPage($page);
|
||||
|
||||
/* @var $entries Pagerfanta */
|
||||
$entries = $this->getRepository()->findByQuery($query);
|
||||
|
||||
return $this->render('timesheet/index.html.twig', [
|
||||
'entries' => $entries,
|
||||
'page' => $page,
|
||||
'query' => $query,
|
||||
'toolbarForm' => $this->getToolbarForm($query)->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The "main button and flyout" for displaying (and stopping) active entries.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function activeEntriesAction()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$activeEntries = $this->getRepository()->getActiveEntries($user);
|
||||
|
||||
return $this->render(
|
||||
'navbar/active-entries.html.twig',
|
||||
['entries' => $activeEntries]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to stop a running entry.
|
||||
*
|
||||
* @Route("/{id}/stop", name="timesheet_stop")
|
||||
* @Method({"GET"})
|
||||
* @Security("is_granted('stop', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function stopAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
return $this->stop($entry, 'timesheet');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to stop a running entry.
|
||||
*
|
||||
* @Route("/start/{id}", name="timesheet_start", requirements={"id" = "\d+"})
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('start', activity)")
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function startAction(Activity $activity, Request $request)
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
try {
|
||||
$this->getRepository()->startRecording($user, $activity);
|
||||
$this->flashSuccess('timesheet.start.success');
|
||||
} catch (\Exception $ex) {
|
||||
$this->flashError('timesheet.start.error', ['%reason%' => $ex->getMessage()]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('timesheet');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to edit an existing entry.
|
||||
*
|
||||
* @Route("/{id}/edit", name="timesheet_edit")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('edit', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function editAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
return $this->edit($entry, $request, 'timesheet_paginated', 'timesheet/edit.html.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to create a new entry by form.
|
||||
*
|
||||
* @Route("/create", name="timesheet_create")
|
||||
* @Method({"GET", "POST"})
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
{
|
||||
return $this->create($request, 'timesheet', 'timesheet/edit.html.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* The route to delete an existing entry.
|
||||
*
|
||||
* @Route("/{id}/delete", name="timesheet_delete")
|
||||
* @Method({"GET", "POST"})
|
||||
* @Security("is_granted('delete', entry)")
|
||||
*
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function deleteAction(Timesheet $entry, Request $request)
|
||||
{
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->remove($entry);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('timesheet_paginated', ['page' => $request->get('page')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getCreateForm(Timesheet $entry)
|
||||
{
|
||||
return $this->createForm(
|
||||
TimesheetEditForm::class,
|
||||
$entry,
|
||||
[
|
||||
'action' => $this->generateUrl('timesheet_create'),
|
||||
'method' => 'POST',
|
||||
'currency' => Customer::DEFAULT_CURRENCY,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @param int $page
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
protected function getEditForm(Timesheet $entry, $page)
|
||||
{
|
||||
return $this->createForm(
|
||||
TimesheetEditForm::class,
|
||||
$entry,
|
||||
[
|
||||
'action' => $this->generateUrl('timesheet_edit', [
|
||||
'id' => $entry->getId(),
|
||||
'page' => $page
|
||||
]),
|
||||
'method' => 'POST',
|
||||
'currency' => $entry->getActivity()->getProject()->getCustomer()->getCurrency(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
206
src/Controller/TimesheetControllerTrait.php
Normal file
206
src/Controller/TimesheetControllerTrait.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai package.
|
||||
*
|
||||
* (c) Kevin Papst <kevin@kevinpapst.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use App\Form\Toolbar\TimesheetToolbarForm;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
use App\Repository\TimesheetRepository;
|
||||
|
||||
/**
|
||||
* Helper functions for Timesheet controller
|
||||
*
|
||||
* @author Kevin Papst <kevin@kevinpapst.de>
|
||||
*/
|
||||
trait TimesheetControllerTrait
|
||||
{
|
||||
/**
|
||||
* @return TimesheetRepository
|
||||
*/
|
||||
protected function getRepository()
|
||||
{
|
||||
return $this->getDoctrine()->getRepository(Timesheet::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return TimesheetQuery
|
||||
*/
|
||||
protected function getQueryForRequest(Request $request)
|
||||
{
|
||||
$activity = $request->get('activity');
|
||||
$activity = !empty(trim($activity)) ? trim($activity) : null;
|
||||
$project = $request->get('project');
|
||||
$project = !empty(trim($project)) ? trim($project) : null;
|
||||
$customer = $request->get('customer');
|
||||
$customer = !empty(trim($customer)) ? trim($customer) : null;
|
||||
$state = $request->get('state');
|
||||
$state = !empty(trim($state)) ? trim($state) : null;
|
||||
$pageSize = (int) $request->get('pageSize');
|
||||
|
||||
if ($activity !== null) {
|
||||
$repo = $this->getDoctrine()->getRepository(Activity::class);
|
||||
$activity = $repo->getById($activity);
|
||||
if ($activity !== null) {
|
||||
$project = $activity->getProject();
|
||||
if ($project !== null) {
|
||||
$customer = $project->getCustomer();
|
||||
}
|
||||
} else {
|
||||
$customer = null;
|
||||
$project = null;
|
||||
}
|
||||
} elseif ($project !== null) {
|
||||
$repo = $this->getDoctrine()->getRepository(Project::class);
|
||||
$project = $repo->getById($project);
|
||||
if ($project !== null) {
|
||||
$customer = $project->getCustomer();
|
||||
} else {
|
||||
$customer = null;
|
||||
}
|
||||
} elseif ($customer !== null) {
|
||||
$repo = $this->getDoctrine()->getRepository(Customer::class);
|
||||
$customer = $repo->getById($customer);
|
||||
}
|
||||
|
||||
$query = new TimesheetQuery();
|
||||
$query
|
||||
->setActivity($activity)
|
||||
->setProject($project)
|
||||
->setCustomer($customer)
|
||||
->setPageSize($pageSize)
|
||||
->setState($state);
|
||||
|
||||
return $query ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetQuery $query
|
||||
* @param string $route
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getToolbarForm(TimesheetQuery $query, $route = 'timesheet')
|
||||
{
|
||||
return $this->createForm(
|
||||
TimesheetToolbarForm::class,
|
||||
$query,
|
||||
[
|
||||
'action' => $this->generateUrl($route, [
|
||||
'page' => $query->getPage(),
|
||||
]),
|
||||
'method' => 'GET',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @param string $route
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function stop(Timesheet $entry, $route)
|
||||
{
|
||||
try {
|
||||
$this->getRepository()->stopRecording($entry);
|
||||
$this->flashSuccess('timesheet.stop.success');
|
||||
} catch (\Exception $ex) {
|
||||
$this->flashError('timesheet.stop.error', ['%reason%' => $ex->getMessage()]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute($route);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @param Request $request
|
||||
* @param string $redirectRoute
|
||||
* @param string $renderTemplate
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function edit(Timesheet $entry, Request $request, $redirectRoute, $renderTemplate)
|
||||
{
|
||||
$editForm = $this->getEditForm($entry, $request->get('page'));
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($entry);
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute($redirectRoute, ['page' => $request->get('page')]);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$renderTemplate,
|
||||
[
|
||||
'entry' => $entry,
|
||||
'form' => $editForm->createView(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $redirectRoute
|
||||
* @param string $renderTemplate
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function create(Request $request, $redirectRoute, $renderTemplate)
|
||||
{
|
||||
$entry = new Timesheet();
|
||||
$entry->setUser($this->getUser());
|
||||
$entry->setBegin(new \DateTime());
|
||||
|
||||
$createForm = $this->getCreateForm($entry);
|
||||
|
||||
$createForm->handleRequest($request);
|
||||
|
||||
if ($createForm->isSubmitted() && $createForm->isValid()) {
|
||||
$entityManager = $this->getDoctrine()->getManager();
|
||||
$entityManager->persist($entry);
|
||||
|
||||
$entityManager->flush();
|
||||
|
||||
$this->flashSuccess('action.updated_successfully');
|
||||
|
||||
return $this->redirectToRoute($redirectRoute);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
$renderTemplate,
|
||||
[
|
||||
'entry' => $entry,
|
||||
'form' => $createForm->createView(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
abstract protected function getCreateForm(Timesheet $entry);
|
||||
|
||||
/**
|
||||
* @param Timesheet $entry
|
||||
* @param int $page
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
abstract protected function getEditForm(Timesheet $entry, $page);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user