Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/publication state #274

Open
wants to merge 19 commits into
base: master-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
26d79b6
Add states Draft, Scheduled, Published to events only first to test
PhilippeFerreiraDeSousa Oct 14, 2017
57dcede
Déplacement de l'état de publication sur Post. Arrangement formulaire…
PhilippeFerreiraDeSousa Oct 15, 2017
8be81e6
Creation and modification of events work, cannot modify to inferior s…
PhilippeFerreiraDeSousa Oct 15, 2017
adf716a
Publications with ribbon, draft events from other club members don't …
PhilippeFerreiraDeSousa Oct 17, 2017
dbcd096
La modification des events/news se fait directement à l'endroit des p…
PhilippeFerreiraDeSousa Oct 19, 2017
4d40da7
add cancelation of publication edit
PhilippeFerreiraDeSousa Oct 19, 2017
d3187ad
remove alertify ask for mail
PhilippeFerreiraDeSousa Oct 19, 2017
ab5969a
Add ClubUser fixture, remove deprecated doctrine assertion constraint
PhilippeFerreiraDeSousa Oct 19, 2017
0e72392
Change publication ticket color to publication state color
PhilippeFerreiraDeSousa Oct 19, 2017
e81e438
Fix multiple pagination, add /events/check-dates/{slug} to check for …
PhilippeFerreiraDeSousa Oct 20, 2017
ca0a65a
Small front factorization
PhilippeFerreiraDeSousa Oct 21, 2017
4a70526
Back propre sur les requêtes d'events/newsitems qui ne sont pas des b…
PhilippeFerreiraDeSousa Oct 21, 2017
e0928be
Adaptation aux users de l'administration
PhilippeFerreiraDeSousa Oct 21, 2017
469d085
Oops typos
PhilippeFerreiraDeSousa Oct 21, 2017
cc330f1
change style
PhilippeFerreiraDeSousa Oct 29, 2017
daad1bc
migrate data send_mail into publicationState, move getEventCheckDates…
PhilippeFerreiraDeSousa Oct 30, 2017
c1627b8
fix unregistered repos, bfix bug changing a publication slug twice in…
PhilippeFerreiraDeSousa Oct 30, 2017
a82e2fc
fix data migration down
PhilippeFerreiraDeSousa Oct 30, 2017
a2ce603
Not working version on /club/slug/newsitems but checking totalpages i…
PhilippeFerreiraDeSousa Oct 31, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions back/app/DoctrineMigrations/Version20171015200834.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Application\Migrations;

use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;

/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20171015200834 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');

$this->addSql('ALTER TABLE Post ADD publicationState VARCHAR(255) DEFAULT \'published\' NOT NULL');
$this->addSql('
UPDATE Post
SET Post.publicationState = \'emailed\'
WHERE Post.send_mail
');
$this->addSql('ALTER TABLE Post DROP send_mail');
}

/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');

