FINAL suepr merge step : added all modules to this super repos
This commit is contained in:
339
sites/all/modules/contrib/mail/mandrill/LICENSE.txt
Normal file
339
sites/all/modules/contrib/mail/mandrill/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
129
sites/all/modules/contrib/mail/mandrill/README.txt
Normal file
129
sites/all/modules/contrib/mail/mandrill/README.txt
Normal file
@@ -0,0 +1,129 @@
|
||||
## SUMMARY
|
||||
|
||||
Integrates Drupal's mail system with Mandrill transactional emails, a service
|
||||
by the folks behind MailChimp. Learn more about Mandrill and how to sign up on
|
||||
[their website](http://mandrill.com). (Or don't, but then this module isn't
|
||||
terribly useful...)
|
||||
|
||||
## INSTALLATION NOTES
|
||||
|
||||
* If you previously installed version 1.3, you will get the following error
|
||||
message when enabling the mandrill_template module:
|
||||
|
||||
DatabaseSchemaObjectExistsException:
|
||||
Table <em class="placeholder">mandrill_template_map</em> already exists.
|
||||
|
||||
This is ugly but irrelevant, everything should function normally.
|
||||
|
||||
* If you are upgrading from one of many previous versions, You may also find
|
||||
an extra Mail System class in the Mail System configuration called "Mandrill
|
||||
module class". It's harmless, but feel free to delete it.
|
||||
|
||||
## CONFIGURATION
|
||||
|
||||
### Set Mandrill API Key
|
||||
Start by loading up the Mandrill admin page at Configuration -> Web
|
||||
Services (or admin/config/services/mandrill) and adding your API key from
|
||||
http://mandrillapp.com. Then you'll see more configuration options.
|
||||
|
||||
### Email Options
|
||||
* **From address:** The email address that emails should be sent from
|
||||
* **From name:** The name to use for sending (optional)
|
||||
* **Subaccount:** This selection box appears if you have configured subaccounts
|
||||
on your Mandrill account, and can be used to select the outgoing subaccount to
|
||||
use for Mandrill sending.
|
||||
* **_Input format_:** An optional input format to apply to the message body
|
||||
before sending emails
|
||||
|
||||
### Send Options
|
||||
* **Track opens:** Toggles open tracking for messages
|
||||
* **Track clicks:** Toggles click tracking for messages
|
||||
* **Strip query string:** Strips the query string from URLs when aggregating
|
||||
tracked URL data
|
||||
* **Log sends that are not registered in mailsystem:** Useful for configuring
|
||||
Mail System and getting more granular control over emails coming from various
|
||||
modules. Enable this and set the system default in Mail System to Mandrill,
|
||||
then trigger emails from various modules and functions on your site. You'll
|
||||
see Mandrill writing log messages identifying the modules and keys that are
|
||||
triggering each email. Now you can add these keys in Mail System and control
|
||||
each email-generating module/key pair specifically. WARNING: If you leave this
|
||||
enabled, you may slow your site significantly and clog your log files. Enable
|
||||
only during configuration.
|
||||
|
||||
### Google Analytics
|
||||
* **Domains:** One or more domains for which any matching URLs will
|
||||
automatically have Google Analytics parameters appended to their query string.
|
||||
Separate each domain with a comma.
|
||||
* **Campaign:** The value to set for the utm_campaign tracking parameter. If
|
||||
empty, the from address of the message will be used instead.
|
||||
|
||||
### Asynchronous Options
|
||||
* **Queue Outgoing Messages** Drops all messages sent through Mandrill into a
|
||||
queue without sending them. When Cron is triggered, a number of queued messages
|
||||
are sent equal to the specified Batch Size.
|
||||
* **Batch Size** The number of messages to send when Cron triggers. Must be
|
||||
greater than 0.
|
||||
|
||||
### SEND TEST EMAIL
|
||||
|
||||
The Send Test Email function is pretty self-explanatory. The To: field will
|
||||
accept multiple addresses formatted in any Drupal mail system approved way.
|
||||
By configuring the Mandrill Test module/key pair in Mail System, you can
|
||||
use this tool to test outgoing mail for any installed mailer.
|
||||
|
||||
### Update Mail System settings
|
||||
Mandrill Mail interface is enabled by using the
|
||||
[Mail System module](http://drupal.org/project/mailsystem). Go to the
|
||||
[Mail System configuration page](admin/config/system/mailsystem) to start
|
||||
sending emails through Mandrill. Once you do this, you'll see a list of the
|
||||
module keys that are using Mandrill listed near the top of the Mandrill
|
||||
settings page.
|
||||
|
||||
Once you set the site-wide default (and any other module classes that may be
|
||||
listed) to MandrillMailSystem, your site will immediately start using Mandrill
|
||||
to deliver all outgoing email.
|
||||
|
||||
### Module/key pairs
|
||||
The key is optional: not every module or email uses a key. That is why on the
|
||||
mail system settings page, you may see some modules listed without keys. For
|
||||
more details about this, see the help text on the mail system configuration
|
||||
page.
|
||||
|
||||
# Sub-modules
|
||||
|
||||
## Templates
|
||||
|
||||
In order to use the mandrill_template module, start by creating some templates
|
||||
in your Mandrill account. Once you do, you can add one or more Mandrill
|
||||
Template Maps for that template, specifying where in the template to place
|
||||
the email content and which module/key pair should be sent using the template.
|
||||
If you want to send multiple module/key pairs through the same Template, you
|
||||
can make Mandrill the default mail system and make that Template Map the
|
||||
default template, or you can clone the Template Map for each module/key pair
|
||||
and assign them individually.
|
||||
|
||||
You should also consider enabling the css-inline feature in your Mandrill
|
||||
account under Settings -> Sending Options. For more info, see
|
||||
"http://help.mandrill.com/entries/24460141-Does-Mandrill-inline-CSS-automatically-".
|
||||
|
||||
## Reports
|
||||
The mandrill_reports sub-module provides reports on various metrics. It may
|
||||
take a long time to load. This module is due for some attention.
|
||||
|
||||
### Dashboard
|
||||
Displays charts that show volume and engagement, along with a tabular list of
|
||||
URL interactions for the past 30 days.
|
||||
|
||||
### Account Summary
|
||||
Shows account information, quotas, and all-time usage stats.
|
||||
|
||||
## Activity
|
||||
The Mandrill Activity sub-modules allows users to view email activity for any
|
||||
Drupal entity with a valid email address. Configuration and usage details are in
|
||||
sub-module's README file.
|
||||
|
||||
## Advanced Options
|
||||
If you would like to use additional template (or other) Mandrill API
|
||||
variables not implemented in this module, set them in hook_mail_alter under:
|
||||
$params['mandrill']. Have a look at mandrill.mail.inc to learn more.
|
||||
(Search for "mandrill parameters".)
|
517
sites/all/modules/contrib/mail/mandrill/lib/mandrill.inc
Normal file
517
sites/all/modules/contrib/mail/mandrill/lib/mandrill.inc
Normal file
@@ -0,0 +1,517 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Wrapper class around the Mandrill API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class MandrillException.
|
||||
*/
|
||||
class MandrillException extends Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Class DrupalMandrill.
|
||||
*/
|
||||
class DrupalMandrill {
|
||||
const API_VERSION = '1.0';
|
||||
const END_POINT = 'https://mandrillapp.com/api/';
|
||||
|
||||
protected $api;
|
||||
|
||||
/**
|
||||
* Default to a 300 second timeout on server calls
|
||||
*/
|
||||
protected $timeout = 300;
|
||||
|
||||
/**
|
||||
* Constructor to set internal values.
|
||||
*
|
||||
* @param string $api_key
|
||||
* Mandrill API key.
|
||||
* @param int $timeout
|
||||
* Server timeout.
|
||||
*
|
||||
* @throws MandrillException.
|
||||
*/
|
||||
public function __construct($api_key, $timeout = 300) {
|
||||
if (empty($api_key)) {
|
||||
throw new MandrillException('Invalid API key');
|
||||
}
|
||||
try {
|
||||
$response = $this->request('users/ping', array('key' => $api_key));
|
||||
if ($response != 'PONG!') {
|
||||
throw new MandrillException('Invalid API key: ' . $response);
|
||||
}
|
||||
|
||||
$this->api = $api_key;
|
||||
$this->timeout = $timeout;
|
||||
|
||||
}
|
||||
catch (Exception $e) {
|
||||
throw new MandrillException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a request to Mandrill's API.
|
||||
*
|
||||
* Every API call uses this function to actually make the request to
|
||||
* Mandrill's servers.
|
||||
*
|
||||
* @link https://mandrillapp.com/api/docs/
|
||||
*
|
||||
* @param string $method
|
||||
* API method name
|
||||
* @param array $args
|
||||
* query arguments
|
||||
* @param string $http
|
||||
* GET or POST request type
|
||||
* @param string $output
|
||||
* API response format (json,php,xml,yaml). json and xml are decoded into
|
||||
* arrays automatically.
|
||||
*
|
||||
* @return array
|
||||
* Array on success.
|
||||
*
|
||||
* @throws MandrillException.
|
||||
*/
|
||||
protected function request($method, $args = array(), $http = 'POST', $output = 'json') {
|
||||
if (!isset($args['key'])) {
|
||||
$args['key'] = $this->api;
|
||||
}
|
||||
|
||||
$api_version = self::API_VERSION;
|
||||
$dot_output = ('json' == $output) ? '' : ".{$output}";
|
||||
|
||||
$url = self::END_POINT . "{$api_version}/{$method}{$dot_output}";
|
||||
$params = drupal_json_encode($args);
|
||||
|
||||
switch ($http) {
|
||||
case 'GET':
|
||||
$url .= '?' . $params;
|
||||
$response = drupal_http_request($url, array(
|
||||
'method' => 'GET',
|
||||
'timeout' => $this->timeout,
|
||||
));
|
||||
break;
|
||||
|
||||
case 'POST':
|
||||
$response = drupal_http_request($url, array(
|
||||
'method' => 'POST',
|
||||
'data' => $params,
|
||||
'timeout' => $this->timeout,
|
||||
));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new MandrillException('Unknown request type');
|
||||
}
|
||||
|
||||
$response_code = $response->code;
|
||||
if (0 == $response_code) {
|
||||
return $response->error;
|
||||
}
|
||||
$body = $response->data;
|
||||
|
||||
switch ($output) {
|
||||
case 'json':
|
||||
$body = json_decode($body, TRUE);
|
||||
break;
|
||||
|
||||
case 'php':
|
||||
$body = unserialize($body);
|
||||
break;
|
||||
}
|
||||
|
||||
if (200 == $response_code) {
|
||||
return $body;
|
||||
}
|
||||
else {
|
||||
$message = isset($body['message']) ? $body['message'] : $body;
|
||||
if (is_array($message)) {
|
||||
$message = "Unspecified Error";
|
||||
}
|
||||
throw new MandrillException($message, $response_code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/users.html#method=ping
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function users_ping() {
|
||||
return $this->request('users/ping');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/users.html#method=info
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function users_info() {
|
||||
return $this->request('users/info');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/users.html#method=senders
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function users_senders() {
|
||||
return $this->request('users/senders');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/senders.html#method=domains
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function senders_domains() {
|
||||
return $this->request('senders/domains');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/senders.html#method=list
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function senders_list() {
|
||||
return $this->request('senders/list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/senders.html#method=info
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function senders_info($email) {
|
||||
return $this->request('senders/info', array('address' => $email));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/senders.html#method=time-series
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function senders_time_series($email) {
|
||||
return $this->request('senders/time-series', array('address' => $email));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/subaccounts.html#method=method-list
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function subaccounts() {
|
||||
return $this->request('subaccounts/list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/tags.html#method=list
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function tags_list() {
|
||||
return $this->request('tags/list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/tags.html#method=info
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function tags_info($tag) {
|
||||
return $this->request('tags/info', array('tag' => $tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/tags.html#method=time-series
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function tags_time_series($tag) {
|
||||
return $this->request('tags/time-series', array('tag' => $tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/tags.html#method=all-time-series
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function tags_all_time_series() {
|
||||
return $this->request('tags/all-time-series');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/templates.html#method=add
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function templates_add($name, $code) {
|
||||
return $this->request('templates/add', array(
|
||||
'name' => $name,
|
||||
'code' => $code,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/templates.html#method=update
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function templates_update($name, $code) {
|
||||
return $this->request('templates/update', array(
|
||||
'name' => $name,
|
||||
'code' => $code,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/templates.html#method=delete
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function templates_delete($name) {
|
||||
return $this->request('templates/delete', array('name' => $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/templates.html#method=info
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function templates_info($name) {
|
||||
return $this->request('templates/info', array('name' => $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/templates.html#method=list
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function templates_list() {
|
||||
return $this->request('templates/list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/templates.html#method=time-series
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function templates_time_series($name) {
|
||||
return $this->request('templates/time-series', array('name' => $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/urls.html#method=list
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function urls_list() {
|
||||
return $this->request('urls/list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/urls.html#method=time-series
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function urls_time_series($url) {
|
||||
return $this->request('urls/time-series', array('url' => $url));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/urls.html#method=search
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function urls_search($q) {
|
||||
return $this->request('urls/search', array('q' => $q));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/webhooks.html#method=add
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function webhooks_add($url, $events) {
|
||||
return $this->request('webhooks/add', array(
|
||||
'url' => $url,
|
||||
'events' => $events,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/webhooks.html#method=update
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function webhooks_update($id, $url, $events) {
|
||||
return $this->request('webhooks/update', array(
|
||||
'id' => $id,
|
||||
'url' => $url,
|
||||
'events' => $events,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/webhooks.html#method=delete
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function webhooks_delete($id) {
|
||||
return $this->request('webhooks/delete', array('id' => $id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/webhooks.html#method=info
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function webhooks_info($id) {
|
||||
return $this->request('webhooks/info', array('id' => $id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/webhooks.html#method=list
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function webhooks_list() {
|
||||
return $this->request('webhooks/list');
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/messages.html#method=search
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function messages_search($query, $date_from = '', $date_to = '', $tags = array(), $senders = array(), $limit = 100) {
|
||||
return $this->request('messages/search', compact('query', 'date_from', 'date_to', 'tags', 'senders', 'limit'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/messages.html#method=send
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function messages_send($message) {
|
||||
return $this->request('messages/send', array('message' => $message));
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://mandrillapp.com/api/docs/messages.html#method=send-template
|
||||
*
|
||||
* @return array|MandrillException
|
||||
*/
|
||||
public function messages_send_template($template_name, $template_content, $message) {
|
||||
return $this->request('messages/send-template', compact('template_name', 'template_content', 'message'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array structure for a message attachment.
|
||||
*
|
||||
* @param string $path
|
||||
* Attachment path.
|
||||
*
|
||||
* @return array
|
||||
* Attachment structure.
|
||||
*
|
||||
* @throws MandrillException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getAttachmentStruct($path) {
|
||||
$struct = array();
|
||||
|
||||
try {
|
||||
|
||||
if (!@is_file($path)) {
|
||||
throw new Exception($path . ' is not a valid file.');
|
||||
}
|
||||
|
||||
$filename = basename($path);
|
||||
|
||||
if (!function_exists('get_magic_quotes')) {
|
||||
function get_magic_quotes() {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (!function_exists('set_magic_quotes')) {
|
||||
function set_magic_quotes($value) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (strnatcmp(phpversion(), '6') >= 0) {
|
||||
$magic_quotes = get_magic_quotes_runtime();
|
||||
set_magic_quotes_runtime(0);
|
||||
}
|
||||
|
||||
$file_buffer = file_get_contents($path);
|
||||
$file_buffer = chunk_split(base64_encode($file_buffer), 76, "\n");
|
||||
|
||||
if (strnatcmp(phpversion(), '6') >= 0) {
|
||||
set_magic_quotes_runtime($magic_quotes);
|
||||
}
|
||||
|
||||
$mime_type = file_get_mimetype($path);
|
||||
if (!DrupalMandrill::isValidContentType($mime_type)) {
|
||||
throw new Exception($mime_type . ' is not a valid content type (it should be ' . implode('*,', self::getValidContentTypes()) . ').');
|
||||
}
|
||||
|
||||
$struct['type'] = $mime_type;
|
||||
$struct['name'] = $filename;
|
||||
$struct['content'] = $file_buffer;
|
||||
|
||||
}
|
||||
catch (Exception $e) {
|
||||
throw new MandrillException('Error creating the attachment structure: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return $struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to determine attachment is valid.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $ct
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function isValidContentType($ct) {
|
||||
$valids = self::getValidContentTypes();
|
||||
|
||||
foreach ($valids as $vct) {
|
||||
if (strpos($ct, $vct) !== FALSE) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of valid content types.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @return array
|
||||
* Valid content types to attach to an email.
|
||||
*/
|
||||
protected static function getValidContentTypes() {
|
||||
$valid_types = array(
|
||||
'image/',
|
||||
'text/',
|
||||
'application/pdf',
|
||||
'application/x-zip',
|
||||
);
|
||||
drupal_alter('mandrill_valid_attachment_types', $valid_types);
|
||||
return $valid_types;
|
||||
}
|
||||
}
|
||||
|
184
sites/all/modules/contrib/mail/mandrill/lib/mandrill.mail.inc
Normal file
184
sites/all/modules/contrib/mail/mandrill/lib/mandrill.mail.inc
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Implements Mandrill as a Drupal MailSystemInterface
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modify the drupal mail system to use Mandrill when sending emails.
|
||||
*/
|
||||
class MandrillMailSystem implements MailSystemInterface {
|
||||
|
||||
/**
|
||||
* Concatenate and wrap the email body for either plain-text or HTML emails.
|
||||
*
|
||||
* @param array $message
|
||||
* A message array, as described in hook_mail_alter().
|
||||
*
|
||||
* @return array
|
||||
* The formatted $message.
|
||||
*/
|
||||
public function format(array $message) {
|
||||
// Join the body array into one string.
|
||||
if (is_array($message['body'])) {
|
||||
$message['body'] = implode("\n\n", $message['body']);
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the email message.
|
||||
*
|
||||
* @see drupal_mail()
|
||||
*
|
||||
* @param array $message
|
||||
* A message array, as described in hook_mail_alter().
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the mail was successfully accepted, otherwise FALSE.
|
||||
*/
|
||||
public function mail(array $message) {
|
||||
// Optionally log mail keys not using Mandrill already. Helpful in
|
||||
// configuring Mandrill.
|
||||
if (variable_get('mandrill_log_defaulted_sends', FALSE)) {
|
||||
$systems = mailsystem_get();
|
||||
$registered = FALSE;
|
||||
foreach ($systems as $key => $system) {
|
||||
if ($message['id'] == $key) {
|
||||
$registered = TRUE;
|
||||
}
|
||||
if (!$registered) {
|
||||
watchdog(
|
||||
'mandrill',
|
||||
"Module: %module Key: %key invoked Mandrill to send email because Mandrill is configured as the default mail system. Specify alternate configuration for this module & key in !mailsystem if this is not desirable.",
|
||||
array(
|
||||
'%module' => $message['module'],
|
||||
'%key' => $message['key'],
|
||||
'!mailsystem' => l(t('Mail System'), 'admin/config/system/mailsystem'),
|
||||
),
|
||||
WATCHDOG_INFO
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mailer = mandrill_get_api_object();
|
||||
|
||||
// Apply input format to body.
|
||||
$format = variable_get('mandrill_filter_format', '');
|
||||
if (!empty($format)) {
|
||||
$message['body'] = check_markup($message['body'], $format);
|
||||
}
|
||||
|
||||
// Extract an array of recipients.
|
||||
$to = mandrill_get_to($message['to']);
|
||||
|
||||
// Prepare headers, defaulting the reply-to to the from address since
|
||||
// Mandrill needs the from address to be configured separately.
|
||||
// Note that only Reply-To and X-* headers are allowed.
|
||||
$headers = isset($message['headers']) ? $message['headers'] : array();
|
||||
if (!empty($message['from']) && empty($headers['Reply-To'])) {
|
||||
$headers['Reply-To'] = $message['from'];
|
||||
}
|
||||
|
||||
// Prepare attachments.
|
||||
$attachments = array();
|
||||
if (isset($message['attachments']) && !empty($message['attachments'])) {
|
||||
foreach ($message['attachments'] as $attachment) {
|
||||
if (is_file($attachment)) {
|
||||
$attachments[] = $mailer->getAttachmentStruct($attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if content should be available for this message.
|
||||
$blacklisted_keys = explode(',', mandrill_mail_key_blacklist());
|
||||
$view_content = TRUE;
|
||||
foreach ($blacklisted_keys as $key) {
|
||||
if ($message['id'] == drupal_strtolower(trim($key))) {
|
||||
$view_content = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The Mime Mail module (mimemail) expects attachments as an array of file
|
||||
// arrays in $message['params']['attachments']. As many modules assume you
|
||||
// will be using Mime Mail to handle attachments, we need to parse this
|
||||
// array as well.
|
||||
if (isset($message['params']['attachments']) && !empty($message['params']['attachments'])) {
|
||||
foreach ($message['params']['attachments'] as $attachment) {
|
||||
$attachment_path = drupal_realpath($attachment['uri']);
|
||||
if (is_file($attachment_path)) {
|
||||
$struct = $mailer->getAttachmentStruct($attachment_path);
|
||||
// Allow for customised filenames.
|
||||
if (!empty($attachment['filename'])) {
|
||||
$struct['name'] = $attachment['filename'];
|
||||
}
|
||||
$attachments[] = $struct;
|
||||
}
|
||||
}
|
||||
// Remove the file objects from $message['params']['attachments'].
|
||||
// (This prevents double-attaching in the drupal_alter hook below.)
|
||||
unset($message['params']['attachments']);
|
||||
}
|
||||
|
||||
// Account for the plaintext parameter provided by the mimemail module.
|
||||
$plain_text = empty($message['params']['plaintext']) ? drupal_html_to_text($message['body']) : $message['params']['plaintext'];
|
||||
|
||||
// Get metadata.
|
||||
$metadata = isset($message['metadata']) ? $message['metadata'] : array();
|
||||
|
||||
$from = mandrill_from();
|
||||
$mandrill_message = array(
|
||||
'html' => $message['body'],
|
||||
'text' => $plain_text,
|
||||
'subject' => $message['subject'],
|
||||
'from_email' => $from['email'],
|
||||
'from_name' => $from['name'],
|
||||
'to' => $to,
|
||||
'headers' => $headers,
|
||||
'track_opens' => variable_get('mandrill_track_opens', TRUE),
|
||||
'track_clicks' => variable_get('mandrill_track_clicks', TRUE),
|
||||
// We're handling this with drupal_html_to_text().
|
||||
'auto_text' => FALSE,
|
||||
'url_strip_qs' => variable_get('mandrill_url_strip_qs', FALSE),
|
||||
'bcc_address' => isset($message['bcc_email']) ? $message['bcc_email'] : NULL,
|
||||
'tags' => array($message['id']),
|
||||
'google_analytics_domains' => (variable_get('mandrill_analytics_domains', NULL)) ? explode(',', variable_get('mandrill_analytics_domains')) : array(),
|
||||
'google_analytics_campaign' => variable_get('mandrill_analytics_campaign', ''),
|
||||
'attachments' => $attachments,
|
||||
'view_content_link' => $view_content,
|
||||
'metadata' => $metadata,
|
||||
);
|
||||
$subaccount = variable_get('mandrill_subaccount', FALSE);
|
||||
if ($subaccount) {
|
||||
$mandrill_message['subaccount'] = $subaccount;
|
||||
}
|
||||
// Allow other modules to alter the Mandrill message, and sender/args.
|
||||
$mandrill_params = array(
|
||||
'message' => $mandrill_message,
|
||||
'function' => 'mandrill_sender_plain',
|
||||
'args' => array(),
|
||||
);
|
||||
drupal_alter('mandrill_mail', $mandrill_params, $message);
|
||||
|
||||
// Queue for processing during cron or send immediately.
|
||||
$status = NULL;
|
||||
if (mandrill_process_async()) {
|
||||
$queue = DrupalQueue::get(MANDRILL_QUEUE, TRUE);
|
||||
$queue->createItem($mandrill_params);
|
||||
if (variable_get('mandrill_batch_log_queued', TRUE)) {
|
||||
watchdog('mandrill', 'Message from %from to %to queued for delivery.',
|
||||
array(
|
||||
'%from' => $from['email'],
|
||||
'%to' => $to[0]['email'],
|
||||
), WATCHDOG_NOTICE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return mandrill_mailsend($mandrill_params['message'], $mandrill_params['function'], $mandrill_params['args']);
|
||||
}
|
||||
}
|
||||
}
|
300
sites/all/modules/contrib/mail/mandrill/mandrill.admin.inc
Normal file
300
sites/all/modules/contrib/mail/mandrill/mandrill.admin.inc
Normal file
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Administrative forms for Mandrill module.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Administrative settings.
|
||||
*
|
||||
* @return array
|
||||
* An array containing form items to place on the module settings page.
|
||||
*/
|
||||
function mandrill_admin_settings($form, &$form_state) {
|
||||
$key = variable_get('mandrill_api_key');
|
||||
$form['mandrill_api_key'] = array(
|
||||
'#title' => t('Mandrill API Key'),
|
||||
'#type' => 'textfield',
|
||||
'#description' => t('Create or grab your API key from the !link.',
|
||||
array('!link' => l(t('Mandrill settings'), 'https://mandrillapp.com/settings/index'))),
|
||||
'#default_value' => $key,
|
||||
);
|
||||
|
||||
if ($key) {
|
||||
$mailsystem_config_keys = mailsystem_get();
|
||||
$in_use = FALSE;
|
||||
$usage_rows = array();
|
||||
foreach ($mailsystem_config_keys as $key => $sys) {
|
||||
if ($sys === 'MandrillMailSystem' && $key != 'mandrill_test') {
|
||||
$in_use = TRUE;
|
||||
$usage_rows[] = array(
|
||||
$key,
|
||||
$sys,
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($in_use) {
|
||||
$usage_array = array(
|
||||
'#theme' => 'table',
|
||||
'#header' => array(
|
||||
t('Module Key'),
|
||||
t('Mail System'),
|
||||
),
|
||||
'#rows' => $usage_rows,
|
||||
);
|
||||
$form['mandrill_status'] = array(
|
||||
'#type' => 'markup',
|
||||
'#markup' => t('Mandrill is currently configured to be used by the following Module Keys. To change these settings or configure additional systems to use Mandrill, use !link.<br /><br />!table',
|
||||
array(
|
||||
'!link' => l(t('Mail System'), 'admin/config/system/mailsystem'),
|
||||
'!table' => drupal_render($usage_array),
|
||||
)),
|
||||
);
|
||||
}
|
||||
elseif (!$form_state['rebuild']) {
|
||||
drupal_set_message(t('PLEASE NOTE: Mandrill is not currently configured for use by Drupal. In order to route your email through Mandrill, you must configure at least one MailSystemInterface (other than mandrill) to use "MandrillMailSystem" in !link, or you will only be able to send Test Emails through Mandrill.',
|
||||
array('!link' => l(t('Mail System'), 'admin/config/system/mailsystem'))), 'warning');
|
||||
}
|
||||
|
||||
$form['email_options'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#title' => t('Email options'),
|
||||
);
|
||||
|
||||
$from = mandrill_from();
|
||||
$form['email_options']['mandrill_from'] = array(
|
||||
'#title' => t('From address'),
|
||||
'#type' => 'textfield',
|
||||
'#description' => t('The sender email address. If this address has not been verified, messages will be queued and not sent until it is. This address will appear in the "from" field, and any emails sent through Mandrill with a "from" address will have that address moved to the Reply-To field.'),
|
||||
'#default_value' => $from['email'],
|
||||
);
|
||||
$form['email_options']['mandrill_from_name'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('From name'),
|
||||
'#default_value' => $from['name'],
|
||||
'#description' => t('Optionally enter a from name to be used.'),
|
||||
);
|
||||
$subaccounts = mandrill_get_subaccounts();
|
||||
$sub_acct_options = array('' => '-- Select --');
|
||||
if (count($subaccounts)) {
|
||||
$sub_acct_options = array('' => '-- Select --');
|
||||
foreach ($subaccounts as $acct) {
|
||||
if ($acct['status'] == 'active') {
|
||||
$sub_acct_options[$acct['id']] = $acct['name'] . ' (' . $acct['reputation'] . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (variable_get('mandrill_subaccount', FALSE)) {
|
||||
variable_set('mandrill_subaccount', FALSE);
|
||||
}
|
||||
if (count($sub_acct_options) > 1) {
|
||||
$form['email_options']['mandrill_subaccount'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Subaccount'),
|
||||
'#options' => $sub_acct_options,
|
||||
'#default_value' => variable_get('mandrill_subaccount', ''),
|
||||
'#description' => t('Choose a subaccount to send through.'),
|
||||
);
|
||||
}
|
||||
$formats = filter_formats();
|
||||
$options = array('' => t('-- Select --'));
|
||||
foreach ($formats as $v => $format) {
|
||||
$options[$v] = $format->name;
|
||||
}
|
||||
$form['email_options']['mandrill_filter_format'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Input format'),
|
||||
'#description' => t('If selected, the input format to apply to the message body before sending to the Mandrill API.'),
|
||||
'#options' => $options,
|
||||
'#default_value' => array(variable_get('mandrill_filter_format', 'full_html')),
|
||||
);
|
||||
$form['send_options'] = array(
|
||||
'#title' => t('Send options'),
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
);
|
||||
$form['send_options']['mandrill_track_opens'] = array(
|
||||
'#title' => t('Track opens'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('Whether or not to turn on open tracking for messages.'),
|
||||
'#default_value' => variable_get('mandrill_track_opens', TRUE),
|
||||
);
|
||||
$form['send_options']['mandrill_track_clicks'] = array(
|
||||
'#title' => t('Track clicks'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('Whether or not to turn on click tracking for messages.'),
|
||||
'#default_value' => variable_get('mandrill_track_clicks', TRUE),
|
||||
);
|
||||
$form['send_options']['mandrill_url_strip_qs'] = array(
|
||||
'#title' => t('Strip query string'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('Whether or not to strip the query string from URLs when aggregating tracked URL data.'),
|
||||
'#default_value' => variable_get('mandrill_url_strip_qs', FALSE),
|
||||
);
|
||||
$form['send_options']['mandrill_mail_key_blacklist'] = array(
|
||||
'#title' => t('Content logging blacklist'),
|
||||
'#type' => 'textarea',
|
||||
'#description' => t('Comma delimited list of Drupal mail keys to exclude content logging for. CAUTION: Removing the default password reset key may expose a security risk.'),
|
||||
'#default_value' => mandrill_mail_key_blacklist(),
|
||||
);
|
||||
$form['send_options']['mandrill_log_defaulted_sends'] = array(
|
||||
'#title' => t('Log sends from module/key pairs that are not registered independently in mailsystem.'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('If you select Mandrill as the site-wide default email sender in !mailsystem and check this box, any messages that are sent through Mandrill using module/key pairs that are not specifically registered in mailsystem will cause a message to be written to the !systemlog (type: Mandrill, severity: info). Enable this to identify keys and modules for automated emails for which you would like to have more granular control. It is not recommended to leave this box checked for extended periods, as it slows Mandrill and can clog your logs.',
|
||||
array(
|
||||
'!mailsystem' => l(t('Mail System'), 'admin/config/system/mailsystem'),
|
||||
'!systemlog' => l(t('system log'), 'admin/reports/dblog'),
|
||||
)),
|
||||
'#default_value' => variable_get('mandrill_log_defaulted_sends', FALSE),
|
||||
);
|
||||
|
||||
$form['analytics'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#title' => t('Google analytics'),
|
||||
);
|
||||
$form['analytics']['mandrill_analytics_domains'] = array(
|
||||
'#title' => t('Google analytics domains'),
|
||||
'#type' => 'textfield',
|
||||
'#description' => t('One or more domains for which any matching URLs will automatically have Google Analytics parameters appended to their query string. Separate each domain with a comma.'),
|
||||
'#default_value' => variable_get('mandrill_analytics_domains', ''),
|
||||
);
|
||||
$form['analytics']['mandrill_analytics_campaign'] = array(
|
||||
'#title' => t('Google analytics campaign'),
|
||||
'#type' => 'textfield',
|
||||
'#description' => t("The value to set for the utm_campaign tracking parameter. If this isn't provided the messages from address will be used instead."),
|
||||
'#default_value' => variable_get('mandrill_analytics_campaign', ''),
|
||||
);
|
||||
$form['asynchronous_options'] = array(
|
||||
'#title' => t('Asynchronous options'),
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#attributes' => array(
|
||||
'id' => array('mandrill-async-options'),
|
||||
),
|
||||
);
|
||||
$form['asynchronous_options']['mandrill_process_async'] = array(
|
||||
'#title' => t('Queue outgoing messages'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('When set, emails will not be immediately sent. Instead, they will be placed in a queue and sent when cron is triggered.'),
|
||||
'#default_value' => mandrill_process_async(),
|
||||
);
|
||||
$form['asynchronous_options']['mandrill_batch_log_queued'] = array(
|
||||
'#title' => t('Log queued emails in watchdog'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('Do you want to create a watchdog entry when an email is queued to be sent?'),
|
||||
'#default_value' => variable_get('mandrill_batch_log_queued', TRUE),
|
||||
'#states' => array(
|
||||
'invisible' => array(
|
||||
':input[name="mandrill_process_async"]' => array('checked' => FALSE),
|
||||
),
|
||||
),
|
||||
);
|
||||
$form['asynchronous_options']['mandrill_queue_worker_timeout'] = array(
|
||||
'#title' => t('Queue worker timeout'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => '12',
|
||||
'#description' => t('Number of seconds to spend processing messages during cron. Zero or negative values are not allowed.'),
|
||||
'#required' => TRUE,
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
'#default_value' => variable_get('mandrill_queue_worker_timeout', 15),
|
||||
'#states' => array(
|
||||
'invisible' => array(
|
||||
':input[name="mandrill_process_async"]' => array('checked' => FALSE),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return system_settings_form($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Javascript callback for the mandrill_admin_settings form.
|
||||
*
|
||||
* @param array $form
|
||||
* a drupal form
|
||||
* @param array $form_state
|
||||
* drupal form_state
|
||||
*
|
||||
* @return array
|
||||
* a form section
|
||||
*/
|
||||
function mandrill_admin_settings_form_callback($form, &$form_state) {
|
||||
return $form['asynchronous_options'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a form for sending a test email.
|
||||
*/
|
||||
function mandrill_test_form($form, &$form_state) {
|
||||
drupal_set_title(t('Send test email'));
|
||||
|
||||
$form['mandrill_test_address'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Email address to send a test email to'),
|
||||
'#default_value' => variable_get('site_mail', ''),
|
||||
'#description' => t('Type in an address to have a test email sent there.'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
$form['mandrill_test_body'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Test body contents'),
|
||||
'#default_value' => t('If you receive this message it means your site is capable of using Mandrill to send email. This url is here to test click tracking: !link',
|
||||
array('!link' => l(t('link'), 'http://www.drupal.org/project/mandrill'))),
|
||||
);
|
||||
$form['include_attachment'] = array(
|
||||
'#title' => t('Include attachment'),
|
||||
'#type' => 'checkbox',
|
||||
'#description' => t('If checked, the Drupal icon will be included as an attachment with the test email.'),
|
||||
'#default_value' => TRUE,
|
||||
);
|
||||
|
||||
$form['test_submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Send test email'),
|
||||
);
|
||||
$form['test_cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#href' => 'admin/config/services/mandrill',
|
||||
'#title' => t('Cancel'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for mandrill_test_form(), sends the test email.
|
||||
*/
|
||||
function mandrill_test_form_submit($form, &$form_state) {
|
||||
// If an address was given, send a test email message.
|
||||
$test_address = $form_state['values']['mandrill_test_address'];
|
||||
global $language;
|
||||
$params['subject'] = t('Drupal Mandrill test email');
|
||||
$params['body'] = $form_state['values']['mandrill_test_body'];
|
||||
$params['include_attachment'] = $form_state['values']['include_attachment'];
|
||||
$mailsystem = mailsystem_get();
|
||||
// Check for empty mailsystem config for Mandrill:
|
||||
if (empty($mailsystem['mandrill_test'])) {
|
||||
drupal_set_message(t('Automatically setting Mandrill tests to go through Mandrill API: MandrillMailSystem was not previously configured in Mail System.'));
|
||||
mailsystem_set(array('mandrill_test' => 'MandrillMailSystem'));
|
||||
}
|
||||
// Check for wrong mailsystem config for Mandrill, if not empty, and issue a
|
||||
// warning:
|
||||
elseif ($mailsystem['mandrill_test'] != 'MandrillMailSystem') {
|
||||
drupal_set_message(
|
||||
t('Mail System is configured to send Mandrill Test messages through %system, not Mandrill. To send tests through Mandrill, go to !link and change the setting.',
|
||||
array(
|
||||
'%system' => $mailsystem['mandrill_test'],
|
||||
'!link' => l(t('Mandrill'), 'https://mandrillapp.com/templates'))),
|
||||
'warning');
|
||||
// Hack because we are apparently formatting the body differently than
|
||||
// default drupal messages.
|
||||
$params['body'] = array('0' => $params['body']);
|
||||
}
|
||||
$result = drupal_mail('mandrill', 'test', $test_address, $language, $params);
|
||||
if (isset($result['result']) && $result['result'] == 'true') {
|
||||
drupal_set_message(t('Mandrill test email sent from %from to %to.', array('%from' => $result['from'], '%to' => $result['to'])), 'status');
|
||||
}
|
||||
}
|
50
sites/all/modules/contrib/mail/mandrill/mandrill.api.php
Normal file
50
sites/all/modules/contrib/mail/mandrill/mandrill.api.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains no working PHP code; it exists to provide additional
|
||||
* documentation for doxygen as well as to document hooks in the standard
|
||||
* Drupal manner.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows other modules to alter the Mandrill message and sender arguments.
|
||||
*
|
||||
* @array $mandrill_params
|
||||
* The mandril message array
|
||||
* @see MandrillMailSystem::mail()
|
||||
*
|
||||
* @array $message
|
||||
* The drupal_mail message array.
|
||||
* @see drupal_mail()
|
||||
*/
|
||||
function hook_mandrill_mail_alter(&$mandrill_params, $message) {
|
||||
// No example.
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows other modules to alter the allowed attachment file types.
|
||||
*
|
||||
* @array $types
|
||||
* An array of file types indexed numerically.
|
||||
*/
|
||||
function hook_mandrill_valid_attachment_types_alter(&$types) {
|
||||
// Example, allow word docs:
|
||||
$types[] = 'application/msword';
|
||||
// Allow openoffice docs:
|
||||
$types[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow other modules to respond to the result of sending an email.
|
||||
*
|
||||
* @param array $result
|
||||
* Associative array containing the send result, including the status.
|
||||
*/
|
||||
function hook_mandrill_mailsend_result($result) {
|
||||
if ($result['status'] == 'rejected') {
|
||||
// Delete user.
|
||||
$user = user_load_by_mail($result['email']);
|
||||
user_delete($user->uid);
|
||||
}
|
||||
}
|
18
sites/all/modules/contrib/mail/mandrill/mandrill.info
Normal file
18
sites/all/modules/contrib/mail/mandrill/mandrill.info
Normal file
@@ -0,0 +1,18 @@
|
||||
name = Mandrill
|
||||
description = "Allow for site emails to be sent through Mandrill."
|
||||
core = 7.x
|
||||
package = MailChimp
|
||||
|
||||
configure = admin/config/services/mandrill
|
||||
|
||||
dependencies[] = mailsystem (>=2.x)
|
||||
|
||||
files[] = lib/mandrill.mail.inc
|
||||
files[] = lib/mandrill.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2014-05-09
|
||||
version = "7.x-1.6"
|
||||
core = "7.x"
|
||||
project = "mandrill"
|
||||
datestamp = "1399658028"
|
||||
|
96
sites/all/modules/contrib/mail/mandrill/mandrill.install
Normal file
96
sites/all/modules/contrib/mail/mandrill/mandrill.install
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the mandrill module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function mandrill_uninstall() {
|
||||
// Delete other variables:
|
||||
variable_del('mandrill_analytics_campaign');
|
||||
variable_del('mandrill_analytics_domains');
|
||||
variable_del('mandrill_api_key');
|
||||
variable_del('mandrill_filter_format');
|
||||
variable_del('mandrill_from');
|
||||
variable_del('mandrill_from_name');
|
||||
variable_del('mandrill_mail_key_blacklist');
|
||||
variable_del('mandrill_test_address');
|
||||
variable_del('mandrill_test_body');
|
||||
variable_del('mandrill_track_clicks');
|
||||
variable_del('mandrill_track_opens');
|
||||
variable_del('mandrill_url_strip_qs');
|
||||
variable_del('mandrill_process_async');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_enable().
|
||||
*/
|
||||
function mandrill_enable() {
|
||||
mailsystem_set(array('mandrill_test' => 'MandrillMailSystem'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_disable().
|
||||
*/
|
||||
function mandrill_disable() {
|
||||
// Tell mailsystem to remove mandrill and restore to defaults:
|
||||
mailsystem_clear(array('mandrill_test' => 'MandrillMailSystem'));
|
||||
watchdog('mandrill', 'Mandrill has been disabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes obsolete variables.
|
||||
*/
|
||||
function mandrill_update_7001() {
|
||||
variable_del('mandrill_status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds the registry, as we've moved some files around.
|
||||
*/
|
||||
function mandrill_update_7002() {
|
||||
|
||||
// Rebuild the registry, we've moved some files around.
|
||||
registry_rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function mandrill_requirements($phase) {
|
||||
$requirements = array();
|
||||
// Ensure translations don't break at install time.
|
||||
$t = get_t();
|
||||
|
||||
if ($phase == 'update') {
|
||||
if (!module_exists('mailsystem')) {
|
||||
$requirements['mandrill'] = array(
|
||||
'title' => $t('Mandrill'),
|
||||
'value' => '7.x-1.4',
|
||||
'description' => $t('Mail System module is required for Mandrill 7.x-1.3 or higher.'),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete obsolete batch limit variable.
|
||||
*/
|
||||
function mandrill_update_7003() {
|
||||
variable_del('mandrill_batch_limit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache to pick up new class name for DrupalMandrill class.
|
||||
*/
|
||||
function mandrill_update_7004() {
|
||||
cache_clear_all();
|
||||
}
|
406
sites/all/modules/contrib/mail/mandrill/mandrill.module
Normal file
406
sites/all/modules/contrib/mail/mandrill/mandrill.module
Normal file
@@ -0,0 +1,406 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Enables Drupal to send email directly through Mandrill.
|
||||
*
|
||||
* Overriding mail handling in Drupal to make Mandrill the default
|
||||
* transport layer, requires to change the mail_system variable's
|
||||
* default value array('default-system' => 'DefaultMailSystem').
|
||||
* This module uses array('default-system' => 'MailChimpMandrillMailSystem').
|
||||
*/
|
||||
|
||||
|
||||
define('MANDRILL_QUEUE', 'mandrill_queue');
|
||||
define('MANDRILL_EMAIL_REGEX', '/^\s*(.+?)\s*<\s*([^>]+)\s*>$/');
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
function mandrill_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/help#mandrill':
|
||||
return t('Allow for site emails to be sent through Mandrill.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function mandrill_menu() {
|
||||
$items = array();
|
||||
$items['admin/config/services/mandrill'] = array(
|
||||
'title' => 'Mandrill',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('mandrill_admin_settings'),
|
||||
'access arguments' => array('administer mandrill'),
|
||||
'description' => 'Send emails through the Mandrill transactional email service.',
|
||||
'file' => 'mandrill.admin.inc',
|
||||
'type' => MENU_NORMAL_ITEM,
|
||||
);
|
||||
$items['admin/config/services/mandrill/settings'] = array(
|
||||
'title' => 'Settings',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => 0,
|
||||
);
|
||||
$items['admin/config/services/mandrill/test'] = array(
|
||||
'title' => 'Send test email',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('mandrill_test_form'),
|
||||
'access callback' => 'mandrill_test_access',
|
||||
'description' => 'Send a test email using the Mandrill API.',
|
||||
'file' => 'mandrill.admin.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 1,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback for sending test email.
|
||||
*
|
||||
* @return bool
|
||||
* True if current user has access to send test messages
|
||||
*/
|
||||
function mandrill_test_access() {
|
||||
$a = user_access('administer mandrill');
|
||||
$b = variable_get('mandrill_api_key');
|
||||
return $a & !empty($b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function mandrill_permission() {
|
||||
return array(
|
||||
'administer mandrill' => array(
|
||||
'title' => t('Administer Mandrill'),
|
||||
'description' => t('Perform administration tasks for the Mandrill email service.'),
|
||||
"restrict access" => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_cron_queue_info().
|
||||
*/
|
||||
function mandrill_cron_queue_info() {
|
||||
$queues = array();
|
||||
$queues[MANDRILL_QUEUE] = array(
|
||||
'worker callback' => 'mandrill_queue_worker_mailsend',
|
||||
'time' => variable_get('mandrill_queue_worker_timeout', 15),
|
||||
);
|
||||
return $queues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a queued email.
|
||||
* @see mandrill_cron_queue_info()
|
||||
*/
|
||||
function mandrill_queue_worker_mailsend($data) {
|
||||
// Send the message stored in the queue item.
|
||||
mandrill_mailsend(
|
||||
$data['message'],
|
||||
$data['function'],
|
||||
$data['args']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_mail().
|
||||
*/
|
||||
function mandrill_mail($key, &$message, $params) {
|
||||
if ($key == 'test') {
|
||||
$message['subject'] = $params['subject'];
|
||||
$message['body'] = $params['body'];
|
||||
if ($params['include_attachment']) {
|
||||
$message['attachments'][] = drupal_realpath('misc/druplicon.png');
|
||||
$message['body'] .= ' ' . t('The Drupal icon is included as an attachment to test the attachment functionality.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstracts sending of messages, allowing queueing option.
|
||||
*
|
||||
* @param array $message
|
||||
* A message array formatted for Mandrill's sending API, plus 2 additional
|
||||
* indexes for the send_function and an array of $args, if needed by the send
|
||||
* function.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if no exception thrown
|
||||
*/
|
||||
function mandrill_mailsend($message, $function, $args = array()) {
|
||||
try {
|
||||
if (!function_exists($function)) {
|
||||
watchdog('mandrill', 'Error sending email from %from to %to. Function %function not found.',
|
||||
array(
|
||||
'%from' => $message['from_email'],
|
||||
'%to' => $message['to'],
|
||||
'%function' => $function,
|
||||
),
|
||||
WATCHDOG_ERROR
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$params = array($message) + $args;
|
||||
$results = call_user_func_array($function, $params);
|
||||
foreach ($results as $result) {
|
||||
// Allow other modules to react based on a send result.
|
||||
module_invoke_all('mandrill_mailsend_result', $result);
|
||||
|
||||
switch ($result['status']) {
|
||||
case "error":
|
||||
case "invalid":
|
||||
case "rejected":
|
||||
$to = isset($result['email']) ? $result['email'] : 'recipient';
|
||||
$status = isset($result['status']) ? $result['status'] : 'message';
|
||||
$error_message = isset($result['message']) ? $result['message'] : 'no message';
|
||||
watchdog('mandrill', 'Failed sending email from %from to %to. @status: @message',
|
||||
array(
|
||||
'%from' => $message['from_email'],
|
||||
'%to' => $to,
|
||||
'@status' => $status,
|
||||
'@message' => $error_message,
|
||||
),
|
||||
WATCHDOG_ERROR
|
||||
);
|
||||
return FALSE;
|
||||
|
||||
case "queued":
|
||||
watchdog('mandrill', 'Email from %from to %to queued by Mandrill App.',
|
||||
array(
|
||||
'%from' => $message['from_email'],
|
||||
'%to' => $result['email'],
|
||||
),
|
||||
WATCHDOG_INFO
|
||||
);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
catch (MandrillException $e) {
|
||||
watchdog('mandrill', 'Error sending email from %from to %to. @code: @message',
|
||||
array(
|
||||
'%from' => $message['from_email'],
|
||||
'%to' => $message['to'],
|
||||
'@code' => $e->getCode(),
|
||||
'@message' => $e->getMessage(),
|
||||
),
|
||||
WATCHDOG_ERROR
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The actual function that calls the API send message.
|
||||
*
|
||||
* This is the default function used by mandrill_mailsend().
|
||||
*
|
||||
* @array $message
|
||||
* Associative array containing message data.
|
||||
*
|
||||
* @return array
|
||||
* Results of sending the message.
|
||||
*
|
||||
* @throws MandrillException
|
||||
*/
|
||||
function mandrill_sender_plain($message) {
|
||||
if ($mailer = mandrill_get_api_object()) {
|
||||
return $mailer->messages_send($message);
|
||||
}
|
||||
else {
|
||||
throw new MandrillException('Missing API key.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Mandrill API object for communication with the mailchimp server.
|
||||
*
|
||||
* @param bool $reset
|
||||
* Pass in TRUE to reset the statically cached object.
|
||||
* @param string $classname
|
||||
* The Mandrill class to use for sending emails. Passing a parameter allows
|
||||
* the class used to be overridden, E.g., for tests.
|
||||
*
|
||||
* @throws MandrillException
|
||||
*
|
||||
* @return Mandrill|bool
|
||||
* Mandrill Object upon success
|
||||
* FALSE if variable_get('mandrill_api_key') is unset
|
||||
*/
|
||||
function mandrill_get_api_object($reset = FALSE, $classname = 'DrupalMandrill') {
|
||||
$api =& drupal_static(__FUNCTION__, NULL);
|
||||
|
||||
if ($api === NULL || $reset === TRUE) {
|
||||
$api_key = variable_get('mandrill_api_key', '');
|
||||
$api_timeout = variable_get('mandrill_api_timeout', 60);
|
||||
if (empty($api_key)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$api = new $classname($api_key, $api_timeout);
|
||||
}
|
||||
|
||||
return $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the names of the modules that are using Mailsystem.
|
||||
*
|
||||
* This is consistent with with Mailsystem's display. In the future, if
|
||||
* Mailsystem were to provide an API for their labeling, that should be used.
|
||||
*
|
||||
* @return array
|
||||
* Array of all module names indexing to their "display" names,
|
||||
* and some special items for non-module values like null, default-system,
|
||||
* and some clarification talked onto the end of the Mandrill module's name.
|
||||
*/
|
||||
function mandrill_get_module_key_names() {
|
||||
$name_array = array(
|
||||
'' => '--none--',
|
||||
'default-system' => "Site-wide default",
|
||||
);
|
||||
$descriptions = array();
|
||||
foreach (system_rebuild_module_data() as $item) {
|
||||
if ($item->status) {
|
||||
$descriptions[$item->name] = (empty($item->info['package']) ? '' : $item->info['package']) . ' » ' . t('!module module', array('!module' => $item->info['name']));
|
||||
}
|
||||
}
|
||||
asort($descriptions);
|
||||
$mailsystem_settings = mailsystem_get();
|
||||
unset($mailsystem_settings['default-system']);
|
||||
foreach ($mailsystem_settings as $id => $class) {
|
||||
// Separate $id into $module and $key.
|
||||
$module = $id;
|
||||
while ($module && empty($descriptions[$module])) {
|
||||
// Remove a key from the end.
|
||||
$module = implode('_', explode('_', $module, -1));
|
||||
}
|
||||
// If an array key of the $mail_system variable is neither "default-system"
|
||||
// nor begins with a module name, then it should be unset.
|
||||
if (empty($module)) {
|
||||
// This shouldn't happen.
|
||||
}
|
||||
// Set $title to the human-readable module name.
|
||||
$title = preg_replace('/^.* » /', '', $descriptions[$module]);
|
||||
if ($key = substr($id, strlen($module) + 1)) {
|
||||
$title .= " ($key key)";
|
||||
}
|
||||
$name_array[$id] = $title;
|
||||
}
|
||||
|
||||
return $name_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of mandrill template objects.
|
||||
*
|
||||
* @return array
|
||||
* An of available templates with complete data or NULL if none are available.
|
||||
*/
|
||||
function mandrill_get_templates() {
|
||||
// Only show the template settings if the mandrill api can be called.
|
||||
$templates = NULL;
|
||||
try {
|
||||
$mailer = mandrill_get_api_object();
|
||||
$templates = $mailer->templates_list();
|
||||
}
|
||||
catch (MandrillException $e) {
|
||||
drupal_set_message(t('Mandrill: %message', array('%message' => check_plain($e->getMessage()))), 'error');
|
||||
watchdog_exception('mandrill', $e);
|
||||
}
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of subaccounts.
|
||||
*/
|
||||
function mandrill_get_subaccounts() {
|
||||
$subaccounts = array();
|
||||
try {
|
||||
$mandrill = mandrill_get_api_object();
|
||||
$subaccounts = $mandrill->subaccounts();
|
||||
}
|
||||
catch (MandrillException $e) {
|
||||
drupal_set_message(t('Mandrill: %message', array('%message' => check_plain($e->getMessage()))), 'error');
|
||||
watchdog_exception('mandrill', $e);
|
||||
}
|
||||
|
||||
return $subaccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to return a comma delimited list of mail keys to not log content for.
|
||||
*
|
||||
* @return string
|
||||
* a comma delimited list of mail keys
|
||||
*/
|
||||
function mandrill_mail_key_blacklist() {
|
||||
return variable_get('mandrill_mail_key_blacklist', 'user_password_reset');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate an array of recipients.
|
||||
*
|
||||
* @param mixed $to
|
||||
* a comma delimited list of email addresses in 1 of 2 forms:
|
||||
* user@domain.com
|
||||
* any number of names <user@domain.com>
|
||||
*
|
||||
* @return array
|
||||
* array of email addresses
|
||||
*/
|
||||
function mandrill_get_to($to) {
|
||||
$recipients = array();
|
||||
$to_array = explode(',', $to);
|
||||
foreach ($to_array as $email) {
|
||||
if (preg_match(MANDRILL_EMAIL_REGEX, $email, $matches)) {
|
||||
$recipients[] = array(
|
||||
'email' => $matches[2],
|
||||
'name' => $matches[1],
|
||||
);
|
||||
}
|
||||
else {
|
||||
$recipients[] = array('email' => $email);
|
||||
}
|
||||
}
|
||||
return $recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if mail should be processed asynchronously.
|
||||
*
|
||||
* @return bool
|
||||
* True if asyncronous processing is enabled
|
||||
*/
|
||||
function mandrill_process_async() {
|
||||
return variable_get('mandrill_process_async', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the from information for a Mandrill message.
|
||||
*
|
||||
* @return array
|
||||
* array(
|
||||
* 'email' => 'admin@example.com',
|
||||
* 'name' => 'My Site',
|
||||
* )
|
||||
*/
|
||||
function mandrill_from() {
|
||||
$default_from = variable_get('site_mail', ini_get('sendmail_from'));
|
||||
$email = variable_get('mandrill_from', $default_from);
|
||||
$name = variable_get('mandrill_from_name', variable_get('site_name'));
|
||||
return array(
|
||||
'email' => $email,
|
||||
'name' => $name,
|
||||
);
|
||||
}
|
109
sites/all/modules/contrib/mail/mandrill/mandrill.variable.inc
Normal file
109
sites/all/modules/contrib/mail/mandrill/mandrill.variable.inc
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Mandrill variable hooks.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_variable_group_info().
|
||||
*/
|
||||
function mandrill_variable_group_info() {
|
||||
$groups['mandrill'] = array(
|
||||
'title' => t('Mandrill'),
|
||||
'description' => t('Settings related to Mandrill.'),
|
||||
'access' => 'administer mandrill',
|
||||
'path' => array('admin/config/services/mandrill'),
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_variable_info().
|
||||
*/
|
||||
function mandrill_variable_info($options) {
|
||||
$variables = array();
|
||||
|
||||
$variables['mandrill_api_key'] = array(
|
||||
'title' => t('Mandrill API Key', array(), $options),
|
||||
'description' => t('Create or grab your API key from the !link.',
|
||||
array('!link' => l(t('Mandrill settings'), 'https://mandrillapp.com/settings/index')),
|
||||
$options),
|
||||
'type' => 'string',
|
||||
'group' => 'mandrill',
|
||||
'default' => variable_get('site_mail'),
|
||||
);
|
||||
$variables['mandrill_from'] = array(
|
||||
'title' => t('From address', array(), $options),
|
||||
'description' => t('The sender email address. If this address has not been verified, messages will be queued and not sent until it is.', array(), $options),
|
||||
'type' => 'string',
|
||||
'group' => 'mandrill',
|
||||
'default' => '',
|
||||
);
|
||||
$variables['mandrill_from_name'] = array(
|
||||
'title' => t('From name', array(), $options),
|
||||
'description' => t('Optionally enter a from name to be used.', array(), $options),
|
||||
'type' => 'string',
|
||||
'group' => 'mandrill',
|
||||
'default' => '',
|
||||
);
|
||||
$formats = filter_formats();
|
||||
$mandrill_filter_format_options = array();
|
||||
foreach ($formats as $v => $format) {
|
||||
$mandrill_filter_format_options[$v] = $format->name;
|
||||
}
|
||||
$variables['mandrill_filter_format'] = array(
|
||||
'title' => t('Input format', array(), $options),
|
||||
'description' => t('If selected, the input format to apply to the message body before sending to the Mandrill API.', array(), $options),
|
||||
'type' => 'select',
|
||||
'options' => $mandrill_filter_format_options,
|
||||
'group' => 'mandrill',
|
||||
'default' => 'full_html',
|
||||
);
|
||||
|
||||
$variables['mandrill_track_opens'] = array(
|
||||
'title' => t('Track opens', array(), $options),
|
||||
'description' => t('Whether or not to turn on open tracking for messages.', array(), $options),
|
||||
'type' => 'boolean',
|
||||
'group' => 'mandrill',
|
||||
'default' => TRUE,
|
||||
);
|
||||
$variables['mandrill_track_clicks'] = array(
|
||||
'title' => t('mandrill_track_clicks', array(), $options),
|
||||
'description' => t('Whether or not to turn on click tracking for messages.', array(), $options),
|
||||
'type' => 'boolean',
|
||||
'group' => 'mandrill',
|
||||
'default' => TRUE,
|
||||
);
|
||||
$variables['mandrill_url_strip_qs'] = array(
|
||||
'title' => t('Strip query string', array(), $options),
|
||||
'description' => t('Whether or not to strip the query string from URLs when aggregating tracked URL data.', array(), $options),
|
||||
'type' => 'boolean',
|
||||
'group' => 'mandrill',
|
||||
'default' => FALSE,
|
||||
);
|
||||
$variables['mandrill_mail_key_blacklist'] = array(
|
||||
'title' => t('Content logging blacklist', array(), $options),
|
||||
'description' => t('Comma delimited list of Drupal mail keys to exclude content logging for. CAUTION: Removing the default password reset key may expose a security risk.', array(), $options),
|
||||
'type' => 'text',
|
||||
'group' => 'mandrill',
|
||||
'default' => mandrill_mail_key_blacklist(),
|
||||
);
|
||||
|
||||
$variables['mandrill_analytics_domains'] = array(
|
||||
'title' => t('Google analytics domains', array(), $options),
|
||||
'description' => t('One or more domains for which any matching URLs will automatically have Google Analytics parameters appended to their query string. Separate each domain with a comma.', array(), $options),
|
||||
'type' => 'string',
|
||||
'group' => 'mandrill',
|
||||
'default' => '',
|
||||
);
|
||||
$variables['mandrill_analytics_campaign'] = array(
|
||||
'title' => t('Google analytics campaign', array(), $options),
|
||||
'description' => t("The value to set for the utm_campaign tracking parameter. If this isn't provided the messages from address will be used instead.", array(), $options),
|
||||
'type' => 'string',
|
||||
'group' => 'mandrill',
|
||||
'default' => '',
|
||||
);
|
||||
|
||||
return $variables;
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
View Mandrill activity for any entity with a valid email address.
|
||||
Activity keys off of an email address.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Enable the Mandrill Activity module.
|
||||
2. To use Mandrill Activity module, you will need to install and enable Mandrill
|
||||
and Entity API module [http://drupal.org/project/entity]([http://drupal.org/project/entity).
|
||||
|
||||
## Usage
|
||||
|
||||
1. Define which entity types you want to show Mandrill activity for at
|
||||
/admin/config/services/mandrill/activity.
|
||||
* Select a Drupal entity type.
|
||||
* Select a bundle.
|
||||
* Select the email entity property.
|
||||
2. Configure permissions for viewing Mandrill activity.
|
||||
3. Once setup, a new Mandrill activity local task will appear for any configured
|
||||
entity.
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Class defining a MandrillActivityEntity.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class MandrillActivityEntity
|
||||
*
|
||||
* Extend Entity to define a MandrillActivityEntity.
|
||||
*/
|
||||
class MandrillActivityEntity extends Entity {
|
||||
public
|
||||
$mandrill_activity_entity_id,
|
||||
$name,
|
||||
$label,
|
||||
$entity_type,
|
||||
$bundle,
|
||||
$email_property,
|
||||
$entity_path,
|
||||
$enabled;
|
||||
|
||||
/**
|
||||
* Override constructor to set entity type.
|
||||
*/
|
||||
public function __construct(array $values = array()) {
|
||||
parent::__construct($values, 'mandrill_activity_entity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a label for this entity.
|
||||
*
|
||||
* @return string
|
||||
* Label.
|
||||
*/
|
||||
public function label() {
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Class defining MandrillActivityUIController.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Override EntityDefaultUIController to customize our menu items.
|
||||
*/
|
||||
class MandrillActivityUIController extends EntityDefaultUIController {
|
||||
|
||||
/**
|
||||
* Override hook_menu() to add a proper description.
|
||||
*/
|
||||
public function hook_menu() {
|
||||
$items = parent::hook_menu();
|
||||
$items[$this->path]['description'] = 'Manage Mandrill Activity entity settings.';
|
||||
$items[$this->path]['type'] = MENU_LOCAL_TASK;
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Administration pages for mandrill_activity module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a form for a mandrill_activity_entity.
|
||||
*/
|
||||
function mandrill_activity_entity_form($form, &$form_state, MandrillActivityEntity $mandrill_activity_entity = NULL, $op = 'edit') {
|
||||
if ($op == 'clone') {
|
||||
$mandrill_activity_entity->label .= ' (cloned)';
|
||||
$mandrill_activity_entity->name = '';
|
||||
}
|
||||
$entitynotnull = isset($mandrill_activity_entity->mandrill_activity_entity_id);
|
||||
$form_state['mandrill_activity'] = $mandrill_activity_entity;
|
||||
|
||||
$form['label'] = array(
|
||||
'#title' => t('Label'),
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => $entitynotnull ? $mandrill_activity_entity->label : '',
|
||||
'#description' => t('The human-readable name of this activity entity.'),
|
||||
'#required' => TRUE,
|
||||
'#weight' => -10,
|
||||
);
|
||||
|
||||
$form['name'] = array(
|
||||
'#title' => t('Name'),
|
||||
'#type' => 'machine_name',
|
||||
'#default_value' => $entitynotnull ? $mandrill_activity_entity->name : '',
|
||||
'#description' => t('machine name should only contain lowercase letters & underscores'),
|
||||
'#disabled' => !empty($mandrill_activity_entity->name),
|
||||
'#required' => TRUE,
|
||||
'#machine_name' => array(
|
||||
'exists' => 'mandrill_activity_load',
|
||||
'source' => array('label'),
|
||||
),
|
||||
'#weight' => -9,
|
||||
);
|
||||
|
||||
$form['drupal_entity'] = array(
|
||||
'#title' => t('Drupal entity'),
|
||||
'#type' => 'fieldset',
|
||||
'#attributes' => array(
|
||||
'id' => array('Mandrill-activity-drupal-entity'),
|
||||
),
|
||||
'#weight' => -8,
|
||||
);
|
||||
|
||||
// Prep the entity type list before creating the form item:
|
||||
$entity_types = array('' => t('-- Select --'));
|
||||
foreach (entity_get_info() as $entity_type => $info) {
|
||||
// Ignore Mandrill entity types.
|
||||
if (strpos($entity_type, 'mandrill') === FALSE) {
|
||||
$entity_types[$entity_type] = $info['label'];
|
||||
}
|
||||
}
|
||||
asort($entity_types);
|
||||
$form['drupal_entity']['entity_type'] = array(
|
||||
'#title' => t('Entity type'),
|
||||
'#type' => 'select',
|
||||
'#options' => $entity_types,
|
||||
'#default_value' => $entitynotnull ? $mandrill_activity_entity->entity_type : 0,
|
||||
'#required' => TRUE,
|
||||
'#description' => t('Select an entity type to enable Mandrill history on.'),
|
||||
'#ajax' => array(
|
||||
'callback' => 'mandrill_activity_mapping_form_callback',
|
||||
'wrapper' => 'Mandrill-activity-drupal-entity',
|
||||
),
|
||||
'#weight' => -8,
|
||||
);
|
||||
|
||||
$form_entity_type = & $form_state['values']['entity_type'];
|
||||
if (!$form_entity_type && $entitynotnull) {
|
||||
$form_entity_type = $mandrill_activity_entity->entity_type;
|
||||
}
|
||||
if ($form_entity_type) {
|
||||
// Prep the bundle list before creating the form item:
|
||||
$bundles = array('' => t('-- Select --'));
|
||||
$info = entity_get_info($form_entity_type);
|
||||
foreach ($info['bundles'] as $key => $bundle) {
|
||||
$bundles[$key] = $bundle['label'];
|
||||
}
|
||||
asort($bundles);
|
||||
$form['drupal_entity']['bundle'] = array(
|
||||
'#title' => t('Entity bundle'),
|
||||
'#type' => 'select',
|
||||
'#required' => TRUE,
|
||||
'#description' => t('Select a Drupal entity bundle with an email address to report on.'),
|
||||
'#options' => $bundles,
|
||||
'#default_value' => $entitynotnull ? $mandrill_activity_entity->bundle : 0,
|
||||
'#weight' => -7,
|
||||
'#ajax' => array(
|
||||
'callback' => 'mandrill_activity_mapping_form_callback',
|
||||
'wrapper' => 'Mandrill-activity-drupal-entity',
|
||||
),
|
||||
);
|
||||
|
||||
$form_bundle = & $form_state['values']['bundle'];
|
||||
if (!$form_bundle && $entitynotnull) {
|
||||
$form_bundle = $mandrill_activity_entity->bundle;
|
||||
}
|
||||
if ($form_bundle) {
|
||||
// Prep the field & properties list before creating the form item:
|
||||
$fields = mandrill_activity_email_fieldmap_options($form_entity_type, $form_bundle);
|
||||
$form['drupal_entity']['email_property'] = array(
|
||||
'#title' => t('Email Property'),
|
||||
'#type' => 'select',
|
||||
'#required' => TRUE,
|
||||
'#description' => t('Select the field which contains the email address'),
|
||||
'#options' => $fields,
|
||||
'#default_value' => $entitynotnull ? $mandrill_activity_entity->email_property : 0,
|
||||
'#maxlength' => 127,
|
||||
'#weight' => -6,
|
||||
);
|
||||
}
|
||||
}
|
||||
$form['enabled'] = array(
|
||||
'#title' => t('Enabled'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => $entitynotnull ? $mandrill_activity_entity->enabled : TRUE,
|
||||
'#weight' => -5,
|
||||
);
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#value' => t('Save Entity'),
|
||||
'#type' => 'submit',
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax callback for mandrill_activity_mapping_form().
|
||||
*/
|
||||
function mandrill_activity_mapping_form_callback($form, &$form_state) {
|
||||
return $form['drupal_entity'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation callback for mandrill_activity_entity_form().
|
||||
*/
|
||||
function mandrill_activity_entity_form_validate($form, &$form_state) {
|
||||
$extant_mc_entities = entity_load('mandrill_activity_entity');
|
||||
$form_id = $form_state['mandrill_activity_entity']->mandrill_activity_entity_id;
|
||||
$form_bundle = $form_state['values']['bundle'];
|
||||
$form_entity_id = $form_state['values']['entity_type'];
|
||||
foreach ($extant_mc_entities as $extant_ent) {
|
||||
if ($form_bundle == $extant_ent->bundle &&
|
||||
$form_entity_id == $extant_ent->entity_type &&
|
||||
$form_id != $extant_ent->mandrill_activity_entity_id) {
|
||||
form_set_error(
|
||||
'bundle',
|
||||
t('A Mandrill Activity Entity already exists for this Bundle. Either select a different Bundle or edit the !link for this bundle.',
|
||||
array(
|
||||
'!link' => l(t('existing Mandrill Activity Entity'), "admin/config/services/mandrill/activity/manage/{$extant_ent->name}"),
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for mandrill_activity_entity_form().
|
||||
*/
|
||||
function mandrill_activity_entity_form_submit($form, &$form_state) {
|
||||
$values = $form_state['values'];
|
||||
if ($form_state['op'] == 'add' || $form_state['op'] == 'clone') {
|
||||
$dummy = entity_create($form_state['values']['entity_type'], array('type' => $form_state['values']['bundle']));
|
||||
$uri = entity_uri($form_state['values']['entity_type'], $dummy);
|
||||
$values['entity_path'] = $uri['path'];
|
||||
$activity_entity = entity_create('mandrill_activity_entity', $values);
|
||||
}
|
||||
else {
|
||||
$activity_entity = $form_state['mandrill_activity_entity'];
|
||||
foreach ($values as $key => $val) {
|
||||
$activity_entity->{$key} = $val;
|
||||
}
|
||||
}
|
||||
$activity_entity->save();
|
||||
|
||||
// Ensure the new local task appears on the entity.
|
||||
menu_rebuild();
|
||||
$form_state['redirect'] = 'admin/config/services/Mandrill/activity';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all possible Drupal properties for a given entity type.
|
||||
*
|
||||
* @string $entity_type
|
||||
* Name of entity whose properties to list.
|
||||
* @string $entity_bundle
|
||||
* Entity bundle to get properties for.
|
||||
*
|
||||
* @return array
|
||||
* List of entities that can be used as an #options list.
|
||||
*/
|
||||
function mandrill_activity_email_fieldmap_options($entity_type, $entity_bundle = NULL) {
|
||||
$options = array('' => t('-- Select --'));
|
||||
|
||||
$properties = entity_get_all_property_info($entity_type);
|
||||
if (isset($entity_bundle)) {
|
||||
$info = entity_get_property_info($entity_type);
|
||||
$properties = $info['properties'];
|
||||
if (isset($info['bundles'][$entity_bundle])) {
|
||||
$properties += $info['bundles'][$entity_bundle]['properties'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($properties as $key => $property) {
|
||||
$type = isset($property['type']) ? entity_property_extract_innermost_type($property['type']) : 'text';
|
||||
$is_entity = ($type == 'entity') || (bool) entity_get_info($type);
|
||||
// Leave entities out of this.
|
||||
if (!$is_entity) {
|
||||
if (isset($property['field']) && $property['field'] && !empty($property['property info'])) {
|
||||
foreach ($property['property info'] as $sub_key => $sub_prop) {
|
||||
$options[$property['label']][$key . ':' . $sub_key] = $sub_prop['label'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$options[$key] = $property['label'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
name = Mandrill Activity
|
||||
description = View activity for an email address associated with any entity.
|
||||
package = Mandrill
|
||||
core = 7.x
|
||||
|
||||
dependencies[] = mandrill
|
||||
dependencies[] = entity
|
||||
|
||||
files[] = lib/mandrill_activity.entity.inc
|
||||
files[] = lib/mandrill_activity.ui_controller.inc
|
||||
|
||||
|
||||
; Information added by Drupal.org packaging script on 2014-05-09
|
||||
version = "7.x-1.6"
|
||||
core = "7.x"
|
||||
project = "mandrill"
|
||||
datestamp = "1399658028"
|
||||
|
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Install hooks for mandrill_activity.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function mandrill_activity_schema() {
|
||||
|
||||
$schema['mandrill_activity_entity'] = array(
|
||||
'description' => 'Mandrill activity enabled entities.',
|
||||
'fields' => array(
|
||||
'mandrill_activity_entity_id' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary Key: Unique mandrill_activity_entity entity ID.',
|
||||
),
|
||||
'name' => array(
|
||||
'description' => 'The machine-readable name of this mandrill_activity_entity.',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'label' => array(
|
||||
'description' => 'The human-readable name of this mandrill_activity_entity.',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'entity_type' => array(
|
||||
'description' => 'The Drupal entity type (e.g. "node", "user").',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'bundle' => array(
|
||||
'description' => 'The Drupal bundle (e.g. "page", "user")',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'entity_path' => array(
|
||||
'description' => 'The path to view individual entities of the selected type.',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'email_property' => array(
|
||||
'description' => 'The property that contains the email address to track',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'enabled' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
'description' => 'Whether or not this Mandrill activity stream is enabled.',
|
||||
),
|
||||
// Following fields are for supporting exportable status.
|
||||
'locked' => array(
|
||||
'description' => 'A boolean indicating whether the administrator may delete this mapping.',
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
// Set the default to ENTITY_CUSTOM without using the constant as it is
|
||||
// not safe to use it at this point.
|
||||
'default' => 0x01,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The exportable status of the entity.',
|
||||
),
|
||||
'module' => array(
|
||||
'description' => 'The name of the providing module if the entity has been defined in code.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('mandrill_activity_entity_id'),
|
||||
'unique keys' => array(
|
||||
'name' => array('name'),
|
||||
'entity_type_bundle' => array(
|
||||
'entity_type',
|
||||
'bundle',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Main module functions for mandrill_activity.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info().
|
||||
*/
|
||||
function mandrill_activity_entity_info() {
|
||||
$return = array(
|
||||
'mandrill_activity_entity' => array(
|
||||
'label' => t('Mandrill Activity Entity'),
|
||||
'controller class' => 'EntityAPIControllerExportable',
|
||||
'entity class' => 'MandrillActivityEntity',
|
||||
'base table' => 'mandrill_activity_entity',
|
||||
'uri callback' => 'entity_class_uri',
|
||||
'fieldable' => FALSE,
|
||||
'exportable' => TRUE,
|
||||
'module' => 'mandrill_activity',
|
||||
'entity keys' => array(
|
||||
'id' => 'mandrill_activity_entity_id',
|
||||
'name' => 'name',
|
||||
'label' => 'label',
|
||||
),
|
||||
// Enable the entity API's admin UI.
|
||||
'admin ui' => array(
|
||||
'path' => 'admin/config/services/mandrill/activity',
|
||||
'file' => 'mandrill_activity.admin.inc',
|
||||
'controller class' => 'MandrillActivityUIController',
|
||||
),
|
||||
'label callback' => 'entity_class_label',
|
||||
'access callback' => 'mandrill_activity_entity_access',
|
||||
),
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback for mandrill_activity_entity.
|
||||
*/
|
||||
function mandrill_activity_entity_access() {
|
||||
return user_access('administer mandrill activity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function mandrill_activity_menu() {
|
||||
$items = array();
|
||||
$mandrill_activity_entities = mandrill_activity_load();
|
||||
foreach ($mandrill_activity_entities as $mandrill_activity_entity) {
|
||||
$arg = substr_count($mandrill_activity_entity->entity_path, '/');
|
||||
$items[$mandrill_activity_entity->entity_path . '%entity_object/mandrill_activity'] = array(
|
||||
'title' => 'Mandrill Activity',
|
||||
'load arguments' => array($mandrill_activity_entity->entity_type),
|
||||
'page callback' => 'mandrill_activity_page',
|
||||
'page arguments' => array($arg, $mandrill_activity_entity),
|
||||
'access callback' => 'mandrill_activity_access',
|
||||
'access arguments' => array($mandrill_activity_entity),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback for activity menu items.
|
||||
*/
|
||||
function mandrill_activity_access(MandrillActivityEntity $mandrill_activity_entity) {
|
||||
if ($mandrill_activity_entity->enabled && user_access('access Mandrill activity')) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a single mandrill_activity_entity or all of them if no name provided.
|
||||
*
|
||||
* @string $name
|
||||
* Machine name of Mandrill Activity Entity to load.
|
||||
*
|
||||
* @return MandrillActivityEntity|array
|
||||
* Array of MandrillActivityEntity's or a single MandrillActivityEntity.
|
||||
*/
|
||||
function mandrill_activity_load($name = NULL) {
|
||||
$types = entity_load_multiple_by_name('mandrill_activity_entity', isset($name) ? array($name) : FALSE);
|
||||
return isset($name) ? reset($types) : $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content for the Mandrill log tab on entity instance pages.
|
||||
*
|
||||
* @object $entity
|
||||
* Entity to load activity for.
|
||||
*
|
||||
* @param MandrillActivityEntity $mandrill_activity_entity
|
||||
* Loaded MandrillActivityEntity object.
|
||||
*
|
||||
* @return array
|
||||
* Render array.
|
||||
*/
|
||||
function mandrill_activity_page($entity, MandrillActivityEntity $mandrill_activity_entity) {
|
||||
$entity_wrapper = entity_metadata_wrapper($mandrill_activity_entity->entity_type, $entity);
|
||||
$email_property = $mandrill_activity_entity->email_property;
|
||||
$email_property_array = explode(':', $email_property);
|
||||
$parent = $entity_wrapper;
|
||||
foreach ($email_property_array as $drupal_field) {
|
||||
if ($parent instanceof EntityListWrapper) {
|
||||
$child_wrapper = $parent->get(0)->{$drupal_field};
|
||||
}
|
||||
else {
|
||||
$child_wrapper = $parent->{$drupal_field};
|
||||
}
|
||||
$parent = $child_wrapper;
|
||||
}
|
||||
$email = $parent->value();
|
||||
// Validate email address.
|
||||
if (!valid_email_address($email)) {
|
||||
return array(
|
||||
'error_notice' => array(
|
||||
'#markup' => t('%email does not contain a valid email address. Unable to lookup Mandrill activity history without a valid email.',
|
||||
array('%email' => $email_property)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$header = array(
|
||||
t('Subject'),
|
||||
t('Timestamp'),
|
||||
t('State'),
|
||||
t('Opens'),
|
||||
t('Clicks'),
|
||||
t('Tags'),
|
||||
);
|
||||
$rows = array();
|
||||
|
||||
// Loop through all activities, creating rows for each.
|
||||
$activity = mandrill_activity_get_activity($email);
|
||||
foreach ($activity as $sent_email) {
|
||||
$rows[] = array(
|
||||
$sent_email['subject'],
|
||||
format_date($sent_email['ts'], 'short'),
|
||||
$sent_email['state'],
|
||||
$sent_email['opens'],
|
||||
$sent_email['clicks'],
|
||||
implode(', ', $sent_email['tags']),
|
||||
);
|
||||
}
|
||||
|
||||
$display['mandrill_activity'] = array(
|
||||
'message' => array(
|
||||
'#markup' => t('The 100 most recent Emails sent to %email via Mandrill.', array('%email' => $email)),
|
||||
),
|
||||
'activity' => array(
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
),
|
||||
);
|
||||
|
||||
return $display;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return all activity on all lists for a given email address.
|
||||
*
|
||||
* @string $email
|
||||
* Email to load Mandrill activity for.
|
||||
*
|
||||
* @return array
|
||||
* Array of activity.
|
||||
*/
|
||||
function mandrill_activity_get_activity($email) {
|
||||
$mandrill = mandrill_get_api_object();
|
||||
return $mandrill->messages_search("email:{$email}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function mandrill_activity_permission() {
|
||||
$return = array();
|
||||
|
||||
$return['access mandrill activity'] = array(
|
||||
'title' => t('Access Mandrill activity'),
|
||||
'description' => t('View own Mandrill activity history.'),
|
||||
);
|
||||
$return['administer mandrill activity'] = array(
|
||||
'title' => t('Administer Mandrill activity entities'),
|
||||
'description' => t('Add, Delete, and Configure Mandrill Activity entity settings.'),
|
||||
);
|
||||
return $return;
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
name = Mandrill Reports
|
||||
description = "Providing reporting on activity through Mandrill."
|
||||
core = 7.x
|
||||
package = MailChimp
|
||||
|
||||
dependencies[] = mandrill
|
||||
|
||||
; Information added by Drupal.org packaging script on 2014-05-09
|
||||
version = "7.x-1.6"
|
||||
core = "7.x"
|
||||
project = "mandrill"
|
||||
datestamp = "1399658028"
|
||||
|
@@ -0,0 +1,50 @@
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.mandrill_reports = {
|
||||
attach: function (context, settings) {
|
||||
google.load("visualization", "1", {packages:["corechart"], "callback":drawCharts});
|
||||
|
||||
function drawCharts() {
|
||||
var dataTableVol = new google.visualization.DataTable();
|
||||
dataTableVol.addColumn('datetime', Drupal.t('Date'));
|
||||
dataTableVol.addColumn('number', Drupal.t('Delivered'));
|
||||
dataTableVol.addColumn('number', Drupal.t('Bounced'));
|
||||
dataTableVol.addColumn('number', Drupal.t('Rejected'));
|
||||
|
||||
for (var key in settings.mandrill_reports.volume) {
|
||||
dataTableVol.addRow([
|
||||
new Date(settings.mandrill_reports.volume[key]['date']),
|
||||
settings.mandrill_reports.volume[key]['sent'],
|
||||
settings.mandrill_reports.volume[key]['bounced'],
|
||||
settings.mandrill_reports.volume[key]['rejected']
|
||||
]);
|
||||
}
|
||||
|
||||
var options = {
|
||||
pointSize: 5,
|
||||
hAxis: {format: 'MM/dd/y hh:mm aaa'}
|
||||
};
|
||||
|
||||
var chart = new google.visualization.LineChart(document.getElementById('mandrill-volume-chart'));
|
||||
chart.draw(dataTableVol, options);
|
||||
|
||||
var dataTableEng = new google.visualization.DataTable();
|
||||
dataTableEng.addColumn('datetime', Drupal.t('Date'));
|
||||
dataTableEng.addColumn('number', Drupal.t('Open rate'));
|
||||
dataTableEng.addColumn('number', Drupal.t('Click rate'));
|
||||
|
||||
for (var key in settings.mandrill_reports.engagement) {
|
||||
dataTableEng.addRow([
|
||||
new Date(settings.mandrill_reports.engagement[key]['date']),
|
||||
settings.mandrill_reports.engagement[key]['open_rate'],
|
||||
settings.mandrill_reports.engagement[key]['click_rate']
|
||||
]);
|
||||
}
|
||||
|
||||
var chart = new google.visualization.LineChart(document.getElementById('mandrill-engage-chart'));
|
||||
chart.draw(dataTableEng, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Main module functions for mandrill_reports.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function mandrill_reports_menu() {
|
||||
$items = array();
|
||||
$items['admin/reports/mandrill'] = array(
|
||||
'title' => 'Mandrill',
|
||||
'page callback' => 'mandrill_reports_dashboard_page',
|
||||
'access arguments' => array('view mandrill reports'),
|
||||
'description' => 'View Mandrill dashboard.',
|
||||
);
|
||||
$items['admin/reports/mandrill/dashboard'] = array(
|
||||
'title' => 'Dashboard',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => -10,
|
||||
);
|
||||
$items['admin/reports/mandrill/summary'] = array(
|
||||
'title' => 'Account summary',
|
||||
'page callback' => 'mandrill_reports_summary_page',
|
||||
'access arguments' => array('view mandrill reports'),
|
||||
'description' => 'View account summary.',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function mandrill_reports_permission() {
|
||||
return array(
|
||||
'view mandrill reports' => array(
|
||||
'title' => t('View Mandrill reports'),
|
||||
'description' => t('View all Mandrill reports.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an associative array containing raw stats.
|
||||
*
|
||||
* @return array
|
||||
* Associative array containing report data.
|
||||
*/
|
||||
function mandrill_reports_data() {
|
||||
if ($cache = cache_get('mandrill_report_data')) {
|
||||
return $cache->data;
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$api = mandrill_get_api_object();
|
||||
|
||||
if ($api) {
|
||||
// Basic user info.
|
||||
$data['user'] = $api->users_info();
|
||||
|
||||
// Tags.
|
||||
$tags = $api->tags_list();
|
||||
foreach ($tags as $tag) {
|
||||
if (!empty($tag['tag'])) {
|
||||
$data['tags'][$tag['tag']] = $api->tags_info($tag['tag']);
|
||||
$data['tags'][$tag['tag']]['time_series'] = $api->tags_time_series($tag['tag']);
|
||||
}
|
||||
}
|
||||
|
||||
// All time.
|
||||
$data['all_time_series'] = $api->tags_all_time_series();
|
||||
|
||||
// Senders: data is not being used, and the API currently (3/12/13) behaves
|
||||
// badly if you have a bad email address anywhere in your sender history, so
|
||||
// commenting out for now:
|
||||
$senders = $api->senders_list();
|
||||
foreach ($senders as $sender) {
|
||||
try {
|
||||
$data['senders'][$sender['address']] = $api->senders_info($sender['address']);
|
||||
$data['senders'][$sender['address']]['time_series'] = $api->senders_time_series($sender['address']);
|
||||
}
|
||||
catch (MandrillException $e) {
|
||||
watchdog('mandrill', 'An error occurred requesting sender information from Mandrill for address %address. "%message"', array(
|
||||
'%address' => $sender['address'],
|
||||
'%message' => $e->getMessage(),
|
||||
), WATCHDOG_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// Urls.
|
||||
$urls = $api->urls_list();
|
||||
foreach ($urls as $url) {
|
||||
// Api has been intermittently tacking on incomplete $url arrays,
|
||||
// so we have to check validity first:
|
||||
if (isset($url['url'])) {
|
||||
$data['urls'][$url['url']] = $url;
|
||||
$data['urls'][$url['url']]['time_series'] = $api->urls_time_series($url['url']);
|
||||
}
|
||||
}
|
||||
cache_set('mandrill_report_data', $data, 'cache', CACHE_TEMPORARY);
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Please enter a Mandrill API key to use reports.'));
|
||||
drupal_goto('admin/config/services/mandrill');
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback for rendering stats.
|
||||
*
|
||||
* @return array
|
||||
* Render array.
|
||||
*/
|
||||
function mandrill_reports_dashboard_page() {
|
||||
$data = mandrill_reports_data();
|
||||
$settings = array();
|
||||
// All time series chart data.
|
||||
foreach ($data['all_time_series'] as $series) {
|
||||
$settings['mandrill_reports']['volume'][] = array(
|
||||
'date' => $series['time'],
|
||||
'sent' => $series['sent'],
|
||||
'bounced' => $series['hard_bounces'] + $series['soft_bounces'],
|
||||
'rejected' => $series['rejects'],
|
||||
);
|
||||
$settings['mandrill_reports']['engagement'][] = array(
|
||||
'date' => $series['time'],
|
||||
'open_rate' => $series['sent'] == 0 ? 0 : $series['unique_opens'] / $series['sent'],
|
||||
'click_rate' => $series['sent'] == 0 ? 0 : $series['unique_clicks'] / $series['sent'],
|
||||
);
|
||||
}
|
||||
|
||||
// Url table.
|
||||
$rows = array();
|
||||
$header = array(
|
||||
t('URL'),
|
||||
t('Delivered'),
|
||||
t('Unique clicks'),
|
||||
t('Total Clicks'),
|
||||
);
|
||||
foreach ($data['urls'] as $url) {
|
||||
$percent = number_format($url['unique_clicks'] / $url['sent'], 2) * 100;
|
||||
$rows[] = array(
|
||||
l($url['url'], $url['url']),
|
||||
$url['sent'],
|
||||
$url['unique_clicks'] . "({$percent}%)",
|
||||
$url['clicks']);
|
||||
}
|
||||
|
||||
$path = drupal_get_path('module', 'mandrill_reports');
|
||||
$render = array(
|
||||
'#attached' => array(
|
||||
'js' => array(
|
||||
array(
|
||||
'data' => 'https://www.google.com/jsapi',
|
||||
'type' => 'external',
|
||||
),
|
||||
$path . '/mandrill_reports.js',
|
||||
array(
|
||||
'data' => $settings,
|
||||
'type' => 'setting',
|
||||
),
|
||||
),
|
||||
),
|
||||
'message' => array(
|
||||
'#markup' => t(
|
||||
'The following reports are based on Mandrill data from the last 30 days. For more comprehensive data, please visit your !dashboard. !cache to ensure the data is current.',
|
||||
array(
|
||||
'!dashboard' => l(t('Mandrill Dashboard'), 'https://mandrillapp.com/'),
|
||||
'!cache' => l(t('Clear your cache'), 'admin/config/development/performance'),
|
||||
)
|
||||
),
|
||||
),
|
||||
'volume' => array(
|
||||
'#prefix' => '<h2>' . t('Sending Volume') . '</h2>',
|
||||
'#markup' => '<div id="mandrill-volume-chart"></div>',
|
||||
),
|
||||
'engagement' => array(
|
||||
'#prefix' => '<h2>' . t('Average Open and Click Rate') . '</h2>',
|
||||
'#markup' => '<div id="mandrill-engage-chart"></div>',
|
||||
),
|
||||
'urls' => array(
|
||||
'#prefix' => '<h2>' . t('Tracked URLs') . '</h2>',
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
),
|
||||
);
|
||||
|
||||
return $render;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays summary information for the active API user.
|
||||
*/
|
||||
function mandrill_reports_summary_page() {
|
||||
$data = mandrill_reports_data();
|
||||
$info = $data['user'];
|
||||
|
||||
$header = array(
|
||||
t('Range'),
|
||||
t('Sent'),
|
||||
t('hard_bounces'),
|
||||
t('soft_bounces'),
|
||||
t('Rejects'),
|
||||
t('Complaints'),
|
||||
t('Unsubs'),
|
||||
t('Opens'),
|
||||
t('unique_opens'),
|
||||
t('Clicks'),
|
||||
t('unique_clicks'),
|
||||
);
|
||||
|
||||
$rows = array();
|
||||
foreach ($info['stats'] as $key => $stat) {
|
||||
$rows[] = array(
|
||||
str_replace('_', ' ', $key),
|
||||
$stat['sent'],
|
||||
$stat['hard_bounces'],
|
||||
$stat['soft_bounces'],
|
||||
$stat['rejects'],
|
||||
$stat['complaints'],
|
||||
$stat['unsubs'],
|
||||
$stat['opens'],
|
||||
$stat['unique_opens'],
|
||||
$stat['clicks'],
|
||||
$stat['unique_clicks'],
|
||||
);
|
||||
}
|
||||
|
||||
$render = array(
|
||||
'info' => array(
|
||||
'#theme' => 'table',
|
||||
'#rows' => array(
|
||||
array(t('Username'), $info['username']),
|
||||
array(t('Reputation'), $info['reputation']),
|
||||
array(t('Hourly quota'), $info['hourly_quota']),
|
||||
array(t('Backlog'), $info['backlog']),
|
||||
),
|
||||
'#header' => array(t('Attribute'), t('Value')),
|
||||
'#caption' => t('Active API user information.'),
|
||||
),
|
||||
'stats' => array(
|
||||
'#theme' => 'table',
|
||||
'#rows' => $rows,
|
||||
'#header' => $header,
|
||||
'#caption' => t("This table contains an aggregate summary of the account's sending stats."),
|
||||
),
|
||||
);
|
||||
|
||||
return $render;
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Mandrill Template entity class
|
||||
*/
|
||||
|
||||
class MandrillTemplateMap extends Entity {
|
||||
public
|
||||
$mandrill_template_map_entity_id,
|
||||
$name,
|
||||
$label,
|
||||
$mailsystem_key,
|
||||
$template_id,
|
||||
$main_section,
|
||||
$sections;
|
||||
|
||||
/**
|
||||
* Return a new entity instance of type mandrill_template_map.
|
||||
*/
|
||||
public function __construct(array $values = array()) {
|
||||
parent::__construct($values, 'mandrill_template_map');
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify URI.
|
||||
*/
|
||||
protected function defaultUri() {
|
||||
return array('path' => 'admin/config/services/mandrill/templates/' . $this->identifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the arguments that are required for sending templates.
|
||||
*
|
||||
* @return array
|
||||
* An associative array containing message template arguments.
|
||||
*/
|
||||
public function message_send_arguments($message) {
|
||||
return array(
|
||||
'id' => $this->template_id,
|
||||
'template_content' => array(
|
||||
'0' => array(
|
||||
'name' => $this->main_section,
|
||||
'content_postprocess' => 'html',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* The UI controller for the template map entity.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Override EntityDefaultUIController to customize our menu items.
|
||||
*/
|
||||
class MandrillTemplateMapUIController extends EntityDefaultUIController {
|
||||
|
||||
/**
|
||||
* Overrides EntityDefaultUIController::hook_menu().
|
||||
*/
|
||||
public function hook_menu() {
|
||||
$items = parent::hook_menu();
|
||||
$items[$this->path]['description'] = 'Manage Mandrill Template Mapping entity settings.';
|
||||
$items[$this->path]['type'] = MENU_LOCAL_TASK;
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides EntityDefaultUIController::overviewTableHeaders().
|
||||
*/
|
||||
protected function overviewTableHeaders($conditions, $rows, $additional_header = array()) {
|
||||
$additional_header[] = t('Mandrill Template');
|
||||
$additional_header[] = t('Primary Content Zone');
|
||||
$additional_header[] = t('In Use By');
|
||||
$header = parent::overviewTableHeaders($conditions, $rows, $additional_header);
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides EntityDefaultUIController::overviewTableRow().
|
||||
*/
|
||||
protected function overviewTableRow($conditions, $id, $entity, $additional_cols = array()) {
|
||||
$additional_cols[] = $entity->template_id;
|
||||
$additional_cols[] = $entity->main_section;
|
||||
$additional_cols[] = $entity->mailsystem_key;
|
||||
return parent::overviewTableRow($conditions, $id, $entity, $additional_cols);
|
||||
}
|
||||
}
|
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Administrative forms for Mandrill Template module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return a form for adding/editing a Mandrill template map.
|
||||
*/
|
||||
function mandrill_template_map_form($form, &$form_state, MandrillTemplateMap $map = NULL, $op = 'edit') {
|
||||
$form_state['op'] = $op;
|
||||
if ($form_state['op'] == 'clone') {
|
||||
$map->label .= ' (cloned)';
|
||||
$map->name = '';
|
||||
}
|
||||
// Store the existing map for updating on submit.
|
||||
if (isset($map)) {
|
||||
$form_state['map'] = $map;
|
||||
}
|
||||
else {
|
||||
$form_state['op'] = 'add';
|
||||
}
|
||||
|
||||
$form['label'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Label'),
|
||||
'#description' => t('The name of this Template Mapping.'),
|
||||
'#size' => 35,
|
||||
'#maxlength' => 32,
|
||||
'#default_value' => $map ? $map->label : '',
|
||||
'#required' => TRUE,
|
||||
);
|
||||
|
||||
// Machine-readable list name.
|
||||
$form['name'] = array(
|
||||
'#type' => 'machine_name',
|
||||
'#default_value' => isset($map->name) ? $map->name : '',
|
||||
'#maxlength' => 32,
|
||||
'#machine_name' => array(
|
||||
'exists' => 'mandrill_template_map_load_entities',
|
||||
'source' => array('label'),
|
||||
),
|
||||
'#description' => t('A unique machine-readable name for this template map. It must only contain lowercase letters, numbers, and underscores.'),
|
||||
);
|
||||
|
||||
$form['map_settings'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Template Map Settings'),
|
||||
'#collapsible' => FALSE,
|
||||
'#attributes' => array(
|
||||
'id' => array('mandrill-template-mapping'),
|
||||
),
|
||||
);
|
||||
|
||||
$templates = mandrill_get_templates();
|
||||
$template_names = array();
|
||||
foreach ($templates as $template) {
|
||||
$template_names[$template['slug']] = $template;
|
||||
}
|
||||
// Check if the currently configured template still exists.
|
||||
if (!empty($map->template_id) && !array_key_exists($map->template_id, $template_names)) {
|
||||
drupal_set_message(t('The configured Mandrill template is no longer available, please select a valid one.'), 'warning');
|
||||
}
|
||||
if (!empty($templates)) {
|
||||
$options = array('' => t('-- Select --'));
|
||||
foreach ($templates as $template) {
|
||||
$options[$template['slug']] = $template['name'];
|
||||
}
|
||||
$form['map_settings']['template_id'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Email Template'),
|
||||
'#description' => t('Select a Mandrill template.'),
|
||||
'#options' => $options,
|
||||
'#default_value' => isset($map->template_id) ? $map->template_id : '',
|
||||
'#required' => TRUE,
|
||||
'#ajax' => array(
|
||||
'callback' => 'mandrill_template_map_form_callback',
|
||||
'wrapper' => 'mandrill-template-mapping',
|
||||
),
|
||||
);
|
||||
$form_template_id = & $form_state['values']['template_id'];
|
||||
|
||||
if (!$form_template_id && isset($map->mandrill_template_map_entity_id)) {
|
||||
$form_template_id = $map->template_id;
|
||||
}
|
||||
|
||||
if ($form_template_id) {
|
||||
$regions = array('' => t('-- Select --')) + _mandrill_parse_regions($template_names[$form_template_id]['publish_code']);
|
||||
$form['map_settings']['main_section'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Template region'),
|
||||
'#description' => t('Select the template region to use for email content. <i>Note that you can populate more regions by attaching an array to your message with the index "mandrill_template_content", using region names as indexes to the content for that region.'),
|
||||
'#options' => $regions,
|
||||
'#default_value' => isset($map->main_section) ? $map->main_section : '',
|
||||
'#required' => TRUE,
|
||||
);
|
||||
}
|
||||
$usable_keys = mandrill_template_map_usage();
|
||||
$module_names = mandrill_get_module_key_names();
|
||||
$mandrill_in_use = FALSE;
|
||||
$available_modules = FALSE;
|
||||
$mailsystem_options = array('' => t('-- None --'));
|
||||
foreach ($usable_keys as $key => $sys) {
|
||||
$mandrill_in_use = TRUE;
|
||||
if ($sys === NULL || (isset($map) && $sys == $map->mandrill_template_map_entity_id)) {
|
||||
$mailsystem_options[$key] = $module_names[$key];
|
||||
$available_modules = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ($mandrill_in_use) {
|
||||
$form['mailsystem_key'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Email key'),
|
||||
'#description' => t(
|
||||
'Select a module and mail key to use this template for outgoing email. Note that if an email has been selected in another Template Mapping, it will not appear in this list. These keys are defined through the !MailSystem interface.',
|
||||
array('!MailSystem' => l(t('MailSystem'), 'admin/config/system/mailsystem'))
|
||||
),
|
||||
'#options' => $mailsystem_options,
|
||||
'#default_value' => isset($map->mailsystem_key) ? $map->mailsystem_key : '',
|
||||
);
|
||||
if (!$available_modules) {
|
||||
drupal_set_message(t("All email-using modules that have been assigned to Mandrill are already assigned to other template maps"), 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$mandrill_in_use) {
|
||||
drupal_set_message(t("You have not assigned any Modules to use Mandrill: to use this template, make sure Mandrill is assigned in Mailsystem."), 'warning');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form['email_options']['#description'] = t('The template selection is only available if the Mandrill API is correctly configured and available.');
|
||||
}
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
);
|
||||
$form['actions']['cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Cancel'),
|
||||
'#href' => 'admin/config/services/mandrill/templates',
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate handler for mandrill_template_map().
|
||||
*/
|
||||
function mandrill_template_map_form_validate($form, &$form_state) {
|
||||
$values = $form_state['values'];
|
||||
// Test to see if mandrill_template_map value will exceed row length of 255
|
||||
// characters
|
||||
if (strlen($values['mailsystem_key']) > 255) {
|
||||
form_set_error('mailsystem_key', t('The length of the mailsytem_key name is too long.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for mandrill_template_map(), creates the entity.
|
||||
*/
|
||||
function mandrill_template_map_form_submit($form, &$form_state) {
|
||||
$values = $form_state['values'];
|
||||
if ($form_state['op'] == 'add' || $form_state['op'] == 'clone') {
|
||||
$map = entity_create('mandrill_template_map', $values);
|
||||
}
|
||||
else {
|
||||
$map = $form_state['mandrill_template_map'];
|
||||
foreach ($values as $key => $val) {
|
||||
$map->{$key} = $val;
|
||||
}
|
||||
}
|
||||
$map->save();
|
||||
drupal_set_message(t('Mandrill template mapping saved.'));
|
||||
$form_state['redirect'] = 'admin/config/services/mandrill/templates';
|
||||
}
|
||||
|
||||
/**
|
||||
* Javascript callback for the mandrill_template_map_form.
|
||||
*/
|
||||
function mandrill_template_map_form_callback($form, &$form_state) {
|
||||
return $form['map_settings'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a Mandrill template to extract its regions.
|
||||
*
|
||||
* The Mandrill API does not provide an elegant data structure
|
||||
* containing the mc:edit tags for a given template, but rather
|
||||
* a big pile of ugly HTML containing the tags. We need to parse
|
||||
* through it.
|
||||
*/
|
||||
function _mandrill_parse_regions($html, $tag = 'mc:edit') {
|
||||
$instances = array();
|
||||
$offset = 0;
|
||||
$inst = NULL;
|
||||
while ($offset = strpos($html, $tag, $offset)) {
|
||||
$start = 1 + strpos($html, '"', $offset);
|
||||
$length = strpos($html, '"', $start) - $start;
|
||||
$inst = substr($html, $start, $length);
|
||||
$instances[$inst] = $inst;
|
||||
$offset = $start + $length;
|
||||
}
|
||||
return $instances;
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
name = Mandrill Template
|
||||
description = "Use Mandrill templates for messages sent through Mandrill."
|
||||
core = 7.x
|
||||
package = MailChimp
|
||||
|
||||
configure = admin/config/services/mandrill/templates
|
||||
|
||||
dependencies[] = entity (>=1.0)
|
||||
dependencies[] = mandrill
|
||||
|
||||
files[] = lib/mandrill_template_map.entity.inc
|
||||
files[] = lib/mandrill_template_map.ui_controller.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2014-05-09
|
||||
version = "7.x-1.6"
|
||||
core = "7.x"
|
||||
project = "mandrill"
|
||||
datestamp = "1399658028"
|
||||
|
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the mandrill_template module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function mandrill_template_schema() {
|
||||
$schema['mandrill_template_map'] = array(
|
||||
'description' => 'The base table for the mandrill template module.',
|
||||
'fields' => array(
|
||||
'mandrill_template_map_entity_id' => array(
|
||||
'description' => 'The primary identifier for a mandrill_template_map.',
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'name' => array(
|
||||
'description' => 'The name of this mandrill_template_map',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'label' => array(
|
||||
'description' => 'The label for this mandrill_template_map',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'mailsystem_key' => array(
|
||||
'description' => 'The mailsystem_key that is using this mandrill_template_map.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'default' => '',
|
||||
),
|
||||
'template_id' => array(
|
||||
'description' => 'The unique identifier of the Mandrill Template this mapping uses.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'main_section' => array(
|
||||
'description' => 'The name of the section where primary email content should go.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'author_uid' => array(
|
||||
'description' => 'The uid of the user who created this mandrill_template_map.',
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'sections' => array(
|
||||
'description' => 'An array of content sections for the template.',
|
||||
'type' => 'blob',
|
||||
'size' => 'big',
|
||||
'not null' => TRUE,
|
||||
'serialize' => TRUE,
|
||||
),
|
||||
'created' => array(
|
||||
'description' => 'The Unix timestamp when the mandrill_template_map was created.',
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'updated' => array(
|
||||
'description' => 'The Unix timestamp when the mandrill_template_map was most recently saved.',
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
// Following fields are for supporting exportable status.
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
// Set the default to ENTITY_CUSTOM without using the constant as it is
|
||||
// not safe to use it at this point.
|
||||
'default' => 0x01,
|
||||
'size' => 'tiny',
|
||||
'description' => 'The exportable status of the entity.',
|
||||
),
|
||||
'module' => array(
|
||||
'description' => 'The name of the providing module if the entity has been defined in code.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'mandrill_template_map_updated' => array('updated'),
|
||||
'mandrill_template_map_created' => array('created'),
|
||||
'mandrill_template_map_author' => array('author_uid'),
|
||||
),
|
||||
'unique keys' => array(
|
||||
'mandrill_template_map_entity_id' => array('mandrill_template_map_entity_id'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'mandrill_template_map_author' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('author_uid' => 'uid'),
|
||||
),
|
||||
),
|
||||
'primary key' => array('mandrill_template_map_entity_id'),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the mailsystem_key field to support longer template key names.
|
||||
*/
|
||||
function mandrill_template_update_7001() {
|
||||
db_change_field('mandrill_template_map', 'mailsystem_key', 'mailsystem_key',
|
||||
array(
|
||||
'description' => 'The mailsystem_key that is using this mandrill_template_map.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'default' => '',
|
||||
)
|
||||
);
|
||||
}
|
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Enables Drupal to send email using Mandrill's template system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info().
|
||||
*/
|
||||
function mandrill_template_entity_info() {
|
||||
$return = array(
|
||||
'mandrill_template_map' => array(
|
||||
'label' => t('Mandrill Template Map'),
|
||||
'plural label' => t('Mandrill Template Maps'),
|
||||
'controller class' => 'EntityAPIControllerExportable',
|
||||
'entity class' => 'MandrillTemplateMap',
|
||||
'base table' => 'mandrill_template_map',
|
||||
'uri callback' => 'entity_class_uri',
|
||||
'fieldable' => FALSE,
|
||||
'exportable' => TRUE,
|
||||
'module' => 'mandrill_template',
|
||||
'access callback' => 'mandrill_template_map_access',
|
||||
'entity keys' => array(
|
||||
'id' => 'mandrill_template_map_entity_id',
|
||||
'label' => 'label',
|
||||
'name' => 'name',
|
||||
),
|
||||
'admin ui' => array(
|
||||
'path' => 'admin/config/services/mandrill/templates',
|
||||
'file' => 'mandrill_template.admin.inc',
|
||||
'controller class' => 'MandrillTemplateMapUIController',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback for mandrill_template_map.
|
||||
*
|
||||
* @return bool
|
||||
* True if current user has acces to template maps, else false
|
||||
*/
|
||||
function mandrill_template_map_access() {
|
||||
$a = user_access('configure mandrill templates');
|
||||
$b = variable_get('mandrill_api_key');
|
||||
return $a & !empty($b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function mandrill_template_permission() {
|
||||
return array(
|
||||
'configure mandrill templates' => array(
|
||||
'title' => t('Configure Mandrill Templates'),
|
||||
'description' => t('Select & configure which Mandrill Templates to use for messages going through Mandrill.'),
|
||||
"restrict access" => FALSE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a single mandrill_template_map or all of them if no name provided.
|
||||
*
|
||||
* @param null $name
|
||||
* name of the template map entity
|
||||
*
|
||||
* @return array
|
||||
* array of template_map entities
|
||||
*/
|
||||
function mandrill_template_map_load_entities($name = NULL) {
|
||||
$maps = entity_load_multiple_by_name('mandrill_template_map', isset($name) ? array($name) : FALSE);
|
||||
return isset($name) ? reset($maps) : $maps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells you which template_map is configured for a mailsystem key, if any.
|
||||
*
|
||||
* Will search for a default-system mapping if none is availble for a given key.
|
||||
*
|
||||
* @param string $mailsystem
|
||||
* Mail key to search for a template mapping.
|
||||
*
|
||||
* @return entity
|
||||
* Mandrill template map.
|
||||
*/
|
||||
function mandrill_template_map_load_by_mailsystem($mailsystem) {
|
||||
// Append the default-system condition as a fallback.
|
||||
$params = array($mailsystem, 'default-system');
|
||||
$query = new EntityFieldQuery();
|
||||
$query_result = $query
|
||||
->entityCondition('entity_type', 'mandrill_template_map')
|
||||
->propertyCondition('mailsystem_key', $params, 'IN')
|
||||
->execute();
|
||||
|
||||
if (!empty($query_result['mandrill_template_map'])) {
|
||||
$template_maps = entity_load('mandrill_template_map', array_keys($query_result['mandrill_template_map']));
|
||||
if (count($template_maps) > 1) {
|
||||
foreach ($template_maps as $template_map) {
|
||||
if ($template_map->mailsystem_key == $mailsystem) {
|
||||
return $template_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return reset($template_maps);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all mailsystem keys pointed at mandrill and their template mappings.
|
||||
*
|
||||
* @return array
|
||||
* Returns an array with indexes matching each module which is assigned
|
||||
* to use Mandrill for email sends, and values equal to the template_map_ids
|
||||
* that are assigned to those modules. If no template maps are assigned, the
|
||||
* value is set to NULL.
|
||||
*/
|
||||
function mandrill_template_map_usage() {
|
||||
$system_assignments = mailsystem_get();
|
||||
// Filter out the systems that aren't using Mandrill:
|
||||
foreach ($system_assignments as $system => $assignment) {
|
||||
if ($assignment != 'MandrillMailSystem') {
|
||||
unset($system_assignments[$system]);
|
||||
}
|
||||
else {
|
||||
$system_assignments[$system] = NULL;
|
||||
}
|
||||
}
|
||||
$maps = mandrill_template_map_load_entities();
|
||||
foreach ($maps as $map) {
|
||||
if (isset($map->mailsystem_key) && array_key_exists($map->mailsystem_key, $system_assignments)) {
|
||||
$system_assignments[$map->mailsystem_key] = $map->mandrill_template_map_entity_id;
|
||||
}
|
||||
}
|
||||
uksort($system_assignments, '_mandrill_template_map_mailsystem_sort');
|
||||
return $system_assignments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_mandrill_mail_alter().
|
||||
*
|
||||
* Determine if an email is configured to use a Mandrill template and change the
|
||||
* mandrill_send_function parameter as needed.
|
||||
*/
|
||||
function mandrill_template_mandrill_mail_alter(&$mandrill_params, $message) {
|
||||
$template_map = mandrill_template_map_load_by_mailsystem($message['id']);
|
||||
if ($template_map) {
|
||||
$mandrill_params['function'] = 'mandrill_template_sender';
|
||||
$mandrill_params['args'] = array(
|
||||
'template_id' => $template_map->template_id,
|
||||
'template_content' => array(
|
||||
array(
|
||||
'name' => $template_map->main_section,
|
||||
'content' => $message['body'],
|
||||
),
|
||||
),
|
||||
);
|
||||
if (isset($message['mandrill_template_content'])) {
|
||||
$mandrill_params['args']['template_content'] = array_merge($message['mandrill_template_content'], $mandrill_params['args']['template_content']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a templated Mandrill message.
|
||||
*
|
||||
* This function checks for appropriate settings in the message, then uses the
|
||||
* template API call to send the message if the settings are valid.
|
||||
*
|
||||
* @param array $message
|
||||
* Mandrill message to send.
|
||||
* @param string $template_id
|
||||
* Name of the template to use.
|
||||
* @param array $template_content
|
||||
* Associative array mapping template regions and content.
|
||||
*
|
||||
* @return array
|
||||
* Message response.
|
||||
*
|
||||
* @throws MandrillException
|
||||
*/
|
||||
function mandrill_template_sender($message, $template_id, $template_content) {
|
||||
if ($mailer = mandrill_get_api_object()) {
|
||||
return $mailer->messages_send_template($template_id, $template_content, $message);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple sorting algorithm to organize mailsystems arrays in a logical way.
|
||||
*
|
||||
* @param string $a
|
||||
* a mailsystem key name
|
||||
* @param string $b
|
||||
* a mailsystem key name
|
||||
*
|
||||
* @return int
|
||||
* Negative if $a should come before $b, else positive.
|
||||
*/
|
||||
function _mandrill_template_map_mailsystem_sort($a, $b) {
|
||||
$first = "default-system";
|
||||
$last = "mandrill_test";
|
||||
if ($a == $first || $b == $last) {
|
||||
return -1;
|
||||
}
|
||||
if ($b == $first || $a == $last) {
|
||||
return 1;
|
||||
}
|
||||
// Otherwise sort alphabetically, case-agnostic
|
||||
return strcasecmp($a, $b);
|
||||
}
|
Reference in New Issue
Block a user