Click here to Skip to main content
15,895,142 members
Articles / Programming Languages / Razor

Extending WordPress with C# Plugins

Rate me:
Please Sign up or sign in to vote.
4.98/5 (21 votes)
30 May 2012Apache16 min read 171K   1.5K   57  
This article describes how to extend WordPress with plugins written in C# and shows very first C# plugin for this system.
/*
 * Content Watchdog Wordpress C# Plugin
 * 
 * Author: 
 *  Miloslav Beno (miloslav@devsense.com)
 * 
 * Copyright (c) 2012 DEVSENSE s.r.o
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Devsense.Text;

namespace Devsense.WordPress.Plugins.ContentWatchdog
{   
    
    /// <summary>
    /// Main class of ContentWatchdog plugin for monitoring content of posts and pages
    /// </summary>
    public class ContentWatchdog
    {
        #region Constants
        private const string optionfPrefix = "content_watch_dog_";

        private const string badWordsOption     = optionfPrefix + "bad_words";
        private const string emailOption        = optionfPrefix + "email";
        private const string watchContentOption = optionfPrefix + "watching";
        private const string matchWholeWordOption = optionfPrefix + "matchWholeWord";

        private const string badWordFoundArg = "badWordFound";
        #endregion

        #region Fields and Properties

        private static StringSearch badWordsSearch;
        private dynamic wp;

        /// <summary>
        /// Collection of words to be monitored in posts and pages by the plugin
        /// </summary>
        public StringSearch BadWordsSearch
        {
            get 
            {
                if (badWordsSearch == null)
                    InitStringSearch();

                return badWordsSearch; 
            }
        }

        /// <summary>
        /// String of comma separated words to be monitored by the plugin
        /// </summary>
        public string BadWordsString
        {
            get { return wp.get_site_option(badWordsOption) as string; }
            set {
                if (value != null)
                {
                    string trimed = value.Trim();
                    wp.update_site_option(badWordsOption, value);
                    InitStringSearch();
                }
            }
        }

        /// <summary>
        /// Email address where notification email will be sent in case of post/page was
        /// submitted with bad word.
        /// </summary>
        /// <remarks>Default email is email of administrator</remarks>
        public string Email
        {
            get
            {
                string recipient = wp.get_site_option(emailOption) as string;

                //Check if email is not set
                if (String.IsNullOrEmpty(recipient))
                {
                    //return administrator email
                    return wp.get_site_option("admin_email") as string;
                }

                return recipient;
            }
            set { wp.update_site_option(emailOption, value); }
        }

        /// <summary>
        /// Indicates whether content monitoring is enabled
        /// </summary>
        public bool WatchContent
        {
            get { return !String.IsNullOrEmpty(wp.get_site_option(watchContentOption) as string); }
            set { wp.update_site_option(watchContentOption, value ? "1" : String.Empty); }
        }


        /// <summary>
        /// Indicates whether content monitoring is enabled
        /// </summary>
        public bool MatchWholeWord
        {
            get { return !String.IsNullOrEmpty(wp.get_site_option(matchWholeWordOption) as string); }
            set { wp.update_site_option(matchWholeWordOption, value ? "1" : String.Empty); }
        }

        /// <summary>
        /// Bad word was detected during saving the post
        /// </summary>
        public bool BadWordFound
        {
            get { return (wp._GET[badWordFoundArg] as string) != null; }
        }

        #endregion

        #region Construction

        /// <summary>
        /// Initialize new instance of the ContentWatchdog plugin
        /// </summary>
        public ContentWatchdog()
        {
            wp = PHP.Core.ScriptContext.CurrentContext.Globals;
           
            if (wp.is_multisite())
                wp.add_action("network_admin_menu", new Action(AddAdminPage), 10, 0);
            else
                wp.add_action("admin_menu", new Action(AddAdminPage), 10, 0);

            if (WatchContent)
            {
                wp.add_action("save_post", new Action<int, dynamic>(CheckPost), 10, 2);
                wp.add_action("all_admin_notices", new Action(ShowNotification), 10, 0);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Initialize StringSearch tree structure
        /// </summary>
        private void InitStringSearch()
        {
            var badWordsCol = BadWordsString.Split(',').Select(p => p.Trim()).ToArray();
            badWordsSearch = new StringSearch(badWordsCol, MatchWholeWord);
        }

        /// <summary>
        /// Adds admin page into admin section
        /// </summary>
        private void AddAdminPage() 
        {
            if (wp.is_multisite())
                wp.add_submenu_page("settings.php", Strings.PluginName, Strings.PluginName, 10, "content-watch-dog", new Action(AdminPageOutput));
            else
                wp.add_options_page(Strings.PluginName, Strings.PluginName, 10, "content-watch-dog", new Action(AdminPageOutput));
        }

        /// <summary>
        /// Outputs admin page
        /// </summary>
        /// <param name="s"></param>
        private void AdminPageOutput()
        {
            InitPropertiesFromForm();

            var template = new AdminPage{Model = this};
            template.Execute(); //Sends AdminPage to output stream
        }

        /// <summary>
        /// Initialize properties from submitted user form
        /// </summary>
        private void InitPropertiesFromForm()
        {
            var request = System.Web.HttpContext.Current.Request;
            if (request.Form.Count > 0)
            {
                //Update properties
                Email = wp.is_email(request.Form["Email"]) as string;
                WatchContent = request.Form["WatchContent"] != null ;
                MatchWholeWord = request.Form["MatchWholeWord"] != null;
                BadWordsString = wp.esc_html(request.Form["BadWordsString"]) as string;
            }
        }

        /// <summary>
        /// Checks post/page for occurrence of bad word
        /// </summary>
        /// <param name="postId">Identificator of post/page</param>
        /// <param name="post">Object representing the post/page</param>
        private void CheckPost(int postId, dynamic post) 
        {
            // Don't check it if it's not a post or page
            if (post.post_type != "post" && post.post_type != "page")
                return;

            //Don't check it if it's not published or it's password protected
            if (post.post_status != "publish" || !String.IsNullOrEmpty(post.post_password))
                return;

            if (BadWordsSearch.ContainsAny(post.post_title) || BadWordsSearch.ContainsAny(post.post_content))
            {
                //bad word was found
                string post_permalink = wp.get_permalink(postId);

                NotifyUser();
		        MailNotify(post_permalink, post.post_type);
            }
        }

        /// <summary>
        /// Sends a notification email to address in Email property
        /// </summary>
        /// <param name="postUrl">URL of the post</param>
        /// <param name="postType">Type of the post</param>
        private void MailNotify(string postUrl, string postType)
        {
            string subject = String.Format(Strings.MessageSubject, wp.get_site_url());
            string message = String.Format(Strings.MessageBody, postType, postUrl);

        	wp.wp_mail(Email, subject, message);
        }

        /// <summary>
        /// Sets notification argument into URL query string so user is notified after saving the post
        /// </summary>
        private void NotifyUser()
        {
            Func<string, int, string> redirect_post = (location, postId) => { return wp.add_query_arg(badWordFoundArg, "1", location); };

            wp.add_filter("redirect_post_location", redirect_post, 10, 2);
        }

        /// <summary>
        /// Displays warning notification that bad word was found
        /// </summary>
        private void ShowNotification()
        {
            if (BadWordFound)
                wp.notice = Strings.BadWordFoundWarning;
        }


        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Software Developer DEVSENSE s.r.o
Czech Republic Czech Republic
Miloslav is software developer of open-source PHP compiler & runtime for .NET/Mono called Phalanger and PHP Tools for Visual Studio. He's graduated at Faculty of Mathematics and Physics at Charles University in Prague. Beside of compilers and dynamic languages he is also interested in semantic web technologies. Available on twitter @miloslavbeno

Comments and Discussions