Sivel.net  Throwing Hot Coals


Manually Install Silverlight On Mac

A few weeks ago Aaron Brazell mentioned on Twitter that he had been unable to run Silverlight on his brand new Macbook Air:

This intrigued me, as many random things do. I love attempting to resolve obscure issues, and after watching him struggle for a few days I decided to help out. I spent about an hour, and learned some really cool things about the installation process for Mac apps packaged as ‘.pkg’ files, and how to go about installing them manually.

I had a hard time finding the information anywhere, and figured that, while this is somewhat specific to Silverlight, that it may be useful to others.

Although I use a Mac, and love the beauty of it’s UI, I spend most of my time on the command line. I am a Linux Systems/DevOps Engineer by trade, so I of course interact with most of my daily tasks from the command line.

I needed to download a copy of the Silverlight.dmg file, but quickly found that if you hit the Silverlight site, and already have Silverlight installed you couldn’t get to the download. Fortunately they link you to an uninstall page on their site, so I just deleted the paths specified there:

rm -rf /Library/Internet\ Plug-Ins/Silverlight.plugin /Library/Receipts/Silverlight.pkg /Library/Receipts/Silverlight_W2_MIX.pkg /Library/Internet\ Plug-Ins/WPFe.plugin /Library/Receipts/WPFe.pkg

I restarted my browser, hit the Silverlight site again, and downloaded the Silverlight.dmg file. I did take this opportunity, to inspect my HTTP requests from my browser, and determined the actual URL where the file lives for future reference.

After downloading and double clicking to mount, you can just navigate directly into /Volumes/Silverlight/Silverlight.pkg from the command line. On Mac ‘.app’ and ‘.pkg’ as well as many other items that appear to be files, are actually just specially named directories. Mac styles them to look like files. If you really want, you can right click on such an item and select ‘Show Package Contents’.

Once inside, I took a look around, and quickly noticed that the Contents/Archive.pax.gz file was where the majority of the data was located based on size, and looking in the Contents/Resources directory, I found some simple shell scripts and perl scripts.

There is an InstallationCheck perl script, that is used to validate that your system meets the requirements. After looking into it, I couldn’t determine why it would fail to succeed, and neither could Aaron. Attempting to modify this file and install, resulted in the installer reporting some generic error, which was the result of the signature of the InstallationCheck file being different than the stored value. With that option gone, I took a look at the other files.

I found preflight was a shell script version of the uninstall instructions on the site. And postflight went around cleaning some things up and generating CPU specific optimized libraries for Silverlight to use, as opposed to just-in-time compilation.

Back to Archive.pax.gz

I quickly recognized the ‘.gz’ extension, as that is a standard gzip file extension. I however, did not recognize the ‘.pax’ file extension, although after reading a little about it), I am a little surprised I didn’t.

In any case, after gunzipping and unarchiving using pax, You basically get a directory hierarchy that can be dropped into the root (/) partition on your Mac. So to keep from wasting any more of your time, let’s get on to the actual steps to get it working:

Note: I wouldn’t try just copy/pasting that whole block. Run each command separately to avoid potential issue.

cd ~/Downloads
curl -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" \
    -Lo Silverlight.dmg http://www.microsoft.com/getsilverlight/handlers/getsilverlight.ashx
hdiutil attach Silverlight.dmg
cp -r /Volumes/Silverlight/Silverlight.pkg ~/Downloads/Silverlight.pkg
hdiutil detach /Volumes/Silverlight
cd ~/Downloads/Silverlight.pkg/Contents/
sudo ./Resources/preflight
gunzip Archive.pax.gz
pax -r -f Archive.pax
sudo cp -r Library/ /Library/
cd Resources/
sed -i '.bak' -e 's/rm\ -rf\ coregen.*)/)/' postflight
sudo PACKAGE_PATH=~/Downloads/Silverlight.pkg ./postflight

Close your web browser(s) and reopen visiting the following URL to test Silverlight: http://www.microsoft.com/getsilverlight/default.aspx

At this point you should have a Silverlight working on your Mac, or at least it was for Aaron:

That Github Gist, still exists, and contains the same steps as outlined above.

Most of those instructions are pretty self explanatory, the one that is not is probably the sed command. Basically in postflight it kicks off a number of commands into the background that utilize a binary called coregen_i386. It also deletes the coregen_i386 binary. In my testing I found that it often deleted the coregen_i386 binary before all of the coregen_i386 commands had executed, causing some of them to fail. So the sed command does an inplace edit of the postflight file to remove the rm -rf commands to delete the coregen_i386 and coregen_x86_64 binaries.

Anyway, hopefully this helps someone else. Enjoy!

HowTo Mac Questions Technology

WordPress Caching Comparisons Part 2

This post has been on my mind for quite some time now, ever since I wrote Part 1 over 1 year ago.

Part 1 only really addressed opcode 1 and Object caching 2 and didn’t really touch page caching 3. In this post I have revisited all tests and added in comparisons of using both the APC Object Cache + Batcache plugins as well as using the W3 Total Cache plugin.

Tests

  • No opcode, no caching
  • APC opcode, no caching
  • APC opcode, APC object caching plugin
  • APC opcode, W3 Total Cache APC object caching
  • APC opcode, APC object caching plugin, Batcache page caching
  • APC opcode, W3 Total Cache APC object and page caching

Comparison Stats

  • PHP generation time 4
  • Number of include/include_once/require/require_once calls 5
  • Number of stat() calls per dtruss/strace 6
  • cURL time to start transfer 7
  • Apache Bench (ab) tests for concurrency 8 and requests per second

For the above stats gathering, with PHP generation time and cURL time to start transfer, 102 sets were collected, the first 2 were dropped due to cache priming, the remaining 100 were used, and averaged. With the Apache Bench tests, 12 sets were used, dropping the highest and lowest value, and averaging across the remaining 10. Include and stat() counts were gathered over 5 sets not requiring averaging as they were the same between runs.

To find the optimal concurrency and req/s for Apache Bench, I performed manual testing, visually inspecting the results until I reached what I classified as a “sweet spot”. Using the “sweet spot” stats, I performed additional sets to gather the averages for requests per second.

The Setup

  • 256MB Rackspace Cloud Server
  • Ubuntu 11.04 amd64
  • Apache 2.2.17 - Default Ubuntu Install, no modifications, default document root located at /var/www
  • PHP 5.3.5 (mod_php) - Default Ubuntu Install, no modifications
  • PHP APC 3.1.3p1 - Default Ubuntu Install, no modifications
  • MySQL 5.1.54 - Default Ubuntu Install, no modifications
  • WordPress 3.3-beta4-r19470 - Default Install, requests made to the “home” page
  • APC Object Cache trunk version
  • Batcache trunk version
  • W3 Total Cache 0.9.2.4

I have not compared static file caching yet and hope to compare W3 Total Cache and WP Super Cache in the future. In this comparison I am mainly focusing on opcode, object caching and page caching.

I am going to try to keep this comparison about the stats only, and not make this a critique or review of the plugin, although in some cases this will not be possible.

Test Data

No opcode and no caching:
PHP Generation Time: 0.13787 seconds
Number of includes: 80
Number of stat calls: 266
cURL time to start transfer: 0.15463 seconds
Apache Bench Concurrency: 15
Apache Bench Requests Per Second: 19.1483 req/s

APC opcode and no caching:
PHP Generation Time: 0.05088 seconds
Number of includes: 80
Number of stat calls: 148
cURL time to start transfer: 0.05673 seconds
Apache Bench Concurrency: 60
Apache Bench Requests Per Second: 68.2636 req/s

APC opcode and APC Object caching:
PHP Generation Time: 0.03407 seconds
Number of includes: 81
Number of stat calls: 148
cURL time to start transfer: 0.03975 seconds
Apache Bench Concurrency: 260
Apache Bench Requests Per Second: 77.7214 req/s

APC opcode and W3TC APC Object caching:
PHP Generation Time: 0.03993 seconds
Number of includes: 102
Number of stat calls: 285
cURL time to start transfer: 0.04591 seconds
Apache Bench Concurrency: 200
Apache Bench Requests Per Second: 67.581 req/s

APC opcode and APC Object and Page caching with Batcache:
PHP Generation Time: N/A
Number of includes: Unable to collect
Number of stat calls: 41
cURL time to start transfer: 0.00316 seconds
Apache Bench Concurrency: 600
Apache Bench Requests Per Second: 147.2156 req/s

APC opcode and W3TC APC Object and Page caching:
PHP Generation Time: N/A
Number of includes: Unable to collect
Number of stat calls: 87
cURL time to start transfer: 0.00625 seconds
Apache Bench Concurrency: 500
Apache Bench Requests Per Second: 147.8425 req/s

Conclusions

I can state the following about just enabling APC in PHP, if you do nothing else, you should at least do this:

  1. 170% PHP generation time improvement by enabling APC opcode caching
  2. 172% Time to start transfer improvement by enabling APC opcode caching
  3. 300% concurrency improvement by enabling APC opcode caching
  4. 256% requests per second improvement by enabling APC opcode caching

I see performance improvements using both APC+Batcache and W3 Total Cache. However, in all tests, APC+Batcache seems to outperform W3 Total Cache, in PHP generation time, number of includes, number of filesystem stat() calls, time to start transfer, number of concurrent requests and requests per second with relation to concurrency.

I was able to push APC+Batcache to 700 concurrent requests, but req/s dropped. W3TC capped out at 500 concurrent requests, and would go no further, however 500 requests per second provided the highest req/s for W3TC.

W3TC does provide a lot of additional functionality to help reduce load on the server, such as tweaking client side caching, and using a CDN, where APC+Batcache does not, although there are small unitasking plugins that can add the missing functionality for you such as:

APC+Batcache consists of adding 3 new files, and no new directories. The W3TC download consists of 60 new directories and 351 files. The directory listing level for W3TC being as deep as it is, 5 levels deep past the directory for the plugin itself, causes a significant increase in filesystem stat() commands.

Most shared hosting providers as well as many multiserver environments will often host their web roots on NFS, and the more filesystem stat() calls, the worse performance you will see, especially under higher load.

Something else to note, is a lot can be done on the server to also improve performance. You can also use caching applications that logically sit in front of the webserver to cache, instead of using caching plugins, which will also improve performance. There are probably eleventy billion ways to improve performance, so if in doubt, consult an expert to help.

Notes:

  1. opcode: A technique of optimizing the PHP code and caching the bytecode compiled version of the code, to reduce the compilation time incurred during PHP code execution #
  2. Object Caching: An in memory key-value storage for arbitrary data, to reduce processing, and storage of external calls to speed up retrieval and display of information #
  3. Page Caching: Full caching of HTML output for web pages #
  4. PHP generation time: The amount of time taken to compile and execute the PHP code into the resulting HTML #
  5. Include/Require Count: The number of calls to the PHP include, include_once, require and require_once functions, which are used to load a separate file #
  6. stat() call count: The number of unix system calls that return information about files, directories and other filesystem related objects. #
  7. Start Transfer Time: The amount of time between the request from the client to the server, and when the server begins returning data to the client #
  8. Concurrency: The number of concurrent client requests to the server #
Code CoolStuff HowTo PHP Technology Uncategorized WordPress

WordPress Caching Comparisons Part 1

For some time now I have been wanting to write an up to date XCache object cache plugin for WordPress. Around 4 years ago I did an opcode caching comparison between APC, XCache and eAccelerator. My results had shown that at the time that XCache was the fastest of the 3. Unfortunately I didn’t think to keep that data around. As a result of these tests I had standardized the environment I was working on with XCache, and have never thought twice about it. Since I use XCache for opcode caching everywhere, it seemed like writing such an object cache plugin would be beneficial. After writing the plugin I figured it best to test performance, comparing it to the Memcached object cache and the APC Object cache. I tweeted a lot during my initial testing, and got an overwhelming response to write up a post, and here we are…

I’ll try to make this comparison comprehensive, but it can be a little difficult to always cover everything.

The test environment:

  • Toshiba T135-S1310
  • Intel SU4100 64bit Dual-Core 1.3GHz
  • 4GB DDR3 Memory
  • Ubuntu 10.10 64bit
  • Apache 2.2.16
  • PHP 5.3.3
  • PHP XCache 1.3.0
  • PHP APC 3.1.3p1
  • Memcached 1.4.5
  • Pecl Memcached 3.0.4
  • MySQL 5.1.49 No caching configured
  • cURL 7.21.0
  • WordPress 3.1-alpha (r16527) Default install with Twenty Ten and no plugins other than the one I mention below

The times are based off of the standard timer_stop() code often found in the footer.php of themes, in this case added using the wp_footer filter through a mu (must use) plugin:

<?php
add_action('wp_footer', 'print_queries', 1000);
function print_queries() {
?>


<!-- <?php echo get_num_queries(); ?> queries. <?php timer_stop(1); ?> seconds. -->


<?php
}

cURL was used to make the HTTP requests and grab the value from the comment created by the above code:

for (( c=1; c<=101; c++ )); do curl -s http://wordpress.trunk/ | grep '</body>' -B 1 | head -1 | awk -F"queries. " '{print $2}' | awk -F" seconds" '{print $1}'; done;

In each data set I gather 101 results and omit result 1 so that we only have results after the initial cache is generated. The tests are only performed on the home page.

The tests:

  1. No Object or Opcode Cache
  2. Memcached Object Cache with no Opcode Cache
  3. Memcached Object Cache with APC Opcode Cache
  4. Memcached Object Cache with XCache Opcode Cache
  5. APC Object and Opcode Cache
  6. APC Opcode Cache with no Object Cache
  7. XCache Object and Opcode Cache
  8. XCache Opcode Cache with no Object Cache

I didn’t evaluate eAccelerator due to the fact that it isn’t available in the Ubuntu repositories and I did not feel likely compiling…

The results (in seconds):

For a larger view of the spreadsheet above or if you cannot see it, take a look here.

These results are quite interesting and actually shocked me a little bit. The first thing that I found when developing an up to date XCache Object Cache plugin was that it can’t handle objects! So the plugin has to serialize all data when setting, and unserialize when retrieving. This of course is going to add overhead to every operation.

When I first tested the Memcached Object Cache I was surprised at how little it improved speed. It took me about an hour to realize that the comparison of just using Memcached was unfair as it didn’t include any Opcode caching, adding an Opcode cache brings it more in line with what I would expect.

Using an opcode cache improves performance by over 200% on a stock WordPress install without using any object caching. While APC and XCache provided similar results, my tests still show XCache to be ever so slightly faster as an opcode cache.

Where we see the biggest difference between the 3 of these caches when using APC for both opcode and object caching.

Assuming we are using both Opcode and Object caching here are the results from best to worst:

  1. APC
  2. Memcached (With either APC or XCache)
  3. XCache

At this point the single largest failure of XCache is it’s inability to store objects, so I am pretty much planning on dropping XCache on my servers in favor of APC, which will be included with PHP as of PHP 6. I would likely still see marginal speed improvements using XCache on sites that I am not using XCache for an object cache, but on those that I am I’ll get much improved performance off of APC or Memcached.

Now why would I want to use APC over Memcached or vice versa? Well, the one thing that Memcached provides that APC doesn’t is the ability to share the cache between servers. In a load balanced multi web server environment, using APC you would be duplicating the cache on all of the servers as APC provides no way to share this data or allow for remote connections. Memcached however, being a PHP independent daemon can be used for pooling resources and allowing remote connections. You also can get more bang for your buck with Memcached in a load balanced multi server environment because of it’s pooling capability. The pooling capability allows you to dedicate say 128MB of RAM to each memcached instance and when pooled together will give you 128MB x N where N is the number of servers in the pool. Anyway, I digress…

In the end, if you have WordPress hosted on a single web server, APC is the way to go. If you are in a multi web server environment, Memcached is the way to go, but remember to install an Opcode cache as well. If you are crazy and just want to use more CPU cycles, XCache is the way to go.

Some of you may be thinking “why would I need an object cache in addition opcode caching, if the results are similar?” Well, under higher load an object cache will respond better than MySQL, even with MySQL caching. In addition, other factors with MySQL can come into play, such as connectivity to the MySQL server. It may be on another server, with not enough memory, slow disks, with an overloaded network, which decreases performance. Any time that an update query is run, MySQL will flush the whole cache. Another benefit, is we are rarely, if ever, going to use the data exactly as it is given to us from the MySQL query. In the end we are going to process the data before displaying, an object cache allows you to store the processed data, rather than the raw data from the query saving CPU cycles required for the processing. Individually these items may not consume much time, but added together and in a more efficient delivery system, this can make a huge difference.

Now for any of you who go run out and install Memcached, if you install version 1.4.x make sure you get at least pecl memcached 2.2.6 or 3.0.4. Memcached made a change that breaks deletes with earlier pecl memcached versions, which adversely affects WordPress.

A few additional things that I have been asked to talk about are using caching with a WordPress Network, output caching with Batcache and query counts. I promise to get to those, but I just wanted to get this out sooner rather than later.

Yo Dawg! We heard you like caching so we put a cache in your cache, so you can optimize while you optimize…Sorry couldn’t resist.

Code CoolStuff HowTo PHP Technology WordPress

Using MySQL Sockets in the WordPress wp-config.php

Recently I have been getting a lot of questions about how to use a MySQL socket in place of the DB_HOST constant for WordPress in the WordPress IRC channel.

Fortunately this is pretty easy, unfortunately if you are using the web based installer you cannot specify a socket in the “Database Host” field. However, you can do things the manual way and copy wp-config-sample.php to wp-config.php and go that route.

The first thing you need to do is determine the path to the MySQL socket. By inspecting my.cnf you would need to look for something that looks like:

socket      = /var/run/mysqld/mysqld.sock

If you don’t have access to look at my.cnf you can try to run the following MySQL query:

SHOW VARIABLES LIKE 'socket';

Now crack open your wp-config.php file and set DB_HOST to ‘:/path/to/mysql.sock’. Take careful note of the ‘:’ (colon) preceding the path. In my example the define for the DB_HOST looks like:

define('DB_HOST', ':/var/run/mysqld/mysqld.sock');
CoolStuff HowTo WordPress

Detect wp_head and wp_footer from a Plugin

Normally I start these posts with “Every so often someone asks a question in the WordPress IRC channel that sparks my interest”, however today, to my great surprise someone actually caught my attention on the wp-hackers mailing list.

For those of you who didn’t click through, the question was:

Couldn’t find this on forums or anywhere else.
What can I test to check if wp_footer was placed on the theme?

Before any replies came in I was already interested and when Peter Westwood replied with “The other way to do it is to do a http request based test which a special query arg on which you output a string on wp_footer.“, I was on the hook.

I spent a few minutes writing up a test plugin, to perform only this functionality and responded back to the list. It was pretty well accepted and I got a few comments from Ozh and Andrew Nacin on Twitter. One of the comments was actually an idea, to extend the checks to make sure that the calls to <?php wp_head(); ?> and

<?php wp_footer(); ?> were in the proper places in the code.

Before I get to the code, I want to spend a little time talking about the significance of wp_head() and wp_footer(). These 2 functions are the key to functionality of a lot of plugins and are the real work horses of themes. The wp_head and wp_footer functions allow WordPress core and plugins to hook into your theme either directly before the </head> or </body> html tags in your theme and perform actions. The majority of the time these actions are used to output style sheets or JavaScript, for use by plugins. WordPress core uses it to output a lot of good functionality such as relational links to your RSS and ATOM feeds into the head of the document. Joseph Scott wrote about this nearly a year ago. His post is fairly short but does a good job at explaining why it is important to include these functions.

Back to the original discussion, which was how do we detect whether or not wp_head and wp_footer are called in the active theme, and if called are they called, was it from the proper locations?

In my proof of concept plugin, we hook into admin_init, which will actually use wp_remote_get() to retrieve the frontend of our WordPress site. It calls the url with 2 query vars, that if present will cause the plugin to hook into wp_head and wp_footer and output some content that we will later look for. If the response was successful, as in returning a 200 response code, we will look at the content to see if <!--wp_head--> and

<!--wp_footer--> are present. If they are not we will see an admin notice telling us which problems were found. If those strings were found but they were not found directly before

</head> or </body> the notice will alert you of such.

Without further adieu:

Just in case you cannot see the code above, use this link: http://paste.sivel.net/24.

CoolStuff Fun HowTo PHP Plugins Questions Uncategorized WordPress

WordPress Maintenance Mode Without a Plugin Part 3

A few months ago I wrote part 1 and part 2 of WordPress Maintenance Mode Without a Plugin. Part 1 covered the basics of using the .maintenance file, and part 2 covered styling the maintenance page using wp-content/maintenance.php. Part 3 covers the short comings of the other 2 by addressing how to let a user log into the admin and allowing logged in users access to the front end of the site while in maintenance mode.

It only takes a little bit of extra code in a file called .maintenance in the root of your WordPress installation to conditionally return a time that falls within the logic described in part 1. Now without forther adieu:

<?php
function is_user_logged_in() {
$loggedin = false;
foreach ( (array) $_COOKIE as $cookie => $value ) {
        if ( stristr($cookie, 'wordpress_logged_in_') )
            $loggedin = true;
    }
    return $loggedin;
}
if ( ! stristr($_SERVER['REQUEST_URI'], '/wp-admin') && ! stristr($_SERVER['REQUEST_URI'], '/wp-login.php') && ! is_user_logged_in() )
    $upgrading = time();
?>

Just drop the above code in the .maintenance file perhaps take a look at part 2 and away you go. Enjoy!

Code CoolStuff HowTo PHP Snippet WordPress

WordPress Maintenance Mode Without a Plugin Part 2

A few days ago I wrote a post about WordPress Maintenance Mode Without a Plugin. A common question that I got afterwards was whether or not the maintenance page could be styled. The answer, is yes it can be.

After wp-settings.php determines whether or not to put the blog into maintenance mode it checks to see if there is a file titled maintenance.php located in WP_CONTENT_DIR which is by default wp-content/.

Simply create a file at wp-content/maintenance.php containing the code you want to display the for the maintenance page. Below is a sample of code based off of the default maintenance page.

<?php
$protocol = $_SERVER["SERVER_PROTOCOL"];
if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
    $protocol = 'HTTP/1.0';
header( "$protocol 503 Service Unavailable", true, 503 );
header( 'Content-Type: text/html; charset=utf-8' );
?>

<html xmlns="http://www.w3.org/1999/xhtml">

<body>
    <h1>Briefly unavailable for scheduled maintenance. Check back in a minute.</h1>
</body>
</html>


<?php die(); ?>

Modify as needed, add some css, some images and there you go.

Code CoolStuff HowTo PHP Snippet WordPress

WordPress Maintenance Mode Without a Plugin

Every so often someone asks a question in the WordPress IRC channel that sparks my interest, and in this case the core maintenance mode functionality was one of those questions. I’ve known for sometime that WordPress has it’s own maintenance mode functionality since core upgrades were added, however I had never really looked into the functionality. Hooking into this functionality is really quite simple and effective.

Start by creating a file in the root of your WordPress install (on level with wp-settings.php) called .maintenance. Note the preceding dot like a .htaccess file; in Linux this is considered a hidden file. In this file add the following code:

<?php $upgrading = time(); ?>

This code will basically cause the maintenance page to display until you remove the .maintenance file. In wp-settings.php there are 2 checks to see if it should display the maintenance page. First, it makes sure that the .maintenance file exists. Second, it checks that the current time minus the time specified by the $upgrading variable is less than 10 minutes. Using the code above will insure that it is always less than 10 minutes since time() - time() == 0. If you want it to display for a certain period of time you would want to use:

<?php $upgrading = 1234567890; ?>

For your usage you would want to replace 1234567890 with the unix formatted timestamp of the time minus 10 minutes at which you want the maintenance page to stop displaying.

For example if I wanted the maintenance page to stop displaying at November 14, 2013 at 20:13:00, I would really set the $upgrading variable to November 14, 2013 at 20:03:00. Notice the 03 instead of 13. In unix time this would look like 1384459380. And the code needed for the .maintenance file would be:

<?php $upgrading = 1384459380; ?>

Take note that if you use a specific time in the .maintenance file and you do not remove the .maintenance file, your users will see your site and not be affected, however in the admin you will see a notice stating, “An automated WordPress update has failed to complete - please attempt the update again now.” Deleting the .maintenance file will remove this notice.

I’m sure that this functionality could be wrapped in a plugin, or even better an option added to the core code in the admin. However, I am happy with just manually creating the file.

For information on modifying or styling the maintenance page see WordPress Maintenance Mode Without a Plugin Part 2.

Code CoolStuff HowTo PHP Snippet WordPress

WordPress Update/Install Clarifications and Requirements

Recently I have been responding to numerous questions about the update/install functionality in WordPress for core, plugins and soon themes. I wanted to take a few moments to make some clarifications and to inform people of the requirements.

To update the WordPress core or update/install plugins or themes without having to enter your FTP/SSH information you have 2 options:

  1. Define the required constants in wp-config.php
  2. Make the necessary file permission/ownership configurations required to use a direct update/install instead of using FTP or SSH

For information on achieving the first option see take a look at the follow links:

The second option is a little more confusing for some people. Most people think that as long as they give full write access to the plugins or wp-content directories that they will not be asked for their FTP/SSH connection information. Unfortunately, this falls short of the requirements for performing a direct update or install. There are 4 possible methods for performing the file operations. The operations are ‘direct’, ‘ftp’, ‘ssh2’, and ‘ftpsocket’. The direct method allows php to do all of the file operations on its own without requiring any external dependencies. For the ‘direct’ method to work, the web server, and by extension php, needs full write access to the files it is trying to modify.

