Ver código fonte

[Technique] Paramètres : nouveau système de settings

feature/souke
Guillaume Bourgeois 1 ano atrás
pai
commit
7d9da1c1ab
23 arquivos alterados com 398 adições e 44 exclusões
  1. +86
    -0
      backend/controllers/SettingAdminController.php
  2. +57
    -0
      backend/forms/AdminSettingsForm.php
  3. +1
    -0
      backend/views/layouts/left.php
  4. +78
    -0
      backend/views/setting-admin/index.php
  5. +1
    -1
      common/logic/AbstractRepository.php
  6. +1
    -0
      common/logic/Feature/Feature/Feature.php
  7. +1
    -0
      common/logic/Feature/Feature/FeatureDefinition.php
  8. +5
    -0
      common/logic/ProducerContextTrait.php
  9. +39
    -0
      common/logic/Setting/AdminSettingBag.php
  10. +6
    -3
      common/logic/Setting/Setting.php
  11. +0
    -22
      common/logic/Setting/SettingBag.php
  12. +16
    -9
      common/logic/Setting/SettingBuilder.php
  13. +12
    -0
      common/logic/Setting/SettingDetails/AbstractSettingDetail.php
  14. +32
    -0
      common/logic/Setting/SettingDetails/Admin/AdminSettingDefinition.php
  15. +1
    -0
      common/logic/Setting/SettingDetails/Admin/General/AdministratorEmailAdminSetting.php
  16. +1
    -0
      common/logic/Setting/SettingDetails/Admin/General/AdministratorPhoneNumberAdminSetting.php
  17. +1
    -0
      common/logic/Setting/SettingDetails/Admin/General/IsTestAdminSetting.php
  18. +1
    -0
      common/logic/Setting/SettingDetails/Admin/General/SupportEmailAdminSetting.php
  19. +16
    -0
      common/logic/Setting/SettingDetails/Admin/General2/AnOtherTestAdminSetting.php
  20. +2
    -8
      common/logic/Setting/SettingImporter.php
  21. +17
    -1
      common/logic/Setting/SettingModule.php
  22. +18
    -0
      common/logic/Setting/SettingRepository.php
  23. +6
    -0
      common/logic/Setting/SettingRepositoryQuery.php

+ 86
- 0
backend/controllers/SettingAdminController.php Ver arquivo

@@ -0,0 +1,86 @@
<?php

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace backend\controllers;

use backend\forms\AdminSettingsForm;
use common\helpers\Ajax;
use yii\filters\AccessControl;
use yii\helpers\Html;
use yii\web\NotFoundHttpException;

/**
* UserController implements the CRUD actions for User model.
*/
class SettingAdminController extends BackendController
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return $this->getUserModule()
->getAuthorizationChecker()
->isGrantedAsAdministrator($this->getUserCurrent());
}
]
],
],
];
}

public function actionIndex()
{
$settingModule = $this->getSettingModule();
$model = new AdminSettingsForm();
if($model->load(\Yii::$app->request->post()) && $model->validate()) {
foreach($settingModule->getAdminSettingDefinition()->getSettingDetailsFlat() as $settingDetail) {
$settingModule->getAdminSettingBag()->set($settingDetail->getName(), $model->{$settingDetail->getName()});
}
}

return $this->render('index', [
'model' => $model
]);
}
}

+ 57
- 0
backend/forms/AdminSettingsForm.php Ver arquivo

@@ -0,0 +1,57 @@
<?php

namespace backend\forms;

use common\logic\Setting\SettingModule;
use yii\base\Model;

class AdminSettingsForm extends Model
{
public function __get($name)
{
return SettingModule::getInstance()->getAdminSettingBag()->get($name);
}

public function __set($name, $value)
{
$this->$name = $value;
}

public function rules()
{
$rulesArray = [];
$typesArray = [
'string' => ['string', 'text'],
'date' => ['date'],
'boolean' => ['boolean'],
'integer' => ['integer'],
'double' => ['double', 'float'],
];
foreach($typesArray as $rule => $typesSettingArray) {
$rulesArray[] = [$this->getSettingNamesByTypeArray($typesSettingArray), $rule];
}
return $rulesArray;
}

public function attributeLabels()
{
$attributeLabelsArray = [];
foreach(SettingModule::getInstance()->getAdminSettingDefinition()->getSettingDetailsFlat() as $settingDetail) {
$attributeLabelsArray[$settingDetail->getName()] = $settingDetail->getLabel();
}
return $attributeLabelsArray;
}

public function getSettingNamesByTypeArray(array $typesSettingArray): array
{
$settingNamesTypeArray = [];
foreach(SettingModule::getInstance()->getAdminSettingDefinition()->getSettingDetailsFlat() as $settingDetail) {
if(in_array($settingDetail->getType(), $typesSettingArray)) {
$settingNamesTypeArray[] = $settingDetail->getName();
}
}
return $settingNamesTypeArray;
}
}

?>

+ 1
- 0
backend/views/layouts/left.php Ver arquivo

