Commit 296f00e3 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Commit initial.

parent cd31a8e7
<?php
namespace UnicaenFaq;
use UnicaenApp\Exception\RuntimeException;
use UnicaenFaq\Service\FaqService;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$application = $e->getApplication();
$application->getServiceManager()->get('translator');
$eventManager = $application->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$this->checkModuleRequirements($e);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return [
'Zend\Loader\StandardAutoloader' => [
'namespaces' => [
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
],
],
];
}
public function checkModuleRequirements(MvcEvent $event)
{
$sl = $event->getApplication()->getServiceManager();
/** @var FaqService $service */
$service = $sl->get('UnicaenFaq\Service\FaqService');
try {
$service->checkSchema();
}
catch (\Exception $e) {
$config = $sl->get('config');
$pathsArray = glob($config['unicaen-faq']['db_schema_glob_paths']);
throw new RuntimeException(sprintf(
"Vous avez activé le module UnicaenFaq mais le schéma de base de données est incorrect: %s. " .
"Reportez-vous aux scripts suivants : %s.",
$e->getMessage(),
implode(', ', array_map('realpath', $pathsArray))
));
}
}
}
<?php
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\ORM\Mapping\Driver\XmlDriver;
use UnicaenFaq\Controller\Factory\FaqControllerFactory;
use UnicaenFaq\Form\Factory\FaqFormFactory;
use UnicaenFaq\Provider\Privilege\FaqPrivileges;
use UnicaenFaq\Service\FaqServiceFactory;
return array(
'unicaen-faq' => [
/*
* Masque des chemins vers les scripts SQL de création du schéma de base de données sur lequel repose ce module.
*/
'db_schema_glob_paths' => __DIR__ . '/../data/*.sql',
],
'doctrine' => [
'driver' => [
'orm_default' => [
'class' => MappingDriverChain::class,
'drivers' => [
'UnicaenFaq\Entity\Db' => 'orm_default_xml_driver',
],
],
'orm_default_xml_driver' => [
'class' => XmlDriver::class,
'cache' => 'array',
'paths' => [
__DIR__ . '/../src/UnicaenFaq/Entity/Db/Mapping',
],
],
],
],
'bjyauthorize' => [
'resource_providers' => [
'BjyAuthorize\Provider\Resource\Config' => [
'Faq' => [],
],
],
'guards' => [
'\UnicaenAuth\Guard\PrivilegeController' => [
[
'controller' => 'UnicaenFaq\Controller\Index',
'action' => [
'index',
],
'roles' => ['guest'], // pas d'authentification requise
],
[
'controller' => 'UnicaenFaq\Controller\Index',
'action' => [
'ajouter',
'modifier',
'supprimer',
],
'privileges' => [FaqPrivileges::FAQ_MODIFICATION]
],
],
],
],
'router' => [
'routes' => [
'faq' => [
'type' => 'Literal',
'options' => [
'route' => '/faq',
'defaults' => [
'controller' => 'UnicaenFaq\Controller\Index',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'ajouter' => [
'type' => 'Segment',
'options' => [
'route' => '/ajouter',
'defaults' => [
'action' => 'ajouter',
],
],
],
'modifier' => [
'type' => 'Segment',
'options' => [
'route' => '/:faq/modifier',
'constraints' => [
'faq' => '\d+',
],
'defaults' => [
'action' => 'modifier',
],
],
],
'supprimer' => [
'type' => 'Segment',
'options' => [
'route' => '/:faq/supprimer',
'constraints' => [
'faq' => '\d+',
],
'defaults' => [
'action' => 'supprimer',
],
],
],
],
],
],
],
'navigation' => [
'default' => [
'home' => [
'pages' => [
'faq' => [
'label' => 'FAQ',
'route' => 'faq',
],
],
],
],
],
'service_manager' => [
'factories' => [
'UnicaenFaq\Service\FaqService' => FaqServiceFactory::class,
],
],
'controllers' => [
'factories' => [
'UnicaenFaq\Controller\Index' => FaqControllerFactory::class,
],
],
'form_elements' => [
'factories' => [
'UnicaenFaq\Form\FaqForm' => FaqFormFactory::class,
],
],
'view_manager' => [
'template_map' => [
'unicaen-faq/index' => __DIR__ . '/../view/unicaen-faq/index.phtml',
'unicaen-faq/modifier' => __DIR__ . '/../view/unicaen-faq/modifier.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
],
'public_files' => [
'inline_scripts' => [
'902_' => '//gest.unicaen.fr/public/tinymce-4.4.1/js/tinymce/tinymce.min.js',
],
'stylesheets' => [
// '112_' => 'https://gest.unicaen.fr/public/font-awesome-4.5.0/css/font-awesome.min.css',
// '113_' => 'https://gest.unicaen.fr/public/open-sans-gh-pages/open-sans.css',
// '120_' => 'css/callout.css',
// '121_' => 'https://gest.unicaen.fr/public/DataTables-1.10.12/media/css/dataTables.bootstrap.min.css',
],
],
);
\ No newline at end of file
<?php
use UnicaenFaq\Entity\Db\Faq;
return array(
'unicaen-faq' => [
/*
* Nom du gestionnaire d'entité concerné.
* Par défaut: 'orm_default'.
*/
'entity_manager_name' => 'orm_default',
/*
* Classe de l'entité représentant un couple question-réponse.
* Par défaut: 'UnicaenFaq\Entity\Db\Faq'.
*/
'faq_entity_class' => Faq::class,
],
/*
* Customisation de la navigation.
* Ex: masquer le menu, modifier sa position, changer son label, associer une ressource ACL.
*/
// 'navigation' => [
// 'default' => [
// 'home' => [
// 'pages' => [
// 'faq' => [
// 'visible' => true,
// 'order' => -1000,
// 'label' => 'FAQ',
// 'resource' => PrivilegeController::getResourceId('UnicaenFaq\Controller\Index', 'index'),
// ],
// ],
// ],
// ],
// ],
);
\ No newline at end of file
--
-- Table FAQ.
--
CREATE TABLE FAQ (
ID NUMBER(38, 0),
QUESTION VARCHAR2(2000 CHAR) NOT NULL,
REPONSE VARCHAR2(2000 CHAR) NOT NULL,
ORDRE NUMBER(38, 0),
CONSTRAINT FAQ_PK PRIMARY KEY (ID)
);
CREATE SEQUENCE FAQ_ID_SEQ;
--
-- Jeu d'essai.
--
INSERT INTO FAQ(ID, QUESTION, REPONSE, ORDRE) VALUES
(FAQ_ID_SEQ.nextval, 'Qu''est-ce qu''une question ?', 'C''est une phrase appelant une réponse.', 10);
--
-- Création si besoin de la catégorie de privilège 'faq'.
--
insert into CATEGORIE_PRIVILEGE(ID, CODE, LIBELLE, ORDRE) values
(CATEGORIE_PRIVILEGE_ID_SEQ.nextval, 'faq', 'FAQ', 10);
--
-- Privilège 'modification'.
--
insert into PRIVILEGE(ID, CATEGORIE_ID, CODE, LIBELLE, ORDRE)
select privilege_id_seq.nextval, cp.id, 'modification', 'Modification de la FAQ', 10
from CATEGORIE_PRIVILEGE cp where cp.CODE = 'faq';
<?php
namespace UnicaenFaq\Controller\Factory;
use UnicaenFaq\Controller\FaqController;
use UnicaenFaq\Form\FaqForm;
use UnicaenFaq\Service\FaqService;
use Zend\Mvc\Controller\ControllerManager;
use Zend\ServiceManager\ServiceLocatorInterface;
class FaqControllerFactory
{
/**
* Create service
*
* @param ControllerManager $controllerManager
* @return FaqController
*/
public function __invoke(ControllerManager $controllerManager)
{
$faqService = $this->getFaqService($controllerManager->getServiceLocator());
/** @var FaqForm $form */
$form = $controllerManager->getServiceLocator()->get('FormElementManager')->get('UnicaenFaq\Form\FaqForm');
$controller = new FaqController($form);
$controller->setFaqService($faqService);
return $controller;
}
private function getFaqService(ServiceLocatorInterface $serviceLocator)
{
/** @var FaqService $service */
$service = $serviceLocator->get('UnicaenFaq\Service\FaqService');
return $service;
}
}
\ No newline at end of file
<?php
namespace UnicaenFaq\Controller;
use Doctrine\ORM\Tools\Pagination\Paginator;
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator;
use UnicaenFaq\Entity\Db\Faq;
use UnicaenFaq\Form\FaqForm;
use UnicaenFaq\Service\FaqServiceAwareInterface;
use UnicaenFaq\Service\FaqServiceAwareTrait;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class FaqController extends AbstractActionController implements FaqServiceAwareInterface
{
use FaqServiceAwareTrait;
/**
* @var FaqForm
*/
protected $faqForm;
/**
* FaqController constructor.
*
* @param FaqForm $faqForm
*/
public function __construct(FaqForm $faqForm)
{
$this->faqForm = $faqForm;
}
public function indexAction()
{
$qb = $this->faqService->getRepository()->createQueryBuilder('f');
$qb->addOrderBy('f.ordre');
$paginator = new \Zend\Paginator\Paginator(new DoctrinePaginator(new Paginator($qb, true)));
$paginator->setItemCountPerPage(-1);
$viewModel = new ViewModel([
'faqs' => $paginator,
]);
$viewModel->setTemplate('unicaen-faq/index');
return $viewModel;
}
public function modifierAction()
{
$faq = $this->requestedFaq();
$this->faqForm->bind($faq);
if ($data = $this->params()->fromPost()) {
$this->faqForm->setData($data);
if ($this->faqForm->isValid()) {
/** @var Faq $faq */
$faq = $this->faqForm->getData();
$this->faqService->update($faq);
$this->flashMessenger()->addSuccessMessage("Question-réponse modifiée avec succès");
return $this->redirect()->toRoute('faq', [], ['query' => ['selected' => $faq->getId()]], true);
}
}
$this->faqForm->setAttribute('action', $this->url()->fromRoute('faq/modifier', [], [], true));
$viewModel = new ViewModel([
'form' => $this->faqForm,
]);
$viewModel->setTemplate('unicaen-faq/modifier');
return $viewModel;
}
public function ajouterAction()
{
if ($data = $this->params()->fromPost()) {
$this->faqForm->setData($data);
if ($this->faqForm->isValid()) {
/** @var Faq $faq */
$faq = $this->faqForm->getData();
$this->faqService->create($faq);
$this->flashMessenger()->addSuccessMessage("Question-réponse ajoutée avec succès");
return $this->redirect()->toRoute('faq', [], ['query' => ['selected' => $faq->getId()]], true);
}
}
$this->faqForm->setAttribute('action', $this->url()->fromRoute('faq/ajouter'));
$viewModel = new ViewModel([
'form' => $this->faqForm,
]);
$viewModel->setTemplate('unicaen-faq/modifier');
return $viewModel;
}
public function supprimerAction()
{
$faq = $this->requestedFaq();
$this->faqService->delete($faq);
$this->flashMessenger()->addSuccessMessage("Question-réponse supprimée avec succès");
return $this->redirect()->toRoute('faq', [], [], true);
}
/**
* @return Faq
*/
protected function requestedFaq()
{
$id = $this->params()->fromRoute('faq');
if (!$id) {
return null;
}
/** @var Faq $faq */
$faq = $this->faqService->getRepository()->find($id);
return $faq;
}
}
\ No newline at end of file
<?php
namespace UnicaenFaq\Entity\Db;
use Zend\Permissions\Acl\Resource\ResourceInterface;
/**
* Entité représentant un couple question-réponse.
*/
class Faq implements ResourceInterface
{
const RESOURCE_ID = 'Faq';
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $question;
/**
* @var string
*/
private $reponse;
/**
* @var integer
*/
private $ordre;
/**
* Set contenu
*
* @param string $question
* @return self
*/
public function setQuestion($question)
{
$this->question = $question;
return $this;
}
/**
* Get contenu
*
* @return string
*/
public function getQuestion()
{
return $this->question;
}
/**
* Set nom
*
* @param string $reponse
* @return self
*/
public function setReponse($reponse)
{
$this->reponse = $reponse;
return $this;
}
/**
* Get nom
*
* @return string
*/
public function getReponse()
{
return $this->reponse;
}
/**
* @param string $id
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @return int
*/
public function getOrdre()
{
return $this->ordre;
}
/**
* @param int $ordre
* @return Faq
*/
public function setOrdre($ordre)
{
$this->ordre = (int) $ordre;
return $this;
}
/**
* Returns the string identifier of the Resource
*
* @return string
*/
public function getResourceId()
{
return self::RESOURCE_ID;
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="UnicaenFaq\Entity\Db\Faq" table="FAQ">
<id name="id" type="integer" column="ID">
<generator strategy="SEQUENCE"/>
</id>
<field name="question" type="string" column="QUESTION" nullable="false"/>
<field name="reponse" type="string" column="REPONSE" nullable="false"/>
<field name="ordre" type="integer" column="ORDRE" nullable="true"/>
</entity>
</doctrine-mapping>
\ No newline at end of file