Commit d13ddc55 authored by Chris Shantz's avatar Chris Shantz
Browse files

Merge branch '1.0.x' into prod/1.0.x

parents 17986a84 2c36caaf
services:
uw_cfg_common.commands:
class: Drupal\uw_cfg_common\Commands\UwDrushCommands
arguments: ['@entity_type.manager', '@uw_cfg_common.missing_blocks', '@config.factory', '@request_stack']
arguments: ['@entity_type.manager', '@uw_cfg_common.missing_blocks', '@config.factory', '@module_handler', '@module_installer']
tags:
- { name: drush.command }
......@@ -4,7 +4,10 @@ namespace Drupal\uw_cfg_common\Commands;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\ProxyClass\Extension\ModuleInstaller;
use Drupal\uw_cfg_common\Service\UWMissingBlocks;
use Drupal\uw_cfg_common\UwPermissions\UwPermissions;
use Drupal\uw_cfg_common\UwRoles\UwRoles;
use Drush\Commands\DrushCommands;
use Drush\Utils\StringUtils;
......@@ -37,13 +40,35 @@ class UwDrushCommands extends DrushCommands {
*/
protected $configFactory;
/**
* Module handler.
*
* @var \Drupal\Core\Extension\ModuleHandler
*/
protected $moduleHandler;
/**
* Module installer.
*
* @var \Drupal\Core\ProxyClass\Extension\ModuleInstaller
*/
protected $moduleInstaller;
/**
* {@inheritDoc}
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, UWMissingBlocks $missingBlocks, ConfigFactoryInterface $configFactory) {
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
UWMissingBlocks $missingBlocks,
ConfigFactoryInterface $configFactory,
ModuleHandler $moduleHandler,
ModuleInstaller $moduleInstaller
) {
$this->entityTypeManager = $entityTypeManager;
$this->missingBlocks = $missingBlocks;
$this->configFactory = $configFactory;
$this->moduleHandler = $moduleHandler;
$this->moduleInstaller = $moduleInstaller;
}
/**
......@@ -64,13 +89,20 @@ class UwDrushCommands extends DrushCommands {
$rids = UwRoles::getAllRoles();
// Step through each rid and set the permissions.
foreach ($rids as $rid) {
$all = UwPermissions::setAccessPermissions();
foreach ($rids as $rid) {
// Get the info about the role.
$uw_role = UwRoles::getUwRole($rid);
// Array to hold additional access content permissions for each role.
$additional = [];
if ($uw_role['label'] && !empty($all[$uw_role['label']])) {
$additional = $all[$uw_role['label']];
}
// Set the permissions for the role.
UwRoles::setUwPermissions($uw_role);
UwRoles::setUwPermissions($uw_role, $additional);
// Set message for specific role setting permissions.
$this->logger()->success('Permissions set for ' . $uw_role['label'] . '.');
......@@ -219,4 +251,36 @@ class UwDrushCommands extends DrushCommands {
return $path;
}
/**
* Drush command to cleanup after a migration.
*
* @command mim:cleanup
* @aliases mimcu
* @usage mimcu
*/
public function migrationCleanUp() {
// Modules to uninstall.
$modules = [
'uw_migrate',
'webform_migrate',
'webform_node',
];
// Step through each of the modules, ensure that they
// are enabled, and if enabled, uninstall.
foreach ($modules as $module) {
// If the module is enabled, uninstall it.
if ($this->moduleHandler->moduleExists($module)) {
// Uninstall the module.
$this->moduleInstaller->uninstall([$module]);
// Log to the screen.
$this->logger()->success('Uninstalled: ' . $module);
}
}
}
}
......@@ -6,11 +6,14 @@ use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Url;
use Drupal\field\FieldConfigInterface;
use Drupal\uw_cfg_common\Service\UWService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Form class for the content access form.
......@@ -45,6 +48,13 @@ class UwContentModerationForm extends ConfirmFormBase {
*/
protected $currentUser;
/**
* The drupal messaging.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Class constructor.
*
......@@ -52,10 +62,17 @@ class UwContentModerationForm extends ConfirmFormBase {
* The entity type manager.
* @param \Drupal\Core\Session\AccountProxyInterface $currentUser
* The entity type manager.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The drupal messaging.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountProxyInterface $currentUser) {
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
AccountProxyInterface $currentUser,
MessengerInterface $messenger
) {
$this->entityTypeManager = $entity_type_manager;
$this->currentUser = $currentUser;
$this->messenger = $messenger;
}
/**
......@@ -65,7 +82,8 @@ class UwContentModerationForm extends ConfirmFormBase {
// Instantiates this form class.
return new static(
$container->get('entity_type.manager'),
$container->get('current_user')
$container->get('current_user'),
$container->get('messenger')
);
}
......@@ -117,6 +135,64 @@ class UwContentModerationForm extends ConfirmFormBase {
$this->vid = $vid;
$this->status = $status;
// If we are publishing this node, ensure that the meta
// content description is set.
if (!$this->status) {
/*
* This code is taken from the require_on_publish
* module, there was no easy way to use the validator
* inside this class.
*/
// Load the node of this revision.
$entity = $this->entityTypeManager->getStorage('node')->loadRevision($this->vid);
/** @var \Drupal\Core\Field\FieldItemListInterface $field */
foreach ($entity->getFields() as $field) {
/** @var \Drupal\Core\Field\FieldConfigInterface $field_config */
$field_config = $field->getFieldDefinition();
if (!($field_config instanceof FieldConfigInterface)) {
continue;
}
if (!$field->isEmpty()) {
continue;
}
// If the field has require on publish, check that it has a value.
if ($field_config->getThirdPartySetting('require_on_publish', 'require_on_publish', FALSE)) {
// If the field does not have a value, set the message and redirect.
if (!$field->getValue()) {
// Get the URL to the node.
$url = Url::fromRoute('entity.node.canonical', ['node' => $this->nid]);
// Setup the redirect.
$redirect = new RedirectResponse($url->toString());
// Send the redirect.
$redirect->send();
// Get the message to be displayed.
$message = $this->t(
'Field "@field_label" is required when publishing.',
['@field_label' => $field_config->getLabel()]
);
// Add the message that the description for content is required.
$this->messenger->addError($message);
// We need to exit the code so that redirect and the message
// work correctly, without this the message does not display.
exit;
}
}
}
}
// Get the form from the parent, we need this to ensure
// that we have all the components (like confirm/cancel)
// load with this form as well.
......
<?php
namespace Drupal\uw_cfg_common\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\Core\Routing\TrustedRedirectResponse;
/**
* Form class for the search form.
*/
class UwSearchForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'uw_search_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Set the attributes and role for the form.
$form['#attributes'] = [
'class' => ['uw-search--form'],
'role' => 'search',
];
// Element used to open the tray for phone view.
$form['opentray'] = [
'#type' => 'checkbox',
'#title' => $this->t('<span class="uw-search--checkboxlabel--labeltext">Search Checkbox</span>'),
'#label_classes' => [
'uw-search--checkboxlabel',
],
'#attributes' => [
'class' => [
'uw-input',
'uw-input--checkboxform',
],
'aria-hidden' => 'true',
'tabindex' => '-1',
],
'#theme_wrappers' => [],
];
// This is the label that is used for the "phone" view on
// the site search. We need to use form element label here
// by itself, since we use theme_wrappers as an empty array
// above in the input, which would normally give us the form
// label.
$form['label'] = [
'#theme' => 'form_element_label',
'#title' => $this->t('<span class="uw-search--checkboxlabel__labeltext">Open Search Location </span>'),
'#title_display' => 'after',
'#required' => FALSE,
'#id' => 'edit-opentray',
'#attributes' => [
'class' => ['uw-search--checkboxlabel'],
],
];
// The search text.
$form['search-input'] = [
'#type' => 'textfield',
'#attributes' => [
'class' => ['uw-input', 'uw-input--search'],
],
'#id' => 'uw-search',
'#placeholder' => $this->t('Search'),
'#title' => $this->t('<span class="uw-search--labeltext">Search for </span>'),
'#title_display' => 'invisible',
'#label' => [
'#theme' => 'form_element_label',
'#required' => FALSE,
'#id' => 'uw-search',
'#attributes' => [
'class' => ['uw-search--hidelabel'],
],
],
];
// Get the URL for this site to be used in the options.
$url = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
// The type of search, either all sites or this site.
$form['search-type'] = [
'#type' => 'select',
'#id' => 'uw-select-site',
'#attributes' => [
'class' => ['form-item__select', 'uw-select--search'],
],
'#options' => [
'' => $this->t('On all sites'),
'inurl:' . $url => $this->t('On this site'),
],
'#title_display' => 'invisible',
'#title' => $this->t('Search Location'),
'#label' => [
'#theme' => 'form_element_label',
'#required' => FALSE,
'#id' => 'uw-select-site',
'#attributes' => [
'class' => ['uw-search--hidelabel'],
],
],
];
// The submit button.
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = [
'#type' => 'submit',
'#attributes' => [
'value' => $this->t('Search'),
'class' => [
'button',
'button--submit',
'button--submit__form',
],
],
'#prefix' => '<div class="uw-search-button__wrapper">',
'#suffix' => '</div>',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Variable for the parameters.
$parameters = '';
// Get the values from the form state.
$values = $form_state->getValues();
// If this is a site search, add it to parameters.
if ($values['search-type']) {
$parameters .= $values['search-type'] . ' ';
}
// If there is search text add it to the parameters.
if ($values['search-input']) {
$parameters .= $values['search-input'];
}
// The URL to the uwaterloo search.
$url = 'https://uwaterloo.ca/search';
// If there are parameters, encode and add to URL.
if ($parameters !== '') {
$url .= '/?search-input=' . urlencode($parameters);
}
// Redirect to the uwaterloo search.
$form_state->setResponse(new TrustedRedirectResponse($url, 302));
}
}
......@@ -3,6 +3,7 @@
namespace Drupal\uw_cfg_common\UwPermissions;
use Drupal\user\Entity\Role;
use Symfony\Component\Yaml\Yaml;
/**
* Class UwPermissions.
......@@ -297,6 +298,37 @@ class UwPermissions {
return $uw_permissions;
}
/**
* Convert the permissions array and send it to grantRevoke.
*/
public static function setAccessPermissions(): array {
// Load and transform content-access permissions.
$all_permissions = UwPermissions::getPermissionsArray();
$module_handler = \Drupal::service('module_handler');
$module_path = $module_handler->getModule('uw_cfg_common')->getPath();
$yaml_perm = Yaml::parseFile($module_path . '/src/UwRoles/access_content_permissions.yml');
$all = [];
foreach ($yaml_perm as $ct => $actions) {
foreach ($actions as $name => $roles) {
foreach (['Site manager', 'Content author', 'Content editor'] as $role) {
if (!empty($all_permissions[$ct][$name][$role])) {
if (!isset($all[$role])) {
$all[$role] = [];
}
$all[$role] = array_merge($all[$role], $all_permissions[$ct][$name][$role]);
}
}
}
}
return $all;
}
/**
* Build uw role permissions list for content types.
*
......
......@@ -99,7 +99,7 @@ class UwRoles {
return 'Site manager';
case 'uw_role_content_author':
return 'Content Author';
return 'Content author';
case 'uw_role_content_editor':
return 'Content editor';
......@@ -149,14 +149,25 @@ class UwRoles {
* Set the list of permissions inside the uw_role array.
*
* @param array $uw_role
* - The roles array.
* @param array $additional
* - The access content array.
* The uw_role array from function getRole.
*/
public static function setUwPermissions(array $uw_role): void {
public static function setUwPermissions(array $uw_role, array $additional = []) {
foreach ($uw_role['permissions'] as $permission) {
$current_permissions = $uw_role['object']->getPermissions();
$desired_permissions = $uw_role['permissions'];
$add_permissions = array_diff($desired_permissions, $current_permissions);
foreach ($add_permissions as $permission) {
$uw_role['object']->grantPermission($permission);
}
$remove_permissions = array_diff($current_permissions, $desired_permissions, $additional);
foreach ($remove_permissions as $permission) {
$uw_role['object']->revokePermission($permission);
}
$uw_role['object']->save();
}
......
Blog:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit tags':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete tags':
- 'Site manager'
Contact:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit groups':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete groups':
- 'Site manager'
Catalog:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit audience':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete audience':
- 'Site manager'
'Create/edit categories':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete categories':
- 'Site manager'
'Create/edit catalogs':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete catalogs':
- 'Site manager'
Event:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit tags':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete tags':
- 'Site manager'
'Create/edit types':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete types':
- 'Site manager'
'Expand/Collapse Group':
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
News:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit tags':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete tags':
- 'Site manager'
Opportunity:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
Profile:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit types':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete types':
- 'Site manager'
Project:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit roles':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete roles':
- 'Site manager'
'Create/edit topics':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete topics':
- 'Site manager'
Service:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Create/edit categories':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Delete categories':
- 'Site manager'
Sidebar:
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Site footer':
'Use content type':
- 'Site manager'
- 'Content author'
- 'Content editor'
'Special alert':
'Use':
- 'Site manager'
'Web page':
'Use content type':