Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/entries with category features #11749

Merged
merged 20 commits into from
Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
468486a
Initial work
timkelty Feb 22, 2022
e17daa4
merge in tims initial work
myleshyson Aug 6, 2022
75bb0ca
begin merging in category markup into element selector field.
myleshyson Aug 6, 2022
48868ae
move CategoryInput logic to BaseElementInput. Move CategoriesControll…
myleshyson Aug 7, 2022
75c43f9
move branch limit next to relateAncestors field in settings
myleshyson Aug 7, 2022
3c0f8d0
a little cleanup. give branch limit a default value. remove entry lan…
myleshyson Aug 7, 2022
a0005bf
Merge branch '4.3' of https://github.com/myleshyson/craft into featur…
myleshyson Aug 15, 2022
28aa6be
merge in 4.3. re-run Unknown command: "build"
myleshyson Aug 15, 2022
e7d7be6
fix conflict. also remove inputs from form data for structured elemen…
myleshyson Aug 23, 2022
cc7cffa
Add Craft.ElementFieldSettings module to handle view logic for elemen…
myleshyson Aug 30, 2022
1fe86b9
merge in 4.3 and fix conflict
myleshyson Aug 30, 2022
1a524c0
allow categories to act like entries
myleshyson Aug 30, 2022
1cc6fa1
address formatting errors. disable instructions when disabling relate…
myleshyson Sep 12, 2022
d4bcd3c
add sources validator for when relateAncestors is checked.
myleshyson Sep 12, 2022
c9f4c65
fix indentation
myleshyson Sep 12, 2022
d17cc6f
force relation save when field relates ancestors
myleshyson Sep 12, 2022
1013dbc
sync with 4.3
myleshyson Sep 12, 2022
8228d6b
updated disabled state for relateAncestors instructions
myleshyson Sep 12, 2022
cb550ec
use translation function for model errors. rename structured input ac…
myleshyson Sep 13, 2022
6da08a8
update source validation message
myleshyson Sep 13, 2022
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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions src/controllers/ElementsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,57 @@ public function actionGetElementHtml(): Response
return $this->asJson(compact('html', 'headHtml'));
}

/**
* Returns HTML for the elements field input that has "relateAncestors" set to true,
* based on a given list of selected element ids.
*
* @return Response
* @throws BadRequestHttpException
* @throws ForbiddenHttpException
* @since 4.0.0
*/
public function actionInputHtml(): Response
{
timkelty marked this conversation as resolved.
Show resolved Hide resolved
$this->requireAcceptsJson();

$elementType = $this->request->getRequiredParam('elementType', null);
$elementIds = $this->request->getParam('elementIds', []);

$elements = [];

if (!empty($elementIds)) {
/** @var ElementInterface[] $elements */
$elements = $elementType::find()
->id($elementIds)
->siteId($this->request->getParam('siteId'))
->status(null)
->all();

// Fill in the gaps
$structuresService = Craft::$app->getStructures();
$structuresService->fillGapsInElements($elements);

// Enforce the branch limit
if ($branchLimit = $this->request->getParam('branchLimit')) {
$structuresService->applyBranchLimitToElements($elements, $branchLimit);
}
}

$html = $this->getView()->renderTemplate('_includes/forms/elementselect',
[
'elements' => $elements,
'id' => $this->request->getParam('containerId'),
'name' => $this->request->getParam('name'),
'selectionLabel' => $this->request->getParam('selectionLabel'),
'elementType' => $elementType,
'relateAncestors' => true
]);

return $this->asJson([
'html' => $html,
]);
}

/**
* Returns the requested element, populated with any posted attributes.
*
Expand Down
48 changes: 46 additions & 2 deletions src/fields/BaseRelationField.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ public static function valueType(): string
*/
public bool $showSiteMenu = false;

/**
* @var bool Whether to automatically relate structural ancestors.
*
* @since 4.0.0
*/
public bool $relateAncestors = false;

/**
* @var int|null Branch limit
*
* @since 4.0.0
*/
public ?int $branchLimit = null;

