<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Cash Costello</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://cashcostello.com/blog/atom.xml" />
    <id>tag:cashcostello.com,2009-09-25:/blog//1</id>
    <updated>2010-08-07T19:11:22Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.31-en</generator>

<entry>
    <title>Building a Web Services API with Elgg</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2010/08/building-a-web-services-api-with-elgg.html" />
    <id>tag:cashcostello.com,2010:/blog//1.11</id>

    <published>2010-08-07T18:53:46Z</published>
    <updated>2010-08-07T19:11:22Z</updated>

    <summary>Elgg provides an API for building custom web services. You expose functionality through the web services API by building a plugin and then either publish your API for other developers to build clients or provide your own. Here is a...</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="elgg" label="elgg" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="webservices" label="web services" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>Elgg provides an API for building custom web services. You expose functionality through the web services API by building a plugin and then either publish your API for other developers to build clients or provide your own. Here is a simple example of exposing a method so that a client app can post a status update to the wire in Elgg:</p>

<p><strong>1. Write your function that creates the wire post</strong></p>

<pre>
function rest_wire_post($username, $text) {
    $user = get_user_by_username($username);
    if (!$user) {
        throw new InvalidParameterException('Bad username');
    }

    $obj = new ElggObject();
    $obj->subtype = 'thewire';
    $obj->owner_guid = $user->guid;
    $obj->access_id = ACCESS_PUBLIC;
    $obj->method = 'api';
    $obj->description = elgg_substr(strip_tags($text), 0, 140);

    $guid = $obj->save();

    add_to_river('river/object/thewire/create',
                 'create',
                 $user->guid,
                 $obj->guid
                );

    return 'success';
}
</pre>

<p><br />
<strong>2. Expose it</strong></p>

<pre>
expose_function('wire.post',
                'rest_wire_post',
                array( 'username' => array ('type' => 'string'),
                       'text' => array ('type' => 'string'),
                     ),
                'Post a status update to the wire',
                'GET',
                false,
                false);
</pre>

<p><br />
<strong>3. Use it</strong></p>

<p>Type this into your browser's address bar making the obvious replacements for your site:</p>

<p>http://mysite.com/services/api/rest/xml/?method=wire.post&amp;username=cash&amp;text=hello</p>

<p>Now, in a real application you would make this a POST request rather than a GET and protect it with user and API authentication. For more information on that see the <a href = "http://docs.elgg.org/wiki/Web_Services">Elgg web services wiki page</a>.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Session security and Chrome Frame</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2010/04/session-security-and-googles-chrome-frame.html" />
    <id>tag:cashcostello.com,2010:/blog//1.9</id>

    <published>2010-04-29T00:27:27Z</published>
    <updated>2010-04-29T00:44:10Z</updated>

    <summary>I&apos;ve run into the nasty problem that Chrome Frame causes to session handling code that uses the user agent in its security. There are applications that use the user agent string in a hash that sets the signature of a...</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="chromeframe" label="chromeframe" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="google" label="google" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="security" label="security" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>I've run into the nasty problem that Chrome Frame causes to session handling code that uses the user agent in its security. There are applications that use the user agent string in a hash that sets the signature of a session. Each time the session is loaded using that key, the signature is checked. This catches some session hijacking attempts. Let's assume that an attacker is able to obtain a user's session key and then uses it. There is some probability that the user agent will be different and the attack will fail. It's a layers of security approach - it doesn't prevent the attack but makes it harder. Of course, if the attacker sniffed the session key, the attacker also has the user agent. If the attacker obtain the session key from the user's computer, the user agent was available there also. So you can see that it is not much of a security feature.</p>

<p>There are web applications that use this and this is where Google's Chrome Frame browser addon for IE comes into play. This extension changes the user agent based on the type of data requested and the method of the request. These user agent changes result in the signature check to fail and the session is regenerated (and the user is logged out). Depending on the site and content, this can appear to be almost random or it can be very consistent (log in, log out, log in, log out...).</p>

<p>The solutions are to either drop this security feature or filter the chromeframe string out of the user agent.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Piwik and Elgg</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2010/04/piwik-and-elgg.html" />
    <id>tag:cashcostello.com,2010:/blog//1.8</id>

    <published>2010-04-24T21:03:03Z</published>
    <updated>2010-04-24T22:04:38Z</updated>

    <summary>While Google Analytics may be the most popular analytics service, there are times when you want to use your own hosted solution (intranet, control over data). Piwik is a great open source package that provides an impressive set of tools...</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="analytics" label="analytics" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="elgg" label="elgg" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="piwik" label="piwik" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>While Google Analytics may be the most popular analytics service, there are times when you want to use your own hosted solution (intranet, control over data). <a href="http://piwik.org/">Piwik</a> is a great open source package that provides an impressive set of tools and a very nice look and feel. Using it with Elgg is extremely easy. You can write a plugin to do this in a few minutes as Elgg provides an analytics view in the footer that can be extended.</p>

<p>This is all it takes:<br />
<ol><br />
	<li>Install Piwik</li><br />
	<li>Create your Elgg <a href="http://docs.elgg.org/wiki/Plugin_skeleton">plugin skeleton</a></li><br />
	<li>Create a view to hold your Piwik javascript code - in this case <em>piwik/analytics</em></li><br />
	<li>Register a callback for the init:system event</li><br />
	<li>In the callback extend the <em>footer/analytics</em> view</li><br />
	<li>Install and activate the plugin</li><br />
</ol></p>

<p>The structure of this very simple plugin looks like this:</p>

<p><img alt="Plugin Structure" src="http://cashcostello.com/blog/images/piwik_structure.png" width="206" height="131" class="mt-image-none" style="" /></p>

<p>You can download it <a href="http://cashcostello.com/files/piwik.zip">here</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Piwik and Reverse Proxy</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2010/02/piwik-and-reverse-proxy.html" />
    <id>tag:cashcostello.com,2010:/blog//1.10</id>

    <published>2010-02-18T01:51:09Z</published>
    <updated>2010-04-29T13:17:36Z</updated>

    <summary>Piwik generates its URLs used in links and forms based on data in $_SERVER[]. If you are using a reverse proxy in front of your web server, the incoming request URLS are for the internal server. This results in the...</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="php" label="php" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="piwik" label="piwik" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="reverseproxy" label="reverse proxy" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>Piwik generates its URLs used in links and forms based on data in $_SERVER[]. If you are using a reverse proxy in front of your web server, the incoming request URLS are for the internal server. This results in the people from the outside getting 404 errors after the getting the initial landing page.</p>

<p>To work around this, I was able to use Piwik's boostrap.php file. This is loaded first for any Piwik page. I added some code in there to rewrite PHP's $_SERVER[] parameters to match the original request to the proxy. The variables I had to set were<br />
<ul><br />
	<li>$_SERVER['HTTP_HOST']</li><br />
	<li>$_SERVER['PHP_SELF']</li><br />
	<li>$_SERVER['SCRIPT_NAME']</li><br />
	<li>$_SERVER['REQUEST_URI']</li><br />
</ul></p>]]>
        
    </content>
</entry>

