Simple Switching of Variable Values

This just came to me, a rather nifty trick inspired by Python's tuples. I'm sure this is well known. But, I haven't written about anything useful in a while so I thought that I'd do something simple. Normally to switch the values of two variables one would do the following..

$a = 'a';
$b = 'b';
$c;

$c = $b;
$b = $a;
$a = $c;

var_dump($a); // output: b
var_dump($b); // output: a

This is pretty ugly, so lets simplify things a bit...


$a = 'a';
$b = 'b';

list($b, $a) = array($a, $b);

var_dump($a); // output: b
var_dump($b); // output: a

Cheers.

I've Dived Into Python

I recently downloaded the book Dive Into Python and am making my way through the chapters. It's a book on Python for programmers who are curious about the language.

So far I really like the language an what it has to offer. Two things I especially like are the lambdas and list processing functions. In fact I am even thinking of going head on into python and giving PHP a break for a while. This change of heart was sparked by three factors. First, I feel like I write more than I need to with PHP. Languages such as ECMAscript allow you to do things so succinctly that it makes PHP feel brutish. Second, I love functional programming (I also love object-oriented programming) and unfortunately, PHP5 is lacking in that respect. The closest it can come to closures is its create_function() function. create_function is tantamount to using eval() to make a function on the fly. I also find that it doesn't work as I expect it to do so, for example: because create_function just creates a function in the global namespace and returns it is a string. That means that the following will fail: $obj->test = create_function(...); $obj->test();. That was one thing that really disappointed me. Finally, Pihipi made me realize many oh PHP's flaws. This is a funny thought because Pihipi adds almost every feature I've ever wanted to PHP. It also serves as a reminder of many important features that other languages have to offer that PHP doesn't.

To sum up, I haven't had as much coding motivation recently and I think learning Python will change that. I'm excited about using the language, and I'm also curious about the Django framework.

Curiosity is healthy and I think this move will ultimately make me a better programmer.

New Blog Mostly Finished

I'm mostly finished the new version of the blog. One cool thing I just did was the login feature. In my framework I now have a small library that can sit on top of any database table and transparently deal with logging users in, out, and auto logging users in. Getting it to work with wordpress was a bit tricky; however, because this library is normally meant to stand alone.

The way I solved logging in to the new site and logging in to wordpress was to open a socket connection to wp-login.php and POST the appropriate form information.

Another recent addition was the pagination library that I mentioned in my last post. From the PHP side, it lets me do the following:

$response['posts_pager'] = $this->pager
					->numPages($num_pages)
					->currentPage($request['page_num'])
					->showRightOfCurrent(3)
					->showLeftOfCurrent(3)
					->setPath('/page/%page%/');

An then I can use that pager from the templates with the following tags: page:open, page:first, page:prev, page:each, page:next, and page:last. If you scroll down to the bottom of the front page then you can see when/how each of these tags is used. For example, if we can see the number '1' for page one, then page:first isn't shown. If we are not on page 1, then page:prev is shown. The Pager::showLeftOfCurrent() and Pager::showRightOfCurrent() dictate the maximum number of page numbers to show on the left and right sides of the current page we are on. So, for example, if you go to the front page, you will only see up to the number 4, because there are only allowed to be 3 page numbers to the right of the current page.

Another great thing about the pagination library is that it takes a lot of the hassle out of doing pagination. One such hassle this removes is having to worry about page boundaries. In fact, you can pass it the page number information right out of the $request object and expect it all to work. Of course, its easy to make your own function to do all of this and generate HTML, but then things become trickier if you want to style different pagers differently.

I think this new version of the blog is a testament to how rapidly one can code with the PHP5 framework I am developing. Within a matter of hours I had all of the main functionality of the wordpress homepage. After another few hours, every page worked. After that the only thing left was trying to make it all look half-decent.

Generating code for use in PHP's create_function

I came up with a nifty function while working on the pagination library for my framework and the next version of this blog. The following function isn't actually the same one I use in the framework, but a generalized all-encompassing solution.

The problem I had was that I needed the pagination class to generate a uniform route/path for the urls so that the pagination links--eg: first, prev, 1, 2 ... next, last--would all work in the same way. One thing I realized that I didn't want to do was put the url into the template because that meant having to repeat the format several times over. It also meant that dealing with the previous and next page links would be tricky because I don't want to let them get out of bounds.

