Commit 20d30630 by Mathieu Poisbeau

#255: add abilities to sync Prestataires from Kohinos Admin to Wordpress

(one, several or all)
parent 5b7584bb
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "d4a364a00fe16a9ef06a06f73973f4f4", "content-hash": "215d9dc36bb4f8c0921209bb611d636c",
"packages": [ "packages": [
{ {
"name": "api-platform/api-pack", "name": "api-platform/api-pack",
...@@ -1967,6 +1967,7 @@ ...@@ -1967,6 +1967,7 @@
"reflection", "reflection",
"static" "static"
], ],
"abandoned": "roave/better-reflection",
"time": "2020-03-27T11:06:43+00:00" "time": "2020-03-27T11:06:43+00:00"
}, },
{ {
...@@ -2423,6 +2424,7 @@ ...@@ -2423,6 +2424,7 @@
"faker", "faker",
"fixtures" "fixtures"
], ],
"abandoned": true,
"time": "2019-12-12T13:22:17+00:00" "time": "2019-12-12T13:22:17+00:00"
}, },
{ {
...@@ -10018,6 +10020,83 @@ ...@@ -10018,6 +10020,83 @@
"time": "2020-06-12T08:10:13+00:00" "time": "2020-06-12T08:10:13+00:00"
}, },
{ {
"name": "symfony/http-client",
"version": "v4.4.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "3ead7e297f4cc8a84661ef1f411c029acb34bc11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/3ead7e297f4cc8a84661ef1f411c029acb34bc11",
"reference": "3ead7e297f4cc8a84661ef1f411c029acb34bc11",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"psr/log": "^1.0",
"symfony/http-client-contracts": "^1.1.10|^2",
"symfony/polyfill-php73": "^1.11",
"symfony/service-contracts": "^1.0|^2"
},
"provide": {
"php-http/async-client-implementation": "*",
"php-http/client-implementation": "*",
"psr/http-client-implementation": "1.0",
"symfony/http-client-implementation": "1.1"
},
"require-dev": {
"guzzlehttp/promises": "^1.3.1",
"nyholm/psr7": "^1.0",
"php-http/httplug": "^1.0|^2.0",
"psr/http-client": "^1.0",
"symfony/dependency-injection": "^4.3|^5.0",
"symfony/http-kernel": "^4.4.13",
"symfony/process": "^4.2|^5.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpClient\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpClient component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-24T11:50:19+00:00"
},
{
"name": "symfony/http-client-contracts", "name": "symfony/http-client-contracts",
"version": "v2.3.1", "version": "v2.3.1",
"source": { "source": {
......
...@@ -93,7 +93,7 @@ services: ...@@ -93,7 +93,7 @@ services:
app.twig.main.extension: app.twig.main.extension:
class: App\Twig\AppExtension class: App\Twig\AppExtension
autowire: false autowire: false
arguments: ["@service_container", "@security.helper", "@doctrine.orm.entity_manager", "@knp_paginator", "@session"] arguments: ["@service_container", "@security.helper", "@doctrine.orm.entity_manager", "@knp_paginator", "@session", "@app.util.wordpress"]
app.twig.mlc.globals.extension: app.twig.mlc.globals.extension:
class: App\Twig\MlcGlobalsExtension class: App\Twig\MlcGlobalsExtension
...@@ -173,6 +173,9 @@ services: ...@@ -173,6 +173,9 @@ services:
tags: tags:
- { name: payum.gateway_factory_builder, factory: payzen } - { name: payum.gateway_factory_builder, factory: payzen }
app.util.wordpress:
class: App\Util\WordpressUtil
###### Configuration de l'admin ###### ###### Configuration de l'admin ######
admin.block.dashboard: admin.block.dashboard:
...@@ -238,7 +241,10 @@ services: ...@@ -238,7 +241,10 @@ services:
admin.prestataire.gerer: admin.prestataire.gerer:
class: App\Admin\PrestataireAdmin class: App\Admin\PrestataireAdmin
arguments: [~, App\Entity\Prestataire, ~] arguments:
- ~
- App\Entity\Prestataire
- App\Controller\CRUD\PrestataireCRUDController
tags: tags:
- name: sonata.admin - name: sonata.admin
manager_type: orm manager_type: orm
...@@ -250,6 +256,7 @@ services: ...@@ -250,6 +256,7 @@ services:
- [ addChild, ['@sonata.user.admin.user', 'user']] - [ addChild, ['@sonata.user.admin.user', 'user']]
- [ setSecurity, ['@security.helper']] - [ setSecurity, ['@security.helper']]
- [ setPool, ['@sonata.media.pool']] - [ setPool, ['@sonata.media.pool']]
- [ setWordpressUtil, ['@app.util.wordpress']]
admin.prestataire.cotisations: admin.prestataire.cotisations:
class: App\Admin\CotisationPrestataireAdmin class: App\Admin\CotisationPrestataireAdmin
......
...@@ -21,6 +21,7 @@ use App\Form\Type\CotisationFormType; ...@@ -21,6 +21,7 @@ use App\Form\Type\CotisationFormType;
use App\Form\Type\GeolocPrestataireFormType; use App\Form\Type\GeolocPrestataireFormType;
use App\Form\Type\UserFormType; use App\Form\Type\UserFormType;
use App\Form\Type\UserInfosFormType; use App\Form\Type\UserInfosFormType;
use App\Util\WordpressUtil;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use FOS\CKEditorBundle\Form\Type\CKEditorType; use FOS\CKEditorBundle\Form\Type\CKEditorType;
use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Model\UserManagerInterface;
...@@ -65,6 +66,7 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -65,6 +66,7 @@ class PrestataireAdmin extends AbstractAdmin
protected $baseRoutePattern = 'prestataire'; protected $baseRoutePattern = 'prestataire';
protected $security; protected $security;
protected $pool; protected $pool;
protected $wp;
protected $datagridValues = [ protected $datagridValues = [
// reverse order (default = 'ASC') // reverse order (default = 'ASC')
'_sort_order' => 'DESC', '_sort_order' => 'DESC',
...@@ -84,6 +86,11 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -84,6 +86,11 @@ class PrestataireAdmin extends AbstractAdmin
$this->pool = $pool; $this->pool = $pool;
} }
public function setWordpressUtil(WordpressUtil $wp)
{
$this->wp = $wp;
}
public function configure() public function configure()
{ {
parent::configure(); parent::configure();
...@@ -430,25 +437,15 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -430,25 +437,15 @@ class PrestataireAdmin extends AbstractAdmin
{ {
unset($this->listModes['mosaic']); unset($this->listModes['mosaic']);
$user = $this->security->getUser(); $user = $this->security->getUser();
$isWordpressActivated = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(GlobalParameter::class)->val(GlobalParameter::USE_WORDPRESS);
if ($isWordpressActivated == 'false') { $actions = ['edit' => ['link_parameters' => ['full' => true]]];
$actions = [
'show' => ['template' => '@SonataAdmin/CRUD/list__action_showonfront.html.twig'], if (false === $this->wp->isUsed()) {
'edit' => [ $actions['show'] = ['template' => '@SonataAdmin/CRUD/list__action_showonfront.html.twig'];
// You may add custom link parameters used to generate the action url } elseif ($this->wp->canSync()) {
'link_parameters' => [ $actions['sync-wp'] = [];
'full' => true,
]
]];
} else {
$actions = [
'edit' => [
// You may add custom link parameters used to generate the action url
'link_parameters' => [
'full' => true,
]
]];
} }
$listMapper $listMapper
->addIdentifier('raison') ->addIdentifier('raison')
->add('groupe', null, array( ->add('groupe', null, array(
...@@ -485,6 +482,22 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -485,6 +482,22 @@ class PrestataireAdmin extends AbstractAdmin
protected function configureRoutes(RouteCollection $collection) protected function configureRoutes(RouteCollection $collection)
{ {
$collection->remove('delete'); $collection->remove('delete');
if ($this->wp->canSync()) {
$collection->add('sync-wp', $this->getRouterIdParameter().'/sync-wp');
$collection->add('sync-all-wp');
}
}
public function configureActionButtons($action, $object = null)
{
$list = parent::configureActionButtons($action, $object);
if ($this->wp->canSync()) {
$list['sync-all-wp']['template'] = '@SonataAdmin/CRUD/sync-all-wp_button.html.twig';
}
return $list;
} }
public function getObjectMetadata($object) public function getObjectMetadata($object)
...@@ -502,11 +515,18 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -502,11 +515,18 @@ class PrestataireAdmin extends AbstractAdmin
return new Metadata($object->getRaison(), strip_tags($object->getDescription())); return new Metadata($object->getRaison(), strip_tags($object->getDescription()));
} }
public function getBatchActions() public function configureBatchActions($actions)
{ {
$actions = parent::getBatchActions();
unset($actions['delete']); unset($actions['delete']);
if ($this->wp->canSync()) {
$actions['sync-wp'] = [
'ask_confirmation' => true,
'label' => 'batch_sync-wp',
'translation_domain' => 'SonataAdminBundle',
];
}
return $actions; return $actions;
} }
...@@ -523,4 +543,20 @@ class PrestataireAdmin extends AbstractAdmin ...@@ -523,4 +543,20 @@ class PrestataireAdmin extends AbstractAdmin
'Tags' => 'etatsString' 'Tags' => 'etatsString'
]; ];
} }
/**
* Synchronize with Wordpress here (rather than through Doctrine ORM events).
*/
public function postPersist($presta)
{
if ($this->wp->runSync($presta->getId())) {
$this->getRequest()->getSession()->getFlashBag()->add(
'sonata_flash_success', 'Synchronisation vers Wordpress effectuée<br>'
);
}
}
public function postUpdate($presta)
{
$this->postPersist($presta);
}
} }
<?php
namespace App\Controller\CRUD;
use App\Util\WordpressUtil;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
class PrestataireCRUDController extends CRUDController
{
protected $wp;
public function __construct(WordpressUtil $wp)
{
$this->wp = $wp;
}
/**
* @param array|int|null If $id is null, sync all the Prestataires
*/
protected function syncToWordpress($id)
{
if ($this->wp->runSync($id)) {
$this->addFlash('sonata_flash_success', 'Synchronisation vers Wordpress effectuée');
}
return new RedirectResponse(
$this->admin->generateUrl('list', ['filter' => $this->admin->getFilterParameters()])
);
}
public function syncAllWpAction()
{
return $this->syncToWordpress(null);
}
public function syncWpAction($id)
{
if (!$this->admin->hasSubject()) {
throw new NotFoundHttpException(sprintf('Unable to find the Prestataire with id: %s', $id));
}
return $this->syncToWordpress($id);
}
public function batchActionSyncWp(ProxyQueryInterface $query)
{
$ids = [];
$selected = $query->execute();
foreach ($selected as $e) {
$ids[] = $e->getId();
}
return $this->syncToWordpress($ids);
}
}
...@@ -12,6 +12,7 @@ use App\Entity\Rubrique; ...@@ -12,6 +12,7 @@ use App\Entity\Rubrique;
use App\Entity\Siege; use App\Entity\Siege;
use App\Entity\User; use App\Entity\User;
use App\Entity\GlobalParameter; use App\Entity\GlobalParameter;
use App\Util\WordpressUtil;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface; use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
...@@ -31,14 +32,16 @@ class AppExtension extends AbstractExtension ...@@ -31,14 +32,16 @@ class AppExtension extends AbstractExtension
public $container; public $container;
public $paginator; public $paginator;
public $session; public $session;
public $wp;
public function __construct(ContainerInterface $container, Security $security, EntityManagerInterface $em, PaginatorInterface $paginator, SessionInterface $session) public function __construct(ContainerInterface $container, Security $security, EntityManagerInterface $em, PaginatorInterface $paginator, SessionInterface $session, WordpressUtil $wp)
{ {
$this->em = $em; $this->em = $em;
$this->security = $security; $this->security = $security;
$this->container = $container; $this->container = $container;
$this->paginator = $paginator; $this->paginator = $paginator;
$this->session = $session; $this->session = $session;
$this->wp = $wp;
} }
public function getFunctions() public function getFunctions()
...@@ -87,12 +90,7 @@ class AppExtension extends AbstractExtension ...@@ -87,12 +90,7 @@ class AppExtension extends AbstractExtension
public function getWordpressApiKey() public function getWordpressApiKey()
{ {
$users = $this->em->getRepository(User::class)->findByRole('ROLE_API'); return $this->wp->getApiKey();
if (count($users) <= 0) {
// @TODO :erreur => crée un nouvel utilisateur API si non existant ?
return '';
}
return $users[0]->getApiKey();
} }
public function showModalGroupChoice() public function showModalGroupChoice()
......
<?php
namespace App\Util;
use App\Entity\User;
use App\Entity\GlobalParameter;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class WordpressUtil
{
protected $em;
protected $client;
protected $apiKey = null;
protected $isUsed = null;
protected $url = null;
public function __construct(EntityManagerInterface $em, HttpClientInterface $client)
{
$this->em = $em;
$this->client = $client;
}
public function getApiKey(): string
{
if (null !== $this->apiKey) {
return $this->apiKey;
}
$users = $this->em->getRepository(User::class)->findByRole('ROLE_API');
return $this->apiKey = $users[0]->getApiKey() ?? '';
}
public function getUrl(): string
{
if (null !== $this->url) {
return $this->url;
}
return $this->url = $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::WORDPRESS_URL);
}
/**
* Determine whether Wordpress is used or not.
*
* @return bool
*/
public function isUsed(): bool
{
if (null !== $this->isUsed) {
return $this->isUsed;
}
return $this->isUsed = (
'true' === $this->em->getRepository(GlobalParameter::class)
->val(GlobalParameter::USE_WORDPRESS)
? true
: false
);
}
/**
* Determine whether synchronization with Wordpress is available or not.
*
* @return bool
*/
public function canSync(): bool
{
return $this->isUsed() && $this->getUrl();
}
/**
* Run the synchronization with Wordpress, through an API call.
* Actually, only 'Prestataires' can be sync.
*
* @param array|int|null $id If null, ask for a full sync.
*
* @return bool Return false if the sync isn't run. Else true.
*/
public function runSync($id = null): bool
{
if (! $this->canSync()) {
return false;
}
$endpoint = sprintf("%s/%s/%s",
$this->getUrl(),
"wp-json/wosmpl/v1/sync_partners",
null === $id ? '' : ('?ids=' . \implode(',', (array) $id))
);
$this->client->request('GET', $endpoint, [
'headers' => [
'API-AUTH-TOKEN' => $this->getApiKey(),
],
]);
return true;
}
}
...@@ -663,6 +663,9 @@ ...@@ -663,6 +663,9 @@
"ref": "2230e9f42b10616b91a28d15ed3a2d984e0b6c10" "ref": "2230e9f42b10616b91a28d15ed3a2d984e0b6c10"
} }
}, },
"symfony/http-client": {
"version": "v4.4.16"
},
"symfony/http-client-contracts": { "symfony/http-client-contracts": {
"version": "v2.3.1" "version": "v2.3.1"
}, },
......
{% if admin.hasRoute('sync-wp') %}
{% set confirmText = 'confirm_sync-wp'|trans({}, 'SonataAdminBundle') %}
<a href="{{ admin.generateObjectUrl('sync-wp', object) }}" class="btn btn-sm btn-default sync-wp_link"
title="{{ 'action_sync-wp'|trans({}, 'SonataAdminBundle') }}"
onclick="return confirm('{{- confirmText -}}')"
>
<i class="fa fa-refresh" aria-hidden="true"></i>
{{ 'action_sync-wp'|trans({}, 'SonataAdminBundle') }}
</a>
{% endif %}
{% if admin.hasRoute('sync-all-wp') %}
{% set confirmPhrase = 'confirm_phrase_sync-all-wp'|trans({}, 'SonataAdminBundle') %}
{% set promptText = 'confirm_sync-all-wp'|trans({'%phrase%': confirmPhrase}, 'SonataAdminBundle') %}
<li>
<a class="sonata-action-element danger" href="{{ admin.generateUrl('sync-all-wp') }}"
onclick="return '{{-confirmPhrase-}}' == prompt('{{ promptText }}')"
>
<i class="fa fa-refresh" aria-hidden="true"></i>
{{ 'action_sync-all-wp'|trans({}, 'SonataAdminBundle') }}
</a>
</li>
{% endif %}
app.admin.group.adherent: Adherent app.admin.group.adherent: Adherent
app.admin.group.prestataire: Prestataire app.admin.group.prestataire: Prestataire
app.admin.group.groupe: Groupe app.admin.group.groupe: Groupe
###
# About Wordpress synchronisation
###
batch_sync-wp: 'Synchronisation Wordpress'
action_sync-wp: 'Sync. WP'
action_sync-all-wp: 'Tout synchroniser vers Wordpress'
# In the 3 following messages, please escape the " and ' characters.
confirm_sync-wp: 'Êtes-vous sûrs de vouloir synchroniser vers Wordpress ?'
confirm_sync-all-wp: 'Attention, vous vous apprêtez à TOUT synchroniser vers Wordpress.\nTapez \"%phrase%\" pour confirmer.'
confirm_phrase_sync-all-wp: 'Je confirme'
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