*/}}
Browse Source

subscription

YimingWu 1 week ago
parent
commit
3fc838d5dc
3 changed files with 219 additions and 14 deletions
  1. 46 14
      index.php
  2. 170 0
      mailsub.php
  3. 3 0
      translations.md

+ 46 - 14
index.php

@@ -282,6 +282,7 @@ class LA{
         fwrite($conf,'- DefaultGallery = '.$this->DefaultGallery.PHP_EOL);
         fwrite($conf,'- SelfAuthPath = '.$this->SelfAuthPath.PHP_EOL);
         fwrite($conf,'- CommentEnabled = '.($this->CommentEnabled?"True":"False").PHP_EOL);
+        fwrite($conf,'- NewsletterEnabled = '.($this->NewsletterEnabled?"True":"False").PHP_EOL);
         fwrite($conf,'- HereHost = '.$this->HereHost.PHP_EOL);
         fwrite($conf,'- HereTitle = '.$this->HereTitle.PHP_EOL);
         fwrite($conf,'- HereShortTitle = '.$this->HereShortTitle.PHP_EOL);
@@ -584,7 +585,7 @@ header li ul li a{font-size:0.9em;}
 //h1,h2,h3,h4,h5{font-size:1em;}
 //h1{text-decoration:underline;}
 header h1,header h2,header h3,header h4,header h5,header p{display:inline;font-size:1rem;}
-.main{position:relative;word-spacing:-1em;top:2em;}
+.main{position:relative;word-spacing:-1em;top:2em;margin-bottom:2em;}
 .main *{word-spacing:initial;}
 pre{overflow:auto;display:block;line-break:anywhere;white-space:pre-wrap;}code{font-size:0.83em;}
 ul{display:block;}
@@ -753,10 +754,11 @@ margin-left:auto;margin-right:auto;max-width:100%;max-height:90vh;}
 .original_img img,.original_img video{max-height:90vh;max-width:100%;}
 .p_row .original_img{margin-bottom:0;}
 .post_ref .original_img{margin:unset;max-width:unset;max-height:min(70vh, 20rem);max-width:min(100%, 20rem);}
-.imbtn{display:block;contain:content;padding:0.25em;margin-bottom:0.5em;text-decoration:none;text-shadow:0px 0px 5px %white%;}
+.imbtn{color:rgba(0,0,0,0);display:block;contain:content;padding:0.25em;margin-bottom:0.5em;text-decoration:none;}
 .imbtn img{display:block;object-fit:cover;position:absolute;top:0;left:0;bottom:0;right:0;margin:auto;z-index:-1;
-min-width:100% !important;min-height:100% !important;filter:opacity(40%);}
-.imbtn:hover img{filter:opacity(20%) blur(0.1em);} .imbtn:hover{color:%black% !important;}
+min-width:100% !important;min-height:100% !important;filter:opacity(70%);transition:0.1s;}
+.imbtn:hover img{filter:opacity(20%) blur(0.2em);} .imbtn:hover{color:%black% !important;}
+.imbtn:hover {color:%black%;text-shadow:0px 0px 5px %white%;}
 header .imbtn{display:inherit;border:none;padding:0em;height:unset;height:unset;margin:0em;contain:unset;}
 header .imbtn:hover{border:none;color:%gray% !important;} header .imbtn img{display:none;}
 .b ul{font-size:1.4em;}
@@ -879,7 +881,7 @@ label{text-align:left;display:inline-block;}
 }
 
 @media screen and (max-width:666px){
-.main{top:unset;}
+.main{top:unset;margin-bottom:unset;}
 html{font-size:16px;}
 pre{max-width:85vw;}
 #titlectrl:checked ~ header .mobile_fold{display:block !important;}
@@ -958,7 +960,7 @@ border-radius:unset;box-shadow:unset;font-size:1.3rem;text-shadow:unset;}
 @media print{
 .small_footer .hidden_on_print{display:none}
 header b,.small_footer b{font-weight:normal;}
-header{display:table-header-group;box-shadow:none;} .main{display:table-row-group;top:unset;} .small_footer{text-align:right;}
+header{display:table-header-group;box-shadow:none;} .main{display:table-row-group;top:unset;margin-bottom:unset;} .small_footer{text-align:right;}
 header::before{box-shadow:none;display:none;} header::after{display:block;height:1em;content:' ';}
 .small_footer::before{box-shadow:none;display:block;height:1em;position:relative;}
 body,footer,header,.small_footer,a,.clean_a,.invert_a,.clean_a a,.invert_a a{background:none;color:black;}
@@ -2680,6 +2682,7 @@ blockquote{border-left:2px solid black;}
                 if(isset($_POST['settings_default_gallery'])) $this->DefaultGallery=$_POST['settings_default_gallery'];
                 if(isset($_POST['settings_selfauth_path'])) $this->SelfAuthPath=$_POST['settings_selfauth_path'];
                 if(isset($_POST['settings_enable_comments'])) $this->CommentEnabled=True; else $this->CommentEnabled=False;
+                if(isset($_POST['settings_enable_newsletter'])) $this->NewsletterEnabled=True; else $this->NewsletterEnabled=False;
                 if(isset($_POST['settings_gallery_step'])) $this->GalleryStep=$_POST['settings_gallery_step'];
                 if(isset($_POST['settings_here_host'])) $this->HereHost=$_POST['settings_here_host'];
                 if(isset($_POST['settings_here_title'])) $this->HereTitle=$_POST['settings_here_title'];
@@ -2995,17 +2998,18 @@ blockquote{border-left:2px solid black;}
     }
     function GetPostTitle(&$post, $h1_only=false, $add_unamed=true){
         if($h1_only){
-            if(preg_match('/^#\s+(.*?)$/mu',$post['content'],$m)) return $m[1];
+            if(preg_match('/^#\s+(.*?)$/mu',$post['content'],$m)) return strip_tags($this->TranslatePostParts($m[1]));
             else return NULL;
         }
         if(!isset($post['title'])){
-            if(preg_match('/^#{1,6}\s+(.*?)$/mu',$post['content'],$m)){$post['title']=$m[1];}
+            if(preg_match('/^#{1,6}\s+(.*?)$/mu',$post['content'],$m)){$post['title']=$m[0];}
             else{ $post['title'] = $add_unamed?$this->T('未命名'):""; 
                 if(preg_match('/(.*)$/mu',$post['content'],$m)){
-                    $post['title'].=($add_unamed?' (':'').strip_tags($this->PDE->text($m[1])).($add_unamed?')':''); } 
+                    $post['title'].=($add_unamed?' (':'').$this->PDE->text($m[1]).($add_unamed?')':''); } 
             }
         }
-        return $this->ChoosePartsByLanguage($post['title']);
+        
+        return strip_tags($this->TranslatePostParts($this->PDE->text($post['title'])));
     }
     
     function DetectPageType(){
@@ -3444,6 +3448,7 @@ blockquote{border-left:2px solid black;}
             $STR.="<div class='hidden_on_print'><br />{$this->MakePostingFieldsV2($is_thread?$th['last']['id']:$post['id'], true)}</div>";
             $this->TFill(2,$STR); $this->TRow();
         }
+        if($this->NewsletterEnabled){ $STR=$this->MakeSubscription(); $this->TFill(2,$STR); $this->TRow(); }
         //$this->MakeCommentSection($post);
         $STR="";
         if(isset($post['slides']) || ($is_thread&&isset($post['tid']['slides']))){
@@ -3502,6 +3507,19 @@ blockquote{border-left:2px solid black;}
         }
     }
 
+    function MakeSubscription($smaller=false){
+        $STR="";$STR.="<div".($smaller?" class='smaller hidden_on_print'":"").">
+        <form action='mailsub.php?subscribe=1' method='post' id='subscribe_form' style='display:none;'></form>
+        <br />
+        <h".($smaller?"3":"2").">{$this->T("订阅我的新闻")}</h".($smaller?"3":"2").">
+        <span class='gray'>{$this->T("输入您的邮件:")}</span>
+        <input type='text' id='email_subscribe_name' name='email_subscribe_name' form='subscribe_form' ".
+            ($smaller?"style='border-color:#f8ca9b88;background:rgba(0,0,0,0.2);max-width:16em;'":"").">
+        <input class='button' form='subscribe_form' type='submit' value={$this->T("订阅")}>
+        <br /></div>";
+        return $STR;
+    }
+
     function MakeRecentPostsV2($search_term=NULL, $category=NULL){ global $INDEXPHP;
         $STR="";
         if(!isset($search_term) && !isset($category) &&
@@ -3509,12 +3527,15 @@ blockquote{border-left:2px solid black;}
             $this->CanShowPost($p)){
             $this->MakeSinglePostV2($p, true, false, "active_post", false, true, false, false, false, true, false);
         }
+        if($this->NewsletterEnabled && !isset($category) && !isset($search_term)){
+            $STR=$this->MakeSubscription(); $this->TFill(2,$STR); $this->TRow(); $STR='';
+        }
         $STR.="<br /><h2>".(isset($search_term)?$this->T('搜索'):
                                 (isset($category)?("<span class='gray'>".$this->T('分类')."</span> ".
                                     ($category=='none'?$this->T('未分类'):$this->T($category))):($this->T('最近')).
                                     " <span class='gray invert_a hidden_on_print'>".//"<a href='index.php?&set_wayback=true'>↶</a>".
                                     ($this->LoggedIn?"<a href='".$INDEXPHP."?comments=all'>@</a> <a href='".$INDEXPHP."?statistics=all'>%</a>":"")."</span>")).
-                    "</h2>";
+                    "</h2><br />";
         $this->TFill(2,$STR); $this->TRow();
         if(isset($search_term)){
             $STR.="<form action='".$INDEXPHP."' method='post' style='display:none;' id='search_form'></form>".
@@ -4166,6 +4187,7 @@ blockquote{border-left:2px solid black;}
         <li><a rel="alternate" type="application/rss+xml" href="?rss=<?=$this->LanguageAppendix;?>" />RSS/Atom<sup><?=$this->LanguageAppendix;?></sup></a></li>
         </ul>
         </div>
+        <?php  if($this->NewsletterEnabled){ $STR=$this->MakeSubscription(1); echo $STR; }?>
         <br />
         <hr class="hidden_on_desktop" />
         </div>
@@ -4970,6 +4992,9 @@ blockquote{border-left:2px solid black;}
                     <tr><td><?=$this->T('启用评论')?></td>
                         <td><input type="checkbox" id="settings_enable_comments" name="settings_enable_comments"
                         form="settings_form" <?=$this->CommentEnabled?"checked":""?>/></td></tr>
+                    <tr><td><?=$this->T('启用新闻')?></td>
+                        <td><input type="checkbox" id="settings_enable_newsletter" name="settings_enable_newsletter"
+                        form="settings_form" <?=$this->NewsletterEnabled?"checked":""?>/></td></tr>
                     <tr><td><?=$this->T('附加操作')?></td><td><a class='gray' href='<?=$INDEXPHP?>?extras=true'><?=$this->T('进入')?></a></td></tr>
                         
                     <tr><td class='smaller gray'>&nbsp;</td></tr>
@@ -5086,7 +5111,7 @@ blockquote{border-left:2px solid black;}
                 <?=$this->T('P为帖子跳转,匹配REQUEST_URI跳到目标文章;S为站点跳转,可以重定向来源域名,例子:')?>
             <br /><pre>P discount:20001001010101;<br />S old_domain:www.new_domain.com:20001001010101;</pre></span>
             <form action="<?=$_SERVER['REQUEST_URI']?>" method="post" style='display:none;' id='settings_form2'></form>
-            <textarea id="settings_redirect" name="settings_redirect" rows="3" class='full_box' wrap="off"
+            <textarea id="settings_redirect" name="settings_redirect" rows="4" class='full_box' wrap="off"
                 form='settings_form2'><?=$this->DisplayRedirectConfig()?></textarea>
             <input class='button' form="settings_form2" type="submit" name='settings_save_redirect'
                 value='<?=$this->T('保存重定向设置')?>' />
@@ -5096,11 +5121,18 @@ blockquote{border-left:2px solid black;}
                 <?=$this->T('填写格式:')?>
             <br /><pre>- 语言 | Language</pre></span>
             <form action="<?=$_SERVER['REQUEST_URI']?>" method="post" style='display:none;' id='settings_form3'></form>
-            <textarea id="settings_translation" name="settings_translation" rows="3" class='full_box' wrap="off"
+            <textarea id="settings_translation" name="settings_translation" rows="4" class='full_box' wrap="off"
                 form='settings_form3'><?=$this->CustomTranslationContent?></textarea>
             <input class='button' form="settings_form3" type="submit" name='settings_save_translation'
                 value='<?=$this->T('保存翻译')?>' />
-            <p>&nbsp;</p>
+
+            <?php if($this->NewsletterEnabled){
+                $subs=file_get_contents("all_subscribers.php"); ?>
+                <br /><br /><h3><?=$this->T('邮件订阅者')?></h3>
+                <textarea rows="4" class='full_box' wrap="off"><?=$subs?substr($subs,5):"error"?></textarea>
+            <?php } ?>
+
+            <br />
             <p class='smaller gray'><?=$this->T('ActivityPub 测试:')?></p>
             <ul>
                 <li><a href='?TestAPubDeliver=1'><?=$this->T('测试发送')?></a></li></ui>

+ 170 - 0
mailsub.php

@@ -0,0 +1,170 @@
+<?php
+
+require_once("PHPMailer/PHPMailer.php");
+require_once("PHPMailer/SMTP.php");
+require_once("PHPMailer/Exception.php");
+
+require_once("mailconf.php");
+
+use PHPMailer\PHPMailer\PHPMailer;
+use PHPMailer\PHPMailer\SMTP;
+
+$mail = new PHPMailer(true);
+
+if(!isset($GLOBALS['MAILSUB_CONFIRM'])){
+    $GLOBALS['MAILSUB_CONFIRM']="<h2>Confirm Subscription</h2>
+<p>You are subscribing to my email newsletter. Click the link below to confirm:</p><br />
+<a href='{CONFIRMLINK}'>{CONFIRMLINK}</a>";
+}
+if(!isset($GLOBALS['MAILSUB_REGULAR'])){
+    $GLOBALS['MAILSUB_REGULAR']="
+<p>This is my email newsletter. <a href='{EDITSUBSCRIPTION}'>Edit your subscription</a></p><br />";
+}
+if(!isset($GLOBALS['MAILSUB_WELCOME'])){
+    $GLOBALS['MAILSUB_WELCOME']="<h2>Welcome</h2>
+<p>You have subscribed to my email newsletter. Edit your subscription below:</p><br />
+<a href='{EDITSUBSCRIPTION}'>{EDITSUBSCRIPTION}</a>";
+}
+if(!isset($GLOBALS['MAILSUB_EDIT'])){
+    $GLOBALS['MAILSUB_EDIT']="<h2>Edit Subscription</h2>
+<p>Unsubscribe my newsletter: <a href='{UNSUBSCRIBE}'>CONFIRM</a></p><br />";
+}
+if(!isset($GLOBALS['MY_HOST'])){
+    $GLOBALS['MY_HOST']="https://www.example.com";
+}
+
+
+$PENDING=[];
+$ACCEPTED=[];
+
+$f = fopen("pending_confirm.php",'r'); $tries=0;
+while(!$f && $tries<100){ $f = fopen("pending_confirm.php",'w'); fclose($f); $tries++;} $f=0;
+$content = file_get_contents("pending_confirm.php");
+
+$f = fopen("all_subscribers.php",'r'); $tries=0;
+while(!$f && $tries<100){ $f = fopen("all_subscribers.php",'w'); fclose($f); $tries++;} $f=0;
+$subscribers = file_get_contents("all_subscribers.php");
+
+
+if(preg_match_all("/(.*)\s+?\[\[\[(.*)\]\]\]\s*?(zh|en|)/",$content,$matches,PREG_SET_ORDER)){
+    foreach($matches as $m){ $PENDING[]=[$m[1],$m[2],$m[3]]; }
+}
+
+if(preg_match_all("/(.*)\s+?\[\[\[(.*)\]\]\]\s*?(zh|en|)/",$subscribers,$matches,PREG_SET_ORDER)){
+    foreach($matches as $m){ $ACCEPTED[]=[$m[1],$m[2],$m[3]]; }
+}
+
+if(isset($_GET['subscribe']) && isset($_POST['email_subscribe_name'])){
+    if(preg_match("/^((?!\.)[\w\-_.]*[^.])(@\w+)(\.\w+(\.\w+)?[^.\W])$/",$_POST['email_subscribe_name'])){
+        $item=[uniqid(),$_POST['email_subscribe_name'],'en'];
+        $PENDING[]=$item;
+        send_verification($item[0],$_POST['email_subscribe_name']);
+    }else{
+        echo "Not a valid email.";
+    }
+
+    $tries=0; while(!$f && $tries<100){ $f = fopen("pending_confirm.php",'w'); $tries++; }
+    fwrite($f,"<php".PHP_EOL);
+    foreach($PENDING as $p){ if($p[1]==0) continue; fwrite($f,"".$p[0]." [[[".$p[1]."]]] $p[2]".PHP_EOL); }
+    fclose($f); $f=0;
+}
+
+if(isset($_GET['confirm']) && isset($_GET['id'])){
+    $address=urldecode($_GET['confirm']); $any=0;
+    foreach($PENDING as $p){
+        if($p[0]==$_GET['id'] && $address==$p[1]){
+            $ACCEPTED[]=$p; unset($PENDING[key($PENDING)]); $any=1;
+            send_welcome($p[0],$address); break;
+        }
+    }
+    if(!$any){ echo "<h2>Couldn't confirm your subscription.</h2>"; exit; }
+
+    $tries=0; while(!$f && $tries<100){ $f = fopen("all_subscribers.php",'w'); $tries++; }
+    fwrite($f,"<php".PHP_EOL);
+    foreach($ACCEPTED as $p){ if($p[1]==0) continue; fwrite($f,"".$p[0]." [[[".$p[1]."]]] $p[2]".PHP_EOL); }
+    fclose($f); $f=0;
+
+    $tries=0; while(!$f && $tries<100){ $f = fopen("pending_confirm.php",'w'); $tries++; }
+    fwrite($f,"<php".PHP_EOL);
+    foreach($PENDING as $p){ if($p[1]==0) continue; fwrite($f,"".$p[0]." [[[".$p[1]."]]] $p[2]".PHP_EOL); }
+    fclose($f); $f=0;
+
+    echo "<h2>Successfully subscribed</h2>";
+}
+
+if(isset($_GET['unsubscribe'])&&isset($_GET['id'])){
+    if(!isset($_GET['doit'])){
+        $link="{$GLOBALS['MY_HOST']}/mailsub.php?unsubscribe={$_GET['unsubscribe']}&doit=1&id={$_GET['id']}";
+        $body=preg_replace("/\{UNSUBSCRIBE\}/",$link,$GLOBALS['MAILSUB_EDIT']);
+        echo $body; exit;
+    }
+
+    $any=0;
+    foreach(array_values($ACCEPTED) as $key=>$p){
+        if($p[0]==$_GET['id'] && $_GET['unsubscribe']==$p[1]){
+            unset($ACCEPTED[$key]); $any=1;
+        }
+    }
+    if(!$any){ echo "<h2>Unknown error</h2>"; exit; }
+
+    $tries=0; while(!$f && $tries<100){ $f = fopen("all_subscribers.php",'w'); $tries++; }
+    fwrite($f,"<php".PHP_EOL);
+    foreach($ACCEPTED as $p){ if($p[1]==0) continue; fwrite($f,"".$p[0]." [[[".$p[1]."]]] $p[2]".PHP_EOL); }
+    fclose($f); $f=0;
+
+    $tries=0; while(!$f && $tries<100){ $f = fopen("pending_confirm.php",'w'); $tries++; }
+    fwrite($f,"<php".PHP_EOL);
+    foreach($PENDING as $p){ if($p[1]==0) continue; fwrite($f,"".$p[0]." [[[".$p[1]."]]] $p[2]".PHP_EOL); }
+    fclose($f); $f=0;
+
+    echo "<h2>Successfully unsubscribed</h2>";
+}
+
+function send_email($to,$subject,$body){
+    try {
+        global $mail;
+        global $mailconf;
+        //Server settings
+        //$mail->SMTPDebug = SMTP::DEBUG_SERVER;                      //Enable verbose debug output
+        $mail->isSMTP();                                            //Send using SMTP
+        $mail->Host       = $mailconf['host'];                     //Set the SMTP server to send through
+        $mail->SMTPAuth   = true;                                   //Enable SMTP authentication
+        $mail->Username   = $mailconf['username'];                     //SMTP username
+        $mail->Password   = $mailconf['password'];                            //SMTP password
+        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;            //Enable implicit TLS encryption
+        $mail->Port       = 587;                                    //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
+    
+        //Recipients
+        $mail->setFrom($mailconf['from'], $mailconf['name']);
+        $mail->addAddress($to);
+    
+        //Content
+        $mail->isHTML(true);                                  //Set email format to HTML
+        $mail->Subject = $subject;
+        $mail->Body    = $body;
+    
+        $mail->send();
+        
+        return null;
+    } catch (Exception $e) {
+        echo "Message could not be sent."; #Mailer Error: {$mail->ErrorInfo}";
+        return -1;
+    }
+}
+
+function send_verification($id,$address){
+    $addressencode=urlencode($address);
+    $link="{$GLOBALS['MY_HOST']}/mailsub.php?confirm=$addressencode&id=$id";
+    $body=preg_replace("/\{CONFIRMLINK\}/",$link,$GLOBALS['MAILSUB_CONFIRM']);
+    if(!send_email($address,"Confirm Subscription",$body)){
+        echo "Please check your inbox for confirmation e-mail.";
+    }else{
+        echo "Error sending email.";
+    }
+}
+function send_welcome($id,$address){
+    $addressencode=urlencode($address);
+    $link="{$GLOBALS['MY_HOST']}/mailsub.php?unsubscribe=$addressencode&id=$id";
+    $body=preg_replace("/\{EDITSUBSCRIPTION\}/",$link,$GLOBALS['MAILSUB_WELCOME']);
+    send_email($address,"Welcome!",$body);
+}

+ 3 - 0
translations.md

@@ -1,3 +1,6 @@
+- 订阅 | Subscribe
+- 输入您的邮件: | Enter your email:
+- 订阅我的新闻 | Newsletters
 - 那么的维基 | laMDWiki
 - 基 | Ki
 - 管理员 | Administrator