Uncategorized


25
Jul 10

Kohana3: Setting up phpUnit and phpDocumentor

Here is my quick guide on how to setup phpUnit and phpDoc for Kohana 3.

phpUnit

1. Setup

Install phpUnit using pear:

pear install phpunit

(See the PEAR site for how to install PEAR.)
Get the Kohana unittest module from http://github.com/kohana/unittest. If you aren’t using git for your repo, just clone the files (git clone http://github.com/kohana/unittest.git), get rid of the .git subdirectories and copy the module to your modules/ directory.

Follow the setup instructions on GitHub. Some tips:

It may be easiest to define an alternative default database configuration, since currently unittest does not automatically change any of the database configurations (ex. in models). Since I use a Fedora VM for development but prefer to run tests on Windows, I added the following logic to config/database.php:

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
return array('default' => ..test config..);
} else {
return array('default' => ..normal config..);
}

I did the same thing in bootstrap.php, selectively enabling the unittest module and changing the cache dir based on the OS. You can probably think of some way to do the same in your setup even if you aren’t using a different OS for serving HTTP requests.

2. Creating tests

Tests for application files go into the application/tests/ folder you create.

Tests for any module (inc. application, database, unittest etc.) go in the ‘tests’ folder in the module.

Tests extend Kohana_Unittest_TestCase, not PHPUnit_Framework_TestCase.

To group individual tests into modules you need to add the tests to a group for that module. The convention for group names is modules.{module_name}. This is done using the docblock @group specification (can have multiple group specifications). See Writing Tests in the repo on GitHub.

3. Fixtures

The easiest way to create fixtures is to use setUp() to set the DB, then tearDown() to clean up. You can just use the DB class, or use ORM to add the records. Example:

class WhateverTest extends Kohana_Unittest_TestCase {
   function setUp() {
      // setup the DB
      DB::query(NULL, "TRUNCATE `kohana_test`.`whatever`;")->execute();
      $fixture_rows = array(
          array(
            'key' => 'billing_key',
            'value' => '0',
          ),
      );
      // add the necessary items
      foreach($fixture_rows as $row) {
         DB::insert('whatever', array_keys($row))->values(array_values($row))->execute();
      }
   }
   function tearDown() {
   }

There is probably a better way using a proper fixture class, but I haven’t seen one for Kohana yet.

4. Execution

You will need to specify the path to the KO3 webroot index.php as the bootstrap for phpUnit. This is because the dependencies which your code has need to be loaded by Kohana.

By default, all tests in application/tests/ will be run.

phpunit --bootstrap=index.php ./modules/unittest/tests.php

To run a specific group of tests on the cli add –group {groupname.in.testfile} between the –bootstrap switch and the path to the tests folder.

phpunit --bootstrap=index.php --group groupname.in.testfile ./modules/unittest/tests.php

phpDocumentor

Install phpDocumentor using PEAR: pear install phpDocumentor.

On Windows, if you use paths with spaces in them it is easiest to make sure that phpDocumentor is in the php include path (edit php.ini if necessary), and invoke php while passing the phpdoc file directly (see below for example).

You will probably only want to generate API docs for application/, perhaps selectively adding a few modules. And you probably want to exclude: application/vendor/, application/logs/, application/views/, application/bootstrap.php and application/config/ from the API documentation.

Remember that phpDocumentor does not support multiple option specifications: you have to join the paths with a comma. Furthermore, remember to have the directory separator character at the end of directories to trigger the correct interpretation.

Kohana3 uses a number of custom tags, so you will want to exclude those. Here is a sample run:

php "c:\Program Files (x86)\PEAR\phpdoc" --directory application/
--ignore application/vendor/,application/logs/,application/views/,application/bootstrap.php,application/config/ --target doc/api
--customtags type,default,constructor,chainable,class,namespace,module,group

There are a few options that may also prove useful:
–parseprivate causes private methods to be shown
–output HTML:frames:earthli changes the output to earthli, which I like.
–undocumentedelements Adds warnings to errors.html for undocumented elements.


20
Jul 10

Better web application interface markup: lessons from theme frameworks

Every time I start a new web application project, I spend a while (re)thinking what the layout structure should be in terms of CSS and HTML (e.g. semantic naming, organizing CSS markup).

Recently, I did a project using the Thematic theme framework for WordPress, and that got me thinking about how custom web applications interfaces could be improved. As an individual developer, I rarely have the luxury of focusing on the details of the layout. In contrast, the developers building theme frameworks have spent years thinking about how to create a generic, extensible structure for web application interfaces.

I had a look at Thematic, WP-Framework and Theme Hybrid (see more frameworks in this Smashing Magazine article). I used Thematic, since I ended up using it in the WordPress project I did. Here is how Thematic does it’s HTML layout:

An overview of the HTML code (based on Thematic)

I think the most interest parts of Thematic for web application design are the HTML structure, use of ids and classes and the CSS files. The hook-and-filter system (overview here) is less interesting from the web application point of view, since you will most likely be writing all of the code from scratch for your own web applications.

<body class="wordpress y2010 m06 d02 h03 home blog not-singular windows firefox ff3">
<div id="wrapper">
   <!-- Header -->
   <div id="header">
      <div id="branding">
         <div id="blog-title"><span>...</span></div>
         ...
      </div>
      <div id="access">
         <div class="menu"><ul>...</ul></div>          
      </div>
   </div>
   <!-- Main -->
   <div id="main">
       <div id="container">
          <div id="content"><div>...</div></div>
       </div>
       <div id="primary"><ul>...</ul></div>
   </div>
   <!-- Footer -->
   <div id="footer">
      <div id="siteinfo">...</div>
   </div>
</div>
</body>

1. Body and wrapper

In all of the frameworks, the body classes contain various information such as the platform (windows) and the browser (firefox, ff3).

Benefits:
Easier to specify per-browser css fixes (if needed). This makes it easier to make adjustments based on the browser or OS used in CSS, eg. “.windows xxx.yyy { … }”.

Separation between body and content wrapper. In the framework, the content is wrapped in a wrapper layer (id=wrapper), so that the body has only one child element. I would imagine this is to make it easier to use CSS to adjust the padding and background of the pages.

2. Heading

The heading consists of two sub-divs, as shown below:

There are only three subelements to the content wrapper: heading, main and footer. Each of these divs is full-size and positioned relatively.

Benefits:
Easy to add repeating backgrounds. One can easily apply a CSS background-image to create a repeating and consistent heading.

Easy positioning of the elements. The heading consist of the branding and access divs. This makes it easy to add new heading elements in the branding, while keeping the menu (=access div) separate, with it’s own background.

Standard menu HTML. All of the frameworks appear to be using the Superfish menu by default, which is based on jQuery.

3. Main content

The main content consists of a container with a content-sub-div and a primary sidebar:

The main content div has a fixed size. This is then subdivided into two divs, container (for the content) and primary (for the primary menu block).

Benefits:
Semantic markup; floats to reposition Having these separate divs means that switching from “menu on the right” to menu on the left is simple, since one can change the CSS float directions to reverse the positions of the subcontainers.
Easy to add new content areas One could also add more subdiv for additional content areas, and create multiple columns relatively easily by positioning the subdivs within the main content div.
Easy to add sub-items The primary menu is a div, with each block having its own unordered list (ul). In practice, this leads to two levels of lists – one for the item blocks themselves, the other for the sub-items (e.g. the links in a Archives block).

4. Footer

The footer consists of a single subdiv:

Again, the top-level div only specifies the margin, while the inner divs are positioned within it. This makes it easy to add a background to the footer div.

Does this work?

I’m currently using this approach in recent two web applications I built. The markup seems a lot cleaner, more standard and I have found that re-theming the same basic HTML is much nicer than reinventing the wheel. In short, I think this is a good approach. Let me know if you have improvements via a comment.

Somewhat related: What about other techniques, such as CSS Grid frameworks or Haml/Sass?

I’m not yet convinced that I need to use a CSS Grid framework (e.g. Stackoverflow discussion).

As for Haml, I’m pretty sure that I am fine with regular HTML without any syntactic sugar.

Sass seems to be a real improvement over CSS (variables, nesting, mixins etc.), but on the other hand I haven’t had the time to set it up with my non-Ruby environment.


10
Jul 10

Quick tip: Netbeans is excluding / ignoring directories in version control

Is Netbeans not showing the version control options correctly for some of your directories? Check whether you have accidentally left .svn directories. All source control system directories are hidden by default in Netbeans, which makes spotting this a bit tricky.

Check for whether there is a another repo, e.g. a .svn directory somewhere in your path. Netbeans seems to allow “stacking” source control systems, and will unsuccessfully try to load this versioning data instead of whatever you are using in your repository. This means that you won’t get those pretty markers for modified lines and won’t be able to view history for those files or perform a diff from the Netbeans GUI.

See ~/.netbeans/$version/var/log/messages.log for debugging information. Look for messages related to source control loading failures.

Get rid of the extra directories (e.g. .svn in each directory) in your repo, and delete ~/.netbeans/$version/var/cache/svncache to avoid conflicts with cached incorrect versioning data.


6
Jun 10

Quick tip: how to fix “mysqlnd cannot connect to MySQL 4.1+ using old authentication” onPHP5.3

I recently upgraded to PHP 5.3 on Windows, and ran into this problem:

Warning: mysql_connect(): OK packet 6 bytes shorter than expected in ...
Warning: mysql_connect(): mysqlnd cannot connect to MySQL 4.1+ using old authentication in ... 

I run my Linux servers on VMWare when I do development, so the MySQL database itself was from quite a while ago. As you will see, the core issue here is that MySQL can have passwords with hashes stored in the old 16-character format, which is not supported by PHP 5.3′s new mysqlnd library.

Since I couldn’t find a good solution with a quick Google, here is how I solved this without having to downgrade PHP or MySQL (as some of the solutions suggested):

1. Change MySQL to NOT to use old_passwords

It seems that even MySQL 5.x versions still default to the old password hashes. You need to change this in “my.cnf” (e.g. /etc/my.cnf): remove or comment out the line that says

old_passwords = 1

Restart MySQL. If you don’t, MySQL will keep using the old password format, which will mean that you cannot upgrade the passwords using the builtin PASSWORD() hashing function. You can test this by running:

 SELECT Length(PASSWORD('xyz'));  
+-------------------------+
| Length(PASSWORD('xyz')) |
+-------------------------+
|                      16 | 
+-------------------------+
1 row IN SET (0.00 sec)

The old password hashes are 16 characters, the new ones are 41 characters.

2. Change the format of all the passwords in the database to the new format

Connect to the database, and run the following query:

SELECT user,  Length(`Password`) FROM   `mysql`.`user`;

This will show you which passwords are in the old format, ex:

+----------+--------------------+
| user     | Length(`Password`) |
+----------+--------------------+
| root     |                 41 | 
| root     |                 16 | 
| user2    |                 16 | 
| user2    |                 16 | 
+----------+--------------------+

Notice here that each user can have multiple rows (one for each different host specification).

To update the password for each user, run the following:

UPDATE mysql.user SET Password = PASSWORD('password') WHERE user = 'username';

Finally, flush privileges:

FLUSH PRIVILEGES;

31
May 10

WordPress 3.0 multi-site multi-domain problems with solutions

Here are some problems I ran into when setting up WordPress 3.0 with multiple different domains, along with how I solved them. I figured it’s better to get them out on the blog now, and update this post if/when I have more solutions.

Problem 1: I can’t load page URLs except when using ?p=xyz permalinks

If you are having problems with page URLs not working on multisite domains, make sure you have:

    AllowOverride FileInfo Options

defined in your httpd.conf for the directory the Virtual host is in.

Problem 2: The new themes I installed and activated on the main WP 3.0 site do not show up on separate domains

The permissions for separate domains do not get automatically updated when you activate themes on the main site.

In MySQL, copy the value for “allowedthemes” in the wp_sitemeta table. This will enable themes on separate domains. Example:

INSERT INTO `wordpress_database`.`wp_sitemeta` (`meta_id`, `site_id`, `meta_key`, `meta_value`) VALUES (NULL, '2', 'allowedthemes', 'a:2:{s:9:"it-oikeus";b:1;s:9:"twentyten";b:1;}');

where the site_id is the site ID for the separate domain, and meta_value is copied from the first site.

Problem 3: I cannot access Plugins on separate domains

In MySQL, copy the value for “menu_items” in the wp_sitemeta table. This will enable plugins on separate domains. Example:

INSERT INTO `wordpress_database`.`wp_sitemeta` (`meta_id`, `site_id`, `meta_key`, `meta_value`) VALUES (NULL, '2', 'menu_items', 'a:1:{s:7:"plugins";s:1:"1";}');

where the site_id is the site ID for the separate domain, and menu_items is copied from the first site.

Problem 4: New users are not visible on separate domains

in wp_usermeta, set:

wp_2_capabilities = a:1:{s:13:”administrator”;s:1:”1″;}
wp_2_user_level = 10

(NEW June/2010) Problem 5: Upload files not working on separate domains

Replace site_id (2) with your site id in the query below:

INSERT INTO `wordpress_database`.`wp_sitemeta` (`meta_id`, `site_id`, `meta_key`, `meta_value`) VALUES (NULL, '2', 'upload_filetypes', 'jpg jpeg png gif midi mid aac ac3 aif aiff m3a m4a m4b mka mp1 mp2 mp3 ogg oga ram wav wma asf avi divx dv flv m4v mkv mov mp4 mpeg mpg mpv ogm ogv qt rm vob wmv doc docx docm dotm odt pages pdf rtf wp wpd numbers ods xls xlsx xlsb xlsm key ppt pptx pptm odp swf asc csv tsv txt bz2 cab dmg gz rar sea sit sqx tar tgz zip css htm html php js
');

23
May 10

Upgrading / moving WordPress 2.9 installs to multisite WP 3.0

In the previous blog post I discussed how the multi-site functionality in WP 3.0 can be enabled and how it can be hacked to use multiple different domains. Now, let’s have a look at how you can migrate all of your old WP 2.9 sites under a single WP3.0 installation.

The basic steps are:

  1. Move posts
  2. Move attached files
  3. Fix URLs in posts
  4. Move/recreate users

1. Moving the posts from WP 2.9 to 3.0

Moving the posts, links, comments and terms to WP 3.0 is quite easy. A table-by-table comparison shows that the main tables have identical structures (comparison between a 2.9.2 site and 3.0 beta 2). This means that we can use SQL for the migration. Alternatively, you could export and import (see the functionality under Tools -> Export / Import).

In WP 3.0, the tables are sharded – each blog has it’s own set of tables, and the id of the blog is used as a part of the table name: for example, wp_2_commentmeta is the wp_commentmeta table for the multisite blog with id=2. Find out what the blog_id for your blog is, and use it in the SQL queries below.

I performed the following queries, which move all the tables EXCEPT the options table. Moving the options table seems to result in a broken blog, since the themes, settings and plugins referenced by WordPress will not exist in the new environment.

TRUNCATE newblog.wp_2_commentmeta;
INSERT INTO newblog.wp_2_commentmeta SELECT * FROM oldblog.wp_commentmeta;
 
TRUNCATE newblog.wp_2_comments;
INSERT INTO newblog.wp_2_comments SELECT * FROM oldblog.wp_comments;
 
TRUNCATE newblog.wp_2_links;
INSERT INTO newblog.wp_2_links SELECT * FROM oldblog.wp_links;
 
TRUNCATE newblog.wp_2_postmeta;
INSERT INTO newblog.wp_2_postmeta SELECT * FROM oldblog.wp_postmeta;
 
TRUNCATE newblog.wp_2_posts;
INSERT INTO newblog.wp_2_posts SELECT * FROM oldblog.wp_posts;
 
TRUNCATE newblog.wp_2_terms;
INSERT INTO newblog.wp_2_terms SELECT * FROM oldblog.wp_terms;
 
TRUNCATE newblog.wp_2_term_relationships;
INSERT INTO newblog.wp_2_term_relationships SELECT * FROM oldblog.wp_term_relationships;
 
TRUNCATE newblog.wp_2_term_taxonomy;
INSERT INTO newblog.wp_2_term_taxonomy SELECT * FROM oldblog.wp_term_taxonomy;

What if these queries fail?

Some WordPress plugins modify the default tables – which means there are extra fields that need to be ignored. If the INSERT INTO statements below don’t work for you, you need to explicitly state the names of the source and destination fields instead of using *. This means losing the added fields, so you need to think about it on a case-by-case basis. See the MySQL docs for INSERT INTO … SELECT syntax.

2. Moving attached files

WP 3.0 uses a slightly different directory structure for multisite. The files for each blog are under blogs.dir/[blog_id]/, and use the same substructure as before. Hence, the new directory structure is like this:

/wp-content/blogs.dir/[blog_id]/files/...

and if you keep using the same structure (ex. “year/month/filename”) you can just copy the files:

mkdir -p ./wp-content/blogs.dir/[blog_id]/files/
cp -R ./oldblog/wp-content/uploads/* ./newblog/wp-content/blogs.dir/[blog_id]/files/

3. Fixing URLs in posts

Try loading a post with images. The URLs (may) change from:

http://blog.domain.com/wp-content/uploads/2010/04/image.png

to:

http://blog.domain.com/files/2010/04/image.png

You can fix this by performing a replace on the wp_[blog_id]_posts table:

UPDATE wp_2_posts SET guid = REPLACE(guid, "http://oldblog.domain.com/wp-content/uploads", "http://blog.domain.com/files");
UPDATE wp_2_posts SET post_content_filtered = REPLACE(post_content_filtered, "http://oldblog.domain.com/wp-content/uploads", "http://blog.domain.com/files");
UPDATE wp_2_posts SET pinged = REPLACE(pinged, "http://oldblog.domain.com/wp-content/uploads", "http://blog.domain.com/files");
UPDATE wp_2_posts SET post_excerpt = REPLACE(post_excerpt, "http://oldblog.domain.com/wp-content/uploads", "http://blog.domain.com/files");
UPDATE wp_2_posts SET post_content = REPLACE(post_content, "http://oldblog.domain.com/wp-content/uploads", "http://blog.domain.com/files");

If you also changed the domain, you need to fix the links (do this after you fix the file upload paths):

UPDATE wp_2_posts SET guid = REPLACE(guid, "http://oldblog.domain.com", "http://blog.domain.com");
UPDATE wp_2_posts SET post_content_filtered = REPLACE(post_content_filtered, "http://oldblog.domain.com", "http://blog.domain.com");
UPDATE wp_2_posts SET pinged = REPLACE(pinged, "http://oldblog.domain.com", "http://blog.domain.com");
UPDATE wp_2_posts SET post_excerpt = REPLACE(post_excerpt, "http://oldblog.domain.com", "http://blog.domain.com");
UPDATE wp_2_posts SET post_content = REPLACE(post_content, "http://oldblog.domain.com", "http://blog.domain.com");

4. Moving the users

You can either 1) manually create new user accounts for your users, or 2) try to move the user accounts. Most blogs don’t really have many users beyond the admin, since commenting doesn’t need a user account. My recommendation would be to manually add the very few users you have.

If you want to move the users in bulk using SQL, then you will need to take into account that:

  1. In WP 3.0, the wp_users table is shared among all the sites.
  2. The wp_users table in WP 3.0 has two extra fields: spam and deleted.
  3. Each blog site has its own wp_capabilities, wp_user-settings and wp_user-settings_time fields (e.g. wp_2_capabilities) in the wp_users table. The format (serialized PHP arrays) appears to be the same, so you will need to create one user with the rights you want manually, then these three keys for each of the blogs you want to user to be able to access.

I didn’t try this out, since the blogs I have only use a small number of users. I just created individual admin accounts for those blogs that I am not administering personally.


17
May 10

Setting up multisite WordPress 3.0 with multiple different domains

WordPress 3.0 is coming out very soon (apparently they missed their original deadline, see the schedule here) – and it has one killer feature for anyone who maintains multiple WordPress sites: official support for multiple subdomains and (unofficial) support for multiple different domains. This means that one only has to maintain and upgrade one WordPress installation.

Here is my guide to setting up WordPress 3.0 with multiple different domains and subdomains – based on the experience I got from moving my own blogs to WP 3.0 beta 2 (still waiting for the final release before moving clients as well).

Installing WordPress 3.0

The basic installation process is the same as that of WP 2.9. Download, unzip, set up the database and the set up wp-config.php. If you aren’t going to use the multi-site support, then not much will change. Brief instructions below.

Multi-site mode with Apache

You will need to separately enable the multi-site mode, as well as take care of your Apache settings. WP 3.0 will handle all the requests it gets from a single directory, which means that all your subdomains must use that directory as their DocumentRoot/VirtualDocumentRoot.

Furthermore, WP 3.0 will assume that if you are using multi-site mode with subdomains, you want the subdomains under the first site’s URL – ex. if your first WP 3.0 install is under www.domain.com, then WP 3.0 will set up subdomains in the format subdomain1.www.domain.com.

That means that if you want to use first-level subdomains (ex. blog.domain.com, subdomain2.domain.com etc.), you have to set up WP 3.0 so that your first blog is using the bare domain (ex. domain.com) and not on the www.domain.com subdomain.

0. (Optional) Bare domain setup for Apache

The way in which you setup your bare domain (and forward from the www -subdomain to the bare domain) depends a lot on how you have set up your domain originally in Apache.

I have been using virtual hosts to host multiple sites, with each subdomain having its own directory. This means that I had to add an additional Vhost directive before my original Vhost directive in httpd.conf. Here is how I did it:

    ServerName domain.com
    ServerAlias domain.com blog.domain.com subdomain1.domain.com
    DocumentRoot /var/www/domain.com/www

As you can see in the first Vhosts directive, I have used the ServerAlias directive to specify domain.com, blog.domain.com and subdomain1.domain.com to be served from the DocumentRoot /var/www/domain.com/www (which is where I have installed WP 3.0).

In addition, I still have the rest of my subdomains served from a VirtualDocumentRoot, and have a forward from the www.domain.com -subdomain to the domain.com bare domain.

    ServerName domain.com
    ServerAlias *.domain.com
    VirtualDocumentRoot /var/www/domain.com/%1
    # rewrite www to bare domain
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
    RewriteRule (.*) http://domain.com$1 [R=301,L]

Apache will use the first matching VirtualHost directive (see “An in-depth discussion of Virtual Host Matching” for more details).

If you want to test your setup – remember to restart Apache – you can use an online redirect checker such as: http://www.internetofficer.com/seo-tool/redirect-check/

1. Get the files and unzip them

2. Edit wp_config_sample.php

You can use https://api.wordpress.org/secret-key/1.1/salt/ to generate the secret keys

3. Enable multisite

Add:

 define(’WP_ALLOW_MULTISITE’, true);

to wp-config.php after the secret keys

4. Log in, go to Tools/Network

Select either the blogs-as-subdomains or blogs-as-directories option and install.

5. Make the changes detailed on the post-install page

WP 3.0 gives you a number of changes you will need to make manually to .htaccess and wp-config.php.

Adding a new subdomain

You have now set up the multisite functionality. Next, add a subdomain (see below for how to add a different domain).

1. Login in on your main site

2. Go to Super Admin (new menu at the top)

3. Use the add site form to add a new subdomain

4. Configure your DNS and add a Vhost for the subdomain

Make sure there is a DNS entry for your subdomain – if you don’t have a wildcard redirect for your domain to your server. If you did the Apache configuration, all you need to do now is to set up your DNS so that the subdomains you want are mapped to your server.

Quick tip for Windows: edit C:\Windows\System32\drivers\etc\hosts and add a temporary hosts entry for your new subdomain, such as:

123.14.15.16 subdomain.domain.com

This will allow you to test the subdomain without having to wait for DNS to propagate. Under Win7, you need to start Notepad as an Administrator (right-click) to edit the file.

5. All done!

Try navigating to your new subdomain. It should be set up now!

Adding a new (different) domain

1. Use the add site form to add a new subdomain

You will use the default tools to create all the tables, then you will make a small number of changes to make WordPress accept a different domain. All credit for this method goes InterconnectIt – see their writeup here.

2. Configure your DNS and add a Vhost for the subdomain

The easiest way is to add another ServerAlias domain to the original domain’s VirtualHost -> ServerAlias directive.

If you try to access the site now, you will get a “Registration” page. This means the Vhost is working.

3. Edit the wp_site table to include your new domain

This table stores all the domains that can be used in WP 3.0.

Leave “id” empty (it is an autoincrement field), set “domain” to the domain name, “path” should be /.

Make a note of the id your newly inserted row gets after saving, since you will need it in the next step.

4. Edit the wp_blogs table to use the new domain

Find the row for the subdomain you added earlier. Change “site_id” to the id given to the new row in the wp_site table. Change “domain” to the domain name you want to use.

5. Edit wp_[blog_id]_options to use the new domain name

The WP 3.0 multisite database schema is sharded by having the blog id in the table names. By default these are in the form wp_[blog_id]_*, so you will need to find which set of tables contains your new blog.

Each WordPress blog stores a small number of settings which need be changed to use the new domain name. You can use the query below to find the mentions of the domain in the options table:

SELECT * FROM `wp_[blog_id]_options` WHERE `option_value` LIKE "%subdomain.domain.com%";

For me these are: siteurl, home, fileupload_url. Change them to use the new domain.

6. Done!

Do you need to move an existing WP 2.9 to WP3.0 multisite? If you are moving an existing site to the WP multisite you’ve set up, check out my second tutorial on the topic.

Did you run into problems enabling themes or plugins on your separate domains? Have a look at how I solved a number of issues related to the separate domains setup.

References

  1. http://www.interconnectit.com/840/wordpress-3-0-multisite-with-multiple-domains-setup/

3
May 10

Syntax highlighting / color schemes for Netbeans

There are two important things to try out in picking the IDE settings that work best for you: 1) the font you use and 2) the color scheme for syntax highlighting.

Choice of font

My font of choice is Consolas (included in Vista/Win7 and available for download). It looks awesome with ClearType and the zero character is different from the letter O. My second choice is Bitstream Vera Sans Mono, which is free and widely available.

The Code Project has a great compilation of the 42 best programming fonts.

Choice of color

The basic choice is between a dark background and a light background. Full contrast schemes are considered more hard to read, which means that slightly off-white or off-black backgrounds are easier to read.

Personally, I prefer white or off-white with dark text. Jeff Atwood did some background reading into this and quotes from a study that “When light text is placed on a dark background the text may seem to glow and become blurred; this is referred to as halation, and it may make the text harder to read.” Subjectively, I find white text on dark backgrounds to be a bit uncomfortable.

“If everything is important, then nothing is important”. This was mentioned in Garret Dimon’s Application Interface Design presentation, and I think it is a good point: Don’t highlight every syntactically different part of the code with sharp colors, just the stuff that matters the most. For me, these would be the keywords, variables and class names.

Hence I changed comments to be de-emphasized (gray) as well as any HTML tags (which are less important than the code in views). I am experimenting with a off-white background to slightly reduce contrast and eyestrain.

My color scheme:

See what my color scheme looks like at the bottom of the post. You can download it for NetBeans here.

More color schemes:

Whether or not you use Visual Studio (I use Netbeans), go check out the great gallery of syntax coloring schemes at studiostyles. They have dozens of user-submitted color schemes and alternatives which you can use as a basis for configuring your own IDE.


15
Mar 10

7 additional tips for CSS markup

1. Use a test page

Make a test page that has:

  1. All of the common HTML elements
  2. All of your widgets and inline elements

… on one page. This allows you to make and preview changes quickly.

Snippllr.com has a couple of test pages containing the major HTML elements:

http://snipplr.com/view/8121/html-test-page-for-css-style-guide/
http://snipplr.com/view/12564/css-test-page/

2. Start with a CSS reset

Using a CSS reset helps because it eliminates the inconsistencies between browsers and forces you to specify all of the styles you want. It makes CSS stylesheets more explicit, which is a good thing for maintainability.

http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/

http://developer.yahoo.com/yui/reset/

3.Order your rulesets into sections – generic to specific

Use stylesheet rule order to define “base” and “special case” tags. First, organize your CSS rules into sections so that the most generic rules (e.g. typography) come first before specific rules such as widgets. This is useful because it makes it easier to locate rules within the file and to make modifications.

For example, I have used the following sections:

  1. Base/reset styles (Yahoo’s CSS reset rules)
  2. Typography styles (inline elements applied to the whole page such as fonts, links, headings, paragraphs)
  3. Layout (fixed containers, blocks of content and other “website-specific” positioning)
  4. Widgets (ex.  informational messages, contextual help, menu lists, collapsible navigation list, tabs, table styles…)

4. Order your widget rules from “base” to “special case”

Organize the rules into “base” widgets and “special case” if necessary. Have the “base” widget specify the most important rules, and then override for the “special case”.

5. Indent your CSS files!

Use indentation to organize the code – the first level of indentation is for sections, the second for widgets and the third for special cases of widgets or sub-widgets. (If you are concerned about bandwidth, use a CSS minifier afterwards – don’t sacrifice understandability just to try to save a few characters).

For example:

/** Css reset **/
/** Base styles **/
   ...
/** Typography styles **/
   ...
/** Layout styles **/
   /** Containers **/
   ...
/** Widgets **/
   /** Information messages **/
   ...
   /** Tabs widget **/
   div.tabs {
      ...
   }
   div.tabs ul {
      ...
   }
   div.tabs ul li {
      ...
   }
   div.tabs ul a:link, div.tabs ul a:visited {
      ...
   }
   div.tabs ul li.selected a, div.tabs ul a:hover {
      ...
   }

6. Keep the dependency chains as short as possible

Avoid modifying the HTML element styles without specifying a class. Adding styles to tags without a class -attribute is problematic because it makes the dependencies much more complex.

By keeping dependency chains short – so that the base CSS is unmodified and all necessary styles are defined on a class-specific level –  you keep the dependencies reasonably simple.

7. Never rely on coincidental nesting & avoid “class-itis”

“Class-itis” is the disease that causes CSS files to have too many classes. Instead, use tag nesting to create widgets.

Have single base element with a simple but descriptive class name, and then specify the sub-elements.

For example:

  • Instead of “div.content-title” use “#content h1″ (e.g. div#content with a h1 tag inside it)
  • Instead of “div.form-label” use “#form label” (e.g. form#form with a label tag inside it)

24
Feb 10

Options for securing PHP in a shared virtual hosting environment

The terms and options for implementing security measures can be quite confusing. This blog post is a survey of the options available, including some possible pros and cons and definitions of relevant terminology.

It is very typical to run multiple sites on a single server, since it would be overkill to run each small website and blog on its own VPS instance. The default Apache setup: mod_php and prefork-mpm does not offer any privilege separation or hardening for virtual hosts. Hence the need for additional security measures.

What are the general approaches taken to securing PHP?

The approaches taken in securing PHP can be divided into two broad categories:

  1. Hardening PHP. This approach aims to improve the security of PHP scripts by limiting dangerous functionality on a site-by-site basis and by preventing flaws from escalating through additional patches to the PHP core. The main examples are: a) tweaking PHP core settings such as open_basedir and b) running a version of PHP which includes additional options to limit functionality and prevent flaws such as buffer overflows (Suhosin).
  2. Privilege separation. This approach limits the extent to which other sites can be damaged if one of the websites on the shared server is compromised. There are several solutions, including mod_suPHP and suEXEC.

How can PHP and Apache interact?

There are several ways in which PHP and other scripts can be invoked by Apache:

  • CGI (Common Gateway Interface) is a standard protocol that defines how webserver software can delegate the generation of webpages to a console application. It operates on a “one new process per request” basis.
  • FastCGI is a protocol introduced in the mid-1990s that improves upon the older CGI protocol. It allows a single persistent process pool to handle multiple requests over its lifetime, reducing overhead.
  • In-process as an Apache module, such as the default mod_php.

The default interaction between PHP and Apache is handled by the mod_php module. The most common ways of implementing privilege separation use either CGI or FastCGI to interface with PHP. PHP supports both CGI and FastCGI protocols.

Privilege separation can be done either:

  1. by using CGI scripts and suEXEC, a feature built in Apache
  2. by using Apache modules that make invoking CGI scripts easier
    • Apache modules are bundles that can be loaded to add new functionality to Apache. They are integrated into the Apache server and add new functionality to instances of the server, such as the capability to interpret PHP scripts.
    • Examples: mod_php, mod_suPHP, mod_fastcgi and mod_fcgid.
  3. by using Apache MPMs that support privilege separation
    • Apache MPMs (Multi-Processing Modules) are responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests. There are several different MPMs – the Unix platform default is the prefork mpm.
    • Examples: prefork, worker, perchild, mpm_itk, mpm_peruser