$this->addSql('ALTER TABLE Post ADD send_mail TINYINT(1) DEFAULT NULL');
$this->addSql('
UPDATE Post
SET Post.send_mail = true
WHERE Post.publicationState = \'emailed\'
');
$this->addSql('
UPDATE Post
SET Post.send_mail = false
WHERE Post.publicationState != \'emailed\'
');
$this->addSql('ALTER TABLE Post DROP publicationState');
}
}
24 changes: 22 additions & 2 deletions back/src/KI/CoreBundle/Controller/ResourceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,32 @@ class ResourceController extends LikeableController
* @param boolean $auth Un override éventuel pour le check des permissions
* @return Response
*/
public function getAll($auth = false)
public function getAll($auth = false, array $findBy = [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi un $findBy sur le getAll des resources ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je l'utilise pour requêter les messages à /newsitems?name=message

if ($request->query->get('name') == 'message') {
      $findBy = array('name' => 'message');
      return $this->getAll($this->is('EXTERIEUR'), $findBy);
}

En soi donner "message" comme titre de news aux messages de l'accueil est très douteux

{
$this->trust(!$this->is('EXTERIEUR') || $auth);

$paginateHelper = $this->get('ki_core.helper.paginate');
extract($paginateHelper->paginateData($this->repository));
extract($paginateHelper->paginateData($this->repository, $findBy));

list($results, $links, $count) = $paginateHelper->paginateView($results, $limit, $page, $totalPages, $count);

return $this->json($results, 200, [
'Links' => implode(',', $links),
'Total-count' => $count
]);
}

/**
* Route GET (liste) générique
* @param boolean $auth Un override éventuel pour le check des permissions
* @return Response
*/
public function getPaginatedResponse($dql, $auth = false)
{
$this->trust(!$this->is('EXTERIEUR') || $auth);

$paginateHelper = $this->get('ki_core.helper.paginate');
extract($paginateHelper->paginateQuery($dql));

list($results, $links, $count) = $paginateHelper->paginateView($results, $limit, $page, $totalPages, $count);

Expand Down
4 changes: 1 addition & 3 deletions back/src/KI/CoreBundle/Helper/FormHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ public function formData($item, $method, $flush = true)
if ($form->isSubmitted() && $form->isValid()) {
if ($method == 'POST') {
$this->manager->persist($item);
$code = 201;
} else {
$code = 204;
}
$code = 201;
if ($flush)
$this->manager->flush();
} else {
Expand Down
63 changes: 62 additions & 1 deletion back/src/KI/CoreBundle/Helper/PaginateHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function paginateData(EntityRepository $repository, array $findBy = [])

// On s'assure de bien recevoir des arrays
foreach ($findBy as $key => $value) {
$findBy[$key] = array($value);
$findBy[$key] = is_array($value) ? $value : array($value);
}

// On récupère les paramètres de la requête
Expand Down Expand Up @@ -109,6 +109,67 @@ public function paginateData(EntityRepository $repository, array $findBy = [])
];
}

/**
* En fonction de la requête et de la requête DQL, récupère les données utiles à la pagination
* Utiliser en cas de requête plus complexe qui ne peut se réduire à une forme normale conjonctive
* d'égalités simples sur les attributs de l'objet requêté
* @param string $dql La requête dql à paginer
* @return array Les données de pagination (nombre de pages, etc.)
*/
public function paginateQuery(string $dql)
{
$request = $this->request->query;
$objectRefererLength = strpos($dql, "FROM") - 8;
$objectReferer = substr($dql, 7, $objectRefererLength);

// On récupère les paramètres de la requête
$page = $request->has('page') ? $request->get('page') : 1;
$limit = $request->has('limit') ? $request->get('limit') : 100;
$sort = $request->has('sort') ? $request->get('sort') : null;

if ($sort === null) {
$sortBy = ['id' => 'DESC'];
} else {
$sortBy = [];

foreach (explode(',', $sort) as $value) {
$order = preg_match('/^\-.*/isU', $value) ? 'DESC' : 'ASC';
$field = preg_replace('/^\-/isU', '', $value);
$sortBy[$field] = $order;
}
}

foreach($sortBy as $field => $order){
$dql .= (' ORDER BY ' . $objectReferer . "." . $field . " " . $order);
}

$posReferer = strpos($dql, $objectReferer);
$countDql = substr_replace($dql, "COUNT(" . $objectReferer . ")", $posReferer, strlen($objectReferer));
$count = $this->manager->createQuery($countDql)->getSingleScalarResult();

// On vérifie que l'utilisateur ne fasse pas de connerie avec les variables
$totalPages = ceil($count/$limit);
$limit = min($limit, 10000);
$limit = max($limit, 1);
$page = min($page, $totalPages);
$page = max($page, 1);

$results = $this->manager->createQuery($dql)
->setMaxResults($limit)
->setFirstResult(($page - 1)*$limit)
->getResult();

return [
'sortBy' => $sortBy,
'limit' => $limit,
'offset' => ($page - 1)*$limit,
'page' => $page,
'totalPages' => $totalPages,
'count' => $count,
'results' => $results,
];
}

/**
* Génère les headers de pagination et renvoie la réponse
* @param array $results Les résultats à paginer
Expand Down
19 changes: 19 additions & 0 deletions back/src/KI/CoreBundle/Repository/ResourceRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,24 @@

abstract class ResourceRepository extends EntityRepository
{
public function findByDql($dql, $objectReferer, $findBy) {
foreach ($findBy as $key => $values) {
if ($key != 'page' && $key != 'limit' && $key != 'sort') {
$values = explode(',', $values);
$andCount = 0;
$and = '';
foreach($values as $value) {
if($andCount > 0){
$and .= ' OR ';
}
$and .= ($objectReferer . '.' . $key . ' = ' . (is_string($value) ? "\'" . $value . "\'" : $value));

$andCount++;
}
$dql .= " AND (" . $and . ")";
}
}

return $dql;
}
}
33 changes: 31 additions & 2 deletions back/src/KI/PublicationBundle/Controller/EventsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class EventsController extends ResourceController
{
Expand All @@ -39,9 +40,10 @@ public function setContainer(ContainerInterface $container = null)
* @Route("/events")
* @Method("GET")
*/
public function getEventsAction()
public function getEventsAction(Request $request)
{
return $this->getAll();
$dql = $this->repository->getAllowedNewsitemsDql($this->getUser()->getId(), $request->query->all());
return $this->getPaginatedResponse($dql);
}

/**
Expand All @@ -63,6 +65,9 @@ public function getEventsAction()
public function getEventAction($slug)
{
$event = $this->getOne($slug);
if ($event->getPublicationState() == 'draft' && !$this->isClubMember($event->getAuthorClub())) {
throw $this->createAccessDeniedException('You cannot access this draft!');
}

return $this->json($event);
}
Expand Down Expand Up @@ -159,6 +164,30 @@ public function deleteEventAction($slug)
return $this->json(null, 204);
}

/**
* @ApiDoc(
* description="Renvoie la liste des événements qui chevauchent un créneau horaire",
* input="KI\PublicationBundle\Form\EventType",
* statusCodes={
* 204="Requête traitée avec succès mais pas d’information à renvoyer",
* 401="Une authentification est nécessaire pour effectuer cette action",
* 503="Service temporairement indisponible ou en maintenance",
* },
* section="Publications"
* )
* @Route("/events/{slug}/check-dates")
* @Method("GET")
*/
public function getEventCheckDatesAction(Request $request, $slug)
{
$startDate = $request->query->get('startDate');
$endDate = $request->query->get('endDate');
$matchedEvents = $this->repository->findSimultaneousEvents($startDate, $endDate, $slug);

return $this->json($matchedEvents);

}

/**
* @ApiDoc(
* description="Shotgunne un événement",
Expand Down
17 changes: 15 additions & 2 deletions back/src/KI/PublicationBundle/Controller/NewsitemsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class NewsitemsController extends ResourceController
{
Expand All @@ -32,9 +35,16 @@ public function setContainer(ContainerInterface $container = null)
* @Route("/newsitems")
* @Method("GET")
*/
public function getNewsitemsAction()
public function getNewsitemsAction(Request $request)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Est-ce que tous les newsitems ne seraient pas des événements ? Pourquoi s'emmerder à dupliquer le code partout ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ca aurait été trop logique, Newsitem et Event héritent tous deux de Post

{
return $this->getAll($this->is('EXTERIEUR'));
if ($request->query->get('name') == 'message') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Est-ce que les messages sont vraiment utiles sur uPont ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non effectivement, on aurait pu en faire quelque chose mais ils n'ont même pas d'existence réel dans la bdd. Mais bon ils ne font de mal à personne où ils sont

$findBy = ['name' => 'message'];
return $this->getAll($this->is('EXTERIEUR'), $findBy);
}
else {
$dql = $this->repository->getAllowedNewsitemsDql($this->getUser()->getId(), $request->query->all());
return $this->getPaginatedResponse($dql);
}
}

/**
Expand All @@ -56,6 +66,9 @@ public function getNewsitemsAction()
public function getNewsitemAction($slug)
{
$newsitem = $this->getOne($slug, $this->is('EXTERIEUR'));
if ($newsitem->getPublicationState() == 'draft' && !$this->isClubMember($newsitem->getAuthorClub())) {
throw $this->createAccessDeniedException('You cannot access this draft!');
}

return $this->json($newsitem);
}
Expand Down
14 changes: 7 additions & 7 deletions back/src/KI/PublicationBundle/DataFixtures/ORM/LoadEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public function load(ObjectManager $manager)
$event->setAuthorClub($this->getReference('club-ki'));
$event->setAuthorUser($this->getReference('user-trancara'));
$event->setEntryMethod('Libre');
$event->setPublicationState('emailed');
$event->setStartDate(mktime(0, 0, 0) + 36*3600);
$event->setEndDate(mktime(0, 0, 0) + 37.5*3600);
$event->setPlace('P102');
$event->setSendMail(true);
$event->addAttendee($this->getReference('user-taquet-c'));
$event->addAttendee($this->getReference('user-de-boisc'));
$event->setLikes([$this->getReference('user-taquet-c')]);
Expand All @@ -35,10 +35,10 @@ public function load(ObjectManager $manager)
$event->setAuthorClub($this->getReference('club-ki'));
$event->setAuthorUser($this->getReference('user-muzardt'));
$event->setEntryMethod('Libre');
$event->setPublicationState('scheduled');
$event->setStartDate(mktime(0, 0, 0) + 36*3600);
$event->setEndDate(mktime(0, 0, 0) + 36.5*3600);
$event->setPlace('P402');
$event->setSendMail(true);
$event->addAttendee($this->getReference('user-taquet-c'));
$event->addAttendee($this->getReference('user-de-boisc'));
$event->addAttendee($this->getReference('user-muzardt'));
Expand All @@ -51,11 +51,11 @@ public function load(ObjectManager $manager)
$event->setAuthorClub($this->getReference('club-mediatek'));
$event->setAuthorUser($this->getReference('user-trancara'));
$event->setEntryMethod('Shotgun');
$event->setPublicationState('emailed');
$event->setStartDate(1413918000);
$event->setEndDate(1413930600);
$event->setShotgunDate(1413396000);
$event->setPlace('P102');
$event->setSendMail(false);
$event->addAttendee($this->getReference('user-taquet-c'));
$event->addAttendee($this->getReference('user-trancara'));
$event->addAttendee($this->getReference('user-guerinh'));
Expand All @@ -68,10 +68,10 @@ public function load(ObjectManager $manager)
$event->setAuthorClub($this->getReference('club-pep'));
$event->setAuthorUser($this->getReference('user-guerinh'));
$event->setEntryMethod('Libre');
$event->setPublicationState('draft');
$event->setStartDate(1413999000);
$event->setEndDate(1414009800);
$event->setPlace('Amphi Navier');
$event->setSendMail(false);
$event->addAttendee($this->getReference('user-taquet-c'));
$event->addAttendee($this->getReference('user-guerinh'));
$manager->persist($event);
Expand All @@ -83,10 +83,10 @@ public function load(ObjectManager $manager)
$event->setAuthorClub($this->getReference('club-bde'));
$event->setAuthorUser($this->getReference('user-dziris'));
$event->setEntryMethod('Libre');
$event->setPublicationState('published');
$event->setStartDate(mktime(0, 0, 0) + 9*3600);
$event->setEndDate(mktime(0, 0, 0) + 15*3600);
$event->setPlace('Salle Polyvalente');
$event->setSendMail(false);
$event->addAttendee($this->getReference('user-taquet-c'));
$event->addAttendee($this->getReference('user-trancara'));
$event->addAttendee($this->getReference('user-guerinh'));
Expand All @@ -102,11 +102,11 @@ public function load(ObjectManager $manager)
$event->setAuthorClub($this->getReference('club-bda'));
$event->setAuthorUser($this->getReference('user-donat-bb'));
$event->setEntryMethod('Shotgun');
$event->setPublicationState('scheduled');
$event->setStartDate(mktime(0, 0, 0) + 40*3600);
$event->setEndDate(mktime(0, 0, 0) + 44*3600);
$event->setShotgunDate(time() + 3600);
$event->setPlace('Opéra Bastille');
$event->setSendMail(true);
$event->setShotgunLimit(12);
$event->setShotgunText('Viens chercher la place chez moi');
$manager->persist($event);
Expand All @@ -115,11 +115,11 @@ public function load(ObjectManager $manager)
$event->setName('Vacances de Noël');
$event->setText('I\'m fucking Santa Claus bitchies!');
$event->setPlace('Ta mère');
$event->setSendMail(false);
$event->setDate(1421778600);
$event->setAuthorClub($this->getReference('club-ki'));
$event->setAuthorUser($this->getReference('user-trancara'));
$event->setEntryMethod('Ferie');
$event->setPublicationState('draft');
$event->setStartDate(time() - 400*3600);
$event->setEndDate(time() + 600*3600);
$manager->persist($event);
Expand Down
Loading