aws_polly-1.0.x-dev/aws_polly.module
aws_polly.module
<?php /** * @file * Main AWS Polly features . */ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\node\NodeInterface; /** * Intro. * * We want to polly 2 fields per node: "title" and "longtext". * Create those file fields via UI, with file extension: mp3 */ /** * To be confirmed. * * Paste this into /admin/structure/types/manage/{C.T.}/fields/add-field. * "field_" will be prepended by Drupal itself. */ define('AWS_POLLY_TITLE_FIELD_NAME', "aws_polly_audio_title"); /** * To be confirmed. * * Paste this into /admin/structure/types/manage/{C.T.}/fields/add-field. * "field_" will be prepended by Drupal itself. */ define('AWS_POLLY_CONTENT_FIELD_NAME', "aws_polly_audio_content"); module_load_include('inc', 'aws_polly', 'aws_polly.form'); /** * Implements hook_help(). */ function aws_polly_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.aws_polly': $output = ''; $output .= '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('AWS Polly module will convert sentences to audio data using the AWS SDK PHP library and attach it to in node field.') . '</p>'; $output .= '<h3>' . t('Set up') . '</h3>'; $output .= '<ol>'; $output .= '<li>' . t('Create a field Polly Audio named !title for the node title and a field named !longtext for a longer voice output.', [ '!title' => AWS_POLLY_TITLE_FIELD_NAME, '!longtext' => AWS_POLLY_LONGTEXT_FIELD_NAME, ]); $output .= t('Both fields type is "File", extension "mp3"') . '</li>'; $output .= '<li>' . t('Please create one separate display for audio convert or you can use any existing and configure all fields which need to convert in the audio.') . '</li>'; $output .= '<li>' . t('Please add display name in Content display field on config URL.') . '</li>'; $output .= '</ol>'; return $output; } } /** * Implements hook_node_presave(). * * { @inheritdoc } */ function aws_polly_node_presave(NodeInterface $node) { $config = aws_polly_validate_aws_configuration(); if (!$config) { return; } if (aws_polly_node_is_ready_for_polly($node) == TRUE) { \Drupal::messenger()->addWarning('Audio fields will be processed by AWS Polly'); } // A. Let's polly node title. if (\Drupal::currentUser()->hasPermission('polly node title')) { if ($node->hasField('field_' . AWS_POLLY_TITLE_FIELD_NAME)) { $output = $node->getTitle() . ". " . $config->get('audio_signature') ?: ' '; $node = aws_polly_add_polly_to_field($node, $output, 'field_' . AWS_POLLY_TITLE_FIELD_NAME); } } // B. Let's polly node content. if (\Drupal::currentUser()->hasPermission('polly node content')) { if ($node->hasField('field_' . AWS_POLLY_CONTENT_FIELD_NAME)) { $output = ''; $view_mode = $config->get('display') ?: 'teaser'; $entity_type = 'node'; $builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type); $build = $builder->view($node, $view_mode); $output = render($build); $output = strip_tags($output); if ($node->original) { $build = $builder->view($node->original, $view_mode); $output_original = render($build); $output_original = strip_tags($output_original); } if ($output != $output_original) { $output .= ". " . $config->get('audio_signature') ?: ' '; $node = aws_polly_add_polly_to_field($node, $output, 'field_' . AWS_POLLY_CONTENT_FIELD_NAME); } } } } /** * Add polly file to node. */ function aws_polly_add_polly_to_field($node, $text, $field_name) { $aws_polly = \Drupal::service('aws_polly.manager'); $file = $aws_polly->generateFile(['format' => 'mp3', 'text' => $text]); $file_id = $file->id(); $node->set($field_name, ['target_id' => $file_id]); return $node; } /** * List of Polly voices. * * @todo add missing voices (anyting via AWS API?). */ function aws_polly_voices($options) { switch ($options['language_code']) { case "en-GB": $list = [ 'Amy' => 'Amy (female)', 'Emma' => 'Emma (female)', 'Brian' => 'Brian (male)', ]; break; case "en-US": $list = [ 'Ivy' => 'Ivy (Female (child))', 'Joanna' => 'Joanna (Female)', 'Kendra' => 'Kendra (Female)', 'Kimberly' => 'Kimberly (Female)', 'Salli' => 'Salli (Female)', 'Joey' => 'Joey (Male)', 'Justin' => 'Justin (Male (child))', 'Kevin' => 'Kevin (Male (child))', 'Matthew' => 'Matthew (Male)', ]; break; case "it-IT": $list = [ 'Carla' => 'Carla (Formale)', 'Bianca' => 'Bianca (Informale)', 'Giorgio' => 'Giorgio (Formale)', ]; break; default: $list = ['Matthew' => 'Matthew (Male)']; } return [$list]; } /** * Function aws_polly_validate_aws_configuration. * * Check if the current configuration is valid. */ function aws_polly_validate_aws_configuration() { $aws_polly = \Drupal::service('aws_polly.manager'); return $aws_polly->checkAwsCredentials(); } /** * Check for node with polly enabled. */ function aws_polly_node_is_ready_for_polly($node) { $ready = FALSE; $check = [ 'enabled' => NULL, 'has_field' => NULL, ]; $check['enabled'] = \Drupal::state()->get('aws_polly_enabled' . $node->type->entity->Id(), NULL); if ($check['enabled'] == 1) { $ready = TRUE; } return $ready; }