@@ -182,6 +182,7 @@ $isUserCurrentGrantedAsProducer = $userModule->getAuthorizationChecker()->isGran
['label' => 'Commandes clients', 'icon' => 'calendar', 'url' => ['/stats-admin/customer-orders'], 'visible' => $isUserCurrentGrantedAsAdministrator],
],
],
['label' => 'Paramètres', 'icon' => 'cog', 'url' => ['/setting-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator && $featureChecker->isEnabled(Feature::ALIAS_SETTINGS)],
['label' => 'Fonctionnalités', 'icon' => 'flag', 'url' => ['/feature-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],
['label' => 'Tranches de prix', 'icon' => 'eur', 'url' => ['/producer-price-range-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],
['label' => 'Taxes', 'icon' => 'eur', 'url' => ['/tax-rate-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],

+ 78
- 0
backend/views/setting-admin/index.php Ver arquivo

@@ -0,0 +1,78 @@
<?php

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

use common\logic\Setting\SettingModule;
use yii\bootstrap\ActiveForm;
use yii\helpers\Html;

$settingModule = SettingModule::getInstance();
$adminSettingDefinition = $settingModule->getAdminSettingDefinition();

$this->setTitle('Paramètres');
$this->addBreadcrumb($this->getTitle());

?>

<div class="setting-admin-index">
<?php $form = ActiveForm::begin(); ?>
<?php foreach($adminSettingDefinition->getSettingDetails() as $sectionName => $sectionsArray): ?>
<h2><?php echo $adminSettingDefinition->getSectionLabelBySectionName($sectionName); ?></h2>
<?php foreach($sectionsArray as $subSectionName => $subSectionsArray): ?>
<h2><?php echo $adminSettingDefinition->getSectionLabelBySectionName($subSectionName); ?></h2>
<?php foreach($subSectionsArray as $settingDetail): ?>
<?php echo field($form, $model, $settingDetail); ?>
<?php endforeach; ?>
<?php endforeach; ?>
<?php endforeach; ?>
<div class="form-group">
<?= Html::submitButton('Sauvegarder', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

<?php

function field($form, $model, $settingDetail) {
if($settingDetail->getType() == 'boolean') {
return $form->field($model, $settingDetail->getName())->checkbox();
} else {
return $form->field($model, $settingDetail->getName())->textInput();
}
}

?>

+ 1
- 1
common/logic/AbstractRepository.php Ver arquivo

@@ -69,7 +69,7 @@ abstract class AbstractRepository extends AbstractService implements RepositoryI
$defaultOptions = $this->getDefaultOptionsSearch();
if(isset($defaultOptions['attribute_id_producer'])
&& $defaultOptions['attribute_id_producer']
&& $this->getProducerContext(false)) {
&& $this->getProducerContext()) {
$this->query->andWhere([$defaultOptions['attribute_id_producer'] => $this->getProducerContextId()]);
}
}

+ 1
- 0
common/logic/Feature/Feature/Feature.php Ver arquivo

@@ -48,6 +48,7 @@ class Feature extends ActiveRecordCommon
const ALIAS_PRODUCT_PRICE_IMPORT = 'product_price_import';
const ALIAS_ONLINE_PAYMENT = 'online_payment';
const ALIAS_EXPORT_SHOPPING_CART_LABELS_ADVANCED = 'export_shopping_cart_labels_advanced';
const ALIAS_SETTINGS = 'settings';

/**
* @inheritdoc

+ 1
- 0
common/logic/Feature/Feature/FeatureDefinition.php Ver arquivo

@@ -18,6 +18,7 @@ class FeatureDefinition extends AbstractDefinition
Feature::ALIAS_PRODUCT_PRICE_IMPORT => 'Produits : import prix',
Feature::ALIAS_ONLINE_PAYMENT => 'Paiement en ligne',
Feature::ALIAS_EXPORT_SHOPPING_CART_LABELS_ADVANCED => "Génération d'étiquettes avec un format spécifique",
Feature::ALIAS_SETTINGS => 'Système de paramètres'
];
}
}

+ 5
- 0
common/logic/ProducerContextTrait.php Ver arquivo

@@ -29,4 +29,9 @@ trait ProducerContextTrait
{
return $this->getProducerContext()->id;
}

public function isOutOfProducerContext(): bool
{
return !$this->producerContext;
}
}

+ 39
- 0
common/logic/Setting/AdminSettingBag.php Ver arquivo

@@ -0,0 +1,39 @@
<?php

namespace common\logic\Setting;

use common\logic\AbstractManager;
use common\logic\Setting\SettingBuilder;
use common\logic\Setting\SettingRepository;

class AdminSettingBag extends AbstractManager
{
protected SettingRepository $settingRepository;
protected SettingBuilder $settingBuilder;

public function loadDependencies(): void
{
$this->settingRepository = $this->loadService(SettingRepository::class);
$this->settingBuilder = $this->loadService(SettingBuilder::class);
}

public function get(string $name)
{
$setting = $this->settingRepository->findOneAdminSettingByName($name);

if($setting) {
return $setting->getValue();
}

return null;
}

public function set(string $name, $value)
{
$setting = $this->settingRepository->findOneAdminSettingByName($name);

if($setting) {
$this->settingBuilder->updateValue($setting, $value);
}
}
}

+ 6
- 3
common/logic/Setting/Setting.php Ver arquivo

@@ -82,9 +82,12 @@ class Setting extends ActiveRecordCommon
];
}

/*
* Relations
*/
public function getValue()
{
$settingDetail = $this->getSettingDetail();
$type = $settingDetail->getType();
return $this->$type;
}

public function getSettingDetail()
{

+ 0
- 22
common/logic/Setting/SettingBag.php Ver arquivo

@@ -1,22 +0,0 @@
<?php

namespace common\logic\Setting;

use common\logic\AbstractChecker;

class SettingBag extends AbstractChecker
{
// $settingModule->getSettingBag()->get('administratorEmail');
// $settingModule->getProducerSettingBag()->get('isTest');
// $producerModule->getSettingBag()->get('isTest');

public function get(string $name)
{

}

public function set(string $name, $value)
{

}
}

+ 16
- 9
common/logic/Setting/SettingBuilder.php Ver arquivo

@@ -3,6 +3,7 @@
namespace common\logic\Setting;

use common\logic\AbstractBuilder;
use common\logic\Producer\Producer\Model\Producer;
use yii\base\ErrorException;

class SettingBuilder extends AbstractBuilder
@@ -17,22 +18,30 @@ class SettingBuilder extends AbstractBuilder
}

public function instanciateSetting(
string $name
string $name,
Producer $producer = null
): Setting
{
$setting = new Setting();
$setting->name = $name;
$setting->populateProducer($this->getProducerContext(false));
$setting->populateProducer($producer);
$this->initDefaultValue($setting);

return $setting;
}

public function createSetting(
string $name
string $name,
Producer $producer = null
): Setting
{
$setting = $this->settingRepository->findOneSettingByName($name);
if($producer) {
$setting = $this->settingRepository->findOneProducerSettingByName($name);
}
else {
$setting = $this->settingRepository->findOneAdminSettingByName($name);
}

if(!$setting) {
$setting = $this->instanciateSetting($name);
$this->create($setting);
@@ -49,7 +58,7 @@ class SettingBuilder extends AbstractBuilder
$setting->$type = $value;
}
else {
throw new ErrorException("Le type de donnée n'est pas reconnu.");
throw new ErrorException("Le type de donnée du SettingDetail n'est pas reconnu.");
}
}

@@ -61,16 +70,14 @@ class SettingBuilder extends AbstractBuilder
}
}

public function updateValueByName(string $name, $value): void
public function updateValue(Setting $setting, $value): void
{
$setting = $this->createSetting($name);
$this->initValue($setting, $value);
$this->update($setting);
}

public function updateDefaultValueByName(string $name)
public function updateDefaultValueByName(Setting $setting)
{
$setting = $this->createSetting($name);
$this->initDefaultValue($setting);
$this->update($setting);
}

+ 12
- 0
common/logic/Setting/SettingDetails/AbstractSettingDetail.php Ver arquivo

@@ -13,6 +13,7 @@ class AbstractSettingDetail
const TYPE_DOUBLE = 'double';

public string $name;
public string $label;
public string $type;
public string $section;
public $defaultValue = null;
@@ -30,6 +31,17 @@ class AbstractSettingDetail
return $this->name;
}

public function setLabel(string $label): self
{
$this->label = $label;
return $this;
}

public function getLabel(): string
{
return $this->label;
}

public function setSection(string $section): self
{
$this->section = $section;

+ 32
- 0
common/logic/Setting/SettingDetails/Admin/AdminSettingDefinition.php Ver arquivo

@@ -7,12 +7,16 @@ use common\logic\Setting\SettingDetails\Admin\General\AdministratorEmailAdminSet
use common\logic\Setting\SettingDetails\Admin\General\AdministratorPhoneNumberAdminSetting;
use common\logic\Setting\SettingDetails\Admin\General\IsTestAdminSetting;
use common\logic\Setting\SettingDetails\Admin\General\SupportEmailAdminSetting;
use common\logic\Setting\SettingDetails\Admin\General2\AnOtherTestAdminSetting;

class AdminSettingDefinition extends SettingDefinition
{
const SECTION_GENERAL = 'general';
const SUBSECTION_GENERAL = 'general.main';

const SECTION_GENERAL2 = 'general2';
const SUBSECTION_GENERAL2 = 'general2.main';

public function getSettingDetails(): array
{
return [
@@ -23,6 +27,11 @@ class AdminSettingDefinition extends SettingDefinition
new AdministratorPhoneNumberAdminSetting,
new IsTestAdminSetting,
]
],
self::SECTION_GENERAL2 => [
self::SUBSECTION_GENERAL2 => [
new AnOtherTestAdminSetting,
],
]
];
}
@@ -32,6 +41,29 @@ class AdminSettingDefinition extends SettingDefinition
return [
self::SECTION_GENERAL => 'General',
self::SUBSECTION_GENERAL => 'General',

self::SECTION_GENERAL2 => 'General deux',
self::SUBSECTION_GENERAL2 => 'General deux',
];
}

public function getSettingDetailsFlat(): array
{
$settingDetailsFlatArray = [];

foreach($this->getSettingDetails() as $sectionsArray) {
foreach($sectionsArray as $subsectionsArray) {
foreach($subsectionsArray as $settingDetail) {
$settingDetailsFlatArray[] = $settingDetail;
}
}
}

return $settingDetailsFlatArray;
}

public function getSectionLabelBySectionName(string $sectionName): string
{
return $this->getSectionLabels()[$sectionName];
}
}

+ 1
- 0
common/logic/Setting/SettingDetails/Admin/General/AdministratorEmailAdminSetting.php Ver arquivo

@@ -10,6 +10,7 @@ class AdministratorEmailAdminSetting extends AbstractSettingDetail
{
$this
->setName('administratorEmail')
->setLabel('Administrator Email')
->setTypeString();
}
}

+ 1
- 0
common/logic/Setting/SettingDetails/Admin/General/AdministratorPhoneNumberAdminSetting.php Ver arquivo

@@ -10,6 +10,7 @@ class AdministratorPhoneNumberAdminSetting extends AbstractSettingDetail
{
$this
->setName('administratorPhoneNumber')
->setLabel('Administrator Phone Number')
->setTypeString();
}
}

+ 1
- 0
common/logic/Setting/SettingDetails/Admin/General/IsTestAdminSetting.php Ver arquivo

@@ -10,6 +10,7 @@ class IsTestAdminSetting extends AbstractSettingDetail
{
$this
->setName('isTest')
->setLabel('Is Test')
->setTypeBoolean()
->setDefaultValue(true);
}

+ 1
- 0
common/logic/Setting/SettingDetails/Admin/General/SupportEmailAdminSetting.php Ver arquivo

@@ -10,6 +10,7 @@ class SupportEmailAdminSetting extends AbstractSettingDetail
{
$this
->setName('supportEmail')
->setLabel('Support Email')
->setTypeString();
}
}

