CRX Framework PHP - Documentation.

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);