123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029 |
- <?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->nextSource();
- }
- if ($spool_data->data) {
- $subscriber = $spool_data->data;
- }
- else {
- $subscriber = simplenews_subscriber_load_by_mail($spool_data->mail);
- }
- if (!$subscriber) {
- // If loading the subscriber 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->nextSource();
- }
- $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'] = $this->getFromAddress();
- $headers['X-Confirm-Reading-To'] = $this->getFromAddress();
- }
- // 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.
- $headers['From'] = $this->getFromFormatted();
- $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() {
- // Windows based PHP systems don't accept formatted email addresses.
- if (drupal_substr(PHP_OS, 0, 3) == 'WIN') {
- return $this->getFromAddress();
- }
- return '"' . addslashes(mime_header_encode($this->getCategory()->from_name)) . '" <' . $this->getFromAddress() . '>';
- }
- /**
- * 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('final', '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();
- }
- }
|