bueller.ca

the digital workshop of Matt Ferris

Wireframe

Release
0.5
Language(s)
PHP
Requirements
PHP 5.2+
Download
tgz
Contribue
GitHub

Wireframe is a lightweight MVC framework for PHP. In addition to MVC, it has a primitive persistence layer, provides dependency injection, session management and class autoloading. It's written with Domain Driven Development in mind.

Getting Started

Let's create a HelloWorld app. First, we'll start by creating a new namespace for out app in Classes/HelloWorld by simply creating the Classes/HelloWorld directory.

Next, we need to create a controller to handle requests. Create the file Classes/HelloWorld/Controllers/DefaultController.php and add the following code.

<?php

namespace HelloWorld\Controllers;

class DefaultController extends \ca\bueller\Wireframe\MVC\Controller
{
    public function DefaultAction ()
    {
    }
}

With our controller setup, we need to create the corresponding view. Create the file Resources/Public/Views/Default/Default.php and add the following.

<html>
<body>
<h1>Hello world!</h1>
</body>
</html>

Finally, we need to let Wireframe know where to find our controller. We do this in Config/settings.php by setting $settings['mvc']['controllerNamespace'] to \HelloWorld\Controllers.

That's it, you've just created your first Wireframe app! Of course, there's many more aspects to the framework, read on for details.

MVC

Controllers and actions are parsed from the path info passed by the web server. Continuing with our HelloWorld app above, a request for http://example.com/wireframe/index.php/Foo/Bar would call \HelloWorld\Controllers\Bar::FooAction().

Each Controller's action has a corresponding View associated with it. On instantiation, the controller is injected with action's View which is available via $this->view. Views can be assigned variables which are then made available to the View's template.

public function SomeAction ()
{
    $this->view->assign('foo', 'bar');
}

In the View template, variables are accessible in the local scope.

<!-- View template for BazController->SomeAction -->
<h1>Some page</h1>
<p><?php echo $foo; ?></p>

At the moment, only PHP templates are supported. If you wanted to use a different template engine such as Smarty, you could the MVC\View class.

<?php

namespace Foo\Bar;

class SmartyView extends \ca\bueller\Wireframe\MVC\Router
{
    public function render ()
    {
        // Load smarty
        // Render template ($this->templateFile)
        return $renderedContent;
    }
}

Then just configure Wireframe to use the new SmartyView class.

$settings['mvc']['viewClass'] = '\Foo\Bar\SmartyView';

If you want to protect the content served by the controller, you can extend \ca\bueller\Wireframe\MVC\ProtectedController instead. When an unathenticated user tries to access a ProtectedController, they are redirected to a URL of you're choosing (like a login page).

<?php
/*
 * This controller requires authentication before viewing
 */
namespace Foo\Bar;
class BazController extends \ca\bueller\Wireframe\MVC\ProtectedController
{
    /*
     * Set the redirect URL to the login page
     */
    protected $__authUrl = 'login.php';

    ...

Domain Driven Design

Wireframe is built with Domain Driven Design (DDD) in mind. As such, it supports key aspects of DDD.

Loose coupling

\ca\bueller\Wireframe\ObjectManagement\ObjectFactory utilizes the Factory Pattern to create objects. You can configure objects to be singletons. Objects are referenced by an arbitrary name, decoupling objects from their fully qualified class names and allowing easy substitution of other objects in their place.

/*
 * Creating an object using the ObjectFactory
 */
$foo = ObjectFactory::getInstance('Foo');

ObjectFactory is instructed how to create objects via ObjectFactoryBindings.

/*
 * A basic object binding
 */
$fooBinding = new ObjectFactoryBinding('\Project\FooClass');
ObjectFactory::registerBinding('Foo', $fooBinding);

The above code registers the \Project\FooClass with ObjectFactory and can now be called via Foo using the ObjectFactory::getInstance() method. You could set FooClass to be a singletone by calling $fooBinding->setSingleton(true).

Dependency Injection

Object dependencies can be injected via constructors and setters and are configured via ObjectFactoryBinding.

/*
 * Inject dependencies
 */
$fooBinding = new ObjectFactoryBinding('\Project\FooClass');
$fooBinding->setConstructorArgs(array($arg1, $arg2, $arg3));
$fooBinding->setSetterArgs(array(
    array('setBar', array('arg1', 'arg2')),
    array('setBaz', array('arg1', 'arg2'))
    );
ObjectFactory::registerBinding('Foo', $fooBinding);

Comments