<?xml version="1.0" encoding="US-ASCII" ?>
<?xml-stylesheet type="text/xsl" href="xslt.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Javod's Blog</title>
        <description>A programmer relating his adventures with coding, and the politics of technology</description>
        <link>http://www.javod.com/blog/</link>
        <atom:link href="http://www.javod.com/blog/atomblog.php" rel="self" type="application/rss+xml" />
	<image>
	<url>http://www.javod.com/blog/images/rss.jpg</url>
	<title>Javod's Blog</title>
	<link>http://www.javod.com/blog/</link>
	</image>

<item><title>Auditing a Drupal Core Install</title>
	<description>&lt;ul&gt;
&lt;li&gt;Determine current version of Drupal being used&lt;/li&gt;
&lt;li&gt;Downloading Clean Drupal Core&lt;/li&gt;
&lt;li&gt;Running an initial diff (show the difference) between the two&lt;/li&gt;
&lt;li&gt;Run a detailed diff on individual files&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Determine Current Version of Drupal being used&lt;/h2&gt;

&lt;p&gt;There are multiple ways to check what version of Drupal is being used.&lt;/p&gt;
&lt;p&gt;Your best bet is to visit one of the admin status report pages as listed below:&lt;/p&gt;

&lt;p&gt;Drupal 6/7: /admin/reports/status&lt;/p&gt;
&lt;p&gt;Drupal 5 : /admin/logs/status&lt;/p&gt;

&lt;p&gt;Finally, you can take a look at the CHANGELOG.txt file located in the main directory of the Drupal install. (This method is prone to error, so use only if you are having trouble finding it elsewhere).&lt;/p&gt;

&lt;h2&gt;Downloading Clean Drupal Core&lt;/h2&gt;

&lt;p&gt;Our next step is to download a clean copy of the Drupal core install that matches our version.&lt;/p&gt;

&lt;p&gt;Thankfully, Drupal.org has set up a &lt;a href=&quot;http://drupal.org/node/3060/release&quot;&gt;release page&lt;/a&gt; where you can download any version of Drupal all the way back to 4.7.0!&lt;/p&gt;

&lt;p&gt;Simply select the branch you wish to download from, and then download the correct zip or tar.gz file from that branch! &lt;/p&gt;

&lt;p&gt;If you're familiar with Drupal's Git process, you can also checkout a copy:&lt;/p&gt;
&lt;pre class=&quot;brush: php&quot;&gt;
git clone http://git.drupal.org/project/drupal.git mydir 
cd mydir 
git checkout -b local 6.20
&lt;/pre&gt;

&lt;p&gt;If, for some unholy reason, you need a copy of a release prior to 4.7, versions 2-3 are avaiable at &lt;a href=&quot;http://www.natrak.net/early-drupal-releases&quot;&gt;Natrak.net&lt;/a&gt;. This is not an official release channel, so download at your own discretion.&lt;/p&gt;

&lt;h2&gt;Running an initial diff (show the difference) between the two&lt;/h2&gt;

&lt;p&gt;(Assume that there are two folders &lt;strong&gt;drupal&lt;/strong&gt; is the clean core, and &lt;strong&gt;myfolder&lt;/strong&gt; is the version we suspect has changes.)&lt;/p&gt;

&lt;p&gt;You can use any diff tool you like, I personally prefer to use the command line for finding the initial differences between the two.&lt;/p&gt;
&lt;p&gt;Here's what I use:&lt;/p&gt;
&lt;pre class=&quot;brush: php&quot;&gt;
// this will dump a txt file that lists the differences between the two files
diff -qr drupal myfolder | sort &gt; diffs.txt

// if you want to ignore a set of files, you can pipe it through grep. 
// In this case, I'm ignoring the .DS_Store file that macs tend to dump in every folder.
diff -qr drupal myfolder | grep -v -e 'DS_Store' | sort &gt; diffs.txt
&lt;/pre&gt;

&lt;p&gt;The preceding command will produce a diffs.txt file that will display any differences between the two. Below is an example of what this might look like.&lt;/p&gt;
 
&lt;pre class=&quot;brush: php&quot;&gt;
Files drupal/.htaccess and mydir/.htaccess differ
Files drupal/includes/common.inc and mydir/includes/common.inc differ
Files drupal/index.php and mydir/index.php differ

Only in mydir/profiles: technology
Only in mydir: phpMyAdmin
&lt;/pre&gt;

&lt;p&gt;From our diffs.txt file we have quickly learned that yes, there have been changes to the core install, and in addition to the changes, there is a phpMyAdmin installation in our current Drupal directory. At this point you should run a diff on each individual file that shows a difference.&lt;/p&gt;

&lt;h2&gt;Run a detailed diff on individual files&lt;/h2&gt;

&lt;p&gt;While you can continue to use the diff command, at this point I would recommend using a GUI diff tool. I like FileMerge, so that's what I'll be using.&lt;/p&gt;

