Producing a Faux-Wordpress Plugin for Symfony, Part II

Working on the Foundations

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.

2 Responses to “Producing a Faux-Wordpress Plugin for Symfony, Part II”
  1. [...] 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. [...]

  2. blogiskewl says:

    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

Leave a Reply