sample code

This commit is contained in:
2022-10-13 11:55:19 -04:00
commit bde8aa5e5d
67 changed files with 6421 additions and 0 deletions
@@ -0,0 +1,9 @@
name: AMCPR User Profile
type: module
description: 'Handles AMCPR user profiles.'
core_version_requirement: ^8.9 || ^9
package: 'AMCPR Profile'
dependencies:
- profile:profile
- amcpr_content:amcpr_content
- amcpr_components:amcpr_components
@@ -0,0 +1,32 @@
<?php
/**
* @file
* This file contains installation and update hooks.
*/
use Drupal\Core\Entity\EntityStorageException;
use Drupal\user\Entity\Role;
/**
* Implements hook_install().
*/
function amcpr_user_profile_install($is_syncing) {
$rids = ['screener', 'reviewer'];
$roles = Role::loadMultiple($rids);
foreach ($rids as $rid) {
if (!isset($roles[$rid])) {
try {
/** @var \Drupal\user\RoleInterface $role */
$role = Role::create([
'id' => 'reviewer',
'label' => 'Reviewer'
]);
$role->save();
}
catch (EntityStorageException $e) {
}
}
}
}
@@ -0,0 +1,5 @@
supplier-wizard:
version: 1.x
css:
theme:
css/supplier-wizard.css: {}
@@ -0,0 +1,7 @@
amcpr_user_profile.admin_config:
title: 'AMCPR Supplier Generic Email Servers'
description: 'Configure AMCPR Supplier Email Server settings'
parent: amcpr_components.admin_config_section
route_name: amcpr_user_profile.manage_supplier_settings
weight: -100
@@ -0,0 +1,25 @@
# Personal Profile View Tab
amcpr_user_profile.profile_view:
title: 'View'
route_name: amcpr_user_profile.profile
base_route: amcpr_user_profile.profile
# Personal Profile Edit Tab
amcpr_user_profile.profile_edit:
title: 'Edit'
route_name: amcpr_user_profile.profile_edit
base_route: amcpr_user_profile.profile
# Supplier Profile View Tab
amcpr_user_profile.profile_supplier_view:
title: 'View'
route_name: amcpr_user_profile.profile_supplier
base_route: amcpr_user_profile.profile_supplier
# Supplier Profile Edit Tab
amcpr_user_profile.profile_supplier_edit:
title: 'Edit'
route_name: amcpr_user_profile.profile_supplier_edit
base_route: amcpr_user_profile.profile_supplier
@@ -0,0 +1,472 @@
<?php
/**
* @file
* Main module file of the AMCPR User Profile module.
*
* This module helps implement AMCPR user profiles.
*/
use Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatch;
use Drupal\Core\Url;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\amcpr_audit\Utility\AuditUtility;
const AMCPR_SUPPLIER_REPO = 'amcprqrepo';
/**
* Implements hook_entity_type_build().
*/
function amcpr_user_profile_entity_type_build(array &$entity_types) {
/** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
$entity_types['profile']->setFormClass('dashboard', 'Drupal\profile\Form\ProfileForm');
$entity_types['profile']->setFormClass('wizard', 'Drupal\profile\Form\ProfileForm');
$entity_types['profile']->setFormClass('wizard_step_1', 'Drupal\profile\Form\ProfileForm');
$entity_types['profile']->setFormClass('wizard_step_2', 'Drupal\profile\Form\ProfileForm');
$entity_types['profile']->setFormClass('wizard_step_3', 'Drupal\profile\Form\ProfileForm');
$entity_types['profile']->setFormClass('wizard_step_4', 'Drupal\profile\Form\ProfileForm');
$entity_types['profile']->setFormClass('wizard_step_5', 'Drupal\profile\Form\ProfileForm');
}
/**
* Implements hook_form_FORM_ID_alter().
* Redirect users to front page after registration.
*/
function amcpr_user_profile_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['#attributes']['autocomplete'] = 'off';
$form['actions']['submit']['#submit'][] = 'amcpr_user_profile_user_register_form_submit_redirect';
}
/**
* User register form callback.
*/
function amcpr_user_profile_user_register_form_submit_redirect(&$form, FormStateInterface $form_state) {
$form_state->setRedirect('<front>');
$form_state->disableRedirect(FALSE);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function amcpr_user_profile_form_profile_personal_wizard_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['field_business_category']['#states'] = [
'visible' => [
':input[name="field_represent_company[value]"]' => ['checked' => TRUE],
],
];
/*
$form['field_company_name']['#states'] = [
'visible' => [
':input[name="field_represent_company[value]"]' => ['checked' => TRUE],
],
];
*/
foreach (array_keys($form['actions']) as $action) {
if ($action == 'submit' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
array_unshift($form['actions'][$action]['#submit'], 'amcpr_user_profile_form_profile_personal_wizard_form_submit_before');
$form['actions'][$action]['#submit'][] = 'amcpr_user_profile_form_profile_personal_wizard_form_submit_after';
$form['actions'][$action]['#value'] = t('Next');
$form['actions'][$action]['#weight'] = 10;
break;
}
}
$form['actions']['previous'] = [
'#type' => 'submit',
'#value' => t('Back'),
'#submit' => [
'amcpr_user_profile_form_profile_personal_wizard_form_submit_previous'
],
'#weight' => 0,
];
}
/**
* Previous/Back button submit handler callback.
*/
function amcpr_user_profile_form_profile_personal_wizard_form_submit_previous(array $form, FormStateInterface $form_state) {
$form_state->setRedirect('amcpr_user_profile.profile_wizard');
}
/**
* Save/Next button submit handler callback.
* Executes before other submit handlers.
* @see \Drupal\profile\Form\ProfileForm::save()
*/
function amcpr_user_profile_form_profile_personal_wizard_form_submit_before(array $form, FormStateInterface $form_state) {
// Disables all redirects initiated by saving the profile entity.
$form_state->disableRedirect();
}
/**
* Save/Next button submit handler callback.
* Executes last after all other submit handlers.
*/
function amcpr_user_profile_form_profile_personal_wizard_form_submit_after(array $form, FormStateInterface $form_state) {
$errors = $form_state->getErrors();
// We disabled all previous redirects so that we can inject our own.
if (!$errors) {
if ($form_state->get('skip_supplier') == null || !$form_state->get('skip_supplier')) {
// Advance form to Step 3: Supplier Prompt
$form_state->setRedirect('amcpr_user_profile.profile_wizard_supplier_prompt');
} else {
// The user is already associated with a supplier (based on email domain)
// Advance form to Step 4: Profile wizard end
$form_state->setRedirect('amcpr_user_profile.profile_wizard_finish');
}
$form_state->disableRedirect(FALSE);
}
}
/**
* Implements hook_user_login().
*/
function amcpr_user_profile_user_insert(Drupal\user\Entity\User $entity){
AuditUtility::audit('User Registration','INFO', $entity->get('uid')->getString());
}
/**
* Implements hook_user_login().
*/
function amcpr_user_profile_user_login(UserInterface $account) {
// Don't force the user to go through the Profile wizard on password resets.
$route = RouteMatch::createFromRequest(\Drupal::request());
if ($route->getRouteName() === 'user.reset.login') {
return;
}
// Redirect the user to the Profile wizard if their profile is not complete.
// A flag to indicate incompleteness is set at the time of registration.
$isIncompleteFlag = $account->get('field_profile_incomplete')->getValue();
// See if the flag value is set to ON (numerical 1).
// It means the user has not completed their profile.
if (!empty($isIncompleteFlag) && $isIncompleteFlag[0]['value']) {
$response = new RedirectResponse(URL::fromRoute('amcpr_user_profile.profile_wizard')
->toString());
//$response->send();
}
// A destination was set, probably on an exception controller,
elseif (!\Drupal::request()->query->has('destination')) {
$response = new RedirectResponse(URL::fromRoute('<front>')->toString());
}
else {
$response = new RedirectResponse(\Drupal::request()->query->get('destination'));
}
//$response->send();
// Updating to 9.2 broke sending redirect response from hook_user_login.
// See https://www.drupal.org/project/drupal/issues/2852657#comment-14151263.
\Drupal::service('request_stack')
->getCurrentRequest()
->query->set('destination', $response->getTargetUrl());
}
/**
* Implements hook_form_alter().
*/
function amcpr_user_profile_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// For the ability to change the supplier profile based on email server, restrict user's ability to alter their email address once set
if ($form_id == 'user_form'){
$user = \Drupal::currentUser();
if (!$user->hasPermission('amcpr repo admin')){
$form['account']['mail']['#disabled'] = true;
$form['account']['mail']['#description'] = t('Only AMCPR Administrators can change an email address.');
}
}
if (!preg_match('/^profile_supplier_wizard_step_(\d+)_form$/', $form_id)) {
return;
}
$step = $form_state->get('step');
foreach (array_keys($form['actions']) as $action) {
if ($action == 'submit' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
array_unshift($form['actions'][$action]['#submit'], 'amcpr_user_profile_form_profile_supplier_wizard_form_submit_disable');
$form['actions'][$action]['#submit'][] = 'amcpr_user_profile_form_profile_supplier_wizard_form_submit_next';
$form['actions'][$action]['#value'] = ($step < SupplierProfileWizardController::MAX_STEPS)
? t('Next')
: t('Submit');
if ($step >= SupplierProfileWizardController::MAX_STEPS) {
$form['actions'][$action]['#submit'][] = 'amcpr_user_profile_create_supplier_in_repo';
}
$form['actions'][$action]['#weight'] = 10;
break;
}
}
if ($step > 1) {
$form['actions']['previous'] = [
'#type' => 'submit',
'#value' => t('Back'),
'#submit' => [
'amcpr_user_profile_form_profile_supplier_wizard_form_submit_previous'
],
'#weight' => 0,
];
}
$form['#attached']['library'][] = 'amcpr_user_profile/supplier-wizard';
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function amcpr_user_profile_form_profile_supplier_dashboard_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Add an additional submit handler to disable redirects after this form
// is submitted. Make sure our submit handler is first to execute.
array_unshift($form['actions']['submit']['#submit'], 'amcpr_user_profile_submit_handler_disable_redirect');
$form['actions']['submit']['#submit'][] = 'amcpr_user_profile_form_profile_supplier_dashboard_redirect';
$form['actions']['submit']['#submit'][] = 'amcpr_user_profile_push_to_qex';
}
function amcpr_user_profile_form_profile_supplier_dashboard_redirect(array $form, FormStateInterface $form_state) {
$form_state->setRedirect('amcpr_user_profile.profile_supplier_edit');
$form_state->disableRedirect(FALSE);
}
/**
* Previous/Back button submit handler callback.
*
*/
function amcpr_user_profile_form_profile_supplier_wizard_form_submit_previous(array $form, FormStateInterface $form_state) {
$step = $form_state->get('step');
$form_state->setRedirect(SupplierProfileWizardController::getPreviousRoute($step));
}
/**
* Save/Next button submit handler callback.
* Executes before other submit handlers.
* @see \Drupal\profile\Form\ProfileForm::save()
*/
function amcpr_user_profile_form_profile_supplier_wizard_form_submit_disable(array $form, FormStateInterface $form_state) {
// Disables all redirects initiated by saving the profile entity.
$form_state->disableRedirect();
}
/**
* Appended to the end of callbacks if it was the last step of the supplier
*/
function amcpr_user_profile_create_supplier_in_repo(array $form, FormStateInterface $form_state) {
$errors = $form_state->getErrors();
if (!$errors) {
amcpr_user_profile_create_supplier_from_current_user();
}
}
/**
* Save/Next button submit handler callback.
* Executes last after all other submit handlers.
*/
function amcpr_user_profile_form_profile_supplier_wizard_form_submit_next(array $form, FormStateInterface $form_state) {
$errors = $form_state->getErrors();
// We disabled all previous redirects so that we can inject our own.
// Advance form to next step.
if (!$errors) {
$step = $form_state->get('step');
$form_state->setRedirect(SupplierProfileWizardController::getNextRoute($step));
$form_state->disableRedirect(FALSE);
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function amcpr_user_profile_form_profile_personal_dashboard_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['field_business_category']['#states'] = [
'visible' => [
':input[name="field_represent_company[value]"]' => ['checked' => TRUE],
],
];
/*
$form['field_company_name']['#states'] = [
'visible' => [
':input[name="field_represent_company[value]"]' => ['checked' => TRUE],
],
];
*/
$form_state->setRedirect('amcpr_user_profile.profile');
$form['actions']['submit']['#submit'][] = 'amcpr_user_profile_form_profile_personal_dashboard_redirect';
}
function amcpr_user_profile_form_profile_personal_dashboard_redirect(array $form, FormStateInterface $form_state) {
$form_state->setRedirect('amcpr_user_profile.profile');
$form_state->disableRedirect(FALSE);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function amcpr_user_profile_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id) {
/** @var Drupal\user\Entity\User $user */
$user = User::load(\Drupal::currentUser()->id());
$passResetToken = \Drupal::request()->query->get('pass-reset-token');
// User could be resetting password using a one-tine link. Tweak the form accordingly.
if ($passResetToken) {
_amcpr_user_profile_form_user_form_alter_scenario_reset($form, $form_state, $user);
}
// Add an additional submit handler to disable redirects after this form
// is submitted. Make sure our submit handler is first to execute.
array_unshift($form['actions']['submit']['#submit'], 'amcpr_user_profile_submit_handler_disable_redirect');
}
function _amcpr_user_profile_form_user_form_alter_scenario_reset(&$form, FormStateInterface $form_state, Drupal\user\Entity\User $user) {
$form['#title'] = t('Password reset');
$form['actions']['submit']['#value'] = t('Update');
// Remove some form items when the form is being accessed via one-time link.
unset($form['field_user_avatar']);
unset($form['account']['mail']);
// Determine whether the User is resetting password during the very first
// log in (post registration).
// A flag is set automatically at the time of registration to indicate
// the user has not set their password yet.
// Fetch the value of the password flag.
$isNotSetFlag = $user->get('field_password_not_set')->getValue();
// See if the field value is set to ON (numerical 1).
// It means the user has not set their first password.
if (!empty($isNotSetFlag) && $isNotSetFlag[0]['value']) {
// Add an additional submit handler to remove the flag once the password is set.
$form['actions']['submit']['#submit'][] = 'amcpr_user_profile_submit_handler_remove_password_flag';
}
// Log the user out after they reset their password.
$form['actions']['submit']['#submit'][] = 'amcpr_user_profile_submit_handler_logout';
}
/**
* Submit handler to disable redirect after form submission.
*/
function amcpr_user_profile_submit_handler_disable_redirect(array $form, FormStateInterface $form_state) {
// Disables all redirects initiated by the form's default submit handler.
$form_state->disableRedirect();
}
/**
* Submit handler callback for User Form.
* Removes password flag once the user sets their password.
* @throws EntityStorageException
*/
function amcpr_user_profile_submit_handler_remove_password_flag(array $form, FormStateInterface $form_state) {
$errors = $form_state->getErrors();
if (!$errors) {
$user = User::load(\Drupal::currentUser()->id());
$user->set('field_password_not_set', 0);
$user->save();
}
}
/**
* Submit handler callback for User Form.
* Logs the user out.
*/
function amcpr_user_profile_submit_handler_logout(array $form, FormStateInterface $form_state) {
$errors = $form_state->getErrors();
if (!$errors) {
$form_state->setRedirect(
'user.logout',
['logout_method' => 'reset']
);
$form_state->disableRedirect(FALSE);
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function amcpr_user_profile_form_user_login_form_alter(&$form, FormStateInterface $form_state) {
$form['reset_password_link'] = [
'#type' => 'link',
'#title' => t('Reset Password'),
'#url' => Url::fromRoute('user.pass'),
'#weight' => 100,
];
}
/**
* Implements hook_menu_local_tasks_alter().
*/
function amcpr_user_profile_menu_local_tasks_alter(&$data, $route_name) {
if (!empty($data['tabs'])) {
if ($route_name == 'user.login'
|| $route_name == 'user.register'
|| $route_name == 'user.pass') {
if ( isset($data['tabs'][0]['user.login']) ) {
unset($data['tabs'][0]['user.login']);
}
if ( isset($data['tabs'][0]['user.register']) ) {
unset($data['tabs'][0]['user.register']);
}
if ( isset($data['tabs'][0]['user.pass']) ) {
unset($data['tabs'][0]['user.pass']);
}
}
if ($route_name == 'entity.user.canonical'
|| $route_name == 'entity.user.edit_form'
|| $route_name == 'profile.user_page.single') {
$tabs = array_keys($data['tabs'][0]);
foreach ($tabs as $tab) {
unset($data['tabs'][0][$tab]);
}
}
}
}
/**
* Implements hook_inline_entity_form_table_fields_alter().
*/
function amcpr_user_profile_inline_entity_form_table_fields_alter(&$fields, $context) {
if ($context['entity_type'] == 'node') {
$fields['label']['label'] = t('Make');
$fields['field_equipment_m'] = [
'type' => 'field',
'label' => t('Model'),
'weight' => 101,
];
$fields['field_equipment_quantity'] = [
'type' => 'field',
'label' => t('Quantity'),
'weight' => 110,
];
unset($fields['status']);
}
}
@@ -0,0 +1,198 @@
amcpr_user_profile.manage_supplier_settings:
path: '/admin/config/supplier_settings'
defaults:
_form: '\Drupal\amcpr_user_profile\Form\SupplierSettingsForm'
_title: 'Manage Supplier Rules'
requirements:
_permission: 'amcpr repo admin'
amcpr_user_profile.profile_wizard_exit:
path: '/profile/wizard/exit'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\PersonalProfileWizardController::exitCompleteProfileWizard'
_title: 'Exit Profile Wizard'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Wizard: Step 1
amcpr_user_profile.profile_wizard:
path: '/profile/wizard'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\PersonalProfileWizardController::showCompleteProfileWizard'
_title: 'Complete Your Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Wizard: Step 2
amcpr_user_profile.profile_wizard_additional_info:
path: '/profile/wizard/additional-info'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\PersonalProfileWizardController::showAdditionalProfileInfoWizard'
_title: 'Complete Your Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Wizard: Step 3
amcpr_user_profile.profile_wizard_supplier_prompt:
path: '/profile/wizard/supplier_prompt'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\PersonalProfileWizardController::showSupplierPromptWizard'
_title: 'Complete Your Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Wizard: Step 4a
amcpr_user_profile.profile_wizard_finish:
path: '/profile/wizard/finish'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\PersonalProfileWizardController::finishCompleteProfileWizard'
_title: 'Complete Your Profile'
continue_supplier: FALSE
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Wizard: Step 4b
amcpr_user_profile.profile_wizard_continue_supplier:
path: '/profile/wizard/supplier-info'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\PersonalProfileWizardController::finishCompleteProfileWizard'
_title: 'Complete Your Profile'
continue_supplier: 'TRUE'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Supplier Profile Wizard: Step 1
amcpr_user_profile.supplier_profile_wizard:
path: '/profile/supplier/wizard'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController::business'
_title: 'Create Supplier Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Supplier Profile Wizard: Step 2
amcpr_user_profile.supplier_profile_wizard_certifications:
path: '/profile/supplier/wizard/certifications'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController::certifications'
_title: 'Create Supplier Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Supplier Profile Wizard: Step 3
amcpr_user_profile.supplier_profile_wizard_materials:
path: '/profile/supplier/wizard/materials'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController::materials'
_title: 'Create Supplier Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Supplier Profile Wizard: Step 4
amcpr_user_profile.supplier_profile_wizard_equipments:
path: '/profile/supplier/wizard/equipments'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController::equipments'
_title: 'Create Supplier Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Supplier Profile Wizard: Step 5
amcpr_user_profile.supplier_profile_wizard_specialities:
path: '/profile/supplier/wizard/specialities'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController::specialities'
_title: 'Create Supplier Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Supplier Profile Wizard: Step 6
amcpr_user_profile.supplier_profile_wizard_finish:
path: '/profile/supplier/wizard/finish'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\SupplierProfileWizardController::finishWizard'
_title: 'Create Supplier Profile'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Account Settings Form
amcpr_user_profile.account_preferences:
path: '/account/preferences'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::accountPreferences'
_title: 'Account Preferences'
requirements:
_role: 'authenticated'
options:
no_cache: 'TRUE'
# Personal Profile Page
amcpr_user_profile.profile:
path: '/account/profile'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::personal'
_title: 'Personal Profile'
requirements:
_custom_access: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::profileAccess'
options:
no_cache: 'TRUE'
# Personal Profile Form
amcpr_user_profile.profile_edit:
path: '/account/profile/edit'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::personalForm'
_title: 'Personal Profile'
requirements:
_custom_access: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::profileAccess'
options:
no_cache: 'TRUE'
# Supplier Profile Page
amcpr_user_profile.profile_supplier:
path: '/account/profile/supplier'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::supplier'
_title: 'Supplier Profile'
requirements:
_custom_access: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::supplierProfileAccess'
options:
no_cache: 'TRUE'
# Supplier Profile Form
amcpr_user_profile.profile_supplier_edit:
path: '/account/profile/supplier/edit'
defaults:
_controller: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::supplierForm'
_title: 'Supplier Profile'
requirements:
_custom_access: '\Drupal\amcpr_user_profile\Controller\ProfileDashboardController::supplierProfileAccess'
options:
no_cache: 'TRUE'
@@ -0,0 +1,18 @@
# Register our Route Subscriber
services:
amcpr_user_profile.route_subscriber:
class: Drupal\amcpr_user_profile\Routing\ProfileRouteSubscriber
tags:
- { name: event_subscriber }
amcpr_user_profile.request_event_subscriber:
class: Drupal\amcpr_user_profile\EventSubscriber\RequestEventSubscriber
arguments: ['@current_user']
tags:
- { name: event_subscriber }
amcpr.user.utility:
class: Drupal\amcpr_user_profile\Service\UserProfileService
arguments: ['@entity_type.manager', '@current_user']
tags:
- { name: amcpr }
@@ -0,0 +1,18 @@
/**
*Primary Material Experience Step
*/
#profile-supplier-wizard-step-3-form .layout__region.layout__region--second {
margin: 0 1.5em;
}
@media screen and (min-width: 40em) {
#profile-supplier-wizard-step-3-form .layout__region.layout__region--first,
#profile-supplier-wizard-step-3-form .layout__region.layout__region--third {
flex: 0 1 31%;
}
#profile-supplier-wizard-step-3-form .layout__region.layout__region--second {
flex: 0 1 32%;
}
}
@@ -0,0 +1,212 @@
<?php
namespace Drupal\amcpr_user_profile\Controller;
use Drupal\amcpr_user_profile\UserProfileServiceInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
class PersonalProfileWizardController extends ControllerBase {
/**
* @var \Drupal\amcpr_user_profile\UserProfileServiceInterface
*/
protected $amcprUserService;
/**
* @var \Drupal\Core\TempStore\PrivateTempStore
*/
protected $tempStore;
/**
* Constructs a new PersonalProfileWizardController.
*
* @param \Drupal\amcpr_user_profile\UserProfileServiceInterface $user_profile_service
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The temp store factory.
*/
public function __construct(UserProfileServiceInterface $user_profile_service, PrivateTempStoreFactory $temp_store_factory) {
// Initialize private members.
$this->currentUser();
$this->messenger();
$this->entityTypeManager();
$this->entityFormBuilder();
$this->amcprUserService = $user_profile_service;
$this->tempStore = $temp_store_factory->get('amcpr_profile_controller');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('amcpr.user.utility'),
$container->get('tempstore.private')
);
}
/**
* Present a wizard to complete profile.
*
* @param bool $show_exit_meesage
* Show a message if the flag is set to TRUE.
*
* @param string $route_name
* The name of the route to which to redirect.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function exitCompleteProfileWizard($show_exit_meesage = TRUE, $route_name = '<front>') {
$this->tempStore->delete('step');
if ($show_exit_meesage) {
$this->messenger->addMessage($this->t('You have exited from completing the profile.'));
}
return $this->redirect($route_name);
}
/**
* Step 1:
* Present a wizard to complete profile.
*
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function showCompleteProfileWizard() {
if ($this->amcprUserService->isProfileIncomplete()) {
$this->tempStore->set('step', 1);
}
else {
$this->messenger->addMessage($this->t('Your profile has been completed already.'));
return $this->exitCompleteProfileWizard(FALSE);
}
return [
'#title' => $this->t("Let's Complete Your Profile"),
'#theme' => 'amcpr_profile_wizard',
'#profiles' => $this->amcprUserService->getProfileTypes(),
'#lead_text' => $this->t('Completing your profile will allow you to be a...'),
'#next_step_path' => Url::fromRoute('amcpr_user_profile.profile_wizard_additional_info')->toString(),
'#exit_wizard_path' => Url::fromRoute('amcpr_user_profile.profile_wizard_exit')->toString(),
];
}
/**
* Step 2:
* Present the Additional Information step in the Complete Profile wizard.
*
* @throws \Drupal\Core\TempStore\TempStoreException
* @throws \Exception
*/
public function showAdditionalProfileInfoWizard() {
$step = $this->tempStore->get('step');
// Need to start at step 1.
if (!$step && $step != 1) {
return $this->redirect('amcpr_user_profile.profile_wizard');
}
// get user personal profile
$personalProfile = $this->amcprUserService->getPersonalProfile();
if (!$personalProfile) {
$this->messenger->addError($this->t('Registration error... Error code 1200-01.'));
return $this->exitCompleteProfileWizard(FALSE);
}
// Advance current step.
if ($this->amcprUserService->getSupplierProfile(FALSE) == null) {
//User's email domain is not associated with a supplier, ask if they want to create supplier profile
$this->tempStore->set('step', 2);
$skipSupplier = false;
} else {
//Email is already associated with a supplier, skip supplier step (handled in amcpr_user_profile_form_profile_personal_wizard_form_submit_after)
$this->tempStore->set('step', 3);
$skipSupplier = true;
}
$form = $this->entityFormBuilder->getForm($personalProfile, 'wizard', ['skip_supplier' => $skipSupplier]);
/** @var \Drupal\Core\Render\Renderer $renderer */
$renderer = \Drupal::service('renderer');
return [
'#title' => $this->t("Let's Complete Your Profile"),
'#theme' => 'amcpr_profile_wizard_form',
'#form_title' => $this->t("Additional Profile Information"),
//'#form' => $renderer->render($form),
'#form' => $form,
];
}
/**
* Step 3:
* Present the Supplier Prompt step in the Complete Profile wizard.
*
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function showSupplierPromptWizard() {
$step = $this->tempStore->get('step');
// Should come from step 2.
if (!$step && $step != 2) {
return $this->redirect('amcpr_user_profile.profile_wizard');
}
// Advance current step.
$this->tempStore->set('step', 3);
return [
'#title' => $this->t('Thank you for updating your information!'),
'#theme' => 'amcpr_profile_wizard_prompt',
'#prompt_title' => $this->t("Do you represent a manufacturing organization (supplier)?"),
'#prompt_text' => $this->t("If so, we need some additional information before we can help connect you with organizations in need."),
'#confirm' => [
'text' => $this->t('Yes'),
'path' => Url::fromRoute('amcpr_user_profile.profile_wizard_continue_supplier')->toString(),
],
'#cancel' => [
'text' => $this->t('No'),
'path' => Url::fromRoute('amcpr_user_profile.profile_wizard_finish')->toString(),
]
];
}
/**
* Step 4
* End of complete profile wizard. Update flags accordingly.
*
* @param bool $continue_supplier
* A boolean flag indicating whether to advance to supplier profile info.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function finishCompleteProfileWizard(bool $continue_supplier) {
$step = $this->tempStore->get('step');
// Should come from step 3.
if (!$step && $step != 3) {
return $this->redirect('amcpr_user_profile.profile_wizard');
}
// Unset incomplete profile flag.
$this->amcprUserService->removeProfileIncompleteFlag();
$this->amcprUserService->killUserPrimaryNavBlockCache();
$this->messenger->addMessage($this->t('You have have completed your profile.'));
if (!$continue_supplier) {
return $this->exitCompleteProfileWizard(FALSE);
}
else {
return $this->exitCompleteProfileWizard(FALSE, 'amcpr_user_profile.supplier_profile_wizard');
}
}
}
@@ -0,0 +1,189 @@
<?php
namespace Drupal\amcpr_user_profile\Controller;
use Drupal\amcpr_user_profile\UserProfileServiceInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ProfileDashboardController extends ControllerBase {
/**
* @var \Drupal\amcpr_user_profile\UserProfileServiceInterface
*/
protected $amcprUserService;
/**
* Constructs a new ProfileDashboardController.
*
* @param \Drupal\amcpr_user_profile\UserProfileServiceInterface $user_profile_service
*/
public function __construct(UserProfileServiceInterface $user_profile_service) {
// Initialize private members.
$this->currentUser();
$this->messenger();
$this->entityTypeManager();
$this->entityFormBuilder();
$this->amcprUserService = $user_profile_service;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('amcpr.user.utility')
);
}
/**
* @deprecated
*
* @return array
* Renderable array.
*/
public function account() {
return [
'#markup' => '<h3>Deprecated.</h3>',
];
}
/**
* @return array
* Renderable array.
*/
public function accountPreferences() {
$user = $this->amcprUserService->getCurrentUser();
if ($user) {
$form = $this->entityFormBuilder->getForm($user, 'default');
// These elements should only be rendered on the admin interface.
unset($form['account']['name']);
unset($form['account']['status']);
unset($form['account']['roles']);
unset($form['account']['notify']);
return $form;
}
else {
return [
'#markup' => '<h3>Something went wrong.</h3>',
];
}
}
/**
* @return array
* Renderable array.
*/
public function personal() {
if (empty($this->currentUser()->id())){
return $this->redirect('user.login');
}
$personalProfile = $this->amcprUserService->getPersonalProfile();
$builder = $this->amcprUserService->getProfileViewBuilder();
$build = [];
$build['entity'] = [
'entity' => $builder->view($personalProfile, 'default')
];
return $build;
}
/**
* @return array
* Renderable array.
*/
public function personalForm() {
$personalProfile = $this->amcprUserService->getPersonalProfile(TRUE);
return $this->entityFormBuilder->getForm($personalProfile, 'dashboard');
}
/**
* @return array
* Renderable array.
*/
public function supplier() {
$supplierProfile = $this->amcprUserService->getSupplierProfile();
$builder = $this->amcprUserService->getProfileViewBuilder();
$build = [];
$build['entity'] = [
'entity' => $builder->view($supplierProfile, 'default')
];
return $build;
}
/**
* @return array
* Renderable array.
*/
public function supplierForm() {
$currUserEmail = \Drupal::currentUser()->getEmail();
$currUserServer = strtolower(substr($currUserEmail, strpos($currUserEmail, "@") + 1));
$configName = (\Drupal\amcpr_user_profile\Form\SupplierSettingsForm::CONFIG_NAME);
$config = \Drupal::config($configName);
$serverListString = $config->get('server_list');
$serverListArray = preg_split('/(,|\r\n|\n|\r| )/', $serverListString);
$isInServerList = FALSE;
foreach($serverListArray as $indivServer){
if (strtolower($indivServer) == $currUserServer){
$isInServerList = TRUE;
}
}
if (!$isInServerList){
\Drupal::messenger()->addStatus(t('This is the supplier information for all users who have the email ending in @:thing.', [':thing' => $currUserServer]));
}
$supplierProfile = $this->amcprUserService->getSupplierProfile();
return $this->entityFormBuilder->getForm($supplierProfile, 'dashboard');
}
/**
* Checks access for personal profile request.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function profileAccess() {
return AccessResult::allowedIf(!$this->amcprUserService->isProfileIncomplete());
}
/**
* Checks access for supplier profile request.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function supplierProfileAccess() {
return AccessResult::allowedIf(!$this->amcprUserService->isProfileIncomplete() && !$this->amcprUserService->isSupplierProfileIncomplete());
}
private function completeProfilePrompt() {
return [
'#theme' => 'amcpr_profile_wizard_prompt',
'#prompt_title' => $this->t("Your profile is incomplete."),
'#prompt_text' => $this->t("Do you wish to complete it now?"),
'#confirm' => [
'text' => $this->t('Yes'),
'path' => Url::fromRoute('amcpr_user_profile.profile_wizard')->toString(),
],
];
}
private function completeSupplierProfilePrompt() {
return [
'#theme' => 'amcpr_profile_wizard_prompt',
'#prompt_title' => $this->t("You have not created a supplier profile."),
'#prompt_text' => $this->t("Do you wish to create it now?"),
'#confirm' => [
'text' => $this->t('Yes'),
'path' => Url::fromRoute('amcpr_user_profile.supplier_profile_wizard')->toString(),
],
];
}
}
@@ -0,0 +1,88 @@
<?php
namespace Drupal\amcpr_user_profile\Controller;
use Drupal\Component\Utility\Crypt;
use Drupal\user\Controller\UserController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
* Controller routines for overridden user routes.
* @see \Drupal\amcpr_user_profile\Routing\ProfileRouteSubscriber
*/
class ProfileUserController extends UserController {
/**
* @param string $logout_method
* @return RedirectResponse
*/
public function customLogout($logout_method = 'user') {
$this->logout();
$logout_method = strtolower($logout_method);
if ($logout_method === 'reset') {
return $this->redirect('<front>', [], ['query' => ['method' => 'reset']]);
}
else {
return $this->redirect('<front>');
}
}
/**
* {@inheritdoc}
*/
public function userPage() {
return $this->redirect('amcpr_user_profile.account_preferences');
}
/**
* {@inheritdoc}
*/
public function resetPassLogin($uid, $timestamp, $hash) {
//@TODO reduce duplicated code by calling parent method.
// The current user is not logged in, so check the parameters.
$current = REQUEST_TIME;
/** @var \Drupal\user\UserInterface $user */
$user = $this->userStorage->load($uid);
// Verify that the user exists and is active.
if ($user === NULL || !$user->isActive()) {
// Blocked or invalid user ID, so deny access. The parameters will be in
// the watchdog's URL for the administrator to check.
throw new AccessDeniedHttpException();
}
// Time out, in seconds, until login URL expires.
$timeout = $this->config('user.settings')->get('password_reset_timeout');
// No time out for first time login.
if ($user->getLastLoginTime() && $current - $timestamp > $timeout) {
$this->messenger()->addError($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'));
return $this->redirect('user.pass');
}
elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && hash_equals($hash, user_pass_rehash($user, $timestamp))) {
user_login_finalize($user);
$this->logger->notice('User %name used one-time login link at time %timestamp.', ['%name' => $user->getDisplayName(), '%timestamp' => $timestamp]);
$this->messenger()->addStatus($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
// Let the user's password be changed without the current password
// check.
$token = Crypt::randomBytesBase64(55);
$_SESSION['pass_reset_' . $user->id()] = $token;
// Clear any flood events for this user.
$this->flood->clear('user.password_request_user', $uid);
return $this->redirect(
'amcpr_user_profile.account_preferences',
[],
[
'query' => ['pass-reset-token' => $token],
'absolute' => TRUE,
]
);
}
$this->messenger()->addError($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'));
return $this->redirect('user.pass');
}
}
@@ -0,0 +1,240 @@
<?php
namespace Drupal\amcpr_user_profile\Controller;
use Drupal\amcpr_user_profile\UserProfileServiceInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
class SupplierProfileWizardController extends ControllerBase {
const MAX_STEPS = 5;
const ROUTES = [
1 => 'amcpr_user_profile.supplier_profile_wizard',
2 => 'amcpr_user_profile.supplier_profile_wizard_certifications',
3 => 'amcpr_user_profile.supplier_profile_wizard_materials',
4 => 'amcpr_user_profile.supplier_profile_wizard_equipments',
5 => 'amcpr_user_profile.supplier_profile_wizard_specialities',
6 => 'amcpr_user_profile.supplier_profile_wizard_finish',
];
/**
* @var \Drupal\amcpr_user_profile\UserProfileServiceInterface
*/
protected $amcprUserService;
/**
* @var \Drupal\Core\TempStore\PrivateTempStore
*/
protected $tempStore;
/**
* Constructs a new SupplierProfileWizardController.
*
* @param \Drupal\amcpr_user_profile\UserProfileServiceInterface $user_profile_service
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The temp store factory.
*/
public function __construct(UserProfileServiceInterface $user_profile_service, PrivateTempStoreFactory $temp_store_factory) {
// Initialize private members.
$this->currentUser();
$this->messenger();
$this->entityTypeManager();
$this->entityFormBuilder();
$this->amcprUserService = $user_profile_service;
$this->tempStore = $temp_store_factory->get('amcpr_supplier_profile_controller');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('amcpr.user.utility'),
$container->get('tempstore.private')
);
}
/**
* Exit from the Supplier Profile wizard.
*
* @param bool $show_exit_meesage
* Show a message if the flag is set to TRUE.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function exitWizard($show_exit_meesage = TRUE) {
$this->tempStore->delete('step');
if ($show_exit_meesage) {
$this->messenger->addMessage($this->t('You have exited from completing the supplier profile.'));
}
return $this->redirect('<front>');
}
/**
* Step 1: Show supplier profile wizard (begin wizard).
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function business() {
if ($this->amcprUserService->isSupplierProfileIncomplete()) {
return $this->form(1, 'Manufacturing Business Type');
}
else {
return $this->redirect('amcpr_user_profile.profile_supplier_edit');
}
}
/**
* Step 2: Certifications
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function certifications() {
return $this->form(2, 'Manufacturing Certificates');
}
/**
* Step 3: Materials
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function materials() {
return $this->form(3, 'Primary Material Experience');
}
/**
* Step 4: Equipments
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function equipments() {
return $this->form(4, 'Manufacturing Equipment');
}
/**
* Step 5: Specialities
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function specialities() {
return $this->form(5, 'Other Specialities (select all that apply)');
}
/**
* Step 6: Profile completed (end wizard).
*
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Drupal\Core\TempStore\TempStoreException
*/
public function finishWizard(Request $request) {
$step = $this->tempStore->get('step');
// Should be at step 5.
if ($step != 5 && $request->getMethod() == 'GET') {
return $this->redirect('amcpr_user_profile.supplier_profile_wizard');
}
$this->messenger->addMessage($this->t('Thank you! Your Supplier profile has been saved.'));
$this->amcprUserService->removeSupplierProfileIncompleteFlag();
$this->amcprUserService->killUserPrimaryNavBlockCache();
return $this->exitWizard(FALSE);
}
/**
* Get the route for the next step;
*
* @param int $step
* The current step.
*
* @return string
* Return the route.
*/
public static function getNextRoute($step) {
switch($step) {
case 1:
case 2:
case 3:
case 4:
case 5:
return static::ROUTES[$step + 1];
default:
return static::ROUTES[1];
}
}
/**
* Get the route for the previous step;
*
* @param int $step
* The current step.
*
* @return string
* Return the route.
*/
public static function getPreviousRoute($step) {
switch($step) {
case 2:
case 3:
case 4:
case 5:
return static::ROUTES[$step - 1];
default:
return '';
}
}
/**
* Helper method controller's action methods.
*
* @param int $step
* @param string $form_title
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
* Return renderable build array. User maybe redirected on error.
* @throws \Drupal\Core\TempStore\TempStoreException
*/
private function form($step, $form_title) {
// Get user supplier profile.
$supplierProfile = $this->amcprUserService->getSupplierProfile(TRUE);
if (!$supplierProfile) {
$this->messenger->addError($this->t('Registration error... Error code 1200-02.'));
return $this->exitWizard(FALSE);
}
// Save current step.
$this->tempStore->set('step', $step);
// Display form according the the current step.
$viewMode = 'wizard_step_' . $step;
$form = $this->entityFormBuilder->getForm(
$supplierProfile,
$viewMode,
['step' => $step]
);
return [
'#title' => $this->t("Let's Complete Your Supplier Profile"),
'#theme' => 'amcpr_profile_wizard_form',
'#form_title' => $this->t($form_title),
'#form' => $form,
];
}
}
@@ -0,0 +1,86 @@
<?php
namespace Drupal\amcpr_user_profile\EventSubscriber;
use Drupal\Core\Routing\RouteMatch;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Event Subscriber UserLogoutEventSubscriber.
*/
class RequestEventSubscriber implements EventSubscriberInterface {
/**
* The current account.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* Constructs a new RequestEventSubscriber.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*/
public function __construct(AccountInterface $account) {
$this->account = $account;
}
/**
* Set message when the user is logged out after password reset.
*
* @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
* The event to process.
*/
public function onKernelRequest(RequestEvent $event) {
$request = $event->getRequest();
$route_match = RouteMatch::createFromRequest($request);
// Don't let the user wander around the site if they used
// a one-time login link.
if ($this->account->isAuthenticated()) {
$resetTokenKey = 'pass_reset_' . $this->account->id();
if (isset($_SESSION[$resetTokenKey]) && !$request->query->get('pass-reset-token') && $route_match->getRouteName() !== 'user.logout' ) {
// Redirect user back to password reset form.
\Drupal::messenger()->addMessage(t('You must reset your password.'));
$event->setResponse(
new RedirectResponse(Url::fromRoute(
'amcpr_user_profile.account_preferences',
[],
[
'query' => ['pass-reset-token' => $_SESSION[$resetTokenKey]],
'absolute' => TRUE,
]
)->toString())
);
}
}
if ($route_match->getRouteName() === 'entity.node.canonical') {
$queryParam = $request->query->get('method');
if ($queryParam === 'reset') {
\Drupal::messenger()->addMessage(t('You have been logged out. Please log back in using the new password.'));
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
KernelEvents::REQUEST => 'onKernelRequest',
];
}
}
@@ -0,0 +1,64 @@
<?php
namespace Drupal\amcpr_user_profile\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Configure TDP submission settings.
*/
class SupplierSettingsForm extends ConfigFormBase {
public const FORM_ID = 'amcpr_user_profile_settings_form';
public const CONFIG_NAME = 'amcpr_user_profile.settings';
/**
* {@inheritdoc}
*/
public function getFormId() {
return self::FORM_ID;
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
SupplierSettingsForm::CONFIG_NAME,
];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config(SupplierSettingsForm::CONFIG_NAME);
$serverList = $config->get('server_list');
$form['server_list'] = [
'#type' => 'textarea',
'#title' => t('Server Listing'),
'#description' => t('Users that use the listed email servers will have the ability to create their own supplier, and will not have a shared supplier for the email server. Separate servers by commas or new line.'),
'#default_value' => ($serverList) ? $serverList : '',
'#format' => 'text',
// '#allowed_formats' => ['basic_html'],
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config(SupplierSettingsForm::CONFIG_NAME)
->set('server_list', $form_state->getValue('server_list'))
->save();
parent::submitForm($form, $form_state);
}
}
@@ -0,0 +1,81 @@
<?php
namespace Drupal\amcpr_user_profile\Plugin\Block;
use Drupal\amcpr_components\ComponentBuilder;
use Drupal\amcpr_user_profile\UserProfileServiceInterface;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a 'User Profile' block.
*
* @Block(
* id = "amcpr_account_preference_links_block",
* admin_label = @Translation("AMCPR Account Preference Links Block"),
* )
*/
class AccountPreferenceLinksBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* @var \Drupal\amcpr_user_profile\UserProfileServiceInterface
*/
protected $amcprUserProfileService;
/**
* @var \Drupal\User\UserInterface
*/
protected $currentUser;
/**
* UserProfileBlock constructor.
*
* @param array $configuration
* @param $plugin_id
* @param $plugin_definition
* @param \Drupal\amcpr_user_profile\UserProfileServiceInterface $user_profile_service
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, UserProfileServiceInterface $user_profile_service) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->amcprUserProfileService = $user_profile_service;
$this->currentUser = $this->amcprUserProfileService->getCurrentUser();
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('amcpr.user.utility')
);
}
/**
* {@inheritdoc}
*/
public function build() {
if (!$this->currentUser->isAuthenticated()) {
return [];
}
$links[] = [
'url' => Url::fromRoute('amcpr_user_profile.account_preferences'),
'title' => $this->t('Sign in & Security'),
'style' => 'primary'
];
$build = ComponentBuilder::buildCard(
'Account Preferences',
$links,
);
$build['#cache'] = ['contexts' => ['user']];
return $build;
}
}
@@ -0,0 +1,194 @@
<?php
namespace Drupal\amcpr_user_profile\Plugin\Block;
use Drupal\amcpr_notification\Service\NotificationService;
use Drupal\amcpr_user_profile\UserProfileServiceInterface;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a 'User Primary Nav' block.
*
* @Block(
* id = "amcpr_user_block",
* admin_label = @Translation("User Primary Nav Block"),
* )
*/
class UserPrimaryNavBlock extends BlockBase implements ContainerFactoryPluginInterface {
// @todo This value should be taken from block settings.
const MAX_NOTIFICATIONS = 5;
/**
* @var \Drupal\amcpr_user_profile\UserProfileServiceInterface
*/
protected $amcprUserProfileService;
/**
* @var \Drupal\amcpr_notification\Service\NotificationService
*/
protected $notificationService;
/**
* @var \Drupal\User\UserInterface
*/
protected $currentUser;
/**
* UserBlock constructor.
*
* @param array $configuration
* @param $plugin_id
* @param $plugin_definition
* @param \Drupal\amcpr_user_profile\UserProfileServiceInterface $user_profile_service
* @param \Drupal\amcpr_notification\Service\NotificationService $notification_service
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, UserProfileServiceInterface $user_profile_service, NotificationService $notification_service) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->amcprUserProfileService = $user_profile_service;
$this->notificationService = $notification_service;
$this->currentUser = $this->amcprUserProfileService->getCurrentUser();
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('amcpr.user.utility'),
$container->get('amcpr.notification')
);
}
/**
* {@inheritdoc}
*/
public function build() {
$is_logged_in = $this->currentUser->isAuthenticated();
$links = [];
$notifications = [];
$dropdown = [];
$links['search'] = [
'url' => '/search', //@todo replace with actual search route.
'title' => $this->t('Search'),
'icon' => 'magnifying-glass',
];
if ($is_logged_in) {
$notifications = $this->notificationService
->getUnreadNotifications(static::MAX_NOTIFICATIONS);
$links['notifications'] = [
'url' => Url::fromRoute('amcpr_dashboard.notifications'),
'title' => $this->t('Notifications'),
'icon' => 'bell',
'unread' => $this->notificationService->getUnreadNotificationsCount()
];
$links['dashboard'] = [
'url' => Url::fromRoute('amcpr_dashboard.index'),
'title' => $this->t('Dashboard'),
'icon' => 'grid-two-up',
];
$dropdown['title'] = t('Me');
$dropdown['name'] = $this->amcprUserProfileService->getFullName();
$dropdown['roles'] = $this->amcprUserProfileService->getAmcprRoles();
$dropdown['profile_links'] = [];
if ($this->amcprUserProfileService->isProfileIncomplete()) {
$dropdown['profile_links']['personal'] = [
'url' => Url::fromRoute('amcpr_user_profile.profile_wizard'),
'title' => $this->t('Complete Profile'),
'icon' => 'person',
];
}
else {
$dropdown['profile_links']['personal'] = [
'url' => Url::fromRoute('amcpr_user_profile.profile'),
'title' => $this->t('Personal Profile'),
'icon' => 'person',
];
if ($this->amcprUserProfileService->isSupplierProfileIncomplete()) {
$dropdown['profile_links']['supplier'] = [
'url' => Url::fromRoute('amcpr_user_profile.supplier_profile_wizard'),
'title' => $this->t('Become a Supplier'),
'icon' => 'globe',
];
}
else {
$dropdown['profile_links']['supplier'] = [
'url' => Url::fromRoute('amcpr_user_profile.profile_supplier'),
'title' => $this->t('Supplier Profile'),
'icon' => 'globe',
];
}
}
$dropdown['link_groups'] = [[
'header' => 'Lists',
'links' => [
'favorites_list' => [
'url' => Url::fromUri('internal:/lists/favorites'),
'title' => $this->t('Favorites'),
'icon' => 'star',
],
'offline_list' => [
'url' => Url::fromUri('internal:/lists/offline'),
'title' => $this->t('Offline Exports'),
'icon' => 'data-transfer-download',
],
]
], [
'header' => 'Account',
'links' => [
'preferences' => [
'url' => Url::fromRoute('amcpr_user_profile.account_preferences'),
'title' => $this->t('Preferences'),
'icon' => 'wrench',
],
]
], [
'header' => '',
'links' =>[
'logout' => [
'url' => Url::fromRoute('user.logout'),
'title' => $this->t('Logout'),
'icon' => 'account-logout',
],
]
]];
}
else {
$links['register'] = [
'url' => Url::fromRoute('user.register'),
'title' => $this->t('Register'),
'icon' => 'briefcase',
];
$links['login'] = [
'url' => Url::fromRoute('user.login'),
'title' => $this->t('Login'),
'icon' => 'account-login',
];
}
return [
'#cache' => ['contexts' => ['user']],
'#theme' => 'amcpr_nav_user_block',
'#is_logged_in' => $is_logged_in,
'#links' => $links,
'#notifications' => $notifications,
'#account_dropdown' => $dropdown,
];
}
}
@@ -0,0 +1,71 @@
<?php
namespace Drupal\amcpr_user_profile\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Listens to the dynamic route events.
*/
class ProfileRouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
// Change paths of following routes.
if ($route = $collection->get('user.register')) {
$route->setPath('/register');
}
if ($route = $collection->get('user.pass')) {
$route->setPath('/login/reset');
}
if ($route = $collection->get('user.pass.http')) {
$route->setPath('/login/reset');
}
if ($route = $collection->get('user.logout.http')) {
$route->setPath('/logout}');
}
if ($route = $collection->get('user.login')) {
$route->setPath('/login');
}
if ($route = $collection->get('user.login.http')) {
$route->setPath('/login');
}
if ($route = $collection->get('user.reset')) {
$route->setPath('/login/reset/{uid}/{timestamp}/{hash}');
}
if ($route = $collection->get('user.reset.form')) {
$route->setPath('/login/reset/{uid}');
}
// Change the path and controller for the password reset login route.
if ($route = $collection->get('user.reset.login')) {
$route->setPath('/login/reset/{uid}/{timestamp}/{hash}/login');
$route->setDefault('_controller', '\Drupal\amcpr_user_profile\Controller\ProfileUserController::resetPassLogin');
}
// Change the path and controller for the logout route.
if ($route = $collection->get('user.logout')) {
$route->setPath('/logout/{logout_method}');
$route->setDefault('_controller', '\Drupal\amcpr_user_profile\Controller\ProfileUserController::customLogout');
$route->setDefault('logout_method', 'user');
}
// Change the controller for the user page route.
if ($route = $collection->get('user.page')) {
$route->setDefault('_controller', '\Drupal\amcpr_user_profile\Controller\ProfileUserController::userPage');
}
}
}
@@ -0,0 +1,438 @@
<?php
namespace Drupal\amcpr_user_profile\Service;
use Drupal\amcpr_user_profile\UserProfileServiceInterface;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\User;
class UserProfileService implements UserProfileServiceInterface {
/**
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
private $entityTypeManager;
/**
* @var \Drupal\user\UserInterface
*/
private $currentUser;
/**
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $profileStorage;
/**
* @var \Drupal\user\UserStorageInterface
*/
protected $userStorage;
/**
* @var \Drupal\profile\Entity\ProfileInterface
*/
protected $personalProfile;
/**
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* @param \Drupal\Core\Session\AccountInterface $current_user
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountInterface $current_user) {
$this->entityTypeManager = $entity_type_manager;
$this->currentUser = User::load($current_user->id());
$this->profileStorage = $this->entityTypeManager->getStorage('profile');
$this->userStorage = $this->entityTypeManager->getStorage('user');
}
/**
* @inheritDoc
*/
public function getCurrentUser() {
return $this->currentUser;
}
public function getFullName() {
if (!isset($this->personalProfile)) {
$this->personalProfile = $this->getPersonalProfile();
}
if (!$this->personalProfile) {
return t('Name Not Set');
}
return $this->personalProfile->get('field_first_name')->getString()
. ' '
. $this->personalProfile->get('field_last_name')->getString();
}
/**
* @inheritDoc
*/
public function getAmcprRoles() {
$roles = [t('Designer')];
if ($this->isSupplier()) {
$roles[] = t('Supplier');
}
if ($this->isScreener()) {
$roles[] = t('Screener');
}
if ($this->isReviewer()) {
$roles[] = t('Reviewer');
}
return $roles;
}
/**
* @inheritDoc
*/
public function isSupplier() {
return !$this->isSupplierProfileIncomplete();
}
/**
* @inheritDoc
*/
public function isScreener() {
return $this->currentUser->hasRole('screener');
}
/**
* @inheritDoc
*/
public function isReviewer() {
return $this->currentUser->hasRole('reviewer');
}
/**
* @inheritDoc
*/
public function getAllScreeners() {
return $this->getUsersWithRole('screener');
}
/**
* @inheritDoc
*/
public function getAllReviewers() {
return $this->getUsersWithRole('reviewer');
}
/**
* @inheritDoc
*/
public function getAllAmcprAdministrators() {
return $this->getUsersWithRole('amcpr_admin');
}
/**
* @inheritDoc
*/
public function isProfileIncomplete() {
// A flag to indicate incompleteness is set at the time of registration.
// Fetch the flag value.
$isIncompleteFlag = $this->currentUser->get('field_profile_incomplete')->getValue();
// See if the flag value is set to ON (numerical 1).
// It means the user has not completed their profile.
if (!empty($isIncompleteFlag) && $isIncompleteFlag[0]['value']) {
return TRUE;
}
return FALSE;
}
/**
* @inheritDoc
*/
public function isSupplierProfileIncomplete() {
/** @var \Drupal\profile\Entity\Profile $supplierProfile */
$supplierProfile = $this->getSupplierProfile();
if ($supplierProfile) {
// A flag to indicate incompleteness is set at the time of registration.
// Fetch the flag value.
$isIncompleteFlag = $supplierProfile->get('field_profile_incomplete')->getValue();
// See if the flag value is set to ON (numerical 1).
// It means the user has not completed their profile.
if (!empty($isIncompleteFlag) && $isIncompleteFlag[0]['value']) {
return TRUE;
}
return FALSE;
}
else {
return TRUE;
}
}
/**
* @inheritDoc
*/
public function removeProfileIncompleteFlag() {
$this->currentUser->set('field_profile_incomplete', 0);
try {
$this->currentUser->save();
}
catch (EntityStorageException $e) {
// @todo Log the exception to watchdog.
}
}
/**
* @inheritDoc
*/
public function removeSupplierProfileIncompleteFlag() {
/** @var \Drupal\profile\Entity\Profile $supplierProfile */
$supplierProfile = $this->getSupplierProfile();
$supplierProfile->set('field_profile_incomplete', 0);
try {
$supplierProfile->save();
}
catch (EntityStorageException $e) {
// @todo Log the exception to watchdog.
}
}
/**
* @inheritDoc
*/
public function getPersonalProfile($create_new = FALSE) {
return $this->getProfileEntity('personal', $create_new);
}
/**
* @inheritDoc
*/
public function getPersonalProfileByUid($uid)
{
$entityProperties = [
'type' => 'personal',
'uid' => $uid,
];
$profile = $this->profileStorage->loadByProperties($entityProperties);
if (!empty($profile)) {
return reset($profile);
}
}
/**
* @inheritDoc
*/
public function getSupplierProfile($create_new = FALSE) {
return $this->getProfileEntity('supplier', $create_new);
}
/**
* Get profile types used for identifying user role.
*
* @param array $excluded
* Array of Profile bundle IDs to exclude.
*
* @return array
* An array of profile type information.
*/
public function getProfileTypes($excluded = ['personal']) {
//$profileBundleInfo = \Drupal::service('entity_type.bundle.info')->getBundleInfo('profile');
/** @var \Drupal\profile\Entity\ProfileType[] $profileBundles */
try {
$profileTypeIds = $this->entityTypeManager
->getStorage('profile_type')
->getQuery()
->condition('id', $excluded, 'NOT IN')
->execute();
$profileBundles = $this->entityTypeManager->getStorage('profile_type')
->loadMultiple($profileTypeIds);
}
catch (PluginException $e) {
$profileBundles = [];
}
// Assemble a new associative array with a few properties.
$profileTypes = [];
foreach ($profileBundles as $profileBundle) {
if (method_exists($profileBundle, 'getDescription')) {
$profileTypes[] = [
'id' => $profileBundle->id(),
'label' => $profileBundle->label(),
'description' => $profileBundle->getDescription(),
];
}
else if (property_exists($profileBundle, 'description')) {
$profileTypes[] = [
'id' => $profileBundle->id(),
'label' => $profileBundle->label(),
'description' => $profileBundle->description,
];
}
}
return $profileTypes;
}
/**
* @inheritDoc
*/
public function getProfileViewBuilder() {
return $this->entityTypeManager->getViewBuilder('profile');
}
/**
* @inheritDoc
*/
public function killUserPrimaryNavBlockCache($uid = NULL) {
if (!$uid) {
$uid = $this->getCurrentUser()->id();
}
// Kill the receivers User Block cache -- dirty method @todo use better method.
$cid = 'entity_view:block:userprimarynavblock:[languages:language_interface]=en:[theme]=b4amcpr:[user]=' . $uid;
\Drupal::cache('render')->delete($cid);
}
public function getSupplierEmails($originalEmail){
$toReturn = [];
$currUserServer = strtolower(substr($originalEmail, strpos($originalEmail, "@") + 1));
$configName = (\Drupal\amcpr_user_profile\Form\SupplierSettingsForm::CONFIG_NAME);
$config = \Drupal::config($configName);
$serverListString = $config->get('server_list');
$serverListArray = preg_split('/(,|\r\n|\n|\r| )/', $serverListString);
$isInServerList = FALSE;
foreach($serverListArray as $indivServer){
if (strtolower($indivServer) == $currUserServer){
$isInServerList = TRUE;
}
}
if (!$isInServerList){
$query = \Drupal::entityQuery('user');
$uids = $query->execute();
$users = User::loadMultiple($uids);
$foundProfile = FALSE;
foreach($users as $indivUser){
$currEmail = $indivUser->getEmail();
$server = strtolower(substr($currEmail, strpos($currEmail, "@") + 1));
if ($server == $currUserServer){
$toReturn[] = $currEmail;
}
}
}
else {
$toReturn[] = $originalEmail;
}
return $toReturn;
}
/**
* Get the profile entity of a given type that belongs to the current user.
*
* @param string $bundle
* A profile entity type (bundle).
*
* @param bool $create_new
* If set to TRUE, creates a new profile entity when one
* isn't found.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* A profile entity if found; otherwise NULL.
*/
public function getProfileEntity($bundle, $create_new = FALSE, $uid_sent = NULL) {
$uid_to_use = $this->currentUser->id();
if (!empty($uid_sent)){
$uid_to_use = $uid_sent;
}
$user_to_use = \Drupal\user\Entity\User::load($uid_to_use);
if ($bundle == 'supplier'){
$currUserEmail = $user_to_use->getEmail();
$currUserServer = strtolower(substr($currUserEmail, strpos($currUserEmail, "@") + 1));
$configName = (\Drupal\amcpr_user_profile\Form\SupplierSettingsForm::CONFIG_NAME);
$config = \Drupal::config($configName);
$serverListString = $config->get('server_list');
$serverListArray = preg_split('/(,|\r\n|\n|\r| )/', $serverListString);
$isInServerList = FALSE;
foreach($serverListArray as $indivServer){
if (strtolower($indivServer) == $currUserServer){
$isInServerList = TRUE;
}
}
if (!$isInServerList){
$query = \Drupal::entityQuery('user');
$uids = $query->execute();
$users = User::loadMultiple($uids);
$foundProfile = FALSE;
foreach($users as $indivUser){
if (!$foundProfile){
$currEmail = $indivUser->getEmail();
$server = strtolower(substr($currEmail, strpos($currEmail, "@") + 1));
if ($server == $currUserServer){
$entityProperties = [
'type' => $bundle,
'uid' => $indivUser->id(),
];
$profile = $this->profileStorage->loadByProperties($entityProperties);
if (!empty($profile)) {
$profile = reset($profile);
$isIncompleteFlag = $profile->get('field_profile_incomplete')->getValue();
if (!empty($isIncompleteFlag) && !$isIncompleteFlag[0]['value']) {
$uid_to_use = $indivUser->id();
$foundProfile = TRUE;
}
}
}
}
}
}
}
$entityProperties = [
'type' => $bundle,
'uid' => $uid_to_use,
];
$profile = $this->profileStorage->loadByProperties($entityProperties);
if (!empty($profile)) {
return reset($profile);
}
if ($create_new) {
try {
$profile = $this->profileStorage->create($entityProperties);
$profile->save();
return $profile;
}
catch (EntityStorageException $e) {
// no code
}
}
return NULL;
}
/**
* Get all users with the given role id.
*
* @param string $rid
* The role id.
*
* @return \Drupal\User\UserInterface[]
*/
private function getUsersWithRole($rid) {
/** @var \Drupal\User\UserInterface[] $users */
$users = $this->userStorage->loadByProperties([
'status' => 1,
'roles' => $rid
]);
return $users;
}
}
@@ -0,0 +1,164 @@
<?php
namespace Drupal\amcpr_user_profile;
interface UserProfileServiceInterface {
/**
* Gets the current active user.
*
* @return \Drupal\User\UserInterface
*/
public function getCurrentUser();
/**
* Gets full name of the current user.
*
* @return string
* The full name of the user.
*/
public function getFullName();
/**
* Gets AMCPR roles for the current user.
*
* @return array
* An array containing AMCPR roles.
*/
public function getAmcprRoles();
/**
* Whether the current user is a supplier.
*
* @return bool
* Returns TRUE if the user is a supplier, otherwise FALSE.
*/
public function isSupplier();
/**
* Whether the current user is a screener.
*
* @return bool
* Returns TRUE if the user is a screener, otherwise FALSE.
*/
public function isScreener();
/**
* Whether the current user is a reviewer.
*
* @return bool
* Returns TRUE if the user is a reviewer, otherwise FALSE.
*/
public function isReviewer();
/**
* Get all users with the Screener role.
*
* @return \Drupal\User\UserInterface[]
*/
public function getAllScreeners();
/**
* Get all users with Reviewer role.
*
* @return \Drupal\User\UserInterface[]
*/
public function getAllReviewers();
/**
* Get all users with administrator role.
*
* @return \Drupal\User\UserInterface[]
*/
public function getAllAmcprAdministrators();
/**
* Whether the current user has an incomplete Personal profile.
*
* @return bool
* Returns TRUE if the use did not complete their profile; FALSE otherwise.
*/
public function isProfileIncomplete();
/**
* Whether the current user has an incomplete Supplier profile.
*
* @return bool
* Returns TRUE if the use did not complete their profile; FALSE otherwise.
*/
public function isSupplierProfileIncomplete();
/**
* Remove the Incomplete Profile flag.
*/
public function removeProfileIncompleteFlag();
/**
* Remove the Incomplete Supplier Profile flag.
*/
public function removeSupplierProfileIncompleteFlag();
/**
* Get Personal profile entity associated with the current user.
*
* @param bool $create_new
* If set to TRUE, creates a new Personal profile entity when one
* isn't found.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* Supplier profile entity.
*/
public function getPersonalProfile($create_new = FALSE);
/**
* Get Personal profile entity associated with the given user uid.
*
* @param int $uid
* The UID of the user.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* Supplier profile entity.
*/
public function getPersonalProfileByUid($uid);
/**
* Get Supplier profile entity associated with the current user.
*
* @param bool $create_new
* If set to TRUE, creates a new Supplier profile entity when one
* isn't found.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* Supplier profile entity.
*/
public function getSupplierProfile($create_new = FALSE);
/**
* Get profile types used for identifying user role.
*
* @param array $excluded
* Array of Profile bundle IDs to exclude.
*
* @return array
* An associative array containing profile type information.
*/
public function getProfileTypes($excluded = ['personal']);
/**
* Creates a new view builder instance for the Profile entity.
*
* @return \Drupal\Core\Entity\EntityViewBuilderInterface
* A view builder instance.
*/
public function getProfileViewBuilder();
/**
* Kill the Primary Nav Block cache of a user.
* @param int|null $uid
* If set, block cache for the given user id will be cleared.
* Defaults to current user id.
*/
public function killUserPrimaryNavBlockCache($uid = NULL);
}