<?php
namespace App\Controller;
use App\Entity\Person;
use App\Entity\PersonLink;
use App\Entity\PersonReference;
use App\Entity\Reference;
use App\Entity\User;
use App\Form\PersonFormType;
use App\Helper\CompareHelper;
use App\Logic\Leecher;
use App\Logic\SyntaxLogic;
use App\Logic\TreeLogic;
use App\Repository\BibleBooksRepository;
use App\Repository\FolkRepository;
use App\Repository\PersonLinkRepository;
use App\Repository\PersonRepository;
use App\Service\UploaderHelper;
use App\Validator\UncertainNumberValidator;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class PersonController extends BaseController
{
/**
* @var PersonRepository
*/
private $personRepository;
/**
* @var BibleBooksRepository
*/
private $bibleBooksRepository;
/**
* @var RouterInterface
*/
private $router;
/**
* @var FolkRepository
*/
private $folkRepository;
/**
* @var PersonLinkRepository
*/
private $personLinkRepository;
public function __construct(BibleBooksRepository $bibleBooksRepository, PersonRepository $personRepository,
FolkRepository $folkRepository, PersonLinkRepository $personLinkRepository, RouterInterface $router)
{
$this->personRepository = $personRepository;
$this->bibleBooksRepository = $bibleBooksRepository;
$this->router = $router;
$this->folkRepository = $folkRepository;
$this->personLinkRepository = $personLinkRepository;
}
/**
* @Route("/persons", name="persons_list")
*/
public function list(Request $request, PaginatorInterface $paginator)
{
$sort = ['field' => 'p.name', 'direction' => 'asc'];
$q = $request->query->get('q');
$queryBuilder = $this->personRepository->filterByUser('p', $this->getUser());
$queryBuilder = $this->personRepository->addSearchQuery($queryBuilder, 'p', $q, false);
$pagination = $paginator->paginate(
$queryBuilder, /* query NOT result */
$request->query->getInt('page', 1)/*page number*/,
20/*limit per page*/, [
'defaultSortFieldName' => $sort['field'],
'defaultSortDirection' => $sort['direction'],
]
);
$pagination->setCustomParameters([
'align' => 'left', # center|right (for template: twitter_bootstrap_v4_pagination and foundation_v6_pagination)
'size' => 'small', # small|large (for template: twitter_bootstrap_v4_pagination)
'style' => 'bottom',
'span_class' => 'whatever',
]);
$pagination->setPageRange(1);
/* $p = $this->personRepository->findOneBy(['id'=>3]);
//$p->getDifference($p->getFather());
$compareHelper = new CompareHelper();
$changes = [];
foreach($p->getUpdates() as $update) {
$changes[$update->getId()] = $compareHelper->cmp($p, $update);
}
dd($changes);*/
return $this->render(
'person/list.html.twig', [
'pagination' => $pagination,
]);
}
/**
* @Route("/person/test", name="person_test")
*/
public function test() {
dd("test");
}
/**
* @Route ("/leech", name ="leech")
* @IsGranted("ROLE_ADMIN")
*/
public function leech(EntityManagerInterface $em, Leecher $leecher)
{
//$leecher->leechLocations($em);
$leecher->leechFolks($em);
//$leecher->leechPersons($em);
}
/**
* @Route ("/person/recalc/ages", name ="recalc_ages")
* @IsGranted("ROLE_ADMIN")
*/
public function recalcAges(EntityManagerInterface $em, TreeLogic $treeLogic)
{
$treeLogic->estimateAgesAction($em, $this->getUser());
}
/**
* @Route ("/person/recalc/tree", name ="recalc_tree")
* @IsGranted("ROLE_ADMIN")
*/
public function recalcTree(EntityManagerInterface $em, TreeLogic $treeLogic)
{
$treeLogic->calcLeafAction($em, $this->getUser());
}
/**
* @Route ("/person/recalc/gender", name ="recalc_gender")
* @IsGranted("ROLE_ADMIN")
*/
public function recalcGender(EntityManagerInterface $em, SyntaxLogic $syntaxLogic)
{
$syntaxLogic->genderHelper($em);
}
/**
* @Route ("/person/recalc/treesyntax", name ="recalc_tree_syntax")
* @IsGranted("ROLE_ADMIN")
*/
public function recalcChildren(EntityManagerInterface $em, SyntaxLogic $syntaxLogic)
{
$syntaxLogic->childrenHelper($em);
}
/**
* @Route ("/person/recalc/folks", name ="recalc_folks")
* @IsGranted("ROLE_ADMIN")
*/
public function recalcFolks(EntityManagerInterface $em, SyntaxLogic $syntaxLogic)
{
$syntaxLogic->folkHelper($em);
}
/**
* @Route ("/person/new", name ="add_person")
* @IsGranted("ROLE_EDIT_ENTITY")
*/
public function new(EntityManagerInterface $em, Request $request, UploaderHelper $uploaderHelper, TreeLogic $treeLogic, ValidatorInterface $validator)
{
$user = $this->getUser();
$form = $this->createForm(PersonFormType::class , null, [
'user' => $user,
]);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
/** @var Person $person */
$person = $form->getData();
/** @var UploadedFile $uploadedFile */
$uploadedFile = $form['imageFile']->getData();
if ($uploadedFile) {
$violations = $validator->validate(
$uploadedFile, [
new NotBlank(
['Please select a File']
) ,
new File([
'maxSize' => '2M',
'mimeTyp es' => [
'image/*',
],
]),
]
);
if($violations->count()>0) {
/** @var ConstraintViolation $violation */
$violation = $violations[0];
$this->addFlash('error', $violation->getMessage());
return $this->redirectToRoute('add_person', [
]);
}
$newFilename = $uploaderHelper->uploadPersonImage($uploadedFile);
$person->setImage($newFilename);
}
$person->setOwner($user);
$user->countChange(User::PERSON);
$em->persist($user);
if (!in_array('ROLE_ACCEPT_CHANGES', $user->getRoles() )) {
/* $change = new EntityChange();
$change->setChangedBy($user)->setModificationType('new');//->setPerson($person);
$person->addChange($change);
$person->setUpdateOf($change);*/
$person->setApproved(false);
$em->persist($person);
// $em->persist($change);
} else {
$person->setApproved(true);
$em->persist($person);
}
$em->flush();
// TODO put in again $treeLogic->calcLeafAction($em);
// $treeLogic->estimateAgesAction($em, $this->getUser());
$this->addFlash('success', 'Person created');
//return $this->redirectToRoute('admin_person_list');
return $this->redirectToRoute('person_edit', [
'id' => $person->getId(),
]);
}
return $this->render('person/new.html.twig', [
'personForm' => $form->createView(),
]);
}
/**
* @Route ("/person/{id}/delete", name="person_delete")
* @IsGranted("ROLE_EDIT_ENTITY", subject="person")
*/
public function delete(Person $person, Request $request)
{
$user = $this->getUser();
$accceptsChanges = $user->acceptsChanges();
$deleteOwnUnaccepted = !$person->getApproved() && $person->getOwner() == $user;
if($accceptsChanges || $deleteOwnUnaccepted){
$person->PrepareDelete($user, $this->em);
$this->em->persist($person);
$this->em->remove($person);
} else {
$person->setTaggedForDeleteBy($user);
$this->em->persist($person);
}
$this->em->flush();
return $this->redirectToRoute('persons_list', [
]);
}
/**
* @Route ("/person/{id}/deny", name="person_deny")
* @IsGranted("ROLE_ACCEPT_CHANGES", subject="person")
* /
public function deny(Person $person, EntityManagerInterface $em)
{
foreach ($person->getChanges() as $change) {
if($change->getModificationType() == "new") {
$em->remove($change);
$person->removeChange($change);
$em->remove($person);
$em->flush();
$this->addFlash('success', 'Person removed');
return $this->redirectToRoute('persons_list', [
]);
}
}
$this->addFlash('success', 'Person reset');
return $this->redirectToRoute('person_edit', [
'id' => $person->getId(),
]);
}
/**
* @Route ("/person/{id}/accept", name="person_accept")
* @IsGranted("ROLE_ACCEPT_CHANGES", subject="person")
* /
public function accept(Person $person, EntityManagerInterface $em)
{
foreach ($person->getChanges() as $change) {
if($change->getModificationType() == "new") {
$em->remove($change);
$person->removeChange($change);
$person->setApproved(true);
$em->persist($person);
$em->flush();
$this->addFlash('success', 'new Person accepted');
break;
}
}
return $this->redirectToRoute('person_edit', [
'id' => $person->getId(),
]);
}*/
/**
* @Route ("/person/{id}/edit", name="person_edit")
* @IsGranted("ROLE_EDIT_ENTITY", subject="person")
*/
public function edit(Person $person, Request $request, EntityManagerInterface $em, UploaderHelper $uploaderHelper,
UncertainNumberValidator $uncertainNumberValidator, TreeLogic $treeLogic)
{
$user = $this->getUser();
$person = $person->getUpdate($user);
if ($request->getMethod() === 'POST' && $request->get('person_form')) {
$cloneNeeded = $person->isCloneNeeded($user);
if($cloneNeeded)
{
$personClone = clone $this->personRepository->find($request->get('id'));
$personClone->setUpdateOf($person);
$personClone->setApproved(false);
$personClone->setOwner($user);
/* $referenceList = $person->getReferenceList();
/** @var PersonReference $reference * /
foreach ($referenceList as $reference){
$referenceClone = clone($reference);
$personClone->addPersonReference($referenceClone);
$em->persist();
}*/
$em->persist($personClone);
$em->flush();
$person = $personClone;
}
}
$form = $this->createForm(PersonFormType::class, $person,
[
'user' => $user,
]
);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
// new
/* if (!$this->isGranted('ROLE_MANAGER', $this->getUser())) {
$this->CheckChanges($old, $windingWorkstepForm, $em, 'windingWorkstep', $article->getWindingWorkstep());
}*/
/** @var UploadedFile $uploadedFile */
$uploadedFile = $form['imageFile']->getData();
if($uploadedFile) {
$newFilename = $uploaderHelper->uploadPersonImage($uploadedFile, $person->getImage());
$person->setImage($newFilename);
}
$uow = $em->getUnitOfWork();
$uow->computeChangeSet($em->getClassMetadata(get_class($person)), $form->getViewData());
$changeSet = $uow->getEntityChangeSet($form->getData());
$em->persist($person);
$em->flush();
if(isset($changeSet['gender'])) {
foreach ($person->getChildren() as $child) {
dd("??");
$person->removeChild($child);
}
}
$born = null;
$died = null;
$bornUncertain = $form['uncertainBorn']->getData();
$diedUncertain = $form['uncertainDied']->getData();
$isBornUncertain = false;
$isDiedUncertain = false;
if($bornUncertain) {
$born = $uncertainNumberValidator->getValue($bornUncertain);
if($uncertainNumberValidator->isUncertain($bornUncertain)) {
$person->setBornEstimated($born);
$person->setBorn(null);
$isBornUncertain = true;
} else {
$person->setBorn($born);
$person->setBornEstimated($born);
}
} else {
$person->setBorn(null);
$person->setBornEstimated(null);
}
if($diedUncertain) {
$died = $uncertainNumberValidator->getValue($diedUncertain);
if($uncertainNumberValidator->isUncertain($diedUncertain)) {
$person->setDiedEstimated($died);
$person->setDied(null);
$isDiedUncertain = true;
} else {
$person->setDied($died);
$person->setDiedEstimated($died);
}
} else {
$person->setDied(null);
$person->setDiedEstimated(null);
}
$em->persist($person);
$em->flush();
$age = $form['age']->getData();
if($age!=null) {
if($born == null) {
if($died != null) {
if ($isDiedUncertain) {
$person->setBornEstimated($born = $died - $age);
} else {
$person->setBorn($born = $died - $age);
}
$em->persist($person);
$em->flush();
}
}
if($died == null) {
if($born != null) {
if ($isBornUncertain) {
$person->setDiedEstimated($born + $age);
} else {
$person->setDied($born + $age);
}
$em->persist($person);
$em->flush();
}
}
}
if (in_array('ROLE_ACCEPT_CHANGES', $this->getUser()->getRoles())) {
if(isset($changeSet['uncertainBorn']) || isset($changeSet['uncertainDied']) || isset($changeSet['age']) || isset($changeSet['livedAtTimeOfPerson'])) {
$treeLogic->estimateAgesAction($em, $this->getUser());
}
if(isset($changeSet['father']) || isset($changeSet['mother']) || isset($changeSet['children'])) {
}
}
$this->addFlash('success', 'Person updated');
}
$addChildren = [];
$q = $request->query->get('q');
if(strlen($q) > 0) {
$addChildren = $this->personRepository->findAllPossibleChildren($this->getUser(), $person, $q);
$existingChildren = $person->getChildren();//$user);
$addChildren = new ArrayCollection(array_diff(
$addChildren,
$existingChildren->toArray()
));
}
return $this->render(
'person/edit.html.twig', [
'personForm' => $form->createView(),
'person' => $person,
'addChildren'=> $addChildren,
]);
}
public function CreateClone(EntityManager $em, Person $originPerson,User $user) : Person{
dd("deprecated");
$personClone = clone $originPerson;
// $change = new EntityChange();
//$change->setPerson($personClone)->setModificationType("edit")->setChangedBy($user);
// $em->persist($change);
//$originPerson->addChange($change);
// $em->persist($change);
$em->persist($originPerson);
$personClone->setUpdateOf($change);
$personClone->setApproved(false);
$personClone->setOwner($user);
$em->persist($personClone);
$em->flush();
return $personClone;
}
/**
* @Route("/person/remove_link/{parent}/{child}", name="removeLink")
* @IsGranted("ROLE_EDIT_ENTITY")
* @param EntityManagerInterface $em
* @param Person $parent
* @param Person $child
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function removeLinkAction(EntityManagerInterface $em, Person $parent, Person $child): \Symfony\Component\HttpFoundation\RedirectResponse
{
$user = $this->getUser();
$existingLinks = $parent->getChildLinks($user);
/** @var PersonLink $existingLink */
foreach ($existingLinks as $existingLink) {
if($existingLink->getChild() == $child && $existingLink->getParent() == $parent->getUpdateOf()){
if(!$existingLink->getApproved() && $existingLink->getOwner() == $user) {
$em->remove($existingLink);
} else {
$existingLink->setTaggedForDeleteBy($user);
}
}
}
$em->flush();
return $this->redirect($this->generateUrl('person_edit',
['id' => $parent->getId()]));
}
/**
* @Route("/person/remove_reference/{person}/{id}", name="remove_reference")
* @IsGranted("ROLE_EDIT_ENTITY")
*/
public function removeReference(EntityManagerInterface $em, Person $person, PersonReference $personReference)
{
$user = $this->getUser();
if ($user && in_array('ROLE_ADMIN', $user->getRoles() )) {
$person->removePersonReference($personReference);
$em->remove($personReference);
$em->persist($person);
} else {
$personReference->setTaggedForDeleteBy($user);
$em->persist($personReference);
}
$em->flush();
return $this->redirectToRoute('person_edit', [
'id' => $person->getId(),
]);
}
/**
* @Route("/person/add_reference/{person}", name="add_reference")
* @IsGranted("ROLE_EDIT_ENTITY")
*/
public function addReferenceAction(BibleBooksUtilityController $bibleBooksUtilityController, Request $request, Person $person)
{
$type = $request->request->get('reftype');
$term = $request->request->get('submit_param');
$valid = $bibleBooksUtilityController->checkIsValid($term);
if($valid['fullReference']!="") {
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository("App:Reference")->findOneBy([
'url' => $valid['fullReference'],
]);
if($reference == null) {
$reference = new Reference();
$reference->setUrl($valid['fullReference']);
$reference->setIsBibleRef($valid['book']!="");
$em->persist($reference);
}
$personReference = new PersonReference();
$personReference->setType($type);
$personReference->setPerson($person);
$personReference->setReference($reference);
$user = $this->getUser();
if($user->acceptsChanges()) {
$personReference->setApproved(true);
} else {
$personReference->setApproved(false);
$personReference->setOwner($user);
}
$em->persist($personReference);
$person->addPersonReference($personReference);
$em->persist($person);
$em->flush();
$this->addFlash('success', 'Reference added');
}else {
$this->addFlash('error', 'Data not valid');
}
return $this->redirectToRoute('person_edit', [
'id' => $person->getId(),
]);
}
/**
* @Route("/person/add_link/{parent}/{child}", name="addLink")
* @IsGranted("ROLE_EDIT_ENTITY")
* @param EntityManagerInterface $em
* @param Person $parent
* @param Person $child
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function addLinkAction(EntityManagerInterface $em, Person $parent, Person $child): \Symfony\Component\HttpFoundation\RedirectResponse
{
$user = $this->getUser();
$child = $child->getUpdateOf() ?? $child;
$parent = $parent->getUpdateOf() ?? $parent;
$parent->getGender() == 'w'
? $child->setMotherParent($em, $parent, $user)
: $child->setFatherParent($em, $parent, $user);
$em = $this->getDoctrine()->getManager();
$em->persist($child);
$em->persist($parent);
$em->flush();
$this->addFlash('success', 'Child link added');
return $this->redirectToRoute('person_edit', [
'id' => $parent->getId(),
]);
}
/**
* @Route("/person/{id}", name="person_show")
*/
public function show(Person $person)
{
$user = $this->getUser();
if ($user && in_array('ROLE_ADMIN', $user->getRoles() )) {
};
/* $addChildren = [];
$q = $request->query->get('q');
if(strlen($q) > 2) {
$addChildren = $repository->findAllPossibleChildren($person, $q);
}*/
/* if(sizeof($person->getReference()) > 0)
{
/** @var Reference $reference* /
$reference = $person->getReferenceL()->toArray()[0];
$reference->generateBibleServerUrl();
}*/
return $this->render('person/show.html.twig', [
'person' => $person,
// 'addchildren' => $addChildren,
]);
}
/**
* @Route("/pedigree", name="pedigree")
*/
public function pedigree()
{
$nodeEntities = $this->personRepository->getNodes($this->getUser());
// dd($nodes);
$nodes = [];
$links = [];
$nodesImages = [];
$i = 0;
/** @var Person $node */
foreach ($nodeEntities as $node){
if($node->getUpdateOf() && $node->getUpdateOf() != $node) // omit, because we get them by getUpdate
{
continue;
}
$node = $node->getUpdate($this->getUser());
$nodeArray['id'] = $node->getId();
$spacePos = strpos($node->getName(), " ");
$nodeArray['name'] = $spacePos ? substr($node->getName(), 0, $spacePos) : $node->getName();
$nodeArray['full_name'] = $node->getName();
$nodeArray['gender'] = $node->getGender();
$nodeArray['level'] = $node->getLeafLevel();
$nodeArray['born'] = $node->getBorn(true, true);
$nodeArray['died'] = $node->getDied(true, true) ?? $nodeArray['born'] + 80;
$nodeArray['fuzzyBegin'] = $node->getBorn() !== null ? 'd' : ($node->getBorn(true) ? 'e' : 'c');
$nodeArray['fuzzyEnd'] = $node->getDied() != null ? 'd' : ($node->getBorn(true) ? 'e' : 'c');
$nodeArray['image'] = $node->getImage();
$nodesImages[$node->getId()] = $node->getImage();
$nodes[] = $nodeArray;
}
$linkEntities = $this->personLinkRepository->getLinks($this->getUser());
/** @var PersonLink $iink */
foreach ($linkEntities as $iink) {
$linkArray = [];
$linkArray['source'] = $iink->getParent()->getUpdate($this->getUser())->getId();
$linkArray['target'] = $iink->getChild()->getUpdate($this->getUser())->getId();
$links[] = $linkArray;
}
// dd($links, $nodes);
// $nodesImages = $this->personRepository->getNodesImageList($this->getUser());
$books = $this->bibleBooksRepository->getJSONNodes();
$folkNodes = $this->folkRepository->getNodes();
$folkLinks = $this->folkRepository->getLinks();
// $getAllUserChanges()
// dd($nodes, $folkNodes);
//dd($links);
$nodes = array_merge($nodes, $folkNodes);
usort($nodes, function($a, $b){
return ($a['born'] < $b['born']) ? -1 : 1;
});
// dd($nodes);
// dd(json_encode(array_merge($links,$folkLinks)));
return $this->render('person/pedigree.html.twig', [
'nodes' => json_encode($nodes),
'images' => $nodesImages,
'links'=>json_encode(array_merge($links,$folkLinks)),
// 'links'=>json_encode($links),
'books'=>$books,
'person_info_url' => $this->router->generate('person_utility_info'),
]);
}
}