Commit 5d957cd6 authored by Sebastian Castro's avatar Sebastian Castro

Adds GoGoLog functionality. Logs can be attachaed to an import, and errors are...

Adds GoGoLog functionality. Logs can be attachaed to an import, and errors are displayed in dashboard
parent d8c7b687
......@@ -56,6 +56,8 @@
}
.markItUpButton4, .markItUpButton5, .markItUpButton6, .markItUpButton12 + .markItUpSeparator, .markItUpButton13, .markItUpButton14 { display: none; }
.box-body > .alert:last-child { margin-bottom: 0 }
</style>
......
......@@ -101,4 +101,15 @@ class APIController extends GoGoController
$response->headers->set('Content-Type', 'application/json');
return $response;
}
public function hideLogAction($id)
{
$odm = $this->get('doctrine_mongodb')->getManager();
$log = $odm->getRepository('BiopenCoreBundle:GoGoLog')->find($id);
$log->setHidden(true);
$odm->flush();
$response = new Response(json_encode(['success' => true]));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
\ No newline at end of file
<?php
namespace Biopen\CoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Gedmo\Mapping\Annotation as Gedmo;
abstract class GoGoLogType
{
const Debug = "debug";
const Info = "info";
const Warning = "warning";
const Error = "error";
const Success = "success";
}
/**
* @MongoDB\Document
*/
class GoGoLog
{
/**
* @var int
*
* @MongoDB\Id(strategy="INCREMENT")
*/
private $id;
/**
* @var string
*
* @MongoDB\Field(type="string")
* @MongoDB\Index
*/
private $type;
/**
* @var string
*
* @MongoDB\Field(type="string")
*/
private $message;
/**
* @var bool
* When user click "dismiss" log, it will not appear again
* @MongoDB\Field(type="bool")
*/
private $hidden = false;
/**
* @var date $createdAt
*
* @MongoDB\Field(type="date")
* @Gedmo\Timestampable(on="create")
*/
protected $createdAt;
public function __construct($type = null, $message = null)
{
$this->type = $type;
$this->message = $message;
}
/**
* Get id
*
* @return int_id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set message
*
* @param string $message
* @return $this
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get message
*
* @return string $message
*/
public function getMessage()
{
return $this->message;
}
/**
* Set createdAt
*
* @param date $createdAt
* @return $this
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* @return date $createdAt
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set type
*
* @param string $type
* @return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return string $type
*/
public function getType()
{
return $this->type;
}
/**
* Set hidden
*
* @param bool $hidden
* @return $this
*/
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get hidden
*
* @return bool $hidden
*/
public function getHidden()
{
return $this->hidden;
}
}
......@@ -20,3 +20,9 @@ biopen_api_configuration:
defaults: { _controller: BiopenCoreBundle:API:getConfiguration }
requirements:
methods: GET
biopen_api_log_hide:
path: /log/{id}/hide
defaults: { _controller: BiopenCoreBundle:API:hideLog }
requirements:
methods: POST
......@@ -23,19 +23,24 @@ class ImportDynamicAdmin extends AbstractAdmin
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('sourceName', 'text', array('required' => true, 'label' => 'Nom de la source '))
->add('url', 'text', array('label' => "Url de l'api Json", 'required' => true))
->add('geocodeIfNecessary', null, array('required' => false, 'label' => 'Géocoder les élements sans latitude ni longitude à partir de leur adresse'))
->add('createMissingOptions', null, array('required' => false, 'label' => 'Créer les options manquantes à partir des catégories renseignées dans chaque élément'))
->add('optionsToAddToEachElement', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Option',
'required' => false,
'choices_as_values' => true,
'multiple' => true,
'btn_add' => false,
'label' => 'Options à ajouter à chaque élément importé'), array('admin_code' => 'admin.option'))
->add('refreshFrequencyInDays', null, array('required' => false, 'label' => "Fréquence de mise à jours des données en jours (laisser vide pour ne jamais mettre à jour automatiquement"))
->add('idsToIgnore', 'text', array('required' => false, 'attr' => ['class' => 'gogo-display-array'], 'label' => "Liste des IDs à ignorer lors de l'import (pour ignorer un élément, supprimer le et il ne sera plus jamais importé"));
->with('Improt Dynamique', array('class' => 'col-sm-12'))
->add('sourceName', 'text', array('required' => true, 'label' => 'Nom de la source '))
->add('url', 'text', array('label' => "Url de l'api Json", 'required' => true))
->add('geocodeIfNecessary', null, array('required' => false, 'label' => 'Géocoder les élements sans latitude ni longitude à partir de leur adresse'))
->add('createMissingOptions', null, array('required' => false, 'label' => 'Créer les options manquantes à partir des catégories renseignées dans chaque élément'))
->add('optionsToAddToEachElement', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Option',
'required' => false,
'choices_as_values' => true,
'multiple' => true,
'btn_add' => false,
'label' => 'Options à ajouter à chaque élément importé'), array('admin_code' => 'admin.option'))
->add('refreshFrequencyInDays', null, array('required' => false, 'label' => "Fréquence de mise à jours des données en jours (laisser vide pour ne jamais mettre à jour automatiquement"))
->add('idsToIgnore', 'text', array('required' => false, 'attr' => ['class' => 'gogo-display-array'], 'label' => "Liste des IDs à ignorer lors de l'import (pour ignorer un élément, supprimer le et il ne sera plus jamais importé"))
->end()
->with('Hitorique', array('class' => 'col-sm-12'))
->add('logs', 'hidden', array('attr' => ['class' => 'gogo-display-logs']))
->end();
}
protected function configureRoutes(RouteCollection $collection)
......
......@@ -54,6 +54,7 @@ class MonitoringElementsBlockService extends AbstractBlockService
$activeUsersCount = $this->em->createQueryBuilder('BiopenCoreBundle:User')->field('enabled')->equals(true)->count()->getQuery()->execute();
$activeUsersNewsletterCount = $this->em->createQueryBuilder('BiopenCoreBundle:User')->field('enabled')->equals(true)
->field('newsletterFrequency')->gt(NewsletterFrequencyOptions::Never)->count()->getQuery()->execute();
$errors = $this->em->getRepository('BiopenCoreBundle:GoGoLog')->findBy(['type' => 'error', 'hidden' => false]);
// merge settings
$settings = $blockContext->getSettings();
......@@ -66,7 +67,8 @@ class MonitoringElementsBlockService extends AbstractBlockService
'allVisibleCount' => $allVisibleElements,
'visibleNonImportedCount' => $visibleNonImportedElements,
'activeUsersCount' => $activeUsersCount,
'activeUsersNewsletterCount' => $activeUsersNewsletterCount
'activeUsersNewsletterCount' => $activeUsersNewsletterCount,
'errors' => $errors
), $response);
}
}
\ No newline at end of file
......@@ -58,7 +58,12 @@ class Import extends AbstractFile
/**
* @MongoDB\Field(type="bool")
*/
private $geocodeIfNecessary = false;
private $geocodeIfNecessary = false;
/**
* @MongoDB\ReferenceMany(targetDocument="Biopen\CoreBundle\Document\GoGoLog", cascade={"all"})
*/
private $logs;
public function __construct() {}
......@@ -215,4 +220,36 @@ class Import extends AbstractFile
{
return $this->sourceName;
}
/**
* Add log
*
* @param Biopen\CoreBundle\Document\GoGoLog $log
*/
public function addLog(\Biopen\CoreBundle\Document\GoGoLog $log)
{
$this->logs[] = $log;
}
/**
* Remove log
*
* @param Biopen\CoreBundle\Document\GoGoLog $log
*/
public function removeLog(\Biopen\CoreBundle\Document\GoGoLog $log)
{
$this->logs->removeElement($log);
}
/**
* Get logs
*
* @return \Doctrine\Common\Collections\Collection $logs
*/
public function getLogs()
{
$logs = is_array($this->logs) ? $this->logs : $this->logs->toArray();
usort( $logs, function ($a, $b) { return $b->getCreatedAt()->getTimestamp() - $a->getCreatedAt()->getTimestamp(); });
return $logs;
}
}
{% extends sonata_block.templates.block_base %}
{% block block %}
{% if errors|length %}
<div class="sonata-block-log-errors box box-danger">
<div class="box-header with-border">
<h3 class="box-title">Des erreurs ont eu lieu récemment</h3>
</div>
<div class="box-body">
{% include '@BiopenAdmin/core_custom/custom-fields/display-logs.html.twig' with { logs: errors, dismissLog: true } %}
</div>
</div>
{% endif %}
<div class="row">
<div class="col-xs-6 col-md-3">
......
<script>
var url = "{{ path('biopen_api_log_hide', {'id': 'ID'}) }}";
function hideLog($logId) {
$.ajax({
method : 'post',
url : url.replace("ID", $logId),
complete : function(data, status, object) {
if ($('.sonata-block-log-errors .alert').length == 0) $('.sonata-block-log-errors').hide();
},
});
}
</script>
{% set logs = logs is defined ? logs : form.vars.sonata_admin.admin.subject.logs %}
{% for log in logs %}
<div class="alert alert-{{ log.type }}">
{% if dismissLog is defined %}
<button type="button" class="close" data-dismiss="alert" aria-label="Fermer" onclick="hideLog({{log.id}})"><span aria-hidden="true" style="font-size: 1.6rem">Ne plus afficher</span></button>
{% endif %}
<strong>{{ log.createdAt|date("d/m/Y à H:i") }}</strong> - {{ log.message }}
</div>
{% endfor %}
......@@ -33,6 +33,8 @@
{% include '@BiopenAdmin/core_custom/custom-fields/ace-code-editor.html.twig' %}
{% elseif attr_class == "gogo-display-array" %}
{% include '@BiopenAdmin/core_custom/custom-fields/display-array.html.twig' %}
{% elseif attr_class == "gogo-display-logs" %}
{% include '@BiopenAdmin/core_custom/custom-fields/display-logs.html.twig' %}
{% else %}
{% set attr = attr|merge({'class': attr_class ~ ' form-control'}) %}
{{ parent() }}
......
......@@ -3,7 +3,7 @@
{% block actions %}
{% endblock %}
{% block sonata_form_actions %}
{% block sonata_form_actions %}
{% if admin.hasroute('edit') and admin.isGranted('EDIT') %}
<button class="btn btn-primary" type="submit" name="btn_create_and_edit"><i class="fa fa-upload" aria-hidden="true"></i> Importer</button>
{% endif %}
......
......@@ -17,6 +17,8 @@ use Biopen\GeoDirectoryBundle\Document\UserRoles;
use Biopen\GeoDirectoryBundle\Document\PostalAddress;
use Biopen\GeoDirectoryBundle\Document\ElementUrl;
use Biopen\GeoDirectoryBundle\Document\ElementImage;
use Biopen\CoreBundle\Document\GoGoLog;
use Biopen\CoreBundle\Document\GoGoLogType;
class ElementImportService
{
......@@ -155,15 +157,19 @@ class ElementImportService
// After flush, we need to get again the import from the DB to avoid doctrine raising errors
$import = $this->em->getRepository('BiopenGeoDirectoryBundle:ImportDynamic')->find($import->getId());
}
}
$this->em->flush();
$this->em->clear();
}
$result = "Import terminé";
if ($this->countElementCreated > 0) $result .= ", " . $this->countElementCreated . " éléments importés";
if ($this->countElementUpdated > 0) $result .= ", " . $this->countElementUpdated . " élements mis à jours";
if ($this->countElementNothingToDo > 0) $result .= ", " . $this->countElementNothingToDo . " élements laissés tels quels (rien à mettre à jour)";
if ($this->countElementErrors > 0) $result .= ", " . $this->countElementErrors . " erreurs pendant l'import";
$logType = $this->countElementErrors > 0 ? ($this->countElementErrors > ($size / 4) ? 'error' : 'warning') : 'success';
$log = new GoGoLog($logType, $result);
$import->addLog($log);
$this->em->flush();
$this->em->clear();
return $result;
}
......
......@@ -7,13 +7,15 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Biopen\CoreBundle\Document\GoGoLog;
use Biopen\CoreBundle\Document\GoGoLogType;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
class GoGoAbstractCommand extends ContainerAwareCommand
{
protected $logger;
protected $output;
protected $odm;
protected function configure()
{
......@@ -24,18 +26,18 @@ class GoGoAbstractCommand extends ContainerAwareCommand
protected function execute(InputInterface $input, OutputInterface $output)
{
$odm = $this->getContainer()->get('doctrine_mongodb.odm.default_document_manager');
$this->odm = $this->getContainer()->get('doctrine_mongodb.odm.default_document_manager');
$this->logger = $this->getContainer()->get('monolog.logger.commands');
$this->output = $output;
if ($input->getArgument('dbname')) $odm->getConfiguration()->setDefaultDB($input->getArgument('dbname'));
if ($input->getArgument('dbname')) $this->odm->getConfiguration()->setDefaultDB($input->getArgument('dbname'));
// create dummy user, as some code called from command will maybe need the current user informations
$token = new AnonymousToken('admin', 'admin', ['ROLE_ADMIN']);
$this->getContainer()->get('security.token_storage')->setToken($token);
$this->gogoExecute($odm, $input, $output);
$this->gogoExecute($this->odm, $input, $output);
}
protected function gogoExecute($odm, InputInterface $input, OutputInterface $output) {}
......@@ -52,5 +54,8 @@ class GoGoAbstractCommand extends ContainerAwareCommand
{
$this->logger->error($message);
$this->output->writeln('ERROR ' . $message);
$log = new GoGoLog(GoGoLogType::Error, 'Error running ' . $this->getName() . ' : ' . $message);
$this->odm->persist($log);
$this->odm->flush();
}
}
\ No newline at end of file
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