&lt;p&gt;Let's compare the common.inc files and see what we get:&lt;/p&gt;
&lt;img src=&quot;/blog/images/diff_text.png&quot; alt=&quot;Diff&quot; /&gt;
&lt;p&gt;Here we can see that someone has placed a redirect instruction in a 404 function.&lt;/p&gt;

&lt;p&gt;Now, as part of our audit, we need to figure out why this was done, and how we can extract this code (either by creating a module, or finding a module that can redirect 404 requests). In this instance, we had a fairly simple change, but sometimes you may come across multiple large chagnes to the core. You must be diligent in discovering what the intent of the changes are, and on how to replicate those changes in a Drupal approved fashion.&lt;/p&gt;

&lt;p&gt;Happy hunting!&lt;/p&gt;</description>
	<link>http://www.javod.com/blog/auditing-a-drupal-core-install</link>
	<comments>http://www.javod.com/blog/auditing-a-drupal-core-install#comments</comments>
	<guid>http://www.javod.com/blog/auditing-a-drupal-core-install</guid>
	<pubDate>Thu, 17 May 2012 16:00:54 -0700</pubDate></item>

<item><title>How to bootstrap Drupal</title>
	<description>&lt;strong&gt;Create a page outside of the CMS workflow that has access to Drupal's built-in functions.&lt;/strong&gt;

&lt;p&gt;There are scenarios, the deeper you get into Drupal, where you will need to access Drupal's database and functions, but outside of the scope of the CMS. For instance, you may need to create an AJAX callback that hooks into the database for a TinyMCE plugin, or you may be looking for ways to port over a custom CMS to Drupal… These are just a couple of reasons for having an easy way to hook into Drupal at the base level.&lt;/p&gt;

&lt;p&gt;And like with everything Drupal, there is a Drupal function for this:&lt;br /&gt; 
&lt;a href=&quot;http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_bootstrap/7&quot;&gt;drupal_bootstrap($phase = NULL, $new_phase = TRUE)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we show how to use this function in code, let's break it down a little.&lt;/p&gt;

&lt;h3&gt;$phase&lt;/h3&gt;

&lt;p&gt;Phase is a predefined constant that identifies which phase of Drupal to load. As the docs state &quot;each phase adds to the previous one, so invoking a later phase automatically rums the earlier phases as well.&quot;&lt;/p&gt;

&lt;p&gt;The constants available for the $phase variable (in order) are:&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_CONFIGURATION&lt;/strong&gt;&lt;br /&gt;
Sets up the script environment and loads settings.php
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_PAGE_CACHE&lt;/strong&gt;&lt;br /&gt;
Attempts to serve a page from the cache
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_DATABASE&lt;/strong&gt;&lt;br /&gt;
Initializes the database system and registers autoload functions
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_VARIABLES&lt;/strong&gt;&lt;br /&gt;
Loads system variables and all enabled bootstrap modules
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_SESSION&lt;/strong&gt;&lt;br /&gt;
Initialize session handling
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_PAGE_HEADER&lt;/strong&gt;&lt;br /&gt;
Invokes hook_boot(), initializes locking system, and sends HTTP headers
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_LANGUAGE&lt;/strong&gt;&lt;br /&gt;
Finds the language of the page
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;DRUPAL_BOOTSTRAP_FULL&lt;/strong&gt;&lt;br /&gt;
Drupal is fully loaded; validate and fix input data.
&lt;/p&gt;
&lt;p&gt;Remember, calling any of the phases automatically will load any preceding phases as well.&lt;/p&gt;

&lt;h3&gt;$new_phase&lt;/h3&gt;

&lt;p&gt;TRUE declares that drupal_boostrap() will run recursively, loading all previous phases up to the one we have chosen.&lt;/p&gt;

&lt;p&gt;Now that we have the basics of the function out of the way, let's see how we can implement it.&lt;/p&gt;

&lt;p&gt;Create a custom page called &lt;em&gt;test.php&lt;/em&gt; and insert the code below:&lt;/p&gt;

&lt;pre class=&quot;brush: php&quot;&gt;
    // Get path of drupal install. 
    $drupal_path = $_SERVER['DOCUMENT_ROOT'];
    
    // Create a constant DRUPAL_ROOT that defines 
    // our path to the drupal install	
    define('DRUPAL_ROOT', $drupal_path);
    
    // We need to load the bootstrap.inc file so we can 
    // have access to the drupal_bootsrap() function
    require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
    
    // Bootstrap Drupal at the phase that you need
    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
    
    // Our custom page now has access to functions such as node_load() and db_query()  
    $node = node_load(1);
&lt;/pre&gt;

&lt;p&gt;(As a side note, if all you need is to query the database, then setting your phase to DRUPAL_BOOTSTRAP_DATABASE will be much less costly in terms of load time).&lt;/p&gt;

&lt;p&gt;That is basically all you need to tie Drupal into any custom page!&lt;/p&gt;

</description>
	<link>http://www.javod.com/blog/how-to-bootsrap-drupal</link>
	<comments>http://www.javod.com/blog/how-to-bootsrap-drupal#comments</comments>
	<guid>http://www.javod.com/blog/how-to-bootsrap-drupal</guid>
	<pubDate>Tue, 01 May 2012 13:20:00 -0700</pubDate></item>

