Skip to content

Commit

Permalink
Merge pull request #568 from craftcms/4.6
Browse files Browse the repository at this point in the history
4.6
  • Loading branch information
AugustMiller authored Jan 9, 2024
2 parents cc8124d + 48e0672 commit 00144a8
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 24 deletions.
12 changes: 11 additions & 1 deletion docs/.vuepress/components/Since.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<a
class="since"
:href="releaseUrl"
:title="`${feature} was first available in version ${ver} of ${product}.`"
:title="parsedDescription"
target="_blank">
{{ ver }}<span class="plus">+</span>
</a>
Expand Down Expand Up @@ -32,6 +32,10 @@ export default {
type: String,
default: 'This feature',
},
description: {
type: String,
default: '{feature} was first available in version {ver} of {product}.',
}
},
computed: {
releaseUrl() {
Expand All @@ -42,6 +46,12 @@ export default {
return `${GITHUB_URL}/${this.repo}/releases/tag/${this.ver}`;
},
parsedDescription() {
return this.description
.replace('{feature}', this.feature)
.replace('{ver}', this.ver)
.replace('{product}', this.product);
}
},
};
</script>
Expand Down
1 change: 1 addition & 0 deletions docs/.vuepress/sets/craft-cms.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ module.exports = {
"categories-fields",
"checkboxes-fields",
"color-fields",
"country-fields",
"date-time-fields",
"dropdown-fields",
"email-fields",
Expand Down
30 changes: 15 additions & 15 deletions docs/4.x/config/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,42 +452,42 @@ If your queue driver supplies its own worker, set the <config4:runQueueAutomatic

### Mutex

Craft uses a file-based mutex (or "mutual exclusivity") driver by default, which should be switched to a different driver in [load-balanced environments](https://craftcms.com/knowledge-base/configuring-load-balanced-environments#mutex-locks).
Craft uses the database for mutex (or “mutually exclusive”) locks <Since ver="4.6.0" feature="The database mutex driver became the default in {ver} of {product}" />, which means it will work natively in [load-balanced environments](kb:configuring-load-balanced-environments#mutex-locks).

::: tip
A [NullMutex](craft4:craft\mutex\NullMutex) driver is used when Dev Mode is enabled, since mutex drivers aren’t necessary for local development and we’ve seen issues with mutex in some Windows and Linux filesystems.
::: warning
Prior to 4.6, enabling `devMode` would automatically switch from the default `FileMutex` driver to a special `NullMutex` driver to help avoid some virtualization bugs. Now, `NullMutex` is only used when a database connection is not available (i.e. prior to installation).
:::

You can configure a custom mutex driver by configuring the `mutex` component’s nested `$mutex` property:
You can configure a custom mutex driver by overriding the `mutex` component’s nested `$mutex` property:

```php
// Use mutex driver provided by yii2-redis
return [
'components' => [
'mutex' => function() {
$generalConfig = Craft::$app->getConfig()->getGeneral();

$config = [
'class' => craft\mutex\Mutex::class,
'class' => craft\mutex\File::class,
// Alter just this nested property of the main mutex component:
'mutex' => [
'class' => yii\redis\Mutex::class,
// set the max duration to 15 minutes for console requests
'expire' => Craft::$app->request->isConsoleRequest ? 900 : 30,
'redis' => [
'hostname' => App::env('REDIS_HOSTNAME') ?: 'localhost',
'port' => 6379,
'password' => App::env('REDIS_PASSWORD') ?: null,
],
'class' => yii\mutex\FileMutex::class,
'fileMode' => $generalConfig->defaultFileMode,
'dirMode' => $generalConfig->defaultDirMode,
],
];

// Return the initialized component:
return Craft::createObject($config);
},
],
// ...
];
```

The specific properties that you can (or must) use in the configuration object will differ based on the specified mutex class—check the driver’s documentation for instructions.

::: warning
Pay careful attention to the structure, here—we’re only modifying the existing component’s `mutex` _property_ and leaving the rest of its config as-is.
The primary mutex _component_ should always be an instance of <craft4:craft\mutex\Mutex>. We’re only modifying the existing `mutex` component’s nested _driver_ property and leaving the rest of its config as-is!
:::

## Modules
Expand Down
4 changes: 4 additions & 0 deletions docs/4.x/control-panel.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ Access to utilities should be granted only to trusted users, especially the inno
Keep in mind that any user marked as an “Admin” implicitly has access to _all_ utilities.
:::

#### Disabling Utilities

You can disable a utility for all users with the [`disabledUtilities` config setting](config4:disabledUtilities). <Since ver="4.6.0" feature="Disabling utilities" /> Refer to each [utility class](repo:craftcms/cms/tree/main/src/utilities)’s `id()` method for their handles—including those provided by plugins.

### Settings

The **Settings** screen is where you’ll configure the system and design your content model. Settings complement [configuration](./config/README.md) are typically stored in [Project Config](./project-config.md) so that you can easily deploy them to other environments.
Expand Down
84 changes: 84 additions & 0 deletions docs/4.x/country-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
description: Select a country from the same database that powers address elements.
---

# Country Fields

The **Country** field <Since ver="4.6.0" feature="The Country field" /> allows authors to select from a the same list of countries made available via [address](addresses.md) elements. When viewed as part of a form in the [control panel](control-panel.md), countries’ names will be localized into the user’s preferred language.

## Settings

This field has no configurable options.

::: tip
You can switch other text-based fields to use the Country field type. As long as your existing field’s values are valid two-letter country codes (or empty) and the existing field
:::

## Development

Craft stores the field’s value as a capitalized, two-letter country code.

```twig
{% if entry.country is not empty %}
Country code: {{ entry.country }}
{% endif %}
```

To get more information about the country, use the [address repository](addresses.md#address-repository) available via the address service:

```twig
{# Load all country data: #}
{% set repo = craft.app.addresses.getCountryRepository() %}
{# Get just the selected country: #}
{% set country = repo.get(entry.country) %}
{# Use properties of the country model: #}
{{ country.name }} ({{ country.threeLetterCode }})
```

The `country` variable in this example is an instance of [`CommerceGuys\Addressing\Country\Country`](repo:commerceguys/addressing/blob/master/src/Country/Country.php).

### Querying by Country

You can query for elements based on a country field’s value in a familiar way:

```twig
{% set letters = craft.entries
.section('letters')
.fromCountry('FR')
.toCountry('GB')
.dateSent()
.all() %}
```

### Front-end Forms

Update the value of a country field on an element by submitting a two-letter country code to the [`entries/save-entry` action](dev/controller-actions.md#post-entries-save-entry). Supposing we are in a template used by the “Letters” section from the previous example, our form might look something like this:

```twig
{% set countries = craft.app.addresses.getCountryRepository().getAll() %}
<form method="post">
{{ csrfInput() }}
{{ actionInput('entries/save-entry') }}
{{ hiddenInput('canonicalId', entry.id) }}
{{ input('text', 'title', entry.title) }}
<select name="fields[toCountry]">
{% for country in countries %}
{{ tag('option', {
text: country.name,
value: country.countryCode,
selected: country.countryCode == entry.toCountry,
}) }}
{% endfor %}
</select>
<button>Save</button>
</form>
```

<See path="dev/controller-actions.md" description="Read more about using forms to submit data to Craft controllers." />
1 change: 1 addition & 0 deletions docs/4.x/dev/controller-actions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
description: Craft has a powerful and secure HTTP API for interacting with accounts, content, and other features from your front-end.
sidebarDepth: 2
related:
- uri: https://craftcms.com/knowledge-base/front-end-user-accounts
Expand Down
2 changes: 1 addition & 1 deletion docs/4.x/extend/utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ You may also implement static `toolbarHtml()` and `footerHtml()` methods to inje

Each utility automatically gets its own [permission](user-permissions.md). Craft checks these permissions before displaying a utility in the sidebar, and when the utility’s URL is requested.

However, those permissions do _not_ have any bearing on what functionality might be accessible to a user via other means. For example, if your utility displayed a form to authorized users and allowed them to download a specialized report of some kind, the [controller](controllers.md) or action that ultimately generates the report must also check the appropriate permissions.
However, those permissions do _not_ have any bearing on what functionality might be accessible to a user via other means. For example, if your utility displayed a form to authorized users and allowed them to download a specialized report of some kind, the [controller](controllers.md) or action that ultimately generates the report must also check the appropriate permissions. In general, those permissions should be discrete: an administrator would grant users access to the utility _and_ a _Modify Widgets_ permission that your plugin explicitly defines (and checks in the appropriate controller action).

## Registering your Utility

Expand Down
2 changes: 1 addition & 1 deletion docs/4.x/fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ All fields share a few settings:
- **Instructions** – Instruction text to guide authors;
- **Field Type** – What [type](#field-types) of field it is;


<BrowserShot url="https://my-project.tld/admin/settings/fields/new" :link="false" :max-height="500">
<img src="./images/fields-field-settings.png">
</BrowserShot>
Expand All @@ -37,6 +36,7 @@ Type | Description
[Categories](categories-fields.md) | Attach category elements.
[Checkboxes](checkboxes-fields.md) | Select any number of values from a list.
[Color](color-fields.md) | Choose a color with the browser’s color picker UI.
[Countries](country-fields.md) | Select from a list of countries available in [address](addresses.md) elements.
[Date](date-time-fields.md) | Choose a date and/or time, as well as a timezone.
[Dropdown](dropdown-fields.md) | Choose one value from a list.
[Email](email-fields.md) | Validate text input as an email address.
Expand Down
8 changes: 7 additions & 1 deletion docs/4.x/searching.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,20 @@ You can configure any [custom field](./fields.md) to make its content available

![Searchable Checkbox](./images/searchable-checkbox.png)

Indexes are only updated once an element with the field is saved, though. If you have a large amount of content and users (admin or otherwise) rely heavily on search, consider [resaving the elements](#rebuilding-your-search-indexes) to populate the index.
Indexes are only updated once an element with the field is saved. If you have a large amount of content and users (admin or otherwise) rely heavily on search, consider [resaving the elements](#rebuilding-your-search-indexes) to populate the index.

::: tip
For Matrix fields, the top-level **Use this field’s values as search keywords** setting determines whether _any_ sub-fields will factor into results for the parent—individual fields must also opt-in to indexing for any keywords to be bubbled up.

For relational fields like [Assets](./assets-fields.md), [Categories](./categories-fields.md), and [Entries](./entries-fields.md), the setting determines whether titles of related elements should factor into search results.
:::

## Indexing Criteria

Any time an indexable attribute or field on an element is updated (as indicated by Craft’s change-tracking feature, which powers drafts and revisions), an “Updating search indexes” job is pushed into the queue. <Since ver="4.6.0" description="A more restrictive set of criteria for indexing elements was implemented in {product} {ver}." /> Prior versions generate an indexing job whenever an element with _any_ searchable attributes or fields is saved, regardless of whether or not those specific attributes changed.

The [eligible properties](#searching-for-specific-element-attributes) differ for each element type, the field layout a given element uses, and which of the underlying fields are flagged as searchable.

## Rebuilding Your Search Indexes

Craft does its best to keep its search indexes as up-to-date as possible, but there are a couple things that might render portions of them inaccurate. If you suspect your search indexes are out of date, you can have Craft rebuild them by bulk-resaving entries with the [`resave/entries`](console-commands.md#resave) command and including the `--update-search-index` flag:
Expand Down
7 changes: 3 additions & 4 deletions docs/4.x/user-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ Considering how much damage an admin can do, we strongly advise caution when cre

If you have Craft Pro, you can create User Groups to help organize your site’s user accounts, as well as batch-set permissions on them.

To create a new User Group, go to **Settings****Users** and press **+ New user group**. You can give your group a Name and Handle, plus any permissions you want every user within the group to have.
To create a new User Group, go to **Settings****Users** and press **+ New user group**. You can give your group a **Name** and **Handle**, plus any **Permissions** you want every user within the group to have.

After you create your groups, you can assign users to groups by going into their account settings and choosing the Permissions tab.
After you create your groups, you can assign users to groups by going into their account settings and choosing the **Permissions** tab.

## Permissions

Expand Down Expand Up @@ -97,11 +97,10 @@ The permissions Craft comes with are:
| ↳&nbsp; Find and Replace | `utility:find-replace`
| ↳&nbsp; Migrations | `utility:migrations`

You may not see all of these options, initially—only ones that are relevant based on the current content schema will be displayed. For example, everything under _View categories_ will be hidden until you have at least one category group.
You may not see all of these options, initially—only ones that are relevant based on the current content schema will be displayed. For example, everything under _View categories_ will be hidden until you have at least one [category group](categories.md#category-groups).

Plugins may register their own permissions, which can appear in a top-level group, under _Access the control panel_, or within _Utilities_.


::: tip
See the _Extending Craft_ [User Permissions](extend/user-permissions.md) page to learn how to register custom permissions from your module or plugin.
:::
Expand Down
2 changes: 1 addition & 1 deletion docs/4.x/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ You can’t create an inactive user from the control panel, but you can deactiva

### Addresses

Users each have an address book. [Addresses](./addresses.md) can be managed on behalf of a User via the control panel, or [by the user themselves](./dev/controller-actions.md#post-users-save-address).
Users each have an address book. [Addresses](./addresses.md) can be managed on behalf of a user via the control panel, or [by the user themselves](./dev/controller-actions.md#post-users-save-address).

## Querying Users

Expand Down

0 comments on commit 00144a8

Please sign in to comment.