Unverified Commit 18e10f78 authored by Sebastian Castro's avatar Sebastian Castro
Browse files

Automatically warn users for abandoned project

parent a9af04a9
......@@ -78,6 +78,10 @@ services:
arguments:
$baseUrl: '%base_url%'
App\Command\RemoveAbandonnerProjectsCommand:
arguments:
$baseUrl: '%base_url%'
# Overide FOS Registration Controller
App\Controller\RegistrationController:
tags: ['controller.service_arguments']
......
......@@ -302,3 +302,4 @@ nginx -t && service nginx restart
# for SAAS instance
# * * * * * php $WEB_DIR/GoGoCarto/bin/console --env=prod app:main-command
# @daily php $WEB_DIR/GoGoCarto/bin/console --env=prod app:saas:update-projects-info
# @daily php $WEB_DIR/GoGoCarto/bin/console --env=prod app:projects:check-for-deleting
\ No newline at end of file
......@@ -36,6 +36,7 @@ class ProjectAdmin extends AbstractAdmin
->add('published', null)
->add('pinned', null, ['editable' => true])
->add('createdAt')
->add('lastLogin')
->add('_action', 'actions', [
'actions' => [
// 'show' => array(),
......
......@@ -65,9 +65,9 @@ class GoGoMainCommand extends Command
$command = $this->getApplication()->find($commandToExecute->getCommandNAme());
$arguments = [
'command' => $commandToExecute->getCommandName(),
'dbname' => $commandToExecute->getProject()->getDbName(),
];
'command' => $commandToExecute->getCommandName(),
'dbname' => $commandToExecute->getProject()->getDbName(),
];
$input = new ArrayInput($arguments);
try {
......
<?php
namespace App\Command;
use App\Document\User;
use App\Services\MailService;
use Doctrine\ODM\MongoDB\DocumentManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use App\Document\GoGoLogUpdate;
use Symfony\Component\Routing\RouterInterface;
final class RemoveAbandonnerProjectsCommand extends GoGoAbstractCommand
{
public function __construct(DocumentManager $dm, LoggerInterface $commandsLogger,
TokenStorageInterface $security, RouterInterface $router,
MailService $mailService,
$baseUrl
)
{
$this->baseUrl = $baseUrl;
$this->router = $router;
$this->mailService = $mailService;
parent::__construct($dm, $commandsLogger, $security);
}
protected function gogoConfigure(): void
{
$this
->setName('app:projects:check-for-deleting')
->setDescription('Send the newsletter to each user')
;
}
protected function gogoExecute(DocumentManager $dm, InputInterface $input, OutputInterface $output): void
{
$date = new \DateTime();
$projectsToWarn = $dm->createQueryBuilder('App\Document\Project')
->field('lastLogin')->lte($date->setTimestamp(strtotime("-6 month")))
->field('warningToDeleteProjectSentAt')->exists(false)
->getQuery()->execute();
if ($projectsToWarn->count() > 0)
$this->log('Nombre de projets avertis de la suppression : '. $projectsToWarn->count());
foreach ($projectsToWarn as $project) {
$subject = "Votre carte créée sur $this->baseUrl peut elle être effacée?";
$adminUrl = $this->generateUrlForProject($project, 'sonata_admin_dashboard');
$content = "Bonjour !</br></br> Vous êtes administrateur.ice de la carte {$project->getName()} sur {$this->baseUrl}. Nous avons noté qu'aucun utilisateur ne s'est logué sur cette carte depuis plusieurs mois. Votre projet est-il abandonné?</br>
Le nombre de carte sur $this->baseUrl ne cesse de grandir, et cela utilise pas mal de ressources sur notre serveur. Si votre projet n'a plus lieu d'être merci de vous connecter à votre <a href='{$adminUrl}'>espace d'administration</a> et de cliquer sur \"Supprimer mon projet\" en bas du menu de gauche.</br>
Si au contraire vous souhaitez conserver votre projet, merci de vous loguer sur votre carte.</br>
Si votre inactivité persiste dans les prochains mois, nous nous réservons le droit de supprimer votre carte en dernier recours (après vérification bien sûr).</br></br>
Bien cordialement,</br>
L'équipe de {$this->baseUrl}";
foreach ($project->getAdminEmailsArray() as $email) {
$this->mailService->sendMail($email, $subject, $content);
}
$project->setWarningToDeleteProjectSentAt(time());
$dm->persist($project);
}
$projectsToDelete = $dm->createQueryBuilder('App\Document\Project')
->field('lastLogin')->lte($date->setTimestamp(strtotime("-8 month")))
->field('warningToDeleteProjectSentAt')->lte($date->setTimestamp(strtotime("-2 month")))
->getQuery()->execute();
$message = "Les projets suivants sont probablement à supprimer : ";
foreach ($projectsToDelete as $project) {
$url = $this->generateUrlForProject($project);
$message .= '<li><a href="' . $url .'">' . $project->getName() .' / Nombre de points : ' . $project->getDataSize() .'</li>';
$project->setWarningToDeleteProjectSentAt(time());
}
if ($projectsToDelete->count() > 0) {
$this->log('Nombre de projets à supprimer : '. $projectsToDelete->count());
$log = new GoGoLogUpdate('info', $message);
$dm->persist($log);
}
$dm->flush();
}
protected function generateUrlForProject($project, $route = 'gogo_homepage', $params = [])
{
return 'http://'.$project->getDomainName().'.'.$this->baseUrl.$this->router->generate($route, $params);
}
}
......@@ -48,6 +48,7 @@ class UpdateProjectsInfoCommand extends Command
$project->setDataSize($data['dataSize']);
$project->setAdminEmails($data['adminEmails']);
$project->setPublished($data['publish']);
$project->setLastLogin($data['lastLogin']);
$this->dm->persist($project);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
......
......@@ -313,8 +313,10 @@ class APIController extends GoGoController
$users = $dm->getRepository('App\Document\User')->findAll();
$adminEmails = [];
$lastLogin = null;
foreach ($users as $key => $user) {
if ($user->isAdmin()) $adminEmails[] = $user->getEmail();
if (!$lastLogin || $user->getLastLogin() > $lastLogin) $lastLogin = $user->getLastLogin();
}
$responseArray = [
'name' => $config->getAppName(),
......@@ -323,7 +325,8 @@ class APIController extends GoGoController
'tags' => $config->getAppTags(),
'dataSize' => $dataSize,
'adminEmails' => implode(',', $adminEmails),
'publish' => $config->getPublishOnSaasPage()
'publish' => $config->getPublishOnSaasPage(),
'lastLogin' => $lastLogin->getTimestamp()
];
$response = new Response(json_encode($responseArray));
$response->headers->set('Content-Type', 'application/json');
......
......@@ -47,6 +47,13 @@ class Project
/** @MongoDB\Field(type="string") */
private $adminEmails;
/** @MongoDB\Field(type="date") */
private $lastLogin;
/** @MongoDB\Field(type="date") */
private $warningToDeleteProjectSentAt;
/** @MongoDB\Field(type="string") */
private $tags;
......@@ -305,8 +312,12 @@ class Project
public function getAdminEmails() {
return $this->adminEmails;
}
public function getAdminEmailsArray() {
return explode(',', $this->adminEmails);
}
public function setAdminEmails($emails) {
$this->adminEmails = $emails || "";
if (!$this->adminEmails) $emails = "";
$this->adminEmails = $emails;
return $this;
}
public function getPublished() {
......@@ -339,4 +350,22 @@ class Project
$this->tags = $tags;
return $this;
}
public function getLastLogin() {
return $this->lastLogin;
}
public function setLastLogin($date) {
// That's mean that a user logs in again, so we cancel the deletion
if ($this->lastLogin != $date) {
$this->warningToDeleteProjectSentAt = null;
}
$this->lastLogin = $date;
return $this;
}
public function getWarningToDeleteProjectSentAt() {
return $this->warningToDeleteProjectSentAt;
}
public function setWarningToDeleteProjectSentAt($date) {
$this->warningToDeleteProjectSentAt = $date;
return $this;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment