AcyMailing
Our siteForumBlog
Latest version
Latest version
  • AcyMailing documentation
  • How to renew AcyMailing license?
  • How to switch AcyMailing license plan?
  • Setup AcyMailing
    • Update from AcyMailing 5
    • Installation
      • Download AcyMailing
      • Install AcyMailing
      • Update AcyMailing
      • Switching from Starter to a paid version
      • Uninstall AcyMailing
    • Move AcyMailing between websites
      • Migrate between Joomla! and WordPress
      • Move between two WordPress websites
      • Switch from Joomla 3 to Joomla 4/5
    • Configuration
      • License
      • Mail settings
        • Set up your DKIM : DomainKeys Identified Mail
        • Set up Oauth 2.0
      • Queue process
      • Configure your send process
      • Subscription
      • Bounce handling
      • Data collection
      • Security
      • Languages
    • Step by step guide
    • Multilingual websites
      • Translate AcyMailing
      • Custom translation
    • Subscription to your lists
      • Subscription form - Joomla
      • Subscription form - WordPress
      • Other subscription methods
      • RSForm!Pro integration
  • External sending methods
    • AcyMailing Sending Service
    • Amazon SES
    • ElasticEmail
    • Mailgun
    • Postmark
    • SendGrid
    • Brevo SMTP Relay
    • Brevo / Sendinblue (Legacy)
  • Main pages
    • Dashboard
    • Subscription forms
      • Subscription Form
      • Header
      • Footer
      • Popup
      • Shortcode (Wordpress)
    • Subscribers
      • Create a subscriber
      • Import subscribers
      • Export subscribers
    • Custom fields
      • Create Custom Field
      • Examples
    • Lists
      • Create a list
    • Segment
      • Edition
    • Emails
      • Creation of a campaign
        • Choose a template
        • Edit email
        • Recipients
        • Segment
        • Send settings
        • Tests
        • Summary
      • A/B testing
      • Automatic campaigns
      • Follow-up
        • Trigger
        • Condition
        • Emails
        • Summary
      • Special mails
    • The email editor
      • Tenor integration
      • Unsplash integration
    • Templates
      • Create a template
      • Import a template
    • Email overrides
      • Edition
    • Automations
      • Information
      • Conditions
      • Actions
      • Action targets
      • Summary
    • Scenario
      • Create a new Scenario
      • Performances
    • Queue
    • Statistics
      • Overview
      • Detailed Statistics
      • Click map
      • Links details
      • User click details
      • Statistics per list
    • Add-ons
    • Mailbox actions
      • Mailbox actions
        • Edition
      • Bounce rules
        • Configuration
        • Listing
        • Create bounce rules
  • Advanced
    • Send follow-up messages based on subscription
    • Let site users use AcyMailing
      • List management
      • User management
      • Campaigns management
    • Show an archive of the sent newsletters
    • Show a profile edition form on your site
    • Partner platform
      • Log in
      • Dashboard
      • Single domain details
  • Integrations
    • Settings
    • Joomla add-ons
      • Joomla articles
      • CB Subscriptions
      • Community Builder
      • Community Quiz
      • Community Surveys
      • Contacts
      • Dashboard Quick icon
      • Docman
      • DPCalendar
      • EasyBlog
      • EasyProfile
      • EasySocial
      • Event Booking
      • FLEXIcontent
      • HikaShop
      • iCagenda
      • JCal Pro
      • jDownloads
      • JEvents
      • JSW CRM
      • JTicketing
      • K2 Content
      • Membership Pro
      • Module
      • PayPlans
      • Phoca Download
      • RSEvents!Pro
      • Seblod
      • Shika
      • VirtueMart
      • Zoo
    • WordPress add-ons
      • WordPress posts and pages
      • Advanced Custom Fields (ACF)
      • Business Directory
      • Contact Form 7
      • Easy Digital Downloads
      • EventON
      • Events Manager
      • Gravity Forms
      • Learndash
      • MemberPress
      • Modern Events Calendar
      • The events calendar
      • Ultimate Member
      • Uncanny Automator
      • WooCommerce
    • All websites add-ons
      • Articles, posts and pages from WordPress and Joomla
      • Automation - export action
      • Create user
      • Custom headers
      • RSS and Atom feeds
      • Table of contents generator
      • Universal filter
    • Zapier
  • Developers
    • Developer Documentation
    • Making a custom add-on
      • Execute custom script on specific AcyMailing actions
      • Insert a dynamic text in an email for Joomla
      • Insert a custom block in an email for Joomla
      • Insert a dynamic text in an email for WordPress
      • Insert a custom block in an email for WordPress
    • Custom script using our code
    • Create a page override
    • Joomla quickstart package with AcyMailing
    • Customise inserted content
  • FAQ
    • Could not instantiate mail function - AcyMailing
    • Spam issue
    • Your send process is slow?
    • Compatibility issues
    • Mail archive not displaying special characters
Powered by GitBook
On this page
  • Base file
  • Define the insertion options
  • Dynamically insert a content one by one in an email
  • Dynamically insert content by category in an email
  1. Developers
  2. Making a custom add-on

Insert a custom block in an email for WordPress

This step by step guide shows you how to develop your own add-on, allowing you to insert a dynamic HTML block in your emails with data pulled from an other plugin.

PreviousInsert a dynamic text in an email for WordPressNextCustom script using our code

Last updated 5 months ago

You may want to send to your users the latest products you have in store this month, the upcoming events they can book, or your latest articles built with an other plugin.

To do this, you can either copy your content title, image, description, etc... or you can use one of our add-ons.

If we don't have any add-on yet for the plugin you're using, you can create it using this guide, which will add a new block type in our email editor:

As an example, here is a simple WordPress post inserted in an email:

For this step by step guide, we will create an integration with WordPress posts that lets you:

  • search and insert a post

  • insert posts by category

Base file

Before continuing, make sure you created a custom add-on by following this guide:

In your add-on main folder, add an image that will be shown as the icon of your new block type. We will use this image in this example:

In the file plugin.php, add the following method to your class:

public function __construct()
{
    parent::__construct();
    //$this->installed = acym_isExtensionActive('custom-post-type-ui/custom-post-type-ui.php');

    $this->pluginDescription->name = 'Posts';
    $this->pluginDescription->category = 'Anything';
    $this->pluginDescription->description = '- Insert posts in emails';
    $this->pluginDescription->icon = ACYM_PLUGINS_URL.'/'.basename(__DIR__).'/icon.png';
}
  • on line 4, we can make sure any plugin we need is both installed and active. AcyMailing won't show the block type if you set false for this variable.

  • on line 6, the name you set will be shown on your new block type

  • on line 9, the URL must point to your icon image

Define the insertion options

For your integration to be visible in the editor, you will need to add the following method to your plugin.php file:

public function getPossibleIntegrations()
{
    return $this->pluginDescription;
}

If you return null in this method, your integration won't be shown. This gives you the possibility to add conditions here.

At this point your new block type should be visible in the editor if your custom plugin is activated:

To define the insertion options that will be shown in the right panel of the editor, you will need to add this use statement at the top of the plugin.php file:

use AcyMailing\Helpers\TabHelper;

Then add this method:

public function insertionOptions($defaultValues = null)
{
    $this->defaultValues = $defaultValues;
    $this->prepareWPCategories('category');

    $tabHelper = new TabHelper();
    $identifier = $this->name;
    $tabHelper->startTab(acym_translation('ACYM_ONE_BY_ONE'), !empty($this->defaultValues->defaultPluginTab) && $identifier === $this->defaultValues->defaultPluginTab);

    $displayOptions = [
        [
            'title' => 'ACYM_DISPLAY',
            'type' => 'checkbox',
            'name' => 'display',
            'options' => [
                'title' => ['ACYM_TITLE', true],
                'image' => ['ACYM_FEATURED_IMAGE', true],
                'excerpt' => ['ACYM_EXCERPT', false],
                'intro' => ['ACYM_INTRO_ONLY', true],
                'content' => ['ACYM_FULL_TEXT', false],
                'readmore' => ['ACYM_READ_MORE', false],
            ],
        ],
        [
            'title' => 'ACYM_CLICKABLE_TITLE',
            'type' => 'boolean',
            'name' => 'clickable',
            'default' => true,
        ],
        [
            'title' => 'ACYM_CLICKABLE_IMAGE',
            'type' => 'boolean',
            'name' => 'clickableimg',
            'default' => false,
        ],
        [
            'title' => 'ACYM_TRUNCATE',
            'type' => 'intextfield',
            'isNumber' => 1,
            'name' => 'wrap',
            'text' => 'ACYM_TRUNCATE_AFTER',
            'default' => 0,
        ],
        [
            'title' => 'ACYM_DISPLAY_PICTURES',
            'type' => 'pictures',
            'name' => 'pictures',
        ],
    ];

    echo $this->displaySelectionZone($this->getFilteringZone().$this->prepareListing());
    echo $this->pluginHelper->displayOptions($displayOptions, $identifier, 'individual', $this->defaultValues);

    $tabHelper->endTab();
    $identifier = 'auto'.$this->name;
    $tabHelper->startTab(acym_translation('ACYM_BY_CATEGORY'), !empty($this->defaultValues->defaultPluginTab) && $identifier === $this->defaultValues->defaultPluginTab);

    $catOptions = [
        [
            'title' => 'ACYM_ORDER_BY',
            'type' => 'select',
            'name' => 'order',
            'options' => [
                'ID' => 'ACYM_ID',
                'post_date' => 'ACYM_PUBLISHING_DATE',
                'post_title' => 'ACYM_TITLE',
                'rand' => 'ACYM_RANDOM',
            ],
        ],
    ];

    $this->autoContentOptions($catOptions);
    $this->autoCampaignOptions($catOptions);
    $displayOptions = array_merge($displayOptions, $catOptions);

    echo $this->displaySelectionZone($this->getCategoryListing());
    echo $this->pluginHelper->displayOptions($displayOptions, $identifier, 'grouped', $this->defaultValues);

    $tabHelper->endTab();
    $tabHelper->display('plugin');
}

You will need to modify multiple parts of this method:

  • line 4, we get the categories to be able to filter posts. For plugins not using the WordPress category system, you will need to set an array of objects to the categories variable. Each object must have an id, parent_id and title.

  • if your plugin's main parent category ID is 0, you need to add $this->rootCategoryId = 0; into the add-on's construct method. This will help AcyMailing display the categories correctly on the listing

  • line 10 we define the most common options shown in the right panel, you may want to modify the lines 16 to 21 if you want to have more data to display in your email

  • lines 64 to 67, we define the possible columns used to order the posts when multiple ones are inserted by category

You will also need to add this method to prepare the listing showing the content you can insert:

public function prepareListing()
{
    $this->querySelect = 'SELECT post.ID, post.post_title, post.post_date, post.post_content ';
    $this->query = 'FROM #__posts AS post ';
    $this->filters = [];
    $this->filters[] = 'post.post_type = "post"';
    $this->filters[] = 'post.post_status = "publish"';
    $this->searchFields = ['post.ID', 'post.post_title'];
    $this->pageInfo->order = 'post.ID';
    $this->elementIdTable = 'post';
    $this->elementIdColumn = 'ID';

    parent::prepareListing();

    if (!empty($this->pageInfo->filter_cat)) {
        $this->query .= 'JOIN #__term_relationships AS cat ON post.ID = cat.object_id';
        $this->filters[] = 'cat.term_taxonomy_id = '.intval($this->pageInfo->filter_cat);
    }

    return $this->getElementsListing(
        [
            'header' => [
                'post_title' => [
                    'label' => 'ACYM_TITLE',
                    'size' => '7',
                ],
                'post_date' => [
                    'label' => 'ACYM_PUBLISHING_DATE',
                    'size' => '4',
                    'type' => 'date',
                ],
                'ID' => [
                    'label' => 'ACYM_ID',
                    'size' => '1',
                    'class' => 'text-center',
                ],
            ],
            'id' => 'ID',
            'rows' => $this->getElements(),
        ]
    );
}

