<?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>php&#124;architect - The site for PHP professionals &#187; bing</title>
	<atom:link href="http://www.phparch.com/tag/bing/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phparch.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Fri, 10 Feb 2012 15:11:29 +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>Bing Powered 404 for non-WordPress websites</title>
		<link>http://www.phparch.com/2010/06/bing-powered-404-for-non-wordpress-websites/</link>
		<comments>http://www.phparch.com/2010/06/bing-powered-404-for-non-wordpress-websites/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 11:00:47 +0000</pubDate>
		<dc:creator>Cal Evans</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[bing]]></category>
		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://www.phparch.com/?p=5336</guid>
		<description><![CDATA[Ok, after my last post on using the Bing Search Wrapper for handing 404 errors in WordPress I had several people tell me that while they liked the idea, they didn&#8217;t want to install WordPress just so they can have intelligent 404 errors. Several other people pinged me and suggested a way that you could [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, after my last post on <a href="http://blog.calevans.com/2010/06/01/bing-search-api-wrapper-for-php/">using the Bing Search Wrapper for handing 404 errors in WordPress</a> I had several people tell me that while they liked the idea, they didn&#8217;t want to install WordPress just so they can have intelligent 404 errors. Several other people pinged me and suggested a way that you could use the Bing Search API to handle 404&#8242;s without WordPress. As a public service, I am going to try and bridge the gap between these two groups. Going on leads provided by friends, I have hammered out a solution that works with Apache and PHP.</p>
<h2>Step 1: Write a 404 Handler page.</h2>
<p>This technique is predicated on the fact that Apache lets you define your own pages for handling every error. In this example We will define a script, name it 404.php and place it in the web root.</p>
<p>You will notice that this is a very plain, black and white page. Feel free to decorate it to taste. The one on my personal site actually designed using my WordPress template so it matches my blog. (you can see it by clicking here, <a href="http://calevans.com/bing-rocks">http://calevans.com/bing-rocks</a>)</p>
<p>If you want to skip this step, here is a simple one, just copy and paste it. Make sure you put in your domain name and your <a href="http://www.bing.com/developers/createapp.aspx">Bing App Id</a></p>
<pre lang="php">
&lt;?PHP
function __autoload($className)
{
   $fileName = strtr($className,'_',DIRECTORY_SEPARATOR).".php";
   include $fileName;
   return;
}

   $o = new Msft_Bing_Search('BING APP ID GOES HERE');
   $o-&gt;setQuery('')
     -&gt;setWebCount(10)
     -&gt;setSource('web')
     -&gt;setSite('YOUR DOMAIN GOES HERE')
     ;

   $raw    = $o-&gt;search();
   $result = json_decode($raw);

?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"&gt;

&lt;head profile="http://gmpg.org/xfn/11"&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;

&lt;title&gt;calevans dot com 404 page&lt;/title&gt;

&lt;/head&gt;
&lt;body&gt;
&lt;h3&gt; I'm sorry, we couldn't find what you are looking for.&lt;/h3&gt;
&lt;p&gt;However, here are the top 10 links from &lt;a href="http://bing.com"&gt;Bing&lt;/a&gt; for this site. I hope one of them is what you are looking for.&lt;/p&gt;
&lt;ol&gt;
&lt;?PHP
       foreach($result-&gt;SearchResponse-&gt;Web-&gt;Results as $value) {
           printf('&lt;li&gt;&lt;a href="%s"&gt;%s&lt;/a&gt;&lt;/li&gt;',$value-&gt;Url,$value-&gt;Title);
       }
?&gt;
&lt;/ol&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h2>Step 2: Configure Apache</h2>
<p>If you are not familiar with Apache config files, this one is going to be a bit tricky. The only generic advice I can give you is, back everything up, they are only text files. Unless you delete things without backups, it&#8217;s really hard to do permanent damage. Oh and if you do manage to do permanent damage, I am not responsible.</p>
<p>My Apache is configured with <a href="http://httpd.apache.org/docs/2.1/vhosts/name-based.html">name based virtual hosts</a>. As such I have a separate Apache conf file for each domain and all the settings go in those files. As such, inside my <code> &lt;VirtualHost</code> tag I place the line:</p>
<pre lang="conf">
ErrorDocument 404 /404.php
</pre>
<p>Now restart Apache and you too can type in:</p>
<p>http://example.com/bing-rocks</p>
<p>and get something that looks like this:<br />
<a href="http://beta.phparch.com/wp-content/uploads/2010/05/404-1.png"><img src="http://www.phparch.com/files/2010/05/404-1-300x220.png" alt="" title="404-1" width="300" height="220" class="alignnone size-medium wp-image-5347" /></a></p>
<p>Or, if you are lucky enough to have a designer like <a href="http://kathyevans.biz">the lovely and talented Kathy</a> Then you may have something that looks like this:<br />
<a href="http://beta.phparch.com/wp-content/uploads/2010/05/404-2-e1273524502241.png"><img src="http://www.phparch.com/files/2010/05/404-2-e1273524502241-300x239.png" alt="" title="404-2" width="300" height="239" class="alignnone size-medium wp-image-5348" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phparch.com/2010/06/bing-powered-404-for-non-wordpress-websites/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress 404 Plugin built on Bing Wrapper</title>
		<link>http://www.phparch.com/2010/06/wordpress-404-plugin-built-on-bing-wrapper/</link>
		<comments>http://www.phparch.com/2010/06/wordpress-404-plugin-built-on-bing-wrapper/#comments</comments>
		<pubDate>Fri, 04 Jun 2010 14:00:55 +0000</pubDate>
		<dc:creator>Cal Evans</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[bing]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.phparch.com/?p=5322</guid>
		<description><![CDATA[One of the things I've always hated about WordPress is the stock 404 error message. Out of the box, WordPress just tells users "I'm sorry, I can't find what you are looking for." Granted it is better than the stock Apache 404 page but it isn't much more helpful. This post talks about a new WordPress plugin that utilizes the Bing Search Wrapper to display a more helpful 404 page.]]></description>
			<content:encoded><![CDATA[<p><strong>Update: We have added a link to a short youtube video on how to install the plugin. It explains each the options as well.<br />
</strong></p>
<p>Over at my personal blog, I recently posted about the new<a href="http://blog.calevans.com/2010/06/01/bing-search-api-wrapper-for-php/"> Bing Search API  wrapper</a> I wrote for Microsoft. In the post, I said that I would talk about some of the uses of the wrapper. This post is the the first of two I have planned.</p>
<p><a href="http://phparch.com">php|architect</a>, <a href="http://blog.tabini.ca/">The Accidental Businessman</a> and <a href="http://blog.calevans.com">Postcards From My Life</a> are all three WordPress blogs. Personally, I have three others as well because it&#8217;s just so easy to setup and get running that I really have to have some serious requirements that absolutely cannot be met within WordPress to consider another option.</p>
<p>These days, being more of a market-teer than a code monkey, I worry about thinks like my site being &#8220;sticky&#8221;, people being able to find my site, and generally the things that programmers laugh at but are important to the rest of us that build out sites.</p>
<p>One of the things I&#8217;ve always hated about WordPress is the stock 404 error message. Out of the box, WordPress just tells users &#8220;I&#8217;m sorry, I can&#8217;t find what you are looking for.&#8221; Granted it is better than the stock Apache 404 page but it isn&#8217;t much more helpful. Having just finished working on the Bing Search Wrapper for PHP, the best use case I could think of for the wrapper was to solve this particular problem. This is how I helped Microsoft&#8217;s Interoperability team to put together the Bing 404 Plugin for WordPress.</p>
<h2>Quick Start</h2>
<p>Ok, if you are in a hurry you can either watch this video or follow the 4 steps below.</p>
<p><object width="580" height="360"><param name="movie" value="http://www.youtube.com/v/8VVSnaF98Fo&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;color1=0x234900&#038;color2=0x4e9e00&#038;border=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/8VVSnaF98Fo&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;color1=0x234900&#038;color2=0x4e9e00&#038;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="580" height="360"></embed></object></p>
<ol>
<li>Install the <a href="http://wordpress.org/extend/plugins/bing-404/">Bing 404 Plugin</a> from the wordpres.org repository</li>
<li>Get a <a href="http://www.bing.com/developers/createapp.aspx">Bing App ID</a></li>
<li>Configure the plugin and give it your App Id</li>
<li>Test it out by trying to go to an invalid URL on your blog.</li>
</ol>
<p>All told, it should take you about 5 minutes, 2 if yo have the App Id already.</p>
<h2>All the gory details</h2>
<p>The goal of the plugin was to give useful 404 page. However, the definition of useful is different for different people. To be specific, I wanted to see if we could find what the user was looking for on the site and if not, then at the very least I wanted to suggest a few of the most popular articles on the blog. To further narrow the search, I wanted to be able to plug in &#8220;standard&#8221; search terms for which to search.</p>
<h2>Abbreviated Workflow</h2>
<p><strong>Get the URL, strip off the domain. Everything else is considered the query.</strong><br />
If the url that led them to the 404 page is <code>http://phparch.com/bing-rocks/</code> then I want to strip off <code>http://phparch.com/</code> and be left with <code>/bing-rocks/</code>. Granted it is not very useful by itself but it gives us a hint at what the user was looking for.</p>
<p><strong>Get the standard search terms.</strong><br />
Just in case the query string doesn&#8217;t return enough results (or any at all) we have the option of specifying some generic terms. In the case of <code>phparch.com</code>, we specify php, because that is what most people will be looking for here.</p>
<p><strong>Run both queries, combine the arrays and pop off the top x results</strong><br />
In the setup, you can specify how many entries you want displayed on your page. If the query using the user&#8217;s original query string returns enough results, we use only those. However, if that doesn&#8217;t return enough to flesh out the entire x, the results of the second query to Bing, using the specified default keywords, will round out the list. Both queries honor the localized domain option so if you put in your domain name there, it will limit the results of both queries to results from your domain.</p>
<h2>Code</h2>
<p>Counting comments and all, the entire plugin (sans the API library) is 500+ lines. I am not going to paste them all in here but I will show the heart of the plugin and a couple of the bits of magic that allow it to work.</p>
<pre lang="php">/**
 * perform the actual search
 *
 * This is the heart of the plugin. This function is called from the 404.php
 * template. No parameters are necessary. It returns the properly formatted
 * HTML to either display a list of potential links or an error message.
 *
 * @return string html to output.
 */
function bing404_search_bing() {
    include 'Msft/Exception.php';
    include 'Msft/Bing/Exception.php';
    include 'Msft/Bing/Search/Exception.php';
    include 'Msft/Bing/Search.php';

    /*
     * Create the Bing Search object.
     */
    $search = new Msft_Bing_Search( get_option( 'b4_apiKey' ) );
    $search-&gt;setWebCount( get_option( 'b4_count' ) );
    $search-&gt;setSource( 'Web' );
    $search-&gt;setAdult( get_option( 'b4_adult' ) );

    /*
     * If requested, make this a site specific search
     */
    if ( $localsite = get_option( 'b4_site' ) ) {
        $search-&gt;setSite( $localsite );
    }

    /*
     * If set, set the local market
     */
    $localMarket = get_option( 'b4_market' );
    if ( !empty( $localMarket ) &amp;&amp; $localMarket != 'NONE' ) {
        $search-&gt;setMarket( $localMarket );
    }

    /*
     * Build the query to execute
     */
    $queryTerms = str_replace( '/', ' ', html_entity_decode( urldecode( $_SERVER['REQUEST_URI'] ) ) );
    $localQuery = get_option( 'b4_query' );

    /*
     * Try to pull the site-wide from cache. Otherwise, pull from bing
     */
    $cacheKey = md5( $localQuery );
    $raw      = wp_cache_get( $cacheKey );

    if ( $raw === false ) {
        $search-&gt;setQuery( $localQuery );
        $raw = $search-&gt;search();
        wp_cache_set( $cacheKey, $raw,'',86400 );
    }

    $siteResults = json_decode( $raw );

    /*
     * Try to pull the regular query from cache. Otherwise, pull from bing
     */
    $localQuery = trim( $queryTerms );
    $cacheKey   = md5( $localQuery );
    $raw        = wp_cache_get( $cacheKey );

    if ( $raw === false ) {
        $search-&gt;setQuery( $localQuery );
        $raw = $search-&gt;search();
        wp_cache_set( $cacheKey, $raw,'',86400 );
    }
    $results = json_decode( $raw );

    /*
     * Now merge the resultsets
     */
    $finalResults = bing404_merge_results( $results, $siteResults );

    /*
     * Finally, prepare the output
     */
    $output = '
<ol class="bing404">';
    foreach ( $finalResults as $value ) {
        $output .= sprintf( '
<li><a href="%s">%s</a></li>

', $value-&gt;Url, $value-&gt;Title );
    }

    $output .= '</ol>

';
    $bing404_dirname = WP_PLUGIN_URL . '/' . ( basename( dirname( __FILE__ ) ) );

    switch ( get_option( 'b4_poweredByBing' ) ) {
        case 'Banner':
            $output .= '
<div class="bing404_powerByBing"><a href="http://bing.com" target="_blank"><img src="'. $bing404_dirname . '/bing_powered.gif" alt="" /></a></div>

';
            break;
        case 'Text':
            $output .= '
<div class="bing404_powerByBing">Powered by <a href="http://bing.com" target="_blank">Bing</a></div>

';
            break;
        case 'Off':
            break;
    }
    return $output;</pre>
<p>A few of the code highlights:</p>
<ul>
<li>Line 19 &#8211; Create the Bing search object.</li>
<li>Line 27 &#8211; If you have specified a local domain, localize the search to only that domain.</li>
<li>Line 42 &#8211; Get the query terms to search for. Note, 2 queries are actually made.</li>
<li>Line 48 &#8211; Execute the query pulling back the most popular items for the blog optionally using your specified query term.</li>
<li>Line 59 &#8211; Execute the query trying to find the page for which the user was actually looking</li>
</ul>
<p>As I hope you can see, using the Bing Search wrapper makes this code very simple. The bulk of this method is simply parameter checking and setting defaults.</p>
<h2>A bit of WordPress magic</h2>
<p>Intercepting the 404 page on WordPress took a bit of digging. It turns out however to be simple, once you find the right hook.</p>
<pre lang="php">/**
 * Register the 404 hook.
 *
 * Only register the 404 hook if the user wants to use our included template.
 */
if ( get_option( 'b4_useIncludedTemplate' ) ) {
    add_action( '404_template','bing404_use_included_template_hook' );
}

/**
 * include the standard template.
 *
 * If the user has opted to use the included template then include it for use.
 */
function bing404_use_included_template_hook() {
    include dirname( __FILE__ ). '/default-404.php';
    exit;
}</pre>
<p>The plugin works in one of two ways.</p>
<ol>
<li>The plugin includes a 404 page. If you check the option, this will be the one that is used. This should work in 75%-80% of the cases and requires no code changes to get the plugin working.</li>
<li>If you want to roll your own, include this line in your template&#8217;s 404.php.
<pre lang="php">&lt;?php if(function_exists('bing404_search_bing')) { echo bing404_search_bing(); } ?&gt;</pre>
</li>
</ol>
<p>Either way works the same, a call is made to <code>bing404_search_bing()</code> and the results are displayed.</p>
<h2>Conclusion</h2>
<p>That is all there is to it. There are several other options for setting region localization, safe search and other options. All in all though, the Bing Search Wrapper allowed me to put this plugin together in a couple of hours. It took care of the details of the search and allowed me to worry about navigating the WordPress API minefield.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phparch.com/2010/06/wordpress-404-plugin-built-on-bing-wrapper/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>php&#124;architect Podcast: 2009 in Revue</title>
		<link>http://www.phparch.com/2010/01/php-architect-podcast-2009-in-review/</link>
		<comments>http://www.phparch.com/2010/01/php-architect-podcast-2009-in-review/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 16:00:13 +0000</pubDate>
		<dc:creator>Cal Evans</dc:creator>
				<category><![CDATA[podcast]]></category>
		<category><![CDATA[bing]]></category>
		<category><![CDATA[CodeWorks]]></category>
		<category><![CDATA[confoo]]></category>
		<category><![CDATA[Dutch PHP Conference]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php quebec]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[ZendCon php|tek]]></category>

		<guid isPermaLink="false">http://phparch.com/?p=3132</guid>
		<description><![CDATA[php&#124;architect podcast Episode 2010-001. Sit with us as we look back at 2009 and what it meant to PHP.]]></description>
			<content:encoded><![CDATA[<p>Happy 2010! We&#8217;re back with another episode of the php|architect Podcast.</p>
<p>In this episode, which shall henceforth be referred to as the one where Marco realizes that hosting a podcast with bronchitis may not be the best of ideas, our special guest is Zend&#8217;s Matthew Weier O&#8217;Phinney, head of Zend Framework.</p>
<p>Here are some of the topics we cover:</p>
<ul>
<li>PHP Quebec (now <a href="http://www.confoo.ca/en">confoo</a>)</li>
<li><a href="http://tek.phparch.com">php|tek 2009</a></li>
<li><a href="http://phpconference.nl/">DPC</a></li>
<li><a href="http://cw.mtacon.com/">CodeWorks</a></li>
<li><a href="http://zendcon.com/">ZendCon</a></li>
<li><a href="http://www.flickr.com/search/?q=zendcon%20bing%20party&amp;w=all">Flickr feed for the Bing Party</a></li>
<li><a href="http://enterpriselamp.org/camp/">Big Lamp Camp</a></li>
<li><a href="http://www.web2project.net/">Web2Project</a></li>
<li><a href="http://www.phpdeveloper.org/news/13629">MSWDS Wrap-ups</a></li>
<li><a href="http://tek.phparch.com/2009/12/you-can-hack-if-you-wanna/">HackTrack</a></li>
</ul>
<h2>Subscribe to the Notes</h2>
<p>If you have stumbled upon this page and aren&#8217;t a regular listner, <a href="http://blueparabola.us1.list-manage.com/subscribe?u=2d8ce686a29a06277ff9b9c15&amp;id=45db2e1464&amp;utm_source=php%7Carchitect+Postcast+Show+Notes&amp;utm_campaign=3c21f92e0f-Episode_ow001_Show_Notes1_19_2010&amp;utm_medium=email">subscribe to the php|architect podcast Show Notes mailing list</a>. Each week, when we release an episode, we&#8217;ll send you an email with all the links and notes from that show.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phparch.com/2010/01/php-architect-podcast-2009-in-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://mtadata.s3.amazonaws.com/podcasts/20100106.mp3" length="52563982" type="audio/mpeg" />
		</item>
	</channel>
</rss>

