Offline runnable Thesaurus Training Web App – Deployment

Deployment of the offline runnable thesaurus training web app was not the easiest part so far. Yii has some configuration aids. Some portion of code may be configuration dependent. For example, the paths to the resources may vary from development to production. There are Yii variables like YII_ENV. When YII_ENV ist set to prod, then YII_ENV_PROD is defined, so you code can make a query like if (YII_ENV_PROD) { do it; }. Now I have one or two places in my code, to ask if in production or in development and set the paths accordingly.
What puzzled me most about Yii until now was the publishing of assets. An asset is a resource like a Javascript or CSS file. When they are getting auto published, what must explicitly be prohibited, they reside in folder with a hashed name. It is to avoid version conflicts. I can’t find a use case for that yet. But each time I wanted to deploy the app on openshift, the scripts where put into a folder with another hashed name. So I cannot reference them outside Yii. I am using HTML5 Application Cache, an HTML5 technique to make web sites or part of them able to run offline. For knowing which files to cache, there is a manifest file which references this files. Even if there is a server connection available, this files will be obtained from the cache, that is defined in the manifest. Thus, HTML5 Application Cache saves bandwidth. Sometimes I may want to update my Javascript files, so this requires to specify an update strategy which I left out for the future. The way to left out the resources to be published is to set the variable $sourcePath in each asset class which extends the class AssetBundle to null. Took me a while to find this out. In addition the initialization of the array js which is inherited from the AssetBundle base class depends on where the app runs, on localhost or on production server. My solution is to override the init() method of the existing asset classes and use a method getAssetSourcePath() there which I added to the AssetBundle class:

    public function getAssetSourcePath(){
        if (YII_ENV_DEV) {
            return "phpapp/web/";
        } else if (YII_ENV_PROD){
            return "";
        }
    }

My YiiAssetclass now looks like this:

class YiiAsset extends AssetBundle
{
    public $sourcePath = null;

    public function init(){
        $this->js = [];
        array_push($this->js, parent::getAssetSourcePath().'js/yii.js');
        parent::init();
    }

    public $depends = [
        'yii\web\JqueryAsset',
    ];
}

deployment on openshift is the easiest part of deployment and works with a few console commands using git, the rhc command and in my case mysql. First I have to install ruby, since the rhc command line tool requires it. The documentation on openshift can be followed quite straight forward.

Deploying the MySQL database worked with these commands:

rhc scp myapp upload /path/to/db.slp app-root/data
rhc app ssh myapp
mysql $OPENSHIFT_APP_NAME < $OPENSHIFT_DATA_DIR/db.sql

Another strange problem: To download compressed CSV files and uncompress them via Javascript, I use zip.js. In the production environment I stumbled upon a strange error. zip.js first makes a HEAD Ajax request, before actually downloading the zipped file via Ajax. But the Content-Length of the response header was not there, so Javascript reads 0 and zip.js interpretes this as a corrupted file. I don’t want to spend much time to go deep into that problem. I just return the Content-Length statically, since all data is static. Sure, it is no solution for getting data with dynamic length.

That’s it for deployment. Now, when I deploy I change YII_ENV from dev to prod and set YII_DEBUG to false and run the following three git commands

git add —all
git commit -m "my comment“
git push