You are here

MailchimpCampaignController.php in Mailchimp 8

File

modules/mailchimp_campaign/src/Controller/MailchimpCampaignController.php
View source
<?php

namespace Drupal\mailchimp_campaign\Controller;

use Drupal\Component\Utility\Html;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\mailchimp_campaign\Entity\MailchimpCampaign;
use Mailchimp\MailchimpAPIException;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Mailchimp Campaign controller.
 */
class MailchimpCampaignController extends ControllerBase {

  /**
   * The current request.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected $request;

  /**
   * The entity query.
   *
   * @var \Drupal\Core\Entity\Query\QueryFactory
   */
  protected $entityQuery;

  /**
   * The date formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * Entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * A logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * Initializes a MailchimpCampaignController.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The current request.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   */
  public function __construct(Request $request, DateFormatterInterface $date_formatter, EntityTypeManagerInterface $entityTypeManager, MessengerInterface $messenger, LoggerInterface $logger) {
    $this->request = $request;
    $this->dateFormatter = $date_formatter;
    $this->entityTypeManager = $entityTypeManager;
    $this->messenger = $messenger;
    $this->logger = $logger;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('request_stack')
      ->getCurrentRequest(), $container
      ->get('date.formatter'), $container
      ->get('entity_type.manager'), $container
      ->get('messenger'), $container
      ->get('logger.factory')
      ->get('mailchimp_campaign'));
  }

  /**
   * {@inheritdoc}
   */
  public function overview() {
    $content = [];
    $content['campaigns_table'] = [
      '#type' => 'table',
      '#header' => [
        $this
          ->t('Title'),
        $this
          ->t('Subject'),
        $this
          ->t('Status'),
        $this
          ->t('Mailchimp Audience'),
        $this
          ->t('Mailchimp Template'),
        $this
          ->t('Created'),
        $this
          ->t('Actions'),
      ],
      '#empty' => '',
    ];
    try {
      $campaigns = mailchimp_campaign_load_multiple();
      $templates = mailchimp_campaign_list_templates();
    } catch (MailchimpAPIException $e) {
      $this
        ->messenger()
        ->addError($this
        ->t('Unable to fetch Mailchimp campaign data, caught API exception: @error', [
        '@error' => $e
          ->getMessage(),
      ]));
      return $content;
    }

    /* @var $campaign \Drupal\mailchimp_campaign\Entity\MailchimpCampaign */
    foreach ($campaigns as $campaign) {
      if (!$campaign
        ->isInitialized()) {
        continue;
      }

      // Ensure the associated list/audience still exists.
      if (!isset($campaign->list) || !$campaign->list) {
        continue;
      }
      $campaign_id = $campaign
        ->getMcCampaignId();
      $archive_url = Url::fromUri($campaign->mc_data->archive_url);
      $campaign_url = Url::fromRoute('entity.mailchimp_campaign.view', [
        'mailchimp_campaign' => $campaign_id,
      ]);
      $list_url = Url::fromUri('https://admin.mailchimp.com/lists/dashboard/overview?id=' . $campaign->list->id, [
        'attributes' => [
          'target' => '_blank',
        ],
      ]);
      $send_url = Url::fromRoute('entity.mailchimp_campaign.send', [
        'mailchimp_campaign' => $campaign_id,
      ]);
      if ($campaign->mc_data->status === "save") {
        $send_link = Link::fromTextAndUrl($this
          ->t("Send"), $send_url)
          ->toString();
      }
      elseif ($campaign->mc_data->status === "sending") {
        $campaigns = mailchimp_campaign_load_multiple([
          $campaign_id,
        ], TRUE);
        $campaign = $campaigns[$campaign_id];
        $send_link = $this
          ->t("Sent");
      }
      else {
        $send_link = $this
          ->t("Sent");
      }
      $actions = [
        Link::fromTextAndUrl('View Archive', $archive_url)
          ->toString(),
        Link::fromTextAndUrl('View', $campaign_url)
          ->toString(),
        $send_link,
      ];
      $content['campaigns_table'][$campaign_id]['title'] = [
        '#markup' => Link::fromTextAndUrl($campaign->mc_data->settings->title, $campaign_url)
          ->toString(),
      ];
      $content['campaigns_table'][$campaign_id]['subject'] = [
        '#markup' => $campaign->mc_data->settings->subject_line,
      ];
      $content['campaigns_table'][$campaign_id]['status'] = [
        '#markup' => $campaign->mc_data->status,
      ];
      $content['campaigns_table'][$campaign_id]['list'] = [
        '#markup' => Link::fromTextAndUrl($campaign->list->name, $list_url)
          ->toString(),
      ];
      if (empty($campaign->mc_data->settings->template_id)) {
        $content['campaigns_table'][$campaign_id]['template'] = [
          '#markup' => "-- none --",
        ];
      }
      else {
        $template_url = Url::fromUri('https://admin.mailchimp.com/templates/edit?id=' . $campaign->mc_data->settings->template_id, [
          'attributes' => [
            'target' => '_blank',
          ],
        ]);
        $category = FALSE;

        // Templates are grouped into categories, so we go hunting for our
        // template ID in each category.
        $template_category = [];
        foreach ($templates as $category_name => $template_category) {
          if (isset($template_category[$campaign->mc_data->settings->template_id])) {
            $category = $category_name;
            break;
          }
        }
        if ($category) {
          $content['campaigns_table'][$campaign_id]['template'] = [
            '#markup' => Link::fromTextAndUrl($template_category[$campaign->mc_data->settings->template_id]->name, $template_url)
              ->toString(),
          ];
        }
        else {
          $content['campaigns_table'][$campaign_id]['template'] = [
            '#markup' => $this
              ->t('-- template %template_url not found --', [
              '%template_url' => Link::fromTextAndUrl($campaign->mc_data->settings->template_id, $template_url)
                ->toString(),
            ]),
          ];
        }
      }
      $content['campaigns_table'][$campaign_id]['created'] = [
        '#markup' => $this->dateFormatter
          ->format(strtotime($campaign->mc_data->create_time), 'custom', 'F j, Y - g:ia'),
      ];
      $content['campaigns_table'][$campaign_id]['actions'] = [
        '#markup' => implode(' | ', $actions),
      ];
    }
    $mailchimp_campaigns_url = Url::fromUri('https://admin.mailchimp.com/campaigns', [
      'attributes' => [
        'target' => '_blank',
      ],
    ]);
    $content['mailchimp_list_link'] = [
      '#title' => $this
        ->t('Go to Mailchimp Campaigns'),
      '#type' => 'link',
      '#url' => $mailchimp_campaigns_url,
    ];
    return $content;
  }

  /**
   * View a Mailchimp campaign.
   *
   * @param \Drupal\mailchimp_campaign\Entity\MailchimpCampaign $mailchimp_campaign
   *   The Mailchimp campaign to view.
   *
   * @return array
   *   Renderable array of page content.
   */
  public function view(MailchimpCampaign $mailchimp_campaign) {
    $view_builder = $this->entityTypeManager
      ->getViewBuilder('mailchimp_campaign');
    $content = $view_builder
      ->view($mailchimp_campaign);
    return $content;
  }

  /**
   * View a Mailchimp campaign stats.
   *
   * @param \Drupal\mailchimp_campaign\Entity\MailchimpCampaign $mailchimp_campaign
   *   The Mailchimp campaign to view stats for.
   *
   * @return array
   *   Renderable array of page content.
   */
  public function stats(MailchimpCampaign $mailchimp_campaign) {
    $content = [];

    /* @var \Mailchimp\MailchimpReports $mc_reports */
    $mc_reports = mailchimp_get_api_object('MailchimpReports');
    try {
      if (!$mc_reports) {
        throw new MailchimpAPIException('Cannot get campaign stats without Mailchimp API. Check API key has been entered.');
      }
      $response = $mc_reports
        ->getCampaignSummary($mailchimp_campaign
        ->getMcCampaignId());
    } catch (\Exception $e) {
      $this->messenger
        ->addError($e
        ->getMessage());
      $this->logger
        ->error('An error occurred getting report data from Mailchimp: {message}', [
        'message' => $e
          ->getMessage(),
      ]);
    }
    if (!empty($response)) {

      // Attach stats JS.
      $content['#attached']['library'][] = 'mailchimp_campaign/google-jsapi';
      $content['#attached']['library'][] = 'mailchimp_campaign/campaign-stats';

      // Time series chart data.
      $content['#attached']['drupalSettings']['mailchimp_campaign'] = [
        'stats' => [],
      ];
      foreach ($response->timeseries as $series) {
        $content['#attached']['drupalSettings']['mailchimp_campaign']['stats'][] = [
          'timestamp' => $series->timestamp,
          'emails_sent' => isset($series->emails_sent) ? $series->emails_sent : 0,
          'unique_opens' => $series->unique_opens,
          'recipients_click' => isset($series->recipients_click) ? $series->recipients_click : 0,
        ];
      }
      $content['charts'] = [
        '#prefix' => '<h2>' . $this
          ->t('Hourly stats for the first 24 hours of the campaign') . '</h2>',
        '#markup' => '<div id="mailchimp-campaign-chart"></div>',
      ];
      $content['metrics_table'] = [
        '#type' => 'table',
        '#header' => [
          $this
            ->t('Key'),
          $this
            ->t('Value'),
        ],
        '#empty' => '',
        '#prefix' => '<h2>' . $this
          ->t('Other campaign metrics') . '</h2>',
      ];
      $stat_groups = [
        'bounces',
        'forwards',
        'opens',
        'clicks',
        'facebook_likes',
        'list_stats',
      ];
      foreach ($stat_groups as $group) {
        $content['metrics_table'][] = [
          'key' => [
            '#markup' => '<strong>' . ucfirst(str_replace('_', ' ', $group)) . '</strong>',
          ],
          'value' => [
            '#markup' => '',
          ],
        ];
        foreach ($response->{$group} as $key => $value) {
          if ($key == "last_open" && !empty($value)) {
            $value = $this->dateFormatter
              ->format(strtotime($value), 'custom', 'F j, Y - g:ia');
          }
          $content['metrics_table'][] = [
            'key' => [
              '#markup' => $key,
            ],
            'value' => [
              '#markup' => $value,
            ],
          ];
        }
      }
    }
    else {
      $content['unavailable'] = [
        '#markup' => $this
          ->t('The campaign stats are unavailable at this time.'),
      ];
    }
    return $content;
  }

  /**
   * Callback for entity title autocomplete field.
   *
   * @param string $entity_type
   *   The entity type to search by title.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   A JSON response containing matched entity data.
   */
  public function entityAutocomplete($entity_type) {
    $q = $this->request
      ->get('q');
    $query = $this->entityTypeManager
      ->getStorage($entity_type)
      ->getQuery()
      ->condition('title', $q, 'CONTAINS')
      ->range(0, 10);
    $entity_ids = $query
      ->execute();
    $entities = [];
    if (!empty($entity_ids)) {
      $entities_data = $this->entityTypeManager
        ->getStorage($entity_type)
        ->loadMultiple($entity_ids);
      if (!empty($entities_data)) {

        /* @var $entity \Drupal\Core\Entity\EntityInterface */
        foreach ($entities_data as $id => $entity) {
          $title = $entity
            ->getTypedData()
            ->getString('title');
          $entities[] = [
            'value' => $title . ' [' . $id . ']',
            'label' => Html::escape($title),
          ];
        }
      }
    }
    return new JsonResponse($entities);
  }

}

Classes

Namesort descending Description
MailchimpCampaignController Mailchimp Campaign controller.