예제 #1
0
/**
 * prepares a weblogname so it can be used as a parameter in an URL
 * it it's us-ascii, it can be used straight away, otherwise it uses 
 * the index in $Weblogs
 *
 * @param string $weblog
 * @param array $categories
 * @return string
 */
function para_weblog($weblogkey, $categories = "")
{
    global $Weblogs;
    if ($categories != "") {
        $in_weblogs = find_weblogs_with_cat($categories);
        if (count($in_weblogs) != 0 && !in_array($weblogkey, $in_weblogs)) {
            $weblogkey = $in_weblogs[0];
        }
    }
    // We do 'allow' spaces in the names, but we need to represent them as
    // underscores. (even though i'm not sure this case is even possible)
    $weblog = str_replace(" ", "_", $weblogkey);
    // see if we need to represent the weblog name as a number to prevent problems:
    if ($weblog != urlencode($weblog)) {
        $keys = array_flip(array_keys($Weblogs));
        $parameter = $keys[$weblogkey];
    } else {
        $parameter = $weblog;
    }
    return safe_string($parameter);
}
예제 #2
0
/**
 * Checks if a word is part of the search index and if so sets the global variable
 * $matches to the matching entry codes.
 * 
 * @param string $word Word to search for.
 * @return boolean False if not found, else true.
 */
function getword($word)
{
    global $search_all, $Current_weblog, $index_file, $db, $matches;
    if (isset($index_file[$word[0]][$word])) {
        if (!isset($db)) {
            $db = new db();
        }
        $tmp_matches = explode("|", $index_file[$word[0]][$word]);
        // All entries should be searched.
        if ($search_all) {
            if (count($tmp_matches) > 0) {
                $matches[] = $tmp_matches;
                return TRUE;
            } else {
                return FALSE;
            }
        }
        // OK, we are run from a weblog - check if the matched entries
        // belong to the current weblog, and are still published,
        // i.e., not set on hold.
        foreach ($tmp_matches as $match) {
            $db->read_entry($match);
            $weblogs = find_weblogs_with_cat($db->entry['category']);
            if (in_array($Current_weblog, $weblogs) && $db->entry['status'] == "publish") {
                $valid_matches[] = $match;
            }
        }
        if (count($valid_matches) > 0) {
            $matches[] = $valid_matches;
            return TRUE;
        }
    }
    return FALSE;
}
예제 #3
0
/**
 * Get the TagCosmos. Preferably use the cached version, otherwise just make it
 * on the fly. (and then we store the cached version)
 *
 * If $max is given, it will return at most that many tags, ordered by size.
 * If $weblogname is given, only tags for that weblog will be returned.
 *
 * Returns an array with the following elements:
 * 'minvalue' => minimum value of a tag
 * 'maxvalue' => maximum value of a tag
 * 'amount' => number of tags
 * 'tags' => array of the tags. The indices are the tags, the values the number of occurences
 *
 * @param integer $max
 * @param string $weblogname 
 * @return array
 *
 */