Let's break down this code:

  • line 3, we get the columns needed to show the content that can be inserted. You should always at least get the id and the title

  • line 4, we define in which table we get the content that can be inserted.

  • we can filter the content shown in the insertion options by adding conditions in the filter line 6. In this case, we chose to only show posts that are published

  • line 8, we get the columns on which we want the search field to be applied when searching for a content to insert

  • line 9, we define the column used to order the results. We chose to show the posts by id (recent posts first)

  • line 10, we define the table containing the information we need. We apply the alias "post" on the main table to make the query shorter

  • lines 11 and 38, we define the column name containing the id (often "id", but some plugins can have "ID", "content_id", etc...)

  • lines 16 and 17, we add a condition if a category is selected in the category filter. In this case, the category id of a file is stored in a relationship table so we need to join it

  • lines 23, 27 and 32 must use the column names that are selected on line 3. These will be shown on the posts listing. You can add as many columns as you want, but you should always make sure that the total size is always 12. In this example, the title has a size of 7 (line 25), the publishing date has a size of 4 (line 29) and the id has a size of 1 (line 34)

At this point you should see your insertion options on the right panel after dragging your new block type into an email:

Dynamically insert a content one by one in an email

Now that we have our insertion options, we can at the code inserting our content into the email. For this, add this method to your plugin.php file:

public function replaceContent(&$email)
{
    $this->replaceOne($email);
}

We will modify it later, for now you don't need to modify it.

Add this other method that defines how the inserted content should look like:

public function replaceIndividualContent($tag)
{
    $query = 'SELECT post.*
                FROM #__posts AS post 
                WHERE post.post_type = "post" 
                    AND post.post_status = "publish"
                    AND post.ID = '.intval($tag->id);

    $element = $this->initIndividualContent($tag, $query);

    if (empty($element)) {
        return '';
    }

    $link = get_permalink($element->ID);

    $title = '';
    $afterArticle = '';
    $imagePath = '';
    $contentText = '';

    if (in_array('title', $tag->display)) {
        $title = $element->post_title;
    }

    if (in_array('image', $tag->display)) {
        $imageId = get_post_thumbnail_id($tag->id);
        if (!empty($imageId)) {
            if (empty($tag->size)) {
                $tag->size = 'full';
            }
            $imagePath = get_the_post_thumbnail_url($tag->id, $tag->size);
        }
    }

    if (in_array('excerpt', $tag->display) && !empty($element->post_excerpt)) {
        $contentText .= '<p>'.$element->post_excerpt.'</p>';
    }

    if (in_array('description', $tag->display)) {
        $contentText .= $element->post_content;
    }

    if (in_array('readmore', $tag->display)) {
        $afterArticle .= '<a class="acymailing_readmore_link" style="text-decoration:none;" target="_blank" href="'.$link.'">';
        $afterArticle .= '<span class="acymailing_readmore">'.acym_escape(acym_translation('ACYM_READ_MORE')).'</span>';
        $afterArticle .= '</a>';
    }

    $format = new stdClass();
    $format->tag = $tag;
    $format->title = $title;
    $format->afterArticle = $afterArticle;
    $format->imagePath = $imagePath;
    $format->description = $contentText;
    $format->link = empty($tag->clickable) && empty($tag->clickableimg) ? '' : $link;
    $result = '<div class="acymailing_content">'.$this->pluginHelper->getStandardDisplay($format).'</div>';

    return $this->finalizeElementFormat($result, $tag, []);
}

Here are the most important things to modify:

  • line 3, you need to make an SQL query that gets all the data you need to display in your email. The id of the selected content can be found in the variable $tag->id.

  • on line 15 you need to get the URL that shows the content on the front-end of your website. It will be added to the title and image of the inserted content

  • lines 22 to 48, we look at the options checked in $tag->display and prepare the data we want to display. All the options selected in the editor's insertion options are stored in $tag, and the data of the content to insert is is $element

  • lines 50 to 56, we create an object used by our code to automatically generate the HTML to insert in the email. Note that you could simply return the HTML you want, but using our code makes life easier to handle most of our options automatically (shorten the description, resize/remove images, add a link to the title/image, etc...)

You should now be able to insert a single element with your new block type:

Dynamically insert content by category in an email

Now that our custom add-on lets us insert posts one by one, we can make it insert them in bulk.

Start by modifying the method replaceContent that we previously added, and call the function replaceMultiple like this, just before calling replaceOne:

public function replaceContent(&$email)
{
    $this->replaceMultiple($email);
    $this->replaceOne($email);
}

You then need to add this method:

public function generateByCategory(&$email)
{
    $tags = $this->pluginHelper->extractTags($email, 'auto'.$this->name);
    $this->tags = [];

    if (empty($tags)) {
        return $this->generateCampaignResult;
    }

    foreach ($tags as $oneTag => $parameter) {
        if (isset($this->tags[$oneTag])) {
            continue;
        }

        $query = 'SELECT DISTINCT post.`ID` FROM #__posts AS post ';

        $where = [];

        $selectedArea = $this->getSelectedArea($parameter);
        if (!empty($selectedArea)) {
            $query .= 'JOIN #__term_relationships AS cat ON post.ID = cat.object_id ';
            $where[] = 'cat.term_taxonomy_id IN ('.implode(',', $selectedArea).')';
        }

        $where[] = 'post.post_type = "post"';
        $where[] = 'post.post_status = "publish"';

        if (!empty($parameter->min_publish)) {
            $parameter->min_publish = acym_date(acym_replaceDate($parameter->min_publish), 'Y-m-d H:i:s', false);
            $where[] = 'post.post_date_gmt >= '.acym_escapeDB($parameter->min_publish);
        }

        if (!empty($parameter->onlynew)) {
            $lastGenerated = $this->getLastGenerated($email->id);
            if (!empty($lastGenerated)) {
                $where[] = 'post.post_date_gmt > '.acym_escapeDB(acym_date($lastGenerated, 'Y-m-d H:i:s', false));
            }
        }

        $query .= ' WHERE ('.implode(') AND (', $where).')';

        $this->tags[$oneTag] = $this->finalizeCategoryFormat($query, $parameter, 'post');
    }

    return $this->generateCampaignResult;
}

This basically builds an SQL query that gets the post IDs that should be inserted in the email, based on what you selected in the insertion options:

  • line 15 we select the id of the posts

  • on lines 21 and 22, we make sure only the posts in the selected categories are inserted. Since the category relationship is stored in an other table we need to adapt the query and join on this other table

  • lines 25 and 27 we make sure only published posts are inserted

  • the lines 28 to 38 are only useful if you want to use your integration with automatic campaigns. This makes sure that the auto-campaign is only sent if the minimum number of posts inserted is met, and that the same post isn't inserted in multiple campaigns

At this point your integration is ready and you should be able to insert the content either one by one or by category in your emails!

Here is the entire code for the plugin.php file:

<?php

use AcyMailing\Core\AcymPlugin;
use AcyMailing\Helpers\TabHelper;

class plgAcymExampleaddon extends AcymPlugin
{
    public function __construct()
    {
        parent::__construct();

        $this->pluginDescription->name = 'Posts';
        $this->pluginDescription->category = 'Anything';
        $this->pluginDescription->description = '- Insert posts in emails';
        $this->pluginDescription->icon = ACYM_PLUGINS_URL.'/'.basename(__DIR__).'/icon.png';

        $this->rootCategoryId = 0;
    }

    public function getPossibleIntegrations()
    {
        return $this->pluginDescription;
    }

