Search

This is totally new for me.

I would like to use Rowan's Email Template Filter to send email notifications on entry creation. The local dev is a default EasyPHP server on WinXP. I followed his tutorial but didn't got this working.

  1. What are the server requirements to send emails?

  2. Do I have to set up anything else beside the instructions in his tutorial to send emails from Symphony?

Thanks for any tips and clues.

Update:

I understood what Email Template Filter does.

THE question: what do I need to set up for the SMTP server to send emails from localhost? Taken from here:

This method is generally more reliable and can be especially helpful when mail/Sendmail is unavailable (e.g. on localhost, or on cloud setups).

On the page I added the necessary fields to the form as suggested in the event (having the Send Notification Email filter) documentation, but I get this error on submitting:

<filter name="send-email" status="failed">No valid recipients found. Check send-email[recipient] field.</filter>

Does it take only an author or developer? I gave it a valid email address.

Symphony's default send-email event only accepts usernames because you have to expose the recipient in your source code (as a hidden field).

I'm in a situation where the client wants a notification email be sent to a certain email address when an entry is created (that address is changeable over time).

@michael

Creating an Author with that email address would be the recommended way to achieve this? Or I could create a section, some entries and temper with the default send-mail filter behavior ...

I wouldn't hack the Symphony core. So I see two options:

  • Create an author (named "email recipient" or s.th. similar) as you proposed.
  • Write a custom event (which isn't too hard with new Core Email API).

If you want to try the latter, take a look at the developer documentation (draft!). You may find it on GitHub:

https://github.com/michael-e/core-email-api-docs/blob/master/developer-documentation.markdown

@Michael,

I'm totally useless at PHP - if I wanted to use some of the example code from the link above - where abouts would I put that to create a custom event.

I'm guessing somewhere in the 'event.name.php' file associated with each event but where abouts does it need to go in that file?

Also - if I wanted to populate the email text with fields from my event, what format would I use in this line?:

$email->text_html              = '<html><body><p>Hello Alice.</p></body></html>';

Can I use fields[fieldname] in that string?

Thanks for the help - quite excited by the possibilities of the Core Email API.

You got me! I haven't tried myself, to be honest, because I am working on the biggest project ever and haven't found the time...

OK, look at lines 174 ff. in symphony/lib/toolkit/events/event.section.php -- this is the standard send-email filter. You see that you can access the POST data using:

$fields = $_POST['send-email'];
...

You could rebuild this functionality in your custom event (resp. event filter).

Honestly speaking it's much easier if you create a "dummy author" and use the standard event! The Core Email API is especially useful if you have to send more customized stuff, and it still has to unleash its power in combination with email templating extensions etc... But if you really want to try building a custom event filter, here is a start:

Class extension_send_custom_email extends Extension{

    public function about(){
        return array(
            'name' => 'Send Custom Email (Event Filter)',
            'version' => '1.0',
            'release-date' => '2011-03-08',
            'author' => array(
                'name' => 'Michael Eichelsdoerfer',
                'website' => 'http://www.michael-eichelsdoerfer.de',
                'email' => 'info@michael-eichelsdoerfer.de'
            )
        );
    }

    public function getSubscribedDelegates(){
        return array(
                    array(
                        'page' => '/frontend/',
                        'delegate' => 'EventPostSaveFilter',
                        'callback' => 'runCustomEmailEvent'
                    ),

                    array(
                        'page' => '/blueprints/events/new/',
                        'delegate' => 'AppendEventFilter',
                        'callback' => 'addFilterToSelect'
                    ),

                    array(
                        'page' => '/blueprints/events/edit/',
                        'delegate' => 'AppendEventFilter',
                        'callback' => 'addFilterToSelect'
                    ),

        );
    }

    public function addFilterToSelect($context){
        $context['options'][] = array('send-custom-email', @in_array('send-custom-email', $context['selected']), 'Send Custom Email');
    }

    public function runCustomEmailEvent($context){
        if(!in_array('send-custom-email', $context['event']->eParamFILTERS)) return;

        ### Do stuff here if necessary. 
        ### $context has everything you might need
        ### ...

        ### Symphony stuff: find form values etc.
        if(!function_exists('__sendEmailFindFormValue')){
            function __sendEmailFindFormValue($needle, $haystack, $discard_field_name=true, $default=NULL, $collapse=true){

                if(preg_match('/^(fields[[^]]+],?)+$/i', $needle)){
                    $parts = preg_split('/,/i', $needle, -1, PREG_SPLIT_NO_EMPTY);
                    $parts = array_map('trim', $parts);

                    $stack = array();
                    foreach($parts as $p){
                        $field = str_replace(array('fields[', ']'), '', $p);
                        ($discard_field_name ? $stack[] = $haystack[$field] : $stack[$field] = $haystack[$field]);
                    }

                    if(is_array($stack) && !empty($stack)) return ($collapse ? implode(' ', $stack) : $stack);
                    else $needle = NULL;
                }

                $needle = trim($needle);
                if(empty($needle)) return $default;

                return $needle;

            }
        }

        $fields = $_POST['send-email'];

        $fields['recipient'] = __sendEmailFindFormValue($fields['recipient'], $_POST['fields'], true);
        $fields['recipient'] = preg_split('/,/i', $fields['recipient'], -1, PREG_SPLIT_NO_EMPTY);
        $fields['recipient'] = array_map('trim', $fields['recipient']);

        $fields['recipient'] = $this->_Parent->Database->fetch("SELECT `email`, `first_name` FROM `sym_authors` WHERE `username` IN ('".@implode("', '", $fields['recipient'])."') ");

        $fields['subject'] = __sendEmailFindFormValue($fields['subject'], $_POST['fields'], true, __('[Symphony] A new entry was created on %s', array($this->_Parent->Configuration->get('sitename', 'general'))));

        $fields['body'] = __sendEmailFindFormValue($fields['body'], $_POST['fields'], false, NULL, false);

        if(is_array($fields['body'])){
            foreach($fields['body'] as $field_handle => $value){
                $body .= "// $field_handle" . General::CRLF . $value . General::CRLF . General::CRLF;
            }
        }

        else $body .= $fields['body'];

        $to = array();
        foreach($fields['recipient'] as $recipient){
            $to[$recipient['email']] = $recipient['first_name'];
        }

        ### Create a message
        ### ...

    }

}

P.S. The above is a skeleton for an extension driver. You have to stick to the naming conventions! It will provide its own event filter which can be added to the "save" event.

@michael-e

Why did you create an extension? Wouldn't it be easier to customize an event?

I was thinking about editing the functionality of the send-mail part of the event processing.

I was thinking about editing the functionality of the send-mail part of the event processing.

This filter is in the Symphony core. Hacking the core is not a good idea.

But you might include the functionality directly in a custom event, i.e. without using an event filter.

Hi Michael, That's what I was trying to get at above.

If you create an event in the symphony admin - can you use any of the functionality discussed on the Email API docs directly in the .php file for that event?

So if the event is called myevent - could I just modify event.myevent.php using code form the API docs? Ie just a custom event rather than an event filter?

If so can you give some hints on how that might be done?

If you edit an event: Don't forget to make the allowEditorToParse() function return false! Or simply remove it. Then Symphony won't ever overwrite this file.

It should work according to my example filter code above. Just paste the relevant code into your event:

if(!function_exists('__sendEmailFindFormValue')){
    function __sendEmailFindFormValue($needle, $haystack, $discard_field_name=true, $default=NULL, $collapse=true){

        if(preg_match('/^(fields[[^]]+],?)+$/i', $needle)){
            $parts = preg_split('/,/i', $needle, -1, PREG_SPLIT_NO_EMPTY);
            $parts = array_map('trim', $parts);

            $stack = array();
            foreach($parts as $p){
                $field = str_replace(array('fields[', ']'), '', $p);
                ($discard_field_name ? $stack[] = $haystack[$field] : $stack[$field] = $haystack[$field]);
            }

            if(is_array($stack) && !empty($stack)) return ($collapse ? implode(' ', $stack) : $stack);
            else $needle = NULL;
        }

        $needle = trim($needle);
        if(empty($needle)) return $default;

        return $needle;

    }
}

$fields = $_POST['send-email'];

$fields['recipient'] = __sendEmailFindFormValue($fields['recipient'], $_POST['fields'], true);
$fields['recipient'] = preg_split('/,/i', $fields['recipient'], -1, PREG_SPLIT_NO_EMPTY);
$fields['recipient'] = array_map('trim', $fields['recipient']);

$fields['recipient'] = $this->_Parent->Database->fetch("SELECT `email`, `first_name` FROM `sym_authors` WHERE `username` IN ('".@implode("', '", $fields['recipient'])."') ");

$fields['subject'] = __sendEmailFindFormValue($fields['subject'], $_POST['fields'], true, __('[Symphony] A new entry was created on %s', array($this->_Parent->Configuration->get('sitename', 'general'))));

$fields['body'] = __sendEmailFindFormValue($fields['body'], $_POST['fields'], false, NULL, false);

if(is_array($fields['body'])){
    foreach($fields['body'] as $field_handle => $value){
        $body .= "// $field_handle" . General::CRLF . $value . General::CRLF . General::CRLF;
    }
}

else $body .= $fields['body'];

$to = array();
foreach($fields['recipient'] as $recipient){
    $to[$recipient['email']] = $recipient['first_name'];
}

### Create a message
### ...

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details