function getTagCosmos($max = 0, $weblogname = '')
{
    global $Paths, $Cfg, $Weblogs;
    if ($weblogname == '' || $Cfg['weblog_count'] == 1) {
        $weblogname = '_all_';
    }
    // If the cached version is fresh enough, we restore that
    if (file_exists($Paths['pivot_path'] . "db/ser_tags.php") && filectime($Paths['pivot_path'] . "db/ser_tags.php") > time() - 60 * $Cfg['tag_cache_timeout']) {
        // Just load it..
        $data = load_serialize("db/ser_tags.php");
        $tagcosmos = $data[$weblogname];
    } else {
        // We have to read it..
        $tagcosmos = array();
        if ($Cfg['weblog_count'] > 1) {
            $temp_db = new db(FALSE);
        }
        foreach ($Weblogs as $weblog => $weblogdata) {
            $tagcosmos[$weblog] = array();
        }
        $tagdir = dir($Paths['pivot_path'] . "db/tagdata/");
        // Read all tags, build the tag index and save it or later.
        while (false !== ($entry = $tagdir->read())) {
            if (getextension($entry) == "tag") {
                list($tagname) = explode(".", $entry);
                $tagfile = implode("", file($Paths['pivot_path'] . "db/tagdata/" . $entry));
                $tagfile = explode(",", $tagfile);
                // If magic_quotes_gpc is set, we need to strip slashes..
                if (get_magic_quotes_gpc()) {
                    $tagname = stripslashes($tagname);
                }
                if ($tagname != "") {
                    $tagcosmos['_all_']['tags'][$tagname] = count($tagfile);
                    if ($Cfg['weblog_count'] > 1) {
                        foreach ($tagfile as $entrycode) {
                            $temp_entry = $temp_db->read_entry($entrycode);
                            $cat_weblogs = find_weblogs_with_cat($temp_entry['category']);
                            foreach ($cat_weblogs as $cat_weblog) {
                                $tagcosmos[$cat_weblog]['tags'][$tagname]++;
                            }
                        }
                    }
                }
            }
        }
        $tagdir->close();
        save_serialize($Paths['pivot_path'] . "db/ser_tags.php", $tagcosmos);
        $tagcosmos = $tagcosmos[$weblogname];
    }
    $tagcosmos['amount'] = count($tagcosmos['tags']);
    // if $max is given, we need to filter out the smaller tags, until the required size is reached.
    if ($max != 0 && $max < count($tagcosmos['tags'])) {
        arsort($tagcosmos['tags']);
        $tagcosmos['tags'] = array_slice($tagcosmos['tags'], 0, $max);
    }
    ksort($tagcosmos['tags']);
    $tagcosmos['minvalue'] = 1000;
    $tagcosmos['maxvalue'] = 0;
    // We determine what the min and max-value in the cosmos is.
    foreach ($tagcosmos['tags'] as $key => $value) {
        $tagcosmos['maxvalue'] = max($tagcosmos['maxvalue'], $value);
        $tagcosmos['minvalue'] = min($tagcosmos['minvalue'], $value);
    }
    return $tagcosmos;
}
예제 #4
0
/**
 * The screen you'll see after submitting an entry. It stores the entry, updates the indices (pivot's
 * content indices, and the search index), rebuilds the frontpage and XML & Atom feeds, and then it
 * displays a list of the latest entries.
 *
 */
function entrysubmit_screen()
{
    global $db, $config_array, $Pivot_Vars, $entry, $Cfg, $Users, $Paths, $Weblogs, $filtered_words;
    // check against unauthorised direct access.
    check_csrf();
    $db = new db();
    $entry = get_entry_from_post();
    if (!$entry['title'] == "" || !$entry['introduction'] == "" || !$entry['user'] == "") {
        // in this part, we remove the entry from the categories in which
        // the current user is not allowed to post entries
        foreach ($entry['category'] as $my_cat) {
            $allowed = explode("|", $Cfg['cat-' . $my_cat]);
            if (in_array($Pivot_Vars['user'], $allowed)) {
                $allowed_cats[] = $my_cat;
            } else {
                $message .= '<br />';
                $message .= sprintf(lang('entries', 'entry_catnopost'), $m_cat);
                debug("not in category: " . $my_cat);
            }
        }
        $entry['category'] = $allowed_cats;
        $db->set_entry($entry);
        if ($db->save_entry(TRUE)) {
            $message = sprintf(lang('entries', 'entry_saved_ok') . $message, '<i>' . trimtext($entry['title'], 25) . '</i>');
        } else {
            $message = sprintf(lang('entries', 'entry_saved_ok'), '<i>' . trimtext($entry['title'], 25) . '</i>');
        }
        // only trigger the ping if it's a new entry..
        if ($entry['code'] == ">" && $entry['status'] == "publish") {
            $ping = TRUE;
        } else {
            $ping = FALSE;
        }
        // only notify if entry is published, and is either new or status changed to publish.
        if ($entry['status'] == "publish") {
            if ($entry['code'] == ">" || $entry['oldstatus'] != "publish") {
                $notified = notify_new('entry', $db->entry);
                $notified = "<br /><br />" . $notified;
            }
        }
        // if the global index as they are made var is set - can continue
        if ('1' == $Cfg['search_index']) {
            /*
            			2004/10/16 =*=*= JM
            			an entry should only be indexed if both are true:
            			 - 'publish'==$entry['status']
            			 - current date is at least equal to $entry['publish_date']
            			I lie, there is another case...
            			it is conceivable that this is a timed publish AND the time has come
            			I will leave this to timed publish routines - if I can find them...
            			-> pvLib ... it's flagged
            and of course, providing that there is at least one
            			category where it would be indexed...
            something else that can't be tested... if the user changes a normal
            			publish to a timed-publish, or puts on hold when it was previously
            			normal. user should reindex in this case
            */
            // check status and date
            if ('publish' == $entry['status'] || 'timed' == $entry['status'] && $entry['publish_date'] <= date('Y-m-d-H-i')) {
                // categories...
                if (can_search_cats(cfg_cat_nosearchindex(), $entry['category'])) {
                    include_once 'modules/module_search.php';
                    update_index($db->entry);
                    debug('update search index: ' . $db->entry['code']);
                }
            }
        }
        // perhaps send a trackback ping.
        if ($Pivot_Vars['tb_url'] != "" && $entry['status'] == "publish") {
            debug("tburl: " . $Pivot_Vars['tb_url']);
            require_once 'includes/send_trackback.php';
            $weblogs = find_weblogs_with_cat($db->entry['category']);
            if (isset($Weblogs[$weblogs[0]])) {
                $my_url = $Paths['host'] . make_filelink($db->entry['code'], $weblogs[0], '');
                $weblog_title = $Weblogs[$weblogs[0]]['name'];
                debug("TRACKBACK ping: {$my_url}");
                $message .= '<br />';
                $message .= sprintf(lang('entries', 'entry_ping_sent'), $Pivot_Vars['tb_url']);
                $tb_urls = explode("\n", $Pivot_Vars['tb_url']);
                // make the contents of what to send with the trackback..
                $tb_contents = parse_step4($entry['introduction']);
                if ($Pivot_Vars['convert_lb'] == 2) {
                    $tb_contents = pivot_textile($tb_contents);
                } else {
                    if ($Pivot_Vars['convert_lb'] == 3 || $Pivot_Vars['convert_lb'] == 4) {
                        $tb_contents = pivot_markdown($tb_contents, $Pivot_Vars['convert_lb']);
                    }
                }
                $tb_contents = trimtext(strip_tags($tb_contents), 255);
                foreach ($tb_urls as $tb_url) {
                    $tb_url = trim($tb_url);
                    if (isurl($tb_url)) {
                        trackback_send($Pivot_Vars['tb_url'], $my_url, $entry['title'], $weblog_title, $tb_contents);
                    }
                }
            }
        }
        // Update the tags for this entry if it's published and remove the old tags if not
        if ($db->entry['status'] == 'publish') {
            writeTags($db->entry['keywords'], $_POST['f_keywords_old'], $db->entry['code']);
        } else {
            deleteTags($_POST['f_keywords_old'], $db->entry['code']);
        }
    }
    generate_pages($db->entry['code'], TRUE, TRUE, TRUE, $ping);
    entries_screen($message . $notified);
}
예제 #5
0
        if ($Pivot_Vars['c'] != "") {
            $in_weblogs = find_weblogs_with_cat($Pivot_Vars['c']);
            if (count($in_weblogs) != 0) {
                $override_weblog = $in_weblogs[0];
            }
        } else {
            reset($Weblogs);
            $override_weblog = key($Weblogs);
        }
    }
    $Pivot_Vars['w'] = $override_weblog;
} else {
    if ($Pivot_Vars['w'] != "") {
        // Both weblog and category has some value - checking if they match
        if ($Pivot_Vars['c'] != "") {
            $in_weblogs = find_weblogs_with_cat($Pivot_Vars['c']);
            if (!in_array($Pivot_Vars['w'], $in_weblogs)) {
                piv_error("Category/weblog mismatch", 'Category "' . htmlspecialchars($Pivot_Vars['c']) . "\" doesn't belong to selected weblog (" . htmlspecialchars($Pivot_Vars['w']) . ").");
            }
        }
    }
}
if (!isset($Pivot_Vars['c'])) {
    $Pivot_Vars['c'] = "";
}
if (!isset($Pivot_Vars['u'])) {
    $Pivot_Vars['u'] = "";
}
if (!isset($Pivot_Vars['t']) || empty($Pivot_Vars['t'])) {
    if ($Pivot_Vars['w'] != "") {
        $Pivot_Vars['t'] = basename($Weblogs[$Pivot_Vars['w']]['extra_template']);
예제 #6
0
function send_mail_comm()
{
    global $Cfg, $db, $my_comment, $ip, $date, $Weblogs, $Current_weblog, $Paths, $Users, $i18n_use;
    $cat_weblogs = find_weblogs_with_cat($db->entry['category']);
    $addr_arr = array();
    foreach ($cat_weblogs as $this_weblog) {
        if ($Weblogs[$this_weblog]['comment_sendmail'] == 1) {
            $addr_arr = array_merge($addr_arr, explode(",", $Weblogs[$this_weblog]['comment_emailto']));
        }
    }
    // make a nice title for the mail..
    if (strlen($db->entry['title']) > 2) {
        $title = $db->entry['title'];
        $title = strip_tags($title);
    } else {
        $title = substr($db->entry['introduction'], 0, 300);
        $title = strip_tags($title);
        $title = str_replace("\n", "", $title);
        $title = str_replace("\r", "", $title);
        $title = substr($title, 0, 60);
    }
    if (!$i18n_use) {
        $title = utf8_encode($title);
    }
    // maybe send some mail to authors..
    if (count($addr_arr) > 0) {
        $adminurl = $Paths['host'] . $Paths['pivot_url'] . "index.php?";
        $id = safe_string($my_comment["name"], TRUE) . "-" . format_date($my_comment["date"], "%ye%%month%%day%%hour24%%minute%");
        $editlink = $adminurl . "menu=entries&func=editcomments&id=" . $db->entry['code'];
        $approvelink = $adminurl . "menu=moderate_comments&" . urlencode($id) . "=1";
        $deletelink = $adminurl . "menu=moderate_comments&" . urlencode($id) . "=2";
        $blocklink = $adminurl . "menu=entries&func=editcomments&id=" . $db->entry['code'] . "&blocksingle=" . $my_comment['ip'];
        $comment = $my_comment['comment'];
        // $comment = unentify($comment);
        $body = sprintf(lang('comment', 'email_posted_comm') . ":\n\n", unentify($my_comment['name']));
        $body .= sprintf("%s", $comment);
        $body .= sprintf("\n\n-------------\n");
        $body .= sprintf(lang('weblog_text', 'name') . ": %s\n", unentify($my_comment['name']));
        $body .= sprintf(lang('weblog_text', 'ip') . ": %s\n", $my_comment['ip']);
        $body .= sprintf(lang('weblog_text', 'date') . ": %s\n", $my_comment['date']);
        $body .= trim(sprintf(lang('weblog_text', 'email') . ": %s", $my_comment['email'])) . "\n";
        $body .= trim(sprintf(lang('weblog_text', 'url') . ": %s\n", $my_comment['url'])) . "\n";
        $body .= sprintf("\n" . lang('comment', 'email_comm_on') . "\n", $title);
        if (count($notify_arr) > 0) {
            $body .= sprintf(lang('comment', 'notifications') . ": %s\n", implode(", ", array_keys($notify_arr)));
        }
        $body .= sprintf("-------------\n");
        if ($Cfg['moderate_comments'] == 1) {
            $body .= sprintf(lang('comment', 'email_allow_comm') . ":\n%s\n", $approvelink);
            $body .= sprintf("\n" . lang('comment', 'email_delete_comm') . ":\n%s\n", $deletelink);
        }
        $body .= sprintf("\n%s:\n%s%s\n", lang('comment', 'email_view_entry'), $Paths['host'], make_filelink("", "", ""));
        $body .= sprintf("\n%s:\n%s%s\n", lang('comment', 'email_view_comm'), $Paths['host'], make_filelink("", "", $id));
        $body .= sprintf("\n%s:\n%s\n", lang('comment', 'email_edit_comm'), $editlink);
        $body .= sprintf("\n%s:\n%s\n", lang('comment', 'email_block_ip'), $blocklink);
        if (!$i18n_use) {
            $body = utf8_encode($body);
        }
        $name = $my_comment['name'];
        if (!$i18n_use) {
            $name = utf8_encode($name);
        }
        $comment_name = '=?UTF-8?B?' . base64_encode($name) . '?=';
        if (isemail($my_comment['email'])) {
            $add_header = sprintf("From: \"%s\" <%s>\n", $comment_name, $my_comment['email']);
        } else {
            $add_header = sprintf("From: \"'%s'\" <%s>\n", $comment_name, $addr_arr[0]);
        }
        $add_header .= "MIME-Version: 1.0\n";
        $add_header .= "Content-Type: text/plain; charset=UTF-8; format=flowed\n";
        $add_header .= "Content-Transfer-Encoding: 8bit\n";
        $subject = lang('comment', 'email_subject_comm') . " Re: {$title}";
        $subject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
        $addr_arr = array_unique($addr_arr);
        foreach ($addr_arr as $addr) {
            $addr = trim($addr);
            @mail($addr, $subject, $body, $add_header);
            debug("Send Mail to {$addr} for '" . $my_comment['name'] . "'");
        }
    }
    // Handle the users that want to be notified via email..
    notify_new('comment', array($db->entry, $my_comment, $Cfg['moderate_comments']));
}
예제 #7
0
function snippet_previousentry($text = "", $cutoff = 20)
{
    global $db, $Current_weblog;
    // initialize a temporary db..
    $temp_db = new db(FALSE);
    // we fetch the next one, until we get one that is set to 'publish'
    $get_prev_amount = 1;
    do {
        $prev_code = $db->get_previous_code($get_prev_amount);
        if ($prev_code) {
            $temp_entry = $temp_db->read_entry($prev_code);
            $weblogs = find_weblogs_with_cat($temp_entry['category']);
            if (in_array($Current_weblog, $weblogs)) {
                $ok = true;
            } else {
                $ok = false;
            }
        }
        $get_prev_amount++;
    } while (!($prev_code === FALSE) && !($temp_entry['status'] == "publish" && $ok));
    unset($temp_db);
    if ('' == $text) {
        $text = '&laquo; <a href="%link%">%title%</a>';
    }
    if ($prev_code) {
        $title = strlen($temp_entry['title']) > 2 ? $temp_entry['title'] : substr($temp_entry['introduction'], 0, 100);
        $link = make_filelink($temp_entry, "", "");
        $output = "{$text}";
        $output = str_replace("%link%", $link, $output);
        $output = str_replace("%code%", $prev_code, $output);
        $output = str_replace("%title%", trimtext($title, $cutoff), $output);
        $output = str_replace("%subtitle%", trimtext($temp_entry['subtitle'], $cutoff), $output);
        return $output;
    } else {
        return "";
    }
}
예제 #8
0
 /**
  * Gets an array of archives - flat file implementation.
  *
  * Reads or creates/updates "db/ser-archives.php".
  *
  * @param boolean $force tells if "db/ser-archives.php" should be updated
  * @return array
  */
 function get_archive_array($force = FALSE)
 {
     global $pivot_path;
     if ($force || !file_exists($pivot_path . 'db/ser-archives.php')) {
         debug("REBUILD make_archive_array");
         $Archive_array = array();
         $lastdate = 0;
         ksort($this->date_index);
         foreach ($this->date_index as $code => $date) {
             $this->entry['code'] = $code;
             $this->check_current_index();
             $this->entry_from_indexline();
             if ($this->entry['status'] == 'publish') {
                 $in_weblogs = find_weblogs_with_cat($this->entry['category']);
                 foreach ($in_weblogs as $in_weblog) {
                     $name = make_archive_name($this->entry['date'], $in_weblog);
                     $Archive_array[$in_weblog][$name] = $this->entry['date'];
                 }
             }
         }
         // sort the array, to maintain correct order..
         foreach ($Archive_array as $key => $value) {
             krsort($Archive_array[$key]);
         }
         // save the archive_array, for easier retrieval next time..
         save_serialize($pivot_path . 'db/ser-archives.php', $Archive_array);
     } else {
         // just load the file, and get the last 3 entries. Much easier..
         $Archive_array = load_serialize($pivot_path . 'db/ser-archives.php');
         $entries_arr = $this->getlist(-3);
         // loop for all entries
         foreach ($entries_arr as $loopentry) {
             // Skipping entries on hold. (If the three last enries
             // are on hold this for loop does nothing.)
             if ($loopentry['status'] != "publish") {
                 continue;
             }
             // then loop for all the weblogs that publish this entry
             $in_weblogs = find_weblogs_with_cat($loopentry['category']);
             foreach ($in_weblogs as $in_weblog) {
                 $name = make_archive_name($loopentry['date'], $in_weblog);
                 $Archive_array[$in_weblog][$name] = $loopentry['date'];
             }
         }
         // sort the array, to maintain correct order..
         foreach ($Archive_array as $key => $value) {
             krsort($Archive_array[$key]);
         }
     }
     return $Archive_array;
 }
예제 #9
0
/**
 * Check if the w parameter is needed in Pivot
 * generated URL (for sites with multiple weblogs).
 *
 * Whenever a weblog is undetermined Pivot, resets
 * $Weblogs to get the key of the first weblog. We
 * are doing the same here.
 *
 * @return boolean
 * @param string $weblog Weblog to be examined.
 * @param array $categories
 */
function para_weblog_needed($weblog, $categories = "")
{
    global $Cfg, $Weblogs;
    reset($Weblogs);
    if ($Cfg['weblog_count'] > 1) {
        if ($categories != "") {
            $in_weblogs = find_weblogs_with_cat($categories);
            if (count($in_weblogs) != 0 && !in_array($weblog, $in_weblogs)) {
                return true;
            }
        }
        if (key($Weblogs) != $weblog) {
            return true;
        }
    }
    return false;
}
예제 #10
0
function send_mail_tb()
{
    global $Cfg, $entry, $PIV_PARA, $my_trackback, $Weblogs, $Current_weblog, $Paths, $Users, $i18n_use;
    $cat_weblogs = find_weblogs_with_cat($entry['category']);
    $addr_arr = array();
    foreach ($cat_weblogs as $this_weblog) {
        $Current_weblog = $this_weblog;
        // Using the same settings as for comments
        if ($Weblogs[$this_weblog]['comment_sendmail'] == 1) {
            $addr_arr = array_merge($addr_arr, explode(",", $Weblogs[$this_weblog]['comment_emailto']));
        }
    }
    // Make the array of user that want to be notified..
    $notify_arr = array();
    $title = $entry['title'];
    if (!$i18n_use) {
        $title = utf8_encode($title);
    }
    // maybe send some mail to authors..
    if (count($addr_arr) > 0 && !isset($PIV_PARA['f_comm_ip'])) {
        $adminurl = $Paths['host'] . $Paths['pivot_url'] . "index.php?";
        $id = format_date($my_trackback["date"], "%ye%%month%%day%%hour24%%minute%");
        $editlink = $adminurl . "menu=entries&func=edittrackbacks&id=" . $entry['code'];
        $blocklink = $adminurl . "menu=entries&func=edittrackbacks&id=" . $entry['code'] . "&blocksingle=" . $my_trackback['ip'];
        $body = sprintf(lang('comment', 'email_posted_tb') . ":", unentify($my_trackback['name']));
        $body .= sprintf("\n\n-------------\n");
        $body .= sprintf(lang('weblog_text', 'title') . ": %s\n", $my_trackback['title']);
        $body .= sprintf("%s", unentify($my_trackback['excerpt']));
        $body .= sprintf("\n-------------\n");
        $body .= sprintf(lang('weblog_text', 'ip') . ": %s\n", $my_trackback['ip']);
        $body .= sprintf(lang('weblog_text', 'date') . ": %s\n", $my_trackback['date']);
        $body .= sprintf(lang('weblog_text', 'url') . ": %s\n", $my_trackback['url']);
        $body .= sprintf("\n" . lang('comment', 'email_tb_on') . "\n", $title);
        if (count($notify_arr) > 0) {
            $body .= sprintf(lang('comment', 'notifications') . ": %s\n", implode(", ", $notify_arr));
        }
        $body .= sprintf("-------------\n");
        $body .= sprintf("%s:\n%s%s\n", lang('comment', 'email_view_entry'), $Paths['host'], make_filelink($PIV_PARA['f_comm_code'], "", $id));
        $body .= sprintf("\n%s:\n%s\n", lang('comment', 'email_edit_tb'), $editlink);
        $body .= sprintf("\n%s:\n%s\n", lang('comment', 'email_block_ip'), $blocklink);
        if (!$i18n_use) {
            $body = utf8_encode($body);
        }
        $contact_addr = $Users[$entry['user']]['email'];
        $user = $Users[$entry['user']]['nick'];
        if (empty($user)) {
            $user = $entry['user'];
        }
        $contact_name = '=?UTF-8?B?' . base64_encode($user) . '?=';
        $add_header = sprintf("From: \"'%s'\" <%s>\n", $contact_name, $contact_addr);
        $add_header .= "MIME-Version: 1.0\n";
        $add_header .= "Content-Type: text/plain; charset=UTF-8; format=flowed\n";
        $add_header .= "Content-Transfer-Encoding: 8bit\n";
        $subject = lang('trackback', 'email_subject') . " " . $title;
        $subject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
        foreach ($addr_arr as $addr) {
            $addr = trim($addr);
            @mail($addr, $subject, $body, $add_header);
            debug("Sent Mail to {$addr} for '" . $my_trackback['name'] . "'");
        }
    }
}