Discrete Yii Projects Based on a Common Core


    Good evening to all habrayuzery!

    I want to share certain ideas and ideas on the topic of creating separate projects in Yii based on one common core.

    Some time ago, when I switched from kohana to yii for work, I was happy for a long time with its simplicity and convenience, which, it seemed to me, were many times more than that of a kohana (lovers forgive this framework forgive me), and then, all for that the same working need, I had to delve into the architecture of Yii, and, in particular, in the possibility of distributing his projects from one separate kernel.

    Initially, what is called “out of the box”, Yii already comes in separate folders with the kernel itself and several demo projects on it, but this wasn’t enough for me, since I needed several other project management and control capabilities, on the basis of which they were created those ideas that I want to state.


    Little reservations

    To begin with, I won’t bother with the fine-tuning of Apache, php, or other things, because I just want to state the idea and find out your opinion, dear habrayuzers, whether it is worth developing the proposed method further and how it can be modified, therefore, I’ll immediately make a reservation that all the actions described below occur on a freshly installed ubunt 11.10 and a traditional lamp out of the box.
    It is also assumed that the reader is already familiar with the basics of Yii and at least roughly knows its directory structure.

    Training

    So, initially we have the simplest host with approximately the following settings:

    
    	ServerName      demo.lori
    	ServerAlias 	demo.lori www.demo.lori
    	DocumentRoot 	/home/lori/workspace/demo.lori/www
    	ErrorLog	/home/lori/workspace/demo.lori/logs/error.log
    	CustomLog	/home/lori/workspace/demo.lori/logs/access.log common
    


    Z.Y. The .lori domain zone is selected for testing and out of all the possible meaningful options, it carries only the alternative name of your humble servant accepted by the people.

    Log folders were chosen for faster access to them during the development process (I do not pretend to be a guru in the Unix area, and therefore, if someone tells me that this is not kosher, I will listen with pleasure).

    Additionally, in the workspace folder, create a folder called yii , where we unpack the freshly downloaded archive in Yii, and more specifically, the framework folder from it (at the time of the creation of the article, the last stable version of the framework was 1.1.10). From now on, this will be our core, and (purely theoretically, of course), we will very rarely touch it in the future.

    After that in the folder/home/lori/workspace/demo.lori/www we will organize the following structure (according to Yii recommendations modified for this method):

    - www /
    —– index.php
    —— .htaccess
    —— config /
    ——— devel /
    ———— <development location config files>
    ——— stable /
    ———— <production location configuration files>
    —— engine /
    ——— <project project files>
    —— themes /
    ——— basic / (name of the main theme)
    - ——— static /
    —————— images /
    ————— css /
    —————js /
    ———— views /
    ————— <files of all our view by topics>

    Now, according to the above organization, all project files (controllers, components, models, etc.) will be stored in the engine folder, the themes folder destination doesn't change, themes and other static content like CSS or JS files will be stored here. The config folder also remains canonical, however, its internals will change somewhat.

    After all the folders and files have been created, it remains, as Yii experts have rightly noticed, to create the runtime and assets folders, however, here the first significant changes begin. These folders will be organized in a special way.

    Just a note: all further commands are executed through sudo, therefore I will not indicate it, assuming that we already have all the rights.

    We create a common warehouse for our projects:
    mkdir -p /home/projects/data/demo.lori
    cd /home/projects/data/demo.lori
    mkdir -p ./assets/stable
    mkdir -p ./runtime/stable
    mkdir -p ./upload/stable
    mkdir -p ./assets/devel
    mkdir -p ./runtime/devel
    mkdir -p ./upload/devel
    

    Now we need to allow our framework to create files in these folders, for this we perform:
    chown www-data -R /home/projects
    

    (There is also a small question for connoisseurs of * unix, are there any comments about the rights?)

    Now all that remains for us is to create symlinks to these folders in our project:
    ln -s /home/projects/data/demo.lori/assets /home/lori/workspace/demo.lori/www/assets
    ln -s /home/projects/data/demo.lori/runtime /home/lori/workspace/demo.lori/www/runtime
    ln -s /home/projects/data/demo.lori/upload /home/lori/workspace/demo.lori/www/upload
    


    UPD1 (Based on comments): why is this directory structure used
    1) According to the Yii theory, assets should be stored in files that somehow attach to the project, for example, some third-party js-scripts, css-files, pictures and other things , therefore, if I use, for example, trivial JQuery or CSS-reset in all my projects, it will be more logical to store them in one place outside of all projects.
    2) runtime did not make much sense, but purely theoretically it does not play a special role in development and is needed by Yii himself, because in order not to clutter up the folder of the project itself, this directory has been moved outside of it.
    3) Remote and centralized upload is necessary so that, for example, in the case when a development environment is deployed on the local network, the files used in the projects are common for all developers, for example, if an avatar is loaded into a project for a user, it’s more logical to make it so that if one person loads a picture, then all other developers should see it if there is some link in the database to it.

    On this, the basic preparations are completed, we proceed directly to the project setup.

    Entry Point Setup

    Let's start with the index.php file, it is almost no different from the standard entry point Yii, with the exception of the amendments for dividing locations into developers and production:
    run();
    

    .Htaccess itself currently looks something like this:
    AddDefaultCharset	UTF-8
    RewriteEngine		on
    RewriteBase		/
    RewriteCond %{REQUEST_FILENAME}	    -d
    RewriteRule ^upload/(.*)$	    /forbidden	    [L]
    RewriteCond %{REQUEST_FILENAME}	    -d
    RewriteRule ^assets/(.*)$	    /forbidden	    [L]
    RewriteCond %{REQUEST_FILENAME}	    !-f
    RewriteRule ^assets/(.*)$	    /nofile	    [L]
    RewriteCond %{REQUEST_FILENAME}	    !-f
    RewriteRule ^upload/(.*)$	    /nofile	    [L]
    RewriteCond %{REQUEST_URI}	    !^/assets
    RewriteCond %{REQUEST_URI}	    !^/upload
    RewriteRule ^(.*)$		    index.php	    [L]
    

    Entry points are ready, now you need to configure configs for them.

    Setting preferences :)

    I will not schedule the creation of settings for each of the locations, and I will describe the actions for the devel location, since all changes will take place on it, and the creation of the config for the production location is identical.

    First, in the config / devel / folder, create the main.php file . It will look like regular main.php from the config of any project on Yii, but we will make some additions to it according to our file organization:
     dirname(__FILE__).'/../../engine/',
    	'name'		=> 'Demo project',
    	// Указываем новый путь к runtime для текущей локации
    	'runtimePath' 	=> dirname(__FILE__).'/../../runtime/devel',
    	// Указываем нашу тему по умолчанию из папки /themes
    	'theme'		=> 'basic',
    	'preload' 		=> ...,
    	'import' 		=> ...,
    	'defaultController' => 'default',
    	// Здесь есть изменения в путях к некоторым папкам
    	'components' => array(
    		'assetManager' 	=> array(
    		    'basePath'	=> dirname(__FILE__).'/../../assets/devel',
    		),
    		'user' 		=> ...,
    		'db'		=> ...,
    		'errorHandler' 	=> ...,
                    'urlManager' 	=> array(
                            'urlFormat' 	=> 'path',
                            'rules'     		=> require_once dirname(__FILE__).'/routes.php',
                    ),
    		'log'		=> ...
    	),
    	'params'	=> require(dirname(__FILE__).'/params.php'),
    );
    

    In the above config, ellipses replace standard blocks of code that are not affected by the current changes in the file organization and which therefore do not need a description.
    It’s worth mentioning about setting up urlManager :
    I don’t really like that according to the classical scheme, routing is confused with the config, because I always put it in a separate routes.php file in the same folder as main.php , and it contains the usual structure like
     'value1'
    );
    

    Afterword

    On this, in principle, the entire basic setup of the project is completed - the project is configured.

    Advantages of this approach:
    - Separation of projects from each other
    - One engine for all projects, which allows you to update it or supplement it once for all projects at once
    - The presence of separation on the development and production locations, with its own configs and included files
    - Convenience when working with version control systems like Git
    - To some extent a theme catalog separate from the project

    Cons:
    - not yet found

    I like this approach because of its flexibility, because if you look at it, you can expand it quite seriously by operating with locations via htaccess, creating separate configs for various environments, and much more, without worrying that every time you add some some goodies in the kernel, transfer changes to all of your projects (after all, the kernel, like any project, is a project in itself, which can also be changed on development locations and uploaded to production.

    If someone has any Some comments or questions, I will be glad to listen and if possible to answer or correct some places in the above example.

    Also, I would like to ask the public about the need to create a series of articles dedicated to the full cycle of creating a project on Yii, because, frankly, I did not find such articles on the network, basically there are a bunch of articles on separate topics like caching or validations, and the original guide presented by the developers also does not give a full perception of the Yii project as a whole.

    Thanks to everyone who read the article to the end!

    UPD: Some nevertheless spoke out that the course of articles is not such a bad proposal, then I would like to ask: if you do a cycle on the development of OT and TO, then what is not trivial (like the proposed blogs or address book) site you would like to see ?

    Also popular now: