diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 5df2f26ad4f0bc19851a054fe1171cf149e983a9..0d7e6601879aa632b0251b1ed2ff116dc1df077e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -16,24 +16,9 @@ parameters: path: src/Drush/Commands/LmsQaCommands.php - - message: "#^Call to an undefined method Drupal\\\\Tests\\\\WebAssert\\:\\:waitForElement\\(\\)\\.$#" + message: "#^Class Drupal\\\\lms\\\\Plugin\\\\ModalSubform\\\\EntityForm is neither abstract nor final\\.$#" count: 1 - path: tests/src/FunctionalJavascript/GeneralLmsTest.php - - - - message: "#^Call to an undefined method Drupal\\\\Tests\\\\WebAssert\\:\\:waitForElementRemoved\\(\\)\\.$#" - count: 1 - path: tests/src/FunctionalJavascript/GeneralLmsTest.php - - - - message: "#^Call to an undefined method Drupal\\\\Tests\\\\WebAssert\\:\\:waitForElementVisible\\(\\)\\.$#" - count: 2 - path: tests/src/FunctionalJavascript/GeneralLmsTest.php - - - - message: "#^Call to an undefined method Drupal\\\\Tests\\\\WebAssert\\:\\:waitOnAutocomplete\\(\\)\\.$#" - count: 1 - path: tests/src/FunctionalJavascript/GeneralLmsTest.php + path: src/Plugin/ModalSubform/EntityForm.php - message: "#^Call to function property_exists\\(\\) with \\$this\\(Drupal\\\\Tests\\\\lms\\\\FunctionalJavascript\\\\GeneralLmsTest\\) and 'userData' will always evaluate to true\\.$#" diff --git a/src/Plugin/Field/FieldWidget/LMSReferenceTable.php b/src/Plugin/Field/FieldWidget/LMSReferenceTable.php index 63865ab5adf9faf36f7391afe02ebae9173004ae..2e5cc5bd228ee0d66a75163aabf41d8dfc511ff1 100644 --- a/src/Plugin/Field/FieldWidget/LMSReferenceTable.php +++ b/src/Plugin/Field/FieldWidget/LMSReferenceTable.php @@ -288,6 +288,7 @@ final class LMSReferenceTable extends WidgetBase { 'selector' => $parameters_selector, 'data_path' => $element_path, 'type' => $target_type, + 'entity_id' => $entity_id, 'form' => 'parameters', ], ], diff --git a/src/Plugin/ModalSubform/EntityForm.php b/src/Plugin/ModalSubform/EntityForm.php index b60962aedc59638b590466a4f474f8f58f76a41c..74826ae944b517fb7d33c3e56c9c89c315957f86 100644 --- a/src/Plugin/ModalSubform/EntityForm.php +++ b/src/Plugin/ModalSubform/EntityForm.php @@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; #[ModalSubform( id: 'entity', )] -final class EntityForm extends ModalSubformBase { +class EntityForm extends ModalSubformBase { public function __construct( array $configuration, @@ -80,16 +80,33 @@ final class EntityForm extends ModalSubformBase { * {@inheritdoc} */ public function access(AccountInterface $currentUser): bool { - // @todo This should be more complex: check if entity ID is provided, - // determine operation and call the relevant entity access handler. - // Will do for now but needs to be updated if this will ever be a general - // API and not a part of Drupal LMS. - if ($this->configuration['type'] === 'group') { - return $currentUser->hasPermission('create lms_course group'); + if (!$this->entityTypeManager->hasHandler($this->configuration['type'], 'access')) { + return FALSE; } - else { - return $currentUser->hasPermission(\sprintf('create %s entities', $this->configuration['type'])); + $access_handler = $this->entityTypeManager->getHandler($this->configuration['type'], 'access'); + + // Entity creation case. + if ( + !\array_key_exists('entity_id', $this->configuration) || + $this->configuration['entity_id'] === '' + ) { + $bundle = $this->getBundle($this->configuration); + if ($bundle === NULL) { + throw new \InvalidArgumentException('Unable to determine entity bundle.'); + } + return $access_handler->createAccess($bundle, $currentUser, []); + } + + // Entity edition case. + $entity = $this->entityTypeManager->getStorage($this->configuration['type'])->load($this->configuration['entity_id']); + if ($entity === NULL) { + throw new \InvalidArgumentException(\sprintf( + 'Invalid entity parameters provided: [%s, %d].', + $this->configuration['type'], + $this->configuration['entity_id'] + )); } + return $access_handler->access($entity, 'edit', $currentUser); } /** diff --git a/src/Plugin/ModalSubform/LmsEntitySpecificForm.php b/src/Plugin/ModalSubform/LmsEntitySpecificForm.php index c172e1e478a53d1796d78f504715df0cff5a9d3b..bf9ab0c5b5d6f01b52e9d56fdfc8ac25c7fda901 100644 --- a/src/Plugin/ModalSubform/LmsEntitySpecificForm.php +++ b/src/Plugin/ModalSubform/LmsEntitySpecificForm.php @@ -4,16 +4,12 @@ declare(strict_types=1); namespace Drupal\lms\Plugin\ModalSubform; -use Drupal\Core\DependencyInjection\ClassResolverInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Form\FormInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\lms\Attribute\ModalSubform; use Drupal\lms\Form\Modal\LmsBundleSelectionForm; use Drupal\lms\Form\Modal\LmsReferenceParametersForm; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Modal LMS entity bundle selection form. @@ -21,44 +17,12 @@ use Symfony\Component\DependencyInjection\ContainerInterface; #[ModalSubform( id: 'lms_entity_param', )] -final class LmsEntitySpecificForm extends ModalSubformBase { - - public function __construct( - array $configuration, - $plugin_id, - $plugin_definition, - FormBuilderInterface $formBuilder, - ClassResolverInterface $classResolver, - protected readonly EntityTypeManagerInterface $entityTypeManager, - ) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $formBuilder, $classResolver); - } - - /** - * {@inheritdoc} - */ - public static function create( - ContainerInterface $container, - array $configuration, - $plugin_id, - $plugin_definition, - ) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('form_builder'), - $container->get('class_resolver'), - $container->get('entity_type.manager') - ); - } +final class LmsEntitySpecificForm extends EntityForm { /** * {@inheritdoc} */ protected function validateConfiguration(array $configuration): void { - parent::validateConfiguration($configuration); - foreach (['type', 'form'] as $parameter) { if ( !\array_key_exists($parameter, $configuration) || @@ -67,22 +31,32 @@ final class LmsEntitySpecificForm extends ModalSubformBase { throw new \InvalidArgumentException(\sprintf('%s parameter missing or invalid.', $parameter)); } } + + if ($configuration['form'] === 'parameters') { + parent::validateConfiguration($configuration); + } } /** * {@inheritdoc} */ public function access(AccountInterface $currentUser): bool { - return $currentUser->hasPermission(\sprintf('create %s entities', $this->configuration['type'])); - } + // Admin permission. + if ($currentUser->hasPermission('administer lms')) { + return TRUE; + } - /** - * {@inheritdoc} - */ - public function getDialogId(): string { - // In order to make the replacement from bundle selection to entity form, - // the dialog ID must be the same as for the entity form. - return '#modal-entity-' . \strtr($this->configuration['type'], '_', '-'); + // Bundle selection - needs create access. + if ($this->configuration['form'] === 'bundle') { + return $currentUser->hasPermission(\sprintf('create %s entities', $this->configuration['type'])); + } + + // Parameters form - edit access. + elseif ($this->configuration['form'] === 'parameters') { + return parent::access($currentUser); + } + + return FALSE; } /** diff --git a/tests/config/user.role.lms_admin.yml b/tests/config/user.role.lms_admin.yml index bdb32f2a38bc0827bbd2631d3a1b63bfe67dc314..0ca0358ccd82e95ef4f942bcbe6ba95f8a8f734d 100644 --- a/tests/config/user.role.lms_admin.yml +++ b/tests/config/user.role.lms_admin.yml @@ -15,6 +15,8 @@ permissions: - 'access group overview' - 'access toolbar' - 'administer lms' + - 'create lms_activity entities' - 'create lms_course group' - 'create lms_class group' + - 'create lms_lesson entities' - 'view the administration theme'