cforge-2.0.x-dev/modules/cforge_broadcast/cforge_broadcast.inc

modules/cforge_broadcast/cforge_broadcast.inc
<?php

/**
 * @file
 * Helper functions.
 */

use Drupal\user\Entity\User;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Core\Entity\ContentEntityInterface;

/**
 * Compose the broadcast mail.
 */
function _cforge_broadcast_mail_broadcast(&$message, $params) {
  $entity = $params['entity'];
  $params[$entity->getEntityTypeId()] = $entity;
  unset($params['entity']);
  if (!isset($params['user'])) {
    \Drupal::service('logger.channel.cforge')->error('No user parameter in broadcast mail');
  }
  $sender = $entity->getOwner();
  $message['subject'] = t(
    '%site_name: %entity_label',
    [
      '%site_name' => \Drupal::Config('system.site')->get('name'),
      '%entity_label' => $entity->label(),
    ]
  );
  $bundleFieldName = $entity->getEntityType()->getKey('bundle');
  $message['body'][] = t(
    '@name [<a href=":contact-url">contact</a>] posted a new @type.',
    [
      '@name' => $sender->getDisplayName(),
      ':contact-url' => Url::fromRoute(
        'entity.user.contact_form',
        ['user' => $sender->id()]
      )->toString(),
      '@type' => $entity->{$bundleFieldName}->entity->label(),
    ]
  );

  $renderable = \Drupal::entityTypeManager()
    ->getViewBuilder($entity->getEntityTypeId())
    ->view($entity, 'default');

  $message['body'][] = render($renderable);
  unset($mailing);

  // Add a paragraph about opting out if settings allow.
  if (\Drupal::config('cforge_broadcast.settings')->get('optout')) {
    $message['body'][] = Link::fromTextAndUrl(
      t("Opt-out of 'broadcast' messages"),
      Url::fromRoute(
        'entity.user.edit_form',
        ['user' => $params['user']->id()],
        ['absolute' => TRUE]
      )
    )->toString();
  }
  $message['headers']['From'] = $sender->getEmail();

  if ($entity->getEntityTypeId() == 'smallad' and property_exists($entity, 'image')) {
    mail('matslats@fastmail.com', 'broadcast attachments', 'somebody tried to email an image attachment');
  }
  // @todo handle file attachments?
  /* this code from d7
  if (isset($node->upload) && is_array($node->upload)) {
    $items = (array)reset($node->upload);
    foreach($items as $att) {
    if (!$att['fid']) continue;
      $file = file_load($att['fid']);
      $message['params']['attachments'][] = array(
        'uri' => $file->uri,
        'filecontent' => file_get_contents($file->uri),
        'filename' => $file->filename,
        'filemime' => file_get_mimetype($file->uri)
      );
    }
  }
   */
}

/**
 * Helper function.
 *
 * @see cforge_broadcast_form_cforge_settings_form_alter()
 */
function _cforge_broadcast_form_cforge_settings_form_alter(&$form, &$form_state) {
  $config = \Drupal::config('cforge_broadcast.settings');
  $form['mail']['scope'] = [
    '#title' => t('Broadcast scope'),
    '#description' => t('How far can a normal trader broadcast?'),
    '#type' => 'radios',
    '#options' => array(
      CFORGE_BROADCAST_ME => t('Traders cannot broadcast'),
      CFORGE_BROADCAST_NEIGHBOURHOOD => t('Only to people in the same neighbourhood'),
      CFORGE_BROADCAST_SITE => t('To all online users'),
    ),
    '#default_value' => $config->get('scope'),
    '#weight' => 1
  ];
  $form['mail']['optout'] = [
    '#title' => t('Broadcast opt-out'),
    '#description' => t('Give each user a setting to opt-out of broadcasts'),
    '#type' => 'checkbox',
    '#default_value' => $config->get('optout'),
    '#weight' => 2
  ];
  $form['#submit'][] = 'broadcast_settings_submit';
}

/**
 * Form submit callback.
 *
 * Save the broadcast settings.
 */
