Setting Plesk Permissions for WordPress & FTP

Since I started using WordPress (and more importantly developing for WordPress) I have been plagued by what seems to be a very common issue – allowing WordPress to simultaneously have internal writing permissions without breaking FTP. When using WordPress on a linux/*nix server combined with Parallels Plesk, you’re subject to dealing with not only Apache and its permissions, but also the permissions setup by Plesk groups, Plesk users, and Plesk FTP restrictions.

The following steps are what I took to enable full FTP access and full Apache/PHP/system write access to the same directories and files. This was tested on Parallels Plesk v 10.1.1 on a Media Temple (dv) Dedicated Virtual 4.0 running Linux version 2.6.18-028stab093.2. In this configuration, Apache is running under the username Apache, but on other servers may run as www-data, nobody, or something else. You will need shell and sudo access to complete the following tasks.

1. Add the apache user to the psacln (plesk) writable group.
You only need to do this once, however, at this time we have not tested what happens when apache is updated (so you may have to repeat after an update/upgrade)

$ usermod -a -G psacln apache

If the user running the web server is not apache (may be www-data or nobody) simply use that user at the end of this command.

2. You now have to give the group write access on the directories and/or files necessary. In wordpress, you’ll want to do this on the entire directory that wordpress is living in.

$ chmod g+w {file}
$ chmod -R g+w {directory/}

NOTE: After further testing, I’ve updated this to reflect better settings. Essentially we’re giving all folders group write access and all files normal 644 access

$ find wp-content/ -type f -exec chmod 644 {} \;
$ find wp-content/ -type d -exec chmod 775 {} \;

3. Now you have to give ownership to the directories and/or files. The psacln group is specific to plesk and is subject to change based on your environment.

$ chown -R {ftp_username}:psacln {directory}/

4. I suggest you restart Apache once you’re done with these steps, and you may need an Apache restart after step 1 as well. On the Media Temple (dv) 4.0 Dedicated Virtual Apache runs as process httpd, though it may run as apache or something else in your server environment.

$ service httpd restart

5. (Optional) Force WordPress to use the filesystem to run updates. WordPress runs through a routine determining how it’s going to write data (directly, FTP, SSH, etc.) but sometimes fails to use the direct method even though it’s available. Usually there is a reason when WordPress does or doesn’t do something even though it’s possible, so this may be a concern (or it may be a dumb bug). Andrew Nacin has kindly chimed in via the comments to explain this -

The reason WordPress sometimes doesn’t use the direct filesystem method even when it would work is because it only detects that the user on the PHP process is the owner. It doesn’t support detecting group-writeable. … essentially, we’re trying to avoid a situation where we create and therefore own a file, when normally we would not be the owner, and that then locks out the FTP user.

That said, if you’d like to force WordPress to use the direct filesystem to write and modify data, simply add the following line to your wp-config.php file:

define('FS_METHOD', 'direct');

I would love to hear if this worked or didn’t work for you in your own server environment – again, this was a very specific test and I haven’t verified on other hosts, versions of Plesk, or versions of Linux. Please feel free to comment and let everyone know if it worked for you and where.

Thank you.

2011 Mini Cooper S Countryman

The new baby. She’s fast. And pretty. And has four doors. And is completely awesome.

Want a great API? Don’t use Goodreads’

I’m in the middle of a client project for a local public library – building a simple mobile site that makes book recommendations based on genres. The titles come from their RSS feeds and we grab additional data from Goodreads. Easy and fun right?

No. Wrong. Very Wrong.

To put it plainly, the Goodreads API is a mess. A convoluted, poorly designed, agonizingly slow mess. To demonstrate, I thought I’d walk you through a few of their API terms (found here).

1. Not request any method more than once a second. Goodreads tracks all requests made by developers.

This sucks. If in your app you want to query a book, grab a review, show the author’s bio, and recommend other books in that series, you need to make 4 API calls. To abide by Goodreads’ terms, you need to make that request last 4 seconds. Seriously?! It’s 2011 – I can make thousands of requests in that time from hundreds of other APIs. But the best part? It actually takes longer than 4 seconds because the response time from Goodreads per request is over 1 second. Plus, if you read term #5, they say you can’t store anything – so every pageload is going to take several seconds. Sounds like an awesome user experience, right?

3. Link back to the page on Goodreads where the data data [sic] appears. For instance, if displaying a review, the name of the reviewer and a “more…” link at the end of the review must link back to the review detail page. You may not nofollow this link.

I had no idea a webservice could be so selfishly greedy. What this is really saying is “We will NOT give you the full review of anything, you must link back to our site to see it, and you must give us link credit for every review you display in your app.”

This is all very frustrating. Goodreads has fantastic data – I’ll be the first to admit that – but they’re actively DISCOURAGING developers from using it!

But the worst part is the developer support.

I was building the application and came across the fact that only a handful of API endpoints returned JSON – the others only returned XML. Not a huge deal, but when trying to save as much time as possible due to aforementioned request time, I wanted to parse JSON in PHP rather than load the SimpleXML resources. I thought this was odd (maybe a bug) so I searched in the developer forums; lo and behold, someone else had the same request. They explained that they were using the Goodreads API as an example in a classroom setting and wanted to give the students JSON to work with. Here’s the response from a Goodreads employee:

“It’s a bit of work to add this. Someday it will likely happen, but probably not that soon. If you were using an API for a class, I don’t think our documentation is that great either. I think flickr has a much more mature api.”

Yes. A Goodreads employee said “That’s too hard so we won’t do it, and our API and documentation isn’t good enough for you to use in a class. Use something else.”

(You can read this entire thread here: http://www.goodreads.com/topic/show/453508-can-we-get-json-for-all-calls?page=1#comment_27316799)

In the end, I’m saddened and appalled. I can’t deliver the product a client wants, I’ve spent several hours fighting an API that is simply poorly documented, developed, and supported, and as someone working on building an API for another product I’m utterly shocked that something like this can be called an active release from a company that has raised nearly $3 Million in venture funding.

It’s 2011 guys. Catch up.

Chandler Urban Art Project at Gangplank

We had the awesome guys over at Tabu Tattoos come and paint a Gangplank graffiti mural for us. I setup my camera and did a time lapse of their work. Give some love over at the Gangplank Blog.