Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/group
  • issue/group-3157478
  • issue/group-3084140
  • issue/group-3159277
  • issue/group-3163334
  • issue/group-3166252
  • issue/group-3167443
  • issue/group-3169377
  • issue/group-2797793
  • issue/group-2919982
  • issue/group-3177042
  • issue/group-3177542
  • issue/group-2801603
  • issue/group-3179857
  • issue/group-3052620
  • issue/group-2872645
  • issue/group-3007472
  • issue/group-3162259
  • issue/group-3183791
  • issue/group-3150877
  • issue/group-3185179
  • issue/group-3067811
  • issue/group-3189659
  • issue/group-3190190
  • issue/group-3190306
  • issue/group-2876696
  • issue/group-3118383
  • issue/group-3026735
  • issue/group-3194750
  • issue/group-3197122
  • issue/group-2746839
  • issue/group-3163683
  • issue/group-3201941
  • issue/group-3202091
  • issue/group-3202966
  • issue/group-3202249
  • issue/group-3045373
  • issue/group-3278740
  • issue/group-3209096
  • issue/group-3207064
  • issue/group-3214009
  • issue/group-3166107
  • issue/group-3214895
  • issue/group-2916907
  • issue/group-3220758
  • issue/group-3221785
  • issue/group-3222359
  • issue/group-3222747
  • issue/group-3223957
  • issue/group-2824018
  • issue/group-3226713
  • issue/group-3227793
  • issue/group-3228454
  • issue/group-3229567
  • issue/group-3232851
  • issue/group-3137312
  • issue/group-2295249
  • issue/group-3236626
  • issue/group-3281530
  • issue/group-3202908
  • issue/group-3278778
  • issue/group-3245095
  • issue/group-2972933
  • issue/group-3074933
  • issue/group-3162511
  • issue/group-3253368
  • issue/group-2767155
  • issue/group-2877493
  • issue/group-3254038
  • issue/group-3257227
  • issue/group-3257756
  • issue/group-2717981
  • issue/group-3259178
  • issue/group-3256998
  • issue/group-3204083
  • issue/group-3082125
  • issue/group-3265962
  • issue/group-3266146
  • issue/group-3262923
  • issue/group-3276613
  • issue/group-3005047
  • issue/group-3284402
  • issue/group-3071489
  • issue/group-3061881
  • issue/group-3305051
  • issue/group-2842630
  • issue/group-3301785
  • issue/group-3310499
  • issue/group-3311119
  • issue/group-3307282
  • issue/group-3307291
  • issue/group-2933819
  • issue/group-3310605
  • issue/group-2774729
  • issue/group-3311949
  • issue/group-3313220
  • issue/group-3317459
  • issue/group-3313515
  • issue/group-3315779
  • issue/group-2817109
  • issue/group-3319274
  • issue/group-3325789
  • issue/group-3320513
  • issue/group-3328660
  • issue/group-3210808
  • issue/group-3317396
  • issue/group-3325994
  • issue/group-3322623
  • issue/group-3331923
  • issue/group-3332963
  • issue/group-3112501
  • issue/group-3324506
  • issue/group-3344283
  • issue/group-3180860
  • issue/group-3104345
  • issue/group-3332640
  • issue/group-3354135
  • issue/group-3322761
  • issue/group-3367755
  • issue/group-3406043
  • issue/group-3398778
  • issue/group-3399601
  • issue/group-3406373
  • issue/group-3371637
  • issue/group-3371641
  • issue/group-3371651
  • issue/group-3374041
  • issue/group-3378653
  • issue/group-3364226
  • issue/group-3378977
  • issue/group-3399569
  • issue/group-3336186
  • issue/group-3382559
  • issue/group-3382831
  • issue/group-3016197
  • issue/group-2878723
  • issue/group-3390016
  • issue/group-3268711
  • issue/group-3394724
  • issue/group-3379174
  • issue/group-3397015
  • issue/group-3397021
  • issue/group-3397114
  • issue/group-3399085
  • issue/group-3406840
  • issue/group-3336280
  • issue/group-3409735
  • issue/group-3411381
  • issue/group-3413722
  • issue/group-3414592
  • issue/group-3415695
  • issue/group-3416324
  • issue/group-3421138
  • issue/group-3422253
  • issue/group-3422445
  • issue/group-3423341
  • issue/group-2895988
  • issue/group-3420605
  • issue/group-3424972
  • issue/group-3132084
  • issue/group-3101314
  • issue/group-3425601
  • issue/group-3426007
  • issue/group-3426098
  • issue/group-3426239
  • issue/group-3426408
  • issue/group-3427343
  • issue/group-3397063
  • issue/group-3427547
  • issue/group-3427552
  • issue/group-3428392
  • issue/group-3419405
  • issue/group-3441929
  • issue/group-2774827
  • issue/group-3414708
  • issue/group-2815971
  • issue/group-3441076
  • issue/group-3438400
  • issue/group-3440222
  • issue/group-3409374
  • issue/group-3430826
  • issue/group-3446192
  • issue/group-3137221
  • issue/group-3448221
  • issue/group-3449620
  • issue/group-3449640
  • issue/group-3346626
  • issue/group-3451560
  • issue/group-3437029
  • issue/group-3457095
  • issue/group-3462425
  • issue/group-2929788
  • issue/group-3352235
  • issue/group-3455789
  • issue/group-3467754
  • issue/group-3469835
  • issue/group-3470663
  • issue/group-3036272
  • issue/group-3469890
  • issue/group-3475807
  • issue/group-2907838
  • issue/group-3476539
  • issue/group-3478088
  • issue/group-3475816
  • issue/group-3399452
  • issue/group-3480110
  • issue/group-2754399
  • issue/group-3278936
  • issue/group-3482975
  • issue/group-3421756
  • issue/group-3485785
  • issue/group-3482418
  • issue/group-3490229
  • issue/group-3490670
  • issue/group-3489243
  • issue/group-3493593
  • issue/group-3493597
  • issue/group-3493741
  • issue/group-3493807
  • issue/group-3494447
  • issue/group-3494780
  • issue/group-3494986
  • issue/group-3497467
  • issue/group-3499639
  • issue/group-3494298
  • issue/group-3501018
  • issue/group-3502994
  • issue/group-3504133
  • issue/group-3504805
  • issue/group-3505771
  • issue/group-3506061
  • issue/group-3506097
  • issue/group-3506163
  • issue/group-3507425
  • issue/group-3508876
  • issue/group-3509416
  • issue/group-3509657
  • issue/group-3511625
  • issue/group-3512941
  • issue/group-3511454
  • issue/group-3484817