Here is the function as I made it in the Pager class. Notice how $path becomes a bit of generated php string concatenation and how I insert it into the create_function. Also notice how the $page in the create_function is then substituted into that string concatenation where there was one the %page% token in the $path variable.

/**
 * Set the format for the path for each page. A path should be supplied to
 * this function and wherever the person wants the page number to appear
 * in the path, they need only put a %page%
 */
public function setPath($path = '') {
	
	// get rid of any quotes in the path... too bad for people who for
	// some reason would do this.
	$path = preg_replace("~['\"]*~", "", $path);
	
	// replace the token with what will be executed php
	$path = str_replace("%page%", "'. \$page .'", $path);
	
	// create a function so that substitution of the page number into the
	// path is as easy as calling the lambda
	$this->path_format = create_function('$page', "return vk_url(vk_path('{$path}'));");
	
	return $this;
}

Here is the generalized function that I derived from this:

function lambda_filter($format, $filter) {
	if(!is_array($filter)) {
		$filter = array($filter);
	}
		
	$args = '';
	$letter = 'a';
	$sep = '';
	
	foreach($filter as $f) {
		$args .= $sep . '$'. $letter++;
		$sep = ',';
	}
	
	return create_function($args, 'return str_replace('. var_export($filter, TRUE) .', array('. $args .'), "'. str_replace('"', '\"', $format) .'");');
}

$fn = lambda_filter("/page/%page%/", '%page%');

echo $fn(1);

// output: /page/1/

If you read through that function, you will notice that the second parameter to lambda_filter can also be an array of tokens to substitute in to the format string. Here's an example of how that can be used.

$fn = lambda_filter("/%year%/%month%/%day%/", array('%year%', '%month%', '%day%'));

echo $fn('2007', '07', '08');

// output: /2007/07/08/

Obviously that format of token doesn't need to be used. Any format of token can be used.

Update on Wordpress sans Wordpress

I wanted to give an update (so soon?) on my progress on making the wordpress front end without wordpress. This is my third part day (because I work all day on other things) working on it, and today I decided to add a nice look to the main page. I've asked a few people and the general consensus is that my design skills are lacking. You can view what's been done so far here: http://core.ioreader.com/wwwroot/. Now, for the good stuff. Here are what a few of the current templates look like that make that page:

home.html

Caveat: there are a lot of divs there to accomplish those nice rounded corners + shadows that I wanted.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
	<title>{$blog_name}</title>
	<link rel="stylesheet" type="text/css" media="screen" href="{/}css/reset.css" />

	<link rel="stylesheet" type="text/css" media="screen" href="{/}css/style.css" />
</head>

<body>

<div id="header">
	<v:component id="menu" />
	<h1><a href="{/}" title="{$blog_name}">{$blog_name}</a></h1>

	<h2>{$blog_description}</h2>
</div>

<div class="t"><div><div></div></div></div>
<div id="content">

	<div class="dialog">
		<div id="main_content">
			<div id="content_left">
				<v:import id="main" />

			</div>
			<div id="content_right">
				<v:component id="calendar" />
				<v:component id="categories" />

				<v:component id="archive" />
				<v:component id="blogroll" />
			</div>
			<br style="clear:both;" />

		</div>
	</div>
</div>

</body>
</html>

posts.html

This is the template that displays all of the posts on the main page.

<v:defaut list="posts">
<div class="message">
	There appear to be no posts yet!
</div>
</v:default>
<v:repeat list="posts" as="post">

<h2><a href="{$post.permalink}" title="" id="post{$post.id}" name="post{$post.id}">{$post.post_title}</a></h2>	
<div class="post">

	{$post.preview_content}
	<ul class="categories">
		<v:repeat list="post.categories" as="category">
		<li><a href="{/$category.nice_name/}" title="{$category.name}">{$category.name}</a></li>

		</v:repeat>
		by {$post.author_name}
		on {$post.date}
	</ul>
</div>
</v:repeat>

components/calendar.html

This displays that fancy calendar that shows which days have posts in them.