function broadcast_settings_submit($form, $form_state) {
  $config = \Drupal::configFactory()->getEditable('cforge_broadcast.settings');
  $config
    ->set('optout', $form_state->getValue('optout'))
    ->set('scope', $form_state->getValue('scope'))
    ->save();
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add broadcasting buttons to the node/smallad form.
 */
function _cforge_broadcast_entity_form_alter(&$form, &$form_state) {
  $entity = $form_state->getFormObject()->getEntity();
  $entityTypeId = $entity->getEntityTypeId();
  $nodetypes = ['story', 'document', 'event'];
  if ($entityTypeId == 'smallad' or in_array($entity->bundle(), $nodetypes)) {
    if ($scopes = cforge_broadcast_options($entity)) {
      $form['actions']['submit']['#dropbutton'] = 'save';
      $sure_message = (string) t('Are you sure you want to email this?');
      foreach ($scopes as $scope_id => $scope_name) {
        $form['actions']["broadcast_$scope_id"] = [
          '#type' => 'submit',
          '#value' => t('Save and broadcast to @scope', ['@scope' => $scope_name]),
          '#submit' => $form['actions']['submit']['#submit'] + ['broadcast' => 'entity_broadcast_submit'],
          '#weight' => 100 + $scope_id,
          '#dropbutton' => 'save',
          '#attributes' => [
            'onclick' => 'if(!confirm("' . $sure_message . '")){return false;}',
          ],
          '#scope' => $scope_id,
        ];
        if (isset($form['image'])) {
          $form['image']['widget']['#description'] = t('Images cannot be included in broadcast mails');
        }
      }
    }
    else {
      $form['actions'][] = [
        '#markup' => '('.t('Already broadcast') .')',
        '#weight' => 100
      ];
    }
  }
}

/**
 * Utility to check to what scope the node can be broadcast.
 *
 * That means:
 * - the user has permission to broadcast
 * - the entity is of a broadcastable type
 * - the entity has not been broadcast before.
 *
 * @param ContentEntityInterface $entity
 *   The broadcastable entity.
 *
 * @return array
 *   The #options for the broadcast scope.
 */
function cforge_broadcast_options(ContentEntityInterface $entity) : array {
  $options = [];
  $pairs = \Drupal::keyValue('cforge_broadcast');
  $already = $pairs->get($entity->getEntityTypeId(), []);
  if ($entity->isNew() or !in_array($entity->id(), $already)) {
    $i = 0;
    $trader_scope = \Drupal::currentUser()->hasPermission('administer nodes') ?
      CFORGE_BROADCAST_SITE :
      \Drupal::config('cforge_broadcast.settings')->get('scope');
    // Increase options until it is as wide as the user allows.
    while ($i <= $trader_scope) {
      if ($name = cforge_broadcast_scope_name($i)) {
        $options[$i] = $name;
      }
      $i++;
    }
  }
  return $options;
}

/**
 * Submit handler for node form.
 *
 * Check the scope, find the emails and batch send an email.
 */
function entity_broadcast_submit($form, $form_state) {
  $entity = $form_state->getFormObject()->getEntity();
  $submit_button = $form_state->getTriggeringElement();
  switch ($submit_button['#scope']) {
    case CFORGE_BROADCAST_ME:
      $uids = [\Drupal::currentUser()->id()];
      break;

    case CFORGE_BROADCAST_NEIGHBOURHOOD:
      $account = User::load(\Drupal::currentUser()->id());
      $address = $account->address->getValue();
      $uids = cforge_neighbour_uids($address[0]['dependent_locality']);
      break;

    // This can't happen.
    case CFORGE_BROADCAST_OGS:
      break;

    case CFORGE_BROADCAST_SITE:
      $uids = \Drupal::entityQuery('user')
        ->condition('status', 1)
        ->execute();
      break;
    default:
      throw \Exception('Unknown broadcast audience');
  }

  if (\Drupal::config('cforge_broadcast.settings')->get('optout')) {
    $opted_out = \Drupal::service('user.data')->get('cforge_broadcast', NULL, 'optout');
    $uids = array_diff($uids, array_keys(array_filter($opted_out)));
  }

  cforge_batch_mail(
    'cforge_broadcast',
    'broadcast',
    $uids,
    ['entity' => $entity]
  );
  // Prevent the entity from being broadcast again.
  if (count($uids) > 1) {
    cforge_broadcast_mark_entity($entity);
  }
}

/**
 * Add the broadcasted entity to the list of already broadcast entities.
 *
 * @param ContentEntityInterface $entity
 *   The entity which has been broadcast.
 */
function cforge_broadcast_mark_entity(ContentEntityInterface $entity) {
  $type = $entity->getEntityTypeId();
  $pairs = \Drupal::keyValue('cforge_broadcast');
  $ids = $pairs->get($type);
  $ids[] = $entity->id();
  $pairs->set($type, array_unique($ids));
}

/**
 * Helper to determine if an entity has already been broadcast.
 * @param type $entity
 * @return bool
 */
function cforge_broadcast_already(\Drupal\Core\Entity\ContentEntityBase $entity) : bool {
  if ($entity->isNew()) return FALSE;
  $type = $entity->getEntityTypeId();
  $pairs = \Drupal::keyValue('cforge_broadcast');
  return in_array($entity->id(), $pairs->get($type, []));
}

/**
 * Get the name or names of the broadcast scopes.
 *
 * @param int $scope
 *   The code of the scope.
 *
 * @return string[]
 *   The name of the scope, or an array of scope names, keyed by scope code
 */
function cforge_broadcast_scope_name($scope = NULL) {
  $scopes = [
    CFORGE_BROADCAST_ME => t('Myself'),
    CFORGE_BROADCAST_NEIGHBOURHOOD => User::load(\Drupal::currentUser()->id())->address->dependent_locality,
    CFORGE_BROADCAST_SITE => t('Everyone in @site', ['@site' => \Drupal::Config('system.site')->get('name')]),
  ];
  if (is_null($scope)) {
    return $scopes;
  }
  return @$scopes[$scope];
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc