MVC and Module Structure - radus28/Vtiger-DevOps GitHub Wiki
Modules
-
Modules are organized into Hierarchical MVC pattern under 'modules' folder
-
Each module can have either one of
- MVC structure
- Models
- Views
- Actions (Controllers)
- Sub modules
- MVC structure
-
Parent module is always Vtiger. It works as Base module as well as fallback module.
-
Each Module class composed of Modulename_Type_ClassName. Example Contacts_Save_Action
-
When an action or view not found inside specific module folder, it is fetched from Vtiger module as fallback. You can see How fall back works.
Module types
There are 2 types
- Extension - Just functionalities such as Emails, SMS, PDF Export
- Entity - Data/record based modules, such as Contacts, Products etc. Entity type has a special type named "Inventory Modules"
Inventory Module is an Entity module , but logically grouping inventory related modules like "Quotes","Invoice", "SalesOrder" and "PurchaseOrder" as sub modules.
Inventory Modules have Line Item block, which is a special blocks to Include Products.
Examples
- Entity modules - Contacts, Products, Organizations, Opportunities, Projects, vendors
- Inventory modules - Quotes, Invoice, PurchaseOrder, SalesOrder
See modules/Inventory/actions/Save.php which is an Extended class of modules/Vtiger/actions/Save.php as shown below
class Inventory_Save_Action extends Vtiger_Save_Action { .. }
Same way modules/Quotes/actions/Save.php is an extended of modules/Inventory/actions/Save.php
class Quotes_Save_Action extends Inventory_Save_Action {..}
Since Vtiger is the parent module the class hierarchy goes like
Vtiger -> Inventory -> Quotes | Sales Order | Invoice | PurchaseOrder
For Entity Modules it is
Vtiger -> Contacts | Leads | Organizations | .....
Settings
Now time to check Settings module ..
- This is a module only accessible to "Admin" users
- This is organized into several sub modules as shown below
- Each of these sub modules handles different functions of the App Settings, such as
- CRON Tasks
- Workflows
- SMS configuration
- Outgoing mail configuration
How MVC works
- Actions - The controller Classes to perform actions. Example, Save, Delete, MassSave, Search and many more
- Views - Responsible to display Contents. In vtiger contents are rendered through Smarty Templates
- Models - All Back end / Database operations Happens here
Auto Loading
Auto Loading happens using PHP's spl_autoload_register() method at
includes/Loader.php
Class and file names follow below conventions
File path : MODULE-NAME/TARGET/FILE
Example : Contacts/actions/Save.php
Class name : Contacts_Save_Actions {}
Views
Take and example of a Detail View http://localhost/v72train/index.php?module=Accounts&view=Detail&record=73&app=MARKETING
This request is routed to
modules/Accounts/views/Detail.php
And class Accounts_Detail_View
This class Extended Vtiger_Detail_View class from
modules/Vtiger/views/Detail.php
And the __contstructor()
Exposes all relevant methods as shown below
function __construct() {
`parent::__construct();`
`$this->exposeMethod('showDetailViewByMode');`
`$this->exposeMethod('showModuleDetailView');`
`$this->exposeMethod('showModuleSummaryView');`
`$this->exposeMethod('showModuleBasicView');`
`$this->exposeMethod('showRecentActivities');`
`$this->exposeMethod('showRecentComments');`
`$this->exposeMethod('showRelatedList');`
`$this->exposeMethod('showChildComments');`
`$this->exposeMethod('getActivities');`
`$this->exposeMethod('showRelatedRecords');`
`}`
And Request goes to process() Function
`function process(Vtiger_Request $request) {`
`$mode = $request->getMode();`
`if(!empty($mode)) {`
`echo $this->invokeExposedMethod($mode, $request);`
`return;`
`}`
`$currentUserModel = Users_Record_Model::getCurrentUserModel();`
`if ($currentUserModel->get('default_record_view') === 'Summary') {`
`echo $this->showModuleBasicView($request);`
`} else {`
`echo $this->showModuleDetailView($request);`
`}`
`}`
If $mode is empty it goes to default DetailView or SummaryView Else Calls relevant Exposed Methods
Actions
Actions goes to the Module's Action file.
Example, in Contacts Edit View, below screen shows the hidden form parameters which are submitted to backend.
The Save Action Request goes to
modules/Contacts/actions/Save.php
and Class Contacts_Save_Action
which extends
modules/Vtiger/actions/Save.php
Vtiger_Save_Action->process($request)
Then in Line 54
$recordModel = $this->saveRecord($request);
it calls saveRecord() from Line 109
Finally in Line 116 it calls
$recordModel->save();
The $recordModel is from
modules/Contacts/models/Record.php
Note if no Record.php found under Contacts/models (MODULE-NAME/models) folder, request will be diverted to Vtiger/models/Record.php
In this case Contacts module has the class Class name Contacts_Record_Model
But save() method not exists, so it is called from it's Parent Vtiger/models/Record.php which calls
Vtiger_Record_Model->save()
then it calls
$this->getModule()->saveRecord($this);
From
modules/Vtiger/models/Module.php
IMPORTANT
- REMEMBER THE WAY TO DEBUG THE ACTIONS OR VIEWS. THERE CAN BE MORE **TRICKY REQUESTS **THAN THIS
- THESE ARE CORE FILES AND MODIFICATION IS NOT RECOMMENDED