Solar

Multiple Database Connections with Solar Dependency Injection

Posted in PHP, Solar on February 24th, 2011 by Jon – 1 Comment

In an email the other day, a person asked about being able to connect to multiple databases in Solar. While this is quite easy to do, it probably isn’t officially documented anywhere. If you poke around in Solar’s code, you will soon discover that it can be accomplished using dependency injection (technically this is a combined dependency injection and service locator).

Each of your application’s models extend the Solar_Sql_Model class. If you examine the Solar_Sql_Model class, you’ll notice that one of the config elements is ‘sql’. This is a key that refers to a Solar dependency. The default value for this is key is ‘sql’. That might seem strange at first. How is the string ‘sql’ a dependency? Well, first, we need to dig into the Solar_Sql_Model class. In the _preSetup() method there is a call to Solar::dependency(), which populates the $_sql property using the config[‘sql’] element.

protected function _preSetup()
{
...
// connect to the database
$this->_sql = Solar::dependency('Solar_Sql', $this->_config['sql']);
}

The first parameter is a hint to the the type of object, and the second is either an object OR a string that refers to an object in Solar’s registry. If you remember, the default value of Solar_Sql_Model’s ‘sql’ config element was a string ‘sql’. Therefore, there must be an object in Solar’s registry named ‘sql’. If not, Solar will throw and exception.

If you look at the Solar vendor’s default config (SYSTEM/source/solar/config/default.php) you will see the following:

$config['Solar']['registry_set'] = array(
    'sql'=>'Solar_Sql',
    'user'=>'Solar_User',
    'model_catalog'=>'Solar_Sql_Model_Catalog',
    'mail_transport'=>'Solar_Mail_Transport',
    'controller_front'=>'Solar_Controller_Front',
);

The ‘sql’=>’Solar_Sql’ tells Solar to register a Solar_Sql object in the registry keyed on the string ‘sql’. If you look again at the default.php config file, you should see a config entry for for Solar_Sql where you can define the options for the Solar_Sql object.

/**
* sql adapter to use
*/
$config['Solar_Sql'] = array(
    'adapter' => 'Solar_Sql_Adapter_Sqlite',
);

That is the background information. To summarize what we now know…

  1. Solar’s models connect to the database using a dependency injection/service locator keyed on the string ‘sql’.
  2. Because the default value for the ‘sql’ key is the string ‘sql’, then we know we are looking for something located in Solar’s registry.
  3. Looking at the Solar default.php config file, we see that there is a ‘registry_set’ config element indicating that ‘sql’ should be registered in the registry as a Solar_Sql object.
  4. Finally, the Solar_Sql object is also configured in the default.php file, and in our example, it is configured to use Solar_Sql_Adapter_Sqlite as its adapter class.

Understanding how this works, we can start setting up other sql dependencies to be used by our models. Here is one way you can do it.

First, we need to add another item to our registry. We can call it ‘sql_acme’. One thing to note is that you can specify an array as its value in the registry, not just a class name. It might look like this:

// configuration for the acme Solar_Sql object to be added to the registry
$sql_acme = array(
    'adapter'=>'Solar_Sql_Adapter_Mysql',
    'host'=>'localhost',
    'name'=>'acme',
    'user'=>'juser',
    'pass'=>'S3cr3t'
);
 
// define what will be added to the regsitry
$config['Solar']['registry_set'] = array(
    'sql'=> 'Solar_Sql',
    'sql_acme'=>array('Solar_Sql', $sql_acme),
    'user'=> 'Solar_User',
    'model_catalog'=>'Solar_Sql_Model_Catalog',
    'mail_transport'=>'Solar_Mail_Transport',
    'controller_front'=>'Solar_Controller_Front',
);

Now, we need to tell Solar what registry entry to use for one of our models. You can set that up like this. Assume the model is for a table of articles.

$config['Acme_Model_Articles']['sql'] = 'sql_acme';

