Last update : 08/2021
Architecture of CRX php framework
CRX Framework work for scripting on service mode or on webmode, on webmode it can provide librairies and also tools for CRX Cms witch a CMS with MVC organisation.
CMS or SCRIPT have the same design:
html / ( HTML folder is the application folder content )
[app-php] / [module] /
[app-js] / [module] /
So each folder represent a module, for example in web mode : forum, mail, directory,
Exemple for from CLI service mode : dxClusterServer ( witch work with socket/thread/shared memory ) or dxClusterMailAlert witch is an alerting daemon.
Of course in same application it's possible to mix server mode and web mode ( server mode = script mode here ).
Inside each module you have these folders :
conf_files ( containt module xml conf file )
handler_files
lang_files
models_files
templates
view_files
On parent level , we have :
conf / (configuration folder contain VHOST configuration and registry of crx application ).
logs / ( can contain APACHE log but also CRX Framework log )
Example of script application :
#!/usr/bin/php
<?php
require_once('/home/hosting/www_root/common.crx.cloud/conf/env.php');
require_once('/home/hosting/www_root/ham.crx.cloud/conf/global.php');
require_once($FMPATH.'/loader/bootScript.php');
bootScript::boot(
'bootScript',
array(
'appli_web_uri' => $APPWEBURI,
'appli_name' => $APPNAME,
'appli_webmaster_email' => $APPWEBMASTERMAIL,
'appli_reg_path' => $APPFSPATH.'/conf/', //registry folder
'appli_path' => $APPFSPATH.'/html/', //_APPLI_MAIN_PATH_
'appli_path_root' => $APPFSPATH,
'appli_secret_key' => $APPSECKEY, //_APPLI_SEC_KEY_
'error_handling' => array(
'PhpDisplay' => $error
),
'server_os' => 'LINUX', //_SERVER_TYPE_
'current_path' => $APPFSPATH.'/html', //_SERVER_EXEC_PATH_
'framework_debug_mode' => 'nothing', //view/nothing/log
'framework_error_mode' => 'nothing', //view/nothing/log
'framework_path' => $FMPATH.'/',
'framework_conf' => array(
'time_zone_set' => 'Europe/Paris',
'framework_debug_console' => NULL, //view/nothing/log
'app_main_ds' => 'mysql',
'load_user_module' => 1,
'load_user_authentification_module' => 1,
'available_languages' => array('fr','en'),
'default_language' => 'fr', //can be fr,en OR auto (detect from user browser_info)
'default_loaded_module' => 'dxClusterWeb',
'process_options_for_module_to_load' => array('action' => 'CRON__updateUserProfileNumberOfSpots')
)
)
);
?>
As you can see this instance will call the module "dxClusterWeb" and the class method "CRON__doSpotArchiving", arguments to the script can be transmit via process_options_for_module_to_load array.
Example of web call :
This example call CRX-CMS from the index.php file.
Here we call the cms module dxClusterWeb when user is login-in.
<?php
require_once('/home/hosting/www_root/common.crx.cloud/conf/env.php');
require_once('/home/hosting/www_root/ham.crx.cloud/conf/global.php');
require_once($FMPATH.'/loader/bootWeb.php');
bootWeb::boot(
'bootWeb',
array(
'appli_web_uri' => $APPWEBURI,//_WEBSITE_URL_
'appli_name' => $APPNAME, //_APPLI_NAME_
'appli_webmaster_email' => $APPWEBMASTERMAIL, //_APPLI_WEBMASTER_MAIL_
'appli_reg_path' => $APPFSPATH.'/conf/', //registry folder
'appli_path' => $APPFSPATH.'/html/', //_APPLI_MAIN_PATH_
'appli_path_root' => $APPFSPATH, //path outside html/www folder using for registry and log(s).
'appli_secret_key' => $APPSECKEY, //_APPLI_SEC_KEY_
'error_handling' => array(
'PhpDisplay' => $error
),
'server_os' => 'LINUX', //_SERVER_TYPE_
'current_path' => getcwd(), //_SERVER_EXEC_PATH_
'framework_debug_mode' => $fmer, //view/nothing/log
'framework_error_mode' => $fmer, //view/nothing/log
'framework_path' => $FMPATH.'/',
'framework_conf' => array(
'caching_xml_to_memcached' => 1, // 0 disable // default 1 => use for module configuration XML.
'caching_xml_to_php' => 1, // 0 disable // default 1 => use for modules global conf/list.
'caching_ini_to_php' => 1, // default 1 => use for languages ini files.
'caching_ini_to_user_session' => 1, // default 1 => use for languages ini files.
'time_zone_set' => 'Europe/Paris',
//'framework_debug_console' => '', //view/nothing/log
//'app_main_ds' => 'mysql', // default 'll be mysql !
'load_user_module' => 1,
'load_user_authentification_module' => 1,
'set_user_authentification_method' => 'webUserAuthentification',
'load_stats_visitor_module' => 0,
'load_common_module' => 1,
'display_modules_output' => 1,
'available_languages' => array('fr','en','it','es'),
'default_language' => 'fr', //can be fr,en OR auto (detect from user browser_info)
'if_access_to_unknow_module' => 'load_default_module',// or view_404, load_default_module,print_error, do_nothing, die.
'define_404_page' => getcwd().'/404.php',
'common_module_name' => 'common',
'default_loaded_module' => 'index',
'on_user_login_in_module' => 'dxClusterWeb',//dxClusterWeb
'maintenance_mode' => 0,
'loadCommondModuleConfiguration' => 1,
//runMain
'enforceUriSecurityMode' => $urlmode, //b64id (require in AJAX mode), normal
'saveUriEncodingIntoMemCache' => 0, //TODO 1
'cachingDataSource' => 'memcached-localhost'
)
)
);
?>
Module env :
Inside a module, you can use pre defined method :
$this->showVars(); // display framework constant defined.
$this->loadIco(); // load HTML Ico picture.
$this->_currentModuleConfiguration // current module XML configuration : /html/app-php/[MODULE_NAME]/conf_files/configuration_module.xml
All values defined into array 'framework_conf' ( see boot method of bootScript or bootweb ), are accessibles :
via crxFramework::getFrameworkConfigurationValue method :
Example :
crxFramework::getFrameworkConfigurationValue('userPasswordHashMethod');
Will return sha256 for exemple.
Module configuration format :
Configuration module is defined via XML configuration file like this :
<?xml version="1.0" encoding="ISO-8859-1"?>
<module>
<conf>
<node_name>F4EYQ-1</node_name>
<node_uri_sch>https</node_uri_sch>
<node_uri>ham.crx.cloud</node_uri>
<node_uri_mobile>m.crx.cloud</node_uri_mobile>
<node_uri_telnet>ham.crx.cloud</node_uri_telnet>
<node_uri_telnet_port>7300</node_uri_telnet_port>
<node_linked>ik5zuk.dyndns.org,ik6xmi.homepc.it,n6ws.no-ip.org</node_linked>
<node_uri_wbs>wbsham.crx.cloud</node_uri_wbs>
<dxcluster_scheduler_path>/home/spider/dxcluster_scheduler_path>
<mail_admin_send>webmaster@crx.cloud</mail_admin_send>
<mail_admin_send_test>f4eyq@crx.cloud</mail_admin_send_test>
<mail_admin_send_test_ob>CRXHAM - testingmail</mail_admin_send_test_ob>
<flags_folder>public/html-app/dxClusterWeb/flags/</flags_folder>
<display_chat_messages_date_format_html_interface>h:i</display_chat_messages_date_format_html_interface>
<enable_paypal_donation>1</enable_paypal_donation>
</conf>
</module>
As you can see, you must use the following tag: module, conf and you can put what ever you want inside conf xml tag.
=> To apply new configuration for module, you must login/logout and before restart your memcached service.
Debug something into a module :
Here we debug $cmd var into a debug log file ( witch is located into log folder on root ) :
//to debug $cmd content :
crxFramework::debugFile(dumper($cmd));
Of course, we can also debug to output via this method :
into the script loader ( boot script / web script ), we configure the display with this directive set to "view" :
//default is nothing
bootScript::boot(
...
'framework_debug_mode' => 'view', //view/nothing/log
Now into the controller module, we can use this function "debugAndContinue", this function take the message and a boolean :
Here is it's a mail alert service process witch run in background :
function handle__startDxclusterMailAlertProcess(){
debugAndContinue('[INFO] '.mktime()." Now Starting mailler alert processus.",DEBUG_MAIL_PROCESS);
$mailling_spots=array();
$i=0;
$count_burst=0;
while(TRUE){
debugAndContinue('[INFO] '.mktime()." Check if there is new spot to send.",DEBUG_MAIL_PROCESS);
Framework env :
All constant php are define here :
[FRAMEWORK PATH] / loader / constant.php
You can ajust some value, if you need advanced debug for example.
define('DEBUG_LNG_LAYER',0);
define('DEBUG_FRMW_MODULE_LOADER_LAYER',0);
define('DEBUG_URL_BUILD_LAYER',0);
define('DEBUG_MODULE_ENGINE_LAYER',0);
define('DEBUG_WEBSERVICE_CRX_LAYER',0);//See crxFrameworkWebserviceCrx
define('ENABLE_LOG_DEBUG',0);//See crxFrameworkWebserviceCrx
define('_DEBUG_LOG_FILE_','/tmp/debug_php.log');//Set debug path
define('DEBUG_crxUploadFiles',0);
To view framework content you can use :
#in HTML :
echo \crx\crxBootLoader::showConstantAsHtmlArray();
#into a CLI :
echo \crx\crxBootLoader::showConstantAsHtmlArray($console=1);
Using database classe
CRX Framework, purpose a powerfull object to SQL mapper, and various method to generate SQL and create schema from object class properties :
$this->_dataAccess = crxDataSource::getDs('mysql_local');
First inside object, you must define the table schema you want, example :
var $_userDonationTableShema = array(
'donation_id'=>'pk',
'donation_date',
'donation_user_id',
'donation_amount',
'donation_type'
);
Example 1 , return data with a filter ( similar to SELECT request ) :
$this->_dataAccess->formatSqlQuery('',$this->_table_users_donation,'DISPLAY','',array('filter_key'=>'donation_id','filter_key_value'=>$id));
$this->_dataAccess -> ExecSql();
return $this->_dataAccess -> returnLineAsso();
Example 2, insert data :
$this->_dataAccess -> defineTableShema($this->_userDonationTableShema);
$this->_dataAccess -> formatSqlQuery($updatedata,$this->_table_users_donation,'INSERT');
$this->_dataAccess -> execSql();
Example 3, update data :
$this->_dataAccess -> defineTableShema($this->_userDonationTableShema);
$this->_dataAccess -> formatSqlQuery($updatedata,$this->_table_users_donation,'UPDATE',array('donation_id'=>$donation_id));
$this->_dataAccess -> execSql();
If error, you can extract it via this command : ( execSql return FALSE )
$this->_dataAccess -> getExecSqlError();
Developping module, create controler :
<?php
namespace crxcms;
use \crx\crxFramework;
use \crx\crxFrameworkWebCommon;
use \crx\crxFrameworkModuleLoader;
use \crx\genericUserModule;
class userControlerHelloWorld extends genericUserModule{
//This setting doesnt overide : <module_is_private>0</module_is_private> (see module configuration xml)
var $_private_scope_handler_webapp = array('exampleProtectedMethodFromPublic');
//Declare here ajax methods to protect from public call :
var $_private_scope_handler_ajaxapp = array('test');
function __construct(){
parent::__construct(
$def_handler = 'showMyDefaultMethod',
$mod_name = 'helloWorld',
array(
// (view_files folder)
//'_IHellowWorldView'=>'helloWorldWebUserView' => load instance $this->_IHellowWorldView of class helloWorldWebUserView.
),
array(
// (model_files folder)
//'_IHelloWorldObject'=>'myhelloWoldOject' => load instance $this->_IHelloWorldObject of class myhelloWoldOject.
),
array(),//class path optionnal.
NULL,//authentification_component
array(),//_delegateModuleHandler => Here you can add multiples linked class :
/*
$delegation=array(
0=>array(
'classToLoad' => 'userControlerHelloWorldDelegationClassN1',
'handleToLoad' => 'callBackLoadItemToDelegate__generic',
'parent' => $this
)
)
*/
'crxcms',//namespace
0 //debug process
);
}
/* example :
function callBackLoadItemToDelegate__generic( $instance_delegate ){
$this->_mcd=\crx\crxDataSource::getDs('memcached-localhost');
$this->c_db=\crx\crxDataSource::getDs('mysql');
$instance_delegate->c_db = $this->c_db;
$instance_delegate->_mcd = $this->_mcd;
}
*/
function handle__exampleAjaxCallMethod1(){
echo "OK";
//This method set current method doesnt need CMS interface,
//It will simply echo a value for example (into ASYNC call).
\crx\crxFrameworkModuleLoader::disableModuleDisplayOutputProcess();
}
//Example of CLI call, see PHP /server/runHelloWorld.php
function handle__CRONtestCLI(){
echo "Hello world !\n";
/*
var_dump($this->getRequestParams());
Exemple :
array(2) {
["action"]=>
string(11) "CRONtestCLI"
["testP"]=>
int(xyz)
}
*/
// Example of display message ( enable or not via a constant )
// define('DEBUG_L1',1);
// \crx\debugAndContinue('[INFO] some debug',DEBUG_L1);
// If _FRAMEWORK_ERROR_MODE is set to 'log' :
// This method can also write into this debug log :
// _APPLI_LOG_DEBUG_; => /logs/debug.log
// Constants are defined in : /conf/global.php
// _FRAMEWORK_DEBUG_MODE must be set to 1.
}
function handle__test(){
$URI_PRIVATE = $this->prepareUrl($this->_moduleName,array('action'=>'exampleProtectedMethodFromPublic'));
$URI_AJAX_CALL = $this->prepareUrl($this->_moduleName,array('action'=>'exampleAjaxCallMethod1'));
$this->setHtmlMainContent(
'<h1>Hello World!</h1>
<h1>This is handle__test()</h1>
- <b>Example of protected URL</b> (can be view only if user is authenticated): <br/><br/>'.$URI_PRIVATE.'<br/><br/>
- <b>Example of AJAX URI</b> (can be called via JS) : <br/><br/>'.$URI_AJAX_CALL.'<br/><br/><br/>
- <b>Example of WIDGET</b> getGenericDeleteAction()
');
//To retreive the request :
//print_r($this->getRequestParams());
//ex: Array ( [action] => test )
//To set pannel content :
//$this->setHtmlPannelContent('Put also this content into interface pannel.');
//To completly disable CMS pannel :
//$this->setHtmlOutputValue('DISABLE_PANNEL',TRUE);
//Display validation message box :
$this->getGenericDeleteAction('handle__onValidObjectDeletionExample','This is an example of warning box widget');
}
function handle__onValidObjectDeletionExample(){
$this->setHtmlMainContent(
'<br /><br /><b>- Debug request parameters : </b>'.
\crx\dumper($this->getRequestParams())
);
}
function handle__exampleProtectedMethodFromPublic(){
$this->setHtmlMainContent('I can be call only is user is authenticated.');
}
function handle__showMyDefaultMethod(){
$URI_TEST = $this->prepareUrl($this->_moduleName,array('action'=>'test','objectid'=>time()));
$this->setHtmlMainContent('Hello world ! - <a href="'.$URI_TEST.'">[Click here to call test method]</a><br />');
}
//Call just after build view object instance:
function handle__loadObjects(){
if(class_exists('\crx\crxFrameworkWebCommon')){
$this->setHtmlMainContent('<br/>-> This module is call from WEB.');
}
else{
echo "-> This method is call from CLI\n";
}
//$_SESSION manipulation : ( scope all modules ) :
//$this->setGlobalPersistantValue('sessionkey1','somevalue');
//$sessionkey1 = $this->getGlobalPersistantValue('sessionkey1');
//$this->getCurrentModuleAdmin(); => return the current module name.
//$action=> 'append' will use array_merge / 'set' (will erase)
//$this->setPersistantValue('KEXAMPLE_localModuleSessionScope','somevalue','set');
//$this->getPersistantValue('KEXAMPLE_localModuleSessionScope'); => return somevalue
}
function runMain($url){
//example : array(1) { ["action"]=> string(4) "test" }
//_handlerMethodNamePrefix is set as : handle__
$this->moduleActionsListener($url);
$this->handle__loadObjects();
}
}
?>
Developping module, use ini file languages
To disable cache, during developpement use :
$this->disableLngCache();
Using CRX users class :
$uid=crxFramework::getGlobalValue('userId');
$u=crxFramework::getUserInstance();
#Retreive user properties :
$usr=$u->getUserInfo('',$uid);
#Retreive current user group :
$g=$u->__getUserGroupsMembers($uid);