<item><title>Drupal 7 - Usage of Foreign Keys in Schema API and current default FK ERD</title>
	<description>&lt;ul&gt;
&lt;li&gt;What are Foreign Keys?&lt;/li&gt;
&lt;li&gt;What is the Schema API?&lt;/li&gt;
&lt;li&gt; Why Drupal only supports FK by documentation and not practice. &lt;/li&gt;
&lt;li&gt;Current mappings with an ERD. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What are Foreign Keys? &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Foreign keys, put simply, are a referential constraint between two tables on a relational database. What this means is that data from one table is dependent on data from another table, and can not exist without it. This is a constraint placed directly on the database.&lt;/p&gt;
&lt;p&gt;For example: let's say we have two tables, USERS and PRODUCTS. If in our setup we know that under every circumstance a product will be assigned to a user, we can add a foreign key to a column in PRODUCTS that relates back to USERS. If we then try to add a product without having a user assigned to it, the query will fail. This helps force the integrity of data.&lt;/p&gt;
&lt;p&gt;When using MySQL I should note that the ISAM engine does not understand foreign keys, however InnoDB does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the Schema API? &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://api.drupal.org/api/drupal/includes!database!schema.inc/group/schemaapi/7&quot;&gt;Schema API&lt;/a&gt; is an array structure that defines one or more tables.&lt;/p&gt;
&lt;p&gt;This is implemented via the hook_schema() function, usually in the myModule.install file. Let's take a look at a very simple implementation:&lt;/p&gt;
&lt;pre class=&quot;brush: php&quot;&gt;
function myModule_schema() {
  $schema['myTable'] = array(
    'description' =&gt; 'A description of my table.',
    'fields' =&gt; array(
      'id' =&gt; array(
        'description' =&gt; 'The id auto incrementing id of this table 
                      (type =&gt; serial designates as auto incrementing).',
        'type' =&gt; 'serial',
        'unsigned' =&gt; TRUE,
        'not null' =&gt; TRUE,
      ),
      'items' =&gt; array(
        'description' =&gt; &quot;The number of whatever in this table.&quot;,
        'type' =&gt; 'int',
        'unsigned' =&gt; TRUE,
        'not null' =&gt; TRUE,
        'default' =&gt; 0,
      ),
      'decribe' =&gt; array(
        'description' =&gt; 'This column, describe, is to store descriptions.',
        'type' =&gt; 'varchar',
        'length' =&gt; 255,
        'not null' =&gt; TRUE,
        'default' =&gt; '',
      ),
     ),
    'primary key' =&gt; array('id'),
    'foreign keys' =&gt; array(
      'fk_name_node' =&gt; array(
        'table' =&gt; 'node',
        'columns' =&gt; array('id' =&gt; 'nid'),
      ),
     ),
  );
}
&lt;/pre&gt;
&lt;p&gt;Right now let's concentrate on the way foreign keys are setup through the Schema API.&lt;/p&gt;
&lt;p&gt;We first create an array called foreign keys.&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;brush: php&quot;&gt;'foreign keys' =&gt; array(&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We now give our foreign key an identifying name.&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;brush: php&quot;&gt;'fk_name_node' =&gt; array(&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Next we designate which table will be our reference, in this case the 'node' table.&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;brush: php&quot;&gt;'table' =&gt; 'node',&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Finally we assign the foreign key column relations from our table to the constraining table.&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;brush: php&quot;&gt;'columns' =&gt; array('id' =&gt; 'nid'), ),&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Drupal only supports FK by documentation and not practice.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So now that we know this what can we do? Well, currently Drupal only supports Foreign Keys as a documentation feature. Even when you've defined it in your schema, it will not actually implement the constraints on the database. So what's the point? Well for one, it helps those writing contributing modules to quickly see what tables are a required reference, but secondly, it is slowly preparing Drupal to actually add Foreign Keys. We might see this in Drupal 8, but probably not until a later release. Still, it's a good idea to implement this feature in your schemas, and those working on core are doing it in theirs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Current mappings with an ERD.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I took a look over the default install of Drupal 7, and grabbed all the schemas with foreign keys. Then I created an Entity Relationship Diagram (ERD) with &lt;em&gt;&lt;strong&gt;ONLY&lt;/strong&gt;&lt;/em&gt; those tables that had foreign key constraints. Click the image below for the full size pdf. This isn't every table that exists on default install, just those that had a foreign key constraint written into its schema.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/blog/files/fk_schema.pdf&quot;&gt;&lt;img style=&quot;border: 0;&quot; src=&quot;/blog/images/fk_schema.jpg&quot; alt=&quot;FK Schema&quot; width=&quot;441&quot; height=&quot;600&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
	<link>http://www.javod.com/blog/drupal-7-usage-of-foreign-keys-in-schema-api-and-current-default-fk-erd</link>
	<comments>http://www.javod.com/blog/drupal-7-usage-of-foreign-keys-in-schema-api-and-current-default-fk-erd#comments</comments>
	<guid>http://www.javod.com/blog/drupal-7-usage-of-foreign-keys-in-schema-api-and-current-default-fk-erd</guid>
	<pubDate>Thu, 12 Apr 2012 10:20:00 -0700</pubDate></item>

<item><title>Drupal 6: Add/Remove field values from a Node Reference in a Content Type</title>
	<description>&lt;p&gt;Drupal 6: When creating a Content Type, one of your options is to create a field with a type: 'Node reference'. Node references are a bit different than normal fields, in that they use other Content Type's values to populate the field values.&lt;/p&gt;

&lt;p&gt;This difference leads to some issues when trying to alter the Node Reference field on a Content Type form. What ends up happening, is that we do not have the ability to add/remove/alter values using the hook_form_alter() function directly. We end up needing a helper function for this. The code below is based on a select field:&lt;/p&gt;
&lt;pre class=&quot;brush: php&quot;&gt;
function myModule_form_alter(&amp;$form, &amp;$form_state){
    if (arg(0) == 'node' &amp;&amp; $form['form_id']['#value'] == 'myContentType_node_form') {
        // Replace our node reference field with the options we want using our helper
        $form['field_location']['#pre_render'] = array('helper_change_options');
    }
}


function helper_change_options($element) {
    $our_new_options = array(‘key’=&gt;’value’, ‘key2’=&gt;’value2’);  
        
    // insert our new values into the element (which is a select field, options)
    $element ['nid']['nid']['#options'] = $our_new_options;
    return $element; 
}
&lt;/pre&gt;
&lt;p&gt;Please note that whatever options you change or add, those node key values DO need to exist in the Node Reference’s Content Type. Otherwise you are going to run into some problems.&lt;/p&gt;
</description>
	<link>http://www.javod.com/blog/drupal-6-add-remove-field-values-from-a-node-reference-in-a-content-type</link>
	<comments>http://www.javod.com/blog/drupal-6-add-remove-field-values-from-a-node-reference-in-a-content-type#comments</comments>
	<guid>http://www.javod.com/blog/drupal-6-add-remove-field-values-from-a-node-reference-in-a-content-type</guid>
	<pubDate>Wed, 15 Feb 2012 17:20:00 -0700</pubDate></item>

<item><title>How to add your personal private/protected Twitter account to Drupal</title>
	<description>&lt;p&gt;(Note: In this post I use the terms private and protected interchangeably.)&lt;/p&gt;&lt;p&gt;There are times you may want to have your protected Tweets available on your site. Perhaps protected Tweets are available to your members but not necessarily the world at large. Non-private accounts are easy enough to pull: These feeds are easily accessible using the &lt;a href=&quot;https://dev.twitter.com/docs/api&quot;&gt;Rest API&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;However, to access protected accounts we must create a Drupal module that authenticates through OAuth. Let's go through this process step by step.&lt;/p&gt;&lt;p&gt;1) First, in Drupal, create a new Content Type.&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;strong&gt;Name:&lt;/strong&gt; Tweet &lt;br /&gt;&lt;strong&gt;Type:&lt;/strong&gt; tweet &lt;br /&gt;&lt;strong&gt;Description:&lt;/strong&gt; This content type pulls our protected tweets from our twitter account.&lt;/p&gt;&lt;p&gt;2) Next, we need to create a twitter app:&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;a) Go to &lt;a href=&quot;https://dev.twitter.com/&quot;&gt;dev.twitter.com&lt;/a&gt;&lt;br /&gt;b) Sign in using the protected twitter account you will be using.&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;img src=&quot;/blog/images/tw1.jpg&quot; alt=&quot;&quot; width=&quot;600&quot; height=&quot;400&quot; /&gt;&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;c) Click on Create an app.&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;img src=&quot;/blog/images/tw2.jpg&quot; alt=&quot;&quot; width=&quot;600&quot; height=&quot;400&quot; /&gt;&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;d) Fill in your app info, agree to the TOS, and submit.&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;img src=&quot;/blog/images/tw3.jpg&quot; alt=&quot;&quot; width=&quot;600&quot; height=&quot;400&quot; /&gt;&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;e) Go to the details tab for your newly created app and make note of the highlighted fields below. (Consumer Key, Consumer Secret, Access Token, Access Secret.)&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;img src=&quot;/blog/images/tw4.jpg&quot; alt=&quot;&quot; width=&quot;532&quot; height=&quot;241&quot; /&gt;&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;img src=&quot;/blog/images/tw5.1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;&lt;p style=&quot;padding-left: 30px;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3) Now we need a way to authenticate our app with our soon to be created module. We must use the OAuth method, and we have the option of writing our own OAuth validator, or using the wonderful &lt;a href=&quot;http://classes.verkoyen.eu/twitter_oauth&quot;&gt;Twitter with OAuth class &lt;/a&gt;which does 99% of the work for us (As of this post the current version is 2.1.2). The rest of this tutorial assumes you have downloaded the class, but if you're a purist and want to write your own, have at it!&lt;/p&gt;&lt;p&gt;4) Unzip the downloaded file and inside should be a file named '&lt;strong&gt;twitter.php&lt;/strong&gt;'. We will include this file in our module.&lt;/p&gt;&lt;p&gt;5) Now we will create our module. Inside your Drupal's modules folder, create a new folder called '&lt;strong&gt;twitter_private&lt;/strong&gt;'.&lt;/p&gt;&lt;p&gt;6) Inside this new folder create two files: '&lt;strong&gt;twitter_private.info&lt;/strong&gt;' and '&lt;strong&gt;twitter_private.module&lt;/strong&gt;' files.&lt;/p&gt;&lt;p&gt;7) Make sure to drop the '&lt;strong&gt;twitter.php&lt;/strong&gt;' file into the '&lt;strong&gt;twitter_private&lt;/strong&gt;' folder as well. You should now have three files in the folder.&lt;/p&gt;

&lt;p&gt;8) Your info file should look something like this:&lt;/p&gt;
&lt;pre class=&quot;brush: php&quot;&gt;
; $Id$
name = Private Twitter App 
description = Retrieves @myaccount tweets for inclusion in site.
core = 6.x
&lt;/pre&gt; 

