Exemplo n.º 1
0
 private function getTemplateImages($templateid, $filename)
 {
     if (basename($filename) == 'powerphplist.png') {
         $templateid = 0;
     }
     $result = phpList::DB()->query(sprintf('SELECT data FROM %s
         WHERE template = %s
         AND (filename = "%s" or filename = "%s")', Config::getTableName('templateimage'), $templateid, $filename, basename($filename)));
     return $result->fetchColumn(0);
 }
Exemplo n.º 2
0
 /**
  * PHP >= 5.4.0<br/>
  * Write session data
  * @link http://php.net/manual/en/sessionhandlerinterafce.write.php
  * @param string $session_id The session id.
  * @param string $session_data <p>
  * The encoded session data. This data is the
  * result of the PHP internally encoding
  * the $_SESSION superglobal to a serialized
  * string and passing it as this parameter.
  * Please note sessions use an alternative serialization method.
  * </p>
  * @return bool <p>
  * The return value (usually TRUE on success, FALSE on failure).
  * Note this value is returned internally to PHP for processing.
  * </p>
  */
 public function write($session_id, $session_data)
 {
     $session_id = addslashes($session_id);
     $session_data = addslashes($session_data);
     $session_exists = phpList::DB()->query(sprintf('SELECT COUNT(*) FROM  %s
             WHERE sessionid = \'%s\'', Config::SESSION_TABLENAME, addslashes($session_id)))->fetchColumn(0);
     if ($session_exists <= 0) {
         $retval = phpList::DB()->query(sprintf('INSERT INTO %s (sessionid,lastactive,data)
                 VALUES("%s",UNIX_TIMESTAMP(NOW()),"%s")', Config::SESSION_TABLENAME, $session_id, $session_data));
     } else {
         $retval = phpList::DB()->query(sprintf('UPDATE %s
                 SET data = "%s", lastactive = UNIX_TIMESTAMP(NOW())
                 WHERE sessionid = "%s"', Config::SESSION_TABLENAME, $session_id, $session_data));
         if ($retval->rowCount() <= 0) {
             //TODO: correct error handling
             phpList::log()->notice('unable to update session data for session ' . $session_id);
             sendError('unable to update session data for session ' . $session_id);
         }
     }
     return $retval;
 }
Exemplo n.º 3
0
 /**
  * Porcess the bounce data and update the database
  * @param Bounce $bounce
  * @param int $campaign_id
  * @param Subscriber $subscriber
  * @return bool
  */
 private function processBounceData($bounce, $campaign_id, $subscriber)
 {
     if ($campaign_id === 'systemmessage' && $subscriber !== false) {
         $bounce->status = 'bounced system message';
         $bounce->comment = sprintf('%s marked unconfirmed', $subscriber->id);
         $bounce->update();
         phpList::log()->notice($subscriber->id . ' ' . s('system message bounced, subscriber marked unconfirmed'));
         $subscriber->addHistory(s('Bounced system message'), sprintf('<br/>%s<br/><a href="./?page=bounce&amp;id=%d">%s</a>', s('Subscriber marked unconfirmed'), $bounce->id, s('View Bounce')), $subscriber->id);
         $subscriber->confirmed = 0;
         $subscriber->update();
     } elseif (!empty($campaign_id) && $subscriber !== false) {
         $bounce->connectMeToSubscriberAndMessage($subscriber, $campaign_id);
     } elseif ($subscriber !== false) {
         $bounce->status = 'bounced unidentified message';
         $bounce->comment = $subscriber->id . ' bouncecount increased';
         $bounce->update();
         $subscriber->bouncecount++;
         $subscriber->update();
     } elseif ($campaign_id === 'systemmessage') {
         $bounce->status = 'bounced system message';
         $bounce->comment = 'unknown subscriber';
         $bounce->update();
         phpList::log()->notice($subscriber->id . ' ' . s('system message bounced, but unknown subscriber'));
     } elseif ($campaign_id) {
         $bounce->status = sprintf('bounced list message %d', $campaign_id);
         $bounce->comment = 'unknown subscriber';
         $bounce->update();
         phpList::DB()->query(sprintf('UPDATE %s
                  SET bouncecount = bouncecount + 1
                  WHERE id = %d', Config::getTableName('message'), $campaign_id));
     } else {
         $bounce->status = 'unidentified bounce';
         $bounce->comment = 'not processed';
         $bounce->update();
         return false;
     }
     return true;
 }
Exemplo n.º 4
0
 /**
  * Check if a form token is valid
  * @param string $token
  * @return bool
  */
 public function verifyToken($token)
 {
     if (empty($token)) {
         return false;
     }
     ## @@@TODO for now ignore the error. This will cause a block on editing admins if the table doesn't exist.
     $result = phpList::DB()->prepare(sprintf('SELECT id FROM %s
             WHERE adminid = %d
             AND value = :token
             AND expires > CURRENT_TIMESTAMP', Config::getTableName('admintoken'), $this->id));
     $result->execute(array(':token' => $token));
     return $result->rowCount() > 0;
 }
Exemplo n.º 5
0
 public static function releaseLock($processid)
 {
     if (!$processid) {
         return;
     }
     phpList::DB()->query('DELETE FROM %s
         WHERE id = %d', Config::getTableName('sendprocess'), $processid);
 }
Exemplo n.º 6
0
 public static function flushClickTrackCache()
 {
     if (count(Cache::$_instance->linktrack_sent_cache) == 0) {
         return;
     }
     foreach (Cache::$_instance->linktrack_sent_cache as $mid => $numsent) {
         foreach ($numsent as $fwdid => $fwdtotal) {
             if (Config::VERBOSE) {
                 phpList::log()->debug("Flushing clicktrack stats for {$mid}: {$fwdid} => {$fwdtotal}", ['page' => 'cache']);
             }
             phpList::DB()->query(sprintf('UPDATE %s SET total = %d
                     WHERE messageid = %d
                     AND forwardid = %d', Config::getTableName('linktrack_ml'), $fwdtotal, $mid, $fwdid));
         }
     }
 }
Exemplo n.º 7
0
 /**
  * Load campaign in memory cache
  * @param Campaign $campaign
  * @param bool $forwardContent
  * @return bool
  */
 public static function precacheCampaign($campaign, $forwardContent = false)
 {
     $domain = Config::get('domain');
     /**
      * @var Campaign $cached_campaign
      */
     $cached_campaign =& Cache::getCachedCampaign($campaign);
     ## the reply to is actually not in use
     if (preg_match('/([^ ]+@[^ ]+)/', $campaign->replyto, $regs)) {
         # if there is an email in the from, rewrite it as "name <email>"
         $campaign->replyto = str_replace($regs[0], '', $campaign->replyto);
         $cached_campaign->replytoemail = $regs[0];
         # if the email has < and > take them out here
         $cached_campaign->replytoemail = str_replace(array('<', '>'), '', $cached_campaign->replytoemail);
         //$cached->replytoemail = str_replace('>', '', $cached->replytoemail);
         # make sure there are no quotes around the name
         $cached_campaign->replytoname = str_replace('"', '', ltrim(rtrim($campaign->replyto)));
     } elseif (strpos($campaign->replyto, ' ')) {
         # if there is a space, we need to add the email
         $cached_campaign->replytoname = $campaign->replyto;
         $cached_campaign->replytoemail = "listmaster@{$domain}";
     } else {
         if (!empty($campaign->replyto)) {
             $cached_campaign->replytoemail = "{$campaign->replyto}@{$domain}";
             ## makes more sense not to add the domain to the word, but the help says it does
             ## so let's keep it for now
             $cached_campaign->replytoname = "{$campaign->replyto}@{$domain}";
         }
     }
     //$cached_campaign->fromname = $campaign->fromname;
     //$cached_campaign->fromemail = $campaign->fromemail;
     $cached_campaign->to = $campaign->tofield;
     #0013076: different content when forwarding 'to a friend'
     $cached_campaign->subject = $forwardContent ? stripslashes($campaign->forwardsubject) : $campaign->subject;
     #0013076: different content when forwarding 'to a friend'
     $cached_campaign->content = $forwardContent ? stripslashes($campaign->forwardcampaign) : $campaign->campaign;
     if (Config::USE_MANUAL_TEXT_PART && !$forwardContent) {
         $cached_campaign->textcontent = $campaign->textcampaign;
     } else {
         $cached_campaign->textcontent = '';
     }
     #var_dump($cached);exit;
     #0013076: different content when forwarding 'to a friend'
     $cached_campaign->footer = $forwardContent ? stripslashes($campaign->forwardfooter) : $campaign->footer;
     if (strip_tags($cached_campaign->footer) != $cached_campaign->footer) {
         $cached_campaign->textfooter = String::HTML2Text($cached_campaign->footer);
         $cached_campaign->htmlfooter = $cached_campaign->footer;
     } else {
         $cached_campaign->textfooter = $cached_campaign->footer;
         $cached_campaign->htmlfooter = PrepareCampaign::parseText($cached_campaign->footer);
     }
     $cached_campaign->htmlformatted = strip_tags($cached_campaign->content) != $cached_campaign->content;
     //$cached_campaign->sendformat = $campaign->sendformat;
     ## @@ put this here, so it can become editable per email sent out at a later stage
     $cached_campaign->html_charset = 'UTF-8';
     #Config::get('html_charset');
     ## @@ need to check on validity of charset
     /*if (!$cached_campaign->html_charset) {
           $cached_campaign->html_charset = 'UTF-8'; #'iso-8859-1';
       }*/
     $cached_campaign->text_charset = 'UTF-8';
     #Config::get('text_charset');
     /*if (!$cached_campaign->text_charset) {
           $cached_campaign->text_charset = 'UTF-8'; #'iso-8859-1';
       }*/
     ## if we are sending a URL that contains subscriber attributes, we cannot pre-parse the campaign here
     ## but that has quite some impact on speed. So check if that's the case and apply
     $cached_campaign->subscriberspecific_url = preg_match('/\\[.+\\]/', $campaign->sendurl);
     if (!$cached_campaign->subscriberspecific_url) {
         ## Fetch external content here, because URL does not contain placeholders
         if (Config::get('canFetchUrl') && preg_match('/\\[URL:([^\\s]+)\\]/i', $cached_campaign->content, $regs)) {
             $remote_content = Util::fetchUrl($regs[1]);
             #  $remote_content = fetchUrl($campaign['sendurl'],array());
             # @@ don't use this
             #      $remote_content = includeStyles($remote_content);
             if ($remote_content) {
                 $cached_campaign->content = str_replace($regs[0], $remote_content, $cached_campaign->content);
                 #  $cached[$campaign_id]['content'] = $remote_content;
                 $cached_campaign->htmlformatted = strip_tags($remote_content) != $remote_content;
             } else {
                 #print Error(s('unable to fetch web page for sending'));
                 phpList::log()->notice("Error fetching URL: " . $campaign->sendurl . ' cannot proceed');
                 return false;
             }
         }
         if (Config::VERBOSE && Config::get('getspeedstats', false) !== false) {
             phpList::log()->debug('fetch URL end', ['page' => 'preparecampaign']);
         }
         /*
         print $campaign->sendurl;
         print $remote_content;exit;
         */
     }
     // end if not subscriberspecific url
     /*if ($cached_campaign->htmlformatted) {
           #   $cached->content = String::compressContent($cached->content);
       }*/
     //$cached_campaign->google_track = $campaign->google_track;
     /*
         else {
     print $campaign->sendurl;
     exit;
     }
     */
     if (Config::VERBOSE && Config::get('getspeedstats', false) !== false) {
         phpList::log()->debug('parse config start', ['page' => 'preparecampaign']);
     }
     /*
              * this is not a good idea, as it'll replace eg "unsubscribeurl" with a general one instead of personalised
              *   if (is_array($GLOBALS['default_config'])) {
       foreach($GLOBALS['default_config'] as $key => $val) {
         if (is_array($val)) {
           $cached[$campaign_id]['content'] = str_ireplace("[$key]",Config::get($key),$cached[$campaign_id]['content']);
           $cached->textcontent = str_ireplace("[$key]",Config::get($key),$cached->textcontent);
           $cached->textfooter = str_ireplace("[$key]",Config::get($key),$cached[$campaign_id]['textfooter']);
           $cached->htmlfooter = str_ireplace("[$key]",Config::get($key),$cached[$campaign_id]['htmlfooter']);
         }
       }
     }
     */
     if (Config::VERBOSE && Config::get('getspeedstats', false) !== false) {
         phpList::log()->debug('parse config end', ['page' => 'preparecampaign']);
     }
     /*TODO: figure out what this does
       foreach ($campaign as $key => $val) {
           if (!is_array($val)) {
               $cached_campaign->content = str_ireplace("[$key]", $val, $cached_campaign->content);
               $cached_campaign->textcontent = str_ireplace("[$key]", $val, $cached_campaign->textcontent);
               $cached_campaign->textfooter = str_ireplace("[$key]", $val, $cached_campaign->textfooter);
               $cached_campaign->htmlfooter = str_ireplace("[$key]", $val, $cached_campaign->htmlfooter);
           }
       }*/
     if (preg_match("/##LISTOWNER=(.*)/", $cached_campaign->content, $regs)) {
         $cached_campaign->listowner = $regs[1];
         $cached_campaign->content = str_replace($regs[0], '', $cached_campaign->content);
     } else {
         $cached_campaign->listowner = 0;
     }
     if (!empty($cached_campaign->listowner)) {
         $att_result = phpList::DB()->query(sprintf('SELECT name,value FROM %s AS aa, %s AS a_a
             WHERE aa.id = a_a.adminattributeid AND aa.adminid = %d', Config::getTableName('adminattribute'), Config::getTableName('admin_attribute'), $cached_campaign->listowner));
         while ($att = $att_result->fetch(\PDO::FETCH_ASSOC)) {
             $cached_campaign->content = preg_replace('#\\[LISTOWNER.' . strtoupper(preg_quote($att['name'])) . '\\]#', $att['value'], $cached_campaign->content);
         }
     }
     $baseurl = Config::get('website');
     if (Config::UPLOADIMAGES_DIR != null) {
         ## escape subdirectories, otherwise this renders empty
         $dir = str_replace('/', '\\/', Config::UPLOADIMAGES_DIR);
         $cached_campaign->content = preg_replace('/<img(.*)src="\\/' . $dir . '(.*)>/iU', '<img\\1src="' . Config::get('public_scheme') . '://' . $baseurl . '/' . Config::UPLOADIMAGES_DIR . '\\2>', $cached_campaign->content);
     }
     //if (defined('FCKIMAGES_DIR') && FCKIMAGES_DIR) {
     //$cached[$campaign_id]['content'] = preg_replace('/<img(.*)src="\/lists\/'.FCKIMAGES_DIR.'(.*)>/iU','<img\\1src="'.$GLOBALS['public_scheme'].'://'.$baseurl.'/lists/'.FCKIMAGES_DIR.'\\2>',$cached[$campaign_id]['content']);
     //}
     return true;
 }
Exemplo n.º 8
0
 /**
  * Check if restrictions have been set
  * @param int $max
  * @return array
  */
 private function checkRestrictions($max = 0)
 {
     $maxbatch = -1;
     $minbatchperiod = -1;
     # check for batch limits
     $restrictions = array();
     $restrictions['rules'] = '';
     $restrictions['locked'] = false;
     if ($fp = @fopen('/etc/phplist.conf', 'r')) {
         $contents = fread($fp, filesize('/etc/phplist.conf'));
         fclose($fp);
         $lines = explode("\n", $contents);
         $restrictions['rules'] = s('The following restrictions have been set by your ISP:') . "\n";
         foreach ($lines as $line) {
             list($key, $val) = explode("=", $line);
             switch ($key) {
                 case 'maxbatch':
                     $maxbatch = sprintf('%d', $val);
                     $restrictions['rules'] .= "{$key} = {$val}\n";
                     break;
                 case 'minbatchperiod':
                     $minbatchperiod = sprintf('%d', $val);
                     $restrictions['rules'] .= "{$key} = {$val}\n";
                     break;
                 case 'lockfile':
                     $restrictions['locked'] = is_file($val);
             }
         }
     }
     if (Config::MAILQUEUE_BATCH_SIZE) {
         if ($maxbatch > 0) {
             $this->num_per_batch = min(Config::MAILQUEUE_BATCH_SIZE, $maxbatch);
         } else {
             $this->num_per_batch = sprintf('%d', Config::MAILQUEUE_BATCH_SIZE);
         }
     } else {
         if ($maxbatch > 0) {
             $this->num_per_batch = $maxbatch;
         }
     }
     if (Config::MAILQUEUE_BATCH_PERIOD) {
         if ($minbatchperiod > 0) {
             $this->batch_period = max(Config::MAILQUEUE_BATCH_PERIOD, $minbatchperiod);
         } else {
             $this->batch_period = Config::MAILQUEUE_BATCH_PERIOD;
         }
     }
     ## force batch processing in small batches when called from the web interface
     /*
      * bad idea, we shouldn't touch the batch settings, in case they are very specific for
      * ISP restrictions, instead limit webpage processing by time (below)
      *
     if (empty($GLOBALS['commandline'])) {
       $this->num_per_batch = min($this->num_per_batch,100);
       $this->batch_period = max($this->batch_period,1);
     } elseif (isset($cline['m'])) {
       $cl_num_per_batch = sprintf('%d',$cline['m']);
       ## don't block when the param is not a number
       if (!empty($cl_num_per_batch)) {
         $this->num_per_batch = $cl_num_per_batch;
       }
       Output::cl_output("Batch set with commandline to $this->num_per_batch");
     }
     */
     $max_process_queue_time = 0;
     if (Config::MAX_PROCESSQUEUE_TIME > 0) {
         $max_process_queue_time = (int) Config::MAX_PROCESSQUEUE_TIME;
     }
     # in-page processing force to a minute max, and make sure there's a batch size
     if (Config::get('commandline', false) === false) {
         $max_process_queue_time = min($max_process_queue_time, 60);
         if ($this->num_per_batch <= 0) {
             $this->num_per_batch = 10000;
         }
     }
     $restrictions['max_process_queue_time'] = $max_process_queue_time;
     if (Config::VERBOSE && $max_process_queue_time) {
         phpList::log()->debug(s('Maximum time for queue processing') . ': ' . $max_process_queue_time, ['page' => 'porcessqueue']);
     }
     if ($max > 0) {
         phpList::log()->info('Max to send is ' . $max . ' num per batch is ' . $this->num_per_batch, ['page' => 'processqueue']);
         $clinemax = (int) $max;
         ## slow down just before max
         if ($clinemax < 20) {
             $this->num_per_batch = min(2, $clinemax, $this->num_per_batch);
         } elseif ($clinemax < 200) {
             $this->num_per_batch = min(20, $clinemax, $this->num_per_batch);
         } else {
             $this->num_per_batch = min($clinemax, $this->num_per_batch);
         }
         phpList::log()->info('Max to send is ' . $max . ' setting num per batch to ' . $this->num_per_batch, ['page' => 'processqueue']);
     }
     if (ini_get('safe_mode')) {
         # keep an eye on timeouts
         $this->safemode = true;
         $this->num_per_batch = min(100, $this->num_per_batch);
         phpList::log()->notice(s('Running in safe mode') . "\n" . s('In safe mode, batches are set to a maximum of 100'), ['page' => 'processqueue']);
     }
     $recently_sent = 0;
     $this->original_num_per_batch = $this->num_per_batch;
     if ($this->num_per_batch && $this->batch_period) {
         # check how many were sent in the last batch period and subtract that
         # amount from this batch
         /*
           phpList::log()->debug(sprintf('select count(*) from %s where entered > date_sub(current_timestamp,interval %d second) and status = "sent"',
             $tables['usermessage'],$this->batch_period));
         */
         $result = phpList::DB()->query(sprintf('SELECT COUNT(*) FROM %s
                 WHERE entered > date_sub(CURRENT_TIMESTAMP,INTERVAL %d second)
                 AND status = "sent"', Config::getTableName('usermessage'), $this->batch_period));
         $recently_sent = $result->fetchColumn(0);
         phpList::log()->info('Recently sent : ' . $recently_sent, ['page' => 'processqueue']);
         $this->num_per_batch -= $recently_sent;
         # if this ends up being 0 or less, don't send anything at all
         if ($this->num_per_batch == 0) {
             $this->num_per_batch = -1;
         }
     }
     $restrictions['recently_sent'] = $recently_sent;
     return $restrictions;
 }