Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • PHP
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SIWECOS
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • Newsletter
  • NewsletterCollection
  • NewsletterJob
  • NewsletterJobCollection
  • NewsletterLog
  • NewsletterLogCollection
  • NewsletterRecipient
  • NewsletterRecipientCollection
  • NewsletterRecipientGroup
  • NewsletterRecipientGroupCollection
  • NewsletterRecipientGroupMember
  • NewsletterRecipientGroupMemberCollection
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
   1: <?php
   2: /**
   3:  * This file contains the Newsletter recipient class.
   4:  *
   5:  * @package Plugin
   6:  * @subpackage Newsletter
   7:  * @author Bjoern Behrens
   8:  * @copyright four for business AG <www.4fb.de>
   9:  * @license http://www.contenido.org/license/LIZENZ.txt
  10:  * @link http://www.4fb.de
  11:  * @link http://www.contenido.org
  12:  */
  13: 
  14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  15: 
  16: /**
  17:  * Newsletter recipient class.
  18:  *
  19:  * @package Plugin
  20:  * @subpackage Newsletter
  21:  * @method Newsletter createNewItem
  22:  * @method Newsletter next
  23:  */
  24: class NewsletterCollection extends ItemCollection
  25: {
  26:     /**
  27:      * Constructor Function
  28:      *
  29:      * @throws cInvalidArgumentException
  30:      */
  31:     public function __construct()
  32:     {
  33:         global $cfg;
  34:         parent::__construct($cfg["tab"]["news"], "idnews");
  35:         $this->_setItemClass("Newsletter");
  36:     }
  37: 
  38:     /**
  39:      * Creates a new newsletter
  40:      *
  41:      * @param $sName string specifies the newsletter name
  42:      *
  43:      * @return Item
  44:      * @throws cDbException
  45:      * @throws cException
  46:      * @throws cInvalidArgumentException
  47:      */
  48:     public function create($sName)
  49:     {
  50:         global $client, $lang, $auth;
  51: 
  52:         // Check if the newsletter name already exists
  53:         $this->resetQuery();
  54:         $this->setWhere("idclient", $client);
  55:         $this->setWhere("idlang", $lang);
  56:         $this->setWhere("name", $sName);
  57:         $this->query();
  58: 
  59:         if ($this->next()) {
  60:             return $this->create($sName . "_" . cString::getPartOfString(md5(rand()), 0, 10));
  61:         }
  62: 
  63:         $oItem = $this->createNewItem();
  64:         $oItem->set("idclient", $client);
  65:         $oItem->set("idlang", $lang);
  66:         $oItem->set("name", $sName);
  67:         $oItem->set("created", date('Y-m-d H:i:s'), false);
  68:         $oItem->set("author", $auth->auth["uid"]);
  69: 
  70:         $oItem->store();
  71: 
  72:         return $oItem;
  73:     }
  74: 
  75:     /**
  76:      * Duplicates the newsletter specified by $itemID
  77:      *
  78:      * @param  int $iItemID specifies the newsletter id
  79:      *
  80:      * @return Item
  81:      * @throws cDbException
  82:      * @throws cException
  83:      * @throws cInvalidArgumentException
  84:      */
  85:     public function duplicate($iItemID)
  86:     {
  87:         global $client, $lang, $auth;
  88: 
  89:         $client = cSecurity::toInteger($client);
  90:         $lang   = cSecurity::toInteger($lang);
  91: 
  92:         cInclude("includes", "functions.con.php");
  93: 
  94:         $oBaseItem = new Newsletter();
  95:         $oBaseItem->loadByPrimaryKey($iItemID);
  96: 
  97:         $oItem = $this->createNewItem();
  98:         $oItem->set("name", $oBaseItem->get("name") . "_" . cString::getPartOfString(md5(rand()), 0, 10));
  99: 
 100:         $iIDArt = 0;
 101:         if ($oBaseItem->get("type") == "html" && $oBaseItem->get("idart") > 0 && $oBaseItem->get("template_idart") > 0) {
 102:             $oClientLang = new cApiClientLanguage(false, $client, $lang);
 103: 
 104:             if ($oClientLang->getProperty("newsletter", "html_newsletter") == "true") {
 105:                 $iIDArt = conCopyArticle($oBaseItem->get("idart"),
 106:                     $oClientLang->getProperty("newsletter", "html_newsletter_idcat"),
 107:                     sprintf(i18n("Newsletter: %s", "newsletter"), $oItem->get("name"))
 108:                 );
 109:                 conMakeOnline($iIDArt, $lang); // Article has to be online for sending...
 110:             }
 111:             unset($oClientLang);
 112:         }
 113:         $oItem->set("idart", $iIDArt);
 114:         $oItem->set("template_idart", $oBaseItem->get("template_idart"));
 115:         $oItem->set("idclient", $client);
 116:         $oItem->set("idlang", $lang);
 117:         $oItem->set("welcome", 0);
 118:         $oItem->set("type", $oBaseItem->get("type"));
 119:         $oItem->set("subject", $oBaseItem->get("subject"));
 120:         $oItem->set("message", $oBaseItem->get("message"));
 121:         $oItem->set("newsfrom", $oBaseItem->get("newsfrom"));
 122:         $oItem->set("newsfromname", $oBaseItem->get("newsfromname"));
 123:         $oItem->set("newsdate", date("Y-m-d H:i:s"), false); // But more or less deprecated
 124:         $oItem->set("use_cronjob", $oBaseItem->get("use_cronjob"));
 125:         $oItem->set("send_to", $oBaseItem->get("send_to"));
 126:         $oItem->set("send_ids", $oBaseItem->get("send_ids"));
 127:         $oItem->set("dispatch", $oBaseItem->get("dispatch"));
 128:         $oItem->set("dispatch_count", $oBaseItem->get("dispatch_count"));
 129:         $oItem->set("dispatch_delay", $oBaseItem->get("dispatch_delay"));
 130:         $oItem->set("author", $auth->auth["uid"]);
 131:         $oItem->set("created", date('Y-m-d H:i:s'), false);
 132: 
 133:         // Copy properties, runtime on-demand allocation of the properties object
 134:         if (!is_object($this->properties)) {
 135:             $this->properties = new cApiPropertyCollection();
 136:         }
 137:         $this->properties->setWhere("idclient", $client);
 138:         $this->properties->setWhere("itemtype", $this->getPrimaryKeyName());
 139:         $this->properties->setWhere("itemid", $iItemID);
 140:         $this->properties->query();
 141: 
 142:         while ($oPropertyItem = $this->properties->next()) {
 143:             $oItem->setProperty($oPropertyItem->get("type"), $oPropertyItem->get("name"), $oPropertyItem->get("value"), $client);
 144:         }
 145: 
 146:         $oItem->store();
 147: 
 148:         return $oItem;
 149:     }
 150: }
 151: 
 152: /**
 153:  * Single Newsletter Item
 154:  */
 155: class Newsletter extends Item
 156: {
 157:     /**
 158:      * @var string Error storage
 159:      */
 160:     public $_sError;
 161: 
 162:     /**
 163:      * Constructor Function
 164:      *
 165:      * @param  mixed $mId Specifies the ID of item to load
 166:      *
 167:      * @throws cDbException
 168:      * @throws cException
 169:      */
 170:     public function __construct($mId = false)
 171:     {
 172:         global $cfg;
 173:         parent::__construct($cfg["tab"]["news"], "idnews");
 174:         $this->_sError = "";
 175:         if ($mId !== false) {
 176:             $this->loadByPrimaryKey($mId);
 177:         }
 178:     }
 179: 
 180:     /**
 181:      * Overriden store()-Method to set modified and modifiedby data and
 182:      * to ensure, that there is only one welcome newsletter
 183:      *
 184:      * @throws cException
 185:      */
 186:     public function store()
 187:     {
 188:         global $client, $lang, $auth;
 189: 
 190:         $client = cSecurity::toInteger($client);
 191:         $lang     = cSecurity::toInteger($lang);
 192: 
 193:         $this->set("modified", date('Y-m-d H:i:s'), false);
 194:         $this->set("modifiedby", $auth->auth["uid"]);
 195: 
 196:         if ($this->get("welcome") == 1) {
 197:             $oItems = new NewsletterCollection();
 198:             $oItems->setWhere("idclient", $client);
 199:             $oItems->setWhere("idlang", $lang);
 200:             $oItems->setWhere("welcome", 1);
 201:             $oItems->setWhere("idnews", $this->get("idnews"), "<>");
 202:             $oItems->query();
 203: 
 204:             while ($oItem = $oItems->next()) {
 205:                 $oItem->set("welcome", 0);
 206:                 $oItem->store();
 207:             }
 208:             unset($oItem);
 209:             unset($oItems);
 210:         }
 211: 
 212:         return parent::store();
 213:     }
 214: 
 215:     /**
 216:      * Userdefined setter for newsletter fields.
 217:      *
 218:      * @param string $name
 219:      * @param mixed  $value
 220:      * @param bool   $bSafe Flag to run defined inFilter on passed value
 221:      *
 222:      * @return bool
 223:      */
 224:     public function setField($name, $value, $bSafe = true) {
 225:         switch ($name) {
 226:             case 'idclient':
 227:                 $value = (int) $value;
 228:                 break;
 229:             case 'idlang':
 230:                 $value = (int) $value;
 231:                 break;
 232:         }
 233: 
 234:         return parent::setField($name, $value, $bSafe);
 235:     }
 236: 
 237:     /**
 238:      * Replaces newsletter tag (e.g. MAIL_NAME) with data.
 239:      * If code is just text using str_replace; if it is HTML by using regular expressions
 240:      * @param string    $sCode    Code, where the tags will be replaced (by reference)
 241:      * @param bool        $bIsHTML    Is code HTML?
 242:      * @param string    $sField    Field name, without MAIL_ (e.g. just "name")
 243:      * @param string    $sData    Data
 244:      */
 245:     public function _replaceTag(&$sCode, $bIsHTML, $sField, $sData)
 246:     {
 247:         if ($sCode && !$bIsHTML) {
 248:             $sCode = str_replace("MAIL_".cString::toUpperCase($sField), $sData, $sCode);
 249:         } elseif ($sCode) {
 250:             // Extract certain tag
 251:             $sRegExp   = '/\[mail\s*([^]]+)\s*name=(?:"|&quot;)'.$sField.'(?:"|&quot;)\s*(.*?)\s*\]((?:.|\s)+?)\[\/mail\]/i';
 252:             $aMatch    = array();
 253:             $iMatches  = preg_match($sRegExp, $sCode, $aMatch) ;
 254: 
 255:             if ($iMatches > 0) {
 256:                 // $aMatch contains parameter info from left [1] or right [2] to name="field"
 257:                 $sParameter = $aMatch[1] . $aMatch[2];
 258:                 $sMessage   = $aMatch[3];
 259:                 $sRegExp    = '/\s*(.*?)\s*=\s*(?:"|&quot;)(.*?)(?:"|&quot;)\s*/i';
 260:                 $aMatch     = array();
 261: 
 262:                 if (preg_match_all($sRegExp, $sParameter, $aMatch) > 0) {
 263:                     // Store parameter data as assoziative array
 264:                     $aParameter = array_combine($aMatch[1], $aMatch[2]);
 265:                     unset($aMatch); // $aMatch not needed anymore
 266: 
 267:                     if (!array_key_exists("type", $aParameter)) {
 268:                         $aParameter["type"] = "text";
 269:                     }
 270: 
 271:                     switch ($aParameter["type"]) {
 272:                         case "link":
 273:                             # TODO: Works everything fine?
 274:                             # The current code makes it possible to do something like
 275:                             # [mail ...]Some text here, then the link: [MAIL_STOP] and more text[/mail]
 276:                             #
 277:                             # If the other lines will be used, you don't need to
 278:                             # set [MAIL_xy] and the message between the [mail]-tags will
 279:                             # be used as link text (instead of using the tag parameter "text")
 280: 
 281:                             $sText = $aParameter["text"];
 282: 
 283:                             if ($sText == "") {
 284:                                 $sText = $sData;
 285:                             }
 286:                             if ($sMessage == "") {
 287:                                 $sMessage = $sData;
 288:                             }
 289: 
 290:                             // Remove not needed parameters from the parameters list
 291:                             // everything else goes into the link as parameters
 292:                             unset($aParameter["type"]);
 293:                             unset($aParameter["text"]);
 294: 
 295:                             $sParameter = "";
 296:                             if (count($aParameter) > 0) {
 297:                                 foreach ($aParameter as $sKey => $sValue) {
 298:                                     $sParameter .= ' '.$sKey . '="' . $sValue . '"';
 299:                                 }
 300:                             }
 301:                             $sMessage    = str_replace("MAIL_".cString::toUpperCase($sField), '<a href="'.conHtmlentities($sData).'"'.$sParameter.'>'.$sText.'</a>', $sMessage);
 302:                             #$sMessage    = '<a href="'.conHtmlentities($sData).'"'.$sParameter.'>'.$sMessage.'</a>';
 303:                             break;
 304:                         default:
 305:                             $sMessage    = str_replace("MAIL_".cString::toUpperCase($sField), $sData, $sMessage);
 306:                             #$sMessage    = $sData;
 307:                     }
 308: 
 309:                     $sRegExp = '/\[mail[^]]+name=(?:"|&quot;)'.$sField.'(?:"|&quot;).*?\].*?\[\/mail\]/is';
 310:                     $sCode   = preg_replace($sRegExp, $sMessage, $sCode, -1);
 311:                     // Just to replace "text"-tags in HTML message also, just in case...
 312:                     $sCode   = str_replace("MAIL_".cString::toUpperCase($sField), $sData, $sCode);
 313:                 }
 314:             }
 315:         }
 316:     }
 317: 
 318:     /**
 319:      * @todo HerrB: Remove or insert some functionality
 320:      * @param $sHTML
 321:      * @param $sTag
 322:      */
 323:     protected function _getNewsletterTagData($sHTML, $sTag)
 324:     {
 325:         //$sRegExp = "/<newsletter[^>](.*?)>.*?<\/newsletter>/i";
 326:         //$sRegExp = "/\[mail[^\]](.*?)>.*?\[\/mail\]/i";
 327:         //\[mail[^\]]((name="(?P<name>.*?)")|(type="(?P<type>.*?)"))\](?P<content>.*?)\[\/mail\]
 328:         //\[mail[^\]]((name=(?P<name>[^"]*.*?[^"]*))|(type="(?P<type>.*?)"))\](?P<content>.*?)\[\/mail\]
 329: 
 330:         /* RegExp explanation:
 331:          * Match the character "[" literally �\[�
 332:          * Match the characters "mail" literally �mail�
 333:          * Match "whitespace characters" (spaces, tabs, line breaks, etc.) after "mail" �\s*�
 334:          * Match the regular expression below and capture its match into backreference number 1 �([^]]+)�
 335:          * Match any character that is not a "]" �[^]]+�
 336:          *       Between one and unlimited times, as many times as possible, giving back as needed (greedy) �+�
 337:          * Match the character "]" literally �\]�
 338:          * Match the regular expression below and capture its match into backreference number 2 �((?:.|\s)+?)�
 339:          *    Match the regular expression below �(?:.|\s)+?�
 340:          *       Between one and unlimited times, as few times as possible, expanding as needed (lazy) �+?�
 341:          *       Match either the regular expression below (attempting the next alternative only if this one fails) �.�
 342:          *          Match any single character that is not a line break character �.�
 343:          *       Or match regular expression number 2 below (the entire group fails if this one fails to match) �\s�
 344:          *          Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) �\s�
 345:          * Match the character "[" literally �\[�
 346:          * Match the characters "/mail" literally �/mail�
 347:          * Match the character "]" literally �\]�
 348:          * Ignore case (i), . includes new lines (s)
 349:          */
 350: 
 351:         /*
 352:         $sRegExp = '/\[mail\s*([^]]+)\]((?:.|\s)+?)\[\/mail\]/is';
 353:         $aMatch = array();
 354:         preg_match_all($sRegExp, $sHTML, $aMatch, PREG_SET_ORDER);
 355:         print_r ($aMatch);
 356: 
 357:         // Auf bestimmten Typ matchen
 358:         $sRegExp = '/\[mail.*?name="name".*?\]((?:.|\s)+?)\[\/mail\]/is';
 359:         $aMatch = array();
 360:         preg_match_all($sRegExp, $sHTML, $aMatch, PREG_SET_ORDER);
 361:         print_r ($aMatch); */
 362: 
 363:         // Parameter auseinandernehmen (ohne PREG_SET_ORDER)
 364:         //$sRegExp = '/\s*(.*?)\s*=\s*"(.*?)"\s*/i';
 365:         //$aMatch = array();
 366:         //preg_match_all($sRegExp, $sHTML, $aMatch);
 367:         //print_r ($aMatch);
 368:     }
 369: 
 370:     /**
 371:      * @param        $sHeader
 372:      * @param        $sBody
 373:      * @param string $sEOL
 374:      *
 375:      * @return string
 376:      */
 377:     protected function _deChunkHTTPBody($sHeader, $sBody, $sEOL = "\r\n")
 378:     {
 379:         // Based on code from jbr at ya-right dot com, posted on http://www.php.net
 380:         // as user comment on fsockopen documentation (2007-05-01)
 381: 
 382:         // Analyze header
 383:         $aParts = preg_split("/\r?\n/", $sHeader, -1, PREG_SPLIT_NO_EMPTY);
 384: 
 385:         $aHeader = array();
 386:         for ($i = 0;$i < sizeof ($aParts); $i++) {
 387:             if ($i != 0) {
 388:                 $iPos       = cString::findFirstPos($aParts[$i], ':');
 389:                 $sParameter = cString::toLowerCase(str_replace(' ', '', cString::getPartOfString($aParts[$i], 0, $iPos)));
 390:                 $sValue     = trim(cString::getPartOfString($aParts[$i], ($iPos + 1)));
 391:             } else {
 392:                 $sField      = 'status';
 393:                 $aParameters = explode(' ', $aParts[$i]);
 394:                 $sParameter  = $aParameters[1];
 395:             }
 396: 
 397:             if ($sParameter == 'set-cookie') {
 398:                 $aHeader['cookies'][] = $sValue;
 399:             } elseif ($sParameter == 'content-type') {
 400:                 if (($iPos = cString::findFirstPos($sValue, ';')) !== false) {
 401:                     $aHeader[$sParameter] = cString::getPartOfString($sValue, 0, $iPos);
 402:                 } else {
 403:                     $aHeader[$sParameter] = $sValue;
 404:                 }
 405:             } else {
 406:                 $aHeader[$sParameter] = $sValue;
 407:             }
 408:         }
 409: 
 410:         // Get dechunked and decompressed body
 411:         $iEOLLen = cString::getStringLength($sEOL);
 412: 
 413:         $sBuffer = '';
 414: 
 415:         // workaround:
 416:         // others and i don't understand this part, thats why i made a workaround
 417:         // seems as it is chunked, but reveived data isn't, thats why hexdec() produces an error
 418:         if (isset($aHeader['transfer-encoding']) && $aHeader['transfer-encoding'] == 'chunked') {
 419:             $isHex = true;
 420: 
 421:             do {
 422:                 $sBody    = ltrim ($sBody);
 423:                 $iPos     = cString::findFirstPos($sBody, $sEOL);
 424:                 $nextChunkLength =  cString::getPartOfString($sBody, 0, (int) $iPos);
 425: 
 426:                 // workaround begin
 427:                 preg_match('/^[0-9A-F]$/', $nextChunkLength, $isHex);
 428:                 if (empty($isHex)) {
 429:                     $isHex = false;
 430:                     break;
 431:                 }
 432:                 // workarround end
 433: 
 434:                 $iDataLen = hexdec($nextChunkLength);
 435: 
 436:                 if (isset($aHeader['content-encoding'])) {
 437:                     $sBuffer .= gzinflate(cString::getPartOfString($sBody, ((int) $iPos + (int) $iEOLLen + 10), (int) $iDataLen));
 438:                 } else {
 439:                     $sBuffer .= cString::getPartOfString($sBody, ((int) $iPos + (int) $iEOLLen), (int) $iDataLen);
 440:                 }
 441: 
 442:                 $sBody      = cString::getPartOfString($sBody, ((int) $iPos + (int) $iDataLen + (int) $iEOLLen));
 443: 
 444:                 $sRemaining = trim ($sBody);
 445:             } while ($sRemaining != '');
 446: 
 447:             // workarround begin
 448:             if ($isHex === false) {
 449:                 if (isset($aHeader['content-encoding'])) {
 450:                     $sBuffer = gzinflate(cString::getPartOfString($sBody, 10));
 451:                 } else {
 452:                     $sBuffer = $sBody; // Not chunked, not compressed
 453:                 }
 454:             }
 455:             // workarround end
 456: 
 457:         } elseif (isset($aHeader['content-encoding'])) {
 458:             $sBuffer = gzinflate(cString::getPartOfString($sBody, 10));
 459:         } else {
 460:             $sBuffer = $sBody; // Not chunked, not compressed
 461:         }
 462: 
 463:         return $sBuffer;
 464:     }
 465: 
 466:     /**
 467:      * If newsletter is HTML newsletter and necessary data available
 468:      * returns final HTML message
 469:      *
 470:      * @return string HTML message
 471:      * @throws cDbException
 472:      * @throws cException
 473:      */
 474:     public function getHTMLMessage()
 475:     {
 476:         global $lang, $client, $contenido;
 477:         $frontendURL = cRegistry::getFrontendUrl();
 478:         if ($this->get("type") == "html" && $this->get("idart") > 0 && $this->htmlArticleExists()) {
 479: 
 480:             // Article ID
 481:             $iIDArt = $this->get("idart");
 482: 
 483:             // Category ID
 484:             $oClientLang = new cApiClientLanguage(false, $client, $lang);
 485:             $iIDCat      = $oClientLang->getProperty("newsletter", "html_newsletter_idcat");
 486:             unset($oClientLang);
 487: 
 488:             // Get http username and password, if frontend is protected
 489:             $oClient = new cApiClient($client);
 490:             $sHTTPUserName = $oClient->getProperty("newsletter", "html_username");
 491:             $sHTTPPassword = $oClient->getProperty("newsletter", "html_password");
 492:             unset($oClient);
 493:             // Get HTML
 494:             if ($iIDArt > 0 && $iIDCat > 0) {
 495:                 // Check, if newsletter is online and set temporarely online, otherwise
 496:                 $bSetOffline = false;
 497:                 $oArticles = new cApiArticleLanguageCollection;
 498:                 $oArticles->setWhere("idlang", $this->get("idlang"));
 499:                 $oArticles->setWhere("idart", $this->get("idart"));
 500:                 $oArticles->query();
 501: 
 502:                 if ($oArticle = $oArticles->next()) {
 503:                     if ($oArticle->get("online") == 0) {
 504:                         $bSetOffline = true;
 505:                         $oArticle->set("online", 1);
 506:                         $oArticle->store();
 507:                     }
 508:                     unset($oArticle);
 509:                 }
 510:                 unset($oArticles);
 511: 
 512:                 $sFile = "front_content.php?client=$client&lang=$lang&idcat=$iIDCat&idart=$iIDArt&noex=1&send=1";
 513: 
 514:                 $handler = cHttpRequest::getHttpRequest($frontendURL.$sFile);
 515:                 $headers = array();
 516: 
 517:                 // Maybe the website has been protected using .htaccess, then login
 518:                 if ($sHTTPUserName != "" && $sHTTPPassword != "") {
 519:                     $headers['Authorization'] = "Basic " . base64_encode("$sHTTPUserName:$sHTTPPassword");
 520:                 }
 521: 
 522:                 $headers['Referer'] = "Referer: http://".$frontendURL;
 523:                 $headers['User-Agent'] = "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
 524: 
 525:                 $handler->setHeaders($headers);
 526: 
 527:                 $iErrorNo    = 0;
 528:                 $sErrorMsg   = "";
 529:                 if ($output = $handler->getRequest(true, true)) {
 530:                     // Get the HTTP header and body separately
 531:                     $sHTML   = strstr(strstr($output, "200"), "\r\n\r\n");
 532:                     $sHeader = strstr($output, "\r\n\r\n", true);
 533:                     $sHTML = $this->_deChunkHTTPBody($sHeader, $sHTML);
 534: 
 535:                     // If someone likes to use anchors in html newsletters (*sigh*)
 536:                     // the base href tag has to be removed - that means, we have to fix
 537:                     // all source paths manually...
 538:                     if (getEffectiveSetting('newsletter', 'remove_base_tag', "false") == "true") {
 539:                         // Remove base tag
 540:                         $sHTML = preg_replace('/<base href=(.*?)>/is', '', $sHTML, 1);
 541: 
 542:                         // Fix source path
 543:                         // TODO: Test any URL specification that may exist under the sun...
 544:                         $sHTML = preg_replace('/[sS[rR][cC][ ]*=[ ]*"([^h][^t][^t][^p][^:].*)"/', 'rc="'.$frontendURL.'$1"', $sHTML);
 545:                         $sHTML = preg_replace('/[hH][rR][eE][fF][ ]*=[ ]*"([^h][^t][^t][^p][^:][A-Za-z0-9#\.?\-=_&]*)"/', 'href="'.$frontendURL.'$1"', $sHTML);
 546:                         $sHTML = preg_replace('/url\((.*)\)/', 'url('. $frontendURL.'$1)', $sHTML);
 547: 
 548:                         // Now replace anchor tags to the newsletter article itself just by the anchor
 549:                         $sHTML = str_replace($frontendURL . "front_content.php?idart=".$iIDArt."#", "#", $sHTML);
 550:                     }
 551: 
 552:                     $sReturn = $sHTML;
 553:                 } else {
 554:                     if ($contenido) { // Use i18n only in backend
 555:                         $sErrorText = i18n("There was a problem getting the newsletter article using http. Error: %s (%s)", "newsletter");
 556:                     } else {
 557:                         $sErrorText = "There was a problem getting the newsletter article using http. Error: %s (%s)";
 558:                     }
 559: 
 560:                     $this->_sError = sprintf($sErrorText, $sErrorMsg, $iErrorNo);
 561:                     $sReturn = false;
 562:                 }
 563: 
 564:                 // Set previously offline article back to offline
 565:                 if ($bSetOffline) {
 566:                     $oArticles = new cApiArticleLanguageCollection();
 567:                     $oArticles->setWhere("idlang", $this->get("idlang"));
 568:                     $oArticles->setWhere("idart", $this->get("idart"));
 569:                     $oArticles->query();
 570: 
 571:                     if ($oArticle = $oArticles->next()) {
 572:                         $oArticle->set("online", 0);
 573:                         $oArticle->store();
 574:                     }
 575:                     unset($oArticle);
 576:                     unset($oArticles);
 577:                 }
 578: 
 579:                 return $sReturn;
 580:             } else {
 581:                 return false;
 582:             }
 583:         } else {
 584:             return false;
 585:         }
 586:     }
 587: 
 588:     /**
 589:      * Checks, if html newsletter article still exists
 590:      *
 591:      * @return bool
 592:      * @throws cException
 593:      */
 594:     public function htmlArticleExists()
 595:     {
 596:         if ($this->get("idart") > 0) {
 597:             $oArticles = new cApiArticleLanguageCollection();
 598:             $oArticles->setWhere("idlang", $this->get("idlang"));
 599:             $oArticles->setWhere("idart", $this->get("idart"));
 600:             $oArticles->query();
 601: 
 602:             if ($oArticles->count() > 0) {
 603:                 $bReturn = true;
 604:             } else {
 605:                 $bReturn = false;
 606:             }
 607: 
 608:             unset($oArticles);
 609:         } else {
 610:             $bReturn = false;
 611:         }
 612: 
 613:         return $bReturn;
 614:     }
 615: 
 616:     /**
 617:      * Sends test newsletter directly to specified email address
 618:      *
 619:      * @param int    $iIDCatArt          idcatart of newsletter handler article
 620:      * @param string $sEMail             Recipient email address
 621:      * @param string $sName              Optional: Recipient name
 622:      * @param bool   $bSimulatePlugins   If recipient plugin activated, include plugins
 623:      *                                   and simulate values from plugins
 624:      * @param string $sEncoding          Message (and header) encoding, e.g. iso-8859-1
 625:      *
 626:      * @return bool
 627:      * @throws cDbException
 628:      * @throws cException
 629:      */
 630:     public function sendEMail($iIDCatArt, $sEMail, $sName = "", $bSimulatePlugins = true, $sEncoding = "iso-8859-1")
 631:     {
 632:         global $lang, $client, $cfg, $cfgClient, $contenido;
 633: 
 634:         // Initialization
 635:         if ($sName == "") {
 636:             $sName = $sEMail;
 637:         }
 638: 
 639:         $oLanguage = new cApiLanguage($lang);
 640:         $sFormatDate = $oLanguage->getProperty("dateformat", "date");
 641:         $sFormatTime = $oLanguage->getProperty("dateformat", "time");
 642:         unset($oLanguage);
 643: 
 644:         if ($sFormatDate == "") {
 645:             $sFormatDate = "%d.%m.%Y";
 646:         }
 647:         if ($sFormatTime == "") {
 648:             $sFormatTime = "%H:%M";
 649:         }
 650: 
 651:         // Get newsletter data
 652:         $sFrom            = $this->get("newsfrom");
 653:         $sFromName        = $this->get("newsfromname");
 654:         if ($sFromName == "") {
 655:             $sFromName    = $sFrom;
 656:         }
 657:         $sSubject        = $this->get("subject");
 658:         $sMessageText    = $this->get("message");
 659: 
 660:         $bIsHTML        = false;
 661:         if ($this->get("type") == "html") {
 662:             $sMessageHTML    = $this->getHTMLMessage();
 663: 
 664:             if ($sMessageHTML === false) {
 665:                 // There was a problem getting the html message (maybe article
 666:                 // deleted). Exit with error instead of sending as text message only
 667: 
 668:                 if (cRegistry::getBackendSessionId()) { // Use i18n only in backend
 669:                     $sError = i18n("Newsletter to %s could not be sent: No html message available", "newsletter");
 670:                 } else {
 671:                     $sError = "Newsletter to %s could not be sent: No html message available";
 672:                 }
 673:                 $this->_sError = $sName." (".$sEMail."): ".sprintf($sError, $sEMail);
 674:                 return false;
 675:             } else {
 676:                 $bIsHTML = true;
 677:             }
 678:         }
 679: 
 680:         // Preventing double lines in mail, you may wish to disable this function on windows servers
 681:         if (!getSystemProperty("newsletter", "disable-rn-replacement")) {
 682:             $sMessageText = str_replace("\r\n", "\n", $sMessageText);
 683:         }
 684: 
 685:         // Simulate key, an alphanumeric string of 30 characters
 686:         $sKey    = str_repeat("key", 10);
 687:         $sPath    = cRegistry::getFrontendUrl() . "front_content.php?changelang=".$lang."&idcatart=".$iIDCatArt."&";
 688: 
 689:         // Replace message tags (text message)
 690:         $this->_replaceTag($sMessageText, false, "name", $sName);
 691:         $this->_replaceTag($sMessageText, false, "number", 1);
 692:         $this->_replaceTag($sMessageText, false, "date", strftime($sFormatDate));
 693:         $this->_replaceTag($sMessageText, false, "time", strftime($sFormatTime));
 694:         $this->_replaceTag($sMessageText, false, "unsubscribe", $sPath."unsubscribe=".$sKey);
 695:         $this->_replaceTag($sMessageText, false, "change", $sPath."change=".$sKey);
 696:         $this->_replaceTag($sMessageText, false, "stop", $sPath."stop=".$sKey);
 697:         $this->_replaceTag($sMessageText, false, "goon", $sPath."goon=".$sKey);
 698: 
 699:         // Replace message tags (html message)
 700:         if ($bIsHTML) {
 701:             $this->_replaceTag($sMessageHTML, true, "name", $sName);
 702:             $this->_replaceTag($sMessageHTML, true, "number", 1);
 703:             $this->_replaceTag($sMessageHTML, true, "date", strftime($sFormatDate));
 704:             $this->_replaceTag($sMessageHTML, true, "time", strftime($sFormatTime));
 705:             $this->_replaceTag($sMessageHTML, true, "unsubscribe", $sPath."unsubscribe=".$sKey);
 706:             $this->_replaceTag($sMessageHTML, true, "change", $sPath."change=".$sKey);
 707:             $this->_replaceTag($sMessageHTML, true, "stop", $sPath."stop=".$sKey);
 708:             $this->_replaceTag($sMessageHTML, true, "goon", $sPath."goon=".$sKey);
 709:         }
 710: 
 711:         if ($bSimulatePlugins) {
 712:             // Enabling plugin interface
 713:             if (getSystemProperty("newsletter", "newsletter-recipients-plugin") == "true") {
 714:                 if (is_array($cfg['plugins']['recipients'])) {
 715:                     foreach ($cfg['plugins']['recipients'] as $sPlugin) {
 716:                         plugin_include("recipients", $sPlugin."/".$sPlugin.".php");
 717:                         if (function_exists("recipients_".$sPlugin."_wantedVariables")) {
 718:                             $aPluginVars = array();
 719:                             $aPluginVars = call_user_func("recipients_".$sPlugin."_wantedVariables");
 720: 
 721:                             foreach ($aPluginVars as $sPluginVar) {
 722:                                 // Replace tags in text message
 723:                                 $this->_replaceTag($sMessageText, false, $sPluginVar, ":: ".$sPlugin.": ".$sPluginVar." ::");
 724:                                 // Replace tags in html message
 725:                                 if ($bIsHTML) {
 726:                                     $this->_replaceTag($sMessageHTML, true,     $sPluginVar, ":: ".$sPlugin.": ".$sPluginVar." ::");
 727:                                 }
 728:                             }
 729:                         }
 730:                     }
 731:                 }
 732:             } else {
 733:                 setSystemProperty("newsletter", "newsletter-recipients-plugin", "false");
 734:             }
 735:         }
 736: 
 737:         if (!isValidMail($sEMail) || cString::toLowerCase($sEMail) == "sysadmin@ihresite.de") {
 738:             // No valid destination mail address specified
 739:             if ($contenido) { // Use i18n only in backend
 740:                 $sError = i18n("Newsletter to %s could not be sent: No valid e-mail address", "newsletter");
 741:             } else {
 742:                 $sError = "Newsletter to %s could not be sent: No valid e-mail address";
 743:             }
 744:             $this->_sError = $sName." (".$sEMail."): ".sprintf($sError, $sEMail);
 745:             return false;
 746:         } else {
 747:             if ($bIsHTML) {
 748:                 $body = $sMessageHTML;
 749:             } else {
 750:                 $body = $sMessageText."\n\n";
 751:             }
 752:             if ($bIsHTML) {
 753:                 $contentType = 'text/html';
 754:             } else {
 755:                 $contentType = 'text/plain';
 756:             }
 757: 
 758:             try {
 759:                 $mailer = new cMailer();
 760:             } catch (cInvalidArgumentException $e) {
 761:                 $this->_sError = $e->getMessage();
 762:                 return false;
 763:             }
 764: 
 765:             $message = Swift_Message::newInstance($sSubject, $body, $contentType, $sEncoding);
 766:             $message->setFrom($sFrom, $sFromName);
 767:             $message->setTo($sEMail);
 768:             $result = $mailer->send($message);
 769: 
 770:             if (!$result) {
 771:                 // Use i18n only in backend
 772:                 if ($contenido) {
 773:                     $sError = i18n("Newsletter to %s could not be sent", "newsletter");
 774:                 } else {
 775:                     $sError = "Newsletter to %s could not be sent";
 776:                 }
 777:                 $this->_sError = $sName." (".$sEMail."): ".sprintf($sError, $sEMail);
 778:                 return false;
 779:             } else {
 780:                 return true;
 781:             }
 782:         }
 783:     }
 784: 
 785:     /**
 786:      * Sends test newsletter directly to specified recipients (single or group)
 787:      *
 788:      * Note: Sending in chunks not supported! Only usable for tests and only a few
 789:      * recipients.
 790:      *
 791:      * @param int    $iIDCatArt    idcatart of newsletter handler article
 792:      * @param bool   $iIDNewsRcp   If specified, newsletter recipient id, ignored, if group specified
 793:      * @param bool   $iIDNewsGroup If specified, newsletter recipient group id
 794:      * @param array  $aSendRcps    As reference: Filled with a list of succesfull recipients
 795:      * @param string $sEncoding    Message (and header) encoding, e.g. iso-8859-1
 796:      *
 797:      * @return bool
 798:      * @throws cDbException
 799:      * @throws cException
 800:      * @throws cInvalidArgumentException
 801:      */
 802:     public function sendDirect($iIDCatArt, $iIDNewsRcp = false, $iIDNewsGroup = false, &$aSendRcps, $sEncoding = "iso-8859-1")
 803:     {
 804:         global $lang, $client, $cfg, $cfgClient, $contenido, $recipient;
 805: 
 806:         // Initialization
 807:         $aMessages  = array();
 808: 
 809:         // Initializing cApiLanguage and get properties for dateformat
 810:         $oLanguage = new cApiLanguage($lang);
 811:         $sFormatDate = $oLanguage->getProperty("dateformat", "date");
 812:         $sFormatTime = $oLanguage->getProperty("dateformat", "time");
 813:         unset($oLanguage);
 814: 
 815:         // If no date- and format defined please set standard values
 816:         if ($sFormatDate == "") {
 817:             $sFormatDate = "%d.%m.%Y";
 818:         }
 819:         if ($sFormatTime == "") {
 820:             $sFormatTime = "%H:%M";
 821:         }
 822: 
 823:         $sPath = cRegistry::getFrontendUrl() . "front_content.php?changelang=".$lang."&idcatart=".$iIDCatArt."&";
 824: 
 825:         // Get newsletter data
 826:         $sFrom     = $this->get("newsfrom");
 827:         $sFromName = $this->get("newsfromname");
 828:         if ($sFromName == "") {
 829:             $sFromName = $sFrom;
 830:         }
 831:         $sSubject     = $this->get("subject");
 832:         $sMessageText = $this->get("message");
 833: 
 834:         $bIsHTML      = false;
 835:         if ($this->get("type") == "html") {
 836:             $sMessageHTML    = $this->getHTMLMessage();
 837: 
 838:             if ($sMessageHTML === false) {
 839:                 // There was a problem getting the html message (maybe article
 840:                 // deleted). Exit with error instead of sending as text message only
 841: 
 842:                 if (cRegistry::getBackendSessionId()) { // Use i18n only in backend
 843:                     $sError = i18n("Newsletter could not be sent: No html message available", "newsletter");
 844:                 } else {
 845:                     $sError = "Newsletter could not be sent: No html message available";
 846:                 }
 847:                 $this->_sError = $sError;
 848:                 return false;
 849:             } else {
 850:                 $bIsHTML = true;
 851:             }
 852:         }
 853: 
 854:         // Preventing double lines in mail, you may wish to disable this function on windows servers
 855:         if (!getSystemProperty("newsletter", "disable-rn-replacement")) {
 856:             $sMessageText = str_replace("\r\n", "\n", $sMessageText);
 857:         }
 858: 
 859:         // Single replacements
 860:         // Replace message tags (text message)
 861:         $this->_replaceTag($sMessageText, false, "date", strftime($sFormatDate));
 862:         $this->_replaceTag($sMessageText, false, "time", strftime($sFormatTime));
 863: 
 864:         // Replace message tags (html message)
 865:         if ($bIsHTML) {
 866:             $this->_replaceTag($sMessageHTML, true, "date", strftime($sFormatDate));
 867:             $this->_replaceTag($sMessageHTML, true, "time", strftime($sFormatTime));
 868:         }
 869: 
 870:         // Enabling plugin interface
 871:         if (getSystemProperty("newsletter", "newsletter-recipients-plugin") == "true") {
 872:             $bPluginEnabled = true;
 873:             $aPlugins       = array();
 874: 
 875:             if (is_array($cfg['plugins']['recipients'])) {
 876:                 foreach ($cfg['plugins']['recipients'] as $sPlugin) {
 877:                     plugin_include("recipients", $sPlugin."/".$sPlugin.".php");
 878:                     if (function_exists("recipients_".$sPlugin."_wantedVariables")) {
 879:                         $aPlugins[$sPlugin] = call_user_func("recipients_".$sPlugin."_wantedVariables");
 880:                     }
 881:                 }
 882:             }
 883:         } else {
 884:             setSystemProperty("newsletter", "newsletter-recipients-plugin", "false");
 885:             $bPluginEnabled = false;
 886:         }
 887: 
 888:         $aRecipients = array();
 889:         if ($iIDNewsGroup !== false) {
 890:             $oGroupMembers = new NewsletterRecipientGroupMemberCollection;
 891:             $aRecipients = $oGroupMembers->getRecipientsInGroup($iIDNewsGroup, false);
 892:         } elseif ($iIDNewsRcp !== false) {
 893:             $aRecipients[] = $iIDNewsRcp;
 894:         }
 895: 
 896:         $iCount = count($aRecipients);
 897:         if ($iCount > 0) {
 898:             $this->_replaceTag($sMessageText, false, "number", $iCount);
 899: 
 900:             // Replace message tags (html message)
 901:             if ($bIsHTML) {
 902:                 $this->_replaceTag($sMessageHTML, true,     "number", $iCount);
 903:             }
 904: 
 905:             foreach ($aRecipients as $iID) {
 906:                 $sRcpMsgText = $sMessageText;
 907:                 $sRcpMsgHTML = $sMessageHTML;
 908: 
 909:                 // Don't change name of $recipient variable as it is used in plugins!
 910:                 $recipient   = new NewsletterRecipient;
 911:                 $recipient->loadByPrimaryKey($iID);
 912: 
 913:                 $sEMail  = $recipient->get("email");
 914:                 $sName   = $recipient->get("name");
 915:                 if (empty ($sName)) {
 916:                     $sName = $sEMail;
 917:                 }
 918:                 $sKey    = $recipient->get("hash");
 919: 
 920:                 $bSendHTML = false;
 921:                 if ($recipient->get("news_type") == 1) {
 922:                     $bSendHTML = true; // Recipient accepts html newsletter
 923:                 }
 924: 
 925:                 $this->_replaceTag($sRcpMsgText, false, "name", $sName);
 926:                 $this->_replaceTag($sRcpMsgText, false, "unsubscribe", $sPath."unsubscribe=".$sKey);
 927:                 $this->_replaceTag($sRcpMsgText, false, "change", $sPath."change=".$sKey);
 928:                 $this->_replaceTag($sRcpMsgText, false, "stop", $sPath."stop=".$sKey);
 929:                 $this->_replaceTag($sRcpMsgText, false, "goon", $sPath."goon=".$sKey);
 930: 
 931:                 // Replace message tags (html message)
 932:                 if ($bIsHTML && $bSendHTML) {
 933:                     $this->_replaceTag($sRcpMsgHTML, true, "name", $sName);
 934:                     $this->_replaceTag($sRcpMsgHTML, true, "unsubscribe", $sPath."unsubscribe=".$sKey);
 935:                     $this->_replaceTag($sRcpMsgHTML, true, "change", $sPath."change=".$sKey);
 936:                     $this->_replaceTag($sRcpMsgHTML, true, "stop", $sPath."stop=".$sKey);
 937:                     $this->_replaceTag($sRcpMsgHTML, true, "goon", $sPath."goon=".$sKey);
 938:                 }
 939: 
 940:                 if ($bPluginEnabled) {
 941:                     foreach ($aPlugins as $sPlugin => $aPluginVar) {
 942:                         foreach ($aPluginVar as $sPluginVar) {
 943:                             // Replace tags in text message
 944:                             $this->_replaceTag($sRcpMsgText, false, $sPluginVar, call_user_func("recipients_".$sPlugin."_getvalue", $sPluginVar));
 945:                             // Replace tags in html message
 946:                             if ($bIsHTML && $bSendHTML) {
 947:                                 $this->_replaceTag($sRcpMsgHTML, true, $sPluginVar, call_user_func("recipients_".$sPlugin."_getvalue", $sPluginVar));
 948:                             }
 949:                         }
 950:                     }
 951:                 }
 952: 
 953:                 if (cString::getStringLength($sKey) != 30) { // Prevents sending without having a key
 954:                     if ($contenido) { // Use i18n only in backend
 955:                         $sError = i18n("Newsletter to %s could not be sent: Recipient has an incompatible or empty key", "newsletter");
 956:                     } else {
 957:                         $sError = "Newsletter to %s could not be sent: Recipient has an incompatible or empty key";
 958:                     }
 959:                     $aMessages[] = $sName." (".$sEMail."): ".sprintf($sError, $sEMail);
 960:                 } elseif (!isValidMail($sEMail)) {
 961:                     if ($contenido) { // Use i18n only in backend
 962:                         $sError = i18n("Newsletter to %s could not be sent: No valid e-mail address specified", "newsletter");
 963:                     } else {
 964:                         $sError = "Newsletter to %s could not be sent: No valid e-mail address specified";
 965:                     }
 966:                     $aMessages[] = $sName." (".$sEMail."): ".sprintf($sError, $sEMail);
 967:                 } else {
 968:                     if ($bIsHTML && $bSendHTML) {
 969:                         $body = $sRcpMsgHTML;
 970:                     } else {
 971:                         $body = $sRcpMsgText."\n\n";
 972:                     }
 973: 
 974:                     if ($bIsHTML && $bSendHTML) {
 975:                         $contentType = 'text/html';
 976:                     } else {
 977:                         $contentType = 'text/plain';
 978:                     }
 979: 
 980:                     $mailer = new cMailer();
 981:                     $message = Swift_Message::newInstance($sSubject, $body, $contentType, $sEncoding);
 982:                     $message->setFrom($sFrom, $sFromName);
 983:                     $message->setTo($sEMail);
 984:                     $result = $mailer->send($message);
 985: 
 986:                     if ($result) {
 987:                         $aSendRcps[] = $sName." (".$sEMail.")";
 988:                     } else {
 989:                         if ($contenido) { // Use i18n only in backend
 990:                             $sError = i18n("Newsletter to %s could not be sent", "newsletter");
 991:                         } else {
 992:                             $sError = "Newsletter to %s could not be sent";
 993:                         }
 994:                         $aMessages[] = $sName." (".$sEMail."): ".sprintf($sError, $sEMail);
 995:                     }
 996:                 }
 997:             }
 998:         } else {
 999:             if ($contenido) { // Use i18n only in backend
1000:                 $sError = i18n("No recipient with specified recipient/group id %s/%s found", "newsletter");
1001:             } else {
1002:                 $sError = "No recipient with specified recpient/group id %s/%s found";
1003:             }
1004:             $aMessages[] = sprintf($sError, $iIDNewsRcp, $iIDNewsGroup);
1005:         }
1006: 
1007:         if (count($aMessages) > 0) {
1008:             $this->_sError = implode("<br>", $aMessages);
1009:             return false;
1010:         } else {
1011:             return true;
1012:         }
1013:     }
1014: }
1015: 
CMS CONTENIDO 4.10.1 API documentation generated by ApiGen 2.8.0