+ 16
- 0
common/logic/Setting/SettingDetails/Admin/General2/AnOtherTestAdminSetting.php Ver arquivo

@@ -0,0 +1,16 @@
<?php

namespace common\logic\Setting\SettingDetails\Admin\General2;

use common\logic\Setting\SettingDetails\AbstractSettingDetail;

class AnOtherTestAdminSetting extends AbstractSettingDetail
{
public function __construct()
{
$this
->setName('anOtherTest')
->setLabel('Un autre test')
->setTypeBoolean();
}
}

+ 2
- 8
common/logic/Setting/SettingImporter.php Ver arquivo

@@ -25,14 +25,8 @@ class SettingImporter extends AbstractManager
public function importFromAdminSettingDefinition(): void
{
\Yii::$app->logic->setProducerContext(null);
$settingDetails = $this->adminSettingDefinition->getSettingDetails();

foreach($settingDetails as $subsectionsArray) {
foreach($subsectionsArray as $settingDetailsArray) {
foreach($settingDetailsArray as $settingDetail) {
$this->settingBuilder->createSetting($settingDetail->getName());
}
}
foreach ($this->adminSettingDefinition->getSettingDetailsFlat() as $settingDetail) {
$this->settingBuilder->createSetting($settingDetail->getName());
}
}


+ 17
- 1
common/logic/Setting/SettingModule.php Ver arquivo

@@ -16,7 +16,8 @@ class SettingModule extends AbstractModule
ProducerSettingDefinition::class,
SettingRepository::class,
SettingBuilder::class,
SettingImporter::class
SettingImporter::class,
AdminSettingBag::class
];
}