That’s all there is to the setup and configuration. There is, however; one important thing to keep in mind. If you are using Solar’s command line tools to create your models then, by default, Solar will use the default ‘sql’ dependency since it can’t read the configuration for a model that doesn’t yet exist. Luckily, you can specify the required configuration options at the command line. For example, if your user credentials and host were the same for both databases, and the only difference was the database name, then you could do this:

$ ./script/solar make-model Acme_Model_Articles --name acme

If you want to know all the options available to the make model (or any) command, use the following:

$ ./script/solar help make-model

So that is one way you can set up multiple databases at the model level in Solar. You can also set up multiple databases for each vendor. I will save that for another post.

SimpleXML + Solar’s Alternate Formats = Easy RSS

Posted in PHP, Solar on February 17th, 2011 by Jon – 1 Comment

Creating your own RSS feeds is generally straightforward, but it’s even easier when you combine PHP’s SimpleXML and Solar’s alternate format mechanism.

If you are new to Solar, you better check out the manual.

Setup Solar

Solar makes it easy to specify an alternate format simply by changing the extension of your request. For example, say you have a list of articles at

http://www.example.com/articles/browse

Here, “articles” refers to the controller, and “browse” refers to the action. By default, no format was explicitly specified, so the default text/html is used when outputting the content to the browser. If you wanted to use an alternate format, you can specify the format by using an extension. Here are a couple of examples:

  • http://www.example.com/articles/browse.rdf (application/rdf+xml)
  • http://www.example.com/articles/browse.xml (application/xml)

Before these will actually work, you have to perform a couple of tasks in your Solar environment.

First, you need to tell Solar that a given format (or formats) are allowed for a given action. Do this by adding code to the top of the Articles.php application controller.

<?php 
protected function _setup()
{
    // chain to parent
    parent::_setup();
 
    // allow xml and rdf formats for the browse action
    $this->_action_format = array(
        'browse'=>array('xml', 'rdf')
    );
}
?>

Second, you need to create an appropriate view for each format specified. In the example above, you need two new views. One for the xml format, and one for the rdf format. The naming convention for each view is as follows:

  • browse.xml.php
  • browse.rdf.php

Now, when browsing to http://www.example.com/articles/browse.xml, Solar will use the browse.xml.php view and output accordingly.

Create Markup with SimpleXML

Before using SimpleXML to format the xml output, it’s assumed that we have a collection of article records to work with, and that they are available to the view as $this->list.

Inside the browse.xml.php file…

<?php
 
// Get the current URI
$uri = Solar::factory('Solar_Uri_Action');
$uri->format = null; // reset the format
$link = $uri->get(true); // get the full uri, including http:// etc
 
$xml = new SimpleXMLElement('<rss version="2.0"></rss>');
$channel = $xml->addChild('channel');
$channel->addChild('title', 'My RSS Feed');
$channel->addChild('link', $link);
$channel->addChild('description', 'My RSS feed about something of interest');
$channel->addChild('language', 'en-ca');
$channel->addChild('pubDate', $this->list[0]->date_added); // assume the list in chronologically ordered
$channel->addChild('lastBuildDate', $this->list[0]->date_added.' MST');
$channel->addChild('webMaster', 'me@example.com');
foreach ($this->list as $item) {
	$uri->path = 'articles/read/' . $item->getPrimaryVal(); // set up the path to each article
	$title = $channel->addChild('item');
	$title->addChild('title', $this->escape($item->title));
	$title->addChild('link', $this->escape($uri->get(true)));
	$title->addChild('description', $this->escape($item->description));
	$title->addChild('pubDate', $this->date($item->date_added, "D, d M Y")); // Solar's date() view helper
}
echo $xml->asXML();
?>

And that’s basically all there is to it! Browse to http://www.example.com/articles/browse.xml and you should see an xml version of the page.

References

Add validation filters before saving in Solar

Posted in PHP, Solar, Uncategorized on October 22nd, 2010 by Jon – Be the first to comment

I have preached about how Solar makes my web development life so much easier, and here is another example of why.

Every once in a while, I have to add or modify my record validation before it is saved in the database. For example, I am working on a publication database where a publication has several availability “flags”, such as

  • available as pdf,
  • available in print,
  • available as pdf by email

In this scenario, all three can be “unchecked”, however; available as pdf and available as pdf by email can NOT both be checked. So, to validate that, I use a pre-save hook in the publication record class and set a filter.

<?php
class Bookstore_Model_Publications_Record extends Bookstore_Sql_Model_Record
{
    protected function _preSave()
    {
        parent::_preSave();
        // Check to make sure that email_pdf and pdf are not both checked
	if ($this->_data['available_pdf'] == '1' && 
            $this->_data['available_pdf_email'] == '1') {
                $this->addFilter(
                    'available_pdf_email', 
                    'validateNotEquals', 
                    'available_pdf'
                );
	    }
	}
    }
}
?>

So, basically, before the record is saved, I look to see if available_pdf == 1 AND available_pdf_email == 1 and if so, add a new validation filter on available_pdf_email. The new filter is called “validateNotEquals” and you pass the name of a field you don’t want to allow it to be the same as. In this case available_pdf.

With this filter added, the record won’t save and will display an error message under available_pdf_email.

Simple.

Solar Framework Goes Beta

Posted in PHP, Solar on January 5th, 2010 by Jon – Be the first to comment

On January 1, 2010, the beta2 of the Solar MVC PHP framework was released. Additionally, a new “Beginner’s Guide” was posted, which will be a great help to anyone wanting to try out a great PHP Framework.

Happy new year!

Start Using a Top Quality Framework “Right Now”

Posted in PHP, Solar on November 13th, 2009 by Jon – Be the first to comment

Paul M. Jones has what I will call a “fun” post on is blog. There may be some “cheerleading”, but I welcome it. His post points to several areas where the Zend Framework (ZF) developers will be implementing approaches already available in Solar. This is by no means framework-bashing. It’s about letting people know that a top quality framework is available right now. So what are you waiting for? Get started.

Solar Alpha3

Posted in Solar on September 10th, 2009 by Jon – Be the first to comment

After about a year, Solar has moved from version 1.0.0alpha2 to 1.0.0alpha3. Yes, it’s been a while, but when you realize that only one person really works on the project in his spare time, that’s a pretty good achievement. This whole spare time thing is also changing. Solar is about to get a whole lot more attention now that the developer’s employer (OmniTI) has agreed to let him use up to 40% of his paid work time to further develop Solar. Obviously, OmniTI knows a good thing when they see it.

As of writing this, Paul hasn’t had time to update the Solar site with the latest download, but that will likely happen tomorrow. Additionally, there will be a nice post about what has changed. I will add some links when they are available.

Anyone who has used a PHP web framework before, or those who just wants to try one out, should give Solar a whirl. It is the most well-thought-out framework I have had the pleasure of using. What’s next for me? Time to checkout the latest from SVN and give it a work out. The faster we test it and iron out bugs, the sooner there will be a beta release. On that note, a beta release is actually not far off and (hopefully) by the end of the year, the official stable release will be available.

Using Solar Access Control

Posted in Solar on June 22nd, 2009 by Jon – 1 Comment

Introduction

Solar has a simple-to-use, role-based access control library. It is nicely integrated into the user object so getting it working is really just a matter of adding a few lines to your config file. Here is a quick rundown of how to get it working using the file adapter. This means your access control list and roles are stored in simple text files.

Setup

Create a file called acl.txt in your config folder
Create a file called roles.txt in your config folder

In the acl.txt file, add the following lines:
allow handle juser * *
allow handle jdoe Vendor_App_Example add
allow handle + Vendor_App_News browse
deny role banned * *

The file format is like this: 0:flag 1:type 2:name 3:class 4:action 5:process
Although I don’t believe that process is currently used.

  1. Flag is either allow or deny
  2. Type is handle, role, or owner
  3. Name is the userid of the person (not used for type owner)
  4. Class is the name of the class you are adding access control to
  5. Action is the action of the access control (edit, add, delete, etc)

allow handle juser * *
means allow user juser access to all classes and all actions.

allow handle jdoe Vendor_App_Example add
means allow user jdoe to the add action in Vendor_App_Example

Wildcards * and + can be used too. For example, a + symbol in the name field means any logged in user.

Now add the following line to your roles.txt
banned:gijoe

The format is role:userone,usertwo,userthree

Now add a few lines to your config, assuming you already have the Solar_Auth config previously set up.

$config['Solar_Role']['adapter'] = 'Solar_Role_Adapter_File';
$config['Solar_Role_Adapter_File']['file'] = "$system/config/roles.txt";
 
$config['Solar_Access']['adapter'] = 'Solar_Access_Adapter_File';
$config['Solar_Access_Adapter_File']['file'] = "$system/config/acl.txt"

Checking Access

In a controller, just add this to one of your actions (for example, actionBrowse()):

if (Solar_Registry::get('user')->access->isAllowed(get_class($this), 'browse')) {
    // browse logic
}
else {
    // access denied logic
}

Or, better yet, follow the _preAction() method in Solar_Base.

protected function _preAction()
{
    $allow = Solar_Registry::get('user')->access->isAllowed(
        get_class($this),
        $this->_action
    );
 
    if (! $allow) {
        $this->errors[] = $this->locale('ERR_NOT_ALLOWED_ACCESS');
        $this->_action = 'error';
    }
}

Is Owner?

You can use the access control file to give object owners access to actions as well. If you want to use the isOwner() method, you will need to extend the Solar_Access_Adapter_File class and write your own isOwner() method.

Your acl.txt entry might look like this:

allow owner * Vendor_App_Example edit

This means allow the edit action to the owner of the object in question (like a record in from a database) within the Vendor_App_Example class.

You could extend the access adapter like this:

<?php
class Vendor_Access_Adapter_File extends Solar_Access_Adapter_File
{
    public function isOwner($content)
    {
        if ($content['owner'] == $content['user']) {
            return true;
        }
	return false;
    }	
}
?>

Then, to use this method, you can do the following:

$content = array(
			'owner'=>'juser', 
			'user'=>Solar_Registry::get('user')->auth->handle
		);
 
if (Solar_Registry::get('user')->access->isAllowed(get_class($this), 'edit', $content)) {
    // edit logic here
}
 
// or just do (assuming they made it this far)
if (Solar_Registry::get('user')->access->isOwner($content)) {
    // edit logic here
}

Well, that’s the basics.

Layouts

Posted in Solar on June 16th, 2009 by Jon – 1 Comment

A layout is basically a view (or collection of views) that wrap around controller specific content. They typically include the repeating parts of a website, such as the header, footer and navigation elements. I’ve written about them briefly in a previous post, but in this post, I will elaborate slightly.

This is the general approach I take when using views and layouts in Solar. This isn’t a CSS framework. This is just an approach to laying out files in such a way that they can be easily shared between various Solar applications.

Let’s start with a basic 2 colum site design where I have my site-wide navigation on the left, a header up on top, and the footer below. In the main column is the controller-specific content. Based on that information, I am going to create 6 individual layout files. That seems like a lot, but it will make more sense shortly.

The Files

The layout files are as follows:

  • 2col-navleft.php
    • _head.php
    • _body.php
      • _header.php
      • _footer.php
      • _nav.php

The main layout file is called 2col-navleft.php. It’s good to choose a descriptive name like this so you know what to expect from the layout. It has 2 columns and the navigation is on the left. This is also the name of the layout you specify in your Solar controllers. For example, your controller would have the following property:

protected $_layout_default = '2col-navleft';

Better yet, you might be using a “Base” controller that all your other controllers extend. In this way, all your child controllers will use the same layout by default. And, of course, you could change this at anytime. More about that later. For now, here is the contents of the main layout.

/**
 * File: 2col-navleft.php
 */
<!DOCTYPE html PUBLIC "-W3CDTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 
<?php
    // generate the <head>
    include $this->template('_head.php');
 
    // generate the <body>
    include $this->template('_body.php')
?>
 
</html>

Nice and simple. You’ve got the doctype and the html block. Within the html block, you can see how to include other layout pieces, such as _head.php and _body.php.

Here is what _head.php looks like. As you can see, its purpose is to create the <head> tags and all the stuff in between.

/**
 * File: _head.php
 */
<head>
<?php
// add meta tags
foreach ((array) $this->layout_head['meta'] as $val) {
    $this->head()->addMeta($val);
}
 
// set the title
$this->head()->setTitle($this->layout_head['title']);
 
// set the uri base
$this->head()->setBase($this->layout_head['base']);
 
// add links
foreach ((array) $this->layout_head['link'] as $val) {
    $this->head()->addLink($val);
}
 
// add baseline styles
$this->head()->addStyleBase("Vendor/styles/2col-navleft.css");
 
// additional baseline styles
foreach ((array) $this->layout_head['style'] as $val) {
    $this->head()->addStyleBase($val);
}
 
// additional baseline scripts
foreach ((array) $this->layout_head['script'] as $val) {
    $this->head()->addScriptBase($val);
}
// done!
echo $this->head()->fetch();
?>
</head>

This layout uses a nice view helper called Solar_View_Helper_Head ($this->head()…). This helper sets all the head elements and displays them in the correct order. A public property (layout_head) need to be set in order for this to work properly. The layout_head public property is an array.

The next file is _body.php. This file, as you can imagine, sets the content between the <body> tags. Here is what _body.php looks like:

/**
  * File:_body.php
  */
<body>
<div id="wrap">
    <div id="header">
	<?php include $this->template('_header.php'); ?>
    </div>
    <div id="nav">
	<?php include $this->template('_nav.php'); ?>
    </div>
    <div id="content">
	<div id="main">
	    <?php echo $this->layout_content; ?>
	</div>
    </div>
    <div id="footer">
	<?php include $this->template('_footer.php'); ?>
    </div>
</div>
</body>

Here, you can see several other includes that point to more “sub layouts”.

  • The _header.php file simply displays the header piece of the page.
  • The _nav.php displays the site-wide navigation.
  • At the bottom is the _footer.php file which displays the footer.
  • Finally, is the php statement which echos $this->layout_content. This is where the controller-specific content is displayed.

Of course, these are just the basic layouts you can use. You could add more layouts as you see fit. Things like an _auth.php layout, a _topnav.php layout, etc.

Vendor- and Application-specific Layouts

So, why break them into such small pieces? Well, for one, you could easily alter the overall structure of your site by using a different main layout (2col-navright.php or 2col-navtop.php). Or, you could implement a CSS framework such as the Stenhouse CSS Framework. Also, Solar enables a nice heirachy of includes that you can easily have a different _header.php and _nav.php layout for each vendor or even each application. Have a look at the following directory structure to help understand how that works. Let’s start the “include” folder.

include/
    Vendor/
        App/
            Base/
                Helper/
                Layout/
                    2col-navleft.php
                    _body.php
                    _footer.php
                    _head.php
                    _header.php
                    _nav.php
                Locale/
                View/
            Index/
                Helper/
                Layout/
                    _nav.php
                Locale/
                View/
    Solar/

In this example, let’s assume that our Vendor_App_Base class extends Solar_Controller_Page. That class specifies the default layout as 2col-navleft.

