Wordpress is, by far, the most popular blogging framework on the Internet today and that popularity is not undeserved. It has an easy installation and is set up to cater to non-technical people. After installation, it simply works and people are up and running quickly. It has an active plugin community to extend it in any direction a user might need. In short, it’s a great solution to use pretty much anywhere.
However, it’s also not very nice to play with as a developer. The code is mostly based around PHP 4 (although that will probably change when 3.0 is released) and writing plugins and themes can occasionally be a nightmare. Security is, unfortunately, a constant problem since the ease-of-use is occasionally in tension with secure practices. Finally, while the self-contained aspect of Wordpress is great for a typical user who pretty much runs their entire site through Wordpress, integrating a Wordpress installation with an existing applicaiton — especially an application that has its own extensive user-management solution — is a daunting task. Wordpress is a streamlined applicaiton, but trying to bend it in ways it wasn’t meant to bend (fiddling with database schemas, login and session management, etc) often breaks either Wordpress or the developer.
The symfony plugin I am trying to write is NOT to somehow replace Wordpress. That is a large project that would be nearly impossible for myself. I have no idea how I’d ever compete against the easiness of a Wordpress installation. The Symfony framework is awesome (and well-suited, I’d argue, for such an endeavor whenever someone wishes to attempt it), but it is meant for PHP developers, not for somebody who just wants to host a blog. So, my plugin will approach the issue from the PHP developer’s point of view. Wordpress plugins extend Wordpress to act however the developer wants; with a Wordpress installation all functions of the website are meant to be handled by Wordpress. With my plugin, it is just a plugin to handle and emulate the blogging aspects of Wordpress; for the other features that a user or developer might want you’ll need to address those through the framework itself. Anything that isn’t the job of a blogging solution (e.g., a contact page) isn’t done by the blogging solution.
So, with that out of the way, on to building the plugin (which, until I think of a better name, is called sfFauxWP).
The foundation of any blogging solution revolves around the basic idea of posts and comments. The following schema (adapted from the already excellent sfSimpleBlogPlugin) allows for posts, comments, tags (non-self-referential post attributes), categories (self-referential post attributes), and user ratings. There are a number of booleans which hold post-specific settings regarding user interaction. While allowing some room for possible modification in the future, this schema is probably more than enough for our needs.
schema.yml
propel:
_attributes:
package: lib.model
defaultIdMethod: native
## Posts ##
sf_faux_wp_posts:
_attributes:
phpName: sfFauxWPPost
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
author_id:
type: integer
required: true
foreignTable: sf_guard_user
foreignReference: id
onDelete: cascade
title:
type: varchar
size: 255
short_title:
type: varchar
size: 255
summary:
type: longvarchar
content:
type: longvarchar
is_published:
type: boolean
default: false
restrict_comments:
type: boolean
default: false
rate_comments:
type: boolean
default: false
rate_posts:
type: boolean
default: false
published_at:
type: date
created_at: ~
updated_at: ~
_uniques:
short_title_published_at: [short_title, published_at]
## Comments ##
sf_faux_wp_comments:
_attributes:
phpName: sfFauxWPComment
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
sf_faux_wp_post_id:
type: integer
required: true
foreignTable: sf_faux_wp_posts
foreignReference: id
onDelete: cascade
sf_guard_user_id:
type: integer
required: false
foreignTable: sf_guard_user
foreignReference: id
onDelete: cascade
author:
type: varchar
size: 255
email:
type: varchar
size: 255
website:
type: varchar
size: 255
content:
type: longvarchar
is_moderated:
type: boolean
default: false
created_at: ~
updated_at: ~
## Tags ##
sf_faux_wp_tags:
_attributes:
phpName: sfFauxWPTag
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
name:
type: varchar
size: 255
index: unique
created_at: ~
updated_at: ~
## Categories ##
sf_faux_wp_categories:
_attributes:
phpName: sfFauxWPCategory
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
parent_id:
type: integer
required: false
foreignTable: sf_faux_wp_posts
foreignReference: id
onDelete: set null
name:
type: varchar
size: 255
index: unique
created_at: ~
updated_at: ~
## The Post<=>Tag Relationship ##
sf_faux_wp_post_tags:
_attributes:
phpName: sfFauxWPPostTag
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
post_id:
type: integer
required: true
foreignTable: sf_faux_wp_posts
foreignReference: id
onDelete: cascade
tag_id:
type: integer
required: true
foreignTable: sf_faux_wp_tags
foreignReference: id
onDelete: cascade
_uniques:
post_tag: [post_id, tag_id]
created_at: ~
updated_at: ~
## The Post<=>Category Relationship ##
sf_faux_wp_post_categories:
_attributes:
phpName: sfFauxWPPostCategory
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
post_id:
type: integer
required: true
foreignTable: sf_faux_wp_posts
foreignReference: id
onDelete: cascade
category_id:
type: integer
required: false
foreignTable: sf_faux_wp_tags
foreignReference: id
onDelete: set null
_uniques:
post_category: [post_id, category_id]
created_at: ~
updated_at: ~
## The Post Group Controls - Who Can Comment? ##
sf_faux_wp_post_groups:
_attributes:
phpName: sfFauxWPPostGroup
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
post_id:
type: integer
required: true
foreignTable: sf_faux_wp_posts
foreignReference: id
onDelete: cascade
group_id:
type: integer
required: true
foreignTable: sf_guard_group
foreignReference: id
onDelete: cascade
created_at: ~
updated_at: ~
## The Category Group Controls - Who Can Create? ##
sf_faux_wp_category_groups:
_attributes:
phpName: sfFauxWPCategoryGroup
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
category_id:
type: integer
required: false
foreignTable: sf_faux_wp_tags
foreignReference: id
onDelete: cascade
group_id:
type: integer
required: true
foreignTable: sf_guard_group
foreignReference: id
onDelete: cascade
created_at: ~
updated_at: ~
## The User Ratings for Comments ##
sf_faux_wp_comment_user_ratings:
_attributes:
phpName: sfFauxWPCommentUserRating
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
comment_id:
type: integer
required: true
foreignTable: sf_faux_wp_comments
foreignReference: id
onDelete: cascade
user_id:
type: integer
required: true
foreignTable: sf_guard_user
foreignReference: id
onDelete: cascade
rating:
type: tinyint
default: 1
created_at: ~
updated_at: ~
## The User Ratings for Posts ##
sf_faux_wp_post_user_ratings:
_attributes:
phpName: sfFauxWPPostUserRating
id:
type: integer
primaryKey: true
autoIncrement: true
required: true
post_id:
type: integer
required: true
foreignTable: sf_faux_wp_posts
foreignReference: id
onDelete: cascade
user_id:
type: integer
required: true
foreignTable: sf_guard_user
foreignReference: id
onDelete: cascade
rating:
type: tinyint
default: 1
created_at: ~
updated_at: ~
This entry was posted on Monday, February 1st, 2010 at 7:00 pm by NoCoolName_Tom and is filed under Technology, symfony Framework. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

[...] Here is a great post on extending a blog plugin for Symfony. There is a new hack attack going around for WordPress, so I’m thinking about switching to Symfony for my blogging. [...]
Hi, I recently started a bloghosting platform (based on wordpress MU) and when I stumbled your blog I paid attention to your theme (looking good) so I was wondering can you tell me is it custom made theme or one of those free ones? thanks in advance! regards, blogiskewl