How to build a Saas platform with Yii?

I am wondering how to build a Saas (Software as a Service) platform with Yii?

How to maintin tenants?

How to maintain performance? Scaling?

One very important aspect of a multi tenant app is the separation of tenants in storage. You can store each tenant’s data in a separate database, but this is the most expensive to maintain. You can create a database schema for each tenant (see this topic). Or you can store the data of all tenants in the same tables and separate the tenants with a tenant identifier field. The latter is generally considered as good practice for large number of tenants with cheap 2.0 web apps.

This is a good article about multi tenant data separation: http://msdn.microsoft.com/en-us/library/aa479086.aspx Database scaling and security is extensively covered in this article.

If you want to build a multi tenant application using MySQL, you could consider using the technique described in this article: http://www.reachcrm.com/2010/03/11/multi-tenant-strategy-for-saas-using-mysql5/ with a code example here: http://blog.empowercampaigns.com/post/1044240481/multi-tenant-data-and-mysql

To separate data in your cache you could use a prefix for each tenant.

Authentication of tenants and users is very important. How and where do users log in? One solution is to offer each tenant it’s own subdomain to the service. You can handle this easily with Yii framework (check this).

Depending on the web application you are building I would build a separate application to manage tenants. When users can sign up to the service on your website their selves automatically, this website would also contain the tenant manager.

Thank you for your answer it is a good place to start.

I am wondering how would code reuse and customization would be possible at Yii level. Basically all companies would be based on the same code base, but they will need slight changes or behavior differences (like different related items algorithm). I know how to handle theme differences, I am more looking into differentiating controllers and models per use.

How would this go separated in Yii?

Good question!

You could customize the behavior of your multi tenant application to the needs of your customer by using configuration options, business rules or logic like decision tables. You could also insert customer specific code as ‘modules’ (I do not mean Yii modules) into your code. Then allow modules to be enabled or disabled for each tenant.

If you really need to customize the code for each tenant, then you should reconsider building a multi tenant application. Because modifications for each tenant to your application make it really difficult to maintain the application for all tenants. For example adding a new feature to your application could break the application for one tenant with a specific configuration and code, you will probably never discover this during development. Which results in a broken app for one tenant.

Depending on the number of customizations, number of tenants, size of customizations, price and SLA of app there are different solutions. It is really hard to give a good advice for you without knowing details.

How we create a SaaS app using Yii?

How i implement this

SaaS

http://blog.empowercampaigns.com/post/1044240481/multi-tenant-data-and-mysql


CREATE TABLE foo_base (

    id INTEGER AUTO_INCREMENT PRIMARY KEY,

    tenant VARCHAR(16),

    foo VARCHAR(64),

    bar VARCHAR(64)

);


CREATE VIEW foo AS

    SELECT id, foo, bar

    FROM foo_base

    WHERE tenant = SUBSTRING_INDEX(USER(), '@', 1);


CREATE TRIGGER foo_base_tenant_trigger

    BEFORE INSERT ON foo_base

    FOR EACH ROW

        SET new.tenant = SUBSTRING_INDEX(USER(), '@', 1);



i created model for the view foo, but cant create crud because that has no Pk. thats ok.

so i created model for foo_base and crud for the same. And when using the model Foo (not Foobase). its working perfectly according to DB user. its only fetching the current user’s value. but in Yii we are using lots of PK(primary key) based operations. like findByPk . so how i solve this?

is it possible with this




class Content extends CActiveRecord

{

    public function defaultScope()

    {

        return array(

            'condition'=>"language='".Yii::app()->language."'",

        );

    }

}



http://www.yiiframework.com/doc/guide/1.1/en/database.ar

default scope