@@ -25,6 +26,16 @@ class SettingModule extends AbstractModule
return SettingDefinition::getInstance();
}

public function getAdminSettingDefinition(): AdminSettingDefinition
{
return AdminSettingDefinition::getInstance();
}

public function getProducerSettingDefinition(): ProducerSettingDefinition
{
return ProducerSettingDefinition::getInstance();
}

public function getRepository(): SettingRepository
{
return SettingRepository::getInstance();
@@ -34,4 +45,9 @@ class SettingModule extends AbstractModule
{
return SettingImporter::getInstance();
}

public function getAdminSettingBag(): AdminSettingBag
{
return AdminSettingBag::getInstance();
}
}

+ 18
- 0
common/logic/Setting/SettingRepository.php Ver arquivo

@@ -24,6 +24,24 @@ class SettingRepository extends AbstractRepository
}

public function findOneSettingByName(string $name)
{
if($this->isOutOfProducerContext()) {
return $this->findOneAdminSettingByName($name);
}
else {
return $this->findOneProducerSettingByName($name);
}
}

public function findOneAdminSettingByName(string $name)
{
return $this->createQuery()
->filterProducerIsNull()
->filterByName($name)
->findOne();
}

public function findOneProducerSettingByName(string $name)
{
return $this->createDefaultQuery()
->filterByName($name)

+ 6
- 0
common/logic/Setting/SettingRepositoryQuery.php Ver arquivo

@@ -13,6 +13,12 @@ class SettingRepositoryQuery extends AbstractRepositoryQuery
$this->loadDefinition(SettingDefinition::class);
}

public function filterProducerIsNull(): self
{
$this->andWhere(['id_producer' => null]);
return $this;
}

public function filterByName(string $name): self
{
$this->andWhere(['name' => $name]);

Carregando…
Cancelar
Salvar