Recargando combos dependientes

Es habitual que tengamos en un formulario el típico combo de provincias y localidades, para ello suelo usar la siguiente función:

function combosObj(padre, hijo, path){
        this.padre = padre;
        this.hijo = hijo;
        this.path = path;
        var _self = this;

        this.load = function(id){
            $.ajax({
                method: 'GET',
                url: this.path + '/' + id,
                dataType: 'json'
              })
              .done(function( resultado ) {
                  $('select[name="'+_self.hijo+'"] option').remove();
                  $.each(resultado, function(i, item) {
                      $('select[name="'+_self.hijo+'"]').append($('<option>').text(item.label).val(item.id));
                  });
                  if ($('select[name="'+_self.hijo+'"]').attr('data-default')) {
                      $('select[name="'+_self.hijo+'"] option[value="'+$('select[name="'+_self.hijo+'"]').data('default')+'"]').prop('selected', 'selected');
                  }
              });
        }

        this.load($('select[name="'+this.padre+'"]').val());
        $('select[name="'+this.padre+'"]').change(function(){
            _self.load($(this).val());
        });
    }

Y para usarla es tan sencillo como pasarle el nombre del select “padre”, el select “hijo” y la url que va a devolver un JSON con los valores a cargar (el JSON debe ser un array con valores id y label):

$(document).ready(function() {
        new combosObj('provincia_id', 'localidad_id', '/localidades');
        new combosObj('categoria_id', 'subcategoria_id', '/subcategorias');
});

En el caso de que tengamos un valor por defecto en el combo “hijo”, deberemos añadirle un atributo data-default con el id que queramos por defecto

<div class="form-group">
  <label for="">Provincia</label>
  <select name="provincia_id" class="form-control">
      @foreach($provincias as $item)
        <option value="{{$item->id}}">{{$item->provincia}}</option>
      @endforeach
  </select>
</div>
<div class="form-group">
  <label for="">Localidad clínica</label>
  <select name="localidad_id" class="form-control" data-default="{{$default_id}}">
  </select>
</div>

Mandar un email con Drupal 8

Cuando quiero mandar un email desde un módulo personalizado lo que suelo hacer es primero crear el fichero templates/mail.html dentro de la carpeta del módulo. En este fichero tebndremos el html que se manda por correo y si queremos personalizar un texto normalmente le pongo el nombre de variables entre corchetes. Por ejemplo:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>el title</title>
</head>
<body>
Este es un email con el siguiente mensaje personalizado: {{mensaje}}
</body>
</html>

Lo siguiente, en la programación de nuestro módulo plantamos el siguiente código:

$mailManager = \Drupal::service('plugin.manager.mail');
$module = 'my_modulo'; 
$key = 'email_contacto'; // clave que identifica el email

// configuración del envio
$html = file_get_contents(str_replace('src/Form', 'templates/mail.html', __DIR__));
$to = 'email@prueba.es';
$params['subject'] = 'el asunto del email ';
$params['message'] = str_replace('{{mensaje}}', 'el texto a sustituir', $html) ;
$params['Cc'] = [];
$langcode = \Drupal::currentUser()->getPreferredLangcode();
$send = true;
$result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);

// guardamos en el log de Drupal el resultado del envio
$message = ($result['result'] !== true)?'Se ha producido un error en el envio de email':'Email enviado';
\Drupal::logger('contactForm')->notice($message);

Por ultimo, en el fichero .modulo especificamos el siguiente hook:

use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;

function my_modulo_mail($key, &$message, $params) {
 $options = array(
   'langcode' => $message['langcode'],
 );
 switch ($key) {
   case 'email_contacto':
     $header = array(
           'MIME-Version' => '1.0',
           'Content-Type' => 'text/html; charset=UTF-8; format=flowed; delsp=yes',
           'Content-Transfer-Encoding' => '8Bit',
           'X-Mailer' => 'Drupal'
     );
     if(count($params['Cc'])>0) $header['Cc'] = implode(',', $params['Cc']);
     $message['headers'] = $header;
     $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed; delsp=yes';
     $message['from'] = \Drupal::config('system.site')->get('mail');
     $message['subject'] = $params['subject'];
     $message['body'][] = $params['message'];
     break;
 }
}

Redireccionar usuario Drupal 8 según perfil

He estado creando un módulo de Drupal 8 que permite subir documentos a un perfil de usuario concreto y a otro poder ver el listado de dichos documentos. Este segundo perfil en concreto debe acceder directamente al listado cuando se loga por lo que he tenido que meter el siguiente hook en el módulo:

function my_module_user_login($account) {
// si es del perfil documentacion le redirigimos al listado de documentos
    if(in_array('documentacion', $account->getRoles())) {
        $response = new Symfony\Component\HttpFoundation\RedirectResponse("/user/listado-documentos");
        $response->send();
        return;
    }
}

Con esto ya estamos redirigiendo a los usuarios pero ahora hay que crear esa ruta, para ello en el módulo creamos un fichero routing y creamos la ruta restringiendo el acceso al perfil documentación:

my_module.listado:
  path: '/user/listado-documentos'
  defaults:
    _controller: '\Drupal\my_module\MyController::listado'
    _title: 'Listado de documentos'
  requirements:
    _permission: 'access content'
    _role: 'financial'

Y ya en el controlador MyController metemos toda la lógica que necesitemos