/**
* @var string|null The view mode
*/
Expand Down Expand Up @@ -280,6 +294,9 @@ public function settingsAttributes(): array
$attributes[] = 'targetSiteId';
$attributes[] = 'validateRelatedElements';
$attributes[] = 'viewMode';
$attributes[] = 'allowSelfRelations';
$attributes[] = 'relateAncestors';
$attributes[] = 'branchLimit';

return $attributes;
}
Expand Down Expand Up @@ -361,7 +378,7 @@ public function validateRelationCount(ElementInterface $element): void
*/
public function validateRelatedElements(ElementInterface $element): void
{
// Prevent circular relations from worrying about this entry
// Prevent circular relations from worrying about this element
$sourceId = $element->getCanonicalId();
$sourceValidates = self::$_relatedElementValidates[$sourceId][$element->siteId] ?? null;
self::$_relatedElementValidates[$sourceId][$element->siteId] = true;
Expand Down Expand Up @@ -489,6 +506,27 @@ public function normalizeValue(mixed $value, ?ElementInterface $element = null):
Craft::configure($query, $source['criteria']);
}
}

if ($this->relateAncestors || $this->branchLimit) {
myleshyson marked this conversation as resolved.
Show resolved Hide resolved
$structuresService = Craft::$app->getStructures();

/** @var ElementInterface[] $structureElements */
$structureElements = (clone($query))
->status(null)
->all();

// Fill in any gaps
if ($this->relateAncestors) {
$structuresService->fillGapsInElements($structureElements);
}

// Enforce the branch limit
if ($this->branchLimit) {
$structuresService->applyBranchLimitToElements($structureElements, $this->branchLimit);
}

$query->id(ArrayHelper::getColumn($structureElements, 'id'));
}
} else {
$query->id(false);
}
Expand Down Expand Up @@ -757,6 +795,10 @@ public function getEagerLoadingMap(array $sourceElements): array|null|false
}
}

if ($this->relateAncestors) {
$criteria['orderBy'] = ['structureelements.lft' => SORT_ASC];
}

return [
'elementType' => static::elementType(),
'map' => $map,
Expand Down Expand Up @@ -1065,7 +1107,9 @@ protected function inputTemplateVariables(array|ElementQueryInterface $value = n
'condition' => $this->getSelectionCondition(),
'criteria' => $selectionCriteria,
'showSiteMenu' => ($this->targetSiteId || !$this->showSiteMenu) ? false : 'auto',
'allowSelfRelations' => $this->allowSelfRelations,
'allowSelfRelations' => (bool)$this->allowSelfRelations,
'relateAncestors' => (bool)$this->relateAncestors,
'branchLimit' => (int)$this->branchLimit,
myleshyson marked this conversation as resolved.
Show resolved Hide resolved
'sourceElementId' => !empty($element->id) ? $element->id : null,
'disabledElementIds' => $disabledElementIds,
'limit' => $this->allowLimit ? $this->maxRelations : null,
Expand Down
34 changes: 11 additions & 23 deletions src/fields/Categories.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use craft\base\ElementInterface;
use craft\elements\Category;
use craft\elements\db\CategoryQuery;
use craft\elements\db\ElementQueryInterface;
use craft\gql\arguments\elements\Category as CategoryArguments;
use craft\gql\interfaces\elements\Category as CategoryInterface;
use craft\gql\resolvers\elements\Category as CategoryResolver;
Expand Down Expand Up @@ -74,11 +73,6 @@ public static function valueType(): string
*/
public bool $allowMultipleSources = false;

/**
* @var int|null Branch limit
*/
public ?int $branchLimit = null;

/**
* @inheritdoc
*/
Expand All @@ -87,17 +81,22 @@ public static function valueType(): string
/**
* @inheritdoc
*/
protected string $inputTemplate = '_components/fieldtypes/Categories/input';
protected bool $sortable = false;

/**
* Force relateAncestors to true.
*
* @inheritdoc
* @since 4.0.0
*/
protected ?string $inputJsClass = 'Craft.CategorySelectInput';
public function __construct($config)
{
if (isset($config['relateAncestors'])) {
$config['relateAncestors'] = true;
}

/**
* @inheritdoc
*/
protected bool $sortable = false;
parent::__construct($config);
}
myleshyson marked this conversation as resolved.
Show resolved Hide resolved

/**
* @inheritdoc
Expand Down Expand Up @@ -144,17 +143,6 @@ protected function inputHtml(mixed $value, ?ElementInterface $element = null): s
return parent::inputHtml($value, $element);
}

/**
* @inheritdoc
*/
protected function inputTemplateVariables(array|ElementQueryInterface $value = null, ?ElementInterface $element = null): array
{
$variables = parent::inputTemplateVariables($value, $element);
$variables['branchLimit'] = $this->branchLimit;

return $variables;
}

public function getEagerLoadingMap(array $sourceElements): array|null|false
{
$map = parent::getEagerLoadingMap($sourceElements);
Expand Down
22 changes: 22 additions & 0 deletions src/templates/_components/fieldtypes/elementfieldsettings.twig
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@
}) }}
{% endblock %}