<dl id="calendar">
	<dt>Calendar</dt>
	<dd>
		<table width="100%" class="cal_month" cellpadding="0" cellspacing="1">

			<thead>
				<th colspan="7">
					<a href="{/$cal_year/$cal_month/}" title="Archives for {$cal_month_name}, {$cal_year}">{$cal_month_name}</a>
					<a href="{/$cal_year/}" title="Archives for {$cal_year}">{$cal_year}</a>

				</th>
			</thead>
			<thead>
				<v:repeat list="cal_day_titles" as="day">
				<th>{$day}</th>

				</v:repeat>
			</thead>
			<tbody>
			<v:repeat list="cal_weeks" as="week">
				<tr class="cal_week">

					<v:repeat list="week.days" as="day">
					<td class="<v:if var="day.month" eqvar="cal_month">cal_day<v:else />cal_day_off</v:if>">

						<v:if var="day.link" eq="1"><a href="{/$day.year/$day.month/$day.day/}" title="View archives for this day">{$day.day}</a><v:else />{$day.day}</v:if>

					</td>
					</v:repeat>
				</tr>
			</v:repeat>
			</tbody>
		</table>

	</dd>
</dl>

SQL Queries

Okay, you get the point. Now, if you're a big wordpress person and are wondering what the SQL queries I am doing to accomplish all of this are, here all of them are:

--- Get all menu items
SELECT p.post_name, p.post_title FROM wp_posts p WHERE p.post_status='publish' AND p.post_type='page' ORDER BY p.menu_order ASC

--- Get only the options needed
SELECT * FROM wp_options WHERE option_name IN('posts_per_page','blogname','blogdescription') 

--- Get the front page posts
SELECT p.*, u.display_name AS author_name, u.ID as author_id, GROUP_CONCAT(ptc.category_id SEPARATOR ',') AS category_ids FROM wp_posts p, wp_users u, wp_post2cat ptc WHERE p.post_author=u.ID AND p.post_status='publish' AND p.post_type='post' AND ptc.post_id=p.ID GROUP BY p.ID ORDER BY p.ID DESC LIMIT 0, 10

--- Get posts to place into the calendar
SELECT DAY(post_date) AS day FROM wp_posts WHERE MONTH(post_date) = 7 AND YEAR(post_date) = 2007 GROUP BY DAY(post_date)

--- Get all top-level categories
SELECT * FROM wp_categories WHERE category_parent = 0 AND category_nicename <> 'blogroll' 

--- Get all sub-level categories
SELECT * FROM wp_categories WHERE category_parent > 0 

--- Get Blogroll links
SELECT * FROM wp_links WHERE link_visible='Y' ORDER BY link_name ASC

--- Get the archives
SELECT MONTH(post_date) as month_num, YEAR(post_date) AS year, COUNT(ID) AS num_posts FROM wp_posts WHERE post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY YEAR(post_date) DESC, MONTH(post_date) DESC

I think that's a good sum up of my progress thus far.

Wordpress... Without Wordpress!

So in the time I've had after work last night and tonight I've started making the front end to wordpress but using my framework. There were a few motivations for this:

  • Wordpress has a POS template engine--or lack thereof. This is an arguable point, of course, because PHP is a template language.
  • I have no idea how many SQL queries wordpress + k2 perform on the main page, but I had a feeling I could do less.
  • I wanted more control over the front-facing side of my blog.

General

In the few hours that I have dedicated to this mini project, I have made quite a lot of progress! You can go see monitor my current progress if you would like to. Otherwise, I've made some general observations about wordpress.

First of all, I get the feeling that the wordpress creators have no idea what they are doing with databases. They need to settle on a single naming scheme for their database table columns. I can imagine that their excuse for the terrible column names was a result of backwards compatibility or some other meaningless argument. There's no excuse for this type of thing. If it were an issue of backward compatibility then when they were programming it then they should have stuck with the original naming scheme and left it at that. If it was a problem of different styles for its different developers then they need to learn how to coordinate their efforts.

It's total guess work about what column you want--especially for table primary keys and foreign keys! Some places have, for example: ID, cat_ID, comment_ID, post_id, category_id, etc. Last time I checked most (if not all) major databases supported ALTER syntax. And if they don't, then they probably support TEMPORARY tables in which case one can use as an intermediate for the data if a table's columns need to be renamed by dropping said table.

Second, their code is a total mess. I get the feeling that this is partly due to the need to be backward compatible to some point, hence their dependence on global variables.

Third, it's a wonder that everything works as well as it seems to. I'm astonished that its developers can maintain it.

Otherwise, since I haven't gone and looked too much at the wordpress internals, I thought I'd show how I solved a few simple problems, namely: archives list and post categories list.

Archives

In my framework I have made these great things called components. Components are controllers that can be accessed through templates using a simple XML tag. If you look at this blog, each box represents a component: menu, blogroll, archives, categories, etc.

