1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024 |
- <?php
- /**
- * @file
- * Contains SimplenewsSource interface and implementations.
- */
- /**
- * The source used to build a newsletter mail.
- *
- * @ingroup source
- */
- interface SimplenewsSourceInterface {
- /**
- * Returns the mail headers.
- *
- * @param $headers
- * The default mail headers.
- *
- * @return
- * Mail headers as an array.
- */
- function getHeaders(array $headers);
- /**
- * Returns the mail subject.
- */
- function getSubject();
- /**
- * Returns the mail body.
- *
- * The body should either be plaintext or html, depending on the format.
- */
- function getBody();
- /**
- * Returns the plaintext body.
- */
- function getPlainBody();
- /**
- * Returns the mail footer.
- *
- * The footer should either be plaintext or html, depending on the format.
- */
- function getFooter();
- /**
- * Returns the plain footer.
- */
- function getPlainFooter();
- /**
- * Returns the mail format.
- *
- * @return
- * The mail format as string, either 'plain' or 'html'.
- */
- function getFormat();
- /**
- * Returns the recipent of this newsletter mail.
- *
- * @return
- * The recipient mail address(es) of this newsletter as a string.
- */
- function getRecipient();
- /**
- * The language that should be used for this newsletter mail.
- */
- function getLanguage();
- /**
- * Returns an array of attachments for this newsletter mail.
- *
- * @return
- * An array of managed file objects with properties uri, filemime and so on.
- */
- function getAttachments();
- /**
- * Returns the token context to be used with token replacements.
- *
- * @return
- * An array of objects as required by token_replace().
- */
- function getTokenContext();
- /**
- * Returns the mail key to be used for drupal_mail().
- *
- * @return
- * The mail key, either test or node.
- */
- function getKey();
- /**
- * Returns the formatted from mail address.
- */
- function getFromFormatted();
- /**
- * Returns the plain mail address.
- */
- function getFromAddress();
- }
- /**
- * Source interface based on a node.
- *
- * This is the interface that needs to be implemented to be compatible with
- * the default simplenews spool implementation and therefore exposed in
- * hook_simplenews_source_cache_info().
- *
- * @ingroup source
- */
- interface SimplenewsSourceNodeInterface extends SimplenewsSourceInterface {
- /**
- * Create a source based on a node and subscriber.
- */
- function __construct($node, $subscriber);
- /**
- * Returns the actually used node of this source.
- */
- function getNode();
- /**
- * Returns the subscriber object.
- */
- function getSubscriber();
- }
- /**
- * Interface for a simplenews source cache implementation.
- *
- * This is only compatible with the SimplenewsSourceNodeInterface interface.
- *
- * @ingroup source
- */
- interface SimplenewsSourceCacheInterface {
- /**
- * Create a new instance, allows to initialize based on the used
- * source.
- */
- function __construct(SimplenewsSourceNodeInterface $source);
- /**
- * Return a cached element, if existing.
- *
- * Although group and key can be used to identify the requested cache, the
- * implementations are responsible to create a unique cache key themself using
- * the $source. For example based on the node id and the language.
- *
- * @param $group
- * Group of the cache key, which allows cache implementations to decide what
- * they want to cache. Currently used groups:
- * - data: Raw data, e.g. attachments.
- * - build: Built and themed content, before personalizations like tokens.
- * - final: The final returned data. Caching this means that newsletter
- * can not be personalized anymore.
- * @param $key
- * Identifies the requested element, e.g. body, footer or attachments.
- */
- function get($group, $key);
- /**
- * Write an element to the cache.
- *
- * Although group and key can be used to identify the requested cache, the
- * implementations are responsible to create a unique cache key themself using
- * the $source. For example based on the node id and the language.
- *
- * @param $group
- * Group of the cache key, which allows cache implementations to decide what
- * they want to cache. Currently used groups:
- * - data: Raw data, e.g. attachments.
- * - build: Built and themed content, before personalizations like tokens.
- * - final: The final returned data. Caching this means that newsletter
- * can not be personalized anymore.
- * @param $key
- * Identifies the requested element, e.g. body, footer or attachments.
- * @param $data
- * The data to be saved in the cache.
- */
- function set($group, $key, $data);
- }
- /**
- * A Simplenews spool implementation is a factory for Simplenews sources.
- *
- * Their main functionility is to return a number of sources based on the passed
- * in array of mail spool rows. Additionally, it needs to return the processed
- * mail rows after a source was sent.
- *
- * @todo: Move spool functions into this interface.
- *
- * @ingroup spool
- */
- interface SimplenewsSpoolInterface {
- /**
- * Initalizes the spool implementation.
- *
- * @param $spool_list
- * An array of rows from the {simplenews_mail_spool} table.
- */
- function __construct($pool_list);
- /**
- * Returns a Simplenews source to be sent.
- *
- * A single source may represent any number of mail spool rows, e.g. by
- * addressing them as BCC.
- */
- function nextSource();
- /**
- * Returns the processed mail spool rows, keyed by the msid.
- *
- * Only rows that were processed while preparing the previously returned
- * source must be returned.
- *
- * @return
- * An array of mail spool rows, keyed by the msid. Can optionally have set
- * the following additional properties.
- * - actual_nid: In case of content translation, the source node that was
- * used for this mail.
- * - error: FALSE if the prepration for this row failed. For example set
- * when the corresponding node failed to load.
- * - status: A simplenews spool status to indicate the status.
- */
- function getProcessed();
- }
- /**
- * Simplenews Spool implementation.
- *
- * @ingroup spool
- */
- class SimplenewsSpool implements SimplenewsSpoolInterface {
- /**
- * Array with mail spool rows being processed.
- *
- * @var array
- */
- protected $spool_list;
- /**
- * Array of the processed mail spool rows.
- */
- protected $processed = array();
- /**
- * Implements SimplenewsSpoolInterface::_construct($spool_list);
- */
- public function __construct($spool_list) {
- $this->spool_list = $spool_list;
- }
- /**
- * Implements SimplenewsSpoolInterface::nextSource();
- */
- public function nextSource() {
- // Get the current mail spool row and update the internal pointer to the
- // next row.
- $return = each($this->spool_list);
- // If we're done, return false.
- if (!$return) {
- return FALSE;
- }
- $spool_data = $return['value'];
- // Store this spool row as processed.
- $this->processed[$spool_data->msid] = $spool_data;
- $node = node_load($spool_data->nid);
- if (!$node) {
- // If node the load failed, set the processed status done and proceed with
- // the next mail.
- $this->processed[$spool_data->msid]->result = array(
- 'status' => SIMPLENEWS_SPOOL_DONE,
- 'error' => TRUE
- );
- return $this->prepareMail();
- }
- if ($spool_data->data) {
- $subscriber = $spool_data->data;
- }
- else {
- $subscriber = simplenews_subscriber_load_by_mail($spool_data->mail);
- }
- $source_class = $this->getSourceImplementation($spool_data);
- $source = new $source_class($node, $subscriber);
- // Set which node is actually used. In case of a translation set, this might
- // not be the same node.
- $this->processed[$spool_data->msid]->actual_nid = $source->getNode()->nid;
- return $source;
- }
- /**
- * Implements SimplenewsSpoolInterface::getProcessed();
- */
- function getProcessed() {
- $processed = $this->processed;
- $this->processed = array();
- return $processed;
- }
- /**
- * Return the Simplenews source implementation for the given mail spool row.
- */
- protected function getSourceImplementation($spool_data) {
- return variable_get('simplenews_source', 'SimplenewsSourceNode');
- }
- }
- /**
- * Simplenews source implementation based on nodes for a single subscriber.
- *
- * @ingroup source
- */
- class SimplenewsSourceNode implements SimplenewsSourceNodeInterface {
- /**
- * The node object.
- */
- protected $node;
- /**
- * The cached build render array.
- */
- protected $build;
- /**
- * The newsletter category.
- */
- protected $category;
- /**
- * The subscriber and therefore recipient of this mail.
- */
- protected $subscriber;
- /**
- * The mail key used for drupal_mail().
- */
- protected $key = 'test';
- /**
- * The simplenews newsletter.
- */
- protected $newsletter;
- /**
- * Cache implementation used for this source.
- *
- * @var SimplenewsSourceCacheInterface
- */
- protected $cache;
- /**
- * Implements SimplenewsSourceInterface::_construct();
- */
- public function __construct($node, $subscriber) {
- $this->setSubscriber($subscriber);
- $this->setNode($node);
- $this->newsletter = simplenews_newsletter_load($node->nid);
- $this->category = simplenews_category_load($this->newsletter->tid);
- $this->initCache();
- }
- /**
- * Set the node of this source.
- *
- * If the node is part of a translation set, switch to the node for the
- * requested language, if existent.
- */
- public function setNode($node) {
- $langcode = $this->getLanguage();
- $nid = $node->nid;
- if (module_exists('translation')) {
- // If the node has translations and a translation is required
- // the equivalent of the node in the required language is used
- // or the base node (nid == tnid) is used.
- if ($tnid = $node->tnid) {
- if ($langcode != $node->language) {
- $translations = translation_node_get_translations($tnid);
- // A translation is available in the preferred language.
- if ($translation = $translations[$langcode]) {
- $nid = $translation->nid;
- $langcode = $translation->language;
- }
- else {
- // No translation found which matches the preferred language.
- foreach ($translations as $translation) {
- if ($translation->nid == $tnid) {
- $nid = $tnid;
- $langcode = $translation->language;
- break;
- }
- }
- }
- }
- }
- }
- // If a translation of the node is used, load this node.
- if ($nid != $node->nid) {
- $this->node = node_load($nid);
- }
- else {
- $this->node = $node;
- }
- }
- /**
- * Initialize the cache implementation.
- */
- protected function initCache() {
- $class = variable_get('simplenews_source_cache', 'SimplenewsSourceCacheBuild');
- $this->cache = new $class($this);
- }
- /**
- * Returns the corresponding category.
- */
- public function getCategory() {
- return $this->category;
- }
- /**
- * Set the active subscriber.
- */
- public function setSubscriber($subscriber) {
- $this->subscriber = $subscriber;
- }
- /**
- * Return the subscriber object.
- */
- public function getSubscriber() {
- return $this->subscriber;
- }
- /**
- * Implements SimplenewsSourceInterface::getHeaders().
- */
- public function getHeaders(array $headers) {
- // If receipt is requested, add headers.
- if ($this->category->receipt) {
- $headers['Disposition-Notification-To'] = $from;
- $headers['X-Confirm-Reading-To'] = $from;
- }
- // Add priority if set.
- switch ($this->category->priority) {
- case SIMPLENEWS_PRIORITY_HIGHEST:
- $headers['Priority'] = 'High';
- $headers['X-Priority'] = '1';
- $headers['X-MSMail-Priority'] = 'Highest';
- break;
- case SIMPLENEWS_PRIORITY_HIGH:
- $headers['Priority'] = 'urgent';
- $headers['X-Priority'] = '2';
- $headers['X-MSMail-Priority'] = 'High';
- break;
- case SIMPLENEWS_PRIORITY_NORMAL:
- $headers['Priority'] = 'normal';
- $headers['X-Priority'] = '3';
- $headers['X-MSMail-Priority'] = 'Normal';
- break;
- case SIMPLENEWS_PRIORITY_LOW:
- $headers['Priority'] = 'non-urgent';
- $headers['X-Priority'] = '4';
- $headers['X-MSMail-Priority'] = 'Low';
- break;
- case SIMPLENEWS_PRIORITY_LOWEST:
- $headers['Priority'] = 'non-urgent';
- $headers['X-Priority'] = '5';
- $headers['X-MSMail-Priority'] = 'Lowest';
- break;
- }
- // Add user specific header data.
- $message['headers']['From'] = $this->getFromFormatted();
- $message['headers']['List-Unsubscribe'] = '<' . token_replace('[simplenews-subscriber:unsubscribe-url]', $this->getTokenContext(), array('sanitize' => FALSE)) . '>';
- // Add general headers
- $headers['Precedence'] = 'bulk';
- return $headers;
- }
- /**
- * Implements SimplenewsSourceInterface::getTokenContext().
- */
- function getTokenContext() {
- return array(
- 'category' => $this->getCategory(),
- 'simplenews_subscriber' => $this->getSubscriber(),
- 'node' => $this->getNode(),
- );
- }
- /**
- * Set the mail key.
- */
- function setKey($key) {
- $this->key = $key;
- }
- /**
- * Implements SimplenewsSourceInterface::getKey().
- */
- function getKey() {
- return $this->key;
- }
- /**
- * Implements SimplenewsSourceInterface::getFromFormatted().
- */
- function getFromFormatted() {
- $name = $this->getCategory()->from_name;
- // Windows based PHP systems don't accept formatted emails.
- if (drupal_substr(PHP_OS, 0, 3) == 'WIN') {
- return $this->getFromAddress();
- }
- else {
- return '"' . $name . '" <' . $this->getFromAddress() . '>';
- }
- return $formatted_address;
- }
- /**
- * Implements SimplenewsSourceInterface::getFromAddress().
- */
- function getFromAddress() {
- return $this->getCategory()->from_address;
- }
- /**
- * Implements SimplenewsSourceInterface::getRecipient().
- */
- function getRecipient() {
- return $this->getSubscriber()->mail;
- }
- /**
- * Implements SimplenewsSourceInterface::getFormat().
- */
- function getFormat() {
- return $this->getCategory()->format;
- }
- /**
- * Implements SimplenewsSourceInterface::getLanguage().
- */
- function getLanguage() {
- return $this->getSubscriber()->language;
- }
- /**
- * Implements SimplenewsSourceSpoolInterface::getNode().
- */
- function getNode() {
- return $this->node;
- }
- /**
- * Implements SimplenewsSourceInterface::getSubject().
- */
- function getSubject() {
- // Build email subject and perform some sanitizing.
- $langcode = $this->getLanguage();
- $language_list = language_list();
- // Use the requested language if enabled.
- $language = isset($language_list[$langcode]) ? $language_list[$langcode] : NULL;
- $subject = token_replace($this->getCategory()->email_subject, $this->getTokenContext(), array('sanitize' => FALSE, 'language' => $language));
- // Line breaks are removed from the email subject to prevent injection of
- // malicious data into the email header.
- $subject = str_replace(array("\r", "\n"), '', $subject);
- return $subject;
- }
- /**
- * Set up the necessary language and user context.
- */
- protected function setContext() {
- // Switch to the user
- if ($this->uid = $this->getSubscriber()->uid) {
- simplenews_impersonate_user($this->uid);
- }
- // Change language if the requested language is enabled.
- $language = $this->getLanguage();
- $languages = language_list();
- if (isset($languages[$language])) {
- $this->original_language = $GLOBALS['language'];
- $GLOBALS['language'] = $languages[$language];
- $GLOBALS['language_url'] = $languages[$language];
- // Overwrites the current content language for i18n_select.
- if (module_exists('i18n_select')) {
- $GLOBALS['language_content'] = $languages[$language];
- }
- }
- }
- /**
- * Reset the context.
- */
- protected function resetContext() {
- // Switch back to the previous user.
- if ($this->uid) {
- simplenews_revert_user();
- }
- // Switch language back.
- if (!empty($this->original_language)) {
- $GLOBALS['language'] = $this->original_language;
- $GLOBALS['language_url'] = $this->original_language;
- if (module_exists('i18n_select')) {
- $GLOBALS['language_content'] = $this->original_language;
- }
- }
- }
- /**
- * Build the node object.
- *
- * The resulting build array is cached as it is used in multiple places.
- * @param $format
- * (Optional) Override the default format. Defaults to getFormat().
- */
- protected function build($format = NULL) {
- if (empty($format)) {
- $format = $this->getFormat();
- }
- if (!empty($this->build[$format])) {
- return $this->build[$format];
- }
- // Build message body
- // Supported view modes: 'email_plain', 'email_html', 'email_textalt'
- $build = node_view($this->node, 'email_' . $format);
- unset($build['#theme']);
- foreach (field_info_instances('node', $this->node->type) as $field_name => $field) {
- if (isset($build[$field_name])) {
- $build[$field_name]['#theme'] = 'simplenews_field';
- }
- }
- $this->build[$format] = $build;
- return $this->build[$format];
- }
- /**
- * Build the themed newsletter body.
- *
- * @param $format
- * (Optional) Override the default format. Defaults to getFormat().
- */
- protected function buildBody($format = NULL) {
- if (empty($format)) {
- $format = $this->getFormat();
- }
- if ($cache = $this->cache->get('build', 'body:' . $format)) {
- return $cache;
- }
- $body = theme('simplenews_newsletter_body', array('build' => $this->build($format), 'category' => $this->getCategory(), 'language' => $this->getLanguage(), 'simplenews_subscriber' => $this->getSubscriber()));
- $this->cache->set('build', 'body:' . $format, $body);
- return $body;
- }
- /**
- * Implements SimplenewsSourceInterface::getBody().
- */
- public function getBody() {
- return $this->getBodyWithFormat($this->getFormat());
- }
- /**
- * Implements SimplenewsSourceInterface::getBody().
- */
- public function getPlainBody() {
- return $this->getBodyWithFormat('plain');
- }
- /**
- * Get the body with the requested format.
- *
- * @param $format
- * Either html or plain.
- *
- * @return
- * The rendered mail body as a string.
- */
- protected function getBodyWithFormat($format) {
- // Switch to correct user and language context.
- $this->setContext();
- if ($cache = $this->cache->get('final', 'body:' . $format)) {
- return $cache;
- }
- $body = $this->buildBody($format);
- // Build message body, replace tokens.
- $body = token_replace($body, $this->getTokenContext(), array('sanitize' => FALSE));
- if ($format == 'plain') {
- // Convert HTML to text if requested to do so.
- $body = simplenews_html_to_text($body, $this->getCategory()->hyperlinks);
- }
- $this->cache->set('final', 'body:' . $format, $body);
- $this->resetContext();
- return $body;
- }
- /**
- * Builds the themed footer.
- *
- * @param $format
- * (Optional) Set the format of this footer build, overrides the default
- * format.
- */
- protected function buildFooter($format = NULL) {
- if (empty($format)) {
- $format = $this->getFormat();
- }
- if ($cache = $this->cache->get('build', 'footer:' . $format)) {
- return $cache;
- }
- // Build and buffer message footer
- $footer = theme('simplenews_newsletter_footer', array(
- 'build' => $this->build($format),
- 'category' => $this->getCategory(),
- 'context' => $this->getTokenContext(),
- 'key' => $this->getKey(),
- 'language' => $this->getLanguage(),
- 'format' => $format,
- ));
- $this->cache->set('build', 'footer:' . $format, $footer);
- return $footer;
- }
- /**
- * Implements SimplenewsSourceInterface::getFooter().
- */
- public function getFooter() {
- return $this->getFooterWithFormat($this->getFormat());
- }
- /**
- * Implements SimplenewsSourceInterface::getPlainFooter().
- */
- public function getPlainFooter() {
- return $this->getFooterWithFormat('plain');
- }
- /**
- * Get the footer in the specified format.
- *
- * @param $format
- * Either html or plain.
- *
- * @return
- * The footer for the requested format.
- */
- protected function getFooterWithFormat($format) {
- // Switch to correct user and language context.
- $this->setContext();
- if ($cache = $this->cache->get('final', 'footer:' . $format)) {
- return $cache;
- }
- $final_footer = token_replace($this->buildFooter($format), $this->getTokenContext(), array('sanitize' => FALSE));
- $this->cache->set('build', 'footer:' . $format, $final_footer);
- $this->resetContext();
- return $final_footer;
- }
- /**
- * Implements SimplenewsSourceInterface::getAttachments().
- */
- function getAttachments() {
- if ($cache = $this->cache->get('data', 'attachments')) {
- return $cache;
- }
- $attachments = array();
- $build = $this->build();
- $fids = array();
- foreach (field_info_instances('node', $this->node->type) as $field_name => $field_instance) {
- // @todo: Find a better way to support more field types.
- // Only add fields of type file which are enabled for the current view
- // mode as attachments.
- $field = field_info_field($field_name);
- if ($field['type'] == 'file' && isset($build[$field_name])) {
- if ($items = field_get_items('node', $this->node, $field_name)) {
- foreach ($items as $item) {
- $fids[] = $item['fid'];
- }
- }
- }
- }
- if (!empty($fids)) {
- $attachments = file_load_multiple($fids);
- }
- $this->cache->set('data', 'attachments', $attachments);
- return $attachments;
- }
- }
- /**
- * Abstract implementation of the source caching that does static caching.
- *
- * Subclasses need to implement the abstract function isCacheable() to decide
- * what should be cached.
- *
- * @ingroup source
- */
- abstract class SimplenewsSourceCacheStatic implements SimplenewsSourceCacheInterface {
- /**
- * The simplenews source for which this cache is used.
- *
- * @var SimplenewsSourceNodeInterface
- */
- protected $source;
- /**
- * The cache identifier for the given source.
- */
- protected $cid;
- /**
- * The static cache.
- */
- protected static $cache = array();
- /**
- * Implements SimplenewsSourceNodeInterface::__construct().
- */
- public function __construct(SimplenewsSourceNodeInterface $source) {
- $this->source = $source;
- self::$cache = &drupal_static(__CLASS__, array());
- }
- /**
- * Returns the cache identifier for the current source.
- */
- protected function getCid() {
- if (empty($this->cid)) {
- $this->cid = $this->source->getNode()->nid . ':' . $this->source->getLanguage();
- }
- return $this->cid;
- }
- /**
- * Implements SimplenewsSourceNodeInterface::get().
- */
- public function get($group, $key) {
- if (!$this->isCacheable($group, $key)) {
- return;
- }
- if (isset(self::$cache[$this->getCid()][$group][$key])) {
- return self::$cache[$this->getCid()][$group][$key];
- }
- }
- /**
- * Implements SimplenewsSourceNodeInterface::set().
- */
- public function set($group, $key, $data) {
- if (!$this->isCacheable($group, $key)) {
- return;
- }
- self::$cache[$this->getCid()][$group][$key] = $data;
- }
- /**
- * Return if the requested element should be cached.
- *
- * @return
- * TRUE if it should be cached, FALSE otherwise.
- */
- abstract function isCacheable($group, $key);
- }
- /**
- * Cache implementation that does not cache anything at all.
- *
- * @ingroup source
- */
- class SimplenewsSourceCacheNone extends SimplenewsSourceCacheStatic {
- /**
- * Implements SimplenewsSourceCacheStatic::set().
- */
- public function isCacheable($group, $key) {
- return FALSE;
- }
- }
- /**
- * Source cache implementation that caches build and data element.
- *
- * @ingroup source
- */
- class SimplenewsSourceCacheBuild extends SimplenewsSourceCacheStatic {
- /**
- * Implements SimplenewsSourceCacheStatic::set().
- */
- function isCacheable($group, $key) {
- // Only cache for anon users.
- if (user_is_logged_in()) {
- return FALSE;
- }
- // Only cache data and build information.
- return in_array($group, array('data', 'build'));
- }
- }
- /**
- * Example source implementation used for tests.
- *
- * @ingroup source
- */
- class SimplenewsSourceTest implements SimplenewsSourceInterface {
- protected $format;
- public function __construct($format) {
- $this->format = $format;
- }
- public function getAttachments() {
- return array(
- array(
- 'uri' => 'example://test.png',
- 'filemime' => 'x-example',
- 'filename' => 'test.png',
- ),
- );
- }
- public function getBody() {
- return $this->getFormat() == 'plain' ? $this->getPlainBody() : 'the body';
- }
- public function getFooter() {
- return $this->getFormat() == 'plain' ? $this->getPlainFooter() : 'the footer';
- }
- public function getPlainFooter() {
- return 'the plain footer';
- }
- public function getFormat() {
- return $this->format;
- }
- public function getFromAddress() {
- return 'test@example.org';
- }
- public function getFromFormatted() {
- return 'Test <test@example.org>';
- }
- public function getHeaders(array $headers) {
- $headers['X-Simplenews-Test'] = 'OK';
- return $headers;
- }
- public function getKey() {
- return 'node';
- }
- public function getLanguage() {
- return 'en';
- }
- public function getPlainBody() {
- return 'the plain body';
- }
- public function getRecipient() {
- return 'recipient@example.org';
- }
- public function getSubject() {
- return 'the subject';
- }
- public function getTokenContext() {
- return array();
- }
- }
|