{% block relateAncestors %}
{{ forms.checkboxField({
label: 'Relate ancestors',
instructions: 'Whether structural ancestors of {type} should be added to the selection.'|t('app', { type: pluralElementType }),
id: 'relate-ancestors',
name: 'relateAncestors',
checked: field.relateAncestors
}) }}
{% endblock %}

{% block branchLimitField %}
{{ forms.textField({
label: "Branch Limit"|t('app'),
instructions: "Limit the number of selectable {type} branches."|t('app', { type: elementType }),
id: 'branchLimit',
name: 'branchLimit',
value: field.branchLimit,
size: 2,
errors: field.getErrors('branchLimit')
}) }}
{% endblock %}

{% block advancedSettings %}
<hr>

Expand Down
16 changes: 16 additions & 0 deletions src/templates/_elements/list.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% set elements = elements ?? [] %}
{% set disabled = disabled ?? null %}
{% set viewMode = viewMode ?? null %}

<div class="elements">
{% for element in elements %}
{% set element = include('_elements/element', {
context: 'field',
size: (viewMode == 'large' ? 'large' : 'small')
}) %}
{% if disabled %}
{% set element = element|removeClass('removable') %}
{% endif %}
{{ element|raw }}
{% endfor %}
</div>
19 changes: 19 additions & 0 deletions src/templates/_elements/structurelist.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% set elements = elements ?? [] %}
{% set id = id ?? null %}

<ul class="elements structure">
{% nav element in elements %}
<li id="{{ id }}-element-{{ element.id }}">
{% set indent = (element.level - 1) * 35 %}
<div class="row" style="margin-left: -{{ indent }}px; padding-left: {{ indent }}px;">
{%- include "_elements/element" with { element: element, context: 'field' } -%}
</div>

{% ifchildren %}
<ul>
{% children %}
</ul>
{% endifchildren %}
</li>
{% endnav %}
</ul>
20 changes: 8 additions & 12 deletions src/templates/_includes/forms/elementSelect.twig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
{% set single = single ?? false %}
{% set limit = single ? 1 : (limit ?? null) %}
{% set disabled = (disabled ?? false) ? true : false %}
{% set relateAncestors = relateAncestors ?? false %}

{% set containerAttributes = {
id: id,
Expand All @@ -28,18 +29,11 @@
{% endif %}

{% tag 'div' with containerAttributes %}
<div class="elements">
{% for element in elements %}
{% set element = include('_elements/element', {
context: 'field',
size: (viewMode == 'large' ? 'large' : 'small')
}) %}
{% if disabled %}
{% set element = element|removeClass('removable') %}
{% endif %}
{{ element|raw }}
{% endfor %}
</div>
{% if relateAncestors %}
{{ include('_elements/structurelist', { elements, id })}}
{% else %}
{{ include('_elements/list', { elements, viewMode, disabled }) }}
{% endif %}

<div class="flex flex-nowrap">
{{ tag('button', {
Expand Down Expand Up @@ -72,6 +66,8 @@
condition: condition ? condition.getConfig() : null,
criteria: criteria,
allowSelfRelations: allowSelfRelations ?? false,
relateAncestors: relateAncestors,
branchLimit: branchLimit ?? null,
sourceElementId: sourceElementId,
disabledElementIds: disabledElementIds ?? null,
viewMode: viewMode,
Expand Down
3 changes: 2 additions & 1 deletion src/web/assets/admintable/dist/css/app.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading