<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>3DN Technology &#187; coding</title>
	<atom:link href="http://wordpress.3dn.nl/category/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://wordpress.3dn.nl</link>
	<description>3DN Technology Blog</description>
	<lastBuildDate>Wed, 27 Jul 2011 07:14:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Playing with Simple Facebook Connect</title>
		<link>http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/</link>
		<comments>http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 22:23:19 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[dutchie]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[fbml]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1996</guid>
		<description><![CDATA[Playing with Simple Facebook Connect]]></description>
			<content:encoded><![CDATA[<div>
<p>As a brief note to myself and other who may experience the same problem: I use the <a title="Simple Facebook Connect" href="http://ottopress.com/wordpress-plugins/simple-facebook-connect/" target="_blank">&#8220;Simple Facebook Connect (SFC)&#8221;</a> WordPress plugin on my site. It&#8217;s a very nice modularly written plugin but that&#8217;s all described very well on the site. My note is about using this plugin on a WordPress instance running multiple domains however.</p>
<p>While adding &#8216;like&#8217; buttons to my second domain on the server, I noticed I started getting error message from Facebook saying:</p>
<blockquote><p>﻿The app ID specified within the &#8220;fb:app_id&#8221; meta tag is not allowed on this domain. You must setup the Connect Base Domains for your app to be a prefix of http://dutchie.org/rowan-lore/.</p></blockquote>
<p>Further investigation showed that the &lt;fb:like tag generated by plugin adds an href parameter which contains the http://dutchie.org/rowan-lore/ URL.</p>
<p>As http://dutchie.org is really running on http://dutchie.3dn.nl but mapped on there with the domain mapping plugin, I figured I&#8217;d change the href parameter into http://dutchie.3dn.nl/rowan-lore. This can be done through a bit of an undocumented feature in SFC. I modify the theme files directly through putting an sfc_like() call in the theme file. When used without arguments, the sfc_like() function will generate the URL based on the get_permalink() WordPress API call. However, noticing the function also parses a $args parameter when provided, I decided to do:</p>
<pre class="brush: php; title: ; notranslate">
$url = urlencode(str_replace('dutchie.org ', 'dutchie.3dn.nl ', get_permalink($id))); sfc_like_button(array('url' =&amp;gt; $url));
</pre>
<p>While of course this little trick is handy to know and resulted in the desired effect, the error message remains.</p>
<p>I&#8217;ve also been looking into the FBML tags being put in the header:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;meta property='fb:app_id' content='100842573341270' /&gt;
&lt;meta property=&amp;quot;og:site_name&amp;quot; content=&amp;quot;Dutchie&amp;quot; /&gt;
&lt;meta property='og:url' content='http://dutchie.org/rowan-lore/' /&gt;
</pre>
<p>And manually tried to force sfc-base.php to generate dutchie.3dn.nl instead of dutchie.org in the og:url field. Alas, this also did not work. Otto, the developer of SFC assured me that there is no way of adding a second domain to a single FB application, but I&#8217;m still curious about this as http://dutchie.org is a second domain on the server indeed, but it&#8217;s *mapped* to http://dutchie.3dn.nl which is a subdomain of the facebook app.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Bookmarks for Chrome?</title>
		<link>http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/</link>
		<comments>http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/#comments</comments>
		<pubDate>Thu, 19 May 2011 09:15:35 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[sharing]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1600</guid>
		<description><![CDATA[I visit Facebook quite frequently, post a lot of stuff, and I always find myself wondering &#8216;hmmm, I posted something about this and that a month or so ago&#8217;. Searching...]]></description>
			<content:encoded><![CDATA[<p>I visit Facebook quite frequently, post a lot of stuff, and I always find myself wondering &#8216;hmmm, I posted something about this and that a month or so ago&#8217;.</p>
<p>Searching through your own posts on Facebook is a nightmare!</p>
<p>I&#8217;m pretty curious if anybody else would be interested in seeing a Chrome plugin that lets you add your own facebook links to your Chrome bookmarks for much easier reference. Like this article if you do and don&#8217;t hesitate sharing the idea as I&#8217;m just really curious if anybody would even use it.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Add Ajax to Expertise Plugin</title>
		<link>http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/</link>
		<comments>http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 08:43:32 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[expertise]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[thickbox]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1508</guid>
		<description><![CDATA[The Expertise plugin is nearing completion now. We still need to give experts a method to sign up as experts for the 3DN expertise areas (or to sign out should they no longer want to act as expert). We will be using some Wordpress specific Ajax constructs for this.]]></description>
			<content:encoded><![CDATA[<h1></h1>
<p>The Expertise plugin is nearing completion now. We still need to give experts a method to sign up as experts for the 3DN expertise areas (or to sign out should they no longer want to act as expert). We will be using some WordPress specific Ajax constructs for this.</p>
<p>One of the reasons we would like users to sign up and be logged in when they look at the expertise pages is so we can see right away if somebody who&#8217;s visiting the pages is an expert himself or not. This way we can decide what button to show and what action to attach to the button. We have two different buttons to choose from:</p>
<p><a href="http://wordpress.3dn.nl/files/2010/02/expert1.png"><img class="alignnone size-full wp-image-1512" src="http://wordpress.3dn.nl/files/2010/02/expert1.png" alt="" width="105" height="34" /></a> <a href="http://wordpress.3dn.nl/files/2010/02/noexpert.png"><img class="alignnone size-full wp-image-1513" src="http://wordpress.3dn.nl/files/2010/02/noexpert.png" alt="" width="128" height="35" /></a></p>
<p>These are opt-in / opt-out buttons where a visitor can indicate whether he is or isn&#8217;t an expert on the expertise being viewed.</p>
<p>These buttons have a simple onclick javascript that gets executed when the user clicks on them; when the opt-in button is clicked a simple thickbox dialog asking for the user&#8217;s expertise level is displayed while the opt-out button simply shows an &#8216;are you sure&#8217; question. In this article I&#8217;ll assume the reader is familiar with thicbox and how to pop-up a dialog.</p>
<h2>Using SACK</h2>
<p>SACK is the Simple Ajax Code Kit. We don&#8217;t want clicking the button on the popup dialog to cause a reload of the whole page so we&#8217;re using SACK to send an asynchronous page request to the server to handle the opt-in / opt-out.</p>
<p>To do this, we first need to tell WordPress to include the SACK library javascript:</p>
<pre class="brush: php; title: ; notranslate">
// Add SACK requirement to head
add_action ('wp_head', 'expertise_js_header');

function expertise_js_header () {
 wp_print_scripts ( array ('sack') );
</pre>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6394625565386592";
/* 468x60, gemaakt 3-2-10 */
google_ad_slot = "0905523941";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>The only thing somewhat complicated for using SACK is that we need to figure out what page to post the AJAX requests to; WordPress comes with a <em>/wp-admin/admin-ajax.php</em> script for this. It&#8217;s a unified Ajax handler script that can be used for all AJAX requests. We only need to tell it about a <em>callback</em> function to use depending on which <em>action</em> the page receives. First we define our own actions, <em>handle_signup</em> and <em>handle_signout</em>:</p>
<pre class="brush: php; title: ; notranslate">
// Configure AJAX callback
add_action ('wp_ajax_handle_signup', &quot;signup_callback&quot;);
add_action ('wp_ajax_nopriv_handle_signup', &quot;signup_callback&quot;);
add_action ('wp_ajax_handle_signout', &quot;signout_callback&quot;);
add_action ('wp_ajax_nopriv_handle_signout', &quot;signout_callback&quot;);
</pre>
<p>Then in our button javascript we use these action names in the SACK initialization:</p>
<pre class="brush: php; title: ; notranslate">
// Define custom Javascript function
?&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
//&lt;![CDATA[
function expertise_signup () {
 for (var i=0; i &lt; document.lvlfrm.lvlval.length; i++) {
 if (document.lvlfrm.lvlval[i].checked) {
 var expertise_level = document.lvlfrm.lvlval[i].value;
 }
 }
 var mysack = new sack (
 &quot;&lt;?php bloginfo ('wpurl'); ?&gt;/wp-admin/admin-ajax.php&quot; );

 mysack.execute = 1;
 mysack.method = 'POST';
 mysack.setVar (&quot;action&quot;, &quot;handle_signup&quot;);
 mysack.setVar (&quot;expertise_level&quot;, expertise_level);
 mysack.runAJAX();

 parent.tb_remove();
}
</pre>
<p>And finally we add the actual callback function:</p>
<pre class="brush: php; title: ; notranslate">
function signup_callback () {
 $level = $_POST['expertise_level'];
 $levels = array( 'junior', 'medior', 'senior' );
 $thelevel = $levels[$level - 1];
 $error = &quot;&quot;;
 $results = &quot;You have signed up as a $thelevel expert!&quot;;
 if ($error ) {
 die ( &quot;alert('$error')&quot; );
 }
 die( &quot;document.getElementById('$results_id').innerHTML = '$results'&quot; );
}
</pre>
<p>The callback function itself is not completely finished here but you&#8217;ll probably get the idea from this sample code.</p>
<h2>Read More</h2>
<p>If  you liked reading this article you might want to read some more articles in 3DN&#8217;s WordPress category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2010/05/12/migrating-wordpress/">New 3DN Techblog</a>   </li><li class = current ><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>Or in the Coding category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/">Facebook Bookmarks for Chrome?</a>   </li><li class = current ><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Checking Comments for Requests</title>
		<link>http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/</link>
		<comments>http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 15:38:32 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[disqus]]></category>
		<category><![CDATA[expertise]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1429</guid>
		<description><![CDATA[Disqus comments are no different from regular Wordpress comments. This means that checking the comments on an expertise page will be no different for Disqus comments as it is for standard Wordpress comments. Can we still find something special to do with Disqus comments?]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px;font-weight: normal">Disqus comments are no different from regular WordPress comments. This means that checking the comments on an expertise page will be no different for Disqus comments as it is for standard WordPress comments. Can we still find something special to do with Disqus comments?</span></h1>
<p>The Disqus comment system is a really well thought out commenting system. I had imagined I would need to use the Disqus API to check for new comments on our expertise pages but no such thing; When users submit a comment through Disqus, a local copy is kept as well according to a comment by avinash on <a title="MattFlies" href="http://mattflies.com/tech/why-and-how-to-use-disqus-with-wordpress/" target="_blank">MattFlies&#8217; blog</a>. Ofcourse I verified this before believing it by posting a comment:</p>
<pre class="brush: sql; title: ; notranslate">
mysql&gt; select count(*) from wp_comments;
+----------+
| count(*) |
+----------+
|       84 |
+----------+
</pre>
<p>Then I posted a comment:</p>
<pre class="brush: sql; title: ; notranslate">
mysql&gt; select count(*) from wp_comments;
+----------+
| count(*) |
+----------+
|       84 |
+----------+
</pre>
<p>So alas, it looks like it&#8217;s not true what&#8217;s being said! I checked into this with the Disqus support and they recommended that I try their beta version. I installed it but the same issue remained. However at some point, &#8216;magically&#8217; the Disqus posts would indeed show up in my wp_comments. I guess I had assumed that the update in wp_comments would be immediate after somebody posts a message. This is not quite true; I inspected the code for the Disqus plugin:</p>
<pre class="brush: php; title: ; notranslate">
add_filter('comments_template', 'dsq_comments_template');

function dsq_comments_template($value) {
...
// Sync comments with database.
 dsq_sync_comments($post, $dsq_response['posts']);
...
}
</pre>
<p>This implies that the <em>dsq_sync_comments()</em> function only gets called when the comments_template hook is triggered. I tried this theory simply by reloading the page after I posted a comment and indeed, the counter on wp_comments increased! Well you could call this a bug or a feature I guess but for my purposes it means that I cannot rely on the WordPress comment functions to work properly under all circumstances. So I decided to mimic the <em>dsq_sync_comments()</em> behaviour in the Expertise plugin&#8217;s hourly message check instead:</p>
<pre class="brush: php; title: ; notranslate">
// Require this in case we use Disqus on our site.
$expert_settings = get_option(&quot;expert_settings&quot;);
$disqusactive = 0;
if ($expert_settings['commentsmethod'] == 'disqus') {
 define ('DISQUS_API_FILE', WP_PLUGIN_DIR . '/disqus-comment-system/lib/api.php');
 // Check if API file exists and if plugin is activated
 if (file_exists(DISQUS_API_FILE) &amp;&amp; function_exists('dsq_sync_comments')) {
 require_once(WP_PLUGIN_DIR . '/disqus-comment-system/lib/api.php');
 $dsq_api = new DisqusAPI(get_option('disqus_forum_url'), get_option('disqus_api_key'));
 $disqusactive = 1;
 }
}

function hourly_msgcheck () {
 global $disqusactive;
 global $dsq_api;

 if ($disqusactive) {
 $args = array (
 'post_type' =&gt; 'page',
 'numberposts' =&gt; -1
 );
 $expert_posts = get_posts ($args);
 if ($expert_posts) {
 foreach ($expert_posts as $post) {
 setup_postdata($post);
 $permalink = get_permalink($post);
 $title = get_the_title($post);
 $excerpt = get_the_excerpt($post);

 // Call &quot;get_thread&quot; API method.
 $dsq_response = $dsq_api-&gt;get_thread($post, $permalink, $title, $excerpt);
 if( $dsq_response &lt; 0 ) {
 return false;
 }

 // Sync comments with database.
 dsq_sync_comments($post, $dsq_response['posts']);
 }
 }
 }
}
</pre>
<p>This seems to work rather well so far, now it&#8217;s off to actually using the WordPress API again and checking for new messages to we can finally get to sending the new messages to the experts!</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding sendmail/SMTP to experts plugin</title>
		<link>http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/</link>
		<comments>http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 16:26:47 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[expertise]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[google apps]]></category>
		<category><![CDATA[mta postfix]]></category>
		<category><![CDATA[smtp servers]]></category>
		<category><![CDATA[smtp service]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1414</guid>
		<description><![CDATA[The expertise plugin I'm writing and have been publishing about needs a selector in the admin screen to allow sending mail through SMTP or through sendmail. This article will include some javascript to do just that.]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px;font-weight: normal">The expertise plugin I&#8217;m writing and have been publishing about needs a selector in the admin screen to allow sending mail through SMTP or through sendmail. This article will include some javascript to do just that.</span></h1>
<h2>GMAIL</h2>
<p>Because of my local setup at first I decided to let the experts plugin use GMAIL&#8217;s SMTP service for mailing the Experts when new expertise requests are posted. GMAIL has a great free service to allow people to use their SMTP servers to send mail through. I&#8217;m also a Google Apps user to host my own domain&#8217;s emails on GMAIL so it seemed like a natural thing to do at first. GMAIL&#8217;s setup is a little bit tricky however as not only do you need to use TLS (encryption) and authentication to use it, there are also some complications with properly setting the sender of the email.</p>
<p>I&#8217;ve long ago been able to configure my local MTA (postfix) to do all of the above but it&#8217;s apparently not so trivial to do this directly from PHP. I tried doing this using the WordPress supplied PHPMailer class but so far I have not been able to get it to send email succesfully using SMTP.</p>
<h2>Sendmail</h2>
<p>The PHPMailer class can also send email using the sendmail method. While the sendmail name is reminiscent of the good old sendmail, it basically means to use the local MTA on the server WordPress is running on. As I&#8217;ve configured my local MTA properly it was easy enough to get PHPMailer to send email through the sendmail method.</p>
<p>So while the experts plugin is now able to send email using the sendmail method, I&#8217;m starting to think that the plugin I&#8217;m developing may be useful to others as well down the line and I decided to keep the broken SMTP part in order to fix it later on. This means I need to have a mail method selector in the admin menu and some code in the plugin to decide what method to use based on the selector value.</p>
<h2>Adding the Selector</h2>
<p>Now that I have the <em>register_settings()</em> understood, it was fairly easy to add a selector. All that it required was to add a <em>mailmethod</em> field to the expert_settings array:</p>
<pre class="brush: php; title: ; notranslate">
add_option('expert_settings', array(
 'onpost' =&gt; 1,
 'mailmethod' =&gt; 'sendmail',
 'smtp_user' =&gt; '',
 'smtp_password' =&gt; '',
 'smtp_server' =&gt; 'smtp.gmail.com'));
</pre>
<p>As well as a select field to the admin form:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;tr&gt;
 &lt;td&gt;Mail Method&lt;/td&gt;
 &lt;td&gt;&lt;select name=&quot;expert_settings[mailmethod]&quot;&gt;
 &lt;option value=&quot;smtp&quot; &lt;?php selected(&quot;smtp&quot;,$expert_settings[mailmethod]); ?&gt;&gt;SMTP&lt;/option&gt;
 &lt;option value=&quot;sendmail&quot; &lt;?php selected(&quot;sendmail&quot;,$expert_settings[mailmethod]); ?&gt;&gt;Sendmail&lt;/option&gt;
 &lt;/select&gt;&lt;/td&gt;
 &lt;tr&gt;
</pre>
<p>This literally took me like 5 minutes to do after having spent considerable time on learning the <em>register_settings()</em> stuff.</p>
<h2>Make it look Pretty</h2>
<p>Since it was so easy to add the above I figured I might as well spend some time I saved on making it look pretty; When the admin chooses to use the <em>sendmail</em> method for sending mail, the SMTP settings (eg. user/password/servername etc.) are irrelevant so we could add some Javascript to enable/disable those fields when either mail method gets selected by the user. The best way to dynamically change form fields is still by using Javascript so let&#8217;s go ahead and add a scripts directory to our project:</p>
<pre class="brush: bash; title: ; notranslate">
fredl@omega:/web/prd/wordpress.3dn.nl/wp-content/plugins/experts$ mkdir scripts
fredl@omega:/web/prd/wordpress.3dn.nl/wp-content/plugins/experts$ svn add scripts/
A         scripts
</pre>
<p>And a bit of Javascript in it&#8217;s own file:</p>
<pre class="brush: bash; title: ; notranslate">
fredl@omega:/web/prd/wordpress.3dn.nl/wp-content/plugins/experts/scripts$ svn add admin.js
A         admin.js
</pre>
<p>We need to include this inside our admin form. To do this we first need to take a step back and look at our admin menu definition again. So far we&#8217;ve only told WordPress to add an action to the admin_menu using</p>
<pre class="brush: php; title: ; notranslate">
// Add page name, then scripts and styles
 if (function_exists('add_options_page')) {
 add_action(&quot;admin_print_scripts&quot;, 'expertise_admin_scripts');
 add_action(&quot;admin_print_styles&quot;, 'expertise_admin_styles');
 }

function expertise_admin_scripts () {
 wp_enqueue_script('expertise-js', EXPERTISE_PLUGPATH.'scripts/admin.js');
}

function expertise_admin_styles () {
  wp_enqueue_style('expertise-css', EXPERTISE_PLUGPATH.'style/admin.css');
}
</pre>
<p>This should now include our still empty piece of Javascript in our admin menu. This is not nearly perfect as the <em>add_action(&#8220;admin_print_scripts&#8221;&#8230;</em> should really have a page name like <em>add_action(&#8220;admin_print_scripts-$pagename&#8221;&#8230;.</em> to limit which admin pages the script gets enqueued in but at the time of writing this I&#8217;m not really sure how to do this. I also added a constant <em>EXPERTISE_PLUGPATH</em> to the plugin as well as a CSS file that may come in handy when we implement our JS to dynamically disable elements.</p>
<p>So now we have the JS script and the CSS in place, we need to add some action to the mailmethod select:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;select name=&quot;expert_settings[mailmethod]&quot; onChange=&quot;toggleSMTP()&quot;&gt;
</pre>
<p>Remember, we want to toggle the visibility of our SMTP settings when the Sendmail or SMTP mailmethod is chosen. So in scripts/admin.js we create the Javascript function toggleSMTP():</p>
<pre class="brush: jscript; title: ; notranslate">
function toggleSMTP () {
 alert(&quot;Toggling&quot;);
}
</pre>
<p>And indeed we get a nice popup saying &#8216;Toggling&#8217; when we toggle the mailmethod in the admin screen. While the popup is a good test to see if things work so far, ofcourse it needs some real functionality now so we wrap our SMTP settings into a div. We define the div style first in admin.css, calling it simply &#8216;#smtpsettings&#8217; and wrapping our SMTP settings in it. The problem with this is that tables, which I used to layout the settings menu initially, don&#8217;t behave very nicely with CSS, so since I added some custom CSS file to the menu anyway I decided to make the settings menu a CSS based layout instead. I also decided to disable the SMTP inputs instead of making them invisible. So in <em>toggleSMTP()</em> we first want to get the selected value of the mailmethod select and based on that we want to enable/disable the three SMTP inputs:</p>
<pre class="brush: jscript; title: ; notranslate">
function toggleSMTP () {
 var dropdownIndex = document.getElementById('mailmethod').selectedIndex;
 var dropdownValue = document.getElementById('mailmethod')[dropdownIndex].value;
 if (dropdownValue == &quot;smtp&quot;) {
 document.settingsform.smtp_user.disabled = false;
 document.settingsform.smtp_password.disabled = false;
 document.settingsform.smtp_server.disabled = false;
 } else {
 document.settingsform.smtp_user.disabled = true;
 document.settingsform.smtp_password.disabled = true;
 document.settingsform.smtp_server.disabled = true;
 }
}
</pre>
<p>So now we end up with an admin menu that looks like:</p>
<p><a href="http://wordpress.3dn.nl/files/2010/02/settings.png"><img class="alignnone size-medium wp-image-1423" src="http://wordpress.3dn.nl/wp-content/uploads/2010/02/settings-300x129.png" alt="" width="300" height="129" /></a></p>
<p>Not looking bad I think!</p>
<h2>Read More</h2>
<p>If you find this article interesting you might want to read some more articles in the WordPress category:</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6394625565386592";
/* 468x60, gemaakt 3-2-10 */
google_ad_slot = "0905523941";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2010/05/12/migrating-wordpress/">New 3DN Techblog</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li class = current ><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>Or in the Coding category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/">Facebook Bookmarks for Chrome?</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li class = current ><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>If you have any questions regarding WordPress, check out our         <a href="http://wordpress.3dn.nl/expertise/wordpress-expertise/" title="Expertise area for Wordpress">Wordpress</a> page or our         <a href="http://wordpress.3dn.nl/expertise/programming/" title="Expertise area for Programming">Programming</a> page. <strong>Note: </strong>The code I&#8217;m writing about is constantly under development. I can&#8217;t write about every little change I make but I try. I&#8217;m learning as I go because this is my first WordPress plugin. If you&#8217;re interested in the latest code you can always look in SVN through my <a title="Dutchie Trac" href="http://trac.dutchie.org/browser/trunk/experts" target="_blank">public Trac server</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Periodic Expertise Events</title>
		<link>http://wordpress.3dn.nl/2010/02/16/periodic-expertise-events/</link>
		<comments>http://wordpress.3dn.nl/2010/02/16/periodic-expertise-events/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 12:37:21 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[activation code]]></category>
		<category><![CDATA[database tables]]></category>
		<category><![CDATA[deactivation]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[expertise]]></category>
		<category><![CDATA[hook function]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[notifications]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1393</guid>
		<description><![CDATA[Earlier I wrote a few articles on creating the expertise plugin and how to add shortcodes to it. Today I want to add scheduled events to the plugin. When somebody posts a question to the expertise page, we could probably write a trigger that checks immediately who's the expert for the section and send a notice in an email. However, I think it's also nice to illustrate making a timed even that will check all expertise pages at once for new messages and send out all notifications right away.]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px;font-weight: normal">Earlier I wrote a few articles on creating the expertise plugin and how to add shortcodes to it. Today I want to add scheduled events to the plugin. When somebody posts a question to the expertise page, we could probably write a trigger that checks immediately who&#8217;s the expert for the section and send a notice in an email. However, I think it&#8217;s also nice to illustrate making a timed even that will check all expertise pages at once for new messages and send out all notifications right away.</span></h1>
<h2>Activation Code</h2>
<p>One thing we have not yet added to the plugin is a decent activation/deactivation section. We should do this first, we&#8217;ll see why later on. In WordPress, a plugin can be activated and deactivated through the administrative plugin menu. These events can be trapped with the <em>register_activation_hook()</em> and <em>register_deactivation_hook() </em>functions. Typically these hooks get used to create extra database tables needed by a plugin, set default values for the plugin etc.</p>
<p>Another thing that can be done in an activation/deactivation section for a plugin is to create / remove a timed event for the plugin:</p>
<pre class="brush: php; title: ; notranslate">
register_activation_hook(__FILE__, 'expert_activate');
add_action ('expert_msgcheck', 'hourly_msgcheck');

register_deactivation_hook(__FILE__, 'expert_deactivate');

function expert_activate () {
 wp_schedule_event(time(), 'hourly', 'expert_msgcheck');
}

function expert_deactivate () {
 wp_clear_scheduled_hook('expert_msgcheck');
}

function hourly_msgcheck () {
}
</pre>
<p>The above code snippet sets this all up; The <em>add_action()</em> call at first seems kind of pointless here as there&#8217;s no point in time where the WordPress core will execute this action. This all changed when an administrator chooses to activate the Expertise plugin. Through the register_activation_hook function <em>expert_activate() </em>will be called. This function in turn calls <em>wp_schedule_event()</em> which schedules the action expert_msgcheck (and thus the function <em>hourly_msgcheck()</em>) to be executed hourly, starting immediately.</p>
<h2>Work with Me</h2>
<p>Let&#8217;s add some code to the <em>hourly_msgcheck()</em> function. We know that we want it to send email eventually, so to check if the mechanism works we&#8217;ll simply let the function send us an email every hour. On my setup I need to use an SMTP mailer as I&#8217;m using Google Apps for email. This requires some settings we might as well initialize on activation of the plugin:</p>
<pre class="brush: php; title: ; notranslate">
function expert_activate () {
 wp_schedule_event(time(), 'hourly', 'expert_msgcheck');
 add_option('expert_settings', array(
 'onpost' =&gt; 1,
 'smtp_user' =&gt; '',
 'smtp_password' =&gt; '',
 'smtp_server' =&gt; 'smtp.gmail.com'));
}

function expert_deactivate () {
 wp_clear_scheduled_hook('expert_msgcheck');
 unregister_setting('experts-settings-group', 'expert_settings');
 delete_option('expert_settings');
}
</pre>
<p>I&#8217;ve changed my earlier approach here from a variable <em>expert_onpost</em> to adding all related options into an array. Just learning as I go, and reading over <a title="Permanent link : Handling Plugins Options in WordPress 2.8 with register_setting()" rel="bookmark" href="http://planetozh.com/blog/2009/05/handling-plugins-options-in-wordpress-28-with-register_setting/" target="_blank">Handling Plugins Options in WordPress 2.8 with register_setting()</a> many times to see if I could figure out what&#8217;s going on there.</p>
<p>Remember we used the new API&#8217;s <em>register_setting()</em> call in a previous article? Well that&#8217;s still compatible with <em>add_option()</em> so it&#8217;s safe to set default values for the options with this. I have included the deactivation code though, just to show that you still need to use <em>delete_option()</em> as <em>unregister_setting()</em> does not take care of this for you.</p>
<p>I also added a parameter validation function:</p>
<pre class="brush: php; title: ; notranslate">
register_setting( 'experts-settings-group', 'expert_settings','expert_onpost_validate');

function expert_onpost_validate ($input) {
 // Our first value is either 0 or 1
 $input['onpost'] = ($input['onpost'] == 1 ? 1 : 0);
 return $input;
}
</pre>
<p>This simply checks whether the variable onpost is actually a boolean. I haven&#8217;t included any validation checks on the other variables yet.</p>
<p>So with the registered variables in place it becomes really very easy to do the actual form building / handling:</p>
<pre class="brush: php; title: ; notranslate">
function expert_settings_page() {
?&gt;
&lt;div&gt;
&lt;h2&gt;Experts&lt;/h2&gt;
&lt;form method=&quot;post&quot; action=&quot;options.php&quot;&gt;
 &lt;?php settings_fields( 'experts-settings-group' ); ?&gt;
 &lt;?php $expert_settings = get_option(&quot;expert_settings&quot;); ?&gt;
 &lt;table&gt;
 &lt;tr valign=&quot;top&quot;&gt;
 &lt;td scope=&quot;row&quot;&gt;On Post in Expertise Section&lt;/td&gt;
 &lt;td&gt;
 &lt;input name=&quot;expert_settings[onpost]&quot; type=&quot;radio&quot; value=&quot;0&quot; &lt;? checked(0,$expert_settings['onpost']); ?&gt; /&gt; Do Nothing &lt;input name=&quot;expert_settings[onpost]&quot; type=&quot;radio&quot; value=&quot;1&quot; &lt;?php checked(1,$expert_settings['onpost']); ?&gt; /&gt; Send Email
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SMTP username&lt;/td&gt;
 &lt;td&gt;
 &lt;input name=&quot;expert_settings[smtp_user]&quot; type=&quot;text&quot; value=&quot;&lt;?php echo $expert_settings['smtp_user']; ?&gt;&quot; /&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SMTP password&lt;/td&gt;
 &lt;td&gt;
 &lt;input name=&quot;expert_settings[smtp_password]&quot; type=&quot;password&quot; value=&quot;&lt;?php echo $expert_settings['smtp_password']; ?&gt;&quot; /&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;SMTP server&lt;/td&gt;
 &lt;td&gt;

&lt;input name=&quot;expert_settings[smtp_server]&quot; type=&quot;text&quot; value=&quot;&lt;?php echo $expert_settings['smtp_server']; ?&gt;&quot; /&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 &lt;/table&gt;

 &lt;p&gt;
 &lt;input type=&quot;submit&quot; value=&quot;&lt;?php _e('Save Changes') ?&gt;&quot; /&gt;
 &lt;/p&gt;

&lt;/form&gt;
&lt;/div&gt;
&lt;?php } ?&gt;
</pre>
<p>Notice that there is no form handling in the plugin itself anymore! That&#8217;s all done by WordPress itself.</p>
<p>So now that we can actually set some required options, let&#8217;s add this <em>send_email()</em> function:</p>
<pre class="brush: php; title: ; notranslate">
function send_email () {
 // PHP Mailer Variables
 if (!class_exists(&quot;phpmailer&quot;)) {
 require_once(ABSPATH.'wp-includes/class-phpmailer.php');
 }
 $expert_settings = get_option(&quot;expert_settings&quot;);
 $mail = new PHPMailer();
 $mail-&gt;Mailer   = &quot;smtp&quot;;
 $mail-&gt;Username = $expert_settings['smtp_user'];
 $mail-&gt;Password = $expert_settings['smtp_password'];
 $mail-&gt;Host     = $expert_settings['smtp_server']
 $mail-&gt;SMTPSecurity = &quot;tls&quot;;
 $mail-&gt;Post     = 465;
 $mail-&gt;SMTPAuth = true;
 $mail-&gt;CharSet  = &quot;utf-8&quot;;
 $mail-&gt;Encoding = &quot;quoted-printable&quot;;
 $mail-&gt;FromName = &quot;3DN Techblog &lt;3dn@3dn.nl&gt;&quot;;
 $mail-&gt;AddReplyTo = &quot;Fred Leeflang &lt;fredl@3dn.nl&gt;&quot;;
 $mail-&gt;Subject  = &quot;Test Email&quot;;
 $mail-&gt;Body     = &quot;Testing gmail functionality&quot;;
 $mail-&gt;AddAddress(&quot;fredl@dutchie.org&quot;);
 if ($mail-&gt;Send()) {
 return 1;
 } else {
 return 0;
 }
}
</pre>
<p>And add a call to this function in the <em>hourly_msgcheck() </em>function just to see if it works:</p>
<pre class="brush: php; title: ; notranslate">
function hourly_msgcheck () {
 send_email();
}
</pre>
<h2>Read More</h2>
<p>If you find this article interesting you might want to read some more articles in the WordPress category:</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6394625565386592";
/* 468x60, gemaakt 3-2-10 */
google_ad_slot = "0905523941";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2010/05/12/migrating-wordpress/">New 3DN Techblog</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>Or in the Coding category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/">Facebook Bookmarks for Chrome?</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>If you have any questions regarding WordPress, check out our         <a href="http://wordpress.3dn.nl/expertise/wordpress-expertise/" title="Expertise area for Wordpress">Wordpress</a> page or our         <a href="http://wordpress.3dn.nl/expertise/programming/" title="Expertise area for Programming">Programming</a> page. <strong>Note: </strong>The code I&#8217;m writing about is constantly under development. I can&#8217;t write about every little change I make but I try. I&#8217;m learning as I go because this is my first WordPress plugin. If you&#8217;re interested in the latest code you can always look in SVN through my <a title="Dutchie Trac" href="http://trac.dutchie.org/browser/trunk/experts" target="_blank">public Trac server</a> or simply <a title="Download Development Code" href="http://trac.dutchie.org/changeset/103/trunk/expertise?old_path=%2F&amp;format=zip" target="_blank">download the latest development copy</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/16/periodic-expertise-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expertise Shortcode</title>
		<link>http://wordpress.3dn.nl/2010/02/15/expertise-shortcode/</link>
		<comments>http://wordpress.3dn.nl/2010/02/15/expertise-shortcode/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 14:25:35 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[attributes]]></category>
		<category><![CDATA[expertise]]></category>
		<category><![CDATA[expertise level]]></category>
		<category><![CDATA[hyperlinks]]></category>
		<category><![CDATA[wordpress plugins]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1377</guid>
		<description><![CDATA[Wordpress has a mechanism for adding 'shortcodes' authors can use in their articles through a plugin. In an earlier article I described how to get started with writing your own Wordpress plugins. In this article I'll show how to add a handy shortcode to the plugin that generates code in the expert pages which allows people to register as experts in a certain area of expertise.]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px;font-weight: normal">WordPress has a mechanism for adding &#8216;shortcodes&#8217; authors can use in their articles through a plugin. In an earlier article I described how to get started with writing your own WordPress plugins. In this article I&#8217;ll show how to add a handy shortcode to the plugin that generates code in the expert pages which allows people to register as experts in a certain area of expertise.</span></h1>
<h2>Functionality</h2>
<p>Every time I create a new expertise page I try to write a brief introduction to the subject. I also want to add a button to this page. When people click on the button they should get a little popup window where they&#8217;re asked to indicate their expertise level. This button is mostly repetitive code which only differs in a few parameters (like &#8216;which expertise page are we on right now&#8217;)</p>
<p>WordPress&#8217; shortcode mechanism is not the best mechanism to get this done but I want to add it this way mostly for educative purposes.</p>
<h2>Adding the Shortcode</h2>
<p>It&#8217;s real simple to add the shortcode to our plugin:</p>
<pre class="brush: php; title: ; notranslate">
add_shortcode('expertise', 'expertise_shortcode');
</pre>
<p>That&#8217;s really all there is to adding the shortcode. Ofcourse we still need some code to implement <em>expert_shortcode()</em>:</p>
<pre class="brush: php; title: ; notranslate">
function expertise_shortcode ($att) {
 $expert = &lt;&lt;&lt;EOM
 &lt;input type=&quot;button&quot; value=&quot;I'm an expert!&quot;&gt;
EOM;
 return $expert;
}
</pre>
<p>After we added this code to our Expertise plugin, inserting <em>[expertise]</em> into our articles/pages should display a very basic button. Why you still see [expertise] in this article even though the plugin is currently active is because I used double [['s in the article.</p>
<p>The above is ofcourse the easiest thing I could think of to make an introduction from.</p>
<h2>Hyperlinks</h2>
<p>Besides adding a button on the expertise page, we could also use this shortcode to link to the expertise page from withing an article. We could ofcourse make an entirely new shortcode for that but it's not neccesary at all; We can add attributes to the shortcode. Let's agree first that we'll give every expertise page it's own 'expertise' custom field which holds the name of the expertise. Custom fields are easy to add in the 'Edit Page' screen. As the value for this 'expertise' field we choose a simple name like 'Linux'.</p>
<p>Now we'll add an attribute <em>link</em> to the expert shortcode so we can use it like <em>[expertise link=Linux]</em>. The expertiselink attribute is optional so if we don&#8217;t add it we&#8217;ll still get the ugly button but if we do add it, the plugin will look in WordPress&#8217; database to find the URL of the page that has custom field &#8216;expertise&#8217; set to &#8216;Linux&#8217; and display code for a hyperlink to that page with all the titles etc.</p>
<pre class="brush: php; title: ; notranslate">
function expertise_shortcode ($atts) {
 global $wpdb;

 // Extract attributes and set defaults if not present.
 extract(shortcode_atts(array(
 'link' =&gt; 0,
 ), $atts));

 if ($link) {
 $expertpost = $wpdb-&gt;get_row(&quot;
 SELECT wposts.*
 FROM $wpdb-&gt;posts wposts, $wpdb-&gt;postmeta wpostmeta
 WHERE wposts.ID = wpostmeta.post_id
 AND wpostmeta.meta_key='expertise'
 AND wpostmeta.meta_value='$link'
 AND wposts.post_status='publish'
 AND wposts.post_type='page'
 &quot;, ARRAY_A);
 $url = get_permalink ($expertpost['ID']);
 $expert = &lt;&lt;&lt;EOM
 &lt;a href=&quot;$url&quot; title=&quot;{$expertpost['post_title']}&quot;&gt;{$expertpost['post_title']}&lt;/a&gt;
EOM;
 } else {
 $expert = &lt;&lt;&lt;EOM
 &lt;input type=&quot;button&quot; value=&quot;I'm an expert!&quot;&gt;
EOM;
 }
 return $expert;
}
</pre>
<p>That code looks a bit more complex already. First of all we&#8217;re using the <em>shortcode_atts()</em> function to check if the attribute <em>link</em> is set in <em>$atts</em>. If it&#8217;s not set, it gets the default value of 0. So whether <em>link</em> is set or not becomes an if-then-else construct that determines whether to show the ugly button or an equally ugly link. When $link is set it will be set to &#8216;Linux&#8217; or something along those lines. We should also do some filtering on this later as it&#8217;s value is put into a SQL query and we don&#8217;t really want to encourage SQL-injection.</p>
<p>The SQL query uses $wpdb, hence the <em>global $wpdb</em> declaration at the top of the function. If everything works well the query should return a row with all the wp_posts columns set. This sample code doesn&#8217;t have error checking yet, which it really should have as the query could also return 0 rows (if the author made a typo, or the expertise page administrator has forgotten to add the expertise custom field).</p>
<p>Finally here&#8217;s an example using [expertise link=Wordpress], please go see our         <a href="http://wordpress.3dn.nl/expertise/wordpress-expertise/" title="Expertise area for Wordpress">Wordpress</a> page!</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6394625565386592";
/* 468x60, gemaakt 3-2-10 */
google_ad_slot = "0905523941";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>Read More</h2>
<p>If you liked this article, maybe you want to read more in the WordPress category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2010/05/12/migrating-wordpress/">New 3DN Techblog</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>Or if you have any questions about this article or WordPress in general you might want to visit our         <a href="http://wordpress.3dn.nl/expertise/wordpress-expertise/" title="Expertise area for Wordpress">Wordpress</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/15/expertise-shortcode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding an Expertise Section to WordPress</title>
		<link>http://wordpress.3dn.nl/2010/02/15/expertise-wordpress/</link>
		<comments>http://wordpress.3dn.nl/2010/02/15/expertise-wordpress/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 08:16:55 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[expertise]]></category>
		<category><![CDATA[expertise section]]></category>
		<category><![CDATA[ipv6]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[section maintainer]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1334</guid>
		<description><![CDATA[I've been thinking about a way to get people to add links to our blog on their site. A friendly way to do this is by adding an 'expertise' section to the site where people can go after they sign up. Here people can ask questions which will be emailed to the section maintainer(s) so they can answer any questions involving their expertise as timely as possible.]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px;font-weight: normal">I&#8217;ve been thinking about a way to get people to add links to our blog on their site. A friendly way to do this is by adding an &#8216;expertise&#8217; section to the site where people can go after they sign up. Here people can ask questions which will be emailed to the section maintainer(s) so they can answer any questions involving their expertise as timely as possible.</span></h1>
<p>This is not a standard WordPress functionality however so I&#8217;m going to write my own WordPress plugin for this.</p>
<h2>Requirements</h2>
<p>I first created an &#8216;Expertise&#8217; page to the blog. This page is freely accessible without having to log in. Then I created some pages with the Expertise page as it&#8217;s parent page. We need to have the &#8216;<a title="Member Access" href="http://www.chrisabernethy.com/wordpress-plugins/member-access/" target="_blank">Member Access</a>&#8216; plugin installed on the blog in order to make the separate expertises member-only. The first three expertise pages I set up were for &#8216;Linux/Unix&#8217; (maintainers: FredLeeflang, TigerP), &#8216;Programming&#8217; (maintainers: FredLeeflang, TigerP) and &#8216;IPv6&#8242; (maintainers: TigerP).</p>
<p>I manually added the &#8216;maintainers&#8217; custom field to each of the separate expertise pages to get started. When the plugin is done this field should be added automatically.</p>
<h2>Getting Started with the Plugin</h2>
<p>Creating a plugin for WordPress is easy. Simply go inside the wp-contents/plugin directory, create a new directory there and some files and you&#8217;re on your merry way. I also took some effort to import the directory into my public subversion server:</p>
<pre class="brush: bash; title: ; notranslate">
svn import experts https://secure.dutchie.org:444/svn/trunk/experts
</pre>
<p>So  you should also be able to check out the source while I&#8217;m developing it by:</p>
<pre class="brush: bash; title: ; notranslate">
cd wp-contents/plugins
svn co https://secure.dutchie.org:444/svn/trunk/experts
</pre>
<p>So all I did to get the plugin to show up with some meaningfull information was to add a file <em>experts.php</em> and a <em>readme.txt</em>. The expert.php has a header in it:</p>
<pre class="brush: php; title: ; notranslate">
/*
Plugin Name:    Experts
Plugin URI:     http://wordpress.3dn.nl/experts/
Description:    This plugin allows you to add experts to several pages on your site. Experts will get notified when a comment on the page is posted, allowing them to quickly respond even though they don't check the site every day.
Author:         Fred Leeflang
Version:        0.1
Author URI:     http://wordpress.3dn.nl/

Setup:
 1) Install the plugin.
 2) Go to the admin menus, and in the &quot;Options&quot; panel, select &quot;Expers&quot;.
 4) Configure the plugin if you need.

*/
</pre>
<p>Which by itself is sufficient to make the plugin show up like this in the admin -&gt; Plugins section:</p>
<p><a href="http://wordpress.3dn.nl/files/2010/02/experts2.png"><img class="size-medium wp-image-1347 alignnone" src="http://wordpress.3dn.nl/wp-content/uploads/2010/02/experts2-300x90.png" alt="" width="300" height="90" /></a></p>
<p style="text-align: left">Obviously this doesn&#8217;t make the plugin do anything yet but it just goes to show that having a header in a file makes the plugin show up with the correct description etc. in the plugin admin screen, ready to be activated!</p>
<h2 style="text-align: left">Got Admin Options?</h2>
<p>First we want to make a basic admin page. This is easily done with:</p>
<pre class="brush: php; title: ; notranslate">
add_action('admin_menu', 'expert_ap');

function expert_ap() {
 //create new submenu under 'Settings'
 add_submenu_page('options-general.php', 'Expertise Settings','Expertise Settings', 'administrator', __FILE__, 'expert_settings_page');

 //call register settings function
 add_action( 'admin_init', 'register_expertsettings' );
}

function register_expertsettings() {
 //register our settings
 register_setting( 'experts-settings-group', 'onpost', 'intval' );
}
</pre>
<p>This is not complete yet but this shows two important mechanism; adding a submenu to an existing (eg. &#8216;Settings&#8217;) menu and registering settings for our plugin.</p>
<p>The <em>add_submenu_page()</em> function links our settings menu under WordPress&#8217; settings (through using <em>options-general.php</em>), gives it a label, sets which <em>capability</em> is required and sets which PHP function must be called when the user selects the menu (<em>expert_settings_page()</em> which we have not added yet).</p>
<p>The <em>add_action() </em>function adds the function <em>register_expertsettings() </em>to the admin_init section of the page. There&#8217;s actually some pretty tricky stuff going on in <em>register_expertsettings()</em>, people who have coded plugins &#8216;the good old way&#8217; will find out what I mean later. Essentially the <em>register_setting() </em>call adds a variable and a variable validation to a pulldown we&#8217;ll design later on. There will be no $_POST processing, HTML filtering etc, WordPress will do all that for us. We just need to make sure that the form POST&#8217;s to options.php and make sure that the variables we want to get from the form get registered with <em>register_setting().</em></p>
<h2>The Form</h2>
<p>Because of letting WordPress handle our variables, we only need to build the form itself in <em>expert_settings_page().</em></p>
<pre class="brush: php; title: ; notranslate">
function expert_settings_page() {
?&gt;
&lt;div&gt;
&lt;h2&gt;Experts&lt;/h2&gt;

&lt;form method=&quot;post&quot; action=&quot;options.php&quot;&gt;
 &lt;?php settings_fields( 'experts-settings-group' ); ?&gt;
 &lt;table&gt;
 &lt;tr valign=&quot;top&quot;&gt;
 &lt;th scope=&quot;row&quot;&gt;On Post in Expertise Section&lt;/th&gt;
 &lt;td&gt;
 &lt;select name='onpost'&gt;
 &lt;option value=&quot;1&quot;&gt;Send Email&lt;/option&gt;
 &lt;option value=&quot;0&quot;&gt;Do Nothing&lt;/option&gt;
 &lt;/select&gt;
 &lt;/td&gt;
 &lt;/tr&gt;

 &lt;/table&gt;

 &lt;p&gt;
 &lt;input type=&quot;submit&quot; value=&quot;&lt;?php _e('Save Changes') ?&gt;&quot; /&gt;
 &lt;/p&gt;

&lt;/form&gt;
&lt;/div&gt;
&lt;?php } ?&gt;
</pre>
<h2>Sample Expertise Area</h2>
<p>I&#8217;ve set up a sample expertise area for <a title="Wordpress Expertise Area" href="http://wordpress.3dn.nl/expertise/wordpress-expertise/" target="_blank">WordPress Expertise</a>. While I&#8217;m developing this plugin further I&#8217;ll post some more followup in there and probably later on I&#8217;ll add one or more articles about the development so stay tuned!</p>
<h2>Read More</h2>
<p>If you enjoyed reading this article you might also like other articles in the Coding category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/">Facebook Bookmarks for Chrome?</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>Or in the WordPress category:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a>   </li><li><a href="http://wordpress.3dn.nl/2010/05/12/migrating-wordpress/">New 3DN Techblog</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a>   </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a>   </li></ul>
<p>Both older and newer articles in the Coding category will be listed here. Should you need (free!) WordPress Expertise, please feel free to check out our <a title="Wordpress Expertise Area" href="http://wordpress.3dn.nl/expertise/wordpress-expertise/" target="_blank">WordPress Expertise area</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/15/expertise-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding Facebook Detail</title>
		<link>http://wordpress.3dn.nl/2010/02/10/facebook-application-contest-detail/</link>
		<comments>http://wordpress.3dn.nl/2010/02/10/facebook-application-contest-detail/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 20:18:31 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[initial setup]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php application]]></category>
		<category><![CDATA[vote]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1312</guid>
		<description><![CDATA[Recently I published a short article on how to create your own Facebook application and a somewhat longer article on implementing some basic code into it. Today I'll tell you how to get some more Facebook gadgets in the application to make it more enticing for people to share it with others.]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px;font-weight: normal">Recently I published a short article on how to create your own Facebook application and a somewhat longer article on implementing some basic code into it. Today I&#8217;ll tell you how to get some more Facebook gadgets in the application to make it more enticing for people to share it with others. I&#8217;ve touched up the HTML and added to the functionality since the most recent article and won&#8217;t be describing much about that process as I assume that most people reading this will be familiar with PHP but are more eager to learn about embedding Facebook functionality in their own PHP application.</span></h1>
<h2>Facebook Hooks</h2>
<p>So we now have a contest that allows people to enter project names, change their suggestions, vote on suggestions or change their votes. All of these events are potentially interesting to people who participate in the contest. Additionally, when people suggest a projectname, they may want to let their friends know they did and invite their friends to vote for their suggested project name. While it&#8217;s very easy to develop an application that does these things on a facebook server itself I&#8217;ve chosen to let my application to run in an <em>iframe.</em> This makes it considerably more difficult to get it to work as we need to enable something called <a title="XFBML" href="http://wiki.developers.facebook.com/index.php/XFBML" target="_blank">XFBML</a> for this.</p>
<p>Setting up XFBML is not very hard to do as there&#8217;s an excellent writeup on the Facebook Wiki called &#8216;<a title="Facebook XFBML Connect" href="Adding Facebook Detail  Recently I published a short article on how to create your own Facebook application and a somewhat longer article on implementing some basic code into it. Today I'll tell you how to get some more Facebook gadgets in the application to make it more enticing for people to share it with others. I've touched up the HTML and added to the functionality since the most recent article and won't be describing much about that process as I assume that most people reading this will be familiar with PHP but are more eager to learn about embedding Facebook functionality in their own PHP application. Facebook Hooks  So we now have a contest that allows people to enter project names, change their suggestions, vote on suggestions or change their votes. All of these events are potentially interesting to people who participate in the contest. Additionally, when people suggest a projectname, they may want to let their friends know they did and invite their friends to vote for their suggested project name. While it's very easy to develop an application that does these things on a facebook server itself I've chosen to let my application to run in an iframe. This makes it considerably more difficult to get it to work as we need to enable something called XFBML for this.  Setting up XFBML is not very hard to do as there's an excellent writeup on the Facebook Wiki called 'Connect/Setting up your Site'" target="_blank">Connect/Setting up your Site</a>&#8216; but I still found it somewhat tricky to do so I&#8217;ll describe the initial setup in some more detail in this article such that it&#8217;s very specific for this application instead of the general setup on the Wiki page. After we&#8217;ve setup Facebook Connect it gets much more comprehensible to do things with it.</p>
<h2>Modify Your Application</h2>
<p><a href="http://wordpress.3dn.nl/files/2010/02/appsettings.png"><img class="alignright size-full wp-image-1315" style="margin-top: 10px;margin-bottom: 10px" src="http://wordpress.3dn.nl/files/2010/02/appsettings.png" alt="" width="285" height="204" /></a>First, the Facebook application I created on Facebook Developer needs to be configured to use XFBML. You need to go into &#8216;Application Settings&#8217; -&gt; &#8216;Edit&#8217; for this. By default you will be shown the &#8216;Basic&#8217; tab but you need to go to the &#8216;Connect&#8217; tab. The most important thing to set there is the &#8216;Connect URL&#8217; which I set to <em>http://wordpress.3dn.nl</em>.</p>
<p>To be quite honest I&#8217;m not sure what it&#8217;s intended for! Something that needs to be set up after this is an <em>xd_receiver.htm</em> file and at first I thought it would need to be in the &#8216;Connect URL&#8217;, however this is not the case as the location of the xd_receiver.htm file gets specified elsewhere later on.</p>
<p>So the xd_receiver.htm file is just a small file that has these contents:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt; &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt; &lt;body&gt; &lt;script src=&quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt; &lt;/body&gt; &lt;/html&gt;
</pre>
<p>There&#8217;s nothing site specific about this file as you can probably tell. The next thing to do is to modify the HTML header. As you may have noticed if you checked out my sources from Subversion (https://secure.dutchie.org:444/svn/trunk/idmcontest) I set up my HTML header for all the files I serve in a single file called <em>head.inc.php</em> so this was fairly easy to do and it&#8217;s all in here:</p>
<pre class="brush: php; title: ; notranslate">
$page = &lt;&lt;&lt;EOM
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot;
 &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:fb=&quot;http://www.facebook.com/2008/fbml&quot;&gt;
</pre>
<p>The next thing that needs to be done is equally simply done in the head.inc.php file, which is including Facebook&#8217;s API library&#8217;s feature loader script:</p>
<pre class="brush: php; title: ; notranslate">
$page .= &quot;&lt;body&gt;&quot;;
 $page .= &lt;&lt;&lt;EOM
 &lt;script src=&quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

EOM;
</pre>
<p>Finally we get to the point where we tell Facebook where out xd_receiver.htm really sits by running a function from the above mentioned API library. This call needs to be made from the bottom of the page and it will render the XFBML code in the body of the document to have actual contents instead of just the markup. As you may have guessed from me using a head.inc.php there&#8217;s also a foot.inc.php from which I will run this function call:</p>
<pre class="brush: php; title: ; notranslate">
$page .= &lt;&lt;&lt;EOM
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;script type=&quot;text/javascript&quot;&gt;
 FB.init(&quot;6082487783cacb849db9e382f1ef92bb&quot;, &quot;/idmcontest/xd_receiver.htm&quot;);
 &lt;/script&gt;
 &lt;/body&gt;
</pre>
<p>So that&#8217;s quite a bit of stuff to do to get this all to work! However, after this it&#8217;s easy to do some really nice things with the quite powerfull XFBML.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6394625565386592";
/* 468x60, gemaakt 3-2-10 */
google_ad_slot = "0905523941";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>Adding an Invite</h2>
<p>So one of the reasons for me to try and rewrite this application as a Facebook application is the potential that people will ask their friends to vote on their suggestion. As long as the method to vote is easy enough, most people will be likely to do so.</p>
<p>This is actually relatively simple to do with the XFBML configured, it almost looks exactly like FBML:</p>
<pre class="brush: php; title: ; notranslate">
if ($addinvitefriends) {
 // Retrieve array of friends who've already authorized the app.
 $fql = 'SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1='.$user_id.') AND is_app_user = 1';
 $_friends = $facebook-&gt;api_client-&gt;fql_query($fql);

 // Extract the user ID's returned in the FQL request into a new array.
 $friends = array();
 if (is_array($_friends) &amp;&amp; count($_friends)) {
   foreach ($_friends as $friend) {
     $friends[] = $friend['uid'];
   }
 }

 // Convert the array of friends into a comma-delimeted string.
 $friends = implode(',', $friends);

 // Prepare the invitation text that all invited users will receive.
 $content =
   &quot;&lt;fb:name uid=\&quot;&quot;.$user_id.&quot;\&quot; firstnameonly=\&quot;true\&quot; shownetwork=\&quot;false\&quot;/&gt; has started using &lt;a href=\&quot;http://apps.facebook.com/idmcontest/\&quot;&gt;3DN IdM Contest&lt;/a&gt; and &quot; . $invitemsg .
   &quot;&lt;fb:req-choice url=\&quot;&quot;.$facebook-&gt;get_add_url().&quot;\&quot; label=\&quot;Put 3DN IdM Contest on your profile\&quot;/&gt;&quot;;
 $page .= &lt;&lt;&lt;EOM
 &lt;fb:serverFbml style=&quot;width: 640px;&quot;&gt;
   &lt;script type=&quot;text/fbml&quot;&gt;
     &lt;fb:fbml&gt;
       &lt;fb:request-form
         action=&quot;invite.php&quot;
         method=&quot;POST&quot;
         type=&quot;XFBML&quot;
         content=&quot;
EOM;
 $page .= htmlentities($content,ENT_COMPAT,'UTF-8') . &quot;\&quot;&gt;\n&quot;;
 $page .= &lt;&lt;&lt;EOM
         &lt;fb:multi-friend-selector
           actiontext=&quot;Invite your friends to vote:&quot;
           exclude_ids=&quot;$friends&quot;&gt;
       &lt;/fb:request-form&gt;
     &lt;/fb:fbml&gt;
   &lt;/script&gt;
 &lt;/fb:serverFbml&gt;

EOM;
}
</pre>
<p>The <em>$addinvitefriends</em> variable is set when a new project name is suggested so that&#8217;s when we want to display the invite box. Line 2 through 15 actually connect to Facebook&#8217;s database using the fql_query() method, so it does a SQL select to find out which friends are already using the application so as to prevent invites to be send repeatedly. Frequently Facebook itself will impose a maximum on the number of friends you can invite but it&#8217;s possible to invite more people the next day.</p>
<h2>Posting Updates on somebody&#8217;s Wall</h2>
<p>In the next and last article in this series I&#8217;ll describe how posting a vote or a new contest leader on somebody&#8217;s wall could entice people to ask more of their friends to vote.</p>
<h2>Read More</h2>
<p>If you enjoyed reading this article you might enjoy reading the following articles in the Coding section as well:</p>
<ul class="lcp_catlist"><li><a href="http://wordpress.3dn.nl/2011/06/16/playing-with-simple-facebook-connect/">Playing with Simple Facebook Connect</a> June 16, 2011  </li><li><a href="http://wordpress.3dn.nl/2011/05/19/facebook-bookmarks-for-chrome/">Facebook Bookmarks for Chrome?</a> May 19, 2011  </li><li><a href="http://wordpress.3dn.nl/2010/02/28/add-ajax-to-expertise-plugin/">Add Ajax to Expertise Plugin</a> February 28, 2010  </li><li><a href="http://wordpress.3dn.nl/2010/02/20/disqus-wordpres/">Checking Comments for Requests</a> February 20, 2010  </li><li><a href="http://wordpress.3dn.nl/2010/02/17/adding-sendmailsmtp-to-experts-plugin/">Adding sendmail/SMTP to experts plugin</a> February 17, 2010  </li></ul>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/10/facebook-application-contest-detail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementing Facebook Contest</title>
		<link>http://wordpress.3dn.nl/2010/02/08/implementing-facebook-contest/</link>
		<comments>http://wordpress.3dn.nl/2010/02/08/implementing-facebook-contest/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 09:16:42 +0000</pubDate>
		<dc:creator>Fred Leeflang</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[programming expertise]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[techblog]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://wordpress.3dn.nl/?p=1216</guid>
		<description><![CDATA[The other day I wrote a very brief article about the basics of writing a Facebook application. Today it's time to implement a contest.]]></description>
			<content:encoded><![CDATA[<h1><span style="font-size: 13px; font-weight: normal;">The other day I wrote a very <a title="Creating a Facebook Application" href="http://wordpress.3dn.nl/2010/02/05/facebook-application/" target="_blank">brief article</a> about the basics of creating a Facebook application. Today it&#8217;s time to implement the contest. I will trust from here that the earlier article got you curious enough and that you have figured out how to set up your own application on Facebook. If you did not manage to get your first sample code to work, feel free to drop me a line at the <a title="Programming Expertise" href="http://wordpress.3dn.nl/expertise/programming/" target="_blank">Programming Expertise page</a> and I&#8217;ll help you out with any detail questions you might have.</span></h1>
<h2>Contest Description</h2>
<p>The idea for the contest is simple enough so we&#8217;ll skip a formal <em>design process</em>. The goal of the contest is:</p>
<ul>
<li>To find a great project name for a <a title="Identity Management Category" href="http://wordpress.3dn.nl/category/idm" target="_blank">global identity management</a> project 3DN is starting.</li>
</ul>
<p>We will do so by:</p>
<ul>
<li>Allowing people to submit their own project name suggestions.</li>
<li>Allow people to vote on the best project name, even if it&#8217;s their own suggestion</li>
</ul>
<p>There are a few conditions:</p>
<ul>
<li>The contest lasts for a month</li>
<li>People cannot change their vote or vote twice</li>
</ul>
<p>The person who suggested the most voted project name will win a small prize.</p>
<h2>Setting Things Up</h2>
<p>For this implementation I copied the same files I set up the first application with to a directory on my webserver. After that I created a completely new application on Facebook developer with it&#8217;s own API key and Secret key. I then changed the $appapikey and $appsecret in the index.php to those new values and imported the whole starting off directory into SVN at https://secure.dutchie.org:444/svn/trunk/idmcontest, you should be able to check out the example code if you like. I then changed the canvas URL to point to my webserver&#8217;s URL (http://wordpress.3dn.nl/idmcontest) and went to http://apps.facebook.com/idmcontest to check if it works. The first thing you get to see is the &#8216;Login to IdM Project Name Contest&#8217; dialog:</p>
<p style="text-align: center;"><img class="aligncenter" src="http://wordpress.3dn.nl/files/2010/02/allow.png" alt="Login to IdM Project Name Contest" width="387" height="171" /></p>
<p style="text-align: left;">Yeah everybody who has used Facebook knows these. It&#8217;s actually worth the while to check out what they mean. It <em>actually</em> means literally what it says there; &#8220;will let it pull your profile information, photos, your friends&#8217; info, and other content that it requires to work&#8221;. So essentially, people who click on &#8216;Allow&#8217; do not just give the application permission to pull up your info but also the info of your friends! Anyway, let&#8217;s assume you&#8217;re familiar with this and click on &#8216;Allow&#8217;. We see the good old initial:</p>
<pre>This is the 3DN IdM Project Name Contest!
Hello, !
Friends:
500011687
501630843</pre>
<p>And we&#8217;re back to an application we&#8217;ll start modifying to make it do what we want it to do.</p>
<h2>Some Formalities</h2>
<p>Let&#8217;s see if it&#8217;s really this easy and add a little form to see if we can get some user feedback into our application.</p>
<pre class="brush: php; title: ; notranslate">
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 echo &quot;&lt;p&gt;You posted: &quot; . $_POST['projectname'] . &quot;&lt;/p&gt;&quot;;
} else {
 print &lt;&lt;&lt;EOM
 &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
 &lt;input type=&quot;text&quot; name=&quot;projectname&quot;&gt;
 &lt;input type=&quot;submit&quot; value=&quot;testme&quot;&gt;
 &lt;/form&gt;
EOM;
}
</pre>
<p>Replacing the functionality of the original index.php with the above snippet actually works like a charm so it should be real easy to:</p>
<ul>
<li>Get some social information about people doing the contest, either through FBML or some client API functions, allowing them to share the contest with their friends more easily</li>
<li>Get their feedback (either their own suggested project name or their vote) and put it in a local database for keeping score.</li>
</ul>
<p>So far so good, this seems real promising. Ofcourse we need a much more decent looking form first, as the above was just a simple testcase, so let&#8217;s create a form that:</p>
<ul>
<li>Shows the existing project names suggestions with radiobuttons , ranked by votecounts (we&#8217;ll store these in a local database, each with a unique ID)</li>
<li>Has an optional text input field for submitting your own proposed project name (if you submit anything in this form field it will be added to the database)</li>
</ul>
<h2>Database Setup</h2>
<p>I decided to use my wordpress database instance for this and simply created two tables in it. I also created a separate database user for the idmcontest that has access only to the idmcontest and the idmcontestvotes tables:</p>
<pre class="brush: sql; title: ; notranslate">
create table idmcontest (
  id int not null auto_increment,
  prjname varchar(128),
  userid int default 0,
  primary key (id)) engine innodb;
create table idmcontestvotes (
  id int not null auto_increment,
  votee int default 0,
  voteid int default 0,
  primary key(id),
  foreign key(voteid) references idmcontest(id)) engine innodb;
grant all privileges on wordpress.idmcontest to idmcontest@localhost identified by 'PASSWORD';
grant all privileges on wordpress.idmcontest to idmcontest@localhost identified by 'PASSWORD';
</pre>
<p>I&#8217;m using the &#8216;innodb&#8217; engine here just to make sure that the referential integrity of the database is guaranteed. MySQL will allow foreign keys but silently ignore them with most other engines.</p>
<p>To do this right, we will obviously need some database connectivity stuff in our PHP script as well. Everybody has their own methods for this and some will use just the standard PHP MySQL functions, but I have some PHP classes of my own that I&#8217;ll be using for this. I won&#8217;t be documenting these here as the methods are quite self-explanatory. All I have to do to initialize a database connection in a safe way is by using:</p>
<pre class="brush: php; title: ; notranslate">
include &quot;autoload.inc.php&quot;;
$db = new DB(DATABASE, CONFDIR);
</pre>
<p>This little snippet basically sets up PHP&#8217;s automatic classloader, initializes some constant values like DATABASE and CONFDIR, gets username/password information from the safe location CONFDIR and makes a connection to the database. I&#8217;ll insert a few test projectnames some of my friends came up with before in the idmcontest table first (I&#8217;ve figured out my own Facebook user ID to be 635153805; so for development purposes only I will set these to my own user ID):</p>
<pre class="brush: sql; title: ; notranslate">
insert into idmcontest values (1, 'enIgMan', 635153805);
insert into idmcontest values (2, 'Genesis', 635153805);
insert into idmcontest values (3, 'Pamoja', 635153805);
insert into idmcontest values (4, 'Persona', 635153805);
insert into idmcontest values (5, 'Merdeka', 635153805);
</pre>
<p>I also populate the idmcontestvotes table to have a vote for one of the project names:</p>
<pre class="brush: sql; title: ; notranslate">
insert into idmcontestvotes values (0, 635153805, 1);
</pre>
<p>So now we&#8217;re all set to create the form using this testdata.</p>
<h2>Building the Form</h2>
<p>Now that we have the form data in place and the database connectivity from our script working, all we need to do is to separate our script into a POST part and a GET part (the form display and the form handling). It&#8217;s convenient to see the scores before and after voting or submitting a project name as well.</p>
<p>First we will have to come up with a clever query that combines the <em>idmcontest</em> table&#8217;s project names with the <em>idmcontestvotes</em> votes. This query does a join on those two tables (it essentially &#8216;links&#8217; these two tables together and filters out the rows we want to see by the <em>WHERE v.voteid=n.id</em> condition) and returns all the fields we want to see:</p>
<pre class="brush: sql; title: ; notranslate">
select COUNT(n.id) AS votes,n.prjname,n.userid,v.id,v.votee,v.voteid FROM idmcontest n, idmcontestvotes v WHERE v.voteid=n.id GROUP BY n.id ORDER BY VOTES DESC;
</pre>
<p>This will return the number of votes in the <em>votes</em> column, which is also the column we sort on, so we&#8217;ll get the most voted on project names first. Let&#8217;s test if this query works for our purposes:</p>
<pre>mysql&gt; select COUNT(n.id) AS votes, n.prjname,n.userid,v.id,v.votee,v.voteid FROM idmcontest n, idmcontestvotes v WHERE v.voteid=n.id GROUP BY n.id ORDER BY VOTES DESC;
+-------+---------+-----------+----+-----------+--------+
| votes | prjname | userid    | id | votee     | voteid |
+-------+---------+-----------+----+-----------+--------+
|     1 | enIgMan | 635153805 |  1 | 635153805 |      1 |
+-------+---------+-----------+----+-----------+--------+
1 row in set (0.00 sec)</pre>
<p>That&#8217;s a promising start, except it displays only 1 row of the project that already has a vote on it; It does not show the project names with zero votes. To fix this we need to modify the query in such a way that it does a so called <em>outer join</em> on the two tables, let&#8217;s see if this one works:</p>
<pre class="brush: sql; title: ; notranslate">
select
  COUNT(n.id) AS votes,
  n.prjname,
  n.userid,
  v.id,
  v.votee,
  v.voteid
from idmcontest n LEFT OUTER JOIN idmcontestvotes v ON v.voteid=n.id
group by n.id order by votes desc;
</pre>
<p>There we have it, but does it return what we want it to return:</p>
<pre>+-------+---------+-----------+------+-----------+--------+
| votes | prjname | userid    | id   | votee     | voteid |
+-------+---------+-----------+------+-----------+--------+
|     1 | Persona | 635153805 | NULL |      NULL |   NULL |
|     1 | enIgMan | 635153805 |    1 | 635153805 |      1 |
|     1 | Pamoja  | 635153805 | NULL |      NULL |   NULL |
|     1 | Merdeka | 635153805 | NULL |      NULL |   NULL |
|     1 | Genesis | 635153805 | NULL |      NULL |   NULL |
+-------+---------+-----------+------+-----------+--------+</pre>
<p>Looks like we need to go back to the drawing board as the votecount is off! It shows there&#8217;s 1 vote on every project name which clearly isn&#8217;t correct. If we add a vote in the database and run the query again:</p>
<pre>+-------+---------+-----------+------+-----------+--------+
| votes | prjname | userid    | id   | votee     | voteid |
+-------+---------+-----------+------+-----------+--------+
|     2 | enIgMan | 635153805 |    1 | 635153805 |      1 |
|     1 | Persona | 635153805 | NULL |      NULL |   NULL |
|     1 | Pamoja  | 635153805 | NULL |      NULL |   NULL |
|     1 | Merdeka | 635153805 | NULL |      NULL |   NULL |
|     1 | Genesis | 635153805 | NULL |      NULL |   NULL |
+-------+---------+-----------+------+-----------+--------+</pre>
<p>We see however that there&#8217;s some method to the madness here; the votecount is actually correct (2 votes for project name &#8216;enIgMan&#8217;) except where <em>id = votee = voteid = NULL.</em> This is easily checked for inside the PHP script so we&#8217;ll use this query to build our pulldown menu with:</p>
<pre class="brush: php; title: ; notranslate">
print &lt;&lt;&lt;EOM
 &lt;form method=&quot;post&quot;&gt;
 &lt;input type=&quot;text&quot; name=&quot;suggestion&quot;&gt;
 &lt;select name=&quot;myvote&quot;&gt;
EOM;
$db-&gt;Q(&quot;select COUNT(n.id) AS votes, n.id AS theid,n.prjname AS prjname,n.userid,v.id,v.votee,v.voteid AS voteid FROM idmcontest n LEFT OUTER JOIN idmcontestvotes v ON v.voteid=n.id GROUP BY n.id ORDER BY VOTES DESC&quot;);
while ($r = $db-&gt;R()) {
 $votes = ($r['id'] &gt; 0)?$r['votes']:0;
 print &quot;&lt;option value=\&quot;{$r['theid']}\&quot;&gt;{$r['prjname']} ($votes vote(s))&lt;/option&gt;\n&quot;;
}

print &lt;&lt;&lt;EOM
 &lt;/select&gt;
 &lt;input type=&quot;submit&quot; value=&quot;Vote!&quot;&gt;
 &lt;/form&gt;
EOM;
</pre>
<p>Good, getting somewhere now. If you paid some real close attention you have noticed I added another selector, &#8216;<em>n.id AS theid</em>&#8216;. We need to select n.id here as the v.id column is NULL is there are no votes and we still need to know the project name&#8217;s ID. Having to add &#8216;AS theid&#8217; is a bit of a quirk of my database class which requires unique names for the columns.</p>
<p>So the form building functionality is in, it just needs some more styling as you can tell from this screenshot:</p>
<p><a href="http://wordpress.3dn.nl/files/2010/02/firstform.png"><img class="size-medium wp-image-1302 alignleft" src="http://wordpress.3dn.nl/wp-content/uploads/2010/02/firstform-300x48.png" alt="" width="300" height="48" /></a></p>
<p>The pulldown shows 0 votes for the other project names but unfortunately I can&#8217;t show the pulldown here.</p>
<h2>Handling the Form</h2>
<p>Now that we&#8217;ve built the form we still need to take some action when somebody clicks on the &#8216;Vote!&#8217; button ofcourse. This is also easy enough to do by putting an if-then-else construct around the form building part using the <em>$_SERVER['REQUEST_METHOD']</em> variable:</p>
<pre class="brush: php; title: ; notranslate">
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
  /* Build Form */
} else {
  /* Handle Form */
}
</pre>
<p>So in the handle-form code we need to check a few things:</p>
<ul>
<li>Is the user POST&#8217;ing logged in on Facebook</li>
<li>Is the post variable &#8216;suggestion&#8217; set; If so, we will ignore any selected vote and assume the user wants to suggest his own projectname (and maybe vote for it the second time he gets the form)</li>
<li>If the variable &#8216;suggestion&#8217; is empty, we will look at the voter&#8217;s user ID first and remove any vote he may have already done. After this we will insert his vote into the table, ths assuring every user has voted only one project name.</li>
</ul>
<p>That&#8217;s easy enough to do! We will need the <code>$user_id</code> <code>= </code><code>$facebook</code><code>-&gt;require_login();</code> of the <a title="Creating a Facebook Application" href="http://wordpress.3dn.nl/2010/02/05/facebook-application/" target="_blank">previous article</a> here and that&#8217;s really all it takes and in it&#8217;s simplest form without any real checking for now it looks like this:</p>
<pre class="brush: php; title: ; notranslate">
if ($_POST['suggestion'] != &quot;&quot;) {
 $db-&gt;Q(&quot;INSERT INTO idmcontest VALUES (0, '{$_POST['suggestion']}',$user_id)&quot;);
 print &quot;You submitted a name! Thanks!&quot;;
 } else {
 $db-&gt;Q(&quot;DELETE FROM idmcontestvotes WHERE votee = $user_id&quot;);
 $db-&gt;Q(&quot;INSERT INTO idmcontestvotes VALUES (0,$user_id,{$_POST['myvote']})&quot;);
 print &quot;Your vote has been accepted! Thanks!&quot;;
 }
</pre>
<p>So I&#8217;ll add some more filtering before putting this thing &#8216;live&#8217; as there are some naughty things that evil people could still do like putting arbitrary SQL into the project name field. I obviously don&#8217;t want anybody to forge my contest results or even completely mess up my wordpress database (which is not possible here as I created a separate database user with privileges only on the two tables above). I&#8217;ll also add some more styling but there you have it, it&#8217;s really mostly just PHP code and only a tiny bit of Facebook specific stuff. In a next article I&#8217;ll show some more Facebook specific stuff like giving people the ability to tell their friends about this contest.</p>
<h2><span style="font-size: 13px; font-weight: normal;">If you want to see it in action, try going to the <a title="IdM Contest" href="http://apps.facebook.com/idmcontest">Facebook application</a>. If you try it out shortly after the publishing date of this article it may still look like above but I&#8217;ll be making edits for later articles as well.</span></h2>
]]></content:encoded>
			<wfw:commentRss>http://wordpress.3dn.nl/2010/02/08/implementing-facebook-contest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