&lt;p&gt;9) Your module file should look something like this (Replace all ALL-CAPS variables with your info):&lt;/p&gt;
&lt;pre class=&quot;brush: php&quot;&gt;
// We're creating a cron hook that will check the tweets. 
// This will check every time you have a cron job set to run.

function twitter_pivate_cron(){ 
    // require the twitter class
    require_once 'twitter.php';
    
    // create instance MAKE SURE to replace the Consumer key 
    // and Consumer Secret with your settings
    $twitter = new Twitter('CONSUMER_KEY', 'CONSUMER_SECRET');
    
    // set tokens MAKE SURE to replace token and secret with your settings
    $twitter-&gt;setOAuthToken('ACCESS_TOKEN');
    $twitter-&gt;setOAuthTokenSecret('ACCESS_SECRET');
    
    // get users timeline, $count being the number of tweets to retrieve 
    // MAKE SURE to replace the screenName with your Twitter account name 
    //(do not include @ symbol)

    $response = $twitter-&gt;statusesUserTimeline($userId = null, 
                          $screenName = 'YOUR_TWITTER_ACCOUNT_NAME', 
                          $sinceId = null, 
                          $maxId = null, 
                          $count = 10, 
                          $page = null, 
                          $trimUser = false, 
                          $includeRts = false, 
                          $includeEntities = false);
    
    
    // Retrieve the 10 most recent tweets in the node table 
    // and place in title array
    $q = db_query(&quot;SELECT title FROM node WHERE type='tweet' 
                           ORDER BY nid DESC LIMIT 10&quot;);
    while($r = mysql_fetch_assoc($q)){
        $title[] = $r['title'];
    }
    
    // search 10 most recent tweets on twitter 
    // and if it doesn't exist in node table, insert
    foreach($response as $r){
        foreach($r as $k=&gt;$v){
            if($k == 'text'){
                if(!in_array($v, $title)){
                    $node = new stdClass();
                    $node-&gt;title = &quot;$v&quot;;
                    $node-&gt;type = 'tweet';
                    $node-&gt;created = time();
                    $node-&gt;changed = $node-&gt;created;
                    node_save($node);

                }
            }
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;10) Now activate the module in your Drupal admin panel, run the cron manually to get started, and you are all set. Just figure out how you would like to use the tweet content type (you can create a new block, or have it feed into a page, or whatever you'd like)&lt;/p&gt;</description>
	<link>http://www.javod.com/blog/how-to-add-your-personal-private-protected-twitter-account-to-drupal</link>
	<comments>http://www.javod.com/blog/how-to-add-your-personal-private-protected-twitter-account-to-drupal#comments</comments>
	<guid>http://www.javod.com/blog/how-to-add-your-personal-private-protected-twitter-account-to-drupal</guid>
	<pubDate>Wed, 28 Dec 2011 13:02:30 -0700</pubDate></item>

<item><title>Using the Firefox Tilt plugin for an unconventional purpose</title>
	<description>&lt;p&gt;&lt;a href=&quot;http://blog.mozilla.com/tilt/&quot;&gt;Tilt&lt;/a&gt; is self described as a &quot;Firefox extension focused on creating a 3D visualization of a webpage, drawn using WebGL. Since the DOM is essentially a tree-like representation of a document, this tool layers each node based on the nesting in the tree, creating stacks of elements, each having a corresponding depth and being textured according to the webpage rendering.&quot;
&lt;/p&gt;
&lt;p&gt;
    The plugin is pretty amazing, and it does help find nested elements very quickly, however there is a novelty to it that seems to wear out after &quot;tilting&quot; a few websites.
&lt;/p&gt;
&lt;p&gt;
   After playing with Tilt, it occurred to me that there was potential for 3D modeling that could be added to a website. 
&lt;/p&gt;
&lt;p&gt;
    &lt;div style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;http://javod.com/blog/files/tilt_building.php&quot;&gt;&lt;img src=&quot;images/willis_web.jpg&quot; alt=&quot;Wills Website&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
    &lt;a href=&quot;http://javod.com/blog/files/tilt_building.php&quot;&gt;The website above&lt;/a&gt; is a very simple example of how one might go about this. I thought it would be neat to have a page about a famous skyscraper, and when the Tilt plugin was applied, the actual skyscraper would be built.
&lt;/p&gt;
&lt;p&gt;
    &lt;div style=&quot;text-align: center&quot;&gt;&lt;img src=&quot;images/willis_tilt.jpg&quot; alt=&quot;Willis Website viewed with Tilt&quot; border=&quot;0&quot; /&gt;&lt;/div&gt;
     I've done the calculations to make sure that the skyscraper is indeed to scale, so if you are viewing it you will have to zoom out all the way to get a good view. A cool little side-project, and a fun easter-egg.
&lt;/p&gt;
&lt;p&gt; 
    I don't know how practical this would be for real modeling, but I could see how an architectural firm might use this technique as a simple &quot;wow&quot; factor in a pitch.
&lt;/p&gt;</description>
	<link>http://www.javod.com/blog/using-the-firefox-tilt-plugin-for-an-unconventional-purpose</link>
	<comments>http://www.javod.com/blog/using-the-firefox-tilt-plugin-for-an-unconventional-purpose#comments</comments>
	<guid>http://www.javod.com/blog/using-the-firefox-tilt-plugin-for-an-unconventional-purpose</guid>
	<pubDate>Tue, 06 Dec 2011 12:54:30 -0700</pubDate></item>

<item><title>Drupal 6: Running Batch via Cron</title>
	<description>&lt;p&gt;Looking through the Drupal documentation, a person is led to believe that automating a Batch script is tantamount to moving Mount Fuji 10 feet to the left with a wooden spoon. The general consensus seems to be that all Batch scripts should be converted to use the Queue API. Sometimes this is an acceptable solution, but when you're running a very large script that makes extensive use of the Batch $context variable, it becomes a daunting task.&lt;/p&gt;

&lt;p&gt;The big issue (or at least the issue I ran into) with Batch and cron, is that the Batch API was really written to be used in conjunction with the browser, so there are calls made to update the progress bar that just don’t jive when running in cron.&lt;/p&gt;

&lt;p&gt;The solution that worked for me was a bit of a hack, but only a small one. If we look over the batch_process() documentation, there’s a telling bit of information: &quot;Unless the batch has been marked with 'progressive' = FALSE, the function issues a drupal_goto and thus ends page execution.&quot; That sounded positive, and from what I could tell it bypasses the progress bar and executes the batch in one pass.&lt;/p&gt;

&lt;p&gt;Now the problem is that even though we are given this information, there’s no parameter to change this variable. It looks like an oversight by the developers. Instead of hacking the core though, what we can do is create a reference to batch_get and turn off the progressive option.&lt;/p&gt;

&lt;pre class=&quot;brush: php&quot;&gt;
// create a reference to batch_get()
// this is called directly in the core batch_process() function
$batch =&amp; batch_get();
// Using the reference, we turn progressive off
// which prevents the redirect to the standard Batch API progress bar
$batch['progressive'] = FALSE;
// Because we are not using the form to trigger the batch, we run batch_process('')
batch_process('');
&lt;/pre&gt;

&lt;p&gt;So let’s take a look at how this would work:&lt;/p&gt;

&lt;pre class=&quot;brush: php&quot;&gt;
hook_cron(){
    hook_my_function();
}
hook_my_function(){
    batch_set(array(
      'title' =&gt; My Title',
      'operations' =&gt; array(
        array(‘hook_another_function_to_run’, array($info))
      ),
      'progress_message' =&gt; 'Processing...',
    ));
   
    $batch =&amp; batch_get();
    $batch['progressive'] = FALSE;
    batch_process('');
}
&lt;/pre&gt;

&lt;p&gt;Now there may be some issues with this implementation that I am unaware of, but I am running a rather large Batch script and have yet to come across any.&lt;/p&gt;

&lt;p&gt;Hope this helps someone!&lt;/p&gt;
</description>
	<link>http://www.javod.com/blog/drupal-6-running-batch-via-cron</link>
	<comments>http://www.javod.com/blog/drupal-6-running-batch-via-cron#comments</comments>
	<guid>http://www.javod.com/blog/drupal-6-running-batch-via-cron</guid>
	<pubDate>Wed, 11 Nov 2011 18:52:30 -0700</pubDate></item>

<item><title>jQuery: Disable right click and drag on images</title>
	<description>&lt;p&gt;Sometimes you get a client that just wants to do what they want to do no matter the reasons they shouldn't.&lt;p&gt;
&lt;p&gt;In the case of disabling right click the short answer is: Don't.&lt;/p&gt; 
&lt;p&gt;The long answer is there is no way to prevent someone from taking images off your site. You can slightly thwart users, but it is against the very principles of the way the internet works, and is considered bad practice. Typically only websites that are either unprofessional or shady use these techniques.&lt;/p&gt;
&lt;p&gt;Now, with that, sometimes you'll get a person who says, &quot;just do it anyway.&quot; So here is some jQuery to make this an easy job for you.&lt;/p&gt;

&lt;pre class=&quot;brush: javascript&quot;&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

    $(document).ready(function(){

// Here we are getting all images and turning off the context menu. 
// return false is the same as calling .preventDefault() and .stopPropagation()
        $('img').bind(&quot;contextmenu&quot;,function(e){
            return false;
        });

// Here we disable default behaviors for mousedown which include the drag options.
        $('img').bind(&quot;mousedown&quot;,function(e){
            return false;
        });
    });

&lt;/script&gt;
&lt;/pre&gt;</description>
	<link>http://www.javod.com/blog/jquery-disable-right-click-and-drag-on-images</link>
	<comments>http://www.javod.com/blog/jquery-disable-right-click-and-drag-on-images#comments</comments>
	<guid>http://www.javod.com/blog/jquery-disable-right-click-and-drag-on-images</guid>
	<pubDate>Wed, 17 Nov 2010 10:46:31 -0700</pubDate></item>

<item><title>Dante's Theme - Piano Cover FMA</title>
	<description>Something a little different: A video of me playing Dante's Theme from Fullmetal Alchemist.

&lt;object width=&quot;640&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/c_9h7lOXVSw?fs=1&amp;amp;hl=en_US&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/c_9h7lOXVSw?fs=1&amp;amp;hl=en_US&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;640&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;</description>
	<link>http://www.javod.com/blog/dantes-theme-piano-cover-fma</link>
	<comments>http://www.javod.com/blog/dantes-theme-piano-cover-fma#comments</comments>
	<guid>http://www.javod.com/blog/dantes-theme-piano-cover-fma</guid>
	<pubDate>Sun, 24 Oct 2010 11:08:34 -0700</pubDate></item>

<item><title>zeroclipboard: Get javascript events firing after AJAX request</title>
	<description>&lt;p&gt;An interesting problem I came across recently was trying to get &lt;a href=&quot;http://code.google.com/p/zeroclipboard/&quot;&gt;Zero Clipboard&lt;/a&gt; to work in an AJAX loaded div. Zero Clipboard is pretty much the only way to copy text to the user's clipboard that works across browsers. There is no native way to do this, so it floats an invisible movie on top of a DOM element. Yes, your users need to have Flash installed for this to work.
&lt;/p&gt;
&lt;p&gt;The issue is as follows: &lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;We need zeroclipboard available on a page that is loaded via ajax inside a div.&lt;/li&gt;
  &lt;li&gt;Javascript events are not bound in an ajax call unless specifically loaded by an onclick, onload etc...&lt;/li&gt;
  &lt;li&gt;The scripts themselves need to exist outside of the ajax loaded page to be loaded during page load.&lt;br /&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At the time of this writing zeroclipboard is on version 1.0.7&lt;/p&gt;
&lt;p&gt;As the documentation notes, the ZeroClipboard.swf file  by default  is sought for in the same directory as the webpage, and this tutorial assumes that it is. &lt;/p&gt;
&lt;p&gt;Let's say we have two pages: index.html and ajaxload.html&lt;/p&gt;
&lt;p&gt;The default example for zeroclipboard:&lt;/p&gt;
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;html&gt;
	&amp;lt;head&gt;
		&amp;lt;style type=&quot;text/css&quot;&gt;
			#d_clip_button {
				text-align:center; 
				border:1px solid black; 
				background-color:#ccc; 
				margin:10px; padding:10px; 
			}
			#d_clip_button.hover { background-color:#eee; }
			#d_clip_button.active { background-color:#aaa; }
		&amp;lt;/style&gt;
	&amp;lt;/head&gt;
	&amp;lt;body&gt;
		&amp;lt;script type=&quot;text/javascript&quot; src=&quot;ZeroClipboard.js&quot;&gt;&amp;lt;/script&gt;
                
		Copy to Clipboard: &amp;lt;input type=&quot;text&quot; id=&quot;clip_text&quot; size=&quot;40&quot; value=&quot;Copy me!&quot;/&gt;
        
		&amp;lt;div id=&quot;d_clip_button&quot;&gt;Copy To Clipboard&amp;lt;/div&gt;
        
		&amp;lt;script language=&quot;JavaScript&quot;&gt;
			var clip = new ZeroClipboard.Client();
                        
			clip.setText( '' ); // will be set later on mouseDown
			clip.setHandCursor( true );
			clip.setCSSEffects( true );
                        
			clip.addEventListener( 'load', function(client) {
				// alert( &quot;movie is loaded&quot; );
			} );
                        
			clip.addEventListener( 'complete', function(client, text) {
				alert(&quot;Copied text to clipboard: &quot; + text );
			} );
                        
			clip.addEventListener( 'mouseOver', function(client) {
				// alert(&quot;mouse over&quot;); 
			} );
                        
			clip.addEventListener( 'mouseOut', function(client) { 
				// alert(&quot;mouse out&quot;); 
			} );
                        
			clip.addEventListener( 'mouseDown', function(client) { 
				// set text to copy here
				clip.setText( document.getElementById('clip_text').value );
                                
				// alert(&quot;mouse down&quot;); 
			} );
                        
			clip.addEventListener( 'mouseUp', function(client) { 
				// alert(&quot;mouse up&quot;); 
			} );
                        
			clip.glue( 'd_clip_button' );
		&amp;lt;/script&gt;
	&amp;lt;/body&gt;
&amp;lt;/html&gt;
&lt;/pre&gt;
&lt;p&gt;For our purposes we're going to make a couple of changes.&lt;br /&gt;
index.html:&lt;/p&gt;
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;html&gt;
	&amp;lt;head&gt;
		&amp;lt;style type=&quot;text/css&quot;&gt;
			#d_clip_button {
				text-align:center; 
				border:1px solid black; 
				background-color:#ccc; 
				margin:10px; padding:10px; 
			}
			#d_clip_button.hover { background-color:#eee; }
			#d_clip_button.active { background-color:#aaa; }
		&amp;lt;/style&gt;

       &amp;lt;!-- We're moving the main javascript file to the head section --&amp;gt;
       &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;ZeroClipboard.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;!-- We're also taking the following code and wrapping it in a function to call later --&amp;gt;
		&amp;lt;script language=&amp;quot;JavaScript&amp;quot;&amp;gt;
		function clipit(){
			var clip = new ZeroClipboard.Client();
                        
			clip.setText( '' ); // will be set later on mouseDown
			clip.setHandCursor( true );
			clip.setCSSEffects( true );
                        
			clip.addEventListener( 'load', function(client) {
				// alert( &amp;quot;movie is loaded&amp;quot; );
			} );
                        
			clip.addEventListener( 'complete', function(client, text) {
				alert(&amp;quot;Copied text to clipboard: &amp;quot; + text );
			} );
                        
			clip.addEventListener( 'mouseOver', function(client) {
				// alert(&amp;quot;mouse over&amp;quot;); 
			} );
                        
			clip.addEventListener( 'mouseOut', function(client) { 
				// alert(&amp;quot;mouse out&amp;quot;); 
			} );
                        
			clip.addEventListener( 'mouseDown', function(client) { 
				// set text to copy here
				clip.setText( document.getElementById('clip_text').value );
                                
				// alert(&amp;quot;mouse down&amp;quot;); 
			} );
                        
			clip.addEventListener( 'mouseUp', function(client) { 
				// alert(&amp;quot;mouse up&amp;quot;); 
			} );
                        
			clip.glue( 'd_clip_button' );
		}
		&amp;lt;/script&amp;gt;

	&amp;lt;/head&gt;
	&amp;lt;body&gt;
		&amp;lt;!-- We're adding the div where we will load our ajax file --&amp;gt;
		&amp;lt;div id=&amp;quot;loadPageHere&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;	
	&amp;lt;/body&gt;
&amp;lt;/html&gt;
&lt;/pre&gt;

&lt;p&gt;ajaxload.html:&lt;/p&gt;
&lt;pre class=&quot;brush: html&quot;&gt;
Copy to Clipboard: &amp;lt;input type=&quot;text&quot; id=&quot;clip_text&quot; size=&quot;40&quot; value=&quot;Copy me!&quot;/&gt;
&amp;lt;div id=&quot;d_clip_button&quot;&gt;Copy To Clipboard&amp;lt;/div&gt;

&amp;lt;!-- Here's the tricky part --&amp;gt;
&amp;lt;!-- We need to load our function after the ajax call, but we can't use a body tag, and divs don't allow the onload attribute --&amp;gt;
&amp;lt;!-- The hack here is to use a 1px x 1px image  and use the onload function available in the img tag to load our function --&amp;gt;
&amp;lt;img src=&amp;quot;blank.gif&amp;quot; onload=&amp;quot;clipit();&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;So that's the way to use zeroclipboard in an AJAX call. Please note that I did not include the ajax code that actually loads ajaxload.php in the index's div. I assume if you're having this problem you've probably  already come that far. If you do need help with that though, just ask!&lt;/p&gt;
&lt;p&gt;If you have any questions, problems or suggestions feel free to leave a comment.&lt;/p&gt;</description>
	<link>http://www.javod.com/blog/zeroclipboard-get-javascript-events-firing-after-ajax-request</link>
	<comments>http://www.javod.com/blog/zeroclipboard-get-javascript-events-firing-after-ajax-request#comments</comments>
	<guid>http://www.javod.com/blog/zeroclipboard-get-javascript-events-firing-after-ajax-request</guid>
	<pubDate>Tue, 25 May 2010 21:08:54 -0700</pubDate></item>

</channel></rss> 
