简体   繁体   中英

how to change OctoberCms rainlabs blogpost plugin from sending automatic email with public function afterSave() to isPublished?

This piece of code shows a smll part of the models post.php from October Rainlab Blog plugin. The AfterSave() function is modified, it sends an e-mail when a new blogPost in the backend is saved by the administrator, however, I would like to send it when it is actually Published and make sure it is not sending multiple times. How could I accomplish this?

    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"],0,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();
        }

        

One way to accomplish this would be to extend the Post model.

As an example, you create a new plugin and model with an is_notified field.

You would then add something like this to the boot() method of your new plugin:

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;
    }
}

You can then use that new model in the afterSave method

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;
            }
           
        }
    }   

}

You should also consider using the extend method instead of modifying 3rd party plugin code. This will allow you to update the plugin without losing your edits. Something like this:

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'])) {
            ..
        }
        
    });
});

Let me know if you have any questions!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM