Is this the best open source CMS ever created?
Meet TYPOlight, a powerful Web content management system that specializes in accessibility (back end and front end) and uses XHTML and CSS to generate W3C/WAI compliant pages.
Accessibility
A growing number of countries around the world have introduced legislation which either directly addresses the need for websites to be accessible to people with disabilities, or which addresses the more general requirement for people with disabilities not to be discriminated against. TYPOlight does not treat accessibility as just an additional feature and is thoroughly accessible.
Web 2.0
PHP 5 and Ajax are modern “Web 2.0″ technologies that you can find in a lot of contemporary applications. TYPOlight has a solid codebase built on the new object-oriented programming features of PHP 5 and can therefore be considered a future-proof software. To ensure back end accessibility, every Ajax feature includes a graceful fallback in case JavaScript is disabled.
Page features
- Different page types
- Multiple websites in one tree
- Manual or timed publication
- Hidden pages
- Password protect pages
Editing features
- Clipboard feature
- Edit multiple records
- Built-in rich text editor (TinyMCE)
- Different content elements and modules
- Multilingual spellchecker
- Insert tags (similar to server side includes)
- Manual or timed publication
File manager
- Multiple file uploads
- Image thumbnails and file preview
- Edit uploaded files with the source editor
- File operation permissions
- Copy, move, rename files or folders
- Delete folders recursively
Form generator
- Automatic input validation
- Store uploaded files on the server
- Send form data via e-mail
- Send uploaded files as e-mail attachment
Search engine
- Automatic page indexing
- Search indexing on protected pages
- Phrase search, wildcard search, AND/OR search
- Search result caching and pagination
Full feature list
- Intuitive user interface
- Accessible XHTML strict output
- Meets W3C/WAI requirements
- Web 2.0 support (mootools-based)
- Live update service
- Accessible administration area
- Multiple back end languages and themes
- Generates search engine friendly URLs
- Multi-language support
- Powerful permission system
- Versioning and undo management
- Advanced search and sorting options
- Front end output 100% template based
- Automatic e-mail encryption (spam protection)
- Supports SMTP in addition to PHP’s mail function
- Supports multiple websites in one tree
- Supports GZip compression
- Print articles as PDF
System features
- Open Source (LGPL)
- Web-based administration
- Platform independent
- Over 150 third party extensions
- Multilingual documentation
Links
E-Books Directory: More than 300 free programming books
Here is a categorized list of online programming books available for free download. The books cover all major programming languages: Ada, Assembly, Basic, C, C#, C++, CGI, JavaScript, Perl, Delphi, Pascal, Haskell, Java, Lisp, PHP, Prolog, Python, Ruby, as well as some other languages, game programming, and software engineering. The books are in various formats for online reading or downloading.
Real Time Web-Based Service Monitoring Tool
phpWatch is a general purpose service monitor that is able to send notifications of outages via e-mail or text-message (SMS). The purpose of this system is to allow administrators to easily check the status of many different services running on any number of servers and also allow developers to interface with the query and notification APIs.
Installation
The basic installation is very simple: chmod config.php to 777 and simply navigate to the install directory in your browser. Fill in the database information and the setup will create the required tables and setup the configuration file as needed. The only required task beyond the automated install is to add cron.php as a cron job (Unix/Linux) or scheduled task (Windows).
SMS Alerts
phpWatch uses pre-existing SMS gateways provided by the cell-carriers themselves. For example, to send a message to a Verizon subscriber with the phone number 123-456-7890, an e-mail can be sent to 1234567890@vtext.com and it will then be forwarded to the individual’s phone.
Links
New Zend Framework Book Published
This book shows you how to build websites fast using PHP and MySQL. What’s more, it shows you how to supercharge your use of these technologies by taking advantage of a powerful, free web development solution known as the Zend Framework, which helps developers build websites with speed and efficiency.
This book embraces a teaching strategy of learning by doing, showing you how to build website features you’ll actually want to use within your own websites. Among other things you’ll learn how to manage data submitted through web forms, send unformatted and HTML e-mails through your website, manage user registrations, logins, and recover forgotten passwords, and even create the structure for a simple social network.
Along the way, you’ll learn how to take advantage of popular online services such as Google Maps, Amazon Web Services, the Facebook Platform, and PayPal to create even more compelling websites.
Yahoo Open Hack 2009 London
Come and join Yahoo! on the 9th and 10th of May in London for 24 hours of learning, hacking, networking and fun.
It’s a two-day event on Saturday 9th of May with a morning of Tech Talks covering a wide range of topics led by some of the Web’s most respected developers. Yahoo will showcase the newest platforms and developer tools for you to play around with, and there will be plenty of experts on hand to answer questions.
PHP Support in Google App Engine
Google App Engine now supports Java, this means that you can write PHP applications using Quercus: Demo script
The App Engine SDK for Java includes:
- A Web application and Web server (Jetty) that emulates all App Engine services on your local development machine.
- All the APIs and libraries available on App Engine.
- Support to upload your application to App Engine.
Learn how to run PHP with Quercus in Jetty Web Server.
An Alternative to Zend_Controller: The Model
Part 1 – An Alternative to Zend_Controller: Introduction
Part 2 – An Alternative to Zend_Controller: The Router
Domain Layer
The domain layer is separated from the other layers and has no dependencies on Zf_Controller.
app/
domain/
Model/
User.php
UserDao.php
lib/
Zend/
Zf/
Adding the domain directory to your include path allows you to load and access Model classes from anywhere within your project:
Bootstrap file
set_include_path(APPLICATION_PATH . '/../lib'
. PATH_SEPARATOR . APPLICATION_PATH . '/../domain);
Index Controller
class IndexController extends Zf_Controller_Action
{
public function indexAction()
{
// DAO pattern
$dao = new Model_UserDao();
...
}
}
The getInstance() method can be used to set or retrieve a singleton instance of a Model class:
class IndexController extends Zf_Controller_Action
{
public function indexAction()
{
$dao = $this->getInstance('Model_UserDao');
// or...
$dao = new Model_UserDao();
$this->setInstance($dao);
$this->userAction();
}
public function userAction()
{
$dao = $this->getInstance('Model_UserDao');
...
}
}
Below is an example of the UserDao class that contains methods to insert, update, and retrieve data:
class Model_UserDao extends Zf_Persistence_Db_Adapter
{
public function find($id)
{
$db = $this->getAdapter();
...
}
}
abstract class Zf_Persistence_Db_Adapter
{
protected $_db = null;
public function setAdapter(Zend_Db_Adapter_Abstract $db)
{
$this->_db = $db;
}
public function getAdapter()
{
if (null === $this->_db) {
if (!Zend_Registry::isRegistered('Zend_Db')) {
throw new Zf_Persistence_Exception('...');
}
$this->setAdapter(Zend_Registry::get('Zend_Db'));
}
return $this->_db;
}
}
More Info
An Alternative to Zend_Controller: The Router
Part 1 – An Alternative to Zend_Controller: Introduction
Here’s the good news: Zf_Controller doesn’t have a Router. It uses a very simple mapping to determine the name of the controller and action. Optionally, you may define parameters in the URI, for example:
http://domain.com/controller/action/value1/value2
An example of how routes are matched:
URI: http://domain.com/news/tag/zend-framework
Controller
class NewsController extends Zf_Controller_Action
{
public function tagAction()
{
print_r($this->_getAllParams());
}
}
Outputs
Array
(
[controller] => News
[action] => tag
)
Variable Defaults
It is often helpful to be able to assign default values to parameters that aren’t passed, that way we don’t have to check if the parameter has been set or not. The $_params property is an array with keys representing variable names and default values.
URI: http://domain.com/news/tag/zend-framework
Controller
class NewsController extends Zf_Controller_Action
{
protected $_params = array(
'name' => null,
'show' => 10
);
...
}
Outputs
Array
(
[controller] => News
[action] => tag
[name] => zend-framework
[show] => 10
)
A parameter sent via the URI will always overwrite a default parameter. That’s the whole point of using default values.
Variable Requirements
The $_paramsMatch property is used to set variable requirements. These are defined as parts of a regular expression:
URI: http://domain.com/news/tag/zend-framework/50
Controller
class NewsController extends Zf_Controller_Action
{
protected $_params = array(
'name' => null,
'show' => 10
);
protected $_paramsMatch = array('show' => '\d+');
...
}
In the example above, Zf_Controller will assign the value to the “show” variable only if the value is a number. If not, it will assign the default value, in this case “10″.
If you think that you need more flexibility than this, I suggest extending Zend_Controller_Action instead.
An Alternative to Zend_Controller: Introduction
Zend Framework is very flexible and one of its strengths is that it allows developers to implement their own components. The Zend_Controller component, for example, is very powerful. Of course, it’s not my intention to replace it, but to offer an alternative that decreases the number of decisions a developer needs to make when developing an application.
Meet Zf_Controller. The Zf_Controller component has the following goals:
- Abstract complexity: Try to reduce the level of details so the developer can focus on a few concepts at a time.
- Emphasize Convention over Configuration: Emphasize CoC, meaning that the user only needs to specify unconventional aspects of the application.
- Maintain backwards compatibility: Allow the developer to replace Zf_Controller with Zend_Controller in case the application grows in size or complexity.
- Improve performance: Load less classes, execute less code.
- Remove circular references: Avoid circular references.
- Remove Singleton classes: Avoid implementing the Singleton pattern.
- Research: Learn more about the framework, what it does, how it works.
Project Structure
Zend_Controller allows you to use the project structure that best suits your needs. On the other hand, Zf_Controller is more rigid, it only allows you to use the standard project structure:
project/
app/
config/
controllers/
ErrorController.php
IndexController.php
views/
layouts/
scripts/
error/
index/
index.phtml
domain/
Model/
Example.php
lib/
Zend/
Zf/
Zf_Controller classes:
Zf/
Controller/
Action/
Helper/
Layout.php
Action.php
Front.php
Bootstrap File
Zend_Controller:
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../app'));
set_include_path(APPLICATION_PATH . '/../lib'
. PATH_SEPARATOR . get_include_path());
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$routes = include_once APPLICATION_PATH . '/config/routes.php';
$router->addRoutes($routes);
$layout = Zend_Layout::startMvc();
$layout->setLayoutPath(APPLICATION_PATH . '/views/layouts');
$frontController->dispatch();
Zf_Controller (no Router):
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../app'));
set_include_path(APPLICATION_PATH . '/../lib'
. PATH_SEPARATOR . APPLICATION_PATH . '/../domain);
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$frontController = new Zf_Controller_Front();
$frontController->setLayoutPath(APPLICATION_PATH . '/views/layouts');
$frontController->dispatch();
Action Controller
The default action controller and the default action are named “index”:
class IndexController extends Zf_Controller_Action
{
public function indexAction()
{}
}
Error Controller
Zend_Controller:
class ErrorController extends Zend_Controller_Action
{
// Action used by Zend_Controller
public function errorAction()
{
$error = $this->_getParam('error_handler');
echo $error->exception->getMessage();
}
}
Zf_Controller:
class ErrorController extends Zf_Controller_Action
{
// Action used by Zf_Controller
public function indexAction($e)
{
echo $e->getMessage();
}
}
Rendering a View Script
Zf_Controller does not use the ViewRenderer helper class. To make the code more readable and testable, you need to call the render() method and return a value:
class IndexController extends Zf_Controller_Action
{
public function indexAction()
{
$view = $this->initView();
$view->message = 'Hello';
// Renders views/scripts/index/index.phtml
return $this->render();
}
public function testAction()
{
$view = $this->initView();
$view->message = 'Goodbye';
// Renders views/scripts/index/index.phtml
return $this->render('index');
}}
index.phtml file:
<p><?php echo $this->message ?></p>
Using a Layout
By setting the path to your layouts in the Bootstrap file, you automatically enable the default layout “layout.phtml”:
$frontController = new Zf_Controller_Front(); $frontController->setLayoutPath(APPLICATION_PATH . '/views/layouts');
To disable the layout:
class IndexController extends Zf_Controller_Action
{
protected $_isLayoutEnabled = false;
}
To use a different layout:
class IndexController extends Zf_Controller_Action
{
protected $_layoutScript = 'main.phtml';
}
main.phtml file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <?php echo $this->headTitle() ?> <?php echo $this->headScript() ?> <?php echo $this->headStyle() ?> </head> <body> <div id="content"><?php echo $this->layout()->content ?></div> </body> </html>