My goal was that no component would execute more than one query, so getting the archives was interesting. You might think that getting the number of posts would be the tricky part, but it actually turns out to be how to get the months themselves. Here's the SQL query I came up with:

SELECT MONTH(post_date) as month_num, YEAR(post_date) AS year, COUNT(ID) AS num_posts 
FROM wp_posts 
WHERE post_status = 'publish' 
GROUP BY YEAR(post_date), MONTH(post_date) 
ORDER BY YEAR(post_date) DESC, MONTH(post_date) DESC

This is quite simple, I wouldn't be surprised if something similar is somewhere in wordpress.

Categories

Another requirement that I set for myself was not to do an extra query to get a posts categories. There was a rather simple solution to this problem. The categories component which lists out all of the categories would have to use the same result set as the categories that are listed under each post name. This means that the categories component does (ghast!) two queries and then every post listed on the front page takes information from those results and figures out which categories it belongs to (without any extra queries). Another requirement was that I not break any existing wordpress urls, that meant that the PHP category needed to have the /development/ parent category in its url.

You might be wondering why I needed two queries for the categories component. This was because I decided that to handle sub-categories, I would only allow for the display of one sub-level and I would use PHP to figure out which categories belonged to which parents. This was a rather simple thing to accomplish.

Regardless, I used a GROUP_CONCAT to get the category ids that a post belongs to along with the normal post data. Here's a super function I made for finding visible posts:

public function findAllVisible($page = 1, $limit = 10, array $filter = array()) {
	
	// build the base of the query		
	$query = new VK_SelectQuery("p.*, u.user_nicename AS author_name, u.ID as author_id", "wp_posts p, wp_users u", "p.post_author=u.ID");
	
	// visible
	$query->addWhere("p.post_status='publish'");
	
	// pagination
	$page = $page < = 1 ? 0 : $page-1;
	$query->addLimit($page * $limit) // start
	 	  ->addLimit($limit);        // offset
	
	// ordering
	$query->addOrderBy('p.ID', 'DESC');
	
	// default type filter
	if(!isset($filter['type'])) {
		$filter['type'] = 'post';
	}
	
	// filter the results further
	foreach($filter as $key => $val) {
		switch($key) {
			
			// by a specific cateogry
			case 'category':
				$query->addJoin("wp_post2cat pc", "pc.post_id=p.ID", 'INNER')
					  ->addWhere("pc.category_id=". (int)$val);
				break;
				
			// by a date
			case 'year':
			case 'month':
			case 'day':
				$query->addWhere(strtoupper($key) ."(p.post_date)=". (int)$val);
				break;
			
			// by an author
			case 'author':
				$query->addWhere("p.post_author=". (int)$val);
				break;
			
			// by type
			case 'type':
				$query->addWhere("p.post_type='{$val}'");
		}
	}
	
	// get the categoriy ids in a comma-separated form
	$query->addFrom("wp_post2cat ptc")
		  ->addSelect("GROUP_CONCAT(ptc.category_id SEPARATOR ',') AS category_ids")
		  ->addWhere("ptc.post_id=p.ID")
		  ->addGroupBy('p.ID');
	
	// get the posts
	return $this->findAllByQuery($query);
}

This fit nicely into PostsRecord class and lets me deal with details such as pagination easily.

Simple ORM Documentation

Today I wrote up the documentation for the simple ORM system in my PHP5 framework and for the CodeIgniter PHP framework as well. You can check out the documentation at: http://ioreader.com/code/ORM Documentation/index.php.

A PHP Domain Specific Language?

I've been thinking over an interesting idea a lot recently and wanted to get it out in words. The general idea is as follows: create a functional domain specific language (DSL) that PHP can parse/interpret/compile. You might be pulling out your hair right now thinking: "why would you write a DSL in an interpreted language???" That's a fair question, and the answer to it is that it's an experiment and I want to see if I can put my ideas to work in the language I know best.

If you're a Lisp/Javascript fan then you probably picked up on the 'functional' part of this idea. I want to make a functional language. I think that they are wildly powerful and totally underrated. I also want to make something that's more approachable than Lisp though! In fact, what I've decided on is not to make a language per se, but the building blocks of a language.

The main idea is that the programmer starts by defining some simple constructs: these describe what things in the language should look like, how they are bound, and how they are called. An idea for these constructs that I'm toying around with looks like this:

<construct =function>
	<definition>
		function -->(<-->)<--{<-->}
	</definition>
	<call>
		-->(<-->)
	</call>
</construct>

That must look so weird. All those weird sets of arrows are simplified pattern matchings. For example, the --> will look for anything from the character left of the arrow up to the character after the arrow. In this case, if we had "function moo(" then the --> would match "moo". The <--> is somewhat more interesting because it implies using a stack and character parser to go and find the the character on the right side of the arrow that properly matches up with the character on the lest side of the arrow. So, if we had "(<-->)" and gave it ""(foo (bar))" then it would match "foo (bar)". Finally, I'm still thinking through the <-- and if it's even necessary or if the right arrow would suffice.

One of the main ideas behind this idea (hehe) is that there are no tokens or grammars per se. I want to be able to define as much as I want in these constructs (pseudo-grammars) and then have tailored PHP classes do the real work of validating the code based on the matches found from the arrows in the constructs.

Okay, so assuming I can this far (parsing), how and where do I go from there. Do I try to compile it into some ridiculously ugly PHP code? Further, what problem will this solve? Right now, it seems like I'm only creating problems for the sake of solving them.

Well, assuming the construct system is flexible enough, I think it should be possible to parse a foreign (programming) language given all the right constructs. Maybe I should stop making such grandiose claims and try to actually get some code written. :P

Active Records in the CodeIgniter Framework

About

I've been working on my own PHP5 framework; however, at work I use the CodeIgniter PHP Framework. For the most part, it's a pretty decent framework. Unfortunately, I think that they've made some mistakes in too. One such mistake is how they handle models and their "active records" system. You can find a detailed account of these on a thread I posted over at the CI forums.

Well, my boss wanted to get rid of all of the redundant SQL queries here and there in site we're working on, so I suggested a new active records system to sit on top of the old one. This system goes into the /application/libraries/ directory of CI but is not accessed as a usual one. Here's how a controller using my ActiveRecords extension looks:

< ?php

require_once APPPATH .'/libraries/ActiveRecords/controller.php';

class Ar extends ActiveController {
	public function index() {
		// stuff here
	}
}
?>

The only difference--as you will see if you are a CI user--is that the controllers now extend ActiveController instead of the normal Controller. Extending the controller seemed to be the best choice mainly because it allowed me to give the programmer the choice of using the advanced AR system or not without breaking any old code.

Things that need further Testing

So, one of the neat features that I detail in the above linked forum thread is the DatabaseModelDefinition::prepareSelect() function. It allows the programmer to append things to every SQL query created by the finder. While testing the system out yesterday using relations to join one table to another through two intermediate tables, and then joining one of those intermediate tables on to the final table in the prepareSelect, I needed to hack around with database table prefixes. In the relations, tables will be prefixed as so: l, m0, m1 ... mn-1, r (left, middle, right). Well, if you are joining a table in addSelect against one of the original tables in the relation join, then one would expect <table name>.<column> to work. Unfortunately the table needed to be prefixed with what its prefix was in the relation join. So, I made a quick workaround to that (see: SelectQuery::getTablePrefix()). Finally, to get everything to work, you just need to alias any tables you are joining on to the query from the prepareSelect(). From this description, it could be difficult to visualize this problem.

Documentation

I will try to make some nice CodeIgniter-esque documentation for all of this code and how to use it in the near future. :)

Download

You can go grab a ZIP file of this over at http://ioreader.com/code/CodeIgniter/ActiveRecords.zip.

PHP5 Reflection API

I've been up to some really interesting things with my PHP5 framework. I've got a pretty sweet active records system going on in it. I will dedicate a one or more articles to that later. In the meantime, I was fooling around with PHP's Reflection API to rebuild classes.

One of the main reasons I wanted to do this is because my PHP Manual dashboard widget does have any SPL classes so every time I go up north or don't have access to the internet, I have no way of knowing how to use some of the classes.

What I did was make a very simple function to rebuild as much of the classes as possible. Unfortunately, Reflection doesn't seem to supply the inner code of class methods. The furthest you seem to be able to get is if you have static variables within the function. Although, if anyone knows how to get the contents, that would be great! I was thinking if anything, because line numbers and file names are supplies (but seemingly not for spl classes) that it could just be extracted from the file.

Oh well, here's the little application I made: http://ioreader.com/code/reflection.php. If you want the code, just ask :)