diff options
author | Alexander Kampmann <programmer@nurfuerspam.de> | 2012-03-01 11:49:22 +0100 |
---|---|---|
committer | Alexander Kampmann <programmer@nurfuerspam.de> | 2012-03-01 11:49:22 +0100 |
commit | dd9432903ddb3e12381881da44fb84afff832d52 (patch) | |
tree | b499e77cd4faf8157c2e048fb8242bc2ca2720cc /include | |
parent | e0c659b34b8992111bcc64d3f0eea75dfa193412 (diff) | |
parent | bd2c8c92f1b30d8f811bd4aab0fe3a2c5496ec61 (diff) | |
download | volse-hubzilla-dd9432903ddb3e12381881da44fb84afff832d52.tar.gz volse-hubzilla-dd9432903ddb3e12381881da44fb84afff832d52.tar.bz2 volse-hubzilla-dd9432903ddb3e12381881da44fb84afff832d52.zip |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'include')
-rwxr-xr-x | include/Scrape.php | 32 | ||||
-rwxr-xr-x | include/bb2diaspora.php | 32 | ||||
-rw-r--r--[-rwxr-xr-x] | include/bbcode.php | 7 | ||||
-rwxr-xr-x | include/config.php | 2 | ||||
-rwxr-xr-x | include/conversation.php | 20 | ||||
-rwxr-xr-x | include/delivery.php | 38 | ||||
-rwxr-xr-x | include/diaspora.php | 12 | ||||
-rwxr-xr-x | include/email.php | 200 | ||||
-rwxr-xr-x | include/enotify.php | 231 | ||||
-rwxr-xr-x | include/event.php | 2 | ||||
-rwxr-xr-x | include/html2bbcode.php | 6 | ||||
-rw-r--r-- | include/html2plain.php | 180 | ||||
-rwxr-xr-x | include/items.php | 69 | ||||
-rwxr-xr-x | include/network.php | 59 | ||||
-rwxr-xr-x | include/notifier.php | 24 | ||||
-rwxr-xr-x | include/plugin.php | 9 | ||||
-rwxr-xr-x | include/poller.php | 72 | ||||
-rw-r--r-- | include/quoteconvert.php | 132 | ||||
-rwxr-xr-x | include/template_processor.php | 23 | ||||
-rwxr-xr-x | include/text.php | 15 |
20 files changed, 914 insertions, 251 deletions
diff --git a/include/Scrape.php b/include/Scrape.php index 52405ae2d..4c4ad3cdb 100755 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -230,11 +230,16 @@ function scrape_feed($url) { $ret = array(); $s = fetch_url($url); - if(! $s) + $headers = $a->get_curl_headers(); + $code = $a->get_curl_code(); + + logger('scrape_feed: returns: ' . $code . ' headers=' . $headers, LOGGER_DEBUG); + + if(! $s) { + logger('scrape_feed: no data returned for ' . $url); return $ret; + } - $headers = $a->get_curl_headers(); - logger('scrape_feed: headers=' . $headers, LOGGER_DEBUG); $lines = explode("\n",$headers); if(count($lines)) { @@ -258,8 +263,10 @@ function scrape_feed($url) { logger('scrape_feed: parse error: ' . $e); } - if(! $dom) + if(! $dom) { + logger('scrape_feed: failed to parse.'); return $ret; + } $head = $dom->getElementsByTagName('base'); @@ -445,10 +452,19 @@ function probe_url($url, $mode = PROBE_NORMAL) { $adr = imap_rfc822_parse_adrlist($x->to,''); if(isset($adr)) { foreach($adr as $feadr) { - if((strcasecmp($feadr->mailbox,$name) == 0) - &&(strcasecmp($feadr->host,$phost) == 0) + if((strcasecmp($feadr->mailbox,$name) == 0) + &&(strcasecmp($feadr->host,$phost) == 0) && (strlen($feadr->personal))) { - $vcard['fn'] = notags($feadr->personal); + + $personal = imap_mime_header_decode($feadr->personal); + $vcard['fn'] = ""; + foreach($personal as $perspart) + if ($perspart->charset != "default") + $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text); + else + $vcard['fn'] .= $perspart->text; + + $vcard['fn'] = notags($vcard['fn']); } } } @@ -556,7 +572,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { if($check_feed) { $feedret = scrape_feed(($poll) ? $poll : $url); - logger('probe_url: scrape_feed returns: ' . print_r($feedret,true), LOGGER_DATA); + logger('probe_url: scrape_feed ' . (($poll)? $poll : $url) . ' returns: ' . print_r($feedret,true), LOGGER_DATA); if(count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) { $poll = ((x($feedret,'feed_atom')) ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss'])); if(! x($vcard)) diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index bcef86616..8487f845a 100755 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -55,42 +55,12 @@ function diaspora2bb($s) { $s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s); // Don't show link to full picture (until it is fixed) - $s = scale_diaspora_images($s, false); + $s = scale_external_images($s, false); return $s; } -function scale_diaspora_images($s,$include_link = true) { - - $matches = null; - $c = preg_match_all('/\[img\](.*?)\[\/img\]/ism',$s,$matches,PREG_SET_ORDER); - if($c) { - require_once('include/Photo.php'); - foreach($matches as $mtch) { - logger('scale_diaspora_image: ' . $mtch[1]); - $i = fetch_url($mtch[1]); - if($i) { - $ph = new Photo($i); - if($ph->is_valid()) { - if($ph->getWidth() > 600 || $ph->getHeight() > 600) { - $ph->scaleImage(600); - $new_width = $ph->getWidth(); - $new_height = $ph->getHeight(); - logger('scale_diaspora_image: ' . $new_width . 'w ' . $new_height . 'h' . 'match: ' . $mtch[0], LOGGER_DEBUG); - $s = str_replace($mtch[0],'[img=' . $new_width . 'x' . $new_height. ']' . $mtch[1] . '[/img]' - . "\n" . (($include_link) - ? '[url=' . $mtch[1] . ']' . t('view full size') . '[/url]' . "\n" - : ''),$s); - logger('scale_diaspora_image: new string: ' . $s, LOGGER_DEBUG); - } - } - } - } - } - return $s; -} - function stripdcode_br_cb($s) { return '[code]' . str_replace('<br />', "\n\t", $s[1]) . '[/code]'; } diff --git a/include/bbcode.php b/include/bbcode.php index 32053b4ec..cff26f5c8 100755..100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -151,7 +151,7 @@ function bbcode($Text,$preserve_nl = false) { // handle nested lists $endlessloop = 0; - while (strpos($Text, "[/list]") and strpos($Text, "[list") and (++$endlessloop < 20)) { + while ((strpos($Text, "[/list]") !== false) and (strpos($Text, "[list") !== false) and (++$endlessloop < 20)) { $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet" style="list-style-type: circle;">$1</ul>' ,$Text); $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>' ,$Text); $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>' ,$Text); @@ -194,7 +194,7 @@ function bbcode($Text,$preserve_nl = false) { // Check for [quote] text // handle nested quotes $endlessloop = 0; - while (strpos($Text, "[/quote]") !== false and strpos($Text, "[quote]") !== false and (++$endlessloop < 20)) + while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20)) $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism","$QuoteLayout", $Text); // Check for [quote=Author] text @@ -203,7 +203,7 @@ function bbcode($Text,$preserve_nl = false) { // handle nested quotes $endlessloop = 0; - while (strpos($Text, "[/quote]") !== false and strpos($Text, "[quote=") !== false and (++$endlessloop < 20)) + while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20)) $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism", "<blockquote><strong>" . $t_wrote . "</strong> $2</blockquote>", $Text); @@ -285,3 +285,4 @@ function bbcode($Text,$preserve_nl = false) { return $Text; } + diff --git a/include/config.php b/include/config.php index 92694f519..2cddda0b8 100755 --- a/include/config.php +++ b/include/config.php @@ -162,7 +162,7 @@ function del_config($family,$key) { if(x($a->config[$family],$key)) unset($a->config[$family][$key]); $ret = q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1", - dbesc($cat), + dbesc($family), dbesc($key) ); return $ret; diff --git a/include/conversation.php b/include/conversation.php index 3d13a1179..2ef37694d 100755 --- a/include/conversation.php +++ b/include/conversation.php @@ -6,6 +6,11 @@ function localize_item(&$item){ $Text = $item['body']; + + + // find private image (w/data url) if present and convert image + // link to a magic-auth redirect. + $saved_image = ''; $img_start = strpos($Text,'[img]data:'); $img_end = strpos($Text,'[/img]'); @@ -232,7 +237,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $alike = array(); $dlike = array(); - + $o = ""; // array with html for each thread (parent+comments) $threads = array(); @@ -403,6 +408,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $toplevelprivate = false; // Take care of author collapsing and comment collapsing + // (author collapsing is currently disabled) // If a single author has more than 3 consecutive top-level posts, squash the remaining ones. // If there are more than two comments, squash all but the last 2. @@ -410,7 +416,9 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $toplevelprivate = (($toplevelpost && $item['private']) ? true : false); $item_writeable = (($item['writable'] || $item['self']) ? true : false); - /*if($blowhard == $item['cid'] && (! $item['self']) && ($mode != 'profile') && ($mode != 'notes')) { + // DISABLED + /* + if($blowhard == $item['cid'] && (! $item['self']) && ($mode != 'profile') && ($mode != 'notes')) { $blowhard_count ++; if($blowhard_count == 3) { $o .= '<div class="icollapse-wrapper fakelink" id="icollapse-wrapper-' . $item['parent'] @@ -424,7 +432,9 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { if($blowhard_count >= 3) $o .= '</div>'; $blowhard_count = 0; - }*/ + } + // END DISABLED + */ $comments_seen = 0; $comments_collapsed = false; @@ -436,7 +446,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { } else { // prevent private email from leaking into public conversation - if((! $toplevelpost) && (! toplevelprivate) && ($item['private']) && ($profile_owner != local_user())) + if((! $toplevelpost) && (! $toplevelprivate) && ($item['private']) && ($profile_owner != local_user())) continue; $comments_seen ++; } @@ -641,7 +651,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $body = prepare_body($item,true); $tmp_item = replace_macros($template,array( - '$type' => implode("",array_slice(split("/",$item['verb']),-1)), + '$type' => implode("",array_slice(explode("/",$item['verb']),-1)), '$tags' => $tags, '$body' => template_escape($body), '$id' => $item['item_id'], diff --git a/include/delivery.php b/include/delivery.php index cbf602a0b..c1ff07bd5 100755 --- a/include/delivery.php +++ b/include/delivery.php @@ -1,6 +1,7 @@ <?php require_once("boot.php"); require_once('include/queue_fn.php'); +require_once('include/html2plain.php'); function delivery_run($argv, $argc){ global $a, $db; @@ -8,7 +9,7 @@ function delivery_run($argv, $argc){ if(is_null($a)){ $a = new App; } - + if(is_null($db)) { @include(".htconfig.php"); require_once("dba.php"); @@ -293,7 +294,7 @@ function delivery_run($argv, $argc){ $sql_extra = sprintf(" AND `dfrn-id` = '%s' ", dbesc($contact['issued-id'])); else $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($contact['dfrn-id'])); - + $x = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`, `contact`.`pubkey` AS `cpubkey`, `contact`.`prvkey` AS `cprvkey`, @@ -322,14 +323,14 @@ function delivery_run($argv, $argc){ require_once('library/simplepie/simplepie.inc'); logger('mod-delivery: local delivery'); local_delivery($x[0],$atom); - break; + break; } } $deliver_status = dfrn_deliver($owner,$contact,$atom); logger('notifier: dfrn_delivery returns ' . $deliver_status); - + if($deliver_status == (-1)) { logger('notifier: delivery failed: queuing message'); add_to_queue($contact['id'],NETWORK_DFRN,$atom); @@ -382,7 +383,7 @@ function delivery_run($argv, $argc){ case NETWORK_MAIL : case NETWORK_MAIL2: - + if(get_config('system','dfrn_only')) break; // WARNING: does not currently convert to RFC2047 header encodings, etc. @@ -432,9 +433,19 @@ function delivery_run($argv, $argc){ if($reply_to) $headers .= 'Reply-to: ' . $reply_to . "\n"; - $headers .= 'Message-id: <' . $it['uri'] . '>' . "\n"; + + // for testing purposes: Collect exported mails + $file = tempnam("/tmp/friendica/", "mail-out-"); + file_put_contents($file, json_encode($it)); + + $headers .= 'Message-Id: <' . iri2msgid($it['uri']). '>' . "\n"; + + //logger("Mail: uri: ".$it['uri']." parent-uri ".$it['parent-uri'], LOGGER_DEBUG); + //logger("Mail: Data: ".print_r($it, true), LOGGER_DEBUG); + //logger("Mail: Data: ".print_r($it, true), LOGGER_DATA); + if($it['uri'] !== $it['parent-uri']) { - $header .= 'References: <' . $it['parent-uri'] . '>' . "\n"; + $headers .= 'References: <' . iri2msgid($it['parent-uri']) . '>' . "\n"; if(! strlen($it['title'])) { $r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1", dbesc($it['parent-uri']) @@ -450,13 +461,16 @@ function delivery_run($argv, $argc){ } } } - $headers .= 'MIME-Version: 1.0' . "\n"; - $headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + /*$headers .= 'MIME-Version: 1.0' . "\n"; + //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + $headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n"; $headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; $html = prepare_body($it); - $message = '<html><body>' . $html . '</body></html>'; + //$message = '<html><body>' . $html . '</body></html>'; + $message = html2plain($html); logger('notifier: email delivery to ' . $addr); - mail($addr, $subject, $message, $headers); + mail($addr, $subject, $message, $headers);*/ + email_send($addr, $subject, $headers, $it); } break; @@ -473,7 +487,7 @@ function delivery_run($argv, $argc){ if((! $contact['pubkey']) && (! $public_message)) break; - + if($target_item['verb'] === ACTIVITY_DISLIKE) { // unsupported break; diff --git a/include/diaspora.php b/include/diaspora.php index 5896f1bfd..dca857a19 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -794,15 +794,15 @@ function diaspora_reshare($importer,$xml) { if(strlen($source_xml->post->asphoto->objectId) && ($source_xml->post->asphoto->objectId != 0) && ($source_xml->post->asphoto->image_url)) { $body = '[url=' . notags(unxmlify($source_xml->post->asphoto->image_url)) . '][img]' . notags(unxmlify($source_xml->post->asphoto->objectId)) . '[/img][/url]' . "\n"; - $body = scale_diaspora_images($body,false); + $body = scale_external_images($body,false); } elseif($source_xml->post->asphoto->image_url) { $body = '[img]' . notags(unxmlify($source_xml->post->asphoto->image_url)) . '[/img]' . "\n"; - $body = scale_diaspora_images($body); + $body = scale_external_images($body); } elseif($source_xml->post->status_message) { $body = diaspora2bb($source_xml->post->status_message->raw_message); - $body = scale_diaspora_images($body); + $body = scale_external_images($body); } else { @@ -945,11 +945,11 @@ function diaspora_asphoto($importer,$xml) { if(strlen($xml->objectId) && ($xml->objectId != 0) && ($xml->image_url)) { $body = '[url=' . notags(unxmlify($xml->image_url)) . '][img]' . notags(unxmlify($xml->objectId)) . '[/img][/url]' . "\n"; - $body = scale_diaspora_images($body,false); + $body = scale_external_images($body,false); } elseif($xml->image_url) { $body = '[img]' . notags(unxmlify($xml->image_url)) . '[/img]' . "\n"; - $body = scale_diaspora_images($body); + $body = scale_external_images($body); } else { logger('diaspora_asphoto: no photo url found.'); @@ -1476,7 +1476,7 @@ function diaspora_photo($importer,$xml,$msg) { $link_text = '[img]' . $remote_photo_path . $remote_photo_name . '[/img]' . "\n"; - $link_text = scale_diaspora_images($link_text); + $link_text = scale_external_images($link_text); if(strpos($parent_item['body'],$link_text) === false) { $r = q("update item set `body` = '%s', `visible` = 1 where `id` = %d and `uid` = %d limit 1", diff --git a/include/email.php b/include/email.php index 3e6a8186d..659978b6e 100755 --- a/include/email.php +++ b/include/email.php @@ -1,4 +1,5 @@ <?php +require_once('include/html2plain.php'); function email_connect($mailbox,$username,$password) { if(! function_exists('imap_open')) @@ -79,15 +80,32 @@ function email_get_msg($mbox,$uid) { if(! $struc) return $ret; + // for testing purposes: Collect imported mails + // $file = tempnam("/tmp/friendica2/", "mail-in-"); + // file_put_contents($file, json_encode($struc)); + if(! $struc->parts) { - $ret['body'] = email_get_part($mbox,$uid,$struc,0); + $ret['body'] = email_get_part($mbox,$uid,$struc,0, 'html'); + + if (trim($ret['body']) == '') + $ret['body'] = email_get_part($mbox,$uid,$struc,0, 'plain'); + else + $ret['body'] = html2bbcode($ret['body']); } else { + $text = ''; + $html = ''; foreach($struc->parts as $ptop => $p) { - $x = email_get_part($mbox,$uid,$p,$ptop + 1); - if($x) - $ret['body'] = $x; + $x = email_get_part($mbox,$uid,$p,$ptop + 1, 'plain'); + if($x) $text .= $x; + + $x = email_get_part($mbox,$uid,$p,$ptop + 1, 'html'); + if($x) $html .= $x; } + if (trim($html) != '') + $ret['body'] = html2bbcode($html); + else + $ret['body'] = $text; } return $ret; } @@ -95,74 +113,81 @@ function email_get_msg($mbox,$uid) { // At the moment - only return plain/text. // Later we'll repackage inline images as data url's and make the HTML safe -function email_get_part($mbox,$uid,$p,$partno) { - // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple - global $htmlmsg,$plainmsg,$charset,$attachments; +function email_get_part($mbox,$uid,$p,$partno, $subtype) { + // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple + global $htmlmsg,$plainmsg,$charset,$attachments; - echo $partno; + //echo $partno."\n"; - // DECODE DATA - $data = ($partno) + // DECODE DATA + $data = ($partno) ? @imap_fetchbody($mbox,$uid,$partno, FT_UID|FT_PEEK) - : @imap_body($mbox,$uid,FT_UID|FT_PEEK); - - // Any part may be encoded, even plain text messages, so check everything. - if ($p->encoding==4) - $data = quoted_printable_decode($data); - elseif ($p->encoding==3) - $data = base64_decode($data); - - // PARAMETERS - // get all parameters, like charset, filenames of attachments, etc. - $params = array(); - if ($p->parameters) - foreach ($p->parameters as $x) - $params[strtolower($x->attribute)] = $x->value; - if ($p->dparameters) - foreach ($p->dparameters as $x) - $params[strtolower($x->attribute)] = $x->value; - - // ATTACHMENT - // Any part with a filename is an attachment, - // so an attached text file (type 0) is not mistaken as the message. - - if ($params['filename'] || $params['name']) { - // filename may be given as 'Filename' or 'Name' or both - $filename = ($params['filename'])? $params['filename'] : $params['name']; - // filename may be encoded, so see imap_mime_header_decode() - $attachments[$filename] = $data; // this is a problem if two files have same name - } + : @imap_body($mbox,$uid,FT_UID|FT_PEEK); + + // for testing purposes: Collect imported mails + // $file = tempnam("/tmp/friendica2/", "mail-body-"); + // file_put_contents($file, $data); + + // Any part may be encoded, even plain text messages, so check everything. + if ($p->encoding==4) + $data = quoted_printable_decode($data); + elseif ($p->encoding==3) + $data = base64_decode($data); + + // PARAMETERS + // get all parameters, like charset, filenames of attachments, etc. + $params = array(); + if ($p->parameters) + foreach ($p->parameters as $x) + $params[strtolower($x->attribute)] = $x->value; + if (isset($p->dparameters) and $p->dparameters) + foreach ($p->dparameters as $x) + $params[strtolower($x->attribute)] = $x->value; + + // ATTACHMENT + // Any part with a filename is an attachment, + // so an attached text file (type 0) is not mistaken as the message. + + if ((isset($params['filename']) and $params['filename']) || (isset($params['name']) and $params['name'])) { + // filename may be given as 'Filename' or 'Name' or both + $filename = ($params['filename'])? $params['filename'] : $params['name']; + // filename may be encoded, so see imap_mime_header_decode() + $attachments[$filename] = $data; // this is a problem if two files have same name + } - // TEXT - if ($p->type == 0 && $data) { - // Messages may be split in different parts because of inline attachments, - // so append parts together with blank row. - if (strtolower($p->subtype)=='plain') - return (trim($data) ."\n\n"); - else + // TEXT + if ($p->type == 0 && $data) { + // Messages may be split in different parts because of inline attachments, + // so append parts together with blank row. + if (strtolower($p->subtype)==$subtype) { + $data = iconv($params['charset'], 'UTF-8//IGNORE', $data); + return (trim($data) ."\n\n"); + } else $data = ''; // $htmlmsg .= $data ."<br><br>"; - $charset = $params['charset']; // assume all parts are same charset - } + $charset = $params['charset']; // assume all parts are same charset + } - // EMBEDDED MESSAGE - // Many bounce notifications embed the original message as type 2, - // but AOL uses type 1 (multipart), which is not handled here. - // There are no PHP functions to parse embedded messages, - // so this just appends the raw source to the main message. -// elseif ($p->type==2 && $data) { -// $plainmsg .= $data."\n\n"; -// } - - // SUBPART RECURSION - if ($p->parts) { - foreach ($p->parts as $partno0=>$p2) { - $x = email_get_part($mbox,$uid,$p2,$partno . '.' . ($partno0+1)); // 1.2, 1.2.1, etc. - if($x) - return $x; + // EMBEDDED MESSAGE + // Many bounce notifications embed the original message as type 2, + // but AOL uses type 1 (multipart), which is not handled here. + // There are no PHP functions to parse embedded messages, + // so this just appends the raw source to the main message. +// elseif ($p->type==2 && $data) { +// $plainmsg .= $data."\n\n"; +// } + + // SUBPART RECURSION + if (isset($p->parts) and $p->parts) { + $x = ""; + foreach ($p->parts as $partno0=>$p2) { + $x .= email_get_part($mbox,$uid,$p2,$partno . '.' . ($partno0+1), $subtype); // 1.2, 1.2.1, etc. + //if($x) + // return $x; } - } + return $x; + } } @@ -216,6 +241,53 @@ function email_header_encode($in_str, $charset) { $out_str = $start . $out_str . $end; } return $out_str; -} +} + +function email_send($addr, $subject, $headers, $item) { + //$headers .= 'MIME-Version: 1.0' . "\n"; + //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + //$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n"; + //$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; + + $part = uniqid("", true); + $html = prepare_body($item); + $headers .= "Mime-Version: 1.0\n"; + $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n"; + + $body = "\n--=_".$part."\n"; + $body .= "Content-Transfer-Encoding: 8bit\n"; + $body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n"; + + $body .= html2plain($html)."\n"; + + $body .= "--=_".$part."\n"; + $body .= "Content-Transfer-Encoding: 8bit\n"; + $body .= "Content-Type: text/html; charset=utf-8\n\n"; + + $body .= '<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">'.$html."</body></html>\n"; + + $body .= "--=_".$part."--"; + + //$message = '<html><body>' . $html . '</body></html>'; + //$message = html2plain($html); + logger('notifier: email delivery to ' . $addr); + mail($addr, $subject, $body, $headers); +} + +function iri2msgid($iri) { + if (!strpos($iri, "@")) + $msgid = preg_replace("/urn:(\S+):(\S+)\.(\S+):(\d+):(\S+)/i", "urn!$1!$4!$5@$2.$3", $iri); + else + $msgid = $iri; + return($msgid); +} + +function msgid2iri($msgid) { + if (strpos($msgid, "@")) + $iri = preg_replace("/urn!(\S+)!(\d+)!(\S+)@(\S+)\.(\S+)/i", "urn:$1:$4.$5:$2:$3", $msgid); + else + $iri = $msgid; + return($iri); +} diff --git a/include/enotify.php b/include/enotify.php index 1eb3b5476..a505f1f04 100755 --- a/include/enotify.php +++ b/include/enotify.php @@ -13,7 +13,9 @@ function notification($params) { $site_admin = sprintf( t('%s Administrator'), $sitename); $sender_name = $product; - $sender_email = t('noreply') . '@' . $a->get_hostname(); + $hostname = $a->get_hostname(); + $sender_email = t('noreply') . '@' . $hostname; + $additional_mail_header = ""; if(array_key_exists('item',$params)) { $title = $params['item']['title']; @@ -23,9 +25,12 @@ function notification($params) { $title = $body = ''; } + // e.g. "your post", "David's photo", etc. + $possess_desc = t('%s <!item_type!>'); + if($params['type'] == NOTIFY_MAIL) { - $subject = sprintf( t('New mail received at %s'),$sitename); + $subject = sprintf( t('[Friendica:Notify] New mail received at %s'),$sitename); $preamble = sprintf( t('%s sent you a new private message at %s.'),$params['source_name'],$sitename); $epreamble = sprintf( t('%s sent you %s.'),'[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('a private message') . '[/url]'); @@ -36,10 +41,43 @@ function notification($params) { } if($params['type'] == NOTIFY_COMMENT) { +// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG); + + $parent_id = $params['parent']; + + + // if it's a post figure out who's post it is. + + $p = null; + + if($params['otype'] === 'item' && $parent_id) { + $p = q("select * from item where id = %d and uid = %d limit 1", + intval($parent_id), + intval($params['uid']) + ); + } + + $possess_desc = str_replace('<!item_type!>',item_post_type($p[0]),$possess_desc); - $subject = sprintf( t('%s commented on an item at %s'), $params['source_name'], $sitename); + // "a post" + $dest_str = sprintf($possess_desc,'a'); + + // "George Bull's post" + if($p) + $dest_str = sprintf($possess_desc,sprintf( t("%s's"),$p[0]['author-name'])); + + // "your post" + if($p[0]['owner-name'] == $p[0]['author-name'] && $p[0]['wall']) + $dest_str = sprintf($possess_desc, t('your') ); + + // Some mail softwares relies on subject field for threading. + // So, we cannot have different subjects for notifications of the same thread. + // Before this we have the name of the replier on the subject rendering + // differents subjects for messages on the same thread. + + $subject = sprintf( t('[Friendica:Notify] Comment to conversation #%d by %s'), $parent_id, $params['source_name']); $preamble = sprintf( t('%s commented on an item/conversation you have been following.'), $params['source_name']); - $epreamble = sprintf( t('%s commented in %s.'), '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('a watched conversation') . '[/url]'); + $epreamble = sprintf( t('%s commented on %s.'), '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . $dest_str . '[/url]'); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); @@ -48,7 +86,10 @@ function notification($params) { } if($params['type'] == NOTIFY_WALL) { - $preamble = $subject = sprintf( t('%s posted to your profile wall at %s') , $params['source_name'], $sitename); + $subject = sprintf( t('[Friendica:Notify] %s posted to your profile wall') , $params['source_name']); + + $preamble = sprintf( t('%s posted to your profile wall at %s') , $params['source_name'], $sitename); + $epreamble = sprintf( t('%s posted to %s') , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('your profile wall.') . '[/url]'); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); @@ -58,7 +99,8 @@ function notification($params) { } if($params['type'] == NOTIFY_TAGSELF) { - $preamble = $subject = sprintf( t('%s tagged you at %s') , $params['source_name'], $sitename); + $subject = sprintf( t('[Friendica:Notify] %s tagged you') , $params['source_name']); + $preamble = sprintf( t('%s tagged you at %s') , $params['source_name'], $sitename); $epreamble = sprintf( t('%s %s.') , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=' . $params['link'] . ']' . t('tagged you') . '[/url]'); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); @@ -68,7 +110,8 @@ function notification($params) { } if($params['type'] == NOTIFY_TAGSHARE) { - $preamble = $subject = sprintf( t('%s tagged your post at %s') , $params['source_name'], $sitename); + $subject = sprintf( t('[Friendica:Notify] %s tagged your post') , $params['source_name']); + $preamble = sprintf( t('%s tagged your post at %s') , $params['source_name'], $sitename); $epreamble = sprintf( t('%s tagged %s') , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]', '[url=$itemlink]' . t('your post') . '[/url]' ); $sitelink = t('Please visit %s to view and/or reply to the conversation.'); @@ -78,7 +121,7 @@ function notification($params) { } if($params['type'] == NOTIFY_INTRO) { - $subject = sprintf( t('Introduction received at %s'), $sitename); + $subject = sprintf( t('[Friendica:Notify] Introduction received')); $preamble = sprintf( t('You\'ve received an introduction from \'%s\' at %s'), $params['source_name'], $sitename); $epreamble = sprintf( t('You\'ve received %s from %s.'), '[url=$itemlink]' . t('an introduction') . '[/url]' , '[url=' . $params['source_link'] . ']' . $params['source_name'] . '[/url]'); $body = sprintf( t('You may visit their profile at %s'),$params['source_link']); @@ -90,7 +133,7 @@ function notification($params) { } if($params['type'] == NOTIFY_SUGGEST) { - $subject = sprintf( t('Friend suggestion received at %s'), $sitename); + $subject = sprintf( t('[Friendica:Notify] Friend suggestion received')); $preamble = sprintf( t('You\'ve received a friend suggestion from \'%s\' at %s'), $params['source_name'], $sitename); $epreamble = sprintf( t('You\'ve received %s for %s from %s.'), '[url=$itemlink]' . t('a friend suggestion') . '[/url]', @@ -126,22 +169,36 @@ function notification($params) { } while($dups == true); - + $datarray = array(); + $datarray['hash'] = $hash; + $datarray['name'] = $params['source_name']; + $datarray['url'] = $params['source_link']; + $datarray['photo'] = $params['source_photo']; + $datarray['date'] = datetime_convert(); + $datarray['uid'] = $params['uid']; + $datarray['link'] = $itemlink; + $datarray['parent'] = $parent_id; + $datarray['type'] = $params['type']; + $datarray['verb'] = $params['verb']; + $datarray['otype'] = $params['otype']; + + call_hooks('enotify_store', $datarray); // create notification entry in DB - $r = q("insert into notify (hash,name,url,photo,date,uid,link,type,verb,otype) - values('%s','%s','%s','%s','%s',%d,'%s',%d,'%s','%s')", - dbesc($hash), - dbesc($params['source_name']), - dbesc($params['source_link']), - dbesc($params['source_photo']), - dbesc(datetime_convert()), - intval($params['uid']), - dbesc($itemlink), - intval($params['type']), - dbesc($params['verb']), - dbesc($params['otype']) + $r = q("insert into notify (hash,name,url,photo,date,uid,link,parent,type,verb,otype) + values('%s','%s','%s','%s','%s',%d,'%s',%d,%d,'%s','%s')", + dbesc($datarray['hash']), + dbesc($datarray['name']), + dbesc($datarray['url']), + dbesc($datarray['photo']), + dbesc($datarray['date']), + intval($datarray['uid']), + dbesc($datarray['link']), + intval($datarray['parent']), + intval($datarray['type']), + dbesc($datarray['verb']), + dbesc($datarray['otype']) ); $r = q("select id from notify where hash = '%s' and uid = %d limit 1", @@ -170,50 +227,111 @@ function notification($params) { logger('notification: sending notification email'); + $id_for_parent = "${params['parent']}@${hostname}"; + + // Is this the first email notification for this parent item and user? + + $r = q("select `id` from `notify-threads` where `master-parent-item` = %d and `receiver-uid` = %d limit 1", + intval($params['parent']), + intval($params['uid']) ); + + // If so, create the record of it and use a message-id smtp header. + + if(!$r) { + logger("norify_id:" . intval($notify_id). ", parent: " . intval($params['parent']) . "uid: " . +intval($params['uid']), LOGGER_DEBUG); + $r = q("insert into `notify-threads` (`notify-id`, `master-parent-item`, `receiver-uid`, `parent-item`) + values(%d,%d,%d,%d)", + intval($notify_id), + intval($params['parent']), + intval($params['uid']), + 0 ); + + $additional_mail_header .= "Message-ID: <${id_for_parent}>\n"; + $log_msg = "include/enotify: No previous notification found for this parent:\n" . + " parent: ${params['parent']}\n" . " uid : ${params['uid']}\n"; + logger($log_msg, LOGGER_DEBUG); + } + + // If not, just "follow" the thread. + + else { + $additional_mail_header = "References: <${id_for_parent}>\nIn-Reply-To: <${id_for_parent}>\n"; + logger("include/enotify: There's already a notification for this parent:\n" . print_r($r, true), LOGGER_DEBUG); + } + + $textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n"), "\n", $body))),ENT_QUOTES,'UTF-8')); $htmlversion = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r","\\n\\n" ,"\\n"), "<br />\n",$body)))); + $datarray = array(); + $datarray['banner'] = $banner; + $datarray['product'] = $product; + $datarray['preamble'] = $preamble; + $datarray['sitename'] = $sitename; + $datarray['siteurl'] = $siteurl; + $datarray['type'] = $params['type']; + $datarray['parent'] = $params['parent']; + $datarray['source_name'] = $params['source_name']; + $datarray['source_link'] = $params['source_link']; + $datarray['source_photo'] = $params['source_photo']; + $datarray['uid'] = $params['uid']; + $datarray['username'] = $params['to_name']; + $datarray['hsitelink'] = $hsitelink; + $datarray['tsitelink'] = $tsitelink; + $datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>'; + $datarray['titemlink'] = $itemlink; + $datarray['thanks'] = $thanks; + $datarray['site_admin'] = $site_admin; + $datarray['title'] = stripslashes($title); + $datarray['htmlversion'] = $htmlversion; + $datarray['textversion'] = $textversion; + $datarray['subject'] = $subject; + $datarray['headers'] = $additional_mail_header; + + call_hooks('enotify_mail', $datarray); + // load the template for private message notifications $tpl = get_markup_template('email_notify_html.tpl'); $email_html_body = replace_macros($tpl,array( - '$banner' => $banner, - '$product' => $product, - '$preamble' => $preamble, - '$sitename' => $sitename, - '$siteurl' => $siteurl, - '$source_name' => $params['source_name'], - '$source_link' => $params['source_link'], - '$source_photo' => $params['source_photo'], - '$username' => $params['to_name'], - '$hsitelink' => $hsitelink, - '$itemlink' => '<a href="' . $itemlink . '">' . $itemlink . '</a>', - '$thanks' => $thanks, - '$site_admin' => $site_admin, - '$title' => stripslashes($title), - '$htmlversion' => $htmlversion, + '$banner' => $datarray['banner'], + '$product' => $datarray['product'], + '$preamble' => $datarray['preamble'], + '$sitename' => $datarray['sitename'], + '$siteurl' => $datarray['siteurl'], + '$source_name' => $datarray['source_name'], + '$source_link' => $datarray['source_link'], + '$source_photo' => $datarray['source_photo'], + '$username' => $datarray['to_name'], + '$hsitelink' => $datarray['hsitelink'], + '$hitemlink' => $datarray['hitemlink'], + '$thanks' => $datarray['thanks'], + '$site_admin' => $datarray['site_admin'], + '$title' => $datarray['title'], + '$htmlversion' => $datarray['htmlversion'], )); // load the template for private message notifications $tpl = get_markup_template('email_notify_text.tpl'); $email_text_body = replace_macros($tpl,array( - '$banner' => $banner, - '$product' => $product, - '$preamble' => $preamble, - '$sitename' => $sitename, - '$siteurl' => $siteurl, - '$source_name' => $params['source_name'], - '$source_link' => $params['source_link'], - '$source_photo' => $params['source_photo'], - '$username' => $params['to_name'], - '$tsitelink' => $tsitelink, - '$itemlink' => $itemlink, - '$thanks' => $thanks, - '$site_admin' => $site_admin, - '$title' => stripslashes($title), - '$textversion' => $textversion, + '$banner' => $datarray['banner'], + '$product' => $datarray['product'], + '$preamble' => $datarray['preamble'], + '$sitename' => $datarray['sitename'], + '$siteurl' => $datarray['siteurl'], + '$source_name' => $datarray['source_name'], + '$source_link' => $datarray['source_link'], + '$source_photo' => $datarray['source_photo'], + '$username' => $datarray['to_name'], + '$tsitelink' => $datarray['tsitelink'], + '$titemlink' => $datarray['titemlink'], + '$thanks' => $datarray['thanks'], + '$site_admin' => $datarray['site_admin'], + '$title' => $datarray['title'], + '$textversion' => $datarray['textversion'], )); // logger('text: ' . $email_text_body); @@ -225,9 +343,10 @@ function notification($params) { 'fromEmail' => $sender_email, 'replyTo' => $sender_email, 'toEmail' => $params['to_email'], - 'messageSubject' => $subject, + 'messageSubject' => $datarray['subject'], 'htmlVersion' => $email_html_body, - 'textVersion' => $email_text_body + 'textVersion' => $email_text_body, + 'additionalMailHeader' => $datarray['headers'], )); } @@ -248,6 +367,7 @@ class enotify { * @param messageSubject subject of the message * @param htmlVersion html version of the message * @param textVersion text only version of the message + * @param additionalMailHeader additions to the smtp mail header */ static public function send($params) { @@ -262,6 +382,7 @@ class enotify { // generate a multipart/alternative message header $messageHeader = + $params['additionalMailHeader'] . "From: {$params['fromName']} <{$params['fromEmail']}>\n" . "Reply-To: {$params['fromName']} <{$params['replyTo']}>\n" . "MIME-Version: 1.0\n" . @@ -291,4 +412,4 @@ class enotify { logger("notification: enotify::send returns " . $res, LOGGER_DEBUG); } } -?>
\ No newline at end of file +?> diff --git a/include/event.php b/include/event.php index c7669b381..4a9a9a004 100755 --- a/include/event.php +++ b/include/event.php @@ -163,7 +163,7 @@ function bbtoevent($s) { if(preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",$s,$match)) $ev['adjust'] = $match[1]; $match = ''; - $ev['nofinish'] = (($ev['start'] && (! $ev['finish'])) ? 1 : 0); + $ev['nofinish'] = (($ev['start'] && (!x($ev, 'finish') || !$ev['finish'])) ? 1 : 0); return $ev; } diff --git a/include/html2bbcode.php b/include/html2bbcode.php index d8f1a24f1..51d629940 100755 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -10,7 +10,7 @@ Originally made for the syncom project: http://wiki.piratenpartei.de/Syncom function node2bbcode(&$doc, $oldnode, $attributes, $startbb, $endbb) { do { - $done = node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb); + $done = node2bbcodesub($doc, $oldnode, $attributes, $startbb, $endbb); } while ($done); } @@ -258,7 +258,7 @@ function html2bbcode($message) "[hr]\n", "\n[list", "[/list]\n", - "\n[/list]", + "\n[/", "[list]\n", "[list=1]\n", "\n[*]"), @@ -268,7 +268,7 @@ function html2bbcode($message) "[hr]", "[list", "[/list]", - "[/list]", + "[/", "[list]", "[list=1]", "[*]"), diff --git a/include/html2plain.php b/include/html2plain.php new file mode 100644 index 000000000..2a4cf6639 --- /dev/null +++ b/include/html2plain.php @@ -0,0 +1,180 @@ +<?php +require_once "html2bbcode.php"; + +function breaklines($line, $level) +{ + $wraplen = 75-$level; + + $newlines = array(); + + do { + $oldline = $line; + + $subline = substr($line, 0, $wraplen); + + $pos = strrpos($subline, ' '); + + if ($pos == 0) + $pos = strpos($line, ' '); + + if (($pos > 0) and strlen($line) > $wraplen) { + $newline = trim(substr($line, 0, $pos)); + if ($level > 0) + $newline = str_repeat(">", $level).' '.$newline; + + $newlines[] = $newline." "; + $line = substr($line, $pos+1); + } + + } while ((strlen($line) > $wraplen) and !($oldline == $line)); + + if ($level > 0) + $line = str_repeat(">", $level).' '.$line; + + $newlines[] = $line; + + + return(implode($newlines, "\n")); +} + +function quotelevel($message) +{ + $lines = explode("\n", $message); + + $newlines = array(); + $level = 0; + foreach($lines as $line) {; + $line = trim($line); + $startquote = false; + while (strpos("*".$line, '[quote]') > 0) { + $level++; + $pos = strpos($line, '[quote]'); + $line = substr($line, 0, $pos).substr($line, $pos+7); + $startquote = true; + } + + $currlevel = $level; + + while (strpos("*".$line, '[/quote]') > 0) { + $level--; + if ($level < 0) + $level = 0; + + $pos = strpos($line, '[/quote]'); + $line = substr($line, 0, $pos).substr($line, $pos+8); + } + + if (!$startquote or ($line != '')) + $newlines[] = breaklines($line, $currlevel); + } + return(implode($newlines, "\n")); +} + +function html2plain($html) +{ + global $lang; + + $message = str_replace("\r", "", $html); + + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; + + $message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8"); + + @$doc->loadHTML($message); + + $xpath = new DomXPath($doc); + $list = $xpath->query("//pre"); + foreach ($list as $node) { + $node->nodeValue = str_replace("\n", "\r", $node->nodeValue); + } + + $message = $doc->saveHTML(); + $message = str_replace(array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"), array("<", ">", "<br>", " ", ""), $message); + $message = preg_replace('= [\s]*=i', " ", $message); + + // nach <a href="...">...</a> suchen, die ... miteinander vergleichen und bei Gleichheit durch ein einzelnes ... ersetzen. + $pattern = '/<a.*?href="(.*?)".*?>(.*?)<\/a>/is'; + preg_match_all($pattern, $message, $result, PREG_SET_ORDER); + + foreach ($result as $treffer) { + if ($treffer[1] == $treffer[2]) { + $search = '<a href="'.$treffer[1].'" target="_blank">'.$treffer[1].'</a>'; + $message = str_replace($search, $treffer[1], $message); + } + } + @$doc->loadHTML($message); + + node2bbcode($doc, 'html', array(), '', ''); + node2bbcode($doc, 'body', array(), '', ''); + + // MyBB-Auszeichnungen + node2bbcode($doc, 'span', array('style'=>'text-decoration: underline;'), '_', '_'); + node2bbcode($doc, 'span', array('style'=>'font-style: italic;'), '/', '/'); + node2bbcode($doc, 'span', array('style'=>'font-weight: bold;'), '*', '*'); + + node2bbcode($doc, 'strong', array(), '*', '*'); + node2bbcode($doc, 'b', array(), '*', '*'); + node2bbcode($doc, 'i', array(), '/', '/'); + node2bbcode($doc, 'u', array(), '_', '_'); + + node2bbcode($doc, 'blockquote', array(), '[quote]', "[/quote]\n"); + + node2bbcode($doc, 'br', array(), "\n", ''); + + node2bbcode($doc, 'span', array(), "", ""); + node2bbcode($doc, 'pre', array(), "", ""); + node2bbcode($doc, 'div', array(), "\r", "\r"); + node2bbcode($doc, 'p', array(), "\n", "\n"); + + //node2bbcode($doc, 'ul', array(), "\n[list]", "[/list]\n"); + //node2bbcode($doc, 'ol', array(), "\n[list=1]", "[/list]\n"); + node2bbcode($doc, 'li', array(), "\n* ", "\n"); + + node2bbcode($doc, 'hr', array(), str_repeat("-", 70), ""); + + node2bbcode($doc, 'tr', array(), "\n", ""); + node2bbcode($doc, 'td', array(), "\t", ""); + + node2bbcode($doc, 'h1', array(), "\n\n*", "*\n"); + node2bbcode($doc, 'h2', array(), "\n\n*", "*\n"); + node2bbcode($doc, 'h3', array(), "\n\n*", "*\n"); + node2bbcode($doc, 'h4', array(), "\n\n*", "*\n"); + node2bbcode($doc, 'h5', array(), "\n\n*", "*\n"); + node2bbcode($doc, 'h6', array(), "\n\n*", "*\n"); + + node2bbcode($doc, 'a', array('href'=>'/(.+)/'), ' $1', '', true); + node2bbcode($doc, 'img', array('alt'=>'/(.+)/'), '$1', ''); + node2bbcode($doc, 'img', array('title'=>'/(.+)/'), '$1', ''); + node2bbcode($doc, 'img', array(), '', ''); + node2bbcode($doc, 'img', array('src'=>'/(.+)/'), '[img]$1', '[/img]'); + + $message = $doc->saveHTML(); + + $message = str_replace("[img]", "", $message); + $message = str_replace("[/img]", "", $message); + + // was ersetze ich da? + // Irgendein stoerrisches UTF-Zeug + $message = str_replace(chr(194).chr(160), ' ', $message); + + $message = str_replace(" ", " ", $message); + + // Aufeinanderfolgende DIVs + $message = preg_replace('=\r *\r=i', "\n", $message); + $message = str_replace("\r", "\n", $message); + + $message = strip_tags($message); + + $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8'); + + do { + $oldmessage = $message; + $message = str_replace("\n\n\n", "\n\n", $message); + } while ($oldmessage != $message); + + $message = quotelevel(trim($message)); + + return(trim($message)); +} +?> diff --git a/include/items.php b/include/items.php index de3ade6b4..a1254e165 100755 --- a/include/items.php +++ b/include/items.php @@ -308,7 +308,7 @@ function get_atom_elements($feed,$item) { if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach($base as $link) { - if(! $res['author-avatar']) { + if(!x($res, 'author-avatar') || !$res['author-avatar']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } @@ -323,7 +323,7 @@ function get_atom_elements($feed,$item) { foreach($base as $link) { if($link['attribs']['']['rel'] === 'alternate' && (! $res['author-link'])) $res['author-link'] = unxmlify($link['attribs']['']['href']); - if(! $res['author-avatar']) { + if(!x($res, 'author-avatar') || !$res['author-avatar']) { if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } @@ -503,7 +503,7 @@ function get_atom_elements($feed,$item) { $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach($base as $link) { - if(! $res['owner-avatar']) { + if(!x($res, 'owner-avatar') || !$res['owner-avatar']) { if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') $res['owner-avatar'] = unxmlify($link['attribs']['']['href']); } @@ -2223,7 +2223,8 @@ function local_delivery($importer,$data) { 'source_photo' => ((link_compare($datarray['author-link'],$importer['url'])) ? $importer['thumb'] : $datarray['author-avatar']), 'verb' => ACTIVITY_POST, - 'otype' => 'item' + 'otype' => 'item', + 'parent' => $parent, )); @@ -2317,39 +2318,51 @@ function local_delivery($importer,$data) { if($datarray['type'] != 'activity') { - $myconv = q("SELECT `author-link`, `author-avatar` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ", + $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ", dbesc($parent_uri), intval($importer['importer_uid']) ); if(count($myconv)) { $importer_url = $a->get_baseurl() . '/profile/' . $importer['nickname']; - foreach($myconv as $conv) { - - if(! link_compare($conv['author-link'],$importer_url)) - continue; - require_once('include/enotify.php'); + // first make sure this isn't our own post coming back to us from a wall-to-wall event + if(! link_compare($datarray['author-link'],$importer_url)) { - notification(array( - 'type' => NOTIFY_COMMENT, - 'notify_flags' => $importer['notify-flags'], - 'language' => $importer['language'], - 'to_name' => $importer['username'], - 'to_email' => $importer['email'], - 'uid' => $importer['importer_uid'], - 'item' => $datarray, - 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, - 'source_name' => stripslashes($datarray['author-name']), - 'source_link' => $datarray['author-link'], - 'source_photo' => ((link_compare($datarray['author-link'],$importer['url'])) - ? $importer['thumb'] : $datarray['author-avatar']), - 'verb' => ACTIVITY_POST, - 'otype' => 'item' + + foreach($myconv as $conv) { - )); + // now if we find a match, it means we're in this conversation + + if(! link_compare($conv['author-link'],$importer_url)) + continue; - break; + require_once('include/enotify.php'); + + $conv_parent = $conv['parent']; + + notification(array( + 'type' => NOTIFY_COMMENT, + 'notify_flags' => $importer['notify-flags'], + 'language' => $importer['language'], + 'to_name' => $importer['username'], + 'to_email' => $importer['email'], + 'uid' => $importer['importer_uid'], + 'item' => $datarray, + 'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id, + 'source_name' => stripslashes($datarray['author-name']), + 'source_link' => $datarray['author-link'], + 'source_photo' => ((link_compare($datarray['author-link'],$importer['url'])) + ? $importer['thumb'] : $datarray['author-avatar']), + 'verb' => ACTIVITY_POST, + 'otype' => 'item', + 'parent' => $conv_parent, + + )); + + // only send one notification + break; + } } } } @@ -2420,7 +2433,7 @@ function local_delivery($importer,$data) { // This is my contact on another system, but it's really me. // Turn this into a wall post. - if($contact['remote_self']) + if($importer['remote_self']) $datarray['wall'] = 1; $datarray['parent-uri'] = $item_id; diff --git a/include/network.php b/include/network.php index 25db62d16..c72919dd8 100755 --- a/include/network.php +++ b/include/network.php @@ -17,7 +17,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_ if (!is_null($accept_content)){ curl_setopt($ch,CURLOPT_HTTPHEADER, array ( - "Accept: "+$accept_content + "Accept: " . $accept_content )); } @@ -60,6 +60,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_ $curl_info = @curl_getinfo($ch); $http_code = $curl_info['http_code']; +// logger('fetch_url:' . $http_code . ' data: ' . $s); $header = ''; // Pull out multiple headers, e.g. proxy and continuation headers @@ -74,11 +75,13 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_ if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307) { $matches = array(); preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); - $url = trim(array_pop($matches)); - $url_parsed = @parse_url($url); + $newurl = trim(array_pop($matches)); + if(strpos($newurl,'/') === 0) + $newurl = $url . $newurl; + $url_parsed = @parse_url($newurl); if (isset($url_parsed)) { $redirects++; - return fetch_url($url,$binary,$redirects,$timeout); + return fetch_url($newurl,$binary,$redirects,$timeout); } } @@ -163,11 +166,13 @@ function post_url($url,$params, $headers = null, &$redirects = 0, $timeout = 0) if($http_code == 301 || $http_code == 302 || $http_code == 303) { $matches = array(); preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); - $url = trim(array_pop($matches)); - $url_parsed = @parse_url($url); + $newurl = trim(array_pop($matches)); + if(strpos($newurl,'/') === 0) + $newurl = $url . $newurl; + $url_parsed = @parse_url($newurl); if (isset($url_parsed)) { $redirects++; - return post_url($url,$params,$headers,$redirects,$timeout); + return fetch_url($newurl,$binary,$redirects,$timeout); } } $a->set_curl_code($http_code); @@ -776,3 +781,43 @@ function add_fcontact($arr,$update = false) { return $r; } + + +function scale_external_images($s,$include_link = true) { + + $a = get_app(); + + $matches = null; + $c = preg_match_all('/\[img\](.*?)\[\/img\]/ism',$s,$matches,PREG_SET_ORDER); + if($c) { + require_once('include/Photo.php'); + foreach($matches as $mtch) { + logger('scale_external_image: ' . $mtch[1]); + $hostname = str_replace('www.','',substr($a->get_baseurl(),strpos($a->get_baseurl(),'://')+3)); + if(stristr($mtch[1],$hostname)) + continue; + $i = fetch_url($mtch[1]); + if($i) { + $ph = new Photo($i); + if($ph->is_valid()) { + $orig_width = $ph->getWidth(); + $orig_height = $ph->getHeight(); + + if($orig_width > 640 || $orig_height > 640) { + + $ph->scaleImage(640); + $new_width = $ph->getWidth(); + $new_height = $ph->getHeight(); + logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG); + $s = str_replace($mtch[0],'[img=' . $new_width . 'x' . $new_height. ']' . $mtch[1] . '[/img]' + . "\n" . (($include_link) + ? '[url=' . $mtch[1] . ']' . t('view full size') . '[/url]' . "\n" + : ''),$s); + logger('scale_external_images: new string: ' . $s, LOGGER_DEBUG); + } + } + } + } + } + return $s; +} diff --git a/include/notifier.php b/include/notifier.php index 8ec625286..4765cca06 100755 --- a/include/notifier.php +++ b/include/notifier.php @@ -2,6 +2,7 @@ require_once("boot.php"); require_once('include/queue_fn.php'); +require_once('include/html2plain.php'); /* * This file was at one time responsible for doing all deliveries, but this caused @@ -633,7 +634,7 @@ function notifier_run($argv, $argc){ ); if($r1 && $r1[0]['reply_to']) $reply_to = $r1[0]['reply_to']; - + $subject = (($it['title']) ? email_header_encode($it['title'],'UTF-8') : t("\x28no subject\x29")) ; // only expose our real email address to true friends @@ -646,10 +647,14 @@ function notifier_run($argv, $argc){ if($reply_to) $headers .= 'Reply-to: ' . $reply_to . "\n"; - $headers .= 'Message-id: <' . $it['uri'] . '>' . "\n"; + // for testing purposes: Collect exported mails + $file = tempnam("/tmp/friendica/", "mail-out2-"); + file_put_contents($file, json_encode($it)); + + $headers .= 'Message-Id: <' . iri2msgid($it['uri']) . '>' . "\n"; if($it['uri'] !== $it['parent-uri']) { - $header .= 'References: <' . $it['parent-uri'] . '>' . "\n"; + $headers .= 'References: <' . iri2msgid($it['parent-uri']) . '>' . "\n"; if(! strlen($it['title'])) { $r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1", dbesc($it['parent-uri']) @@ -666,13 +671,16 @@ function notifier_run($argv, $argc){ } } - $headers .= 'MIME-Version: 1.0' . "\n"; - $headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + /*$headers .= 'MIME-Version: 1.0' . "\n"; + //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + $headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n"; $headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; $html = prepare_body($it); - $message = '<html><body>' . $html . '</body></html>'; + //$message = '<html><body>' . $html . '</body></html>'; + $message = html2plain($html); logger('notifier: email delivery to ' . $addr); - mail($addr, $subject, $message, $headers); + mail($addr, $subject, $message, $headers);*/ + email_send($addr, $subject, $headers, $it); } break; case NETWORK_DIASPORA: @@ -719,7 +727,7 @@ function notifier_run($argv, $argc){ // we are the relay - send comments, likes and unlikes to our conversants diaspora_send_relay($target_item,$owner,$contact); break; - } + } elseif(($top_level) && (! $walltowall)) { // currently no workable solution for sending walltowall diaspora_send_status($target_item,$owner,$contact); diff --git a/include/plugin.php b/include/plugin.php index 57f77cb57..8280b1022 100755 --- a/include/plugin.php +++ b/include/plugin.php @@ -225,9 +225,16 @@ function get_theme_info($theme){ 'description' => "", 'author' => array(), 'maintainer' => array(), - 'version' => "" + 'version' => "", + 'experimental' => false, + 'unsupported' => false ); + if(file_exists("view/theme/$theme/experimental")) + $info['experimental'] = true; + if(file_exists("view/theme/$theme/unsupported")) + $info['unsupported'] = true; + if (!is_file("view/theme/$theme/theme.php")) return $info; $f = file_get_contents("view/theme/$theme/theme.php"); diff --git a/include/poller.php b/include/poller.php index 3e7a1e9b4..cfbc46b87 100755 --- a/include/poller.php +++ b/include/poller.php @@ -1,6 +1,7 @@ <?php require_once("boot.php"); +require_once("include/quoteconvert.php"); function poller_run($argv, $argc){ @@ -419,13 +420,13 @@ function poller_run($argv, $argc){ // look for a 'references' header and try and match with a parent item we have locally. $raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : ''); - $datarray['uri'] = trim($meta->message_id,'<>'); + $datarray['uri'] = msgid2iri(trim($meta->message_id,'<>')); if($raw_refs) { $refs_arr = explode(' ', $raw_refs); if(count($refs_arr)) { for($x = 0; $x < count($refs_arr); $x ++) - $refs_arr[$x] = "'" . str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x])) . "'"; + $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'"; } $qstr = implode(',',$refs_arr); $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1", @@ -453,9 +454,39 @@ function poller_run($argv, $argc){ intval($r[0]['id']) ); } + switch ($mailconf[0]['action']) { + case 0: + break; + case 1: + logger("Mail: Deleting ".$msg_uid); + imap_delete($mbox, $msg_uid, FT_UID); + break; + case 2: + logger("Mail: Mark as seen ".$msg_uid); + imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); + break; + case 3: + logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']); + imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); + if ($mailconf[0]['movetofolder'] != "") + imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID); + break; + } continue; } - $datarray['title'] = notags(trim($meta->subject)); + + // Decoding the header + $subject = imap_mime_header_decode($meta->subject); + $datarray['title'] = ""; + foreach($subject as $subpart) + if ($subpart->charset != "default") + $datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text); + else + $datarray['title'] .= $subpart->text; + + $datarray['title'] = notags(trim($datarray['title'])); + + //$datarray['title'] = notags(trim($meta->subject)); $datarray['created'] = datetime_convert('UTC','UTC',$meta->date); $r = email_get_msg($mbox,$msg_uid); @@ -463,15 +494,24 @@ function poller_run($argv, $argc){ logger("Mail: can't fetch msg ".$msg_uid); continue; } - $datarray['body'] = escape_tags($r['body']); + $datarray['body'] = escape_tags(convertquote($r['body'], false)); logger("Mail: Importing ".$msg_uid); // some mailing lists have the original author as 'from' - add this sender info to msg body. // todo: adding a gravatar for the original author would be cool - if(! stristr($meta->from,$contact['addr'])) - $datarray['body'] = t('From: ') . escape_tags($meta->from) . "\n\n" . $datarray['body']; + if(! stristr($meta->from,$contact['addr'])) { + $from = imap_mime_header_decode($meta->from); + $fromdecoded = ""; + foreach($from as $frompart) + if ($frompart->charset != "default") + $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text); + else + $fromdecoded .= $frompart->text; + + $datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body']; + } $datarray['uid'] = $importer_uid; $datarray['contact-id'] = $contact['id']; @@ -493,6 +533,24 @@ function poller_run($argv, $argc){ q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1", intval($stored_item) ); + switch ($mailconf[0]['action']) { + case 0: + break; + case 1: + logger("Mail: Deleting ".$msg_uid); + imap_delete($mbox, $msg_uid, FT_UID); + break; + case 2: + logger("Mail: Mark as seen ".$msg_uid); + imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); + break; + case 3: + logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']); + imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); + if ($mailconf[0]['movetofolder'] != "") + imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID); + break; + } } } @@ -501,7 +559,7 @@ function poller_run($argv, $argc){ } elseif($contact['network'] === NETWORK_FACEBOOK) { // This is picked up by the Facebook plugin on a cron hook. - // Ignored here. + // Ignored here. } if($xml) { diff --git a/include/quoteconvert.php b/include/quoteconvert.php new file mode 100644 index 000000000..3aee93234 --- /dev/null +++ b/include/quoteconvert.php @@ -0,0 +1,132 @@ +<?php +function convertquote($body, $reply) +{ + // Convert Quotes + $arrbody = explode("\n", trim($body)); + $arrlevel = array(); + + for ($i = 0; $i < count($arrbody); $i++) { + $quotelevel = 0; + $quoteline = $arrbody[$i]; + + while ((strlen($quoteline)>0) and ((substr($quoteline, 0, 1) == '>') + or (substr($quoteline, 0, 1) == ' '))) { + if (substr($quoteline, 0, 1) == '>') + $quotelevel++; + + $quoteline = ltrim(substr($quoteline, 1)); + } + + //echo $quotelevel.'*'.$quoteline."\r\n"; + + $arrlevel[$i] = $quotelevel; + $arrbody[$i] = $quoteline; + } + + $quotelevel = 0; + $previousquote = 0; + $arrbodyquoted = array(); + + for ($i = 0; $i < count($arrbody); $i++) { + + $previousquote = $quotelevel; + $quotelevel = $arrlevel[$i]; + $currline = $arrbody[$i]; + + while ($previousquote < $quotelevel) { + if ($sender != '') { + $quote = "[quote title=$sender]"; + $sender = ''; + } else + $quote = "[quote]"; + + $arrbody[$i] = $quote.$arrbody[$i]; + $previousquote++; + } + + while ($previousquote > $quotelevel) { + $arrbody[$i] = '[/quote]'.$arrbody[$i]; + $previousquote--; + } + + $arrbodyquoted[] = $arrbody[$i]; + } + while ($quotelevel > 0) { + $arrbodyquoted[] = '[/quote]'; + $quotelevel--; + } + + $body = implode("\n", $arrbodyquoted); + + if (strlen($body) > 0) + $body = $body."\n\n"; + + if ($reply) + $body = removetofu($body); + + return($body); +} + +function removetofu($message) +{ + $message = trim($message); + + do { + $oldmessage = $message; + $message = preg_replace('=\[/quote\][\s](.*?)\[quote\]=i', '$1', $message); + $message = str_replace("[/quote][quote]", "", $message); + } while ($message != $oldmessage); + + $quotes = array(); + + $startquotes = 0; + + $start = 0; + + while(($pos = strpos($message, '[quote', $start)) > 0) { + $quotes[$pos] = -1; + $start = $pos + 7; + $startquotes++; + } + + $endquotes = 0; + $start = 0; + + while(($pos = strpos($message, '[/quote]', $start)) > 0) { + $start = $pos + 7; + $endquotes++; + } + + while ($endquotes < $startquotes) { + $message .= '[/quote]'; + ++$endquotes; + } + + $start = 0; + + while(($pos = strpos($message, '[/quote]', $start)) > 0) { + $quotes[$pos] = 1; + $start = $pos + 7; + } + + if (strtolower(substr($message, -8)) != '[/quote]') + return($message); + + krsort($quotes); + + $quotelevel = 0; + $quotestart = 0; + foreach ($quotes as $index => $quote) { + $quotelevel += $quote; + + if (($quotelevel == 0) and ($quotestart == 0)) + $quotestart = $index; + } + + if ($quotestart != 0) { + $message = trim(substr($message, 0, $quotestart))."\n[collapsed]\n".substr($message, $quotestart+7, -8).'[/collapsed]'; + } + + return($message); +} +?> diff --git a/include/template_processor.php b/include/template_processor.php index 0d476f0e6..28c3f07dd 100755 --- a/include/template_processor.php +++ b/include/template_processor.php @@ -32,11 +32,12 @@ if(is_array($r) && count($r)) { foreach ($r as $k => $v ) { - if (is_array($v)) + if (is_array($v)) { $this->_build_replace($v, "$prefix$k."); - - $this->search[] = $prefix . $k; - $this->replace[] = $v; + } else { + $this->search[] = $prefix . $k; + $this->replace[] = $v; + } } } } @@ -53,7 +54,7 @@ $keys = array_map('trim',explode(".",$name)); $val = $this->r; foreach($keys as $k) { - $val = $val[$k]; + $val = (isset($val[$k]) ? $val[$k] : null); } return $val; } @@ -79,8 +80,8 @@ } else { $val = $this->_get_var($args[2]); } - list($strue, $sfalse)= preg_split("|{{ *else *}}|", $args[3]); - return ($val?$strue:$sfalse); + $x = preg_split("|{{ *else *}}|", $args[3]); + return ( $val ? $x[0] : (isset($x[1]) ? $x[1] : "")); } /** @@ -159,7 +160,8 @@ krsort($this->nodes); return $s; } - + + /* private function _str_replace($str){ #$this->search,$this->replace, $searchs = $this->search; @@ -182,7 +184,7 @@ } return str_replace($this->search,$this->replace, $str); - } + }*/ public function replace($s, $r) { @@ -204,7 +206,8 @@ $os = ""; $count=0; while($os!=$s && $count<10){ $os=$s; $count++; - $s = $this->_str_replace($s); + //$s = $this->_str_replace($s); + $s = str_replace($this->search, $this->replace, $s); } return template_unescape($s); } diff --git a/include/text.php b/include/text.php index 0f7d2f731..81e22527a 100755 --- a/include/text.php +++ b/include/text.php @@ -996,7 +996,7 @@ function lang_selector() { } $ll = substr($l,5); $ll = substr($ll,0,strrpos($ll,'/')); - $selected = (($ll === $lang && (x($_SESSION['language']))) ? ' selected="selected" ' : ''); + $selected = (($ll === $lang && (x($_SESSION, 'language'))) ? ' selected="selected" ' : ''); $o .= '<option value="' . $ll . '"' . $selected . '>' . $ll . '</option>'; } } @@ -1201,3 +1201,16 @@ function reltoabs($text, $base) return $text; } +function item_post_type($item) { + if(intval($item['event-id'])) + return t('event'); + if(strlen($item['resource-id'])) + return t('photo'); + if(strlen($item['verb']) && $item['verb'] !== ACTIVITY_POST) + return t('activity'); + if($item['id'] != $item['parent']) + return t('comment'); + return t('post'); +} + + |