What are the options for privilege separation?

suEXEC

suEXEC is a feature built into Apache, but not included in the default Apache installation. It makes all CGI scripts execute with the user id and permissions of their owners. It can be used with PHP and with other CGI scripts.

It consists of a setuid “wrapper” binary that is called by the main Apache web server, and which executes CGI scripts with the correct used id.

+ Tried and tested

+ Can be used with other languages than PHP

- Low performance without FastCGI (similar to suPHP)

- Separate script files are a minor hassle

Module: mod_suPHP

mod_suPHP makes PHP scripts execute with the user id and permissions of their owners.

It consists of an Apache module (mod_suphp) and a setuid root binary (suphp), which calls PHP as a CGI process.

+ Easy to install, in RPMForge repo (http://wiki.centos.org/AdditionalResources/Repositories/RPMForge)

+ Quite commonly used

- Low performance relative to others (similar to suEXEC)

- PHP specific solution

= Recommended for low load sites which are not using their resources to their limits.

Module: FastCGI (mod_fastcgi or mod_fcgid)

mod_fastcgi and mod_fcgid implement process persistence between page views and communicate with PHP using FastCGI. They do not by themselves perform privilege separation, suEXEC is needed.

+ Decent performance when using suEXEC with FastCGI, similar or better performance than mod_php has been reported

+ Can be used with other languages than PHP

- FastCGI may require more memory because there are more persistent processes (more suited for servers with a lot of memory)

- Separate script files are a minor hassle

= Recommended for higher load sites.

MPM: mpm_itk and mpm_peruser

These are alternative MPMs for Apache that replace the default preform MPM and perform additional privilege separation.

mpm_itk works in a manner similar to regular CGI scripts in that it does not reuse processes after each request. However, unlike CGI scripts, it invokes each process with the user id and group specified for that virtual host.

+ Neat solution with decent performance, some systems have it in the repos

- Must patch and compile separately in Centos

- Not as commonly used as suEXEC or suPHP

= Recommended as a upcoming solution that is higher performance than mod_suPHP and easier to setup than suEXEC+FastCgi.

mpm_peruser creates one or more apache child processes for each unique user/group, each handling its own set of virtual hosts.

+ Faster than mpm_itk

- Must patch and compile separately in most systems

- Development and adoption seems to be more limited than mpm_itk