Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
use craft\base\Plugin as BasePlugin;
use craft\elements\Entry;
use craft\events\DefineHtmlEvent;
use craft\events\RegisterUrlRulesEvent;
use craft\helpers\UrlHelper;
use craft\web\Controller;
use craft\web\UrlManager;
use craft\web\View;
use fostercommerce\entrytyperules\assetbundles\entrytyperules\EntryTypeRulesAsset;
use fostercommerce\entrytyperules\models\Settings;
Expand All @@ -25,14 +26,22 @@
*/
class Plugin extends BasePlugin
{
public static ?Plugin $plugin = null;

public bool $hasCpSettings = true;

public static ?Settings $settings = null;

/**
* @throws InvalidConfigException
*/
public function init(): void
{
parent::init();
self::$plugin = $this;

self::$plugin->getSettings();
//self::$settings = $settings;

$this->setComponents([
'service' => Service::class,
Expand Down Expand Up @@ -61,23 +70,34 @@ function (DefineHtmlEvent $event): void {
}
}
);


Event::on(
UrlManager::class,
UrlManager::EVENT_REGISTER_CP_URL_RULES,
function (RegisterUrlRulesEvent $event): void {
// Register Control Panel routes
$event->rules = array_merge(
$event->rules,
[
'entry-type-rules' => 'entry-type-rules/settings',
'entry-type-rules/settings' => 'entry-type-rules/settings',
],
);
}
);
}

public function getSettingsResponse(): mixed
{
$overrides = Craft::$app->getConfig()->getConfigFromFile($this->handle);
/** @var \craft\web\Response $response */
$response = Craft::$app->getResponse();
return $response->redirect(UrlHelper::cpUrl('entry-type-rules/settings'));
}

/** @var Controller $controller */
$controller = Craft::$app->controller;
return $controller->renderTemplate(
'entry-type-rules/settings',
[
'settings' => $this->getSettings(),
'overrides' => $overrides,
'sectionsUrl' => UrlHelper::cpUrl('settings/sections'),
'entriesUrl' => UrlHelper::cpUrl('entries'),
]
);
public function getPluginName(): ?string
{
return $this->name;
}

protected function createSettingsModel(): ?Model
Expand Down
190 changes: 188 additions & 2 deletions src/controllers/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@
use Craft;

use craft\errors\MissingComponentException;
use craft\helpers\ArrayHelper;
use craft\helpers\ConfigHelper;
use craft\helpers\Cp;
use craft\helpers\UrlHelper;
use craft\models\Site;
use craft\web\Controller;
use craft\web\Request;
use fostercommerce\entrytyperules\models\Settings;
use fostercommerce\entrytyperules\Plugin;
use Illuminate\Support\Collection;
use yii\base\InvalidConfigException;
use yii\web\BadRequestHttpException;
use yii\web\MethodNotAllowedHttpException;
Expand All @@ -18,6 +24,49 @@
{
protected array|int|bool $allowAnonymous = [];

public function actionIndex(): Response
{
$site = Cp::requestedSite();
$siteHandle = $site?->handle;
$siteId = $site?->id;
$sections = Craft::$app->getEntries()->getAllSections();

$enabledSections = array_filter($sections, fn ($section) => $section->getSiteSettings()[$siteId]->enabledByDefault ?? false);
$variables = [];

$siteHandleUri = Craft::$app->isMultiSite ? '/' . $siteHandle : '';

$overrides = Craft::$app->getConfig()->getConfigFromFile('entry-type-rules');

// walk through overrides array,
// if the value set for 'limit' is not an array then replace it with an array of siteHandles all with same value
// if the value set for limit is an array and there is a key for '*' then replace it with an array of siteHandles all with same value
$this->_globalValues($overrides);

$variables = [
'sections' => $enabledSections,
'settings' => Plugin::$plugin?->getSettings()->toArray(),
'overrides' => $overrides,
'sectionsUrl' => ConfigHelper::localizedValue(UrlHelper::cpUrl('settings/sections', $siteHandle)),
'siteHandle' => $siteHandle,
'siteHandleUri' => $siteHandleUri,
'siteId' => $siteId,
'crumbs' => $this->_buildCrumbs(),
];


$this->_buildCrumbs();



/** @var Controller $controller */
$controller = Craft::$app->controller;
return $controller->renderTemplate(
'entry-type-rules/settings',
$variables
);
}

/**
* Handle a request going to our plugin's action URL for saving settings,
* e.g.: actions/craft-entry-type-rules/save-settings
Expand All @@ -30,17 +79,30 @@
public function actionSaveSettings(): Response
{
$this->requirePostRequest();

/** @var Request $request */
$request = Craft::$app->getRequest();

$siteHandle = Craft::$app->getSites()->getSiteById($request->getBodyParam('siteId'))->handle;

Check failure on line 85 in src/controllers/SettingsController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Parameter #1 $siteId of method craft\services\Sites::getSiteById() expects int, mixed given.

Check failure on line 85 in src/controllers/SettingsController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Cannot access property $handle on craft\models\Site|null.

/** @var Plugin $plugin */
$plugin = Plugin::getInstance();

$newSettings = $request->getBodyParam('sections');

$oldSettings = $plugin->getSettings()->toArray();

$this->_removeUserGroupsForSite($oldSettings, $siteHandle);

Check failure on line 94 in src/controllers/SettingsController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Parameter #2 $targetSite of method fostercommerce\entrytyperules\controllers\SettingsController::_removeUserGroupsForSite() expects string, string|null given.


$mergedSettings = ArrayHelper::merge($oldSettings['sections'] ?? [], $newSettings ?? []);


$settings = new Settings([
'sections' => $request->getBodyParam('sections'),
'sections' => $mergedSettings,
]);



if (! $settings->validate() || ! Craft::$app->getPlugins()->savePluginSettings($plugin, $settings->toArray())) {
Craft::$app->getSession()->setError(Craft::t('app', 'Couldn’t save plugin settings.'));
} else {
Expand All @@ -49,4 +111,128 @@

return $this->redirectToPostedUrl();
}

public function _removeUserGroupsForSite(array &$array, string $targetSite, ?string $currentSite = null): void

Check failure on line 115 in src/controllers/SettingsController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method fostercommerce\entrytyperules\controllers\SettingsController::_removeUserGroupsForSite() has parameter $array with no value type specified in iterable type array.
{
foreach ($array as $key => &$value) {
// Track when we enter a site-specific branch
$nextSite = $currentSite;
if ($key === 'firstSite' || $key === 'secondSite') {
$nextSite = $key;
}

// Remove userGroups only if we're inside the target site
if ($key === 'userGroups' && $currentSite === $targetSite) {
unset($array[$key]);
continue;
}

if (is_array($value)) {
$this->_removeUserGroupsForSite($value, $targetSite, $nextSite);
}
}
}

/**
* @return array<int, array<string, array<string, array<int, array<string, mixed>>|string>|string|null>>
*/
private function _buildCrumbs(): array
{
$sites = Craft::$app->getSites();
$requestedSite = Cp::requestedSite() ?? Craft::$app->getSites()->getPrimarySite();
$requestedSiteId = $requestedSite->id;
$requestedSiteName = $requestedSite->name;

$siteCrumbItems = [];
$siteGroups = Craft::$app->getSites()->getAllGroups();
$crumbSites = Collection::make($sites->getAllSites())
->map(fn (Site $site): array => [
'site' => $site,
])
->keyBy(fn (array $site): ?int => $site['site']->id)

Check failure on line 152 in src/controllers/SettingsController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Parameter #1 $keyBy of method Illuminate\Support\Collection<(int|string),array<string, craft\models\Site>>::keyBy() expects array|(callable(array{site: craft\models\Site}, int|string): (int|string))|string, Closure(array): (int|null) given.
->all();

foreach ($siteGroups as $siteGroup) {
$groupSites = $siteGroup->getSites();

if (empty($groupSites)) {
continue;
}

$groupSiteItems = array_map(fn (Site $site): array => [
'status' => $crumbSites[$site->id]['site']->status ?? null,
'label' => Craft::t('site', $site->name),
'url' => UrlHelper::cpUrl("entry-type-rules?site={$site->handle}"),
'hidden' => ! isset($crumbSites[$site->id]),
'selected' => $site->id === $requestedSiteId,
'attributes' => [
'data' => [
'site-id' => $site->id,
],
],
], $groupSites);

if (count($siteGroups) > 1) {
$siteCrumbItems[] = [
'heading' => Craft::t('site', $siteGroup->name),
'items' => $groupSiteItems,
'hidden' => ! ArrayHelper::contains($groupSiteItems, fn (array $item): bool => ! $item['hidden']),
];
} else {
array_push($siteCrumbItems, ...$groupSiteItems);
}
}

// Add in the breadcrumbs
$crumbs = [
[
'id' => 'language-menu',
'icon' => 'world',
'label' => Craft::t(
'site',
$requestedSiteName
),
'menu' => [
'items' => $siteCrumbItems,
'label' => Craft::t('site', 'Select site'),
],
],
[
'label' => Plugin::$plugin?->getPluginName(),
],
];

return $crumbs;
}

private function _globalValues(array &$array): void

Check failure on line 208 in src/controllers/SettingsController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method fostercommerce\entrytyperules\controllers\SettingsController::_globalValues() has parameter $array with no value type specified in iterable type array.
{
// get all sitehandles
$sites = Craft::$app->getSites()->getAllSites();
$siteHandles = array_map(fn ($site) => $site->handle, $sites);

foreach ($array as $key => &$value) {
// if we only have an integer as a limit value, then set the value to be an array of site handles set to the value
if ($key === 'limit' && ! is_array($value)) {
$limitValue = $value;
$value = array_fill_keys($siteHandles, $limitValue);
}

// if we have an array of limit values, but the array contains the key '*'
// or there is a '*' array in the userGroups
// then set any undefined sites to use the value for '*'
if (($key === 'limit' && is_array($value) || $key === 'userGroups') && array_key_exists('*', $value)) {
$defaultValue = $value['*'];
$missingSiteHandles = array_values(array_diff($siteHandles, array_keys($value)));
$defaultedSiteHandles = array_fill_keys($missingSiteHandles, $defaultValue);
$value = array_merge($value, $defaultedSiteHandles);
// unset the '*'
unset($value['*']);
}

if (is_array($value)) {
$this->_globalValues($value);
}
}
}
}
13 changes: 9 additions & 4 deletions src/services/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use craft\base\Component;
use craft\elements\Entry;
use craft\helpers\ConfigHelper;
use craft\helpers\Cp;
use craft\web\User;
use fostercommerce\entrytyperules\models\Settings;
use fostercommerce\entrytyperules\Plugin;
Expand All @@ -21,6 +23,8 @@
// We will return an array of locked entry type IDs
$lockedEntryTypes = [];

$site = Cp::requestedSite();

// Get the plugins settings
/** @var Settings $settings */
$settings = Plugin::getInstance()?->getSettings();
Expand Down Expand Up @@ -51,17 +55,18 @@
// Loop through the locked entry type settings
foreach ($lockedTypesSettings as $typeHandle => $setting) {
// Get the count of each entry type and compare it to the limit value
$limit = $setting['limit'] ?? 0;
$limit = ConfigHelper::localizedValue($setting['limit'], $site->handle) ?? 0;

Check failure on line 58 in src/services/Service.php

View workflow job for this annotation

GitHub Actions / PHPStan

Cannot access property $handle on craft\models\Site|null.
if ($limit > 0) {
$entryCount = Entry::find()->sectionId($sectionId)->type($typeHandle)->count();
if ($entryCount >= $setting['limit']) {
if ($entryCount >= $limit) {
$lockedEntryTypes[] = $entryTypesIdsMap[$typeHandle];
}
}

// Check the users groups against the userGroup setting
if (isset($setting['userGroups']) && is_array($setting['userGroups'])) {
$matchedGroups = array_intersect($setting['userGroups'], $userGroupArray);
$userGroups = ConfigHelper::localizedValue($setting['userGroups']);
if (is_array($userGroups)) {
$matchedGroups = array_intersect($userGroups, $userGroupArray);

if ($matchedGroups === [] && ! $user->getIsAdmin()) {
$lockedEntryTypes[] = $entryTypesIdsMap[$typeHandle];
Expand Down
Loading
Loading