About
The QuateCMS is a free (open source) web user interface aimed for managing website content with ease. The 0.4 series has been recoded since the 0.3 series. The logic behind this is to create a new, more customizable base.
Goals
We hope that the QuateCMS meets the following goals when released as a finished project:
- Open source code. Other developers should be able to add on to the code or fork it.
- Easy to add content. Adding content should be easy, yet not restrictive towards features. It should encourage new users to use the system without detracting the attention of more advanced users. Social engineering is crucial towards acomplishing this feat. Wordpress 2.6 has done a great job with this, and should serve as a role model.
- Easy to add/edit a website template. Many robust systems use complex website template systems that make it difficult to incorporate new templates with.
- Lightweight and stable. The CMS should be designed to run in a stressed environment without a problem.
- Flexible. Additional features should be seemlessly integratable into the system. Start simple and let the users add the features they need.
- Support multiple environments. The use of different databases should be supported. Any operating system. Although, additional features may be granted to those using the Apache web server, such as mod_rewrite for url rewriting. But by all means the system should still work at a fundimental level without Apache.
- Multilingual support. At the very least the CMS should contain a system that supports multilingual websites.
- Framework. The QuateCMS should be easy to rebrand and used as a basic framework for other projects.
Settings and Cache
A dynamic settings system should be used, making use of a database. This allows for extensions to be properly integrated. The one constraint is that it may be system intensive.
Problems
The one major constraint is that it may be more server resource intensive.
Solutions
There are two ways to approach this.
The first is the implimentation of a cache system. When settings are saved to the database, a cache of the settings table is created, resulting in two copies of the settings. The system would load a cache file when necessary, rather than calling the database. The end result should be quicker parsing and less stress on the database.
It should be noted that some environments may not have write permissions, and won't be able to make use of the caching system.
(Development note: The config file should have a variable such as $use_cache = 0;.
If writing permissions are available, the installer should change this setting.)
The second approach is to only call certain settings when required. For example, the admin panel loads admin panel settings, the main website pages load page settings. Developers may still add to these settings. Nevertheless, a large amount of settings could still lead to a lot of database querying.
Categories Caching
Another issue is that categories are used often, and subcategories depend on each other. It may be intelligent to include some sort of caching system for categories as well.
Security
Security is fundamentally important in all software.
Passwords
Password Encryption
Passwords should always be stored using one-way encyption. The use of sha1 certainly helps, but using a salt is even more secure:
$newPassword = sha1($password. "" .$salt);
Each user can be assigned a personal random salt upon account creation, which is then stored in the database.
Insecure Connections
Passwords being delivered over an insecure connection can be an issue. The use of a client-side javascript sha1 encryptor can help with that.
Sessions and Cookies
Cookies are problematic because they usually store data on the client-end. Sessions are to be used instead, where this data is stored on the server, and the client gets a session id instead.
Every page which requires user authentication needs to check the client's session id (if any) towards the privileges of the user according to the database.
SQL Protection
For SQL protection, the database's native string escaping function should be used.
XSS Protection
Cross Site Scripting is certainly a concern, but content only needs to be filtered if it will be displayed to the user. If html support is needed, use the strip_tag function to limit what tags may be used. (One still has to wonder if code may still be exploited with a <p> tag for example.)
User Privileges / Permissions
The user priviledges/permissions system needs to be simple. The administrator shouldn't need to spend much time setting up user permissions. And permissions should be extendable.
For efficiency, every page that checks for user permissions/login should keep a global variable containing the user's info and group info, to avoid subsiquent database queries.
Simple Method
One way to work with the user permissions system could be as simple as this: Each user is assigned a group. Each group has its own permission rights (as table fields). Extensions may then alter permission tables for new fields.
On the other side, permissions are checked by comparing the user's session id to the corresponding user and group in the database.
Note that the admin categories could have a database field. Contained within this field for each admin category might be a name of a permission corresponding to those in the groups table. Pages that a user does not have permissions for will thus not be presented to the user.
More Complex Method
A second method might be to use the simple method above, but to assign each group a type:
- admin - Unrestricted access. Can login to admin panel. If an extension adds a new permission, all admin groups should have that permission.
- mod - Some access. Can login to admin panel. If an extension adds a new permission, mods should not have that new permission.
- user - Limited access. Cannot login to admin panel. If an extension adds a new permission, mods should not have that new permission.
Such a system would allow for different moderation (mod) levels of permissions if required. But for users who don't want to deal with permissions may simply use an admin account if they choose (such would be ideal in systems with only one user). Alternatively, a user could chose to only use an admin account when necessary, and may use an additional moderator account instead.
Theming System
General Theming
The QuateCMS will make use of a relatively simple theming system. Dynamic page text is controlled by inserting it into a page variable:
$pg['content'] .= "Add content";
It is up to the theme to display the page contents, among other elements such as the page's title:
<title><?php echo $pg['title']; ?></title> <!-- ... --> <?php echo $pg['content']; ?>
Admin Panel Theming
The admin panel will use the same theming idea, however, certain elements have been attached to CSS classes. As a result, theming the admin panel is a little more restricting. This is a difficult constraint to avoid.
Error Message Theming
Error messages may be customized using the same technique as website theming. One could quite easily make the error message theme the same as their website theme.
File Structure
Directories
File structure follows like so:
- admin/ - Where all admin panel files reside.
- includes/ - Framework files.
- includes/themes/ - Where themes are stored.
- incldues/scripts/ - Where scripts and libraries are stored.
- docs/ - Documentation and licenses.
- install/ - Install script.
- upgrade/ - Upgrade script.
- cache/ - Cached files and settings are kept here.
Everything is centralized to the includes/ directory. Each file should have a location variable that specifies the location of this directory relative to the file:
$location = "./"; // ... require_once($location. "includes/functions.php");
Crucial Files
Some important files for the framework.
- includes/framework.php - Initiates everything.
- includes/functions.php - Contains common functions.
- includes/settings.php - Settings cache and initial configurations such as database connection info.
- includes/databases/*.php - Database classes.
Redundancy / Backups
Users should normally be preforming backups regularly. However, this process can be difficult and takes away from the user experience. Some sort of additional mechanism may need to be provided for saving database entries and settings.
Page Revisions
All old page text will be stored in a separate page table. If a user made a mistake, an older copy has been saved. Additionally, the user may compare revisions and revert back to previous versions at ease.