    public function insertionOptions($defaultValues = null)
    {
        $this->defaultValues = $defaultValues;
        $this->prepareWPCategories('category');

        $tabHelper = new TabHelper();
        $identifier = $this->name;
        $tabHelper->startTab(acym_translation('ACYM_ONE_BY_ONE'), !empty($this->defaultValues->defaultPluginTab) && $identifier === $this->defaultValues->defaultPluginTab);

        $displayOptions = [
            [
                'title' => 'ACYM_DISPLAY',
                'type' => 'checkbox',
                'name' => 'display',
                'options' => [
                    'title' => ['ACYM_TITLE', true],
                    'image' => ['ACYM_FEATURED_IMAGE', true],
                    'excerpt' => ['ACYM_EXCERPT', false],
                    'description' => ['ACYM_DESCRIPTION', true],
                    'readmore' => ['ACYM_READ_MORE', false],
                ],
            ],
            [
                'title' => 'ACYM_CLICKABLE_TITLE',
                'type' => 'boolean',
                'name' => 'clickable',
                'default' => true,
            ],
            [
                'title' => 'ACYM_CLICKABLE_IMAGE',
                'type' => 'boolean',
                'name' => 'clickableimg',
                'default' => false,
            ],
            [
                'title' => 'ACYM_TRUNCATE',
                'type' => 'intextfield',
                'isNumber' => 1,
                'name' => 'wrap',
                'text' => 'ACYM_TRUNCATE_AFTER',
                'default' => 0,
            ],
            [
                'title' => 'ACYM_DISPLAY_PICTURES',
                'type' => 'pictures',
                'name' => 'pictures',
            ],
        ];

        echo $this->displaySelectionZone($this->getFilteringZone().$this->prepareListing());
        echo $this->pluginHelper->displayOptions($displayOptions, $identifier, 'individual', $this->defaultValues);

        $tabHelper->endTab();
        $identifier = 'auto'.$this->name;
        $tabHelper->startTab(acym_translation('ACYM_BY_CATEGORY'), !empty($this->defaultValues->defaultPluginTab) && $identifier === $this->defaultValues->defaultPluginTab);

        $catOptions = [
            [
                'title' => 'ACYM_ORDER_BY',
                'type' => 'select',
                'name' => 'order',
                'options' => [
                    'ID' => 'ACYM_ID',
                    'post_date' => 'ACYM_PUBLISHING_DATE',
                    'post_title' => 'ACYM_TITLE',
                    'rand' => 'ACYM_RANDOM',
                ],
            ],
        ];

        $this->autoContentOptions($catOptions);
        $this->autoCampaignOptions($catOptions);
        $displayOptions = array_merge($displayOptions, $catOptions);

        echo $this->displaySelectionZone($this->getCategoryListing());
        echo $this->pluginHelper->displayOptions($displayOptions, $identifier, 'grouped', $this->defaultValues);

        $tabHelper->endTab();
        $tabHelper->display('plugin');
    }

    public function prepareListing()
    {
        $this->querySelect = 'SELECT post.ID, post.post_title, post.post_date, post.post_content ';
        $this->query = 'FROM #__posts AS post ';
        $this->filters = [];
        $this->filters[] = 'post.post_type = "post"';
        $this->filters[] = 'post.post_status = "publish"';
        $this->searchFields = ['post.ID', 'post.post_title'];
        $this->pageInfo->order = 'post.ID';
        $this->elementIdTable = 'post';
        $this->elementIdColumn = 'ID';

        parent::prepareListing();

        if (!empty($this->pageInfo->filter_cat)) {
            $this->query .= 'JOIN #__term_relationships AS cat ON post.ID = cat.object_id';
            $this->filters[] = 'cat.term_taxonomy_id = '.intval($this->pageInfo->filter_cat);
        }

        return $this->getElementsListing(
            [
                'header' => [
                    'post_title' => [
                        'label' => 'ACYM_TITLE',
                        'size' => '7',
                    ],
                    'post_date' => [
                        'label' => 'ACYM_PUBLISHING_DATE',
                        'size' => '4',
                        'type' => 'date',
                    ],
                    'ID' => [
                        'label' => 'ACYM_ID',
                        'size' => '1',
                        'class' => 'text-center',
                    ],
                ],
                'id' => 'ID',
                'rows' => $this->getElements(),
            ]
        );
    }

    public function replaceContent(&$email)
    {
        $this->replaceMultiple($email);
        $this->replaceOne($email);
    }

    public function replaceIndividualContent($tag)
    {
        $query = 'SELECT post.*
                    FROM #__posts AS post 
                    WHERE post.post_type = "post" 
                        AND post.post_status = "publish"
                        AND post.ID = '.intval($tag->id);

        $element = $this->initIndividualContent($tag, $query);

        if (empty($element)) {
            return '';
        }

        $link = get_permalink($element->ID);

        $title = '';
        $afterArticle = '';
        $imagePath = '';
        $contentText = '';

        if (in_array('title', $tag->display)) {
            $title = $element->post_title;
        }

        if (in_array('image', $tag->display)) {
            $imageId = get_post_thumbnail_id($tag->id);
            if (!empty($imageId)) {
                if (empty($tag->size)) {
                    $tag->size = 'full';
                }
                $imagePath = get_the_post_thumbnail_url($tag->id, $tag->size);
            }
        }

        if (in_array('excerpt', $tag->display) && !empty($element->post_excerpt)) {
            $contentText .= '<p>'.$element->post_excerpt.'</p>';
        }

        if (in_array('description', $tag->display)) {
            $contentText .= $element->post_content;
        }

        if (in_array('readmore', $tag->display)) {
            $afterArticle .= '<a class="acymailing_readmore_link" style="text-decoration:none;" target="_blank" href="'.$link.'">';
            $afterArticle .= '<span class="acymailing_readmore">'.acym_escape(acym_translation('ACYM_READ_MORE')).'</span>';
            $afterArticle .= '</a>';
        }

        $format = new stdClass();
        $format->tag = $tag;
        $format->title = $title;
        $format->afterArticle = $afterArticle;
        $format->imagePath = $imagePath;
        $format->description = $contentText;
        $format->link = empty($tag->clickable) && empty($tag->clickableimg) ? '' : $link;
        $result = '<div class="acymailing_content">'.$this->pluginHelper->getStandardDisplay($format).'</div>';

        return $this->finalizeElementFormat($result, $tag, []);
    }

    public function generateByCategory(&$email)
    {
        $tags = $this->pluginHelper->extractTags($email, 'auto'.$this->name);
        $this->tags = [];

        if (empty($tags)) {
            return $this->generateCampaignResult;
        }

        foreach ($tags as $oneTag => $parameter) {
            if (isset($this->tags[$oneTag])) {
                continue;
            }

            $query = 'SELECT DISTINCT post.`ID` FROM #__posts AS post ';

            $where = [];

            $selectedArea = $this->getSelectedArea($parameter);
            if (!empty($selectedArea)) {
                $query .= 'JOIN #__term_relationships AS cat ON post.ID = cat.object_id ';
                $where[] = 'cat.term_taxonomy_id IN ('.implode(',', $selectedArea).')';
            }

            $where[] = 'post.post_type = "post"';
            $where[] = 'post.post_status = "publish"';

            if (!empty($parameter->min_publish)) {
                $parameter->min_publish = acym_date(acym_replaceDate($parameter->min_publish), 'Y-m-d H:i:s', false);
                $where[] = 'post.post_date_gmt >= '.acym_escapeDB($parameter->min_publish);
            }

            if (!empty($parameter->onlynew)) {
                $lastGenerated = $this->getLastGenerated($email->id);
                if (!empty($lastGenerated)) {
                    $where[] = 'post.post_date_gmt > '.acym_escapeDB(acym_date($lastGenerated, 'Y-m-d H:i:s', false));
                }
            }

            $query .= ' WHERE ('.implode(') AND (', $where).')';

            $this->tags[$oneTag] = $this->finalizeCategoryFormat($query, $parameter, 'post');
        }

        return $this->generateCampaignResult;
    }
}
Making a custom add-on
10KB
icon.png
image