Commit 7781d122 authored by Sebastian Castro's avatar Sebastian Castro

Improve import via csv, and create a UI to upload the file to import and configure

parent c910a23f
......@@ -19,8 +19,7 @@ class AppKernel extends Kernel
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Bazinga\Bundle\GeocoderBundle\BazingaGeocoderBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
//new JMS\TwigJsBundle\JMSTwigJsBundle(),
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
new Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle(),
new Pix\SortableBehaviorBundle\PixSortableBehaviorBundle(),
......@@ -49,6 +48,7 @@ class AppKernel extends Kernel
new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),
new HWI\Bundle\OAuthBundle\HWIOAuthBundle(),
new Ob\HighchartsBundle\ObHighchartsBundle(),
new Vich\UploaderBundle\VichUploaderBundle(),
];
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
......
......@@ -175,8 +175,14 @@ ivory_ck_editor:
- [ Bold, Italic, Underline, Strike, -, RemoveFormat ]
- [ -, Styles,Format,Font,FontSize, TextColor, BGColor]
- [ -, JustifyLeft,JustifyCenter,JustifyRight,JustifyBlock]
vich_uploader:
db_driver: mongodb
mappings:
import_file:
uri_prefix: /imports
upload_destination: '%kernel.root_dir%/../web/uploads/imports'
......@@ -91,6 +91,7 @@ security:
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
- { path: ^/admin/, role: [ROLE_SONATA_ADMIN] }
- { path: ^/import/, role: [ROLE_SONATA_ADMIN] }
- { path: ^/user/, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/api/$, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/api/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
......
......@@ -79,7 +79,13 @@ services:
class: Biopen\GeoDirectoryBundle\Admin\CategoryAdmin
arguments: [~, Biopen\GeoDirectoryBundle\Document\Category, 'BiopenGeoDirectoryBundle:Admin/CategoryAdmin']
tags:
- { name: sonata.admin, manager_type: doctrine_mongodb, group: "data", label: Catégories }
- { name: sonata.admin, manager_type: doctrine_mongodb, group: "data", label: Catégories }
admin.import:
class: Biopen\GeoDirectoryBundle\Admin\ImportAdmin
arguments: [~, Biopen\GeoDirectoryBundle\Document\Import, 'BiopenGeoDirectoryBundle:Admin/ImportAdmin']
tags:
- { name: sonata.admin, manager_type: doctrine_mongodb, group: "data", label: Import }
sonata.block.service.monitoring:
class: Biopen\GeoDirectoryBundle\Block\MonitoringElementsBlockService
......
......@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "16e7a995f5b13d64d76fd078c548a554",
"content-hash": "c772f08f8b7c4e430dc9274d3ddd2c9d",
"hash": "49269ff0eb69aa8544400d44ba3da10e",
"content-hash": "60c4da261b8f1c0bba8c676ea0931fe0",
"packages": [
{
"name": "behat/transliterator",
......@@ -4288,6 +4288,7 @@
"compression",
"minification"
],
"abandoned": "symfony/webpack-encore-pack",
"time": "2017-07-14 07:26:46"
},
{
......@@ -5184,6 +5185,89 @@
],
"time": "2017-09-27 18:06:46"
},
{
"name": "vich/uploader-bundle",
"version": "1.4.2",
"source": {
"type": "git",
"url": "https://github.com/dustin10/VichUploaderBundle.git",
"reference": "09c0f0f805f7dce07c6642548344158a1c7faed6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/09c0f0f805f7dce07c6642548344158a1c7faed6",
"reference": "09c0f0f805f7dce07c6642548344158a1c7faed6",
"shasum": ""
},
"require": {
"jms/metadata": "^1.5",
"php": "^5.5|^7.0",
"symfony/asset": "^2.3|^3.0",
"symfony/dependency-injection": "^2.3|^3.0",
"symfony/finder": "^2.2|^3.0",
"symfony/framework-bundle": "^2.3|^3.0",
"symfony/property-access": "^2.5|^3.0",
"symfony/security": "^2.3|^3.0",
"symfony/templating": "^2.3|^3.0"
},
"require-dev": {
"doctrine/doctrine-bundle": "^1.6",
"doctrine/mongodb-odm": "^1.0",
"doctrine/orm": "^2.2.3",
"ext-sqlite3": "*",
"knplabs/knp-gaufrette-bundle": "^0.3",
"matthiasnoback/symfony-dependency-injection-test": "^0.7",
"mikey179/vfsstream": "^1.2",
"oneup/flysystem-bundle": "^1.0",
"phpunit/phpunit": "^5.6",
"symfony/browser-kit": "^2.3|^3.0",
"symfony/css-selector": "^2.3|^3.0",
"symfony/dom-crawler": "^2.3|^3.0",
"symfony/form": "^2.3|^3.0",
"symfony/twig-bridge": "^2.3.10|^3.0",
"symfony/twig-bundle": "^2.3|^3.0",
"symfony/validator": "^2.3|^3.0",
"symfony/yaml": "^2.0.5|^3.0"
},
"suggest": {
"doctrine/doctrine-bundle": "~1.6",
"doctrine/mongodb-odm-bundle": "*",
"doctrine/orm": "^2.2.3",
"doctrine/phpcr-odm": "~1.0",
"knplabs/knp-gaufrette-bundle": "~0.3",
"ocramius/proxy-manager": "To have the Gaufrette with Doctrine adapter",
"symfony/yaml": "^2.0.5",
"willdurand/propel-eventdispatcher-bundle": "~1.2"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
},
"autoload": {
"psr-4": {
"Vich\\UploaderBundle\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Dustin Dobervich",
"email": "ddobervich@gmail.com"
}
],
"description": "Ease file uploads attached to entities",
"homepage": "https://github.com/dustin10/VichUploaderBundle",
"keywords": [
"file uploads",
"upload"
],
"time": "2017-07-11 09:11:07"
},
{
"name": "willdurand/geocoder",
"version": "v3.3.2",
......
<?php
namespace Biopen\GeoDirectoryBundle\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
class ImportAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('sourceName', 'text', array('required' => false, 'label' => 'Nom de la source'))
->add('fileToImport', 'file', array('label' => 'Fichier à importer'))
->add('geocodeIfNecessary', null, array('required' => false, 'label' => 'Géocoder si élements sans latitude ni longitude'))
->add('createMissingOptions', null, array('required' => false, 'label' => 'Créer les options manquantes'))
->add('parentCategoryToCreateOptions', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Category',
'required' => false,
'choices_as_values' => true,
'label' => 'Catégorie parente pour créer les options manquantes',
'mapped' => true), array('admin_code' => 'admin.category'))
;
}
protected function configureRoutes(RouteCollection $collection)
{
$collection->add('execute', $this->getRouterIdParameter().'/execute');
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('id')
;
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('fileName')
//->add('link', 'string', array('template' => 'KPhoenSingleUploadableBundle:Image:list_link.html.twig'))
->add('_action', 'actions', array(
'actions' => array(
'edit' => array(),
)
))
;
}
}
\ No newline at end of file
<?php
namespace Biopen\GeoDirectoryBundle\Controller\Admin;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Biopen\GeoDirectoryBundle\Document\ElementStatus;
class ImportAdminController extends Controller
{
public function listAction()
{
return $this->redirect($this->admin->generateUrl('create'));
}
protected function configureRoutes(RouteCollection $collection)
{
$collection->remove('edit');
}
private function executeImport($import)
{
$result = $this->get('biopen.import_csv')->import($import);
$this->addFlash(
'sonata_flash_success', 'Les ' . $result .' éléments ont été importés avec succès '
);
}
// This method is just an overwrite of the SonataAdminCRUDController for calling the executeImport once the document is created
public function createAction()
{
$request = $this->getRequest();
// the key used to lookup the template
$templateKey = 'edit';
$this->admin->checkAccess('create');
$class = new \ReflectionClass($this->admin->hasActiveSubClass() ? $this->admin->getActiveSubClass() : $this->admin->getClass());
if ($class->isAbstract()) {
return $this->render(
'SonataAdminBundle:CRUD:select_subclass.html.twig',
array(
'base_template' => $this->getBaseTemplate(),
'admin' => $this->admin,
'action' => 'create',
),
null,
$request
);
}
$object = $this->admin->getNewInstance();
$preResponse = $this->preCreate($request, $object);
if ($preResponse !== null) {
return $preResponse;
}
$this->admin->setSubject($object);
/** @var $form \Symfony\Component\Form\Form */
$form = $this->admin->getForm();
$form->setData($object);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$isFormValid = $form->isValid();
// persist if the form was valid and if in preview mode the preview was approved
if ($isFormValid) {
$this->admin->checkAccess('create', $object);
try {
$object = $this->admin->create($object);
$this->executeImport($object);
// redirect to create mode
return $this->redirect($this->admin->generateUrl('create'));
} catch (ModelManagerException $e) {
$this->handleModelManagerException($e);
$isFormValid = false;
}
}
// show an error message if the form failed validation
if (!$isFormValid) {
if (!$this->isXmlHttpRequest()) {
$this->addFlash(
'sonata_flash_error',
$this->trans(
'flash_create_error',
array('%name%' => $this->escapeHtml($this->admin->toString($object))),
'SonataAdminBundle'
)
);
}
}
}
$view = $form->createView();
// set the theme for the current Admin Form
$this->get('twig')->getExtension('form')->renderer->setTheme($view, $this->admin->getFormTheme());
return $this->render('BiopenGeoDirectoryBundle:admin:edit_import.html.twig', array(
'action' => 'create',
'form' => $view,
'object' => $object,
), null);
}
}
\ No newline at end of file
......@@ -7,7 +7,7 @@
*
* @copyright Copyright (c) 2016 Sebastian Castro - 90scastro@gmail.com
* @license MIT License
* @Last Modified time: 2018-02-12 13:32:04
* @Last Modified time: 2018-05-30 20:31:32
*/
......@@ -43,8 +43,10 @@ class ImportController extends Controller
public function availableOptionsAction()
{
$options = $this->get('biopen.import_csv')->getAvailableOptions();
$options = $this->get('doctrine_mongodb')->getManager()->getRepository('BiopenGeoDirectoryBundle:Option')->findAll();
$bottomOptions = array_filter($options, function($option) { return $option->getSubcategoriesCount() == 0;});
$optionsNames = array_map(function($option) { return $option->getNameWithParent(); }, $bottomOptions);
return new Response(join('<br>', $options));
return new Response(join('<br>', $optionsNames));
}
}
......@@ -7,7 +7,7 @@
*
* @copyright Copyright (c) 2016 Sebastian Castro - 90scastro@gmail.com
* @license MIT License
* @Last Modified time: 2018-05-09 10:34:21
* @Last Modified time: 2018-05-30 21:12:11
*/
namespace Biopen\GeoDirectoryBundle\Document;
......@@ -368,9 +368,9 @@ class Element
if (!$this->isPending()) $needed = false;
break;
case ModerationState::NoOptionProvided:
if ( $this->getOptionValues() == null ||
is_array($this->getOptionValues()) && count($this->getOptionValues()) > 0 ||
!is_array($this->getOptionValues()) && $this->getOptionValues()->count() > 0
if ( $this->getOptionValues() != null && (
(is_array($this->getOptionValues()) && count($this->getOptionValues()) > 0) ||
(!is_array($this->getOptionValues()) && $this->getOptionValues()->count() > 0) )
)
$needed = false;
break;
......
<?php
namespace Biopen\GeoDirectoryBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* @MongoDB\Document
* @Vich\Uploadable
*/
class Import
{
/**
* @var int
* @MongoDB\Id(strategy="INCREMENT")
*/
private $id;
/**
* @var string
* @MongoDB\Field(type="string")
*/
private $sourceName = "";
/**
* @MongoDB\ReferenceOne(targetDocument="Biopen\GeoDirectoryBundle\Document\Category", inversedBy="options")
*/
private $parentCategoryToCreateOptions;
/**
* @MongoDB\EmbedOne(targetDocument="Biopen\GeoDirectoryBundle\Document\Option")
*/
private $optionTemplate;
/**
* @MongoDB\Field(type="bool")
*/
private $createMissingOptions;
/**
* @MongoDB\Field(type="bool")
*/
private $geocodeIfNecessary;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="import_file", fileNameProperty="fileName", size="fileSize")
*
* @var File
*/
private $fileToImport;
/**
* @var string
* @MongoDB\Field(type="string")
*/
public $fileName = "";
/**
* @var string
* @MongoDB\Field(type="int")
*/
public $fileSize = "";
/**
* @MongoDB\Field(type="date")
*
* @var \DateTime
*/
private $updatedAt;
public function __construct()
{
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|UploadedFile $image
*/
public function setFileToImport($file = null)
{
$this->fileToImport = $file;
if (null !== $file) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getFileToImport()
{
return $this->fileToImport;
}
/**
* Get id
*
* @return int_id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set sourceName
*
* @param string $sourceName
* @return $this
*/
public function setSourceName($sourceName)
{
$this->sourceName = $sourceName;
return $this;
}
/**
* Get sourceName
*
* @return string $sourceName
*/
public function getSourceName()
{
return $this->sourceName;
}
/**
* Set updatedAt
*
* @param date $updatedAt
* @return $this
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* @return date $updatedAt
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set fileName
*
* @param string $fileName
* @return $this
*/
public function setFileName($fileName)
{
$this->fileName = $fileName;
return $this;
}
/**
* Get fileName
*
* @return string $fileName
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Set fileSize
*
* @param int $fileSize
* @return $this
*/
public function setFileSize($fileSize)
{
$this->fileSize = $fileSize;
return $this;
}
/**
* Get fileSize
*
* @return int $fileSize
*/
public function getFileSize()
{
return $this->fileSize;
}
/**
* Set parentCategoryToCreateOptions
*
* @param Biopen\GeoDirectoryBundle\Document\Category $parentCategoryToCreateOptions
* @return $this
*/
public function setParentCategoryToCreateOptions(\Biopen\GeoDirectoryBundle\Document\Category $parentCategoryToCreateOptions)
{
$this->parentCategoryToCreateOptions = $parentCategoryToCreateOptions;
return $this;
}
/**
* Get parentCategoryToCreateOptions
*
* @return Biopen\GeoDirectoryBundle\Document\Category $parentCategoryToCreateOptions
*/
public function getParentCategoryToCreateOptions()
{
return $this->parentCategoryToCreateOptions;
}
/**
* Set optionTemplate
*
* @param Biopen\GeoDirectoryBundle\Document\Option $optionTemplate
* @return $this
*/
public function setOptionTemplate(\Biopen\GeoDirectoryBundle\Document\Option $optionTemplate)
{