Server-side Application PHP Methods
The ZnetDK PHP API simplifies the development on the web server side of:
Its source code is defined through PHP classes located in the INSTALL_DIR/engine/core/
folder.
Application views are PHP scripts that are developed to display data and input forms dedicated to the end user.
They are written in pure HTML and include if necessary, PHP and JavaScript code.
A view is usually displayed when you click an item of the Navigation menu.
Once a view is displayed, it remains in the DOM (Document Object Model) of the page, even when another one is displayed as a replacement.
This means that the view is not reloaded when it is displayed again later.
To force the content of the view to refresh each time it is displayed again, simply add the zdk-viewreload
CSS class to any HTML element in the view.
The PHP script of a view, for example myview.php
, is installed into the INSTALL_DIR/applications/default/app/view/
folder.
<h3>My view</h3>
<p class="zdk-viewreload">The name of the application is <?php echo LC_HEAD_TITLE; ?></p>
<p>The current time is <span id="current-time"></span>
<script>
var currentTime = new Date();
$('#current-time').text(currentdate.getHours()
+ ':' + currentdate.getMinutes());
</script>
Here is below the definition of the Starter App navigation menu.
menu.php
script
<?php
/**
* ZnetDK, Starter Web Application for rapid & easy development
* See official website http://www.znetdk.fr
* ------------------------------------------------------------
* Custom navigation menu of the application
* YOU CAN FREELY CUSTOMIZE THE CONTENT OF THIS FILE
*/
namespace app;
class Menu implements \iMenu {
static public function initAppMenuItems() {
\MenuManager::addMenuItem(NULL, 'home', 'Home', 'fa-home');
\MenuManager::addMenuItem(NULL, '_authorizations', LC_MENU_AUTHORIZATION, 'fa-unlock-alt');
\MenuManager::addMenuItem('_authorizations', 'z4musers', LC_MENU_AUTHORIZ_USERS, 'fa-user');
\MenuManager::addMenuItem('_authorizations', 'z4mprofiles', LC_MENU_AUTHORIZ_PROFILES, 'fa-key');
}
}
The first call to \MenuManager::addMenuItem()
adds the Home menu item in first position. This is a one level menu item so the Home
label is both displayed on the main vertical menu and the secondary horizontal menu.
The three next calls to \MenuManager::addMenuItem()
add the Authorizations menu item on the main vertical menu. This is a two levels menu item with two subitems named Users and Profiles displayed on the secondary horizontal menu.
addMenuItem()
<?php
// The 'my_view.php' view is displayed on clicking on the "My view" menu item.
// The Font Awesome 4 'fa-book' icon is displayed for this menu item.
\MenuManager::addMenuItem(NULL, 'my_view', 'My view', 'fa-book');
\AppController
|
\Request
|
\Response
Here is an example below of the mycontroller.php
PHP script implementing the MyController
class having a myaction
action.
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$request = new \Request();
$postValue = $request->my_param;
$response = new \Response();
$response->my_response = $postValue;
return $response;
}
}
?>
This controller action reads the value of the my_param
POST parameter and returns a JSON object with a property named my_response
and a value matching the my_param
parameter value.
You can notice in this example that the namespace
is set to app\controller
. It matches the folder in which the mycontroller.php
script file must be located, i.e. in the INSTALL_DIR/applications/default/app/controller/
folder if the running application is the Starter Application (default
subfolder).
Any application controller class must derive from the abstract
\AppController
class.
doAction()
<?php
$response = \app\controller\MyCtrl::doAction('getall');
The class \Request
when instantiated in a controller action, is used to read the values of the POST parameters sent through an AJAX request from an app view.
$[postParameterName]
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$request = new \Request();
/* POST parameter to read is named "address" */
$requestedAddress = $request->address;
/* ... the rest of the source code ... */
}
}
getValuesAsMap()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$request = new \Request();
$postValues = $request->getValuesAsMap('lastname','firstname');
// For example, the returned associative array is ['lastname' => 'DOE','firstname' => 'John']
/* ... the rest of the source code ... */
}
}
A controller action always returns an object of type \Response
in response to the original HTTP request.
The returned object takes one of the following formats, depending on the case:
\Response::setView()
method.\Response::setFileToDownload()
method.\Response::setPrinting()
method.\Response::setDataForCsv()
method.\Request
object or by calling one of the following methods: \Response::setResponse()
, \Response::setSuccessMessage()
, \Response::setWarningMessage()
, \Response::setFailedMessage()
or \Response::setCriticalMessage()
.\Response::setCustomContent()
method.\Response
PROPERTIES$[propertyName]
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
$response->myFirstValue = 'value 1';
$response->myOtherValue = 124.59;
return $response;
}
}
\Response
METHODS
setResponse()
,
setFileToDownload()
,
setView()
,
setDataForCsv()
,
setPrinting()
,
setCustomContent()
,
setSuccessMessage()
,
setWarningMessage()
,
setFailedMessage()
,
setCriticalMessage()
setResponse()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
$response->setResponse([
'status' => 'KO',
'message' => 'An error occurred!'
]);
return $response;
}
}
setFileToDownload()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_download() {
$response = new \Response();
$fileToDownload = CFG_DOCUMENTS_DIR . DIRECTORY_SEPARATOR . 'mydoc.pdf';
$response->setFileToDownload($fileToDownload, TRUE);
return $response;
}
}
setView()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
/* Returns the view "applications\default\app\view\customers.php" */
$response->setView('customers','view');
return $response;
}
}
setDataForCsv()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_download() {
$response = new \Response();
$header = array('Column 1','Column 2','Column 3');
$data = array(
array('Row 1 col. 1','Row 1 col. 2','Row 1 col. 3'),
array('Row 2 col. 1','Row 2 col. 2','Row 2 col. 3'),
array('Row 3 col. 1','Row 3 col. 2','Row 3 col. 3'),
);
$response->setDataForCsv($data, 'myfile.csv', $header);
return $response;
}
}
setPrinting()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_download() {
$response = new \Response();
$pdf = new \FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'PDF document generated from ZnetDK!');
$response->setPrinting($pdf, 'mydoc.pdf');
return $response;
}
}
setCustomContent()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_run() {
$response = new \Response();
$response->setCustomContent('OK');
return $response;
}
}
setSuccessMessage()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
$response->setSuccessMessage('New item','Item added successfully.');
return $response;
}
}
setWarningMessage()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
$response->setWarningMessage('New item','Item added even if it was incomplete.');
return $response;
}
}
setFailedMessage()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
$response->setFailedMessage('New item','Item added even if it was incomplete.');
return $response;
}
}
setCriticalMessage()
<?php
namespace app\controller;
class MyController extends \AppController {
static protected function action_myaction() {
$response = new \Response();
$response->setCriticalMessage('Unable to store the item data', $ex);
return $response;
}
}
Access to the data stored into the database of the application is simplified thanks to the ZnetDK PHP classes \DAO
and \SimpleDao
, both based on the PHP PDO class.
The ZnetDK class \DAO
allows to achieve complex database operations, in particular when data is to be selected from multiple SQL tables.
See below an example of the custom app\model\TaskDAO
class derived from the ZnetDK \DAO
class.
<?php
namespace app\model;
class TaskDAO extends \DAO {
protected function initDaoProperties() {
$this->table = "zdkapp_tasks";
$this->query = "SELECT tas.*, tas.id AS task_id, usr.user_name,
IF(tas.status_id < 3 AND tas.end_date < CURDATE(), 1, 0) AS late,
IF(tas.status_id < 3, 0, 1) AS display_priority
FROM tasks AS tas
INNER JOIN zdk_users AS usr ON usr.user_id = tas.user_id";
$this->dateColumns = array('begin_date', 'end_date', 'creation_date');
}
public function setNotFinishedAsFilter() {
$this->filterClause = 'WHERE tas.status_id != ?';
$this->setFilterCriteria(3);
}
}
?>
\DAO
PROPERTIES
$table
,
$query
,
$filterClause
,
$groupByClause
,
$idColumnName
,
$dateColumns
,
$moneyColumns
,
$amountColumns
,
$tableAlias
$table
<?php
$this->table = 'my_table';
$query
<?php
$this->query = "SELECT col1, col2 FROM my_table";
$filterClause
<?php
$this->filterClause = "WHERE col1 = ?";
$groupByClause
<?php
$this->groupByClause = "GROUP BY col1 HAVING COUNT(col1) > 5";
$IdColumnName
<?php
$this->IdColumnName = 'my_row_id';
$dateColumns
<?php
$this->dateColumns = ['creation_date', 'update_date'];
$moneyColumns
<?php
$this->moneyColumns = ['subtotal', 'total'];
$amountColumns
<?php
$this->amountColumns = ['subtotal', 'total'];
$tableAlias
<?php
$this->query = "SELECT col1, col2 FROM my_table AS tab";
$this->tableAlias = 'tab';
\DAO
METHODS
initDaoProperties()
,
setFilterCriteria()
,
setSortCriteria()
,
setLimit()
,
setSelectedColumns()
,
setForUpdate()
,
setAmountColumns()
,
setMoneyColumns()
,
setDateColumns()
,
getResult()
,
getById()
,
getCount()
,
store()
,
remove()
,
beginTransaction()
,
commit()
,
rollback()
initDaoProperties()
<?php
namespace app\model;
class Customers extends \DAO
{
protected function initDaoProperties() {
$this->query = "SELECT id, customer_name FROM customers";
$this->filterClause = "WHERE customer_name LIKE ?";
}
}
setFilterCriteria()
<?php
$customers = [];
$myDao = new \app\model\Customers();
$myDao->setFilterCriteria('spain','france','uk');
while($row = $myDao->getResult()) {
$customers[] = $row;
}
setSortCriteria()
<?php
$customers = [];
$myDao = new \app\model\Customers();
$myDao->setSortCriteria('name DESC, city ASC');
while($row = $myDao->getResult()) {
$customers[] = $row;
}
setLimit()
<?php
$customers = [];
$myDao = new \app\model\Customers();
$myDao->setLimit(20,40);
while($row = $myDao->getResult()) {
$customers[] = $row;
}
setSelectedColumns()
<?php
$customers = [];
$myDao = new \app\model\Customers();
$myDao->setSelectedColumns(array('id','name'));
while($row = $myDao->getResult()) {
$customers[] = $row;
}
getResult()
<?php
$customers = [];
$myDao = new \app\model\Customers();
while($row = $myDao->getResult()) {
$customers[] = $row;
}
getById()
<?php
$myDao = new \app\model\Customers();
$rowData = $myDao->getById(43);
$customerName = $rowData['customer_name'];
getCount()
<?php
$myDao = new \app\model\Customers();
$rowCount = $myDao->getCount();
store()
<?php
$row = array('id'=>18,'name'=>'MARTIN','city'=>'Paris');
$myDao = new \app\model\Customers();
$result = $myDao->store($row);
remove()
<?php
$customerId = 52;
$myDao = new \app\model\Customers();
$rowCount = $myDao->remove($customerId);
beginTransaction()
<?php
$myDao = new \app\model\Customers();
$myDao->beginTransaction();
setForUpdate()
<?php
$myDao = new \app\model\Customers();
$myDao->beginTransaction();
$myDao->setForUpdate(TRUE);
$row = $myDao->getById(18);
$row['is_visible'] = 'Y';
$myDao->store($row, FALSE);
$myDao->commit();
setAmountColumns()
<?php
$myDao = new \app\model\Customers();
$myDao->setAmountColumns('balance', 'expenses');
$customer = $myDao->getById(18);
$balanceAmount = $customer['balance_amount'];
$expensesAmount = $customer['expenses_amount'];
setMoneyColumns()
<?php
$myDao = new \app\model\Customers();
$myDao->setMoneyColumns('balance', 'expenses');
$customer = $myDao->getById(18);
$balanceAsMoney = $customer['balance_money'];
$expensesAsMoney = $customer['expenses_money'];
setDateColumns()
<?php
$myDao = new \app\model\Customers();
$myDao->setMoneyColumns('creation_date', 'birthday');
$customer = $myDao->getById(18);
$localeCreationDate = $customer['creation_date_locale'];
$localeBirthday = $customer['birthday_locale'];
commit()
<?php
$row = array('id'=>18,'name'=>'MARTIN','city'=>'Paris');
$myDao = new \app\model\Customers();
$myDao->beginTransaction();
$result = $myDao->store($row, FALSE);
$myDao->commit();
rollback()
<?php
$row = array('id'=>18,'name'=>'MARTIN','city'=>'Paris');
$myDao = new \app\model\Customer();
$myDao->beginTransaction();
$result = $myDao->store($row);
$myDao->rollback();
_construct()
,
getRows()
,
getRowsForCondition()
,
getSuggestions()
,
setKeywordSearchColumn()
The ZnetDK class \SimpleDAO
offers an easy and quick way to operate on a single SQL table or view.
Here is an example of usage of the \SimpleDAO
class.
<?php
$contactsDao = new \SimpleDAO('contacts');
$rowsFound = array();
$rowCount = $contactsDao->getRows($rowsFound, 'name');
?>
_construct()
<?php
$dao = new \SimpleDAO('customers');
getRows()
<?php
/* POST parameters: first='0', count='10', keyword='paul' */
$dao = new \SimpleDAO('customers');
/* keywords searched into the table's column 'name' */
$dao->setKeywordSearchColumn('name');
$customers = array();
/* Rows found are sorted by 'name' (sorting POST parameters not set) */
$total = $dao->getRows($customers, 'name ASC');
getRowsForCondition()
<?php
$dao = new \SimpleDAO('customers');
$condition = 'name LIKE ?';
$value = 'jean';
$result = $dao->getRowsForCondition($condition, "%{$value}%");
getSuggestions()
<?php
/* POST parameter: query='jean' */
$dao = new \SimpleDAO('customers');
$dao->setKeywordSearchColumn('name');
$suggestions = $dao->getSuggestions(20);
setKeywordSearchColumn()
<?php
$dao = new \SimpleDAO('customers');
$dao->setKeywordSearchColumn('name');
Form data sent to the web server can be verified before storage using a custom PHP class in charge of their validation.
\Validator
class is abstract and can only be instantiated through a derived class that implements:initVariables()
method to specify the names of the HTTP request data to check,initOptionalVariables()
method to indicate the names of the HTTP request data whose values are not mandatory,check_[dataName]()
control method for each data of the HTTP request to be checked. For example, it will be called check_email()
to check the POST data named email
.The custom derived class is generally stored into the INSTALL_DIR/applications/default/app/validator/
folder.
MyValidator
class derived from the \Validator
class
<?php
namespace app\validator;
class MyValidator extends \Validator {
protected function initVariables() {
return array('user_name','user_email');
}
protected function check_user_name($value) {
// 100 characters maximum
if (strlen($value) > 100) {
$this->setErrorMessage('User name is too long!');
return FALSE;
}
return TRUE;
}
protected function check_user_email($value) {
// Must be a valid email address
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->setErrorMessage('Email address invalid!');
return FALSE;
}
return TRUE;
}
}
?>
setCheckingMissingValues()
method to specify that empty data (null
) are also checked,validate()
method to check data,getErrorVariable()
method to obtain the name of the first POST data detected in error,getErrorMessage()
method to get the error message returned by the check_[dataName]()
method that detected the error,getValues()
method to get the values of the POST data that have been checked.MyValidator
class for data checking
<?php
namespace app\controller;
class MyController extends \AppController {
protected function action_save() {
$request = new \Request();
$response = new \Response();
// Form data validation
$validator = new \app\validator\MyValidator();
$validator->setCheckingMissingValues();
if (!$validator->validate()) {
$response->setFailedMessage(NULL, $validator->getErrorMessage(),
$validator->getErrorVariable());
return $response;
}
// Storage
$request = new \Request();
$row = $validator->getValues();
$row['id'] = $request->id;
$dao = new \SimpleDAO('my_users');
$dao->store($row);
$response->setSuccessMessage('User', 'Stored successfully.');
return $response;
}
}
?>
\UserSession
|
\controller\Users
\UserSession
class.\controller\Users
class.
setCustomValue()
,
getCustomValue()
,
removeCustomValue()
,
getLoginName()
,
getLanguage()
,
isAuthenticated()
,
getUserId()
User sessions are managed via the \UserSession
ZnetDK class that is used to get informations about the logged in user and to store custom data.
The session is started automatically and so doesn't need to be started explicitly.
setCustomValue()
<?php
\UserSession::setCustomValue('myVarInSession', 18);
?>
getCustomValue()
<?php
$myValueInSession = \UserSession::getCustomValue('myVarInSession');
?>
removeCustomValue()
<?php
\UserSession::removeCustomValue('myVarInSession');
?>
getLoginName()
<?php
$loginName = \UserSession::getLoginName();
?>
getLanguage()
<?php
$userLang = \UserSession::getLanguage();
?>
isAuthenticated()
<?php
if (!\UserSession::isAuthenticated(TRUE)) {
// User not authenticated!
}
?>
getUserId()
<?php
$userId = \UserSession::getUserId();
?>
getUserName()
,
getUserEmail()
,
hasProfile()
,
hasMenuItem()
The \controller\Users
class is used to get informations stored in database about the logged in user.
getUserName()
<?php
$userName = \controller\Users::getUserName();
?>
getUserEmail()
<?php
$userEmail = \controller\Users::getUserEmail();
?>
hasProfile()
<?php
if (\controller\Users::hasProfile('Manager')) {
// User is manager
}
?>
hasMenuItem()
<?php
if (\controller\Users::hasMenuItem('myview')) {
// User has access to "myview.php"
}
?>
The ZnetDK framework provides useful utility classes in PHP through the \General
class.
Data conversion is ensured through the \Convert
class.
callRemoteAction()
,
getCurrentW3CDate()
,
getFilledMessage()
,
getURIforDownload()
,
isW3cDateValid()
,
isPictureTooBig()
,
reducePictureSize()
,
writeErrorLog()
callRemoteAction()
<?php
print_r(json_decode(\General::callRemoteAction('https://usr:pwd@mydomain.com/', 'POST',
'mycontroller', 'myaction', [my_param1 => 'val1', my_param2 => 'val2'])));
?>
getCurrentW3CDate()
<?php
echo \General::getCurrentW3CDate();
?>
getFilledMessage()
<?php
echo \General::getFilledMessage('Your car is %1 and %2.','blue','yellow');
/* Display: Your car is blue and yellow. */
?>
getURIforDownload()
<?php
$downloadUrl = \General::getURIforDownload('mycontroller', 'doc_id=98&cache=true');
/* The URI returned is "/znetdk/?control=mycontroller&action=download&doc_id=98&cache=true" */
echo '<a href="' . $downloadUrl . '">File to download</a>';
isW3cDateValid()
<?php
$isValid = \General::isW3cDateValid('2022-12-29'); // Returns TRUE
$isNotValid = \General::isW3cDateValid('2022-02-30'); // Returns FALSE
isPictureTooBig()
<?php
if (!\General::isPictureTooBig('mypicture.jpg')) {
$resizedPicture = \General::reducePictureSize('mypicture.jpg', 260, 220);
}
?>
reducePictureSize()
<?php
$resizedPicture = \General::reducePictureSize('mypicture.jpg', 260, 220);
?>
writeErrorLog()
<?php
\General::writeErrorLog('MYAPP', 'Error detected...');
?>
base64UrlToBinary()
,
binaryToBase64Url()
,
toMoney()
,
W3CtoLocaleDate()
,
base64UrlToBinary()
<?php
$binaryValue = \Convert::base64UrlToBinary($base64UrlValue);
?>
binaryToBase64Url()
<?php
$base64UrlValue = \Convert::binaryToBase64Url($binVal);
?>
toMoney()
<?php
$myMoney = \Convert::toMoney(3451.7399);
?>
W3CtoLocaleDate()
<?php
$myDate = \Convert::W3CtoLocaleDate('2013-04-22');
?>
The following PHP constants can be used in the views and in the controllers to get absolute or relative path of specific ZnetDK folders.
ZNETDK_APP_NAME
,
ZNETDK_APP_ROOT
,
ZNETDK_APP_URI
,
ZNETDK_ROOT
,
ZNETDK_ROOT_URI
,
ZNETDK_CORE_ROOT
,
ZNETDK_MOD_ROOT
,
CFG_ZNETDK_IMG_DIR
ZNETDK_APP_NAME
Name of the subfolder containing the source code and the documents of the running application.
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_APP_NAME; // Display of default
?>
ZNETDK_APP_ROOT
Absolute path of the folder containing the files of the running application.
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_APP_ROOT; // Display of /home/hosting999/www/znetdk/applications/default
?>
ZNETDK_APP_URI
Relative file path of the directory containing the web resources of the application.
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_APP_URI; // Display of /znetdk/applications/default/public/
?>
ZNETDK_ROOT
Abdolute file path of the root directory of ZnetDK (installation folder).
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_ROOT; // Display of /home/hosting999/www/znetdk/
?>
ZNETDK_ROOT_URI
Relative path of the root directory of ZnetDK (installation folder).
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_ROOT_URI; // Display of /znetdk/
?>
ZNETDK_CORE_ROOT
Abdolute file path of the core directory of ZnetDK.
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_CORE_ROOT; // Display of /home/hosting999/www/znetdk/engine/core
?>
ZNETDK_MOD_ROOT
Abdolute file path of the modules directory of ZnetDK.
<?php
/* If ZnetDK is installed into the /home/hosting999/www/znetdk/ folder
and if the Starter Application is currently running... */
echo ZNETDK_MOD_ROOT; // Display of /home/hosting999/www/znetdk/engine/modules
?>
CFG_ZNETDK_IMG_DIR
Relative file path of the images directory of ZnetDK.
<?php
echo CFG_ZNETDK_IMG_DIR; // Display of engine/public/images
?>