@@ -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 | |||
]); | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
?> |
@@ -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], |
@@ -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(); | |||
} | |||
} | |||
?> |
@@ -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()]); | |||
} | |||
} |
@@ -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 |
@@ -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' | |||
]; | |||
} | |||
} |
@@ -29,4 +29,9 @@ trait ProducerContextTrait | |||
{ | |||
return $this->getProducerContext()->id; | |||
} | |||
public function isOutOfProducerContext(): bool | |||
{ | |||
return !$this->producerContext; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -82,9 +82,12 @@ class Setting extends ActiveRecordCommon | |||
]; | |||
} | |||
/* | |||
* Relations | |||
*/ | |||
public function getValue() | |||
{ | |||
$settingDetail = $this->getSettingDetail(); | |||
$type = $settingDetail->getType(); | |||
return $this->$type; | |||
} | |||
public function getSettingDetail() | |||
{ |
@@ -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) | |||
{ | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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; |
@@ -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]; | |||
} | |||
} |
@@ -10,6 +10,7 @@ class AdministratorEmailAdminSetting extends AbstractSettingDetail | |||
{ | |||
$this | |||
->setName('administratorEmail') | |||
->setLabel('Administrator Email') | |||
->setTypeString(); | |||
} | |||
} |
@@ -10,6 +10,7 @@ class AdministratorPhoneNumberAdminSetting extends AbstractSettingDetail | |||
{ | |||
$this | |||
->setName('administratorPhoneNumber') | |||
->setLabel('Administrator Phone Number') | |||
->setTypeString(); | |||
} | |||
} |
@@ -10,6 +10,7 @@ class IsTestAdminSetting extends AbstractSettingDetail | |||
{ | |||
$this | |||
->setName('isTest') | |||
->setLabel('Is Test') | |||
->setTypeBoolean() | |||
->setDefaultValue(true); | |||
} |
@@ -10,6 +10,7 @@ class SupportEmailAdminSetting extends AbstractSettingDetail | |||
{ | |||
$this | |||
->setName('supportEmail') | |||
->setLabel('Support Email') | |||
->setTypeString(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} | |||
@@ -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(); | |||
} | |||
} |
@@ -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) |
@@ -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]); |