Community Portal tutorial
From PRADO Wiki
Contents |
Introduction
This tutorial will show you how to create a community / content management portal solution in Prado 3.1. For those not familiar with the term community portal solution it basically means a website that allows users to have personalized profiles, send messages, share files, link to friends etc.
Similar projects / references
To get a inspiration / a better understanding of what we are building the following links can be relevant:
- http://www.linkedin.com/ (manage professional relationships)
- http://blink.dagbladet.no (Norwegian "social" community)
- http://www.facebook.com
- http://www.barnraiser.org/demos/aroundme_0_7_2/aroundme/ (quote: "a flexible social tool kit". open source / free(?))
Can someone please update the link section with more English sites?
Prerequisites
This tutorial isn't going to explain the basics of Prado and it would be a advantage if you have read the following articles and tutorials before following this tutorial.
Prado QuickStart
The QuickStart has some excellent tutorials and tips, and everyone should read trough it at least once. The following pages are especially relevant to this tutorial:
- Themes
- Internationalization (I18N) and Localization (L10N)
- TRepeater docs
- Page Config
- Applcation config
- Master and Content
Related Prado tutorials and articles
Other tutorials and articles
Software
This tutorial will assume that you are using MySQL 5.X. Other database servers can also be used, but be sure that you are able to create databases / connections etc if you are going to follow this tutorial.
MySQL Administrator is a very nice tool that lets you create users, databases and tables in a proper GUI. It's available both for Windows and Linux users. Windows users can download it from the url while Linux users should get the packages with apt-get or similar.
MySQL Query Browser is a GUI tool for running queries against your database. It can also export result sets to excel / xml and various other formats. Windows users can download it from the url while Linux users should get the packages with apt-get or similar.
Notepad++ is a really nice free lightweight code-editor for windows.
Part 1 - Planning
Introduction
When I first started working on this project I set out to re-write a popular community service used in Norway called Nettby (www.nettby.no). I got pretty far and had most of the features nailed, but I realized that the application was pretty much useless. Sure I could set up a competing site, but that was about all it was good for.
The project lay dead for a while, but I decided to take it up again in the easter. I sat down and fleshed out a list of key features and requirements to make sure the project could be used for more than just a community portal. The idea is to create a "framework application" that has all the features needed for creating things like online news sites, blogs, fan club community sites, gaming guild sites etc. Each use-case would in theory just need to create a design and tie in the desired functionality from the framework.
After a hour browsing sites like facebook, myspace etc I came up with the following list (random-ish order):
Requirements
* the project should supply a framework for a community portal with content management features * everything in the system should have access permissions * the project should be self sustainable. content and user management should be available in a admin module * make use of Prado globalization features * make use Prado themes support and make sure everything is set up so it can be changed by CSS * use active controls, but only where it really gives an advantage
Features
* users can join or be created * users can have a personal blog * users can send and receive private messages * users can upload photos in photo albums * users can tag other users with various social relation types * users can describe themselves by choosing from a list of metadata-keys and filling out the contents * admins can add and remove metadata-keys * users can storepersonalized profile information and preferences * users can have a guest book * users can upload files and share them (private, social relations, public) * users can create ads for sell / buy etc * users can create events(private, social relations, public) * users can join events * basic forum functionality
I've made a first draft of a class diagram to show the ideas I'm having for the project. User Detail and User Detail Entry is now called Account Metadata and Account Metadata Keys. All metadata is stripped from the actual User class and it only holds email (as user name), password, active state and creation time. The permission tables are also missing.
As you probably can see the model needs more work, and it will of course be updated as the tutorial progresses.
Data access
I've started defining a interface for the data access layer to make sure the whole project doesn't depend on a single data-provider. It will ship with a implementation using LibSoil (which will be documented here as the tutorial progresses).
Permissions and user access
The general idea for access restriction is to assign permissions to users. The various permissions are defined in a permission table in the database and are assigned to each user as the administrator sees fit. The active keys are stored in a array which is loaded into the user object when a user logs in.
The usage is currently $this->User->Permissions->canCreateAccount()
canCreateAccount is really just a wrapper for in_array which returns true if the permission is set and false if it's not.
Example permissions
* CREATE_ACCOUNT * UPDATE_ACCOUNT * DELETE_ACCOUNT * POST_BLOG * SEND_MESSAGE * VIEW_BLOG
There are a support table to aid with setting up the first batch of permissions for a new user. It basically holds a set of permissions grouped by a title (like "normal user", "admin", "senior user" etc). When a user is created the permissions for the selected group is created. After the user is created there is no relation to the group whatsoever.
Part 2 - Setup
Setting up our directory structure
The following directory structure is the suggested one in this tutorial. If you decide to use your own that's no problem, but remember that the tutorial will assume this one is used. The advantage with this structure is that only the www folder needs to be exposed to the web, while the rest of the folders can just be accessed by the web server process.
project -common -conf -controls -data -lang (must be writable by web server process) -layouts -lib -pages -runtime (must be writable by web server process) -www --assets (must be writable by web server process) --themes ---Basic ----images
index.php
Placed in the www folder
application.xml
Placed in the project folder.
Config files
We are going to use the features explained in the Settings File tutorial to allow storage of settings in our application. Later on in the tutorial the benefits of this solution will really shine. There is no need to recap the tutorial here, so head on over and follow it. Come back here when you are done.
Part 3 - Account, Account metadata and Permissions
It's time to get our hands dirty. Part 3 is about creating our main account related tables, setting up the classes in PHP and defining / implementing interface methods to interact with the data. You can
download the code for Part III in the download section.
We'll start with the account related tables.
Table information
The following model shows the tables and classes we'll be creating. Please note that this is just a subset of our model (and every field is set to integer here for no reason).
Account holds the login information along with registration time and a flag for if the active is active or not.
AccountMetadataKeys is a table that holds every kind of metadata we'd like to let the user supply us with. Example: Firstname, Lastname, City, State, Gender, Age, Favorite Music, Favorite Food etc.
AccountMetadataKeyGroup is used to group the metadata keys. Examples of groups would be Personalia, Profile Info etc
AccountMetadata is the table we use to map a account to a metadata key along with the contents the user supplies.
Permission holds all the permission flags for the application. Example of a permission key would be CREATE_ACCOUNT, READ_ACCOUNT, DELETE_ACCOUNT, ACCESS_ADMIN etc.
PermissionGroup is only a support table used for creating new users. Each group consists of one or more permissions and it's identified by a title like "Normal user", "Senior user" or "Admin". When a user
is created we simply add the permissions in the selected group to the users account.
PermissonGroupLink is just used to link the permissions to the groups.
PHP Classes
Since we are using Libsoil we'll need to set up some dataclasses for our tables. These classes goes in /project/lib/libsoil/DataClasses.php
class CBAccount extends DataClass{ protected $table = "account"; } class CBPermission extends DataClass{ protected $table = "permissions"; } class CBAccountPermission extends DataClass{ protected $table = "account_permissions"; } class CBAccountMetadata extends DataClass{ protected $table = "account_metadata"; } class CBAccountMetadataKey extends DataClass { protected $table = "account_metadata_key"; } class CBAccountMetadataKeyGroup extends DataClass { protected $table = "account_metadata_key_group"; } class CBPermissionGroup extends DataClass { protected $table = "permission_group"; } class CBPermissionGroupLink extends DataClass { protected $table = "permission_group_link"; }
Interface Methods
Lets start by defining some interface methods for our newly created classes. These methods goes in /project/common/ICDataModule.php.
// account methods function addAccount($email,$passwd = null,$active = 1, $permissionGroup = null); function getAccount($email); function getAccounts($limit = null,$count = null); function changeAccountState($email,$state); // metadata function getMetadataKeys(); function getAccountMetadata($email); function addAccountMetadata($email, $items); function removeAccountMetadata($email, $key); function updateAccountMetadata($email, $key,$contents); // permissions function getAvailablePermissionsForAccount($email); function getPermissionsForAccount($email); function addPermissionToAccount($email,$permission); function removePermissionFromAccount($email,$permission); // permission groups function getPermissionGroups(); function getPermissionsFromGroup($group); function addPermissionGroup($title); function removePermissionGroup($id); function addPermissionToGroup($group,$permission); function removePermissionFromGroup($group,$permission);
Account Methods
The following methods are used for account management.
addAccount creates a new account. If passwd is null then a random password is created. If permissionGroup is set then the method gets the permissions for the supplied group and adds them to the new
account. If it isn't set then the account is created with no permissions at all. If the active flag is set to 0 then a activation code will be generated and a email is sent to the user for activation.
getAccount simply gets the account for the supplied email
getAccounts is used to get all the registered accounts with a optional limit and offset.
changeAccountState is used to activate / deactivate a account
Metadata Methods
The following methods are used for managing account metadata and metadata keys.
getMetadataKeys fetches all metadata keys
'getAccountMetadata fetches all metadata key and the contents the user has supplied. If a key is without contents it's still fetched.
addAccountMetadata takes a array of metadata-keys and content and uses a replace into method to insert / update the account metadata
removeAccountMetadata simply deletes the metadata for the given key / account
updateAccountMetadata updates the metadata content for the given account / key
Permission Methods
The following methods are used for managing permissions and adding / removing permission for accounts.
getAvailablePermissionsForAccount returns all permissions except the ones active for the given account
getPermissionsForAccount returns all active permissions for the given account
addPermissionToAccount adds the supplied permission to the given account
removePermissionFromAccount removes the supplied permission from the given account
Permission Group Methods
The following methods are used for managing account permission groups.
getPermissionGroups returns all permission groups
getPermissionsFromGroup' returns all the permissions in the selected group
addPermissionGroup creates a new permission group with the supplied name
removePermissionGroup deletes the permission group with the supplied name
addPermissionToGroup adds the supplied permission to the supplied group
removePermissionFromGroup removes the supplied permission from the supplied group
Downloads
Not available yet
Help wanted
A person who could do a nice CSS design would be very appreciated. Please send a private message to eirikhm over at the Prado forums

