diff --git a/README.md b/README.md index 8664f43..43d753d 100755 --- a/README.md +++ b/README.md @@ -2,6 +2,39 @@ REST backend in symfony 5 for Funky framadate frontend. https://framagit.org/framasoft/framadate/funky-framadate-front + ------------------------------------ -------------- -------- ------ ---------------------------------------------------- +Name Method Scheme Host Path + ------------------------------------ -------------- -------- ------ ---------------------------------------------------- +_preview_error ANY ANY ANY /_error/{code}.{_format} +admin_homepage_get_default GET ANY ANY /admin/ +admin_homepage_clean_expired_polls GET ANY ANY /admin/polls/clean/{token} +admin_homepage_migrate_framadate GET ANY ANY /admin/polls/migrate +home_sweet_home GET ANY ANY / +admin_homepage_migrate_from_v1 GET ANY ANY /migration-from-v1/{unique_key} +user_homepageget_default GET ANY ANY /user/ +user_homepage_polls_send_by_email GET ANY ANY /user/{email}/polls/send-by-email +poll_index GET ANY ANY /poll/ +poll_new GET|POST ANY ANY /poll/new +poll_show GET ANY ANY /poll/{id} +poll_edit GET|POST ANY ANY /poll/{id}/edit +poll_delete DELETE ANY ANY /poll/{id} +api_get_poll_comment GET ANY ANY /api/v1/comment/poll/{id}/comments +api_new_comment POST ANY ANY /api/v1/comment/poll/{id}/comment +api_poll_comments_delete DELETE ANY ANY /api/v1/comment/poll/{id}/comments +api_get_all_polls GET ANY ANY /api/v1/poll/ +api_get_poll GET ANY ANY /api/v1/poll/{customUrl} +api_get_protected_poll GET ANY ANY /api/v1/poll/{customUrl}/pass/{md5} +api_get_admin_poll GET ANY ANY /api/v1/polladmin/{admin_key} +api_update_poll PUT ANY ANY /api/v1/poll/{customUrl}/{token} +api_new_poll POST ANY ANY /api/v1/poll/ +api_test-mail-poll GET ANY ANY /api/v1/poll/mail/test-mail-poll/{emailChoice} +api_poll_delete DELETE ANY ANY /api/v1/poll/{customUrl} +api_check_slug_is_unique GET ANY ANY /api/v1/poll/slug/{customUrl} +api_get_admin_config GET ANY ANY /api/v1/poll/admin/{token} +api_new_vote_stack POST|OPTIONS ANY ANY /api/v1/vote/poll/{custom_url}/answer +api_update_vote_stack PATCH ANY ANY /api/v1/vote/vote-stack/{id}/token/{modifierToken} +api_poll_votes_delete DELETE ANY ANY /api/v1/vote/poll/{id}/votes/{accessToken} + ------------------------------------ -------------- -------- ------ ---------------------------------------------------- ## TODO: diff --git a/src/Controller/api/v1/CommentController.php b/src/Controller/api/v1/CommentController.php index 0eda74c..112c227 100644 --- a/src/Controller/api/v1/CommentController.php +++ b/src/Controller/api/v1/CommentController.php @@ -20,7 +20,7 @@ use Symfony\Component\HttpFoundation\Response; /** * Class DefaultController * @package App\Controller - * @Route("/api/v1",name="api_") + * @Route("/api/v1/comment",name="api_") */ class CommentController extends EmailsController { diff --git a/src/Controller/api/v1/PollController.php b/src/Controller/api/v1/PollController.php index 964efcd..795133e 100644 --- a/src/Controller/api/v1/PollController.php +++ b/src/Controller/api/v1/PollController.php @@ -178,9 +178,8 @@ class PollController extends EmailsController { return $this->notFoundPoll( $admin_key ); } - // good matching pass - return $this->json( $poll->displayForAdmin() ); - + // good matching pass + return $this->json( $poll->displayForAdmin() ); } @@ -250,8 +249,8 @@ class PollController extends EmailsController { if ( count( $data[ 'allowed_answers' ] ) ) { $newpoll->setAllowedAnswers( $data[ 'allowed_answers' ] ); } - $expiracyCalculated = $newpoll->addDaysToDate( new DateTime(), - $data[ 'default_expiracy_days_from_now' ] ) ; + $expiracyCalculated = $newpoll->addDaysToDate( new DateTime(), + $data[ 'default_expiracy_days_from_now' ] ); $newpoll->setExpiracyDate( $expiracyCalculated ); $emOwner = $this->getDoctrine()->getRepository( Owner::class ); @@ -280,16 +279,16 @@ class PollController extends EmailsController { // emails $newpoll->setMailOnComment( true ); - if(isset($data['isOwnerNotifiedByEmailOnNewVote'])){ + if ( isset( $data[ 'isOwnerNotifiedByEmailOnNewVote' ] ) ) { - $newpoll->setMailOnVote( $data['isOwnerNotifiedByEmailOnNewVote'] ); + $newpoll->setMailOnVote( $data[ 'isOwnerNotifiedByEmailOnNewVote' ] ); } - $newpoll->setDescription( $data['description'] ); + $newpoll->setDescription( $data[ 'description' ] ); $newpoll->setHideResults( false ); // possible answers $newpoll->setAllowedAnswers( $data[ 'allowed_answers' ] ); $newpoll->setVotesMax( $data[ 'maxCountOfAnswers' ] ); - $newpoll->setCommentsAllowed( $data['allowComments'] ); + $newpoll->setCommentsAllowed( $data[ 'allowComments' ] ); // setup the password, converting the raw with md5 hash if ( $data[ 'password' ] ) { @@ -311,7 +310,7 @@ class PollController extends EmailsController { elseif ( $data[ 'kind' ] == 'date' ) { $choices = $data[ 'dateChoices' ]; - if ( isset($data[ 'hasSeveralHours' ]) && $data[ 'hasSeveralHours' ] == true ) { + if ( isset( $data[ 'hasSeveralHours' ] ) && $data[ 'hasSeveralHours' ] == true ) { // different hours spans make more choices foreach ( $choices as $c ) { @@ -408,7 +407,7 @@ class PollController extends EmailsController { /** * @Delete( - * path = "/{customUrl}", + * path = "/{admin_key}", * name = "poll_delete", * requirements = {"accessToken"="\w+", "poll_id"="\d+"} * ) @@ -419,13 +418,16 @@ class PollController extends EmailsController { */ public function deletePollAction( - Poll $poll, - $accessToken + $admin_key ) { - if ( $accessToken == $poll->getAdminKey() ) { + $emPoll = $this->getDoctrine()->getRepository( Poll::class ); + $found = $emPoll->findOneByAdminKey( $admin_key ); + + + if ( $found ) { $em = $this->getDoctrine()->getManager(); - $em->remove( $poll ); + $em->remove( $found ); $em->flush(); return $this->json( [ @@ -459,7 +461,7 @@ class PollController extends EmailsController { // we should use an other slug return $this->json( [ - 'message' => ' NO, this slug is already taken on this Framadate instance ', + 'message' => ' NO, this custom_url is already taken on this Framadate instance ', 'data' => [ 'slug' => $customUrl, ], @@ -499,11 +501,11 @@ class PollController extends EmailsController { if ( $pollFound ) { - $poll = $pollFound; + $poll = $pollFound; $returnedPoll = [ - 'message' => 'your poll config', - 'poll' => $poll->displayForAdmin(), + 'message' => 'your poll config', + 'poll' => $poll->displayForAdmin(), ]; return $this->json( $returnedPoll, @@ -520,4 +522,78 @@ class PollController extends EmailsController { } + /** + * Find expired polls and set them as such + * @Get( + * path = "/admin/clean_expired_polls/{token}", + * name = "clean_expired_polls", + * ) + * + * @param $token + * + * @return JsonResponse|Response + */ + public function getExpiredPollsCleanup( $token ) { + + if ( $token !== 'superCaligistriixpirlidouciousse' ) { + return $this->json( [ + 'message' => 'not allowed', + 'data' => [ + 'token' => $token, + ], + ], + 403 ); + } + $em = $this->getDoctrine()->getManager(); + $emPoll = $this->getDoctrine()->getRepository( Poll::class ); + $deletablePollsFound = $emPoll->findDeletableExpiredPolls(); // dead by more than 30 days + $expiredPollsFound = $emPoll->findExpiredPolls(); // just dead + $soon_expired_polls = $emPoll->findSoonExpiredPolls(); // will die in 30 days + + + $deletedTitle = []; + $expiredTitle = []; + $soon_expired_title = []; + + $really_delete = false; + + foreach ( $soon_expired_polls as $item ) { + $soon_expired_title[] = $item->getTitle(); + } + + foreach ( $expiredPollsFound as $item ) { + $expiredTitle[] = $item->getTitle(); + $item->setVotesAllowed( false ); + $em->persist( $item ); + } + + + foreach ( $deletablePollsFound as $item ) { + $deletedTitle[] = $item->getTitle(); + if ( $really_delete ) { + + $item->setVotesAllowed( false ); + $em->remove( $item ); + } + } + + $em->flush(); + + return $this->json( [ + 'message' => 'cleanup report', + 'really_delete' => $really_delete, + 'deleted' => count( $deletablePollsFound ), + 'deleted_titles' => $deletedTitle, + 'expired' => count( $expiredPollsFound ), + 'expired_titles' => $expiredTitle, + 'soon_to_be_expired' => count( $soon_expired_polls ), + 'soon_to_be_expired_titles' => $soon_expired_title, + 'data' => [ + 'token' => $token, + ], + ], + 200 ); + + } + } diff --git a/src/Controller/api/v1/VoteController.php b/src/Controller/api/v1/VoteController.php index 73b863f..b07979a 100644 --- a/src/Controller/api/v1/VoteController.php +++ b/src/Controller/api/v1/VoteController.php @@ -21,7 +21,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class DefaultController * @package App\Controller - * @Route("/api/v1",name="api_") + * @Route("/api/v1/vote",name="api_") */ class VoteController extends EmailsController { diff --git a/src/Repository/PollRepository.php b/src/Repository/PollRepository.php index 6091e20..a829e7c 100755 --- a/src/Repository/PollRepository.php +++ b/src/Repository/PollRepository.php @@ -22,29 +22,37 @@ class PollRepository extends ServiceEntityRepository { // /** // * @return Poll[] Returns an array of Poll objects // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('p') - ->andWhere('p.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('p.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - /* - public function findOneBySomeField($value): ?Poll - { - return $this->createQueryBuilder('p') - ->andWhere('p.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; + public function findExpiredPolls() { + return $this->findExpirationPollOfDay( 0 ); } - */ + + public function findSoonExpiredPolls() { + return $this->findExpirationPollOfDay( 30 ); + } + + public function findDeletableExpiredPolls() { + return $this->findExpirationPollOfDay( - 30 ); + } + + public function findExpirationPollOfDay( $count_of_days){ + + $today = new \DateTime(); + + if($count_of_days > -1){ + + $date_soon = $today->add( new \DateInterval( 'P' . $count_of_days . 'D' ) ); + }else{ + $date_soon = $today->sub( new \DateInterval( 'P' . abs($count_of_days) . 'D' ) ); + + } + + return $this->createQueryBuilder( 'p' ) + ->andWhere( 'p.expiracyDate < :date_soon' ) + ->setParameter( 'date_soon', $date_soon ) + ->orderBy( 'p.id', 'ASC' ) + ->getQuery() + ->getResult(); + } + }