Skip to content
Snippets Groups Projects
Mailing-Hooks.php 4.71 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    /**
     * CiviCRM Mailing_Hooks class.
     *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     * @since 5.25
    
     */
    
    namespace CiviCRM_WP_REST\Civi;
    
    class Mailing_Hooks {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      /**
       * @var string
       * Mailing Url endpoint.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public $url_endpoint;
    
      /**
       * @var string
       * Mailing Open endpoint.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public $open_endpoint;
    
      /**
       * @var array
       * The parsed WordPress REST url.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public $parsed_rest_url;
    
      /**
       * Constructor.
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function __construct() {
    
        $this->url_endpoint = rest_url('civicrm/v3/url');
    
        $this->open_endpoint = rest_url('civicrm/v3/open');
    
        $this->parsed_rest_url = parse_url(rest_url());
    
      }
    
      /**
       * Register hooks.
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function register_hooks() {
    
        add_filter('civicrm_alterMailParams', [$this, 'do_mailing_urls'], 10, 2);
    
        add_filter('civicrm_alterExternUrl', [$this, 'alter_mailing_extern_urls'], 10, 6);
    
      }
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Replaces the "open" and "click tracking" URLs for a CiviMail Mailing with
       * their REST counterparts.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @uses 'civicrm_alterExternUrl' filter.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
       * @param \GuzzleHttp\Psr7\Uri $url
       * @param string|NULL $path
       * @param string|NULL $query
       * @param string|NULL $fragment
       * @param bool|NULL $absolute
       * @param bool|NULL $isSSL
       */
      public function alter_mailing_extern_urls(&$url, $path, $query, $fragment, $absolute, $isSSL) {
    
        if ($path == 'extern/url') {
          $url = $url
            ->withHost($this->parsed_rest_url['host'])
            ->withQuery($query)
            ->withPath("{$this->parsed_rest_url['path']}civicrm/v3/url");
        }
    
        if ($path == 'extern/open') {
          $url = $url
            ->withHost($this->parsed_rest_url['host'])
            ->withQuery($query)
            ->withPath("{$this->parsed_rest_url['path']}civicrm/v3/open");
        }
    
      }
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Filters the mailing HTML and replaces calls to 'extern/url.php' and
       * 'extern/open.php' with their REST counterparts 'civicrm/v3/url' and
       * 'civicrm/v3/open'.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
       * @uses 'civicrm_alterMailParams'
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
       *
       * @param array &$params Mail params.
       * @param string $context The Context.
       * @return array $params The filtered Mail params.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function do_mailing_urls(&$params, $context) {
    
        if (in_array($context, ['civimail', 'flexmailer'])) {
    
          if (!empty($params['html'])) {
            $params['html'] = $this->is_mail_tracking_url_alterable($params['html'])
              ? $this->replace_html_mailing_tracking_urls($params['html'])
              : $params['html'];
          }
    
          if (!empty($params['text'])) {
            $params['text'] = $this->is_mail_tracking_url_alterable($params['text'])
              ? $this->replace_text_mailing_tracking_urls($params['text'])
              : $params['text'];
          }
    
        }
    
        return $params;
    
      }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Replace HTML mailing tracking urls.
       *
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @param string $content The mailing content.
       * @return string $content The mailing content.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function replace_html_mailing_tracking_urls(string $content) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $doc = \phpQuery::newDocument($content);
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        foreach ($doc['[href*="civicrm/extern/url.php"], [src*="civicrm/extern/open.php"]'] as $element) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $href = pq($element)->attr('href');
          $src = pq($element)->attr('src');
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Replace extern/url.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if (strpos($href, 'civicrm/extern/url.php')) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $query_string = strstr($href, '?');
            pq($element)->attr('href', $this->url_endpoint . $query_string);
    
          }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Replace extern/open.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if (strpos($src, 'civicrm/extern/open.php')) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $query_string = strstr($src, '?');
            pq($element)->attr('src', $this->open_endpoint . $query_string);
    
          }
    
          unset($href, $src, $query_string);
    
        }
    
        return $doc->html();
    
      }
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Replace text mailing tracking URLs.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.25
       *
       * @param string $content The mailing content.
       * @return string $content The mailing content.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function replace_text_mailing_tracking_urls(string $content) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Replace extern URL.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $content = preg_replace('/http.*civicrm\/extern\/url\.php/i', $this->url_endpoint, $content);
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Replace open URL.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $content = preg_replace('/http.*civicrm\/extern\/open\.php/i', $this->open_endpoint, $content);
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        return $content;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Checks whether for a given mail content (text or HTML) the tracking URLs
       * are alterable or need to be altered.
       *
       * @since 5.25
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @param string $content The mail content: text or HTML.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @return bool $is_alterable
       */
      public function is_mail_tracking_url_alterable($content) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if (!is_string($content)) {
          return FALSE;
        }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        return strpos($content, 'civicrm/extern/url.php') || strpos($content, 'civicrm/extern/open.php');
    
      }