WordPress determines if it can perform a direct update or install by performing a few file operations and looking at the ownership of those file operations. Here are the steps that WordPress goes through when making the determination.

  1. Returns a suitable temporary directory to create a test file (the following is in the order of precedence)
    • If WP_TEMP_DIR is defined it will return this value
    • If WP_CONTENT_DIR is writable by the web server user it will return the path to the wp-content directory
    • If you are running PHP 5.2 or newer it will determine the systems temp directory using sys_get_temp_dir()
    • As a fall back it will return /tmp/
  2. Creates a unique file via touch() in the temporary directory returned in step 1 and returns the path to this temporary file
  3. If the file system owner of wp-admin/includes/file.php and the file system owner of the temporary file that was created are equal to each other then it will use the direct method and then the temporary file is removed
    • The check that is performed uses the file system owner of wp-admin/includes/file.php and not the run time user of that script
    • This is, in my opinion, the most reliable way to make sure that the user the web server is running as can make modifications to all of the WordPress files
  4. If the check failed to use the direct method it will check for the possibility of using:
    • SSH2
    • FTP
    • Sockets (fsockopen, fwrite, fread)

So with the above steps for determining whether or not the ‘direct’ method can be used there are several things that can be done to allow WordPress to use the ‘direct’ method.

  1. If you want to do core upgrades as well as plugin and theme upgrades/installs you can change the ownership of all of the WordPress files to be that of what the web server is running as
  2. If you only want the ability to do plugin and theme upgrades/installs you can modify the ownership of wp-content, all of its contents and wp-admin/includes/file.php to be that of what the web server is running as
  3. If you want to do core upgrades as well as plugin and theme upgrades/installs you can set permissions on all of the WordPress files and all of its contents that give the web server write access to those files and then add a filter to the filesystem method by way of a plugin or addition to functions.php
  4. If you only want the ability to do plugin and theme upgrades/installs you can set permissions on wp-content and all of its contents that give the web server write access to those files and then add a filter to the filesystem method by way of a plugin or addition to functions.php

I am sure there are about 100 different combinations of the above methods, so feel free to experiment.

Since #1 and #2 are fairly self explanatory I will skip those and explain #3 and #4.

  1. Change the file/directory permissions of either the WordPress root or wp-content and all of their contents so that the web server user has the ability to modify those files and write to those directories
  2. Add the following bit of code to either your themes functions.php or to a plugin add_filter(‘filesystem_method’, create_function(‘$a’, ‘return “direct”;’));

In methods 1 and 2 we simply fulfill the requirements needed by WordPress to return the ‘direct’ method on its own. In methods 3 and 4 we have made sure that the web server can do what it needs to the WordPress files and because of this we can tell WordPress to always use the direct method.

I believe that should about cover it. If I have made any mistakes or forgot to include something please let me know. Enjoy!

HowTo WordPress

Separating Pings from Comments in WordPress 2.7

WordPress 2.7 has introduced many new features surrounding comments. Of these is AJAX commenting and threaded comments. To take advantage of the later, you must use a function wp_list_comments instead of the old way of looping through the comments array with a foreach. Weblog Tools Collection has a good how to on the old way that can be found here.

I wanted to get this hashed out before 2.7 goes live so that theme designers and anyone else can implement this in time for the release.

I’ll be referencing the default theme from 2.7 in this how to. If you are interested in adding the new commenting features to your current pre 2.7 theme see this how to by Otto.

wp_list_comments is not documented yet on the WordPress codex. But some feature that are worth mentioning are the ability to specify the comment type to display and a callback so that you can decide how to structure the output.

Let us start by taking a look at the new comments “loop”:

<?php if ( have_comments() ) : ?>
    <h3 id="comments">

<?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;

<?php the_title(); ?>&#8221;</h3>

    <ol class="commentlist">


<?php wp_list_comments(); ?>
    </ol>
    <div class="navigation">
        <div class="alignleft">

<?php previous_comments_link() ?></div>
        <div class="alignright">

<?php next_comments_link() ?></div>
    </div>


<?php else : // this is displayed if there are no comments so far ?>



<?php if ('open' == $post->comment_status) : ?>


<!-- If comments are open, but there are no comments. -->



<?php else : // comments are closed ?>


<!-- If comments are closed. -->
        <p class="nocomments">Comments are closed.</p>



<?php endif; ?>


<?php endif; ?>

As you can see it is much simpler than the old comments “loop”. The majority of everything that is happening is now done via the function wp_list_comments.

To remove pings (pingbacks and trackbacks) we only need to make a few small changes. First open up your themes single.php:

Find the following code:

<?php comments_template(); ?>

And change it to:

<?php comments_template('', true); ?>

The above change tells comments_template to create a global array $comments_by_type that we will use later on.

First open up comments.php.

Look for the following code:

<?php if ( have_comments() ) : ?>

Directly below this add:

<?php if ( ! empty($comments_by_type['comment']) ) : ?>

Change this:

<?php wp_list_comments(); ?>

To this:

<?php wp_list_comments('type=comment'); ?>

Directly below the wp_list_comments function we modified is:

</ol>

Directly below this add:

<?php endif; ?>

The if statement prevents the comments heading and ol tags from displaying if you only have trackbacks and pingbacks on this post.

Much easier so far, right?

To display the pings we need to insert the following code beneath the endif we just added:

<?php if ( ! empty($comments_by_type['pings']) ) : ?>
<h3 id="pings">Trackbacks/Pingbacks</h3>

<ol class="commentlist">


<?php wp_list_comments('type=pings'); ?>
</ol>


<?php endif; ?>

The comments “loop” should now look like this:

<?php if ( have_comments() ) : ?>


<?php if ( ! empty($comments_by_type['comment']) ) : ?>
    <h3 id="comments">

<?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;

<?php the_title(); ?>&#8221;</h3>

    <ol class="commentlist">


<?php wp_list_comments('type=comment'); ?>
    </ol>


<?php endif; ?>



<?php if ( ! empty($comments_by_type['pings']) ) : ?>
    <h3 id="pings">Trackbacks/Pingbacks</h3>

    <ol class="commentlist">


<?php wp_list_comments('type=pings'); ?>
    </ol>


<?php endif; ?>

    <div class="navigation">
        <div class="alignleft">

<?php previous_comments_link() ?></div>
        <div class="alignright">

<?php next_comments_link() ?></div>
    </div>


<?php else : // this is displayed if there are no comments so far ?>



<?php if ('open' == $post->comment_status) : ?>


<!-- If comments are open, but there are no comments. -->



<?php else : // comments are closed ?>


<!-- If comments are closed. -->
        <p class="nocomments">Comments are closed.</p>



<?php endif; ?>


<?php endif; ?>

Now the pings are displayed below the comments. The above code will show the pings in full comment boxes. I personally like a simple ordered list with a link and title of the ping. To achieve this without a foreach (Thanks Ryan Boren for the tip!)

Open your themes functions.php file and create a callback function for wp_list_comments. The following code should be inserted:

<?php

function list_pings($comment, $args, $depth) { $GLOBALS[‘comment’] = $comment; ?> <li id=“comment-

<?php comment_ID(); ?>">

<?php comment_author_link(); ?>


<?php } ?>

Replace this:

<ol class="commentlist">
<?php wp_list_comments('type=pings'); ?>

With this:

<ol class="pinglist">
<?php wp_list_comments('type=pings&callback=list_pings'); ?>

If your theme doesn’t have a functions.php just create it and include the above code.

In this case our full comment “loop” should now look like:

<?php if ( have_comments() ) : ?>


<?php if ( ! empty($comments_by_type['comment']) ) : ?>
    <h3 id="comments">

<?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;

<?php the_title(); ?>&#8221;</h3>

    <ol class="commentlist">


<?php wp_list_comments('type=comment'); ?>
    </ol>


<?php endif; ?>



<?php if ( ! empty($comments_by_type['pings']) ) : ?>
    <h3 id="pings">Trackbacks/Pingbacks</h3>

    <ol class="pinglist">


<?php wp_list_comments('type=pings&callback=list_pings'); ?>
    </ol>


<?php endif; ?>

    <div class="navigation">
        <div class="alignleft">

<?php previous_comments_link() ?></div>
        <div class="alignright">

<?php next_comments_link() ?></div>
    </div>


<?php else : // this is displayed if there are no comments so far ?>



<?php if ('open' == $post->comment_status) : ?>


<!-- If comments are open, but there are no comments. -->



<?php else : // comments are closed ?>


<!-- If comments are closed. -->
        <p class="nocomments">Comments are closed.</p>



<?php endif; ?>


<?php endif; ?>

One last (optional) task is to modify the comment counts to only reflect the number of comments minus pings.

Open your themes functions.php and add the following code:

<?php
add_filter('get_comments_number', 'comment_count', 0);
function comment_count( $count ) {
    if ( ! is_admin() ) {
        global $id;
        $comments_by_type = &separate_comments(get_comments('status=approve&post_id=' . $id));
        return count($comments_by_type['comment']);
    } else {
        return $count;
    }
}
?>

Again if your theme doesn’t have a functions.php just create it and include the above code.

There you have it. If you have any questions let me know.

HowTo PHP Plugins WordPress