241 results
Show changes
Commits on Source (90)
Showing
with 710 additions and 556 deletions
# Group-specific terminology.
gnode
grfd
gcfd
gids
# General list of terms.
subconditions
decoratable
# Test cases.
pagefoobarbaz
relationfoobar
relationfoobarbazfoo
bazfoo
# Not copying all comments from template, original found here:
# https://git.drupalcode.org/project/gitlab_templates/-/blob/1.0.x/gitlab-ci/template.gitlab-ci.yml
include:
- project: $_GITLAB_TEMPLATES_REPO
ref: 'main'
file:
- '/includes/include.drupalci.main.yml'
- '/includes/include.drupalci.variables.yml'
- '/includes/include.drupalci.workflows.yml'
variables:
SKIP_ESLINT: '1'
OPT_IN_TEST_MAX_PHP: '1'
OPT_IN_TEST_NEXT_MINOR: '1'
_CURL_TEMPLATES_REF: 'main'
...@@ -17,8 +17,12 @@ ...@@ -17,8 +17,12 @@
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"minimum-stability": "dev", "minimum-stability": "dev",
"require": { "require": {
"drupal/core": "^9 || ^10", "drupal/core": "^10.3 || ^11",
"drupal/entity": "^1.2", "drupal/entity": "^1.2",
"drupal/flexible_permissions": "^1.0" "drupal/flexible_permissions": "^2.0"
},
"require-dev": {
"drupal/variationcache": "^1.5",
"jangregor/phpstan-prophecy": "^1.0"
} }
} }
...@@ -4,9 +4,9 @@ dependencies: ...@@ -4,9 +4,9 @@ dependencies:
module: module:
- 'group' - 'group'
- 'options' - 'options'
id: 'group_content.group_roles' id: 'group_relationship.group_roles'
field_name: 'group_roles' field_name: 'group_roles'
entity_type: 'group_content' entity_type: 'group_relationship'
type: 'entity_reference' type: 'entity_reference'
settings: settings:
target_type: 'group_role' target_type: 'group_role'
......
...@@ -3,13 +3,13 @@ status: true ...@@ -3,13 +3,13 @@ status: true
dependencies: dependencies:
module: module:
- group - group
id: group_content id: group_relationship
label: 'Group relationship' label: 'Group relationship'
type: 'canonical_entities:group_content' type: 'canonical_entities:group_relationship'
pattern: 'group/[group_content:group:id]/[group_content:pretty-path-key]/[group_content:id]' pattern: 'group/[group_relationship:group:id]/[group_relationship:pretty-path-key]/[group_relationship:id]'
selection_criteria: { } selection_criteria: { }
selection_logic: and selection_logic: and
weight: -5 weight: -5
relationships: relationships:
'group_content:langcode:language': 'group_relationship:langcode:language':
label: Language label: Language
...@@ -2,7 +2,7 @@ langcode: en ...@@ -2,7 +2,7 @@ langcode: en
status: true status: true
dependencies: dependencies:
config: config:
- field.storage.group_content.group_roles - field.storage.group_relationship.group_roles
module: module:
- group - group
- user - user
...@@ -13,144 +13,14 @@ description: '' ...@@ -13,144 +13,14 @@ description: ''
tag: '' tag: ''
base_table: group_relationship_field_data base_table: group_relationship_field_data
base_field: id base_field: id
core: 8.x
display: display:
default: default:
display_plugin: default
id: default id: default
display_title: Master display_title: Master
display_plugin: default
position: 0 position: 0
display_options: display_options:
access: title: Members
type: group_permission
options:
group_permission: 'administer members'
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 50
offset: 0
id: 0
total_pages: null
tags:
previous: ‹‹
next: ››
first: '« First'
last: 'Last »'
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
quantity: 9
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: true
caption: ''
summary: ''
description: ''
columns:
name: name
group_roles: group_roles
changed: changed
created: created
view_group_content: view_group_content
edit_group_content: edit_group_content
delete_group_content: delete_group_content
dropbutton: dropbutton
info:
name:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
group_roles:
align: ''
separator: ''
empty_column: false
responsive: ''
changed:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
created:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
view_group_content:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
edit_group_content:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
delete_group_content:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
dropbutton:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: true
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields: fields:
name: name:
id: name id: name
...@@ -159,6 +29,9 @@ display: ...@@ -159,6 +29,9 @@ display:
relationship: gc__user relationship: gc__user
group_type: group group_type: group
admin_label: '' admin_label: ''
entity_type: user
entity_field: name
plugin_id: field
label: User label: User
exclude: false exclude: false
alter: alter:
...@@ -214,16 +87,14 @@ display: ...@@ -214,16 +87,14 @@ display:
multi_type: separator multi_type: separator
separator: ', ' separator: ', '
field_api_classes: false field_api_classes: false
entity_type: user
entity_field: name
plugin_id: field
group_roles: group_roles:
id: group_roles id: group_roles
table: group_content__group_roles table: group_relationship__group_roles
field: group_roles field: group_roles
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
plugin_id: field
label: Roles label: Roles
exclude: false exclude: false
alter: alter:
...@@ -261,7 +132,7 @@ display: ...@@ -261,7 +132,7 @@ display:
element_wrapper_type: '' element_wrapper_type: ''
element_wrapper_class: '' element_wrapper_class: ''
element_default_classes: true element_default_classes: true
empty: '<div class="item-list"><ul><li>&lt;none&gt;</li></ul></div>' empty: None
hide_empty: false hide_empty: false
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
...@@ -279,7 +150,6 @@ display: ...@@ -279,7 +150,6 @@ display:
multi_type: ul multi_type: ul
separator: ', ' separator: ', '
field_api_classes: false field_api_classes: false
plugin_id: field
changed: changed:
id: changed id: changed
table: group_relationship_field_data table: group_relationship_field_data
...@@ -287,6 +157,9 @@ display: ...@@ -287,6 +157,9 @@ display:
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
entity_type: group_relationship
entity_field: changed
plugin_id: field
label: Updated label: Updated
exclude: false exclude: false
alter: alter:
...@@ -344,9 +217,6 @@ display: ...@@ -344,9 +217,6 @@ display:
multi_type: separator multi_type: separator
separator: ', ' separator: ', '
field_api_classes: false field_api_classes: false
entity_type: group_content
entity_field: changed
plugin_id: field
created: created:
id: created id: created
table: group_relationship_field_data table: group_relationship_field_data
...@@ -354,6 +224,9 @@ display: ...@@ -354,6 +224,9 @@ display:
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
entity_type: group_relationship
entity_field: created
plugin_id: field
label: Joined label: Joined
exclude: false exclude: false
alter: alter:
...@@ -411,16 +284,15 @@ display: ...@@ -411,16 +284,15 @@ display:
multi_type: separator multi_type: separator
separator: ', ' separator: ', '
field_api_classes: false field_api_classes: false
entity_type: group_content view_group_relationship:
entity_field: created id: view_group_relationship
plugin_id: field
view_group_content:
id: view_group_content
table: group_relationship table: group_relationship
field: view_group_content field: view_group_relationship
relationship: none relationship: none
group_type: group group_type: group
admin_label: 'View member link' admin_label: 'View member link'
entity_type: group_relationship
plugin_id: entity_link
label: '' label: ''
exclude: true exclude: true
alter: alter:
...@@ -463,17 +335,17 @@ display: ...@@ -463,17 +335,17 @@ display:
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
text: 'View member' text: 'View member'
entity_type: group_content
plugin_id: entity_link
output_url_as_text: false output_url_as_text: false
absolute: false absolute: false
edit_group_content: edit_group_relationship:
id: edit_group_content id: edit_group_relationship
table: group_relationship table: group_relationship
field: edit_group_content field: edit_group_relationship
relationship: none relationship: none
group_type: group group_type: group
admin_label: 'Edit member link' admin_label: 'Edit member link'
entity_type: group_relationship
plugin_id: entity_link_edit
label: '' label: ''
exclude: true exclude: true
alter: alter:
...@@ -516,15 +388,15 @@ display: ...@@ -516,15 +388,15 @@ display:
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
text: 'Edit member' text: 'Edit member'
entity_type: group_content delete_group_relationship:
plugin_id: entity_link_edit id: delete_group_relationship
delete_group_content:
id: delete_group_content
table: group_relationship table: group_relationship
field: delete_group_content field: delete_group_relationship
relationship: none relationship: none
group_type: group group_type: group
admin_label: 'Remove member link' admin_label: 'Remove member link'
entity_type: group_relationship
plugin_id: entity_link_delete
label: '' label: ''
exclude: true exclude: true
alter: alter:
...@@ -567,8 +439,6 @@ display: ...@@ -567,8 +439,6 @@ display:
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
text: 'Remove member' text: 'Remove member'
entity_type: group_content
plugin_id: entity_link_delete
dropbutton: dropbutton:
id: dropbutton id: dropbutton
table: views table: views
...@@ -576,6 +446,7 @@ display: ...@@ -576,6 +446,7 @@ display:
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
plugin_id: dropbutton
label: Operations label: Operations
exclude: false exclude: false
alter: alter:
...@@ -617,20 +488,53 @@ display: ...@@ -617,20 +488,53 @@ display:
hide_empty: false hide_empty: false
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
destination: true
fields: fields:
view_group_content: view_group_content view_group_relationship: view_group_relationship
edit_group_content: edit_group_content edit_group_relationship: edit_group_relationship
delete_group_content: delete_group_content delete_group_relationship: delete_group_relationship
name: '0' name: '0'
group_roles: '0' group_roles: '0'
changed: '0' changed: '0'
created: '0' created: '0'
destination: true pager:
plugin_id: dropbutton type: full
filters: { } options:
sorts: { } offset: 0
header: { } items_per_page: 50
footer: { } total_pages: null
id: 0
tags:
next: ››
previous: ‹‹
first: '« First'
last: 'Last »'
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
quantity: 9
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
access:
type: group_permission
options:
group_permission: 'administer members'
cache:
type: tag
options: { }
empty: empty:
area_text_custom: area_text_custom:
id: area_text_custom id: area_text_custom
...@@ -639,23 +543,11 @@ display: ...@@ -639,23 +543,11 @@ display:
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
plugin_id: text_custom
empty: true empty: true
tokenize: false
content: 'No members available.' content: 'No members available.'
plugin_id: text_custom tokenize: false
relationships: sorts: { }
gc__user:
id: gc__user
table: group_relationship_field_data
field: gc__user
relationship: none
group_type: group
admin_label: 'Member account'
required: true
group_content_plugins:
group_membership: group_membership
entity_type: group_content
plugin_id: group_content_to_entity
arguments: arguments:
gid: gid:
id: gid id: gid
...@@ -664,6 +556,9 @@ display: ...@@ -664,6 +556,9 @@ display:
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
entity_type: group_relationship
entity_field: gid
plugin_id: numeric
default_action: 'access denied' default_action: 'access denied'
exception: exception:
value: all value: all
...@@ -674,12 +569,11 @@ display: ...@@ -674,12 +569,11 @@ display:
default_argument_type: fixed default_argument_type: fixed
default_argument_options: default_argument_options:
argument: '' argument: ''
default_argument_skip_url: false
summary_options: summary_options:
base_path: '' base_path: ''
count: true count: true
items_per_page: 25
override: false override: false
items_per_page: 25
summary: summary:
sort_order: asc sort_order: asc
number_of_records: 0 number_of_records: 0
...@@ -691,11 +585,115 @@ display: ...@@ -691,11 +585,115 @@ display:
validate_options: { } validate_options: { }
break_phrase: false break_phrase: false
not: false not: false
entity_type: group_content filters: { }
entity_field: gid style:
plugin_id: numeric type: table
options:
grouping: { }
row_class: ''
default_row_class: true
columns:
name: name
group_roles: group_roles
changed: changed
created: created
view_group_relationship: view_group_relationship
edit_group_relationship: edit_group_relationship
delete_group_relationship: delete_group_relationship
dropbutton: dropbutton
default: '-1'
info:
name:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
group_roles:
align: ''
separator: ''
empty_column: false
responsive: ''
changed:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
created:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
view_group_relationship:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
edit_group_relationship:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
delete_group_relationship:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
dropbutton:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
override: true
sticky: true
summary: ''
empty_table: true
caption: ''
description: ''
row:
type: fields
options:
default_field_elements: true
inline: { }
separator: ''
hide_empty: false
query:
type: views_query
options:
query_comment: ''
disable_sql_rewrite: false
distinct: false
replica: false
query_tags: { }
relationships:
gc__user:
id: gc__user
table: group_relationship_field_data
field: gc__user
relationship: none
group_type: group
admin_label: 'Member account'
entity_type: group_relationship
plugin_id: group_relationship_to_entity
required: true
group_relation_plugins:
group_membership: group_membership
header: { }
footer: { }
display_extenders: { } display_extenders: { }
title: Members
cache_metadata: cache_metadata:
max-age: -1 max-age: -1
contexts: contexts:
...@@ -706,11 +704,11 @@ display: ...@@ -706,11 +704,11 @@ display:
- url.query_args - url.query_args
- user.group_permissions - user.group_permissions
tags: tags:
- 'config:field.storage.group_content.group_roles' - 'config:field.storage.group_relationship.group_roles'
page_1: page_1:
display_plugin: page
id: page_1 id: page_1
display_title: Page display_title: Page
display_plugin: page
position: 1 position: 1
display_options: display_options:
display_extenders: { } display_extenders: { }
...@@ -719,12 +717,12 @@ display: ...@@ -719,12 +717,12 @@ display:
type: tab type: tab
title: Members title: Members
description: '' description: ''
weight: 20
enabled: true
expanded: false expanded: false
menu_name: main
parent: '' parent: ''
weight: 20
context: '0' context: '0'
menu_name: main
enabled: true
cache_metadata: cache_metadata:
max-age: -1 max-age: -1
contexts: contexts:
...@@ -735,4 +733,4 @@ display: ...@@ -735,4 +733,4 @@ display:
- url.query_args - url.query_args
- user.group_permissions - user.group_permissions
tags: tags:
- 'config:field.storage.group_content.group_roles' - 'config:field.storage.group_relationship.group_roles'
...@@ -82,7 +82,7 @@ group.role.*: ...@@ -82,7 +82,7 @@ group.role.*:
type: 'string' type: 'string'
label: 'Group permission' label: 'Group permission'
group_content_type: group_relationship_type:
type: 'config_entity' type: 'config_entity'
label: 'Group relationship type' label: 'Group relationship type'
mapping: mapping:
...@@ -107,10 +107,10 @@ group_content_type: ...@@ -107,10 +107,10 @@ group_content_type:
sequence: sequence:
type: 'group_relation.config.[%key]' type: 'group_relation.config.[%key]'
# Follows the pattern group.content_type.GROUP_TYPE_ID-PLUGIN_ID. # Follows the pattern group.relationship_type.GROUP_TYPE_ID-PLUGIN_ID.
# Follows the pattern group.content_type.GROUP_TYPE_ID-PLUGIN_ID-DERIVATIVE_ID. # Follows the pattern group.relationship_type.GROUP_TYPE_ID-PLUGIN_ID-DERIVATIVE_ID.
group.content_type.*: group.relationship_type.*:
type: 'group_content_type' type: 'group_relationship_type'
label: 'Group relationship type' label: 'Group relationship type'
entity_reference_selection.group_type:group_role: entity_reference_selection.group_type:group_role:
......
...@@ -26,21 +26,21 @@ views.argument_default.group_id_from_url: ...@@ -26,21 +26,21 @@ views.argument_default.group_id_from_url:
views_relationship_with_group_plugin_filter: views_relationship_with_group_plugin_filter:
type: 'views_relationship' type: 'views_relationship'
mapping: mapping:
group_content_plugins: group_relation_plugins:
type: 'sequence' type: 'sequence'
label: 'Group relation plugins' label: 'Group relation plugins'
sequence: sequence:
type: 'string' type: 'string'
label: 'Group relation plugin ID' label: 'Group relation plugin ID'
views.relationship.group_content_to_entity: views.relationship.group_relationship_to_entity:
type: 'views_relationship_with_group_plugin_filter' type: 'views_relationship_with_group_plugin_filter'
label: 'Group relationship to entity reference' label: 'Group relationship to entity reference'
views.relationship.group_content_to_entity_reverse: views.relationship.group_relationship_to_entity_reverse:
type: 'views_relationship_with_group_plugin_filter' type: 'views_relationship_with_group_plugin_filter'
label: 'Reverse group relationship to entity reference' label: 'Reverse group relationship to entity reference'
views.relationship.group_to_group_content: views.relationship.group_to_group_relationship:
type: 'views_relationship_with_group_plugin_filter' type: 'views_relationship_with_group_plugin_filter'
label: 'Group to group relationship' label: 'Group to group relationship'
...@@ -4,20 +4,20 @@ ...@@ -4,20 +4,20 @@
/* Permissions page */ /* Permissions page */
.permissions .module { .permissions .module {
font-weight: bold; font-weight: bold;
} }
.permissions .section { .permissions .section {
font-style: italic; padding-left: 1.5em; /* LTR */
padding-left: 1.5em; /* LTR */ font-style: italic;
} }
[dir="rtl"] .permissions .section { [dir="rtl"] .permissions .section {
padding-left: 0; padding-right: 1.5em;
padding-right: 1.5em; padding-left: 0;
} }
.permissions .permission { .permissions .permission {
padding-left: 2.5em; /* LTR */ padding-left: 2.5em; /* LTR */
} }
[dir="rtl"] .permissions .permission { [dir="rtl"] .permissions .permission {
padding-left: 0; padding-right: 2.5em;
padding-right: 2.5em; padding-left: 0;
} }
/** /**
* Main menu icons. * Main menu icons.
*/ */
.toolbar-icon-system-admin-group:before { .toolbar-icon-system-admin-group::before {
background-image: url(../images/icons/787878/toolbar.svg); background-image: url(../images/icons/787878/toolbar.svg);
} }
.toolbar-icon-system-admin-group:active:before, .toolbar-icon-system-admin-group:active::before,
.toolbar-icon-system-admin-group.is-active:before { .toolbar-icon-system-admin-group.is-active::before {
background-image: url(../images/icons/000000/toolbar.svg); background-image: url(../images/icons/000000/toolbar.svg);
} }
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
* Hooks specific to the Group module. * Hooks specific to the Group module.
*/ */
use Drupal\Core\Session\AccountInterface;
use Drupal\group\Entity\GroupInterface; use Drupal\group\Entity\GroupInterface;
/** /**
...@@ -18,7 +17,7 @@ use Drupal\group\Entity\GroupInterface; ...@@ -18,7 +17,7 @@ use Drupal\group\Entity\GroupInterface;
* *
* @param array $operations * @param array $operations
* A list of links to be set in an 'operations' element. * A list of links to be set in an 'operations' element.
* @param GroupInterface $group * @param \Drupal\group\Entity\GroupInterface $group
* The group to alter the operations for. * The group to alter the operations for.
* *
* @see \Drupal\group\Plugin\Block\GroupOperationsBlock * @see \Drupal\group\Plugin\Block\GroupOperationsBlock
......
...@@ -2,7 +2,7 @@ name: 'Group' ...@@ -2,7 +2,7 @@ name: 'Group'
description: 'Allows you to group users, content and other entities' description: 'Allows you to group users, content and other entities'
package: 'Group' package: 'Group'
type: 'module' type: 'module'
core_version_requirement: ^9 || ^10 core_version_requirement: ^10.3 || ^11
configure: 'group.settings' configure: 'group.settings'
dependencies: dependencies:
- 'drupal:options' - 'drupal:options'
......
...@@ -5,268 +5,340 @@ ...@@ -5,268 +5,340 @@
* Install, update and uninstall functions for the group module. * Install, update and uninstall functions for the group module.
*/ */
use Drupal\Core\Config\Entity\Query\QueryFactory;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface; use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\group\Entity\GroupRelationship; use Drupal\field\FieldStorageConfigInterface;
use Drupal\group\Entity\GroupRelationshipType;
use Drupal\group\Entity\GroupTypeInterface;
use Drupal\group\PermissionScopeInterface;
use Drupal\user\RoleInterface;
/** /**
* Implements hook_update_last_removed(). * Implements hook_update_last_removed().
*/ */
function group_update_last_removed() { function group_update_last_removed() {
return 8023; return 9210;
} }
/** /**
* Update class name and handler class names for group_content_type. * Updates database and fields from Group 2 to Group 3.
*/ */
function group_update_9201() { function group_update_10300(&$sandbox) {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager(); $state = \Drupal::state();
$config_factory = \Drupal::configFactory();
// Update the class name and handlers for group_content_type. $group_content_type_configs = $config_factory->listAll('group.content_type.');
$new_handlers = \Drupal::entityTypeManager()->getDefinition('group_content_type')->getHandlerClasses();
$entity_type = $definition_update_manager->getEntityType('group_content_type');
$entity_type->setClass(GroupRelationshipType::class);
$entity_type->set('handlers', $new_handlers);
$definition_update_manager->updateEntityType($entity_type);
}
/** // Short-circuit the following updates if we are already on version 3.
* Update class name and handler class names for group_content. if (empty($group_content_type_configs)) {
*/ $state->set('group_update_10300_detected_legacy_version', FALSE);
function group_update_9202() { return t('Module was already on v3, skipping upgrade path.');
$definition_update_manager = \Drupal::entityDefinitionUpdateManager(); }
$last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository'); $state->set('group_update_10300_detected_legacy_version', TRUE);
assert($last_installed_schema_repository instanceof EntityLastInstalledSchemaRepositoryInterface);
// Update the class name and handlers for group_content. $table_mapping = \Drupal::entityTypeManager()->getStorage('group_relationship')->getTableMapping();
$new_handlers = \Drupal::entityTypeManager()->getDefinition('group_content')->getHandlerClasses(); assert($table_mapping instanceof DefaultTableMapping);
$entity_type = $definition_update_manager->getEntityType('group_content');
$entity_type->setClass(GroupRelationship::class);
$entity_type->set('handlers', $new_handlers);
// Instead of using the entity definition update manager, we immediately write
// these changes as they would otherwise trigger a data migration and choke on
// the fact that the old storage class no longer exists.
$last_installed_schema_repository->setLastInstalledDefinition($entity_type);
}
/**
* Update group_content DB table, fields and indexes.
*/
function group_update_9203(&$sandbox) {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository'); $last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
assert($last_installed_schema_repository instanceof EntityLastInstalledSchemaRepositoryInterface); assert($last_installed_schema_repository instanceof EntityLastInstalledSchemaRepositoryInterface);
// Update the database tables. $installed_storage_schema = \Drupal::keyValue('entity.storage_schema.sql');
$entity_type = $definition_update_manager->getEntityType('group_content'); $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$entity_type->set('base_table', 'group_relationship');
$entity_type->set('data_table', 'group_relationship_field_data');
// Add the plugin_id and group_type field. // Update field storages and DB tables that were created for group_content.
$field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions('group_content'); $field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions('group_content');
$field_storage_definitions['plugin_id'] = BaseFieldDefinition::create('string') foreach ($field_storage_definitions as $fsd) {
->setName('plugin_id') if ($fsd instanceof BaseFieldDefinition) {
->setTargetEntityTypeId('group_content') $fsd->setTargetEntityTypeId('group_relationship');
->setTargetBundle(NULL) $schema = $installed_storage_schema->get('group_content.field_schema_data.' . $fsd->getName());
->setLabel(t('Plugin ID')) $installed_storage_schema->set('group_relationship.field_schema_data.' . $fsd->getName(), $schema);
->setRequired(TRUE) }
->setReadOnly(TRUE) elseif ($fsd instanceof FieldStorageConfigInterface) {
->setInitialValue('TEMP') if ($requires_storage = $table_mapping->requiresDedicatedTableStorage($fsd)) {
->setProvider('group'); $old_table = $table_mapping->getDedicatedDataTableName($fsd);
}
$field_storage_definitions['group_type'] = BaseFieldDefinition::create('entity_reference')
->setName('group_type')
->setTargetEntityTypeId('group_content')
->setTargetBundle(NULL)
->setLabel(t('Group type'))
->setSetting('target_type', 'group_type')
->setRequired(TRUE)
->setReadOnly(TRUE)
->setInitialValue('TEMP')
->setProvider('group');
// Update the fields and regenerate indexes, the correct initial values will
// be retrieved from GroupRelationshipStorage::restore().
$definition_update_manager->updateFieldableEntityType($entity_type, $field_storage_definitions, $sandbox);
}
/** $old_id = $fsd->id();
* Remove the 'bypass group access' permission from all roles. $new_id = str_replace('group_content.', 'group_relationship.', $fsd->id());
*/
function group_update_9204() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory->listAll('user.role.') as $config_name) {
$role = $config_factory->getEditable($config_name);
$role->set('permissions', array_values(array_diff($role->get('permissions'), ['bypass group access'])));
$role->save(TRUE);
}
}
/** $old_config = $config_factory->getEditable('field.storage.' . $old_id);
* Convert group roles with the 'administer group' permission to admin roles. $new_config = $config_factory->getEditable('field.storage.' . $new_id);
*/ $new_config->setData($old_config->getRawData());
function group_update_9205() { $new_config->set('entity_type', 'group_relationship');
$config_factory = \Drupal::configFactory(); $new_config->set('id', $new_id);
foreach ($config_factory->listAll('group.role.') as $config_name) { $new_config->save(TRUE);
$role = $config_factory->getEditable($config_name); $old_config->delete();
if (in_array('administer group', $role->get('permissions'), TRUE)) {
$role->set('permissions', []); $fsd->set('entity_type', 'group_relationship');
$role->set('admin', TRUE); $fsd->set('id', $new_id);
if ($requires_storage) {
$new_table = $table_mapping->getDedicatedDataTableName($fsd);
\Drupal::database()->schema()->renameTable($old_table, $new_table);
}
} }
else { else {
$role->set('admin', FALSE); throw new \Exception('Found a group_content field we could not move to group_relationship.');
} }
$role->save(TRUE);
}
}
/** $last_installed_schema_repository->setLastInstalledFieldStorageDefinition($fsd);
* Convert synchronized group roles to new scope and target_role structure. }
*/
function group_update_9206() {
$config_factory = \Drupal::configFactory();
$synchronized_role_ids = []; // Update entity references that were pointing to group_content.
foreach ($config_factory->listAll('user.role.') as $role_config_name) { foreach ($last_installed_schema_repository->getLastInstalledDefinitions() as $entity_type) {
$role_id = $config_factory->get($role_config_name)->get('id'); $field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions($entity_type->id());
foreach ($field_storage_definitions as $fsd) {
if ($fsd->getType() !== 'entity_reference') {
continue;
}
if ($fsd->getSetting('target_type') !== 'group_content') {
continue;
}
if ($fsd instanceof BaseFieldDefinition) {
// @todo Throw a warning saying a base or bundle field has changed and needs updating in code.
}
elseif ($fsd instanceof FieldStorageConfigInterface) {
$config = $config_factory->getEditable('field.storage.' . $fsd->id());
$settings = $config->get('settings');
$settings['target_type'] = 'group_relationship';
$config->set('settings', $settings);
$config->save(TRUE);
}
else {
throw new \Exception('Found an entity_reference field storage definition we could not alter the settings for.');
}
// We never synced any roles to anonymous or authenticated. $fsd->setSetting('target_type', 'group_relationship');
if ($role_id === RoleInterface::ANONYMOUS_ID || $role_id === RoleInterface::AUTHENTICATED_ID) { $last_installed_schema_repository->setLastInstalledFieldStorageDefinition($fsd);
continue;
} }
$synchronized_role_ids[] = $role_id;
} }
// Nothing to update if we had no user defined global roles. // Update all group_content_type entities to become group_relationship_type.
if (empty($synchronized_role_ids)) { foreach ($group_content_type_configs as $old_id) {
return; $new_id = str_replace('group.content_type.', 'group.relationship_type.', $old_id);
$old_config = $config_factory->getEditable($old_id);
$new_config = $config_factory->getEditable($new_id);
$new_config->setData($old_config->getRawData());
$new_config->save(TRUE);
$old_config->delete();
} }
foreach ($config_factory->listAll('group.type.') as $group_type_config_name) { // Delete the old config key store for QueryFactory.
$group_type_id = $config_factory->get($group_type_config_name)->get('id'); \Drupal::keyValue(QueryFactory::CONFIG_LOOKUP_PREFIX . 'group_content_type')->deleteAll();
// Update field instances on group_content entities.
foreach ($config_factory->listAll('field.field.group_content.') as $old_name) {
$old_config = $config_factory->getEditable($old_name);
$new_name = str_replace('group_content.', 'group_relationship.', $old_name);
$new_id = str_replace('group_content.', 'group_relationship.', $old_config->get('id'));
$new_config = $config_factory->getEditable($new_name);
$new_config->setData($old_config->getRawData());
$new_config->set('entity_type', 'group_relationship');
$new_config->set('id', $new_id);
if ($dependencies = $new_config->get('dependencies')) {
if (!empty($dependencies['config'])) {
$dependencies['config'] = array_map(function ($dependency_name) {
$search = [
'group.content_type.',
'field.storage.group_content.',
];
$replace = [
'group.relationship_type.',
'field.storage.group_relationship.',
];
return str_replace($search, $replace, $dependency_name);
}, $dependencies['config']);
$new_config->set('dependencies', $dependencies);
}
}
foreach ($synchronized_role_ids as $role_id) { $new_config->save(TRUE);
// Copied the group role ID logic directly from the GroupRoleSynchronizer $old_config->delete();
// class because that class has been removed in favor of the new roles. }
$machine_name_max_length = EntityTypeInterface::ID_MAX_LENGTH - GroupTypeInterface::ID_MAX_LENGTH - 1;
$machine_name = substr(md5('group_role_sync.' . $role_id), 0, $machine_name_max_length);
$group_role_id = "$group_type_id-$machine_name";
// Delete the synchronized role if they had no rights. // The bundle field map is only updated when using the update manager.
$group_role = $config_factory->getEditable('group.role.' . $group_role_id); // See \Drupal\Core\Entity\EntityFieldManager::getFieldMap() for more info on
if (!$group_role->get('admin') && empty($group_role->get('permissions'))) { // how the key value collection is used for this purpose.
$group_role->delete(); $bundle_field_map_store = \Drupal::keyValue('entity.definitions.bundle_field_map');
} $bundle_field_map = $bundle_field_map_store->get('group_content');
// Otherwise update the group role to use the new keys. $bundle_field_map_store->set('group_relationship', $bundle_field_map);
else { $bundle_field_map_store->delete('group_content');
$group_role->set('scope', PermissionScopeInterface::OUTSIDER_ID);
$group_role->set('global_role', $role_id); // Update form and view modes for changed instances.
foreach (['entity_form_display', 'entity_view_display'] as $display_key) {
// Clear the old keys and save. foreach ($config_factory->listAll("core.$display_key.group_content.") as $old_name) {
$group_role->clear('permissions_ui'); $old_config = $config_factory->getEditable($old_name);
$group_role->clear('internal');
$group_role->clear('audience'); $new_name = str_replace('group_content.', 'group_relationship.', $old_name);
$group_role->save(TRUE); $new_id = str_replace('group_content.', 'group_relationship.', $old_config->get('id'));
$new_config = $config_factory->getEditable($new_name);
$new_config->setData($old_config->getRawData());
$new_config->set('targetEntityType', 'group_relationship');
$new_config->set('id', $new_id);
if ($dependencies = $new_config->get('dependencies')) {
if (!empty($dependencies['config'])) {
$dependencies['config'] = array_map(function ($dependency_name) {
$search = [
'group.content_type.',
'field.storage.group_content.',
'field.field.group_content.',
];
$replace = [
'group.relationship_type.',
'field.storage.group_relationship.',
'field.field.group_relationship.',
];
return str_replace($search, $replace, $dependency_name);
}, $dependencies['config']);
$new_config->set('dependencies', $dependencies);
}
} }
$new_config->save(TRUE);
$old_config->delete();
} }
} }
// Update the entity type definitions directly so the DB is left untouched.
$definition = $last_installed_schema_repository->getLastInstalledDefinition('group_content_type');
$definition->set('id', 'group_relationship_type');
$definition->set('config_prefix', 'relationship_type');
$definition->set('bundle_of', 'group_content');
$last_installed_schema_repository->setLastInstalledDefinition($definition);
$definition_update_manager->updateEntityType($definition);
$definition = $last_installed_schema_repository->getLastInstalledDefinition('group_content');
$definition->set('id', 'group_relationship');
$definition->set('bundle_entity_type', 'group_relationship_type');
$definition->set('field_ui_base_route', 'entity.group_relationship_type.edit_form');
$last_installed_schema_repository->setLastInstalledDefinition($definition);
$definition_update_manager->updateEntityType($definition);
$last_installed_schema_repository->deleteLastInstalledDefinition('group_content');
$last_installed_schema_repository->deleteLastInstalledDefinition('group_content_type');
}
/**
* Updates indexes from Group 2 to Group 3.
*/
function group_update_10301(&$sandbox) {
// Short-circuit the update if we are already on version 3.
if (!\Drupal::state()->get('group_update_10300_detected_legacy_version', FALSE)) {
return t('Module was already on v3, skipping upgrade path.');
}
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
assert($last_installed_schema_repository instanceof EntityLastInstalledSchemaRepositoryInterface);
$field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions('group_relationship');
$entity_type = $last_installed_schema_repository->getLastInstalledDefinition('group_relationship');
$definition_update_manager->updateFieldableEntityType($entity_type, $field_storage_definitions, $sandbox);
} }
/** /**
* Convert default group roles to new scope and target_role structure. * Updates views from Group 2 to Group 3.
*/ */
function group_update_9207() { function group_update_10302(&$sandbox) {
// Short-circuit the update if we are already on version 3.
if (!\Drupal::state()->get('group_update_10300_detected_legacy_version', FALSE)) {
return t('Module was already on v3, skipping upgrade path.');
}
$config_factory = \Drupal::configFactory(); $config_factory = \Drupal::configFactory();
$group_role_info = [ if (\Drupal::moduleHandler()->moduleExists('views')) {
'anonymous' => [ foreach ($config_factory->listAll('views.view.') as $view_name) {
'scope' => PermissionScopeInterface::OUTSIDER_ID, $view = $config_factory->getEditable($view_name);
'global_role' => RoleInterface::ANONYMOUS_ID, $view->setData(_group_update_view_with_a_bazooka($view->getRawData()))->save(TRUE);
], $view->save(TRUE);
'outsider' => [
'scope' => PermissionScopeInterface::OUTSIDER_ID,
'global_role' => RoleInterface::AUTHENTICATED_ID,
],
'member' => [
'scope' => PermissionScopeInterface::INSIDER_ID,
'global_role' => RoleInterface::AUTHENTICATED_ID,
],
];
// Update anonymous, outsider and member.
foreach ($config_factory->listAll('group.type.') as $group_type_config_name) {
$group_type_id = $config_factory->get($group_type_config_name)->get('id');
foreach ($group_role_info as $group_role_suffix => $info) {
$group_role_id = "$group_type_id-$group_role_suffix";
// We do not delete the default roles, even if they have no rights.
$group_role = $config_factory->getEditable('group.role.' . $group_role_id);
$group_role->set('scope', $info['scope']);
$group_role->set('global_role', $info['global_role']);
// Clear the old keys and save.
$group_role->clear('permissions_ui');
$group_role->clear('internal');
$group_role->clear('audience');
$group_role->save(TRUE);
} }
} }
} }
/** /**
* Convert user created group roles to new scope and target_role structure. * Replaces ALL mention of group_content in a Views view's data.
*
* This is a radical approach in that it makes no assumptions other than any
* mention of group_content on Group v3 or up being wrong and needing
* replacement with group_relationship. Which explains the function name.
*
* @param array $data
* The view data to fire the bazooka at.
*
* @return array
* The data with all replacements made.
*/ */
function group_update_9208() { function _group_update_view_with_a_bazooka(array $data): array {
$config_factory = \Drupal::configFactory(); $search = ['group_content_plugins', 'group.content_type.', 'group_content'];
$replace = ['group_relation_plugins', 'group.relationship_type.', 'group_relationship'];
foreach ($config_factory->listAll('group.role.') as $config_name) { // As we loop over every item in the array, we fill a new one so that order
// Now that we've updated synchronized and default roles, any role that // of keys is preserved even if we change the key name.
// still has the old properties is a user generated one. So skip the rest. $new_data = [];
if (empty($config_factory->get($config_name)->get('audience'))) {
continue; foreach ($data as $key => $value) {
$new_key = str_replace($search, $replace, $key);
if (is_string($value)) {
$new_data[$new_key] = str_replace($search, $replace, $value);
}
elseif (is_array($value)) {
$new_data[$new_key] = _group_update_view_with_a_bazooka($value);
}
else {
$new_data[$new_key] = $value;
} }
}
// We do not delete the user created roles, even if they have no rights. return $new_data;
$group_role = $config_factory->getEditable($config_name); }
$group_role->set('scope', PermissionScopeInterface::INDIVIDUAL_ID);
// Clear the old keys and save. /**
$group_role->clear('permissions_ui'); * Updates views to drop obsolete key.
$group_role->clear('internal'); */
$group_role->clear('audience'); function group_update_10303(&$sandbox) {
$group_role->save(TRUE); if (\Drupal::moduleHandler()->moduleExists('views')) {
$view = \Drupal::configFactory()->getEditable('views.view.group_members');
if (!$view->isNew()) {
$view->clear('display.default.display_options.arguments.gid.default_argument_skip_url');
$view->save(TRUE);
}
} }
} }
/** /**
* Remove label and description from relationship types. * Make state key for tracking if we came from version 2 clearly defined.
*/ */
function group_update_9209() { function group_update_10304(&$sandbox) {
$config_factory = \Drupal::configFactory(); $state = \Drupal::state();
foreach ($config_factory->listAll('group.content_type.') as $config_name) { // Previous updates ran with new state entry, do nothing.
$relationship_type = $config_factory->getEditable($config_name); if (!is_null($state->get('group_update_10300_detected_legacy_version'))) {
$relationship_type->clear('label'); return t('State key was properly set before, skipping update.');
$relationship_type->clear('description');
$relationship_type->save(TRUE);
} }
// Previous updates ran with old state entry, convert to new state entry.
$old_value = (bool) $state->get('group_update_10300_detected_version', FALSE);
$state->set('group_update_10300_detected_legacy_version', !$old_value);
$state->delete('group_update_10300_detected_version');
} }
/** /**
* Introduce the group_config_wrapper entity type. * Upgrade group_relationship type ER field.
*/ */
function group_update_9210() { function group_update_10305(&$sandbox) {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager(); // Short-circuit the update if we are already on version 3.
if (!$definition_update_manager->getEntityType('group_config_wrapper')) { if (!\Drupal::state()->get('group_update_10300_detected_legacy_version', FALSE)) {
$entity_type = \Drupal::entityTypeManager()->getDefinition('group_config_wrapper'); return t('Module was already on v3, skipping upgrade path.');
$definition_update_manager->installEntityType($entity_type);
} }
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$field_storage_definition = $definition_update_manager->getFieldStorageDefinition('type', 'group_relationship');
assert($field_storage_definition instanceof BaseFieldDefinition);
$field_storage_definition->setSetting('target_type', 'group_relationship_type');
$definition_update_manager->updateFieldStorageDefinition($field_storage_definition);
} }
...@@ -17,7 +17,7 @@ group.add_group_role: ...@@ -17,7 +17,7 @@ group.add_group_role:
- 'entity.group_role.collection' - 'entity.group_role.collection'
group.add_member: group.add_member:
route_name: 'entity.group_content.add_form' route_name: 'entity.group_relationship.add_form'
route_parameters: route_parameters:
plugin_id: 'group_membership' plugin_id: 'group_membership'
class: '\Drupal\group\Plugin\Menu\LocalAction\WithDestination' class: '\Drupal\group\Plugin\Menu\LocalAction\WithDestination'
...@@ -25,14 +25,14 @@ group.add_member: ...@@ -25,14 +25,14 @@ group.add_member:
appears_on: appears_on:
- 'view.group_members.page_1' - 'view.group_members.page_1'
group_content.add_page: group_relationship.add_page:
route_name: 'entity.group_content.add_page' route_name: 'entity.group_relationship.add_page'
title: 'Add existing entity' title: 'Add existing entity'
appears_on: appears_on:
- 'entity.group_content.collection' - 'entity.group_relationship.collection'
group_content.create_page: group_relationship.create_page:
route_name: 'entity.group_content.create_page' route_name: 'entity.group_relationship.create_page'
title: 'Add new entity' title: 'Add new entity'
appears_on: appears_on:
- 'entity.group_content.collection' - 'entity.group_relationship.collection'
...@@ -38,15 +38,9 @@ group.delete_form: ...@@ -38,15 +38,9 @@ group.delete_form:
group.content: group.content:
title: 'All entities' title: 'All entities'
base_route: 'entity.group.canonical' base_route: 'entity.group.canonical'
route_name: 'entity.group_content.collection' route_name: 'entity.group_relationship.collection'
weight: 15 weight: 15
group.version_history:
title: 'Revisions'
base_route: 'entity.group.canonical'
route_name: 'entity.group.version_history'
weight: 20
group_type.edit_form: group_type.edit_form:
title: 'Edit' title: 'Edit'
base_route: 'entity.group_type.edit_form' base_route: 'entity.group_type.edit_form'
...@@ -71,10 +65,10 @@ group_type.content_plugins: ...@@ -71,10 +65,10 @@ group_type.content_plugins:
route_name: 'entity.group_type.content_plugins' route_name: 'entity.group_type.content_plugins'
weight: 25 weight: 25
group_content_type.edit_form: group_relationship_type.edit_form:
title: 'Configure' title: 'Configure'
base_route: 'entity.group_content_type.edit_form' base_route: 'entity.group_relationship_type.edit_form'
route_name: 'entity.group_content_type.edit_form' route_name: 'entity.group_relationship_type.edit_form'
weight: 0 weight: 0
group_role.edit_form: group_role.edit_form:
...@@ -95,20 +89,20 @@ group_role.permissions_form: ...@@ -95,20 +89,20 @@ group_role.permissions_form:
base_route: 'entity.group_role.edit_form' base_route: 'entity.group_role.edit_form'
weight: 10 weight: 10
group_content.view: group_relationship.view:
title: 'View' title: 'View'
base_route: 'entity.group_content.canonical' base_route: 'entity.group_relationship.canonical'
route_name: 'entity.group_content.canonical' route_name: 'entity.group_relationship.canonical'
weight: 0 weight: 0
group_content.edit: group_relationship.edit:
title: 'Edit' title: 'Edit'
base_route: 'entity.group_content.canonical' base_route: 'entity.group_relationship.canonical'
route_name: 'entity.group_content.edit_form' route_name: 'entity.group_relationship.edit_form'
weight: 5 weight: 5
group_content.delete: group_relationship.delete:
title: 'Remove' title: 'Remove'
base_route: 'entity.group_content.canonical' base_route: 'entity.group_relationship.canonical'
route_name: 'entity.group_content.delete_form' route_name: 'entity.group_relationship.delete_form'
weight: 10 weight: 10
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Html;
use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\FieldItemListInterface;
...@@ -16,14 +18,14 @@ use Drupal\Core\Form\FormStateInterface; ...@@ -16,14 +18,14 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element; use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\group\Entity\GroupRelationshipInterface;
use Drupal\group\Entity\GroupInterface; use Drupal\group\Entity\GroupInterface;
use Drupal\group\Entity\GroupRelationshipInterface;
use Drupal\group\Entity\Storage\ConfigWrapperStorageInterface; use Drupal\group\Entity\Storage\ConfigWrapperStorageInterface;
use Drupal\group\Entity\Storage\GroupRelationshipStorageInterface; use Drupal\group\Entity\Storage\GroupRelationshipStorageInterface;
use Drupal\group\Entity\Storage\GroupRoleStorageInterface; use Drupal\group\Entity\Storage\GroupRoleStorageInterface;
use Drupal\group\QueryAccess\EntityQueryAlter; use Drupal\group\QueryAccess\EntityQueryAlter;
use Drupal\group\QueryAccess\GroupRelationshipQueryAlter;
use Drupal\group\QueryAccess\GroupQueryAlter; use Drupal\group\QueryAccess\GroupQueryAlter;
use Drupal\group\QueryAccess\GroupRelationshipQueryAlter;
use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\Plugin\views\query\Sql; use Drupal\views\Plugin\views\query\Sql;
use Drupal\views\ViewExecutable; use Drupal\views\ViewExecutable;
...@@ -118,7 +120,7 @@ function group_theme() { ...@@ -118,7 +120,7 @@ function group_theme() {
'group' => [ 'group' => [
'render element' => 'elements', 'render element' => 'elements',
], ],
'group_content' => [ 'group_relationship' => [
'render element' => 'elements', 'render element' => 'elements',
], ],
]; ];
...@@ -147,20 +149,20 @@ function group_theme_suggestions_group(array $variables) { ...@@ -147,20 +149,20 @@ function group_theme_suggestions_group(array $variables) {
/** /**
* Implements hook_theme_suggestions_HOOK(). * Implements hook_theme_suggestions_HOOK().
*/ */
function group_theme_suggestions_group_content(array $variables) { function group_theme_suggestions_group_relationship(array $variables) {
$suggestions = []; $suggestions = [];
$group_relationship = $variables['elements']['#group_content']; $group_relationship = $variables['elements']['#group_relationship'];
assert($group_relationship instanceof GroupRelationshipInterface); assert($group_relationship instanceof GroupRelationshipInterface);
$sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_'); $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
$sanitized_bundle = strtr($group_relationship->bundle(), '-', '_'); $sanitized_bundle = strtr($group_relationship->bundle(), '-', '_');
$suggestions[] = 'group_content__' . $sanitized_view_mode; $suggestions[] = 'group_relationship__' . $sanitized_view_mode;
$suggestions[] = 'group_content__' . $sanitized_bundle; $suggestions[] = 'group_relationship__' . $sanitized_bundle;
$suggestions[] = 'group_content__' . $sanitized_bundle . '__' . $sanitized_view_mode; $suggestions[] = 'group_relationship__' . $sanitized_bundle . '__' . $sanitized_view_mode;
$suggestions[] = 'group_content__' . $group_relationship->id(); $suggestions[] = 'group_relationship__' . $group_relationship->id();
$suggestions[] = 'group_content__' . $group_relationship->id() . '__' . $sanitized_view_mode; $suggestions[] = 'group_relationship__' . $group_relationship->id() . '__' . $sanitized_view_mode;
return $suggestions; return $suggestions;
} }
...@@ -168,7 +170,7 @@ function group_theme_suggestions_group_content(array $variables) { ...@@ -168,7 +170,7 @@ function group_theme_suggestions_group_content(array $variables) {
/** /**
* Prepares variables for the group template. * Prepares variables for the group template.
* *
* Default template: group.html.twig * Default template: group.html.twig.
* *
* @param array $variables * @param array $variables
* - elements: An array of elements to display in view mode. * - elements: An array of elements to display in view mode.
...@@ -182,19 +184,26 @@ function template_preprocess_group(&$variables) { ...@@ -182,19 +184,26 @@ function template_preprocess_group(&$variables) {
$variables['group'] = $group; $variables['group'] = $group;
$variables['view_mode'] = $variables['elements']['#view_mode']; $variables['view_mode'] = $variables['elements']['#view_mode'];
$variables['label'] = $group->label(); $variables['label'] = $group->label();
$variables['url'] = $group->toUrl('canonical', ['language' => $group->language()]);
$variables['attributes']['class'][] = 'group'; $variables['attributes']['class'][] = 'group';
$variables['attributes']['class'][] = Html::cleanCssIdentifier('group--' . $variables['view_mode']); $variables['attributes']['class'][] = Html::cleanCssIdentifier('group--' . $variables['view_mode']);
$variables['attributes']['class'][] = Html::cleanCssIdentifier('group--' . $variables['group']->bundle()); $variables['attributes']['class'][] = Html::cleanCssIdentifier('group--' . $variables['group']->bundle());
// See if we are rendering the group at its canonical route. // Set variables that depend on the group being saved.
$route_match = \Drupal::routeMatch(); $variables['url'] = '';
if ($route_match->getRouteName() == 'entity.group.canonical') { $variables['page'] = FALSE;
$page_group = $route_match->getParameter('group');
if (!$group->isNew()) {
$variables['url'] = $group->toUrl('canonical', ['language' => $group->language()]);
// See if we are rendering the group at its canonical route.
$route_match = \Drupal::routeMatch();
if ($route_match->getRouteName() == 'entity.group.canonical') {
$page_group = $route_match->getParameter('group');
}
$is_page = !empty($page_group) && $page_group->id() == $group->id();
$variables['page'] = $variables['view_mode'] == 'full' && $is_page;
} }
$is_page = (!empty($page_group) ? $page_group->id() == $group->id() : FALSE);
$variables['page'] = $variables['view_mode'] == 'full' && $is_page;
// Helpful $content variable for templates. // Helpful $content variable for templates.
$variables += ['content' => []]; $variables += ['content' => []];
...@@ -206,18 +215,18 @@ function template_preprocess_group(&$variables) { ...@@ -206,18 +215,18 @@ function template_preprocess_group(&$variables) {
/** /**
* Prepares variables for the group relationship template. * Prepares variables for the group relationship template.
* *
* Default template: group-content.html.twig * Default template: group-relationship.html.twig.
* *
* @param array $variables * @param array $variables
* - elements: An array of elements to display in view mode. * - elements: An array of elements to display in view mode.
* - group_content: The group relationship object. * - group_relationship: The group relationship object.
* - view_mode: View mode; e.g., 'full', 'teaser', etc. * - view_mode: View mode; e.g., 'full', 'teaser', etc.
*/ */
function template_preprocess_group_content(&$variables) { function template_preprocess_group_relationship(&$variables) {
$group_relationship = $variables['elements']['#group_content']; $group_relationship = $variables['elements']['#group_relationship'];
assert($group_relationship instanceof GroupRelationshipInterface); assert($group_relationship instanceof GroupRelationshipInterface);
$variables['group_content'] = $group_relationship; $variables['group_relationship'] = $group_relationship;
$variables['view_mode'] = $variables['elements']['#view_mode']; $variables['view_mode'] = $variables['elements']['#view_mode'];
$variables['label'] = $group_relationship->label(); $variables['label'] = $group_relationship->label();
$variables['url'] = $group_relationship->toUrl('canonical', ['language' => $group_relationship->language()]); $variables['url'] = $group_relationship->toUrl('canonical', ['language' => $group_relationship->language()]);
...@@ -227,8 +236,8 @@ function template_preprocess_group_content(&$variables) { ...@@ -227,8 +236,8 @@ function template_preprocess_group_content(&$variables) {
// See if we are rendering the group at its canonical route. // See if we are rendering the group at its canonical route.
$route_match = \Drupal::routeMatch(); $route_match = \Drupal::routeMatch();
if ($route_match->getRouteName() == 'entity.group_content.canonical') { if ($route_match->getRouteName() == 'entity.group_relationship.canonical') {
$page_group_relationship = $route_match->getParameter('group_content'); $page_group_relationship = $route_match->getParameter('group_relationship');
} }
$is_page = (!empty($page_group_relationship) ? $page_group_relationship->id() == $group_relationship->id() : FALSE); $is_page = (!empty($page_group_relationship) ? $page_group_relationship->id() == $group_relationship->id() : FALSE);
$variables['page'] = $variables['view_mode'] == 'full' && $is_page; $variables['page'] = $variables['view_mode'] == 'full' && $is_page;
...@@ -259,10 +268,6 @@ function group_modules_installed($modules) { ...@@ -259,10 +268,6 @@ function group_modules_installed($modules) {
/** /**
* Implements hook_form_FORM_ID_alter(). * Implements hook_form_FORM_ID_alter().
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param string $form_id
*/ */
function group_form_block_form_alter(&$form, FormStateInterface $form_state, $form_id) { function group_form_block_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (isset($form['visibility']['group_type'])) { if (isset($form['visibility']['group_type'])) {
...@@ -290,7 +295,11 @@ function group_module_implements_alter(&$implementations, $hook) { ...@@ -290,7 +295,11 @@ function group_module_implements_alter(&$implementations, $hook) {
/** /**
* Implements hook_query_TAG_alter(). * Implements hook_query_TAG_alter().
*/ */
function group_query_entity_query_alter(SelectInterface $query) { function group_query_entity_query_alter(AlterableInterface $query) {
if (!$query instanceof SelectInterface) {
return;
}
$entity_type_id = $query->getMetaData('entity_type'); $entity_type_id = $query->getMetaData('entity_type');
if ($query->hasTag($entity_type_id . '_access')) { if ($query->hasTag($entity_type_id . '_access')) {
$entity_type_manager = \Drupal::entityTypeManager(); $entity_type_manager = \Drupal::entityTypeManager();
...@@ -311,7 +320,7 @@ function group_query_entity_query_alter(SelectInterface $query) { ...@@ -311,7 +320,7 @@ function group_query_entity_query_alter(SelectInterface $query) {
$class_name = GroupQueryAlter::class; $class_name = GroupQueryAlter::class;
break; break;
case 'group_content': case 'group_relationship':
$class_name = GroupRelationshipQueryAlter::class; $class_name = GroupRelationshipQueryAlter::class;
break; break;
...@@ -328,7 +337,11 @@ function group_query_entity_query_alter(SelectInterface $query) { ...@@ -328,7 +337,11 @@ function group_query_entity_query_alter(SelectInterface $query) {
/** /**
* Implements hook_query_TAG_alter(). * Implements hook_query_TAG_alter().
*/ */
function group_query_views_entity_query_alter(SelectInterface $query) { function group_query_views_entity_query_alter(AlterableInterface $query) {
if (!$query instanceof SelectInterface) {
return;
}
$entity_type_id = $query->getMetaData('entity_type'); $entity_type_id = $query->getMetaData('entity_type');
$query->addTag($entity_type_id . '_access'); $query->addTag($entity_type_id . '_access');
group_query_entity_query_alter($query); group_query_entity_query_alter($query);
...@@ -338,27 +351,29 @@ function group_query_views_entity_query_alter(SelectInterface $query) { ...@@ -338,27 +351,29 @@ function group_query_views_entity_query_alter(SelectInterface $query) {
* Implements hook_views_query_alter(). * Implements hook_views_query_alter().
*/ */
function group_views_query_alter(ViewExecutable $view, QueryPluginBase $query) { function group_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
if ($query instanceof Sql && empty($query->options['disable_sql_rewrite'])) { if (!$query instanceof Sql || !empty($query->options['disable_sql_rewrite'])) {
$table_info = $query->getEntityTableInfo(); return;
$base_table = reset($table_info); }
if (empty($base_table['entity_type']) || $base_table['relationship_id'] != 'none') {
return;
}
// Add a custom tag so we don't trigger all other 'entity_query' tag alters. $table_info = $query->getEntityTableInfo();
$entity_type_id = $base_table['entity_type']; $base_table = reset($table_info);
$query->addTag('views_entity_query'); if (empty($base_table['entity_type']) || $base_table['relationship_id'] != 'none') {
return;
}
// Build the Views query already so we can access the DB query. // Add a custom tag so we don't trigger all other 'entity_query' tag alters.
$query->build($view); $entity_type_id = $base_table['entity_type'];
$view->built = TRUE; $query->addTag('views_entity_query');
// Add metadata to the DB query. // Build the Views query already so we can access the DB query.
$query = $view->build_info['query']; $query->build($view);
$count_query = $view->build_info['count_query']; $view->built = TRUE;
$query->addMetaData('entity_type', $entity_type_id);
$count_query->addMetaData('entity_type', $entity_type_id); // Add metadata to the DB query.
} $query = $view->build_info['query'];
$count_query = $view->build_info['count_query'];
$query->addMetaData('entity_type', $entity_type_id);
$count_query->addMetaData('entity_type', $entity_type_id);
} }
/** /**
...@@ -385,7 +400,7 @@ function group_entity_access(EntityInterface $entity, $operation, AccountInterfa ...@@ -385,7 +400,7 @@ function group_entity_access(EntityInterface $entity, $operation, AccountInterfa
// plugins, it might change access. // plugins, it might change access.
$plugin_cache_tags = []; $plugin_cache_tags = [];
foreach ($plugin_ids as $plugin_id) { foreach ($plugin_ids as $plugin_id) {
$plugin_cache_tags[] = "group_content_list:plugin:$plugin_id"; $plugin_cache_tags[] = "group_relationship_list:plugin:$plugin_id";
} }
$access = AccessResult::neutral()->addCacheTags($plugin_cache_tags); $access = AccessResult::neutral()->addCacheTags($plugin_cache_tags);
...@@ -401,7 +416,7 @@ function group_entity_access(EntityInterface $entity, $operation, AccountInterfa ...@@ -401,7 +416,7 @@ function group_entity_access(EntityInterface $entity, $operation, AccountInterfa
// Reduce the plugin IDs to those that are actually in use. // Reduce the plugin IDs to those that are actually in use.
$data_table = \Drupal::entityTypeManager() $data_table = \Drupal::entityTypeManager()
->getDefinition('group_content') ->getDefinition('group_relationship')
->getDataTable(); ->getDataTable();
$plugin_ids_used = \Drupal::database() $plugin_ids_used = \Drupal::database()
...@@ -431,7 +446,7 @@ function group_entity_access(EntityInterface $entity, $operation, AccountInterfa ...@@ -431,7 +446,7 @@ function group_entity_access(EntityInterface $entity, $operation, AccountInterfa
* Implements hook_entity_delete(). * Implements hook_entity_delete().
*/ */
function group_entity_delete(EntityInterface $entity) { function group_entity_delete(EntityInterface $entity) {
$storage = \Drupal::entityTypeManager()->getStorage('group_content'); $storage = \Drupal::entityTypeManager()->getStorage('group_relationship');
assert($storage instanceof GroupRelationshipStorageInterface); assert($storage instanceof GroupRelationshipStorageInterface);
// See if any relationships exist for the entity and delete them as well. // See if any relationships exist for the entity and delete them as well.
...@@ -459,7 +474,7 @@ function group_entity_delete(EntityInterface $entity) { ...@@ -459,7 +474,7 @@ function group_entity_delete(EntityInterface $entity) {
* @todo Move this to a form controller so we can hide the field if it has no * @todo Move this to a form controller so we can hide the field if it has no
* options available to it? * options available to it?
*/ */
function group_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) { function group_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
// Can't retrieve an entity from an empty item list. // Can't retrieve an entity from an empty item list.
if (!isset($items)) { if (!isset($items)) {
return AccessResult::neutral(); return AccessResult::neutral();
...@@ -471,7 +486,7 @@ function group_entity_field_access($operation, FieldDefinitionInterface $field_d ...@@ -471,7 +486,7 @@ function group_entity_field_access($operation, FieldDefinitionInterface $field_d
} }
// We only care if it is attached to a relationship type entity. // We only care if it is attached to a relationship type entity.
if ($items->getEntity()->getEntityTypeId() != 'group_content') { if ($items->getEntity()->getEntityTypeId() != 'group_relationship') {
return AccessResult::neutral(); return AccessResult::neutral();
} }
...@@ -637,13 +652,13 @@ function group_form_alter(&$form, FormStateInterface $form_state, $form_id) { ...@@ -637,13 +652,13 @@ function group_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if ($wizard) { if ($wizard) {
foreach ($submit as $key => $handler) { foreach ($submit as $key => $handler) {
if ($handler == '::save') { if ($handler == '::save') {
$form['actions'][$name]['#submit'][$key] = 'group_content_wizard_store'; $form['actions'][$name]['#submit'][$key] = 'group_relationship_wizard_store';
} }
} }
} }
// Otherwise, we can simply add our submit handler and be done with it. // Otherwise, we can simply add our submit handler and be done with it.
else { else {
$form['actions'][$name]['#submit'][] = 'group_content_entity_submit'; $form['actions'][$name]['#submit'][] = 'group_relationship_entity_submit';
} }
} }
...@@ -652,7 +667,7 @@ function group_form_alter(&$form, FormStateInterface $form_state, $form_id) { ...@@ -652,7 +667,7 @@ function group_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['actions']['cancel'] = [ $form['actions']['cancel'] = [
'#type' => 'submit', '#type' => 'submit',
'#value' => t('Cancel'), '#value' => t('Cancel'),
'#submit' => ['group_content_wizard_cancel'], '#submit' => ['group_relationship_wizard_cancel'],
'#limit_validation_errors' => [], '#limit_validation_errors' => [],
]; ];
} }
...@@ -665,13 +680,14 @@ function group_form_alter(&$form, FormStateInterface $form_state, $form_id) { ...@@ -665,13 +680,14 @@ function group_form_alter(&$form, FormStateInterface $form_state, $form_id) {
* @see group_form_alter() * @see group_form_alter()
* @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm() * @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm()
*/ */
function group_content_wizard_store($form, FormStateInterface $form_state) { function group_relationship_wizard_store($form, FormStateInterface $form_state) {
$entity = $form_state->getFormObject()->getEntity(); $form_object = $form_state->getFormObject();
assert($form_object instanceof EntityFormInterface);
// Store the unsaved entity in the temp store. // Store the unsaved entity in the temp store.
$store = \Drupal::service('tempstore.private')->get($form_state->get('group_wizard_id')); $store = \Drupal::service('tempstore.private')->get($form_state->get('group_wizard_id'));
$store_id = $form_state->get('store_id'); $store_id = $form_state->get('store_id');
$store->set("$store_id:entity", $entity); $store->set("$store_id:entity", $form_object->getEntity());
$store->set("$store_id:step", 2); $store->set("$store_id:step", 2);
// Disable any URL-based redirect until the final step. // Disable any URL-based redirect until the final step.
...@@ -686,7 +702,7 @@ function group_content_wizard_store($form, FormStateInterface $form_state) { ...@@ -686,7 +702,7 @@ function group_content_wizard_store($form, FormStateInterface $form_state) {
* @see group_form_alter() * @see group_form_alter()
* @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm() * @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm()
*/ */
function group_content_wizard_cancel($form, FormStateInterface $form_state) { function group_relationship_wizard_cancel($form, FormStateInterface $form_state) {
$store = \Drupal::service('tempstore.private')->get($form_state->get('group_wizard_id')); $store = \Drupal::service('tempstore.private')->get($form_state->get('group_wizard_id'));
$store_id = $form_state->get('store_id'); $store_id = $form_state->get('store_id');
$store->delete("$store_id:entity"); $store->delete("$store_id:entity");
...@@ -705,8 +721,11 @@ function group_content_wizard_cancel($form, FormStateInterface $form_state) { ...@@ -705,8 +721,11 @@ function group_content_wizard_cancel($form, FormStateInterface $form_state) {
* @see group_form_alter() * @see group_form_alter()
* @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm() * @see \Drupal\group\Entity\Controller\GroupRelationshipController::createForm()
*/ */
function group_content_entity_submit($form, FormStateInterface $form_state) { function group_relationship_entity_submit($form, FormStateInterface $form_state) {
$entity = $form_state->getFormObject()->getEntity(); $form_object = $form_state->getFormObject();
assert($form_object instanceof EntityFormInterface);
$entity = $form_object->getEntity();
$group = $form_state->get('group'); $group = $form_state->get('group');
assert($group instanceof GroupInterface); assert($group instanceof GroupInterface);
$group->addRelationship($entity, $form_state->get('group_relation')); $group->addRelationship($entity, $form_state->get('group_relation'));
......
...@@ -82,26 +82,26 @@ entity.group_role.permissions_form: ...@@ -82,26 +82,26 @@ entity.group_role.permissions_form:
# todo This route needs a requirement which only allows access if the plugin # todo This route needs a requirement which only allows access if the plugin
# isn't installed on the group type yet. # isn't installed on the group type yet.
entity.group_content_type.add_form: entity.group_relationship_type.add_form:
path: '/admin/group/content/install/{group_type}/{plugin_id}' path: '/admin/group/content/install/{group_type}/{plugin_id}'
defaults: defaults:
_entity_form: 'group_content_type.add' _entity_form: 'group_relationship_type.add'
_title: 'Install content plugin' _title: 'Install content plugin'
requirements: requirements:
_permission: 'administer group' _permission: 'administer group'
entity.group_content_type.edit_form: entity.group_relationship_type.edit_form:
path: '/admin/group/content/manage/{group_content_type}' path: '/admin/group/content/manage/{group_relationship_type}'
defaults: defaults:
_entity_form: 'group_content_type.edit' _entity_form: 'group_relationship_type.edit'
_title: 'Configure content plugin' _title: 'Configure content plugin'
requirements: requirements:
_permission: 'administer group' _permission: 'administer group'
entity.group_content_type.delete_form: entity.group_relationship_type.delete_form:
path: '/admin/group/content/manage/{group_content_type}/uninstall' path: '/admin/group/content/manage/{group_relationship_type}/uninstall'
defaults: defaults:
_entity_form: 'group_content_type.delete' _entity_form: 'group_relationship_type.delete'
_title: 'Uninstall content plugin' _title: 'Uninstall content plugin'
requirements: requirements:
_permission: 'administer group' _permission: 'administer group'
...@@ -15,24 +15,24 @@ services: ...@@ -15,24 +15,24 @@ services:
class: 'Drupal\group\Access\GroupOwnsContentAccessCheck' class: 'Drupal\group\Access\GroupOwnsContentAccessCheck'
tags: tags:
- { name: 'access_check', applies_to: '_group_owns_content' } - { name: 'access_check', applies_to: '_group_owns_content' }
access_check.group_content.create: access_check.group_relationship.create:
class: 'Drupal\group\Access\GroupRelationshipCreateAccessCheck' class: 'Drupal\group\Access\GroupRelationshipCreateAccessCheck'
arguments: ['@entity_type.manager'] arguments: ['@entity_type.manager']
tags: tags:
- { name: 'access_check', applies_to: '_group_content_create_access' } - { name: 'access_check', applies_to: '_group_relationship_create_access' }
access_check.group_content.create_any: access_check.group_relationship.create_any:
class: 'Drupal\group\Access\GroupRelationshipCreateAnyAccessCheck' class: 'Drupal\group\Access\GroupRelationshipCreateAnyAccessCheck'
arguments: ['@entity_type.manager'] arguments: ['@entity_type.manager']
tags: tags:
- { name: 'access_check', applies_to: '_group_content_create_any_access' } - { name: 'access_check', applies_to: '_group_relationship_create_any_access' }
access_check.group_content.create_entity: access_check.group_relationship.create_entity:
class: 'Drupal\group\Access\GroupRelationshipCreateEntityAccessCheck' class: 'Drupal\group\Access\GroupRelationshipCreateEntityAccessCheck'
tags: tags:
- { name: 'access_check', applies_to: '_group_content_create_entity_access' } - { name: 'access_check', applies_to: '_group_relationship_create_entity_access' }
access_check.group_content.create_any_entity: access_check.group_relationship.create_any_entity:
class: 'Drupal\group\Access\GroupRelationshipCreateAnyEntityAccessCheck' class: 'Drupal\group\Access\GroupRelationshipCreateAnyEntityAccessCheck'
tags: tags:
- { name: 'access_check', applies_to: '_group_content_create_any_entity_access' } - { name: 'access_check', applies_to: '_group_relationship_create_any_entity_access' }
access_check.group_latest_revision: access_check.group_latest_revision:
class: 'Drupal\group\Entity\Access\GroupLatestRevisionCheck' class: 'Drupal\group\Entity\Access\GroupLatestRevisionCheck'
arguments: ['@entity_type.manager'] arguments: ['@entity_type.manager']
...@@ -41,6 +41,26 @@ services: ...@@ -41,6 +41,26 @@ services:
tags: tags:
- { name: 'access_check', applies_to: '_group_latest_revision' } - { name: 'access_check', applies_to: '_group_latest_revision' }
cache.group_memberships_memory:
class: 'Drupal\Core\Cache\MemoryCache\MemoryCacheInterface'
tags:
- { name: 'cache.bin.memory', default_backend: 'cache.backend.memory.memory' }
factory: ['@cache_factory', 'get']
arguments: ['group_memberships_memory']
cache.group_memberships:
class: 'Drupal\Core\Cache\CacheBackendInterface'
tags:
- { name: 'cache.bin' }
factory: ['@cache_factory', 'get']
arguments: ['group_memberships']
cache.group_memberships_chained:
class: 'Drupal\Core\Cache\BackendChain'
calls:
- ['appendBackend', ['@cache.group_memberships_memory']]
- ['appendBackend', ['@cache.group_memberships']]
tags:
- { name: 'cache.bin.memory' }
cache_context.route.group: cache_context.route.group:
class: 'Drupal\group\Cache\Context\RouteGroupCacheContext' class: 'Drupal\group\Cache\Context\RouteGroupCacheContext'
arguments: ['@current_route_match', '@entity_type.manager'] arguments: ['@current_route_match', '@entity_type.manager']
...@@ -62,6 +82,11 @@ services: ...@@ -62,6 +82,11 @@ services:
arguments: ['@config.factory'] arguments: ['@config.factory']
tags: tags:
- { name: 'event_subscriber' } - { name: 'event_subscriber' }
group.anonymous_user_response_subscriber:
class: 'Drupal\group\EventSubscriber\AnonymousUserResponseSubscriber'
arguments: ['@current_user', '@group_permission.calculator']
tags:
- { name: 'event_subscriber' }
group.latest_revision.route_subscriber: group.latest_revision.route_subscriber:
class: 'Drupal\group\Entity\Routing\GroupLatestRevisionRouteSubscriber' class: 'Drupal\group\Entity\Routing\GroupLatestRevisionRouteSubscriber'
tags: tags:
...@@ -86,11 +111,11 @@ services: ...@@ -86,11 +111,11 @@ services:
arguments: ['@entity_type.manager', '@current_user'] arguments: ['@entity_type.manager', '@current_user']
group.permissions: group.permissions:
class: 'Drupal\group\Access\GroupPermissionHandler' class: 'Drupal\group\Access\GroupPermissionHandler'
arguments: ['@module_handler', '@string_translation', '@controller_resolver', '@group_relation_type.manager'] arguments: ['@module_handler', '@string_translation', '@controller_resolver', '@group_relation_type.manager', '@extension.list.module']
group_permission.hash_generator: group_permission.hash_generator:
class: 'Drupal\group\Access\GroupPermissionsHashGenerator' class: 'Drupal\group\Access\GroupPermissionsHashGenerator'
arguments: ['@private_key', '@cache.static', '@group_permission.calculator'] arguments: ['@private_key', '@cache.static', '@group_permission.calculator', '@entity_type.manager', '@database']
# Wrappers for Flexible permissions services. # Wrappers for Flexible permissions services.
group_permission.calculator: group_permission.calculator:
...@@ -112,14 +137,14 @@ services: ...@@ -112,14 +137,14 @@ services:
tags: tags:
- { name: flexible_permission_calculator, priority: -50 } - { name: flexible_permission_calculator, priority: -50 }
group.uninstall_validator.group_content: group.uninstall_validator.group_relationship:
class: 'Drupal\group\UninstallValidator\GroupRelationshipUninstallValidator' class: 'Drupal\group\UninstallValidator\GroupRelationshipUninstallValidator'
tags: tags:
- { name: 'module_install.uninstall_validator' } - { name: 'module_install.uninstall_validator' }
arguments: ['@string_translation', '@entity_type.manager', '@group_relation_type.manager'] arguments: ['@string_translation', '@entity_type.manager', '@group_relation_type.manager']
lazy: 'true' lazy: 'true'
group_content_type.breadcrumb: group_relationship_type.breadcrumb:
class: 'Drupal\group\Breadcrumb\GroupRelationshipTypeBreadcrumbBuilder' class: 'Drupal\group\Breadcrumb\GroupRelationshipTypeBreadcrumbBuilder'
tags: tags:
- { name: 'breadcrumb_builder', priority: 100 } - { name: 'breadcrumb_builder', priority: 100 }
...@@ -127,7 +152,6 @@ services: ...@@ -127,7 +152,6 @@ services:
group_relation_type.manager: group_relation_type.manager:
class: 'Drupal\group\Plugin\Group\Relation\GroupRelationTypeManager' class: 'Drupal\group\Plugin\Group\Relation\GroupRelationTypeManager'
arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@entity_type.manager'] arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@entity_type.manager']
parent: container.trait
tags: tags:
- { name: plugin_manager_cache_clear } - { name: plugin_manager_cache_clear }
...@@ -156,19 +180,18 @@ services: ...@@ -156,19 +180,18 @@ services:
shared: false shared: false
# Specific group relation handlers. # Specific group relation handlers.
group.relation_handler.access_control.group_membership:
class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipAccessControl'
arguments: ['@group.relation_handler.access_control']
group.relation_handler.entity_reference.group_membership: group.relation_handler.entity_reference.group_membership:
class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipEntityReference' class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipEntityReference'
arguments: ['@group.relation_handler.entity_reference'] arguments: ['@group.relation_handler.entity_reference']
shared: false
group.relation_handler.operation_provider.group_membership: group.relation_handler.operation_provider.group_membership:
class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipOperationProvider' class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipOperationProvider'
arguments: ['@group.relation_handler.operation_provider', '@current_user', '@string_translation'] arguments: ['@group.relation_handler.operation_provider', '@current_user', '@string_translation']
shared: false
group.relation_handler.permission_provider.group_membership: group.relation_handler.permission_provider.group_membership:
class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipPermissionProvider' class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipPermissionProvider'
arguments: ['@group.relation_handler.permission_provider'] arguments: ['@group.relation_handler.permission_provider']
shared: false
group.relation_handler.post_install.group_membership: group.relation_handler.post_install.group_membership:
class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipPostInstall' class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipPostInstall'
arguments: ['@group.relation_handler.post_install', '@entity_type.manager', '@string_translation'] arguments: ['@group.relation_handler.post_install', '@entity_type.manager', '@string_translation']
shared: false
...@@ -76,49 +76,49 @@ function group_token_info() { ...@@ -76,49 +76,49 @@ function group_token_info() {
'type' => 'user', 'type' => 'user',
]; ];
$types['group_content'] = [ $types['group_relationship'] = [
'name' => t('Group relationship'), 'name' => t('Group relationship'),
'description' => t('Tokens related to the relationships between a group and its content.'), 'description' => t('Tokens related to the relationships between a group and its content.'),
'needs-data' => 'group_content', 'needs-data' => 'group_relationship',
]; ];
$tokens['group_content']['id'] = [ $tokens['group_relationship']['id'] = [
'name' => t('Group relationship ID'), 'name' => t('Group relationship ID'),
'description' => t('The unique ID of the group relationship.'), 'description' => t('The unique ID of the group relationship.'),
]; ];
$tokens['group_content']['langcode'] = [ $tokens['group_relationship']['langcode'] = [
'name' => t('Language code'), 'name' => t('Language code'),
'description' => t('The language code of the language the group relationship is in.'), 'description' => t('The language code of the language the group relationship is in.'),
]; ];
$tokens['group_content']['url'] = [ $tokens['group_relationship']['url'] = [
'name' => t('URL'), 'name' => t('URL'),
'description' => t('The URL of the group relationship.'), 'description' => t('The URL of the group relationship.'),
]; ];
$tokens['group_content']['edit-url'] = [ $tokens['group_relationship']['edit-url'] = [
'name' => t('Edit URL'), 'name' => t('Edit URL'),
'description' => t("The URL of the group's edit page."), 'description' => t("The URL of the group's edit page."),
]; ];
$tokens['group_content']['created'] = [ $tokens['group_relationship']['created'] = [
'name' => t('Date created'), 'name' => t('Date created'),
'type' => 'date', 'type' => 'date',
]; ];
$tokens['group_content']['changed'] = [ $tokens['group_relationship']['changed'] = [
'name' => t('Date changed'), 'name' => t('Date changed'),
'description' => t('The date the group relationship was most recently updated.'), 'description' => t('The date the group relationship was most recently updated.'),
'type' => 'date', 'type' => 'date',
]; ];
$tokens['group_content']['group'] = [ $tokens['group_relationship']['group'] = [
'name' => t('Group'), 'name' => t('Group'),
'type' => 'group', 'type' => 'group',
]; ];
$tokens['group_content']['pretty-path-key'] = [ $tokens['group_relationship']['pretty-path-key'] = [
'name' => t('Pretty path key'), 'name' => t('Pretty path key'),
'description' => t('A prettier way of labeling group relationship of the same relation type.'), 'description' => t('A prettier way of labeling group relationship of the same relation type.'),
]; ];
...@@ -214,8 +214,8 @@ function group_tokens($type, $tokens, array $data, array $options, BubbleableMet ...@@ -214,8 +214,8 @@ function group_tokens($type, $tokens, array $data, array $options, BubbleableMet
$replacements += $token_service->generate('date', $changed_tokens, ['date' => $group->getChangedTime()], $options, $bubbleable_metadata); $replacements += $token_service->generate('date', $changed_tokens, ['date' => $group->getChangedTime()], $options, $bubbleable_metadata);
} }
} }
elseif ($type == 'group_content' && !empty($data[$type])) { elseif ($type == 'group_relationship' && !empty($data[$type])) {
$group_relationship = $data['group_content']; $group_relationship = $data['group_relationship'];
assert($group_relationship instanceof GroupRelationshipInterface); assert($group_relationship instanceof GroupRelationshipInterface);
foreach ($tokens as $name => $original) { foreach ($tokens as $name => $original) {
......
...@@ -16,7 +16,7 @@ function group_views_data_alter(array &$data) { ...@@ -16,7 +16,7 @@ function group_views_data_alter(array &$data) {
$entity_types = $entity_type_manager->getDefinitions(); $entity_types = $entity_type_manager->getDefinitions();
// Get the data table for GroupRelationship entities. // Get the data table for GroupRelationship entities.
$data_table = $entity_types['group_content']->getDataTable(); $data_table = $entity_types['group_relationship']->getDataTable();
$plugin_manager = \Drupal::service('group_relation_type.manager'); $plugin_manager = \Drupal::service('group_relation_type.manager');
assert($plugin_manager instanceof GroupRelationTypeManagerInterface); assert($plugin_manager instanceof GroupRelationTypeManagerInterface);
...@@ -32,8 +32,8 @@ function group_views_data_alter(array &$data) { ...@@ -32,8 +32,8 @@ function group_views_data_alter(array &$data) {
$entity_type = $entity_types[$entity_type_id]; $entity_type = $entity_types[$entity_type_id];
$entity_data_table = $entity_type->getDataTable() ?: $entity_type->getBaseTable(); $entity_data_table = $entity_type->getDataTable() ?: $entity_type->getBaseTable();
// We only add one 'group_content' entry per entity type. // We only add one 'group_relationship' entry per entity type.
if (isset($data[$entity_data_table]['group_content'])) { if (isset($data[$entity_data_table]['group_relationship'])) {
continue; continue;
} }
...@@ -43,7 +43,7 @@ function group_views_data_alter(array &$data) { ...@@ -43,7 +43,7 @@ function group_views_data_alter(array &$data) {
// This relationship will allow a content entity to easily map to the group // This relationship will allow a content entity to easily map to the group
// content entity that ties it to a group, optionally filtering by plugin. // content entity that ties it to a group, optionally filtering by plugin.
$data[$entity_data_table]['group_content'] = [ $data[$entity_data_table]['group_relationship'] = [
'title' => t('Group relationship for @entity_type', $t_args), 'title' => t('Group relationship for @entity_type', $t_args),
'help' => t('Relates to the group relationship entities that represent the @entity_type.', $t_args), 'help' => t('Relates to the group relationship entities that represent the @entity_type.', $t_args),
'relationship' => [ 'relationship' => [
...@@ -51,7 +51,7 @@ function group_views_data_alter(array &$data) { ...@@ -51,7 +51,7 @@ function group_views_data_alter(array &$data) {
'base' => $data_table, 'base' => $data_table,
'base field' => 'entity_id', 'base field' => 'entity_id',
'relationship field' => $entity_type->getKey('id'), 'relationship field' => $entity_type->getKey('id'),
'id' => 'group_content_to_entity_reverse', 'id' => 'group_relationship_to_entity_reverse',
'label' => t('@entity_type group relationship', $t_args), 'label' => t('@entity_type group relationship', $t_args),
], ],
]; ];
......