<entry>
    <title>Elgg Unit Tests</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2009/12/elgg-unit-tests.html" />
    <id>tag:cashcostello.com,2009:/blog//1.7</id>

    <published>2009-12-07T00:21:48Z</published>
    <updated>2009-12-07T00:25:34Z</updated>

    <summary>A new component in Elgg 1.7 will be a unit test framework (SimpleTest). I&apos;ve written a skeleton example of how plugin authors can use the framework. It can be downloaded here....</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="elgg" label="elgg" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="unit tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>A new component in Elgg 1.7 will be a unit test framework (<a href="http://simpletest.org/index.html">SimpleTest</a>). I've written a skeleton example of how plugin authors can use the framework. It can be downloaded <a href="http://cashcostello.com/files/elgg_unit_tests.zip">here</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Debugging Elgg SQL Queries</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2009/11/debugging-elgg-sql-queries.html" />
    <id>tag:cashcostello.com,2009:/blog//1.6</id>

    <published>2009-11-04T12:43:46Z</published>
    <updated>2010-04-24T20:49:30Z</updated>

    <summary>A little trick that I&apos;ve learned for debugging a call to the Elgg API that involves a database call is to wrap it with $CONFIG-&gt;debug. For example: $CONFIG-&gt;debug = true; $images = get_entities(&apos;object&apos;, &apos;blog&apos;, $guid, &apos;&apos;, 25); $CONFIG-&gt;debug = false;...</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="elgg" label="elgg" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>A little trick that I've learned for debugging a call to the <a href="http://elgg.org/">Elgg</a> API that involves a database call is to wrap it with $CONFIG->debug. For example:</p>

<p><code><br />
$CONFIG->debug = true;<br />
$images = get_entities('object', 'blog', $guid, '', 25);<br />
$CONFIG->debug = false;<br />
</code></p>

<p><br />
This will write the query to the error log giving you a chance to see what you are doing wrong (or if there is a bug in the Elgg framework). Make sure that the global $CONFIG is available within the context. This works fine with versions up to 1.6. Unknown how this will work on 1.7 and beyond.</p>

<p><br />
<strong>Update:</strong> For Elgg 1.7 and above you need to do this:<br />
<code><br />
$CONFIG->debug = 'NOTICE';<br />
$images = get_entities('object', 'blog', $guid, '', 25);<br />
unset($CONFIG->debug);<br />
</code></p>

<p>This assumes that you have debugging turned off. If you have it set to something else (like 'ERROR'), you should set it back to that setting.</p>]]>
        
    </content>
</entry>

<entry>
    <title>When Google Goes Down</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2009/10/when-google-goes-down.html" />
    <id>tag:cashcostello.com,2009:/blog//1.5</id>

    <published>2009-10-03T14:58:20Z</published>
    <updated>2009-10-03T15:00:15Z</updated>

    <summary>This morning Google Analytics wasn&apos;t responding. So many sites use it that it basically slowed down the entire Internet....</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="google" label="google" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>This morning Google Analytics wasn't responding. So many sites use it that it basically slowed down the entire Internet.</p>]]>
        
    </content>
</entry>

<entry>
    <title>PHP, RSS, SSL, and Outlook 2007</title>
    <link rel="alternate" type="text/html" href="http://cashcostello.com/blog/2009/09/php-rss-ssl-and-outlook-2007.html" />
    <id>tag:cashcostello.com,2009:/blog//1.4</id>

    <published>2009-09-26T19:58:34Z</published>
    <updated>2009-09-26T21:02:04Z</updated>

    <summary>Someone at work mentioned that Outlook was complaining about an RSS feed. The error message was &quot;The link may not point to a valid RSS source&quot;. This was odd because the feed validated and every other feed reader was able...</summary>
    <author>
        <name>Cash Costello</name>
        
    </author>
    
    <category term="outlook" label="outlook" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="php" label="php" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rss" label="rss" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://cashcostello.com/blog/">
        <![CDATA[<p>Someone at work mentioned that Outlook was complaining about an RSS feed. The error message was "The link may not point to a valid RSS source". This was odd because the feed validated and every other feed reader was able to handle it. Even stranger, Outlook had no issues with the same feed if it was not coming from an https address.</p>

<p>After some experimentation, I tracked the problem down to caching. The feed was being generated by a PHP application that was using sessions. By default, PHP sets some http headers to prevent pages from being cached when sessions are used. Outlook 2007 could not handle an RSS feed coming from a server using SSL with caching requested off. The solution was to either turn off session handling when the request was for an RSS feed or change the headers before sent so that caching wasn't turned off. For this application doing the latter was easier.</p>]]>
        
    </content>
</entry>

</feed>
