class ref name: mass_mail
category-group: email
layer: 11
header file: z_massmail.h synopsis.
The mass mailer class (" massmail_o ") is an object designed to send out a form letter. It requires a lot of configuration and uses 2 input files. The configuration parameters may be supplied either via an INI file or by [repeatedly] calling "config()" member function. It can use a form letter (eg 'template file') with embedded PHP source code. In order to do this, you need to have PHP installed on your machine, with the environment variable 'PHPRC' pointing to PHP's home directory (where php.exe is).
See the PHP file object for more information. You can turn on or off PHP pre-processing, or whether you want to actually send the e-mail (perhaps you are just generating files); you can easily set the MIME type, From: and Reply-To: fields, subject line, and other parameters in an INI file that is supplied to this object prior to invoking run(); or, you can use the config() member function to set these parameters. In addition to setting parameters, you can subclass from the massmail_o class in order to implement pre- and post-processing functions. In a typical window system at the programmatic-API level, you can set "callback" functions after a window event. Likewise, you can set up functions that are invoked:
- preprocess_php() - called before PHP pre-processing occurs.
There is no previous operation, so the error status variables
(my_last_status, my_suberrcode) are always set to 0.
The file supplied to this function is the raw, unchanging template
file.
Since this callback function gets called at the start of the loop, it is always called. It does not depend on the value of the 'PHP' [ini file] parameter.
You can replace the default message printing with your own - do that by providing a line of text in the INI variable "logging/MESSAGE_START=[your text here]". However, this is a kludgy, inferior technique - unless you don't mind printing the same message over and over again. You can turn off printing anything with "logging/PRINT_MSG_START=NO". Or, you can subclass and fill in your own function - in which case, you can do whatever you want. - postprocess_php() - after PHP pre-processing occurs.
The file supplied is that of the output from the PHP CLI (SAPI).
If the 'PHP' [ini file] parameter is not set to YES, this function will not be called. - preprocess_msg() - this function is called before an
e-mail is sent. The input is in the form of a [possibly very large]
string object, not a file. Note that there is almost nothing going on
between postprocess_php() and preprocess_msg(). However,
for sake of completeness (consistency?), this function is included.
Also, between the two functions there is Vettrasoft-custom keyword
replacement processing (controlled as a YES/NO switch in the INI file,
"run/VSKW").
If the 'SEND' [ini file] parameter is not set to YES, this function will not be called. - postprocess_msg() - this is invoked after an e-mail is sent.
A string object is supplied to this function. It contains the final,
actual message text. If the 'SEND' [ini file] parameter is not set to
YES, this function will not be called.
As with preprocess_php(), the default function here prints a message. You can turn this message dump off with "logging/PRINT_MSG_FINISH=NO". Or, you can supply your own [static] message, like so:
logging/MESSAGE_FINISH=[your text here]
And, of course, you can implement your own by subclassing and making your own postprocess_msg(), in which case the message printing would be replaced by whatever you want to do (isn't that what C++ is all about?).
The mass mail class wraps up the entire operation of sending repeated emails into a single object. Everything that it does is encapsulated into the single function run(). Inside this function is a loop which fetches recipients from a file. The loop terminates when the entire file is processed. It can be summarized by this diagram:
- The massmail object opens the INI file and loads the data, thus configuring itself.
- The form letter is opened.
- The recipient list file is opened. Each databag is fetched, one at a time.
- The form letter is copied to a temp file, which is then handed over to the PHP processor.
- the PHP processor generates an output file.
- The output file is opened and read by the massmail object.
- The resultant text (stored inside a string object) is handed over to the Mail Transport Agent, eg, the mail server.
- The MTA forwards the message.
via the INI file:
FROM=gorth.durak@gmail.comvia config():
#include "z_paramstring.h" paramstring_o ps; ps = "FROM=\"gorth.durak@gmail.com\""; massmail_o mmx; mmx.config (ps);config() can also be used to set on/off certain options:
- zFlag_MM_USEINI - use/don't use INI; keyword is "USE_INI". Default if "NO". Note that this option is easily over-ruled, simply by invoking the member function /I>set_ini() with a valid INI file path.
- zFlag_MM_DOSEND - send/don't e-mail. if not sending, this is similar to doing a dry run. It can be used to just generate the form letter output files. Keyword is "DO_SEND". Default is "YES".
- zFlag_MM_USEPHP - use / don't use PHP pre-processing. If turned off, the form letters should not have PHP embedded source code, as any PHP CLI SAPI will not be invoked. Keyword is "USE_PHP". Default value is "NO".
- zFlag_MM_USEEMO - Use / don't use email_address_o (the 'e-mail address object') for sending e-mails. Keyword is "USE_EMO". Default value is YES.
- zFlag_MM_USESENDMAIL - use / don't use sendmail for sending e-mails. This flag is applicable only on unix systems. Also, it is not relevant if zFlag_MM_DOSEND is turned off. Keyword is "USE_SENDMAIL". Default value is "YES".
massmail_o mmx; paramstring_o ps; ps = "DO_SEND=YES USE_PHP=YES"; mmx.config(ps);When setting the "From:" field, use the raw, unmodified e-mail address, without any name prepended. Do not put it in quotes. Keep it simple:
FROM=j.blow@yahoo.comThe following line is WRONG:
FROM=Joe BlowFor setting the "Reply-To:" field, a special syntax is used, that is, a slight modification from the actual string is required. In the INI file, for the "REPLYTO" fields (in the 'letter' group), if using a name and e-mail address, the name part must not be in quotes, and the e-mail address part must be in angle-brackets. Suppose you want the end result (in the actual message) to look like this:# ...Wrong! Error!!
Reply-to: "Gorth Le'Rock"Leave out the quotes. They will be added (in the member function config()). This quirk is necessary, due to the nature of how the INI file object processes an INI file. It pulls in a quote as the value of the keyword, or, if the first non-blank character is not a [single or double] quote, anything up to a comment character ("#") or end-of-line. So the following are ok: FROM=gorth.durak@gmail.com REPLYTO=Gorth Le'Rock
name | values | description |
---|---|---|
database | ||
USE_DB | YES, NO default: YES |
If NO, writing 'event' notes to a database is disabled. |
SERVER | [name-string] | name of the database server (if applicable) |
DATABASE | [name-string] | the database name. |
ACCOUNT | [name-string] | database [user] account name |
PASSWORD | [text-string] | database password for user account. |
files | ||
RECIPIENTS | [file] | full path name of file containing e-mail recipients; by Vettrasoft file convention, the extension is ".bag" |
FORMLETTER | [file] | full path (directory + file name) of template/form file |
ATTACHMENT | [file] | full path (directory + file name) of any file to attach. only 1 file is allowed, in this case. |
INTERIM | [file] | full path (directory + file name) for the temporary output file. You should provide this. |
run | ||
WET, IS_WET | YES, NO default: YES |
Whether or not to do a "wet run". This is almost always 'YES'. Note, you can use either keyword. |
DO_SEND, SEND | YES, NO default: YES |
If set to 'NO', the [generated] form letter will not be e-mailed. |
TARGET | BIZ_ONE | BIZ_ALL | WORKER | ALL_WORKERS | ALL
default: BIZ_ALL |
Since a business can have workers, each with their own
set of e-mails, or multiple e-mails, this dictates which
e-mails are to be sent the letter. The meanings of the
keywords:
BIZ_ONE - send to the first business e-mail (only 1, max). If there is none, zero mails will be sent (irregardless of any employees). BIZ_ALL - send to all the business e-mail addresses. WORKER - send an e-mail message to [at most] the first worker. If there are no workers, or no worker e-mail addresses, none will be sent. ALL_WORKERS - send to all employee e-mail addresses (this can be zero). ALL - send to all e-mail addresses associated with the business. |
PHP, USE_PHP | YES, NO default: NO |
If 'NO', the PHP CLI preprocessor will be skipped (a significant time savings). |
VSKW | YES, NO default: YES |
Whether or not to invoke Vettrasoft keyword (VSKW: "Vettrasoft Key-Word") pre-processing. Set it to NO if you don't want to use this pre-processing step applid to the files. |
EMO, USE_EMO | YES, NO default: YES |
Whether or not to use the email_address_o for sending e-mails. Leave this set to "YES" (not applicable if "SEND=NO") |
SENDMAIL, USE_SENDMAIL | YES, NO default: YES |
[unix only] if YES, "sendmail" will be used to send the mail; otherwise, the "mail" program. |
PAUSE | [n] default: 0 |
"[n]" is simply the number of seconds to wait between iterations (use just a number, ie, "PAUSE=5" |
ABORT_BAGERR | YES, NO default: NO |
Abort run if an error is encountered in the current databag. This is invariably if there is no e-mail address field ("arpa"). |
ABORT_PHPERR | YES, NO default: NO |
Abort the run if an error occurs during PHP processing. This is obviously irrelevant if "PHP=NO". If the PHP SAPI errors out, the program will terminate, instead of just skipping the current databag (eg, recipient). |
ABORT_SENDERR | YES, NO default: YES |
Abort run if there is an error while trying to send the e-mail message. |
BAG_TOPMARKER | [any short text] | this is a sequence of characters, on its own line, that [if set] is used to precede the databag containing a business entry. It is used in conjunction with BAG_BOTMARKER and in opposition to BAG_SEPARATOR (set either a top-bottom pair or the separator string, not both) |
BAG_BOTMARKER | [any short text] | this is a sequence of characters, found on its own line, used to terminate a business entry. It is used in conjunction with BAG_TOPMARKER and in opposition to BAG_SEPARATOR (set either a top-bottom pair or the separator string, not both) |
BAG_SEPARATOR | default: #------o | this is a sequence of characters, found on its own line, that is used to separate databag entries in the source stream. By default, this is set, so to use the parameter pair BAG_TOPMARKER and BAG_BOTMARKER , make sure this parameter is included in your INI file and set this item to an empty string (nothing following the "="). |
logging | ||
VOLUME | [n] default: 0 |
Set the program debugging level to 'n'. This value must be from 0 to 100 (inclusive). See the reference manual page for (quickdirt) rundriver object for details. |
TRACE | YES, NO default: NO |
Set the program debugging level to 'n'. This value must be in 0 to 100 (inclusive). See the reference manual page for (quickdirt) rundriver object for detils. |
LOGSEND | YES, NO default: NO |
log the event to the DB? |
PRINT_MSG_START | YES, NO default: YES |
whether or not to print the default message in preprocess_php(). |
PRINT_MSG_FINISH | YES, NO default: YES |
whether or not to print the default message in postprocess_msg(). |
POPUP_ERRORS | YES, NO default: NO |
If an error occurs, the corresponding message will be put into a pop-up window, instead of printed to the console. The application will block. |
POPUP_EXIT | YES, NO default: NO |
When the program is about to exit, a message will be put into a pop-up window, instead of printed to the console. Thus, you have a very visible notification of the end of a run. The application will block. |
MESSAGE_START | [text] |
If this is set (to a non-empty string), the default text printed in "preprocess_php()" will be replaced by this text. Note that no dynamic information (e-mail address, loop index number) can be printed this way. |
MESSAGE_FINISH | [text] | If this is set (to a non-empty string), the default text printed in "preprocess_msg()" will be replaced by this text. Note that no dynamic information will be printed this way. |
MESSSAGE_EXIT | [text] | If this is set (to a non-empty string), the text will be printed out when the program exits, either to the console (by default), or to a pop-up window (if POPUP_EXIT=YES). |
MSG_INTRO | [text] default: "[[MASSMAIL]] " |
If this is set (to a non-empty string), the text will be printed as the 'starting prompt' upon error or notification messages. This text is intended to be very small (< 20 chars or so). If not set, the default prompt-string is "[[MASSMAIL]]". |
letter | ||
FROM | [email-addr] | enter just a valid [mandatory] e-mail address for the message 'From:' field (no brackets) |
REPLYTO | [text] | use either just an e-mail address, or just a name (not quoted), or an unquoted name followed by an e-mail address. |
SUBJECT | [1-line-text] | This is the e-mail message subject line text. |
EVENT | [text] | |
MIMETYPE | [string] default: "text/plain" |
Enter the text for the MIME type, such as text/html or text/plain (without any quotes). |
DATEFORMAT | [string] default: "%b %d, %Y" |
This is used for setting the format of dates, used by the Vettrasoft custom keyword replacement (VSKW=YES). The default value is given by the macro 'zMM_DEFAULT_DATEFMT'. This may be omitted; it is used only if VSKW=YES. if VSKW=NO. |
mta | ||
MTA_NAME | [string] | the name of the e-mail server to connect to (such as "smtp.gmail.com") |
MTA_PORT | [number] default: 25 |
The server port number to use for connecting to the e-mail server ("Mail Transport Agent"). The macro label for the default value is 'zMM_DEFAULT_SENDPORT'. |
MTA_ENCRYPTION | [keyword] default: NONE |
should be one of: NONE, BASIC, SSL. If omitted, defaults to "NONE". |
MTA_ACCOUNT | [string] | The log-in account string for the e-mail server. |
MTA_PASSWORD | [string] | The log-in password for the e-mail server. |
A note about "VSKW" mode:If you set the INI parameter 'run/VSWK' (a legacy search-replace thing), you can apply transformations like so:
$::date $::who $arpa
$::build_salutation
This is a message from George Bush. Just because I am not officially the president of America doesn't mean I can't control you. I need to know everything about you, including how often you have sex, with who, and what sex the person(s) is/are. If you fail to comply, the power of the American federal government will fall on your disobiedent ass, and you will spend the rest of your life in one of our Supermax prisons. Sincerely, G. Bush (top dictator) punkhol@ex-prs.whitehouse.gov
Thus, given a databag such as this:
# :start-databag: target ( who ( worker ( name ( first Michael last Brown ) title victim ) ) phone <"+1 (314) 522-3100" > email "mbrown@deadguys-butwhy.org" ) # :end-databag:
Can generate output such as this:
Jan 18, 2016 Michael Brown mbrown@deadguys-butwhy.orgmember functions (primary)
Dear Mr. Brown:
This is a message from George Bush. Just because I am not officially the president of America doesn't mean I can't control you. ... Sincerely, G. Bush (top dictator) punkhol@ex-prs.whitehouse.gov
massmail_o()usage.
SIGNATURE: massmail_o ()
SYNOPSIS: creates a a new, 'empty' massmail object. All of its settings are at default values after this construction.
destructor
SIGNATURE: ~massmail_o ()
SYNOPSIS: virtual destructor. The massmail object instance is reset.
config()
SIGNATURE: int config (paramstring_o &ps, int *pi = NULL)
SYNOPSIS:
This member function is the workhorse of configuring a massmail object prior to calling run(). Any of the parameters specified in the main table above can be passed to this function (via input variable "ps"). Multiple name-value pairs can be used, separated by a space. Values with embedded punctuation or whitespace must be quote-wrapped (precede a double-quote by a back-slash {standard c programming}).
Example:
massmail_o mm; mm.config("FORMLETTER=\"readme.txt\" RECIPIENTS=\"targets.bag\"); mm.config("MIMETYPE=\"text/plain\" PHP=NO"); mm.run();This code sliver is not sufficient to actually work. The massmail object requires many parameters to be preconfigured in order to be able to run successfully. As can be seen from the example, config() can be called repeatedly, with a variable number of key-value pairs embedded in the 'ps' parameter.
PARAMETERSpi: [optional] error indicator variable. Its values: set_volume()
0: all ok
1: unknown keyword encountered
2: YES | NO string expected, not found
3: other flag value issue
4: unknown (eg, illegal) encryption type given
SIGNATURE: int set_volume (int x)
SYNOPSIS:
sets the debugging/tracing output volume level. The value of 'x' must be in the range [0..100], inclusive. The volume levels embedded in this object include:
10: error messages printed (symbolic constant 'zMM_Volume_FatalErr');
20: "followup" (post-event) error messages printed (symbolic constant 'zMM_Intolerable_Volume ');
30: default messages in "preprocess_php()" emitted; custom messages in "postprocess_msg()" printed;
35: successful send messages in "postprocess_msg()" emitted;
45: post-send "trace" message printed ('zMM_Volume_BasicMsg')
RETURNS:
0: volume successfully set.
-1: volume not set - inputtd value was out of range.
set_ini()
SIGNATURE: int set_ini (const string_o &spath, int *pi = NULL)
SYNOPSIS:
sets the file name (and path, if one is provided in 'spath') of the INI file. Using this function is optional, and should be used if the object's configuration is to be specified via an INI file. This is "optional" because you can use config() to also configure the object. This routine passes the variable 'spath' to a file object, which then verifies if the file exists. If it is not found, or cannot be accessed, this is not considered an error, but the output error flag will be set to indicate this fact.
If this routine succeeds, the myflags bit 'zFlag_MM_USE_INI' will be set, which will allow load_ini() to proceed.
PARAMETERSpi: [optional] error indicator variable. Its values: RETURNS: 0
0: all ok, file set
1: INI file not found (warning only)
2: INI file name was previously set (warning only)
load_ini()
SIGNATURE: int load_ini (int *pi)
SYNOPSIS:
this member function will load the contents of an INI file. The object will be configured according to the parameters found in the file. This routine can be used in conjunction with config(). The order does not matter. Successive calls to load_ini() will over-write any previously set values. Any parameters omitted from the INI file can be set via config().
This function can be called explicitly, or run() will call it automatically, if an INI file was specified (via set_init()). If called earlier, and "run()" has not been done, this is considered a warning, and the output error variable ('pi') will be set - there is no normallly good reason to call "load_ini()" more than once.
PARAMETERSpi: [optional] error indicator variable. Its values: RETURNS:
0: all ok
1: ini file is not to be used! ('use_ini' is FALSE)
2: ini file load failure; probably bad syntax in the file
3: "load_ini()" called earlier [warning only]
4: 'i' out of bounds (1st loop). should never happen.. unless 'i' value increased and out of sync with # of elements in the ini file.
5: 'i' out of bounds (2nd loop). same reason as *pie = 4. This can never actually happen, because the same error is handled where output value '4' is set.
6: YES | NO string expected, not found
7: [PANIC] "map2_idx_str()" internal error (should not happen)
8: [PANIC] "config()" call failed
0: INI file successfully loaded.
-1: INI file not loaded (See 'pi' for reasons why)
attach_file()
SIGNATURE: int attach_file (const file_o &f, int *pi = NULL)
SYNOPSIS:
This adds an attachment to the e-mail message to send. This function can be called repeatedly to attach more than 1 file. NOte that when using the INI file, only 1 file can be attached.
RETURNS: 0
volume()
SIGNATURE: int volume () const
SYNOPSIS: returns the value of the volume set by set_volume().
RETURNS: 0
TRAITS: this member function is inlined.
reset()
SIGNATURE: int reset()
SYNOPSIS:
resets the massmail object to its default, at-construction-state [eg, default] values. See the main table on this page for a list of the massmail parameter default values.
RETURNS: 0
run()
SIGNATURE: int run (int *pi)
SYNOPSIS:
processes a list of recipients to send each an e-mail. This member function is the only funtion that "does work". See the main description section on this page for more information about what this object does.
This function invokes "pre_check()" to make sure things are in order for doing a run: recipient list file and form letter file must exist; and if using PHP, the directory for the output file from the PHP CLI must exist.
PARAMETERSpi: [mandatory] error indicator variable. Its values: RETURNS:
0: all ok
1: no recipient list (file). This value is set in "pre_check()".
2: no [input] form letter (file) was specified or found. This value is set in "pre_check()".
3: directory for the intermediate [post-PHP] file doesn't exist {from pre_check()}.
4: temporary (work) file name was not set - this should have been auto-generated, if not explicitly set {from pre_check()}.
5: INI file could not be opened (bad path?)
zErr_Resource_Unavail: database could not be opened.
0: recipient list successfully processed.
-1: an error occurred during the run. see 'pi' for info why.
preprocess_php()
SIGNATURE: int preprocess_php (const file_o &f, rec_dbag_o &bag)
SYNOPSIS:
This function is one of a series of 4 virtual functions allowing you the option of overriding the default behavior (which in some cases is nothing, and other cases a message is printed). In order to implement your own reinterpretation of this function, a subclass must be created. Typically this subclass is a minimal class with the only these virtual functions explictly defined.
This function provides a "hook" where the application can do something prior to a file being submitted to PHP for processing. It is always called (whether the default version or your own). See the main description section for more information on this function and the other three associated virtual functions.
The default action of this function specifically is to print 'GOT ANOTHER RECIPIENT (# [n] - "[email-address]"', where '[n]' is the count number and '[email-address]' is the current recipient e-mail address. You can shut off or change printing this message in many ways:
- set the "logging/PRINT_MSG_START" value in the INI file to NO
- call config() with the "PRINT_MSG_START" value set to NO
- set the INI value "logging/MESSAGE_START" to some text, eg, any non-blank characters.
- use config() with the paramstring_o value "MESSAGE_START", providing some text, eg:
massmail_o x; x.config("MESSAGE_START=\"print this!\"");"- set the volume to 36 or higher
PARAMETERSRETURNS: 0
- f: the file object for the template file.
- bag: the [recursive] databag containing the data from the recipient list file. The contents of 'bag' is complete dataset for the current recipient being processed.
postprocess_php()
SIGNATURE: int postprocess_php (const file_o &f, rec_dbag_o &bag)
SYNOPSIS:
This function is one of a series of 4 virtual functions allowing you the option of overriding the default behavior. In order to implement your own function, a subclass must be created. Typically this subclass is a minimal class with the only these virtual functions explictly defined.
This function provides a "hook" where the application can do something after a file has been being submitted to PHP for processing. It differs from preprocess_php() in that it is provided a file object with the contents of the form letter after PHP processing. If PHP processing is turned off, the file object points to the original template file. However, if off, this function will not be called . See the main description section for more information on this function and the other three associated virtual functions.
The default action of this function specifically is nothing. That is, this function does absolutely nothing; it simply returns 0. Furthermore, it is not even called unless PHP (or USE_PHP) is set to YES. The default value of PHP is NO. The file should not be modified, else serious damage can result.
PARAMETERSRETURNS: 0
- f: the file object for the template file.
- bag: the [recursive] databag containing the data from the recipient list file. The contents of 'bag' is complete dataset for the current recipient being processed.
preprocess_msg()
SIGNATURE: int preprocess_msg (const string_o &msg, rec_dbag_o &bag)
SYNOPSIS:
This function is one of a series of 4 virtual functions, thus allowing you the option of overriding its default behavior. This function provides a "hook" where the application can do something prior to a message being sent. It is called only if the SEND parameter is set to YES (this is so by default). The default action of this function specifically is nothing. That is, this function does absolutely nothing; it simply returns 0.
PARAMETERSRETURNS: 0
- msg: a string object containing the text to be sent via e-mail.
- bag: the [recursive] databag containing the data from the recipient list file. The contents of 'bag' is the complete dataset for the current recipient being processed.
postprocess_msg()
SIGNATURE: int postprocess_msg (const string_o &msg, rec_dbag_o &bag)
SYNOPSIS:
This function is one of a series of 4 virtual functions that provide the application a "hook" where the application can do something after to an e-mail has been sent. This is done just prior to the end of the procssing cycle for the current recipient. It is always called.
The default action of this specific function is to print a line to the console [stdout] like: '"[addr]" - letter sent.' where [addr] is the current e-mail address. This is done if the send was successful. If the send failed, a message like this one is printed to stdout:[addr]; last error message: "[error text]"'[error text]' is provided by the OS mail transport system. In the default function case (no subclassing done), there are many ways to turn off or modify console message printing. See the entry for preprocess_php() for a list of alternatives. It can be shut off by setting the parameter 'PRINT_MSG_FINISH' to 'NO'. You can change the message text to your own by setting the parameter MESSAGE_FINISH.
PARAMETERSRETURNS: 0
- msg: a string object containing the text what as sent via e-mail.
- bag: the [recursive] databag containing the data from the recipient list file. The contents of 'bag' is a complete dataset for the current recipient being processed.
curr_count()
SIGNATURE: count_t curr_count ()
SYNOPSIS: returns the index value of the current recipient. The first recipient has value 0.
TRAITS: this member function is inlined.
The steps required to send e-mail using this object, in the simplest case, breaks down into these steps:
- set up the INI file that the object will read.
- write a form letter.
- set up the list of recipients.
- write a program using the object.
- run the program.
This can be as simple as writing a letter. However, it can be very complex because you can write a document written with embedded PHP, or even entirely in PHP. A PHP-based document allows you to tailor the final text to the person, the business, or just about any set of parameters applicable to the letter. The massmail_o instance provides a mechanism for pushing the data of the business to the letter. How this is done is detailed in the PHP file object . You should get familiar with its operation in order to take advantage of the PHP processing behaviour. For those of you in a hurry, a [very minimal] Quick-Start boilerplate example is presented here: The variables from the simple databag items inside a recursive databag are forwarded to the PHP processor. The databag comes from the current business entry being processed. Only simple items (no arrays, lists, or sub-databags) are translated into the PHP file. For a business, this includes the business name (databag path: full_name); and other fields such as id, what, note, or found. Not only top-level simple items are processed: all simple databags in the entire recursive databag. Thus given this business, in databag format:
In addition to the top-level, simple items id and full_name, the worker's first and last name, and title are simple databag items, so they too are forwarded to the PHP file. Normally, a databag item such as last name is accessed by a space-separated path like so:# :start-databag: target ( id 18900309 full_name Brainbench who ( worker ( name ( first Vyacheslav last Molotov ) title lapdog ) ) phone <"+1 (703) 674-3500" "+1 (703) 674-3332"> ) # :end-databag:
To make variable processing a little cleaner inside a PHP environment, these spaces are converted to dashes ('-'):string_o lnam = bag.get("who worker name last"); // returns Molotov
Expanding on this, you should be able to drop the following code into a text file (it can end in .txt or .php - whatever you prefer):$lnam = $_SERVER['who-worker-name-last'];
[3] setting up the recipient list.<?PHP $biz_name = $_SERVER['full_name']; $fname = $_SERVER['who-worker-name-first']; $lname = $_SERVER['who-worker-name-last']; $sex = $_SERVER['who-worker-sex']; if ($fname != '' && $lname != '') { echo ("Attn: $fname $lname\n"); if ($sex == 'F') echo ("Dear Ms. $lname,\n"); else echo ("Dear Mr. $lname,\n"); echo ("Are you still working at \"$biz_name\"?\n"); } ?> The rest of the text is static, and will be mailed as "luggage" in the body of the letter. You can still of course, embed more PHP code <?PHP echo ("like so.\n"); ?>
You can manually edit this file by hand or have a program generate it. For the latter, you can use the business textstream class to convert a text file with standard keyword-oriented business listings to the [simplified] databag format required by this object. Here is a boilerplate example of a typical listing in a file, in the required databag format:
Some notes about the formatting rules:# :start-databag: target ( id 101175 full_name Brainbench who ( worker ( name ( first Vyacheslav last Molotov ) sex M title "CEO" ) ) phone <"+1 (703) 674-3500" "+1 (703) 674-3332"> email <"support@brainbench.com" "marketing@brainbench.com"> url <"http://www.brainbench.com"> found "10/23/2013 08:05:37" ) # :end-databag:
- By default, each business entry's databag must be preceded with "# :start-databag:" (without the double-quotes, on its own line) and followed by "# :end-databag:" (also on a unique line). . The lines separating
- the [top-level] name of the databag ("target", in this example) is irrelevant. You can call it whatever you want (but it must have a name).
- The "id" field is not used. This is an unused extra datum, generated by the business textstream object.
- The databag name "full_name" is the first item checked in order to obtain the name of the business (/organization). If not present, the object searches for "cased_name", then "short_name". The first non-blank field found is used for naming the organization.
- The "who" [recursive databag] list can contain multiple "worker" sub-databags. Each entry represents a worker in the organization.
- Data fields such as phone, url, or found are not used by this class.
- Data fields such as phone, email, and url are repeatable fields: there can be 0, 1, or more occurances within the angle brackets (which represent an array databag). Since the text representation of each of the aforementioned items contains non-alphanumeric characters (e-mails contain at least a '@' character; phone numbers usually contain '+', '-', or '(' and ')'), the values must be wrapped in double-quotes.
- In order to send an e-mail to the recipient, obviously at least 1 e-mail address is required.
Given such a setup, open a cmd ("console") window and run it:#include "z_inifile.h" inifile_o ini; int cmdline (const int argc, const char **argv) { int i; string_o s; for (i=1; i < argc; i++) { s = argv[i]; if (s == "-ini") ini.set_name(argv[++i]); } return 0; }
warnings.massmailer -ini mail.ini
Be very careful about quoting text in the INI file. In the future, given a "key-value" pair (syntax: KEY=VALUE), you will be able to append comments by starting text with a '#' (sharp character) in the 'value part, like so:
MESSAGE_START=TO BE, OR NOT TO BE? # this is a commentHowever, this will not work:
MESSAGE_START="TO BE, OR NOT TO BE?" # this is a commentThat is becuase the INI processor wraps the 'value' part in double-quotes. Internally, when getting the value in the last case (above), it will see this line: ""TO BE, OR NOT TO BE?" # this is a comment" It will get the quoted string - which is the stuff in between the first pair of double-quotes that it encounters, which is an empty string - and the remainder of the line will be discarded. However, as of this writing (July 2012), appending comments in this way IS NOT IMPLEMENTED (this entire warning section has been written as a footnote for a future implementation). limitations.
As of this writing, there are some hard-coded protocols you need to know:
The format of the recipient list has some rather specific rules. It must be in regular text format, and consist of a list of businesses (or other organizations). By default, each biz-org entry starts with this line:
and ends with this line:# :start-databag:
You can change the lines of text that act as delimiters for the databags by using the INI parameters (under [run]) BAG_TOPMARKER, BAG_BOTMARKER, and BAG_SEPARATOR. You can use either a separator, or a top and bottom marker pair. For the latter, the databag must be preceded with a top-marker and followed by the bottom marker. Also, the INI parameter BAG_SEPARATOR must be explicitly set to an empty string. For example, if you have these parameters in your INI file:# :end-databag:
The recipient list file should contain entries like so:BAG_TOPMARKER = ////---o BAG_BOTMARKER = \\\\---o BAG_SEPARATOR =
If, instead the databag separator mode is used, you use a single-line item to separate databags. Given this INI parameter set:////---o target ( id 100 full_name "Acme Cement Company" ) \\\\---o ////---o target ( id 101 full_name "Another Business Entity" ) ////---o
The recipient list file can look like so:BAG_TOPMARKER = BAG_BOTMARKER = BAG_SEPARATOR = [((((NEXT-DATABAG))))]
target ( id 100 full_name "Acme Cement Company" ) [((((NEXT-DATABAG))))] (...this is the 3rd entry) target ( id 101 full_name "Another Business Entity" ) [((((NEXT-DATABAG))))] target ( id 102 full_name "Etc #3" who (name (first John last Doe )) )
Some usage rules for these markers:
- to use upper- and lower- delimiter pairs, include BAG_SEPARATOR in the INI file, and set it to nothing, ie, "BAG_SEPARATOR =". When this parameter is an empty string, massmail_o will turn to the other delimiters. By default this is set to "#------o" (without the double-quotes). It is an error to have all 3 parameters set. However, if BAG_SEPARATOR is set (to anything non-empty), the other two are ignored.
- Each marker parameter is expected to be on its own line, and start the line. That is, the marker text should be the only thing on the line (a newline is allowed). However, extraneous text is permitted to follow the marker text (such as can be seen in the 3rd entry in the above example, " (...this is the 3rd entry)").
- For separators, the lines should be in between the databags. For upper-lower pairs, they should envelop each databag. Thus in the latter case the first line should be the top marker and the last line in the file should be a bottom marker.
zdb_set_access_method(zstyle_DBax_ODBC);
This should be configurable in the near future. Various console messages for emitted for warnings, errors, and checkpoints. These are done at volume levels given by the macro values zMM_Intolerable_Volume, zMM_Volume_FatalErr, and zMM_Volume_BasicMsg. In later versions, these should be under programmatic control in future releases.