如何将 OctoberCms Rainlabs blogpost 插件从发送带有公共函数 afterSave() 的自动电子邮件更改为 isPublished?

问题描述

这段代码显示了来自 October Rainlab Blog 插件的模型 post.PHP 的一小部分。 AfterSave() 函数修改,当后台有新的 blogPost 被管理员保存时,它会发送一封电子邮件,但是,我想在它实际发布时发送它,并确保它不会多次发送。我怎么能做到这一点?

    public function filterFields($fields,$context = null)
    {
        if (!isset($fields->published,$fields->published_at)) {
            return;
        }

        $user = BackendAuth::getUser();

        if (!$user->hasAnyAccess(['rainlab.blog.access_publish'])) {
            $fields->published->hidden = true;
            $fields->published_at->hidden = true;
        }
        else {
            $fields->published->hidden = false;
            $fields->published_at->hidden = false;
        }
    }

    public function afterValidate()
    {
        if ($this->published && !$this->published_at) {
            throw new ValidationException([
               'published_at' => Lang::get('rainlab.blog::lang.post.published_validation')
            ]);
        }
    }

    public function beforeSave()
    {
        if (empty($this->user)) {
            $user = BackendAuth::getUser();
            if (!is_null($user)) {
                $this->user = $user->id;
            }
        }
        $this->content_html = self::formatHtml($this->content);
    }


    public function afterSave()
    {
      
   $user = BackendAuth::getUser();

    if ($user && $user->hasAnyAccess(['rainlab.blog.access_publish'])) {
        
            
    $susers = Db::select('select * from users where is_activated = ?',[1]);
            foreach ($susers as $suser) {
         
     
      $currentPath = $_SERVER['PHP_SELF']; 
      $pathInfo = pathinfo($currentPath); 
      $hostName = $_SERVER['HTTP_HOST']; 
      $protocol = strtolower(substr($_SERVER["SERVER_PROTOCOL"],5))=='https'?'https':'http';
      $protocol.'://'.$hostName.$pathInfo['dirname']."/";     
      $spost_url = $protocol.'://'.$hostName.$pathInfo['dirname']."/"."nieuws/".$this->attributes['slug']   ;   

      $stitle = $this->attributes['title'] ;
      $body = '<div> Hallo '.$suser->name.'</br> Er is zojuist een nieuws bericht gepubliceerd voor alle leden van mycompany.nl,je kunt hier het bericht lezen aangaande:  <a href="'.$spost_url.'">'.$stitle.'</a> </div>' ;
      //$from = $user->email ;
      $from = 'noreply@mycompany.nl';
      $headers  = "From: $from\r\n"; 
      $headers .= "Content-type: text/html\r\n";
 

       mail($suser->email,'Nieuws van mycompany',$body,$headers);
            }
        }   

    }
    /**
     * Sets the "url" attribute with a URL to this object.
     * @param string $pageName
     * @param Controller $controller
     * @param array $params Override request URL parameters
     *
     * @return string
     */
    public function setUrl($pageName,$controller,$params = [])
    {
        $params = array_merge([
            'id'   => $this->id,'slug' => $this->slug,],$params);

        if (empty($params['category'])) {
            $params['category'] = $this->categories->count() ? $this->categories->first()->slug : null;
        }

        // Expose published year,month and day as URL parameters.
        if ($this->published) {
            $params['year']  = $this->published_at->format('Y');
            $params['month'] = $this->published_at->format('m');
            $params['day']   = $this->published_at->format('d');
        }

        return $this->url = $controller->pageUrl($pageName,$params);
    }

    /**
     * Used to test if a certain user has permission to edit post,* returns TRUE if the user is the owner or has other posts access.
     * @param  User $user
     * @return bool
     */
    public function canEdit(User $user)
    {
        return ($this->user_id == $user->id) || $user->hasAnyAccess(['rainlab.blog.access_other_posts']);
    }

    public static function formatHtml($input,$preview = false)
    {
        $result = Markdown::parse(trim($input));

        // Check to see if the HTML should be cleaned from potential XSS
        $user = BackendAuth::getUser();
        if (!$user || !$user->hasAccess('backend.allow_unsafe_markdown')) {
            $result = Html::clean($result);
        }

        if ($preview) {
            $result = str_replace('<pre>','<pre class="prettyprint">',$result);
        }

        $result = TagProcessor::instance()->processtags($result,$preview);

        return $result;
    }

    //
    // Scopes
    //

    public function scopeIsPublished($query)
    {
        return $query
            ->whereNotNull('published')
            ->where('published',true)
            ->whereNotNull('published_at')
            ->where('published_at','<',Carbon::Now())
        ;
    }

    /**
     * Lists posts for the frontend
     *
     * @param        $query
     * @param  array $options display options
     * @return Post
     */
    public function scopeListFrontEnd($query,$options)
    {
        /*
         * Default options
         */
        extract(array_merge([
            'page'             => 1,'perPage'          => 30,'sort'             => 'created_at','categories'       => null,'exceptCategories' => null,'category'         => null,'search'           => '','published'        => true,'exceptPost'       => null
        ],$options));

        $searchableFields = ['title','slug','excerpt','content'];

        if ($published) {
            $query->isPublished();
        }

        

解决方法

实现此目的的一种方法是扩展 Post 模型。

例如,您创建一个带有 is_notified 字段的新插件和模型。

然后,您将在新插件的 boot() 方法中添加如下内容:

PostModel::extend(function ($model) {
    $model->hasOne['your_model'] = ['Author\PluginName\Models\YourModel'];
});

PostsController::extendFormFields(function ($form,$model,$context) {
    // Checking for Post instance
    if (!$model instanceof PostModel) {
        return;
    }

    // without this code you can get an error saying "Call to a member function hasRelation() on null"
    if (!$model->your_model) {
        $model->your_model = new YourModel;
    }
}

然后您可以在 afterSave 方法中使用该新模型

public function afterSave()
{
    
    $user = BackendAuth::getUser();

    if ($user && $user->hasAnyAccess(['rainlab.blog.access_publish'])) {
        $susers = Db::select('select * from users where is_activated = ?',[1]);
        foreach ($susers as $suser) {
            ...

            if ($this->your_model->is_notified != true) {
                mail($suser->email,'Nieuws van mycompany',$body,$headers);
                $this->your_model->is_notified = true;
            }
           
        }
    }   

}

您还应该考虑使用扩展方法而不是修改 3rd 方插件代码。这将允许您更新插件而不会丢失您的编辑。像这样:

PostModel::extend(function ($model) {
    $model->hasOne['your_model'] = ['Author\PluginName\Models\YourModel'];

    // You can transfer your afterSave code here!
    $model->bindEvent('model.afterSave',function () use ($model) {
        $user = BackendAuth::getUser();

        if ($user && $user->hasAnyAccess(['rainlab.blog.access_publish'])) {
            ..
        }
        
    });
});

如果您有任何问题,请告诉我!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...