Skip to content

Commit

Permalink
Merge pull request #14307 from craftcms/feature/cms-1256-limit-sites-…
Browse files Browse the repository at this point in the history
…via-config

Add site limit
  • Loading branch information
brandonkelly authored Feb 6, 2024
2 parents 5d48fc1 + fb7b89f commit a7665ca
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@
- Added `craft\services\ProjectConfig::find()`.
- Added `craft\services\ProjectConfig::flush()`.
- Added `craft\services\ProjectConfig::writeYamlFiles()`.
- Added `craft\services\Sites::$maxSites`. ([#14307](https://github.com/craftcms/cms/pull/14307))
- Added `craft\services\Sites::getRemainingSites()`. ([#14307](https://github.com/craftcms/cms/pull/14307))
- Added `craft\web\CpScreenResponseBehavior::$actionMenuItems`.
- Added `craft\web\CpScreenResponseBehavior::$contextMenuItems`.
- Added `craft\web\CpScreenResponseBehavior::$selectableSites`.
Expand Down Expand Up @@ -609,6 +611,7 @@
- Improved the performance of autosaves for elements with newly-created Matrix entries.
- Slugs are no longer required for elements that don’t have a URI format that contains `slug`.
- Garbage collection now deletes orphaned nested entries.
- Craft now has a default limit of 100 sites, which can be increased via `craft\ervices\Sites::$maxSites` at your own peril. ([#14307](https://github.com/craftcms/cms/pull/14307))
- Fixed a bug where multi-site element queries weren’t scoring elements on a per-site basis. ([#13801](https://github.com/craftcms/cms/discussions/13801))
- Fixed an error that could occur if eager-loading aliases conflicted with native eager-loading handles, such as `author`. ([#14057](https://github.com/craftcms/cms/issues/14057))
- Fixed a bug where layout components provided by disabled plugins weren’t getting omitted. ([#14219](https://github.com/craftcms/cms/pull/14219))
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
- Improved global sidebar styling. ([#14281](https://github.com/craftcms/cms/pull/14281))
- The global sidebar is now collapsible. ([#14281](https://github.com/craftcms/cms/pull/14281))
- Entry cards without a thumbnail now show their entry type icon. ([#14305](https://github.com/craftcms/cms/issues/14305))
- Craft now has a default limit of 100 sites, which can be increased via `craft\ervices\Sites::$maxSites` at your own peril. ([#14307](https://github.com/craftcms/cms/pull/14307))
- Added `craft\services\Sites::$maxSites`. ([#14307](https://github.com/craftcms/cms/pull/14307))
- Added `craft\services\Sites::getRemainingSites()`. ([#14307](https://github.com/craftcms/cms/pull/14307))
- Added `Craft.ElementEditor::markDeltaNameAsModified()`.
- Removed `craft\elements\NestedElementManager::$allowDeletion`.
- Fixed a bug where element editor forms could submit duplicate input values. ([#14276](https://github.com/craftcms/cms/issues/14276))
Expand Down
4 changes: 1 addition & 3 deletions src/controllers/SitesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public function beforeAction($action): bool
public function actionSettingsIndex(?int $groupId = null): Response
{
$sitesService = Craft::$app->getSites();
$allGroups = $sitesService->getAllGroups();

if ($groupId) {
if (($group = $sitesService->getGroupById($groupId)) === null) {
Expand Down Expand Up @@ -88,9 +87,8 @@ public function actionSettingsIndex(?int $groupId = null): Response

return $this->renderTemplate('settings/sites/index.twig', compact(
'crumbs',
'allGroups',
'group',
'sites'
'sites',
));
}

Expand Down
29 changes: 29 additions & 0 deletions src/services/Sites.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ class Sites extends Component
*/
public const EVENT_AFTER_DELETE_SITE = 'afterDeleteSite';

/**
* This value can be configured as needed, but exists as a safeguard against performance issues.
*
* ::: warning
* Craft’s multi-site support is not designed to be infinitely scalable.
* Increase this limit at your own risk!
* :::
*
* @var int The maximum number of sites that can be created.
* @since 5.0.0
*/
public int $maxSites = 100;

/**
* @var MemoizableArray<SiteGroup>|null
* @see _groups()
Expand Down Expand Up @@ -633,6 +646,18 @@ public function getSiteByHandle(string $siteHandle, ?bool $withDisabled = null):
return ArrayHelper::firstWhere($this->_allSites($withDisabled), 'handle', $siteHandle, true);
}

/**
* Returns the number of sites that can be created, based on [[$maxSites]].
*
* @return int
* @see $maxSites
* @since 5.0.0
*/
public function getRemainingSites(): int
{
return max($this->maxSites - count($this->_allSitesById), 0);
}

/**
* Saves a site.
*
Expand All @@ -646,6 +671,10 @@ public function saveSite(Site $site, bool $runValidation = true): bool
{
$isNewSite = !$site->id;

if ($isNewSite && !$this->getRemainingSites()) {
throw new Exception("Maximum number of sites cannot exceed $this->maxSites.");
}

if (!empty($this->_allSitesById)) {
$primarySite = $this->getPrimarySite();
} else {
Expand Down
9 changes: 6 additions & 3 deletions src/templates/settings/sites/index.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@


{% block actionButton %}
{% set newSiteUrl = url('settings/sites/new', (group ? { groupId: group.id } : null)) %}
<a href="{{ newSiteUrl }}" class="btn submit add icon">{{ "New site"|t('app') }}</a>
{{ tag('a', {
href: url('settings/sites/new', (group ? { groupId: group.id } : null)),
class: ['btn', 'submit', 'add', 'icon', craft.app.sites.getRemainingSites() ? null : 'disabled'],
text: "New site"|t('app'),
}) }}
{% endblock %}


{% block sidebar %}
<nav>
<ul id="groups">
<li><a href="{{ url('settings/sites') }}"{% if not group %} class="sel"{% endif %}>{{ "All Sites"|t('app') }}</a></li>
{% for g in allGroups %}
{% for g in craft.app.sites.getAllGroups() %}
<li>
{{ tag('a', {
href: url('settings/sites', {groupId: g.id}),
Expand Down

0 comments on commit a7665ca

Please sign in to comment.