This is intended to be a series of tutorials with tricks to work with Solar. At the end we should have a working app, built step by step. Although I may cover some basic Solar topics, it is expected that you have read the official manual and have setup Solar at least once, to see how it is done.
So, if you haven't done it yet, go and build a Minimal Application Skeleton. You'll need your own “Vendor” directory with an unique name to apply the tricks described here.
<div style="border:1px solid #00A2E6; background:#DBF2FF;padding:10px"> <h4 style="color:#005180;margin:0;">Note</h4> <p style="margin:0">Choose a nice vendor name and let us know about it! Read more on <a href="http://solarphp.org/wiki/GettingStarted/CreatingYourOwnVendorNamespace">Creating Your Own Vendor Namespace</a> and check the <a href="http://solarphp.org/wiki/ClassList">class list</a> for some of the existing vendors.</p> </div>
The first time you ran Solar, you probably created a Bootstrap Script as described in Getting Started with Solar. Something like this:
<?php // $INCPATH is the the path to where Solar is installed, // typically the PEAR PHP directory. set_include_path($INCPATH); // Load and start Solar. Be sure to point to the proper // location of your Solar.config.php file. require_once 'Solar.php'; Solar::start('/path/to/config/Solar.config.php'); // Instantiate and run the front controller. $front = Solar::factory('Solar_Controller_Front'); $front->display(); // Done! Solar::stop();
Now, after I've asked you twice to follow the manual, I'll suggest that you should do some things differently. :) The manual covers the basics to setup and run Solar as it is; here I'll add some spice and share some tricks to setup a vendor prepared to run multiple apps across multiple domains, subdomains, etc.
Here we go: the first trick is to use a different bootstrap, calling your Vendor main class instead of Solar directly. Here's the bootstrap I use (these examples refer to my vendor name which is “Tipos”; adapt the code to use yours):
<?php set_include_path( // ... define your include path ); // Load, build and run Tipos. require 'Tipos.php'; $tipos = new Tipos(); $tipos->run('config.php');
There are several benefits of doing this. Here are some of them:
I hope this makes sense. If not, later on this series I'll show how this can be useful. For now, let's suppose you agree with this and want to use this strategy. :) How would you vendor main class look like? [wiki:tutorials/SolarAppFromScratch_1_SimpleVendorClass Take a look here for a simple one]. As you see, it doesn't change very much from using the bootstrap described in the manual. We have just moved things from one place to another, and this doesn't help very much - except that it'll make us proud of running our own vendor classes. :)
To add more flexibility, let's allow our vendor class to use a configurable front controller. To do this, we'll use some more tricks. Now the class will extend Solar_Base and will be able to use standard Solar exceptions, localization and the $_config property that every class extended from it has. The front controller class will be defined there in the config; by default it will be Solar_Controller_Front.
<div style="border:1px solid #00A2E6; background:#DBF2FF;padding:10px"> <h4 style="color:#005180;margin:0;">Note</h4> <p style="margin:0">All Solar classes, except Solar itself and exceptions, descend from Solar_Base. You should <strong>always</strong> follow this convention and extend all your vendor classes from Solar_Base. If not directly, you should do this extending other Solar class.</p> </div>
Normally we extend everything from Solar_Base and just enjoy the utilities and conventions it provides. The problem here is that we are building a system initialization class that extends Solar_Base before Solar was even started - so we can't use system configurations defined in the config file. To do this we need a trick: set an empty constructor and “construct” our vendor object later, after Solar was started, using the configuration array that we can get directly from Solar. Sounds complicated? I hope not, because it looks simple, see:
<?php /** * @uses Solar. */ require 'Solar.php'; /** * * Tipos base class. * * @category Tipos * * @package Tipos * */ class Tipos extends Solar_Base { /** * * User-defined configuration array. * * Keys are ... * * `front_class` * : (string) Front controller class name. * * @var array * */ protected $_Tipos = array( 'front_class' => 'Solar_Controller_Front', ); /** * * Constructor. Empty to avoid parent construction, which is done on run(). * */ public function __construct($config = null) { } /** * * Starts Solar and the front controller. * * @param string|array $config Config file path or config array. * */ public function run($config = null) { // Start Solar. Solar::start($config); // Do the parent construction using the config from this class. parent::__construct(Solar::config('Tipos')); // Start the front controller. $front = Solar::factory($this->_config['front_class']); // Display the page. $front->display(); // Done! Solar::stop(); } }
<div style="border:1px solid #00A2E6; background:#DBF2FF;padding:10px"> <h4 style="color:#005180;margin:0;">Note</h4> <p style="margin:0">The $_Tipos property in the class above comes from a Solar convention: the property that stores the configuration values for a class is always named with "_" (underscore) plus the class name. Read more about this topic in <a href="http://solarphp.com/manual/Project_standards/Base_class">Base Class</a>.</p> </div>
Until now at least one benefit was added: using the same Bootstrap Script on different sites, you can change the front controller that will be used just setting a new value in the configuration file. In this example we set a different front controller to be used, 'Vendor_Controller_Front':
<?php $config = array(); // Set the front controller. $config['Tipos']['front_class'] = 'Vendor_Controller_Front'; // ... other configuration values return $config;
See? The default front controller value can be easily overriden. For me just this little change made the main vendor class worth, but it will also be useful when we start to use different uri routing strategies, or to implement a benchmark system, later in our next tutorials.
<div style="border:1px solid #FF6600; background:#FFFFCC;padding:10px"> <h4 style="color:#FF6600;margin:0;">Stay tuned!</h4> <p style="margin:0">The vendor main class is what we need to change the uri scheme for different sites just changing their configs. We'll setup our app in the next tutorial, and then we will demonstrate how to move from a path to a subdomain based uri scheme without much effort.</p> </div>
Let me know what you think and don't hesitate to fix or improve this tutorial. Also feel free to use the code posted here on your own vendor classes, and please post what you have improved or done differently.
This is just a small tutorial but I hope it'll grow. See you later then. :)