==== Solar App from Scratch - part 1 ==== === First words === 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 [[http://solarphp.com/manual|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 [[http://solarphp.com/manual/Getting_started/Skeleton_app|Minimal Application Skeleton]]. You'll need your own "Vendor" directory with an unique name to apply the tricks described here.

Note

Choose a nice vendor name and let us know about it! Read more on Creating Your Own Vendor Namespace and check the class list for some of the existing vendors.

=== Spicy trick #1: call your vendor main class in the bootstrap === == Bootstrap Script from Solar manual == The first time you ran Solar, you probably created a Bootstrap Script as described in [[http://solarphp.com/manual/Getting_started|Getting Started with Solar]]. Something like this: 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. == A new Bootstrap Script == 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): run('config.php'); There are several benefits of doing this. Here are some of them: * One bootstrap to rule them all. It's good to have a bootstrap that never, absolutely never changes - except for the include path, in some cases, but even it should be more or less 'static'. The bootstrap provided in the manual is simple to make easy starting with Solar. Here we intend to encapsulate that code and provide a bit of flexibility while keeping our bootstraps always the same, everywhere. * The main purpose is to not add any specific logic or system definitions in the bootstrap. Doing this we centralize app configuration in the config file, and that's all. If we need to call a different controller or initialize something different, we add a hook or a configuration to our main class. * Since Solar initialization is encapsulated, we can use different front controllers or hook more initialization stuff, as we will do later: * initialize benchmark, log, plugin systems, localization based on IP ranges etc; * use different front controllers. * (add more benefits! :) 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 [[http://solarphp.com/manual/Getting_started|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. :) == Adding some spice == 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 [[http://www.solarphp.com/class/Solar_Controller_Front|Solar_Controller_Front]].

Note

All Solar classes, except Solar itself and exceptions, descend from Solar_Base. You should always follow this convention and extend all your vendor classes from Solar_Base. If not directly, you should do this extending other Solar class.

Normally we extend everything from [[http://www.solarphp.com/class/Solar_Base|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: '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(); } }

Note

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 Base Class.

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': 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.

Stay tuned!

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.

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. :)