<?php
class Vendo_App_Base extends Solar_Controller_Page {
 
    protected $_layout_default = 'main';
 
    // The array needed in the _head.php layout
    public $layout_head = array(
        'title'  => null,
        'base'   => null,
        'meta'   => array(),
        'link'   => array(),
        'style'  => array(),
        'script' => array(),
        'object' => array(),
    );
.
.
.
}
?>

Vendor_App_Index extends Vendor_App_Base.

<?php
class Vendor_App_Index extends Vendor_App_Base {
     protected $_action_default = 'browse';
    public function actionBrowse()
    {
	// layout_head defined in parent class
	$this->layout_head['title'] = "Here is my happy site";
    }
.
.
.
}
?>

By default, any class that extends Vendor_App_Base will use the specified default layout (2col-navleft.php) and all sub layouts. However, In Vendor_App_Index_Helper, we have another _nav.php layout. Whenever you request the index application, this application-specific navigation layout will be used instead of that in the base application. Solar doesn’t need any explicit instructions to do this. It just knows.

Interacting with the Layouts (and Views)

As I have mentioned before, both Solar views and layouts have access to public properties in your controller (and those it extends). In the above example, $this->layout_head is a public property, therefore, the layouts and views have access to it via $this->layout_head. Knowing this should help the _head.php layout make even more sense.

Wrapping Up

Views and layouts aren’t too complex. The best way to learn them is to try it all out. The other really important thing you would be wise to learn about are view helpers.

View Helpers

Posted in Solar on June 6th, 2009 by Jon – Be the first to comment

View helpers are very useful for performing repetitive tasks and, more importantly, an essential way to keep domain logic out of your views. View helpers can be very simple, such as displaying a date in a particular format, or they can be quite complex, such as displaying a complete html form. Solar is packed with many very useful view helpers. Additionally, the way Solar applications are organized makes it easy to create your own view helpers and have them available to several applications.

To use a view helper, simply call it in your view. Take, for example, the title view helper bundled with Solar. This helper simply puts the <title> tags around whatever text you pass to it.

<html>
<head>
	<?php 
          // assume $pagetitle was set in the controller and is public 
        ?>
	<?php echo $this->title($this->pagetitle); ?>
</head>

Ok, so that is a very simple example that you might never use, but you never know. What is important in a helper like this is the automatic escaping of text.

One view helper that I use all the time is the action view helper (Solar_View_Helper_Action). This helper displays an escaped link with the properly formed <a> tags. It takes 3 parameters, the second and third are optional.
It works something like this:

<?php echo $this->action($spec, $text = null, $attribs = null); ?>

$spec is the link,
$text is the text (or a locale key for automatic translation),
$attribs is an array of option attributes to use in the link, such as class, style, or even onclick.

For example:

<?php // assume TEXT_BROWSE is a locale key and translates to 'Browse' ?>
<?php echo $this->action('index/browse', 'TEXT_BROWSE'); ?>

This will output:

<a href="/docroot/index/browse">Browse</a>

The docroot part comes from the uri action path in your config file: $config['Solar_Uri_Action']['path'] = ‘/docroot’;

What’s interesting here is that, if you dive into the code, the action helper actually refers to other helpers, actionHref and escape via the $this->_view property. Now you can see how powerful view helpers can be! In fact, many of Solar’s view helpers utilize other Solar view helpers. It just makes sense.

Writing your own view helpers is a snap. You can make them as simple or as complex as you like. Each time you create an application using Solar’s Command Line Interface (CLI), a Helper sub folder is creating in your application’s namespace. For example, if your vendor is named Vendor and your application is named Example, then the Helper folder will exist in a folder structure similar to this.

Vendor/
    App/
	Example/
	    Helper/
	    Layout/
	    Locale/
	    View/
	    Example.php

So, here is an example of a very simple view helper that will take a Canadian postal code in this format A1B2C3 and convert it to the proper A1B 2C3 format.
The helper file is named PostalCode.php and is located in the Helper sub folder of your application.

Here is what it might look like:

<?php
 
/**
 * View Helper to format a postal code from 6 alpha numeric 
 * characters without a space
 * to 6 with a space. T9E5W7->T9E 5W7
 */
class Vendor_App_Example_Helper_PostalCode extends Solar_View_Helper {
 
    public function postalCode($code)
    {
	// Get the first 3 chars (note the use of another 
        // view helper called escape)
	$first_three = $this->_view->escape(strtoupper(substr($code, 0, 3)));
 
	// Get the last 3 chars
	$last_three = $this->_view->escape(strtoupper(substr($code, 3, 3)));
 
	// Return the newly formated code with a space
	return $first_three."&nbsp;".$last_three;
    }
}
?>

To use this view helper in your view it’s as simple as:

<?php echo $this->postalCode($code); ?>

Another nice feature of view helpers is that they ultimately extend Solar_Base. This means they handle the config files just like all the other Solar classes. If you don’t know about Solar’s config file, then you should definitely read about it.

If you want to create a view helper that has a property that can be customized, then just follow Solar’s standards for classes and objects. Here is an example taken from Solar’s date view helper. I have simplified this from the real file.

<?php
class Solar_View_Helper_Date extends Solar_View_Helper
{
    /**
     * 
     * User-defined configuration values.
     * 
     */
    protected $_Solar_View_Helper_Date = array(
        'format' => 'Y-m-d',
    );
 
    public function __construct($config = null)
    {
        parent::__construct($config);
    }
 
    /**
     * 
     * Outputs a formatted date.
     * 
     */
    public function date($spec, $format = null)
    {
	if (! $format) {
		$format = $this->_config['format'];
         }
	return date($format, strtotime($spec));
    }
}
?>

As you can see, the default format is ‘Y-m-d’. But, that can be changed in 2 ways.
First, you can pass whatever format you want to the helper, and second, you can set a $config value in your config file to override the default.

In a view it would look like this:

<?php echo $this->date('Yesterday', 'm jS, Y'); ?>

If you changed the default in your config file, the file would have an entry like this:

<?php
$config['Solar_View_Helper_Date']['format'] = 'm jS, Y';
?>

That is the basic idea behind view helpers. Remember, if you need to access the current view object from within the view helper, you do so using $this->_view.
What’s really important is that these keep unnecessary logic out of the view!

A real Solar application

Posted in Solar on April 24th, 2009 by Jon – 2 Comments

I wrote a web-based application for my dad recently using, you guessed it, Solar. He had been using a really old version of Quattro Pro for keeping track of all his receivables, invoices, etc. He finally got a new computer, which was 64-bit and Vista, and he couldn’t even load Quattro Pro onto it, so it was time to find a new solution. This, IMHO, was a bit of a blessing. (Holy crap! I haven’t done my taxes yet!!!). Anyway, I offered to create a database and a web-based application that would sever existing ties between the data and presentation. He’s pretty clever, so that seemed like a great idea to him.

So I created the DB, which consisted of about 8 tables and 3 views. This isn’t rocket science, but it’s a great case for a relational database. Next, I whipped up a Solar application to keep track of clients, invoices, products, receivables, etc. It’s not fancy, but it works pretty well for a version 1. One of the coolest things about it – thanks to Solar, I didn’t write a single SQL query! The Solar models worked so well for me, that with a single fetch, I can get every bit of data I need, quickly and efficiently. They also make it dead simple to create or update data, complete with Super Awesome (yes, that’s capitalized and bold) form validation.

The next steps for the application will be to make it more user-friendly. It will be pretty easy to sweeten it up using jQuery UI and custom Solar view helpers. Maybe even a touch of Ajax.

Solar definitely makes my job easier.

Oh, and one of the best things about the application – it has the Solar Powered logo on it :)