diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..8af63c78
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,37 @@
+language: php
+
+sudo: false
+
+php:
+ - 7.2
+
+install:
+ - composer global require drush/drush:8.x-dev drupal/coder mglaman/drupal-check friendsoftwig/twigcs
+ - export PATH="$HOME/.config/composer/vendor/bin:$PATH"
+ - phpcs --config-set installed_paths ../../drupal/coder/coder_sniffer
+ - phpenv rehash
+ - nvm install node
+ - nvm use node
+ - npm install --global yarn
+ - cd ../ && drush dl drupal-8 --drupal-project-rename=drupal
+ - cd drupal
+ - DRUPAL_ROOT=$(pwd)
+ - export REPOSITORIES='"repositories":\ \['
+ - export REPOSITORIES_REPLACE='"repositories":\[\{"type":"path","url":"..\/os2forms","options":\{"symlink":false\}\},'
+ - export REQUIRE='"require":\ {'
+ - export REQUIRE_REPLACE='"require":{"os2forms\/os2forms":"\*",'
+ - sed -i "s/$REPOSITORIES/$REPOSITORIES_REPLACE/g" composer.json
+ - sed -i "s/$REQUIRE/$REQUIRE_REPLACE/g" composer.json
+ - composer update
+ - PROJECT_PATH=$DRUPAL_ROOT/modules/contrib/os2forms
+ - cd $DRUPAL_ROOT/core
+ - yarn install
+ - npm install --global eslint-config-drupal-bundle stylelint
+
+script:
+ - phpcs --standard=Drupal --ignore=*.md $PROJECT_PATH
+ - twigcs $PROJECT_PATH
+ - cd $DRUPAL_ROOT/core
+ - eslint $DRUPAL_ROOT/modules/contrib/os2forms
+ - stylelint --aei $DRUPAL_ROOT/modules/contrib/os2forms/**/*.css
+ - drupal-check $DRUPAL_ROOT/modules/contrib/os2forms
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..7b2fe5c2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# OS2Forms Drupal module [](https://travis-ci.org/OS2Forms/os2forms)
+
+## Install
+
+OS2Forms Drupal 8 module is available to download via composer.
+```
+composer require os2forms/os2forms
+drush en os2forms
+```
+
+If you don't have Drupal installed on you server, you will to need install it first.
+Read more about [how to install drupal core](https://www.drupal.org/docs/8/install).
+
+We are recommending to install drupal via composer by using
+[drupal-composer project](https://github.com/drupal-composer/drupal-project).
+
+To get more benefits on your Drupal project we are offering you to use
+[OS2web](https://packagist.org/packages/os2web/os2web) as installation
+profile for Drupal.
+
+You can easy download and install OS2web installation profile to your
+composer based Drupal project with commands:
+```
+composer require os2web/os2web
+drush si os2web --db-url=mysql://db_user:db_pass@mysql_host/db_name --account-pass=admin -y
+```
+
+## Update
+Updating process for OS2forms module is similar to usual Drupal 8 module.
+Use Composer's built-in command for listing packages that have updates available:
+
+```
+composer outdated os2forms/os2forms
+```
+## Automated testing and code quality
+See [OS2Forms testing and CI information](https://github.com/OS2Forms/docs#testing-and-ci)
+
+## Contribution
+
+OS2Forms project is opened for new features and os course bugfixes.
+If you have any suggestion or you found a bug in project, you are very welcome
+to create an issue in github repository issue tracker.
+For issue description there is expected that you will provide clear and
+sufficient information about your feature request or bug report.
+
+### Code review policy
+See [OS2Forms code review policy](https://github.com/OS2Forms/docs#code-review)
+
+### Git name convention
+See [OS2Forms git name convention](https://github.com/OS2Forms/docs#git-guideline)
+
+## Unstable features
+### Export submissions to Word
+This feature is still not part of Webform and Entity print modules stable versions
+due to following issues:
+* [[Webform] Unlock possibility of using Entity print module export to Word feature](https://www.drupal.org/project/webform/issues/3096552)
+* [[Entity Print] Add Export to Word Support](https://www.drupal.org/project/entity_print/issues/2733781)
+
+To get this functionality on drupal project there will be applied patches from issues above via Composer.
+
+NOTE: If you are downloading os2forms module without using composer, be aware that you have apply those patches by yourself.
diff --git a/composer.json b/composer.json
index 4a7203a1..203892e2 100644
--- a/composer.json
+++ b/composer.json
@@ -4,7 +4,7 @@
"description": "Drupal 8 OS2Form module provides advanced webform functionality for Danish Municipalities",
"minimum-stability": "dev",
"prefer-stable": true,
- "license": "GPL-2.0-or-later",
+ "license": "EUPL-1.2",
"repositories": {
"drupal": {
"type": "composer",
@@ -28,6 +28,25 @@
"drupal/entity_print": "^2.1",
"drupal/webform_migrate": "^1.1",
"drupal/maillog": "1.x-dev",
- "drupal/devel": "^2.1"
+ "drupal/devel": "^2.1",
+ "phpoffice/phpword": "^0.17.0",
+ "tecnickcom/tcpdf": "~6",
+ "vaimo/composer-patches": "^4.20",
+ "os2web/os2web_nemlogin": "8.x-dev"
+ },
+ "extra" : {
+ "composer-exit-on-patch-failure": true,
+ "patchLevel": {
+ "test": "-p2"
+ },
+ "enable-patching" : true,
+ "patches": {
+ "drupal/entity_print": {
+ "2733781 - Add Export to Word Support": "https://www.drupal.org/files/issues/2019-11-22/2733781-47.patch"
+ },
+ "drupal/webform" : {
+ "3096552 - Unlock possibility of using Entity print module export to Word feature": "https://www.drupal.org/files/issues/2019-11-25/3096552-unlock-export-to-word-1.patch"
+ }
+ }
}
}
diff --git a/modules/os2forms_nemid/README.md b/modules/os2forms_nemid/README.md
new file mode 100644
index 00000000..6f67a0e9
--- /dev/null
+++ b/modules/os2forms_nemid/README.md
@@ -0,0 +1,19 @@
+# OS2Forms Nemid Drupal module
+
+# Module purpose
+
+The aim of this module is to provide custom NemId field and integration with OS2Web Nemlogin module.
+
+# How does it work
+
+Module exposes dozen of new NemID components that are available in the webform build process.
+
+Build page: admin/structure/webform/manage/[webform]
+
+Besides this module adds a special settings to the Third Party Webform settings:
+
+- Webform type
+- Redirect to nemlogin automatically
+
+Settings: admin/structure/webform/manage/[webform]/settings
+
diff --git a/modules/os2forms_nemid/os2forms_nemid.info.yml b/modules/os2forms_nemid/os2forms_nemid.info.yml
new file mode 100644
index 00000000..a7c4332c
--- /dev/null
+++ b/modules/os2forms_nemid/os2forms_nemid.info.yml
@@ -0,0 +1,10 @@
+name: 'OS2forms NemID'
+type: module
+description: 'Provides custom NemID fields and integration with NemID'
+package: OS2Forms
+core: 8.x
+core_version_requirement: ^8 || ^9
+
+dependencies:
+ - os2forms
+ - os2web_nemlogin
diff --git a/modules/os2forms_nemid/os2forms_nemid.module b/modules/os2forms_nemid/os2forms_nemid.module
new file mode 100644
index 00000000..4b313569
--- /dev/null
+++ b/modules/os2forms_nemid/os2forms_nemid.module
@@ -0,0 +1,97 @@
+getFormObject()->getEntity();
+ $settings = $webform->getThirdPartySetting('os2forms', 'os2forms_nemid');
+
+ // OS2Forms NemID.
+ $form['third_party_settings']['os2forms']['os2forms_nemid'] = [
+ '#type' => 'details',
+ '#title' => t('OS2Forms NemID settings'),
+ '#open' => TRUE,
+ ];
+
+ // Webform type.
+ $webform_types = [
+ OS2FORMS_NEMID_WEBFORM_TYPE_PERSONAL => t('Personal'),
+ OS2FORMS_NEMID_WEBFORM_TYPE_COMPANY => t('Company'),
+ ];
+ $form['third_party_settings']['os2forms']['os2forms_nemid']['webform_type'] = [
+ '#type' => 'select',
+ '#title' => t('Webform type'),
+ '#default_value' => !(empty($settings)) ? $settings['webform_type'] : NULL,
+ '#empty_option' => t('Not specified'),
+ '#options' => $webform_types,
+ '#description' => t('Based on the selected type form irrelevant fields will not be shown to the end user'),
+ ];
+
+ // Nemlogin auto redirect.
+ $form['third_party_settings']['os2forms']['os2forms_nemid']['nemlogin_auto_redirect'] = [
+ '#type' => 'checkbox',
+ '#title' => t('Redirect to nemlogin automatically'),
+ '#default_value' => !(empty($settings)) ? $settings['nemlogin_auto_redirect'] : FALSE,
+ '#description' => t('Redirection will happen right after user has is accessing the form, if user is already authenticated via NemID, redirection will not happen.'),
+ ];
+}
+
+/**
+ * Implements hook_webform_submission_form_alter().
+ */
+function os2forms_nemid_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
+ // Getting webform Nemid settings.
+ /** @var \Drupal\webform\WebformSubmissionInterface Interface $webformSubmission */
+ $webformSubmission = $form_state->getFormObject()->getEntity();
+ /** @var \Drupal\webform\WebformInterface $webform */
+ $webform = $webformSubmission->getWebform();
+ $webformNemidSettings = $webform->getThirdPartySetting('os2forms', 'os2forms_nemid');
+
+ // Getting webform_type setting.
+ $webform_type = NULL;
+ if (isset($webformNemidSettings['webform_type']) && !empty($webformNemidSettings['webform_type'])) {
+ $webform_type = $webformNemidSettings['webform_type'];
+ }
+
+ // Webform type is set and not empty.
+ if ($webform_type) {
+ // Initializing AuthProviderInterface plugin.
+ /** @var \Drupal\os2web_nemlogin\Service\AuthProviderService $authProviderService */
+ $authProviderService = \Drupal::service('os2web_nemlogin.auth_provider');
+ /** @var \Drupal\os2web_nemlogin\Plugin\AuthProviderInterface $authProviderPlugin */
+ $authProviderPlugin = $authProviderService->getActivePlugin();
+
+ // User is authenticated, check if the form type is corresponding to
+ // authentication type.
+ if ($authProviderPlugin->isAuthenticated()) {
+ if ($authProviderPlugin->isAuthenticatedPerson() && $webform_type !== OS2FORMS_NEMID_WEBFORM_TYPE_PERSONAL
+ || $authProviderPlugin->isAuthenticatedCompany() && $webform_type !== OS2FORMS_NEMID_WEBFORM_TYPE_COMPANY) {
+ \Drupal::messenger()
+ ->addWarning(t('Your login type does match the login type required by the webform. Please log out and sign in with a different account', [
+ '@logout' => $authProviderService->getLogoutUrl()
+ ->toString(),
+ ]));
+ }
+ }
+ }
+
+}
diff --git a/modules/os2forms_nemid/os2forms_nemid.services.yml b/modules/os2forms_nemid/os2forms_nemid.services.yml
new file mode 100644
index 00000000..af368626
--- /dev/null
+++ b/modules/os2forms_nemid/os2forms_nemid.services.yml
@@ -0,0 +1,6 @@
+services:
+ os2forms_nemid_nemlogin_redirect_subscriber:
+ class: Drupal\os2forms_nemid\EventSubscriber\NemloginRedirectSubscriber
+ arguments: ['@os2web_nemlogin.auth_provider', '@current_user']
+ tags:
+ - {name: event_subscriber}
diff --git a/modules/os2forms_nemid/src/Element/NemidAddress.php b/modules/os2forms_nemid/src/Element/NemidAddress.php
new file mode 100644
index 00000000..ae555fdf
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidAddress.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidAddress'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidAddress'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidAddress'],
+ ],
+ '#theme' => 'input__os2forms_nemid_address',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_address' element.
+ */
+ public static function processNemidAddress(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_address'.
+ */
+ public static function validateNemidAddress(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidAddress(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-address']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCity.php b/modules/os2forms_nemid/src/Element/NemidCity.php
new file mode 100644
index 00000000..22fbe984
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCity.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidCity'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCity'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCity'],
+ ],
+ '#theme' => 'input__os2forms_nemid_city',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_city' element.
+ */
+ public static function processNemidCity(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_city'.
+ */
+ public static function validateNemidCity(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCity(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-city']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCoaddress.php b/modules/os2forms_nemid/src/Element/NemidCoaddress.php
new file mode 100644
index 00000000..a3094b68
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCoaddress.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidCoaddress'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCoaddress'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCoaddress'],
+ ],
+ '#theme' => 'input__os2forms_nemid_coaddress',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_coaddress' element.
+ */
+ public static function processNemidCoaddress(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_coaddress'.
+ */
+ public static function validateNemidCoaddress(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCoaddress(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-coaddress']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCompanyAddress.php b/modules/os2forms_nemid/src/Element/NemidCompanyAddress.php
new file mode 100644
index 00000000..77f4a109
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCompanyAddress.php
@@ -0,0 +1,66 @@
+ [
+ [$class, 'processNemidCompanyAddress'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCompanyAddress'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCompanyAddress'],
+ ],
+ '#theme' => 'input__os2forms_nemid_company_address',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_company_name' element.
+ */
+ public static function processNemidCompanyAddress(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler.
+ *
+ * For #type 'os2forms_nemid_company_address'.
+ */
+ public static function validateNemidCompanyAddress(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCompanyAddress(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-company-address']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCompanyCvr.php b/modules/os2forms_nemid/src/Element/NemidCompanyCvr.php
new file mode 100644
index 00000000..ca112f3f
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCompanyCvr.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidCompanyCvr'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCompanyCvr'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCompanyCvr'],
+ ],
+ '#theme' => 'input__os2forms_nemid_company_cvr',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_company_cvr' element.
+ */
+ public static function processNemidCompanyCvr(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_company_cvr'.
+ */
+ public static function validateNemidCompanyCvr(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCompanyCvr(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-company-cvr']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCompanyName.php b/modules/os2forms_nemid/src/Element/NemidCompanyName.php
new file mode 100644
index 00000000..469d2b19
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCompanyName.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidCompanyName'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCompanyName'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCompanyName'],
+ ],
+ '#theme' => 'input__os2forms_nemid_company_name',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_company_name' element.
+ */
+ public static function processNemidCompanyName(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_company_name'.
+ */
+ public static function validateNemidCompanyName(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCompanyName(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-company-name']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCompanyRid.php b/modules/os2forms_nemid/src/Element/NemidCompanyRid.php
new file mode 100644
index 00000000..0c4499a8
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCompanyRid.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidCompanyRid'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCompanyRid'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCompanyRid'],
+ ],
+ '#theme' => 'input__os2forms_nemid_company_rid',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_company_rid' element.
+ */
+ public static function processNemidCompanyRid(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_company_rid'.
+ */
+ public static function validateNemidCompanyRid(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCompanyRid(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-company-rid']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidCpr.php b/modules/os2forms_nemid/src/Element/NemidCpr.php
new file mode 100644
index 00000000..319e066f
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidCpr.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidCpr'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidCpr'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidCpr'],
+ ],
+ '#theme' => 'input__os2forms_nemid_cpr',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_cpr' element.
+ */
+ public static function processNemidCpr(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_cpr'.
+ */
+ public static function validateNemidCpr(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidCpr(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-cpr']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidElementBase.php b/modules/os2forms_nemid/src/Element/NemidElementBase.php
new file mode 100644
index 00000000..0964a359
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidElementBase.php
@@ -0,0 +1,53 @@
+ TRUE,
+ '#size' => 60,
+ '#theme_wrappers' => ['form_element'],
+ ];
+ }
+
+ /**
+ * Prepares a render element for theme_element().
+ *
+ * @param array $element
+ * An associative array containing the properties of the element.
+ * Properties used: #title, #value, #description, #size, #maxlength,
+ * #placeholder, #required, #attributes.
+ *
+ * @return array
+ * The $element with prepared variables ready for theme_element().
+ */
+ public static function prerenderNemidElementBase(array $element) {
+ $element['#attributes']['type'] = 'text';
+ Element::setAttributes($element, [
+ 'id',
+ 'name',
+ 'value',
+ 'size',
+ 'maxlength',
+ 'placeholder',
+ ]);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidName.php b/modules/os2forms_nemid/src/Element/NemidName.php
new file mode 100644
index 00000000..307b4588
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidName.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidName'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidName'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidName'],
+ ],
+ '#theme' => 'input__os2forms_nemid_name',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_name' element.
+ */
+ public static function processNemidName(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_name'.
+ */
+ public static function validateNemidName(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidName(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-name']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidNemloginLink.php b/modules/os2forms_nemid/src/Element/NemidNemloginLink.php
new file mode 100644
index 00000000..0cc8edc9
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidNemloginLink.php
@@ -0,0 +1,38 @@
+generateLink($nemlogin_link_login_text, $nemlogin_link_logout_text);
+ $element['#title'] = $link->getText();
+ $element['#url'] = $link->getUrl();
+
+ return parent::preRenderLink($element);
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Element/NemidPid.php b/modules/os2forms_nemid/src/Element/NemidPid.php
new file mode 100644
index 00000000..baf0d341
--- /dev/null
+++ b/modules/os2forms_nemid/src/Element/NemidPid.php
@@ -0,0 +1,64 @@
+ [
+ [$class, 'processNemidPid'],
+ [$class, 'processAjaxForm'],
+ ],
+ '#element_validate' => [
+ [$class, 'validateNemidPid'],
+ ],
+ '#pre_render' => [
+ [$class, 'preRenderNemidPid'],
+ ],
+ '#theme' => 'input__os2forms_nemid_pid',
+ ];
+ }
+
+ /**
+ * Processes a 'os2forms_nemid_pid' element.
+ */
+ public static function processNemidPid(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add and manipulate your element's properties and callbacks.
+ return $element;
+ }
+
+ /**
+ * Webform element validation handler for #type 'os2forms_nemid_pid'.
+ */
+ public static function validateNemidPid(&$element, FormStateInterface $form_state, &$complete_form) {
+ // Here you can add custom validation logic.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function preRenderNemidPid(array $element) {
+ $element = parent::prerenderNemidElementBase($element);
+ static::setAttributes($element, ['form-text', 'os2forms-nemid-pid']);
+ return $element;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/EventSubscriber/NemloginRedirectSubscriber.php b/modules/os2forms_nemid/src/EventSubscriber/NemloginRedirectSubscriber.php
new file mode 100644
index 00000000..9858d82e
--- /dev/null
+++ b/modules/os2forms_nemid/src/EventSubscriber/NemloginRedirectSubscriber.php
@@ -0,0 +1,106 @@
+nemloginAuthProvider = $nemloginAuthProvider;
+ $this->account = $account;
+ }
+
+ /**
+ * Redirects to nemlogin authentication url.
+ *
+ * Only if current webform has nemlogin_auto_redirect on.
+ *
+ * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+ * The subscribed event.
+ */
+ public function redirectToNemlogin(GetResponseEvent $event) {
+ $request = $event->getRequest();
+
+ // This is necessary because this also gets called on
+ // webform sub-tabs such as "edit", "revisions", etc. This
+ // prevents those pages from redirected.
+ if ($request->attributes->get('_route') !== 'entity.webform.canonical') {
+ return;
+ }
+
+ /** @var \Drupal\webform\WebformInterface $webform */
+ $webform = $request->attributes->get('webform');
+ $webformNemidSettings = $webform->getThirdPartySetting('os2forms', 'os2forms_nemid');
+
+ // Getting nemlogin_auto_redirect setting.
+ $nemlogin_auto_redirect = NULL;
+ if (isset($webformNemidSettings['nemlogin_auto_redirect'])) {
+ $nemlogin_auto_redirect = $webformNemidSettings['nemlogin_auto_redirect'];
+ }
+
+ // Checking if $nemlogin_auto_redirect is on.
+ if ($nemlogin_auto_redirect) {
+ // Killing cache so that positive or negative redirect decision is not
+ // cached.
+ \Drupal::service('page_cache_kill_switch')->trigger();
+
+ /** @var \Drupal\os2web_nemlogin\Plugin\AuthProviderInterface $authProviderPlugin */
+ $authProviderPlugin = $this->nemloginAuthProvider->getActivePlugin();
+
+ if (!$authProviderPlugin->isAuthenticated()) {
+ // Redirect directly to the external IdP.
+ $response = new RedirectResponse($this->nemloginAuthProvider->getLoginUrl()->toString());
+ $event->setResponse($response);
+ $event->stopPropagation();
+ }
+ else {
+ \Drupal::messenger()
+ ->addMessage(t('This webform requires a valid NemID authentication and is not visible without it. You currently have an active NemID authentication session. If you do not want to proceed with this webform press log out to return back to the front page.', [
+ '@logout' => $this->nemloginAuthProvider->getLogoutUrl(['query' => ['destination' => Url::fromRoute('')->toString()]])
+ ->toString(),
+ ]));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getSubscribedEvents() {
+ $events[KernelEvents::REQUEST][] = ['redirectToNemlogin'];
+ return $events;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Plugin/WebformElement/NemidAddress.php b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidAddress.php
new file mode 100644
index 00000000..5924728b
--- /dev/null
+++ b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidAddress.php
@@ -0,0 +1,27 @@
+ '',
+ 'size' => '',
+ 'minlength' => '',
+ 'maxlength' => '',
+ 'placeholder' => '',
+ ];
+
+ return $properties;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+ // Only manipulate element on actual submission page.
+ if (!$webform_submission->isCompleted()) {
+ // Getting webform type settings.
+ $webform = $webform_submission->getWebform();
+ $webformNemidSettings = $webform->getThirdPartySetting('os2forms', 'os2forms_nemid');
+ $webform_type = NULL;
+
+ // If webform type is set, handle element visiblity.
+ if (isset($webformNemidSettings['webform_type'])) {
+ $webform_type = $webformNemidSettings['webform_type'];
+
+ $this->handleElementVisibility($element, $webform_type);
+ }
+
+ /** @var \Drupal\os2web_nemlogin\Service\AuthProviderService $authProviderService */
+ $authProviderService = \Drupal::service('os2web_nemlogin.auth_provider');
+ /** @var \Drupal\os2web_nemlogin\Plugin\AuthProviderInterface $plugin */
+ $plugin = $authProviderService->getActivePlugin();
+
+ if ($plugin->isAuthenticated()) {
+ // Handle fields visibility depending on Authorization type.
+ if ($plugin->isAuthenticatedPerson()) {
+ $this->handleElementVisibility($element, OS2FORMS_NEMID_WEBFORM_TYPE_PERSONAL);
+ }
+ if ($plugin->isAuthenticatedCompany()) {
+ $this->handleElementVisibility($element, OS2FORMS_NEMID_WEBFORM_TYPE_COMPANY);
+ }
+
+ // TODO: make a proper values fetching with Serviceplatformen.
+ $nemloginFieldKey = $this->getNemloginFieldKey();
+ $value = $plugin->fetchValue($nemloginFieldKey);
+ $element['#default_value'] = $value;
+ }
+
+ }
+
+ parent::prepare($element, $webform_submission);
+
+ // Here you can customize the webform element's properties.
+ // You can also customize the form/render element's properties via the
+ // FormElement.
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function form(array $form, FormStateInterface $form_state) {
+ $form = parent::form($form, $form_state);
+
+ // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::form
+ $element_properties = $form_state->get('element_properties');
+ // If element is new, set disabled by default.
+ if (empty($element_properties['title'])) {
+ $form['form']['disabled']['#value'] = TRUE;
+ }
+
+ // Here you can define and alter a webform element's properties UI.
+ // Form element property visibility and default values are defined via
+ // ::getDefaultProperties.
+ //
+ // @see \Drupal\webform\Plugin\WebformElementBase::form
+ // @see \Drupal\webform\Plugin\WebformElement\TextBase::form
+ return $form;
+ }
+
+ /**
+ * Handles element visibility on the webform.
+ *
+ * If element type is not corresponding with the form type, element if hidden.
+ *
+ * @param array $element
+ * Array element info.
+ * @param string $allowed_type
+ * Allowed type of the element.
+ */
+ protected function handleElementVisibility(array &$element, $allowed_type) {
+ if ($allowed_type === OS2FORMS_NEMID_WEBFORM_TYPE_PERSONAL) {
+ if ($this instanceof NemidElementCompanyInterface) {
+ $element['#access'] = FALSE;
+ }
+ }
+ elseif ($allowed_type === OS2FORMS_NEMID_WEBFORM_TYPE_COMPANY) {
+ if ($this instanceof NemidElementPersonalInterface) {
+ $element['#access'] = FALSE;
+ }
+ }
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Plugin/WebformElement/NemidElementCompanyInterface.php b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidElementCompanyInterface.php
new file mode 100644
index 00000000..c6a02ed4
--- /dev/null
+++ b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidElementCompanyInterface.php
@@ -0,0 +1,14 @@
+ [],
+ 'nemlogin_link_login_text' => 'Login with Nemlogin',
+ 'nemlogin_link_logout_text' => 'Logout from Nemlogin',
+ ] + parent::getDefaultProperties();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTranslatableProperties() {
+ return array_merge(parent::getTranslatableProperties(), ['nemlogin_link_login_text', 'nemlogin_link_logout_text']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function form(array $form, FormStateInterface $form_state) {
+ $form = parent::form($form, $form_state);
+ $form['markup']['#title'] = $this->t('OS2Forms Nemlogin Link settings');
+ $form['markup']['nemlogin_link_login_text'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Nemlogin link login text'),
+ '#required' => TRUE,
+ ];
+ $form['markup']['nemlogin_link_logout_text'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Nemlogin link logout text'),
+ '#required' => TRUE,
+ ];
+
+ return $form;
+ }
+
+}
diff --git a/modules/os2forms_nemid/src/Plugin/WebformElement/NemidPid.php b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidPid.php
new file mode 100644
index 00000000..74381847
--- /dev/null
+++ b/modules/os2forms_nemid/src/Plugin/WebformElement/NemidPid.php
@@ -0,0 +1,27 @@
+get('entity_print.settings');
+ $severity = REQUIREMENT_OK;
+ if (!empty($config) && \Drupal::moduleHandler()->moduleExists('webform_entity_print_attachment')) {
+ $messages = [
+ '#prefix' => t('Entity print configuration'),
+ '#theme' => 'item_list',
+ '#items' => [],
+ ];
+ foreach (['pdf', 'word_docx'] as $type) {
+ $library = $config->get('print_engines.' . $type . '_engine');
+ if (empty($library)) {
+ $severity = REQUIREMENT_WARNING;
+ $library = t('EMPTY');
+ }
+ $messages['#items'][] = $library_status = t('Engine @type: @value', [
+ '@type' => $type,
+ '@value' => $library,
+ ]);
+ }
+ $messages = \Drupal::service('renderer')->renderPlain($messages);
+ }
+ else {
+ $messages = t('Webform Entity Print Attachment module is not enabled');
+ $severity = REQUIREMENT_WARNING;
+ }
+ $requirements['os2forms'] = [
+ 'title' => t('os2forms'),
+ 'severity' => $severity,
+ 'value' => $messages,
+ ];
+ return $requirements;
+}
diff --git a/os2forms.module b/os2forms.module
new file mode 100644
index 00000000..c6f355cc
--- /dev/null
+++ b/os2forms.module
@@ -0,0 +1,21 @@
+ 'details',
+ '#title' => t('OS2Forms'),
+ '#open' => TRUE,
+ '#description' => t('OS2Forms related settings'),
+ ];
+}