Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
potage
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mathieu
potage
Commits
bbc50df0
Commit
bbc50df0
authored
Sep 04, 2018
by
Mat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
améliore, factorise, déplace une fonction, utilise les objets si possible
parent
e6b8094f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
134 additions
and
122 deletions
+134
-122
src/PotageBundle/Command/CronOffreCommand.php
src/PotageBundle/Command/CronOffreCommand.php
+13
-52
src/PotageBundle/Controller/DefaultController.php
src/PotageBundle/Controller/DefaultController.php
+5
-14
src/PotageBundle/Repository/UserRepository.php
src/PotageBundle/Repository/UserRepository.php
+0
-13
src/PotageBundle/Repository/UtilisateurRepository.php
src/PotageBundle/Repository/UtilisateurRepository.php
+0
-1
src/PotageBundle/Resources/views/Default/test.html.twig
src/PotageBundle/Resources/views/Default/test.html.twig
+8
-4
src/PotageBundle/Services/LettreToken.php
src/PotageBundle/Services/LettreToken.php
+63
-19
src/PotageBundle/Services/Newsletter.php
src/PotageBundle/Services/Newsletter.php
+45
-19
No files found.
src/PotageBundle/Command/CronOffreCommand.php
View file @
bbc50df0
...
...
@@ -4,7 +4,6 @@ namespace PotageBundle\Command;
use
PotageBundle\Entity\Offre
;
use
PotageBundle\Entity\User
;
use
PotageBundle\Services\LettreToken
;
use
Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand
;
use
Symfony\Component\Console\Input\InputInterface
;
...
...
@@ -34,12 +33,13 @@ class CronOffreCommand extends ContainerAwareCommand
{
$this
->
setName
(
'potage:cron:offre'
)
->
setDescription
(
"
Vérifie la date d'expiration des offres en cour
s"
);
->
setDescription
(
"
Archive les offres qui sont expirée
s"
);
}
/**
* Vérifie que les offres en cours n'ont pas expiré.
* Si c'est le cas, le statut est changé et un mail est envoyé aux maraichers.
* Si c'est le cas, le statut est changé, les tokens associés sont révoqués
* et un mail est envoyé aux maraichers.
*
* @param InputInterface $input
* @param OutputInterface $output
...
...
@@ -48,9 +48,11 @@ class CronOffreCommand extends ContainerAwareCommand
protected
function
execute
(
InputInterface
$input
,
OutputInterface
$output
)
{
$em
=
$this
->
getContainer
()
->
get
(
'doctrine'
)
->
getManager
();
$em
=
$this
->
getContainer
()
->
get
(
'doctrine'
)
->
getManager
();
$currentOffre
=
$em
->
getRepository
(
'PotageBundle:Offre'
)
$currentOffre
=
$em
->
getRepository
(
'PotageBundle:Offre'
)
->
findAllByStatusForRead
(
'current'
);
$now
=
new
\DateTime
(
'now'
);
...
...
@@ -62,16 +64,18 @@ class CronOffreCommand extends ContainerAwareCommand
{
if
(
$offre
->
getEndedAt
()
<=
$now
)
{
// change le statut de l'offre
$offre
->
setStatus
(
'closed'
);
$output
->
write
(
"
\n
"
.
$offre
->
getReference
()
.
": offre expired since "
.
date_format
(
$offre
->
getEndedAt
(),
"d/m/Y H:i"
)
.
", change status to archive..
\n
"
);
.
", change status to archive..
\n
"
);
$offre
->
setStatus
(
'closed'
);
$ret
=
$this
->
revoquePotageUsersTokens
(
$offre
);
// révoque les tokens
$ret
=
$this
->
lettreToken
->
revoquePotageUsersTokens
(
$offre
);
$output
->
writeln
(
$ret
);
// TODO envoyer un mail au gestionnaire pour notifier l'expiration de l'offre
...
...
@@ -81,49 +85,6 @@ class CronOffreCommand extends ContainerAwareCommand
$output
->
write
(
"
\n
Done
\n
"
);
}
/**
* On parcourt la table User, colonne tokenKey
* Chaque token est décodé et s'il correspond à l'offre expirée, on le supprime
*
* @param Offre $offre
* @return array
*/
private
function
revoquePotageUsersTokens
(
Offre
$offre
)
{
$em
=
$this
->
getContainer
()
->
get
(
'doctrine'
)
->
getManager
();
$usersTokenKeys
=
$em
->
getRepository
(
'PotageBundle:User'
)
->
findAllTokenKeys
();
$log
=
array
();
foreach
(
$usersTokenKeys
as
$userTokenKeys
)
{
foreach
(
$userTokenKeys
[
'tokenKey'
]
as
$uTokenKey
)
{
$uOffre
=
intval
(
$this
->
lettreToken
->
decodePotageUserToken
(
$uTokenKey
)[
'offre_id'
]);
if
(
$uOffre
===
$offre
->
getId
())
{
/**
* @var User $user
*/
$user
=
$em
->
getRepository
(
'PotageBundle:User'
)
->
find
(
$userTokenKeys
[
'id'
]);
$user
->
removeTokenKey
(
$uTokenKey
);
$log
[]
=
" User "
.
$userTokenKeys
[
'id'
]
.
", removing token "
.
$uTokenKey
;
}
}
}
$em
->
flush
();
count
(
$log
)
===
0
?
$log
[]
=
" No tokens detected for this offre !"
:
null
;
return
$log
;
}
...
...
src/PotageBundle/Controller/DefaultController.php
View file @
bbc50df0
...
...
@@ -28,30 +28,20 @@ class DefaultController extends MasterController
*
* @param Request $request
* @param Newsletter $newsletter
* @param LettreToken $lettreToken
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public
function
testAction
(
Request
$request
,
Newsletter
$newsletter
,
LettreToken
$lettreToken
)
public
function
testAction
(
Request
$request
,
Newsletter
$newsletter
)
{
/**
* @var Lettre $lettre
*/
$lettre
=
$this
->
get
(
'doctrine'
)
->
getManager
()
->
getRepository
(
'PotageBundle:Lettre'
)
->
findOneForSend
(
7
);
->
findOneForSend
(
5
);
$header
=
array
(
'id'
=>
$lettre
->
getId
(),
'start'
=>
$lettre
->
getStartedAt
(),
'end'
=>
$lettre
->
getEndedAt
(),
'status'
=>
$lettre
->
getStatus
(),
'subject'
=>
$lettre
->
getSubject
(),
'reference'
=>
$lettre
->
getReference
(),
);
/**
* Initilalise un formulaire simple pour déclencher l'envoi
*/
...
...
@@ -66,12 +56,13 @@ class DefaultController extends MasterController
$retour
=
null
;
if
(
$form
->
isSubmitted
()
&&
$form
->
isValid
())
{
$retour
=
$newsletter
->
sendLettreToGroup
(
$lettre
,
$lettreToken
);
// Envoi de la newsletter
$retour
=
$newsletter
->
sendLettreToGroup
(
$lettre
);
}
return
$this
->
render
(
'@Potage/Default/test.html.twig'
,
array
(
'lettre'
=>
$header
,
'formEnvoi'
=>
$form
->
createView
(),
'lettre'
=>
$lettre
,
'retour'
=>
$retour
,
));
}
...
...
src/PotageBundle/Repository/UserRepository.php
View file @
bbc50df0
...
...
@@ -12,19 +12,6 @@ use Symfony\Component\Security\Core\User\UserInterface;
*/
class
UserRepository
extends
\Doctrine\ORM\EntityRepository
implements
UserLoaderInterface
{
/**
* @param $id_utilisateur
* @return mixed
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public
function
findOneByUtilisateur
(
$id_utilisateur
)
{
$qb
=
$this
->
createQueryBuilder
(
'fu'
)
->
join
(
'fu.utilisateur'
,
'u'
)
->
where
(
'u.id = :id'
)
->
setParameter
(
':id'
,
$id_utilisateur
);
return
$qb
->
getQuery
()
->
getOneOrNullResult
();
}
/**
* Dans security, je ne peux me référer à une propriété, puisque token_key est un array sérialisé
...
...
src/PotageBundle/Repository/UtilisateurRepository.php
View file @
bbc50df0
...
...
@@ -125,7 +125,6 @@ class UtilisateurRepository extends \Doctrine\ORM\EntityRepository
public
function
findAllByGroup
(
$id_group
)
{
$qb
=
$this
->
createQueryBuilder
(
'u'
)
->
select
(
'u.id'
,
'u.nom'
,
'u.prenom'
,
'u.email'
)
->
join
(
'u.groupes'
,
'g'
)
->
where
(
'g.id = :id'
)
->
setParameter
(
':id'
,
$id_group
);
...
...
src/PotageBundle/Resources/views/Default/test.html.twig
View file @
bbc50df0
...
...
@@ -10,7 +10,7 @@
<h2>
Infolettre #
{{
lettre.id
}}
</h2>
<h3>
{{
lettre.subject
}}
</h3>
<h4>
Période du
{{
lettre.start
|
date
(
'd-m-Y'
)
}}
au
{{
lettre.end
|
date
(
'd-m-Y'
)
}}
</h4>
<h4>
Période du
{{
lettre.start
edAt
|
date
(
'd-m-Y'
)
}}
au
{{
lettre.endedAt
|
date
(
'd-m-Y'
)
}}
</h4>
<h3>
Envoyer la lettre
</h3>
{{
form
(
formEnvoi
)
}}
...
...
@@ -19,11 +19,15 @@
<hr>
<div>
<h4>
Référence:
{{
lettre.reference
}}
</h4>
<h5>
Statut:
{{
lettre.status
}}
</h5>
<h5>
Offre attachée:
{{
lettre.offre.reference
}}
(#
{{
lettre.offre.id
}}
)
</h5>
<h5>
Envoi à :
</h5>
<ul>
{%
for
item
in
retour
%}
<li>
{{
loop.index
}}
)
{{
item.to
}}
→
{{
item.result
}}
</li>
{%
for
mail
in
retour
%}
<li>
{{
loop.index
}}
)
{{
mail.tostring
}}
<span
class=
"text-success"
>
→
{{
mail.result
}}
</span><br>
<span
class=
"small text-muted"
>
→ token attached:
{{
mail.to.token
}}
{%
if
not
mail.to.token
%}
<span
class=
"text-danger"
>
Null
</span>
{%
endif
%}
</span>
</li>
{%
endfor
%}
</ul>
</div>
...
...
src/PotageBundle/Services/LettreToken.php
View file @
bbc50df0
...
...
@@ -3,7 +3,7 @@
namespace
PotageBundle\Services
;
use
PotageBundle\Entity\
Lett
re
;
use
PotageBundle\Entity\
Off
re
;
use
PotageBundle\Entity\User
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
...
...
@@ -36,23 +36,14 @@ class LettreToken
/**
* @param int $id_utilisateur
* @param Lettre $lettre
* Encode un token unique pour une offre et un user
*
* @param User $user
* @param Offre $offre
* @return mixed
*/
public
function
encodePotageUserToken
(
$id_utilisateur
,
Lettre
$lett
re
)
public
function
encodePotageUserToken
(
User
$user
,
Offre
$off
re
)
{
/**
* Si l'utilisateur n'est pas associé à un user, token => null
* TODO il faudra alors l'inviter à se créer un compte user,
* après quoi il accèdera à sa page today, qui lui affichera alors les offres liée à ses groupes.
* Et cela même s'il n'avait pas encore de compte user quand la lettre a été envoyée !
*
* @var User $user
*/
$user
=
$this
->
container
->
get
(
'doctrine'
)
->
getRepository
(
'PotageBundle:User'
)
->
findOneByUtilisateur
(
$id_utilisateur
);
if
(
$user
!==
null
)
{
...
...
@@ -60,7 +51,7 @@ class LettreToken
* Vérifie d'abord qu'aucun token pour cette offre n'existe pour cet utilisateur.
* Pour cela on va parcourir le tableau, récupérer l'offre, et la retourner si elle existe
*/
$newOffre
=
$
lettre
->
getOffre
()
->
getId
();
$newOffre
=
$
offre
->
getId
();
$userTokenKeys
=
$user
->
getTokenKey
();
foreach
(
$userTokenKeys
as
$uTokenKey
)
...
...
@@ -68,7 +59,7 @@ class LettreToken
$uOffre
=
intval
(
$this
->
decodePotageUserToken
(
$uTokenKey
)[
'offre_id'
]);
if
(
$uOffre
===
$newOffre
)
{
return
$uTokenKey
;
return
$uTokenKey
;
// on s'arrête là
}
}
...
...
@@ -78,8 +69,8 @@ class LettreToken
$newKey
=
bin2hex
(
random_bytes
(
15
));
$token
=
$newKey
.
'_'
.
$
lettre
->
getOffre
()
->
getId
()
.
'_'
.
$
lettre
->
getOffre
()
->
getReference
();
.
'_'
.
$
offre
->
getId
()
.
'_'
.
$
offre
->
getReference
();
$tokenKey
=
base64_encode
(
$token
);
...
...
@@ -101,6 +92,8 @@ class LettreToken
/**
* Décode un token
*
* @param $token
* @return array
*/
...
...
@@ -114,4 +107,55 @@ class LettreToken
'offre_ref'
=>
$data
[
2
],
);
}
/**
* Révoque les tokens d'une offre
*
* On parcourt la table User, colonne tokenKey
* Chaque token est décodé et s'il correspond à l'offre expirée, on le supprime
*
* @param Offre $offre
* @return array
*/
public
function
revoquePotageUsersTokens
(
Offre
$offre
)
{
$log
=
array
();
$em
=
$this
->
container
->
get
(
'doctrine'
)
->
getManager
();
/**
* @var array $usersTokenKeys
*/
$usersTokenKeys
=
$em
->
getRepository
(
'PotageBundle:User'
)
->
findAllTokenKeys
();
foreach
(
$usersTokenKeys
as
$userTokenKeys
)
{
foreach
(
$userTokenKeys
[
'tokenKey'
]
as
$uTokenKey
)
{
$uOffre
=
intval
(
$this
->
decodePotageUserToken
(
$uTokenKey
)[
'offre_id'
]);
if
(
$uOffre
===
$offre
->
getId
())
{
/**
* @var User $user
*/
$user
=
$em
->
getRepository
(
'PotageBundle:User'
)
->
find
(
$userTokenKeys
[
'id'
]);
// enlève le token
$user
->
removeTokenKey
(
$uTokenKey
);
$log
[]
=
" User "
.
$userTokenKeys
[
'id'
]
.
", removing token "
.
$uTokenKey
;
}
}
}
$em
->
flush
();
count
(
$log
)
===
0
?
$log
[]
=
" No tokens detected for this offre !"
:
null
;
return
$log
;
}
}
\ No newline at end of file
src/PotageBundle/Services/Newsletter.php
View file @
bbc50df0
...
...
@@ -2,7 +2,10 @@
namespace
PotageBundle\Services
;
use
PotageBundle\Entity\Groupe
;
use
PotageBundle\Entity\Lettre
;
use
PotageBundle\Entity\Offre
;
use
PotageBundle\Entity\User
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
class
Newsletter
...
...
@@ -11,22 +14,23 @@ class Newsletter
/**
* Expéditeur, l'application elle-même
* alternc sur grabuge: la mbox postmaster@potage.domainepublic.site est redirigée vers
* -> mathieu@grabuge.domainepublic.net
* -> jaummathieu@collectifs.net
*/
private
$from
=
[
'postmaster@potage.domainepublic.site'
=>
'Potage'
];
private
$container
;
private
$lettreToken
;
/**
* Newsletter constructor.
*
* @param ContainerInterface $container
* @param LettreToken $lettreToken
*/
public
function
__construct
(
ContainerInterface
$container
)
public
function
__construct
(
ContainerInterface
$container
,
LettreToken
$lettreToken
)
{
$this
->
container
=
$container
;
$this
->
lettreToken
=
$lettreToken
;
}
...
...
@@ -139,46 +143,68 @@ class Newsletter
* (à son groupe d'utilisateurs)
*
* @param Lettre $lettre
* @param LettreToken $lettreToken
* @return array
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public
function
sendLettreToGroup
(
Lettre
$lettre
,
LettreToken
$lettreToken
)
public
function
sendLettreToGroup
(
Lettre
$lettre
)
{
$subject
=
$lettre
->
getSubject
();
/**
* @var Offre $offre
* @var Groupe $groupe
*/
$offre
=
$lettre
->
getOffre
();
$groupe
=
$lettre
->
getGroupe
();
/**
* A partir de l'infolettre on récupère les destinataires
* Les destinataires du groupe de l'infolettre,
* un tableau d'utilisteurs
*
* @var array $utilisateurs
*/
$groupe
=
$lettre
->
getGroupe
()
->
getId
();
$utilisateurs
=
$this
->
container
->
get
(
'doctrine'
)
->
getRepository
(
'PotageBundle:Utilisateur'
)
->
findAllByGroup
(
$groupe
);
->
findAllByGroup
(
$groupe
->
getId
());
/**
* Boucle sur chaque utilisateur, envoie le mail,
* récupère le code de retour dans un tableau
*/
$ret
=
array
();
$ret
our
=
array
();
for
(
$i
=
0
;
$i
<
count
(
$utilisateurs
);
$i
++
)
{
/**
* @var User $user
*/
$user
=
$utilisateurs
[
$i
]
->
getUser
();
$token
=
null
;
if
(
$user
)
{
$token
=
$this
->
lettreToken
->
encodePotageUserToken
(
$user
,
$offre
);
}
// TODO quid des utilisateurs qui n'ont pas encore de compte user ?
$to
=
array
(
'id'
=>
$utilisateurs
[
$i
][
'id'
],
'fullName'
=>
$utilisateurs
[
$i
][
'prenom'
]
.
' '
.
$utilisateurs
[
$i
][
'nom'
],
'email'
=>
$utilisateurs
[
$i
][
'email'
],
'token'
=>
$lettreToken
->
encodePotageUserToken
(
$utilisateurs
[
$i
][
'id'
],
$lettre
)
);
dump
(
$to
);
'fullName'
=>
$utilisateurs
[
$i
]
->
getPrenom
()
.
' '
.
$utilisateurs
[
$i
]
->
getNom
(),
'email'
=>
$utilisateurs
[
$i
]
->
getEmail
(),
'token'
=>
$token
);
//dump($to);
// envoi du mail
$result
=
$this
->
sendMail
(
$to
,
$subject
,
$lettre
)
===
1
?
'Sent'
:
'Error'
;
$ret
[
$i
]
=
array
(
'to'
=>
$this
->
parseMail
(
$to
),
'result'
=>
$this
->
sendMail
(
$to
,
$subject
,
$lettre
)
===
1
?
'sent'
:
'error'
$retour
[
$i
]
=
array
(
'to'
=>
$to
,
'tostring'
=>
$this
->
parseMail
(
$to
),
'result'
=>
$result
);
}
return
$ret
;
return
$ret
our
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment