PRERELEASE 10A

This commit is contained in:
sparkyx 2025-11-22 15:40:35 +01:00
commit 83efa90a33
1141 changed files with 40635 additions and 85178 deletions

View file

@ -36,9 +36,9 @@ function h($p_string)
{
return ( $p_string === null)?"":htmlspecialchars($p_string,ENT_QUOTES|ENT_HTML5,'UTF-8',true);
}
function p($p_string)
function p($p_string, $p_extra='')
{
return '<p>'.$p_string."</p>";
return '<p '.$p_extra.'>'.$p_string."</p.>";
}
function span($p_string, $p_extra='')
{
@ -170,7 +170,7 @@ function echo_error($p_log, $p_line="", $p_message="")
{
$msg="ERREUR :" . $p_log . " " . $p_line . " " . $p_message;
echo $msg;
syslog(LOG_ERR,$msg);
record_log($msg);
}
@ -314,7 +314,7 @@ function html_page_start($p_theme="", $p_script="", $p_script2="")
if ($is_msie == 0 )
{
echo '<!doctype html>';
echo '<!DOCTYPE html>';
printf("\n");
}
@ -519,7 +519,57 @@ function sql_string($p_string)
$p_string = noalyss_str_replace('\\', '\\\\', $p_string);
return $p_string;
}
/**
* @brief Same menu for all extensions, with the right level, it calls
* ShowItem with the right parameters
* @global $level (int) global variable of the menu level
* @param $p_array (array)
* @param $default (string) selected item
* @param $p_extra (string) extra code for the table tag (CSS or javascript)
* @see ShowItem
*/
function show_menu_extension($p_array,$default="",$p_extra="")
{
global $level;
$level++;
switch ($level) {
case 3:
$p_dir='H';
$class="nav-item nav-item-underline";
$class_ref="nav-link";
$p_extra="noprint nav nav-pills nav-level3";
$class_div="menu3";
break;
case 2:
$p_dir='H';
$class="nav-item nav-item-underline";
$class_ref="nav-link";
$p_extra="noprint nav nav-pills nav-level2";
$class_div="menu2";
break;
case 1:
$p_dir='H';
$class="nav-item nav-item-underline";
$class_ref="nav-link";
$p_extra='noprint nav nav-pills nav-fill flex-row ';
$class_div="top_menu";
break;
default:
$p_dir='H';
$class="nav-item nav-item-underline";
$class_ref="nav-link";
$p_extra="noprint nav nav-level4";
$class_div="menu3";
break;
}
return "<div class=\"$class_div\">"
. ShowItem($p_array,$p_dir,$class,$class_ref,$default,$p_extra)
."</div>";
}
/**
* \brief store the string which print
* the content of p_array in a table
@ -536,6 +586,7 @@ function sql_string($p_string)
function ShowItem($p_array, $p_dir='V', $class="nav-item", $class_ref="nav-link", $default="", $p_extra="nav nav-pills nav-fill")
{
$ret = '';
// for comptability with old application mtitle for anchor is replace by nav-link
@ -543,9 +594,9 @@ function ShowItem($p_array, $p_dir='V', $class="nav-item", $class_ref="nav-link"
// direction Vertical
if ($p_dir == 'V')
{
$ret .= "<ul class=\"$p_extra noprint \" flex-row>";
$ret .= "<ul class=\"$p_extra \" flex-row>";
} else {
$ret .= "<ul class=\"$p_extra noprint \" >";
$ret .= "<ul class=\"$p_extra \" >";
}
@ -565,11 +616,11 @@ function ShowItem($p_array, $p_dir='V', $class="nav-item", $class_ref="nav-link"
if ($set==$default)
{
$ret.='<li class="nav-item"><A class="'.$class_ref.' active'.'" HREF="'.$href[0].'" title="'.$title.'" '.$javascript.'>'.$href[1].'</A></li>';
$ret.='<li class="'.$class.'"><A class="'.$class_ref.' active'.'" HREF="'.$href[0].'" title="'.$title.'" '.$javascript.'>'.$href[1].'</A></li>';
}
else
{
$ret.='<li class="nav-item"><A class="'.$class_ref.'" HREF="'.$href[0].'" title="'.$title.'" '.$javascript.'>'.$href[1].'</A></li>';
$ret.='<li class="'.$class.'"><A class="'.$class_ref.'" HREF="'.$href[0].'" title="'.$title.'" '.$javascript.'>'.$href[1].'</A></li>';
}
}
@ -1066,15 +1117,13 @@ function find_default_module()
/**
* @brief show the module
* @var $g_user
* @param $module the $_REQUEST['ac'] exploded into an array
* @param $idx the index of the array : the AD code is splitted into an array thanks the slash
*/
function show_menu($module)
{
if ($module == 0)return;
static $level=0;
global $g_user;
global $level, $g_user;
$http=new HttpInput();
$access_code=$http->request("ac");
$cn = Dossier::connect();
@ -1101,7 +1150,7 @@ function show_menu($module)
if (!empty($amenu) && count($amenu) > 1)
{
$a_style_menu=array('topmenu','menu2','menu3');
if ( $level > count($a_style_menu))
if ( $level >= count($a_style_menu))
$style_menu='menu3';
else {
$style_menu=$a_style_menu[$level];
@ -1728,7 +1777,7 @@ function MaintenanceMode($p_file)
}
/**
* @brief returns an double array with the error found and code , if the count is 0 then the password is very string, 5 means it is
* @brief returns an double array with the error found and code , if the count is 0 then the password is very strong, 5 means it is
* empty ,4 weak, ... the array contains the errors, [msg]=>array message [code] => array of code
* Codes are
* - 1 : too short
@ -1878,3 +1927,105 @@ function guidv4($data = null) {
// Output the 36 character UUID.
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
/**
* @brief retrieve the index for the key percent, returns -1 if nothing found
* @param $array (array) SubTotal
* @param $key (string) name of the key
* @param $value (string) value to look for
* @return int
*/
function find_idx($array,$key,$value) {
if ( count($array) == 0 ) { return -1; }
$nb_array=count($array);
for($i=0;$i <$nb_array;$i++) {
if ($array[$i][$key] == $value) {
return $i;
}
}
return -1;
}
function compute_letter_value()
{
global $aLetter,$aLetterValue;
static $make_string=null;
if ( $make_string == null ) {
for ($i=65;$i!=91;$i++) {
$make_string[chr($i)]=$i-55;
}
$aLetter=array_keys($make_string);
$aLetterValue=array_values($make_string);
}
}
/**
* @brief check that an IBAN is valid
* @param $iban string, this parameter will change:remove of space, comma,...
* @return bool false the IBAN is invalid, true IBAN is VALID
*/
function check_iban(&$iban): bool
{
global $aLetter, $aLetterValue;
if (trim($iban ?? "") == "")
return false;
//------------------------------------------------
// Make the letter
//------------------------------------------------
static $make_string,$aLetter, $aLetterValue=null;
if ( $make_string == null )
{
for ($i=65;$i!=91;$i++)
{
$make_string[chr($i)]=$i-55;
}
$aLetter=array_keys($make_string);
$aLetterValue=array_values($make_string);
}
$iban = strtoupper($iban);
$iban=str_replace([" ", ",", ".", "-"], '', $iban);
$first = substr($iban, 0, 4);
$chain = substr($iban, 4) . $first;
$replaced = str_replace($aLetter, $aLetterValue, $chain);
// computed by slice of 10: mod function is limited
$start = 0;
$slice = 10;
$result = "";
$length = strlen($replaced);
while ($start < $length)
{
$slice_string = $result . substr($replaced, $start, $slice);
$result = $slice_string % 97;
$start += $slice;
}
if ($result == 1)
return true;
return false;
}
/**
* @brief convert a value in Mbytes, kb ... in byte
* @param (string) $p_value containing K , M, G
* @return int in bytes
*/
function convert_ini_unit($p_value)
{
if ($p_value=="") return 0;
$a_convert=["k"=>1024,"m"=>1024**2,"g"=>1024**3];
$p_value=trim($p_value);
$last=strtolower($p_value[strlen($p_value)-1]);
$p_value=substr($p_value,0,strlen($p_value)-1);
if ( isset($a_convert[$last])) {
$p_value=$p_value*$a_convert[$last];
}
return $p_value;
}

View file

@ -34,7 +34,8 @@
*
* - table = name of the view or empty
* - sql = sql statement
* - name = array of column name, match between logic and actual name
* - name = array of column name, match between logic and actual name, or
* only an array of columns
* - type = array , match between column and type of data
* - default = array of column with a default value
* - date_format = format of the date
@ -92,7 +93,8 @@
@endcode
*
*/
#[AllowDynamicProperties]
#[\AllowDynamicProperties]
abstract class Data_SQL
{
var $cn; //! Database connection
@ -101,11 +103,11 @@ abstract class Data_SQL
var $type; //! Type of the data
var $date_format; //! defaullt date format
var $default;
var $table;
var $table;
protected $a_virtual_col;
public function __toString(): string
{
$ret="values ";
$ret=" members: ";
foreach ($this->name as $name) {
$ret.="[ $name => {$this->$name} ]";
}
@ -114,6 +116,7 @@ abstract class Data_SQL
$ret.="| default ".print_r($this->default,true);
$ret.="| primary key ".$this->primary_key;
$ret.="| date_format ".$this->date_format;
$ret.="| a_virtual_col".var_export($this->a_virtual_col,true);
return $ret;
}
@ -123,6 +126,7 @@ abstract class Data_SQL
$this->cn=$p_cn;
$pk=$this->primary_key;
$this->$pk=$p_id;
$this->a_virtual_col=array();
// check that the definition is correct
if (count($this->name) != count($this->type) ){
throw new Exception (__FILE__." $this->table Cannot instantiate");
@ -133,7 +137,7 @@ abstract class Data_SQL
foreach ($this->name as $key)
{
if ( in_array($key,['name','type','format_date','cn','date_format','default'] ) ) {
throw new Exception ('DATASQL-94 invalid column name'.$key);
throw new Exception ('DATASQL-94 invalid column name'.$key,94);
}
$this->$key=null;
}
@ -154,60 +158,120 @@ abstract class Data_SQL
else
$this->update();
}
/**
* @brief return array of virtual cols (alias calculated, formatted cols)
* @return array
*/
public function get_a_virtual_col() {
return $this->a_virtual_col;
}
/**
* @brief add a virtual column (formatted column, sum of 2 col, ...)
* @param $col_name (string) name of the column , will be use in get , getp
* @param $sql_expression (string) SQL Expression for the column
* like "to_char(col1,'DD.MM.YY HH24:MI:SS')", col1+col2, ...
* @note sql expression and col_name must be valid , there is no futher
* check
* @returns void
*/
public function set_virtual_col($col_name,$sql_expression) {
$this->a_virtual_col[$col_name]=$sql_expression;
}
/**
*@brief get the value thanks the colum name and not the alias (name).
*@see getp
*/
public function get($p_string)
public function get($cols)
{
if (array_key_exists($p_string, $this->type)) {
return $this->$p_string;
if (array_key_exists($cols, $this->type)) {
return $this->$cols;
}
else
throw new Exception(__FILE__.":".__LINE__.$p_string.'Erreur attribut inexistant '.$p_string);
if (array_key_exists($cols, $this->a_virtual_col))
{
return $this->$cols;
}
throw new \Exception (" unknow cols [$cols] =".$this,EXC_DATA_SQL);
}
/**
*@brief set the value thanks the colum name and not the alias (name)
*@see setp
*/
public function set($p_string, $p_value)
public function set($cols, $p_value)
{
if (array_key_exists($p_string, $this->type)) {
$this->$p_string=$p_value;
if (array_key_exists($cols, $this->type)) {
$this->$cols=$p_value;
return $this;
} else
throw new Exception(__FILE__.":".__LINE__.$p_string.'Erreur attribut inexistant '.$p_string);
throw new \Exception (" unknow cols [$cols] =".$this,EXC_DATA_SQL);
}
/**
*@brief set the value thanks the alias name instead of the colum name
* if not found try the column name
*@see get
*/
public function getp($p_string)
public function getp($cols)
{
if (array_key_exists($p_string, $this->name)) {
$idx=$this->name[$p_string];
if (array_key_exists($cols, $this->name)) {
$idx=$this->name[$cols];
return $this->$idx;
}
else
throw new Exception(__FILE__.":".__LINE__.$p_string.'Erreur attribut inexistant '.$p_string);
if (array_key_exists($cols, $this->type)) {
return $this->$cols;
}
if (array_key_exists($cols, $this->a_virtual_col))
{
return $this->$cols;
}
throw new \Exception (" unknow cols [$cols] =".$this,EXC_DATA_SQL);
}
/**
*@brief set the value thanks the alias name instead of the colum name
*@brief set the value thanks the alias name instead of the colum name,
* if not found try the column name
*@see set
*/
public function setp($p_string, $p_value)
public function setp($cols, $p_value)
{
if (array_key_exists($p_string, $this->name)) {
$idx=$this->name[$p_string];
if (array_key_exists($cols, $this->name)) {
$idx=$this->name[$cols];
$this->$idx=$p_value;
return $this;
} else
throw new Exception(__FILE__.":".__LINE__.$p_string.'Erreur attribut inexistant '.$p_string);
}
if (array_key_exists($cols, $this->type)) {
$this->$cols=$p_value;
return $this;
}
throw new \Exception (" unknow cols [$cols] =".$this,EXC_DATA_SQL);
}
public function __set($cols,$p_value) {
if (array_key_exists($cols, $this->type)) {
$this->$cols=$p_value;
return $this;
}
if ( ! empty ($this->a_virtual_col) && array_key_exists($cols, $this->a_virtual_col))
{
$this->$cols=$p_value;
return $this;
}
throw new \Exception (" unknow cols [$cols] =".$this,EXC_DATA_SQL);
}
public function __get($cols) {
if (array_key_exists($cols, $this->type)) {
return $this->$cols;
}
if (! empty ($this->a_virtual_col) && array_key_exists($cols, $this->a_virtual_col))
{
return $this->$cols;
}
throw new \Exception (" unknow cols [$cols] =".$this,EXC_DATA_SQL);
}
abstract function insert();
abstract function delete();
@ -273,7 +337,7 @@ abstract class Data_SQL
}
/**
* Transform an array into object
* @brief Transform an array into object
* @param type $p_array
* @return object
*/
@ -306,17 +370,34 @@ abstract class Data_SQL
$nkey=$prefix.$key;
$array[$key]=$this->$key;
}
if ( ! empty ($this->a_virtual_col )) {
$a_column= array_keys($this->a_virtual_col);
foreach( $a_column as $column){
$array[$column]=$this->a_virtual_col[$column];
}
}
return $array;
}
/**
* @brief turns a row fetched from the DB into a SQL object in updating all his attribute
* @param $p_array
* @brief update the data member of current object with the value from the array.
* includes the virtual column, usefull if need to update several columns in once
* @param $p_array (array) associative key = column_vale, value new value for this col.
* @return void
*/
public function to_row($p_array) {
foreach ($this->name as $name) {
$this->$name=$p_array[$name];
if (isset ($p_array[$name])) {
$this->$name=$p_array[$name];
}
}
if ( ! empty ($this->a_virtual_col )) {
$a_column= array_keys($this->a_virtual_col);
foreach( $a_column as $column){
if ( isset ($p_array[$column])) {
$this->$column = $p_array[$column];
}
}
}
}
/**
@ -330,8 +411,8 @@ abstract class Data_SQL
abstract function seek($cond='', $p_array=null);
/**
* @brief get_seek return the next object, the return of the query must have all the column
* of the object
* @brief get_seek return the next object, the return of the query must have
* all the column of the object including the virtual columns
* @param $p_ret is the return value of an exec_sql
* @param $idx is the index
* @see seek
@ -340,7 +421,18 @@ abstract class Data_SQL
public function next($ret, $i)
{
$array=$this->cn->fetch_array($ret, $i);
return $this->from_array($array);
$this->from_array($array);
if ( ! empty ($this->a_virtual_col )) {
$a_column= array_keys($this->a_virtual_col);
foreach( $a_column as $column){
if ( isset ($array[$column] )) {
$this->$column = $array[$column];
} else {
$this->$column = null;
}
}
}
return $this;
}
/**
@ -370,7 +462,9 @@ abstract class Data_SQL
$a_return=array();
for ($i=0; $i<$max; $i++)
{
$a_return[$i]=clone $this->next($ret, $i);
$x=clone $this->next($ret, $i);
$a_return[$i]=$x;
}
return $a_return;
}

View file

@ -35,14 +35,19 @@ require_once NOALYSS_INCLUDE . '/lib/ac_common.php';
class DatabaseCore
{
private $db;
protected $db;
/**< database connection */
private $ret;
protected $ret;
/**< return value */
private $is_open; /*!< true is connected */
protected $is_open; /*!< true is connected */
public $sql; //!< last SQL stmt executed
public $array;
/*** Connect to a database return an connx to db or false if it fails
protected $dbname; ///!< $dbname (string) Database name
protected $dbport;///!< $dbport (int) Database port
protected $dbhost;///!< $dbhost(string) Database host
protected $dbuser;///!< $dbuser(string) Database user
/***
* @brief Connect to a database return an connx to db or false if it fails
*
* @param string $p_user Username
* @param type $p_password User's password
@ -74,13 +79,31 @@ class DatabaseCore
throw new Exception(_('Erreur Connexion'));
}
}
$this->dbport=$p_port;
$this->dbname=$p_dbname;
$this->dbhost=$p_host;
$this->dbuser=$p_user;
$this->is_open = TRUE;
$this->sql="";
}
public function get_dbname() {
return $this->dbname;
}
/**
public function get_dbport() {
return $this->dbport;
}
public function get_dbhost() {
return $this->dbhost;
}
public function get_dbuser() {
return $this->dbuser;
}
/**
* return the name of the current database
* @return false|string
*/
@ -216,7 +239,7 @@ class DatabaseCore
record_log($p_array);
$this->rollback();
throw ($a);
throw new \Exception("exec_sql fails",242,$a);
}
return $this->ret;
@ -383,14 +406,15 @@ class DatabaseCore
/**
* @brief fetch the $p_indice array from the last query
* @param $p_mode is PGSQL_ASSOC, PGSQL_BOTH or PGSQL_NUM (default PGSQL_ASSOC)
* @param $p_indice index
*
*/
function fetch($p_indice)
function fetch($p_indice,$p_mode= PGSQL_ASSOC)
{
if ($this->ret == false)
throw new Exception('this->ret is empty');
return pg_fetch_array($this->ret, $p_indice,PGSQL_ASSOC);
return pg_fetch_array($this->ret, $p_indice,$p_mode);
}
/**
@ -466,16 +490,17 @@ class DatabaseCore
* in a array
* \param $p_sql sql query
* \param $p_array if not null we use ExecSqlParam
* \param $p_mode is PGSQL_ASSOC, PGSQL_BOTH or PGSQL_NUM (default PGSQL_ASSOC)
* \return false if nothing is found
*/
function get_array($p_sql, $p_array = null)
function get_array($p_sql, $p_array = null,$p_mode=PGSQL_ASSOC)
{
$r = $this->exec_sql($p_sql, $p_array);
$r = $this->exec_sql($p_sql, $p_array,$p_mode);
if (pg_num_rows($r) == 0)
return array();
$array = pg_fetch_all($r);
$array = pg_fetch_all($r,$p_mode);
return $array;
}
@ -693,27 +718,39 @@ class DatabaseCore
}
/***
* \brief Save a document into the database , it just puts the file in the database
* \brief Save one or several documents into the database , it just puts the file in the database
* and returns the corresponding OID , the mimetype , size ... of the document
* must be set in the calling function.
*
* \param name of the variable in $_FILES
* \param $only_oid (bool) (default :true) false : return filename and oid in an array , true only OID,
* \return $oid of the lob file if success
* false if a error occurs or if there is no file to upload
* array(oid, filename) if $only_oid is true
*
*/
function upload($p_name)
function upload($p_name,$only_oid = false)
{
//var $a : 0 we're in a transaction, 1 we are not in a transaction
$a=0;
if ( $this->status() !== PGSQL_TRANSACTION_INTRANS ) {
$a=1;
$this->start();
}
/* there is no file to upload */
if ($_FILES[$p_name]["error"] == UPLOAD_ERR_NO_FILE) {
\record_log("DC759: error upload file".var_export($_FILES, true));
if ( $a==1) { $this->rollback(); }
return false;
}
$new_name = tempnam($_ENV['TMP'], $p_name);
if ($_FILES[$p_name]["error"] > 0) {
print_r($_FILES);
echo_error(__FILE__ . ":" . __LINE__ . "Error: " . $_FILES[$p_name]["error"]);
\record_log("DC740: error upload file".var_export($_FILES, true));
if ( $a==1) { $this->rollback(); }
return false;
}
if (strlen($_FILES[$p_name]['tmp_name']) != 0) {
@ -721,19 +758,101 @@ class DatabaseCore
// echo "Image saved";
$oid = pg_lo_import($this->db, $new_name);
if ($oid == false) {
echo_error(__FILE__, __LINE__, "cannot upload document");
\record_log("DC747: error upload file".var_export($_FILES, true). "SQL MESSAGE". pg_last_error($this->db));
$this->rollback();
return false;
}
return $oid;
if ( $a == 1 ) { $this->commit(); }
if ($only_oid ){
return $oid;
}else {
return ["oid"=>$oid,'filename'=>$new_name];
}
} else {
echo "<H1>Error</H1>";
\record_log("DC754: move_uploaded fails".var_export($_FILES, true));
$this->rollback();
return false;
}
}
\record_log("DC576: Files error names empty".var_export($_FILES, true));
if ( $a == 1) { $this->commit(); }
return false;
}
/**
* @brief large_object writee: create a Large object if oid is not given
* with data content in a binaray
* @param $binary_data (raw data) binary
* @returns $oid of the LO, false if it fails
*/
function lo_write($binary_data)
{
//var $a : 0 where in a transaction, 1 we are not in a transaction
$a=0;
if ( $this->status() !== PGSQL_TRANSACTION_INTRANS ) {
$a=1;
$this->start();
}
$oid= pg_lo_create($this->db);
if ( ($handle=pg_lo_open($this->db,$oid,"w")) == false ) { return false ;}
pg_lo_write($handle, $binary_data);
pg_lo_close($handle);
if ( $a==1) { $this->commit(); }
return $oid;
}
/**
* @brief read a Large object with data content in a binary
* @param $oid (int8) oid of the large object
* @returns $binary_data (raw data) binary
*/
function lo_read($oid)
{
//var $a : 0 where in a transaction, 1 we are not in a transaction
$a=0;
if ( $this->status() !== PGSQL_TRANSACTION_INTRANS ) {
$a=1;
$this->start();
}
$handle=pg_lo_open($this->db,$oid,"r");
if ( $handle == false ) { return false ;}
// set position end of the LO
pg_lo_seek($handle, 0, PGSQL_SEEK_END);
// get the size
$size= pg_lo_tell($handle);
// set position to start
pg_lo_seek($handle, 0, PGSQL_SEEK_SET);
// read the comùplete LOB
$binary_data = pg_lo_read($handle,$size );
pg_lo_close($handle);
if ( $a==1) { $this->commit(); }
return $binary_data;
}
/**
* @brief replace a Large object with data content in a binary
* @param $oid (int8) oid of the large object
* @param $binary_data (raw data) binary
* @returns $oid of the LO, false if it fails
*/
function lo_replace($binary_data, $oid) {
$a = 0;
if ($this->status() !== PGSQL_TRANSACTION_INTRANS) {
$a = 1;
$this->start();
}
$handle = pg_lo_open($this->db, $oid, "w");
if ( $handle == false ) { return false ;}
pg_lo_truncate($handle, 0);
pg_lo_write($handle, $binary_data);
pg_lo_close($handle);
if ($a == 1) {
$this->commit();
}
return $oid;
}
/**
* \brief wrapper for the function pg_num_rows
@ -750,7 +869,7 @@ class DatabaseCore
* \brief wrapper for the function pg_fetch_array
* \param $ret is the result of a pg_exec
* \param $p_indice is the index
* \param $p_indice is the index
* \param $p_mode is PGSQL_ASSOC, PGSQL_BOTH or PGSQL_NUM (default PGSQL_ASSOC)
* \return $array of column
*/
@ -762,12 +881,13 @@ class DatabaseCore
/**
* \brief wrapper for the function pg_fetch_all
* \param $ret is the result of pg_exec (exec_sql)
* \param $p_mode is PGSQL_ASSOC, PGSQL_BOTH or PGSQL_NUM (default PGSQL_ASSOC)
* \return double array (row x col ) or false
*/
static function fetch_all($ret)
static function fetch_all($ret,$p_mode= PGSQL_ASSOC)
{
return pg_fetch_all($ret,PGSQL_ASSOC);
return pg_fetch_all($ret,$p_mode);
}
/**
@ -797,7 +917,7 @@ class DatabaseCore
/**
* \brief wrapper for the function pg_lo_unlink
* \param $p_oid is the of oid
* \return return the result of the operation
* \return return the result of the operation : false == fails
*/
function lo_unlink($p_oid)

View file

@ -1780,7 +1780,7 @@ function encodeURIbycharacter($char)
function decodeURI($string)
{
$result = "";
for ($i = 0; $i < strlen($string); $i++)
for ($i = 0; $i < strlen($string)-8; $i++)
{
$decstr = "";
for ($p = 0; $p <= 8; $p++)
@ -2779,14 +2779,16 @@ EOF;
echo js_include('todo_list.js');
echo js_include('anc_script.js');
echo js_include('sorttable.js');
echo js_include('nicEdit.js');
echo js_include('managetable.js');
echo js_include('acc_currency.js');
echo js_include('taggroup.js');
echo js_include('noalyss_checkbox.js');
echo js_include('tinymce/tinymce.min.js');
if (DEBUGNOALYSS > 1) {
echo js_include('noalyss_debug.js');
}
echo '<script src="export.php?loadjs=message" type="text/javascript" charset="utf-8"></script>';
}
/**
* @brief Send header and json object

View file

@ -892,7 +892,7 @@ class HtmlInput
* @return type
*/
static function title_box($p_name, $p_div, $p_mod="close", $p_js="",
$p_draggable="n",$p_enlarge='n',$raw="")
$p_draggable="n",$p_enlarge='n',$raw="",$refresh='')
{
$p_div=strip_tags($p_div);
$r='<div class="bxbutton">';
@ -905,6 +905,9 @@ class HtmlInput
if ( $p_enlarge=='y') {
$r.=Icon_Action::full_size($p_div);
}
if ( $refresh != '') {
$r.=Icon_Action::refresh(uniqid(), $refresh);
}
if ($p_mod=='close')
{
$r.=Icon_Action::close($p_div, $p_js);
@ -1026,6 +1029,30 @@ class HtmlInput
return $sel;
}
}
/**
* @brief filter the rows in a table and keep the colored row in alternance
* @param dom_id $p_table_id table
* @param string $p_col , column to search example 0,1,2
* @param int $start_row row to always keep (header)
* @param string $p_name name of the input field
* @param string $domid domid containing the second filter, it could be an HIDDEN, TEXT, SELECT field
* @return string HTML
*/
static function filter_table_DOM($p_table_id, $p_col, $start_row, $p_name
,$domid)
{
$r="
<span>
<span class=\"icon\" >&#xf50d;</span>
<input id=\"lk_".$p_table_id."\" name=\"$p_name\" autocomplete=\"off\" class=\"input_text\" name=\"filter\" onkeyup=\"filter_table(this, '$p_table_id','$p_col',$start_row ,'$domid')\" type=\"text\" placeholder=\""._("Filtre rapide")."\">
<input type=\"button\" class=\"smallbutton\" onclick=\"$('lk_".$p_table_id."').value='';filter_table($('lk_".$p_table_id."'), '$p_table_id','$p_col',$start_row,'$domid' );\" value=\"X\">
</span>
";
$r.=' <span class="notice" style="display:none" id="info_'.$p_table_id.'"></span>';
return $r;
}
/**
* @brief filter the rows in a table and keep the colored row in alternance
* @param dom_id $p_table_id table
@ -1045,7 +1072,7 @@ class HtmlInput
<input type=\"button\" class=\"smallbutton\" onclick=\"$('lk_".$p_table_id."').value='';filter_table($('lk_".$p_table_id."'), '$p_table_id','$p_col',$start_row );\" value=\"X\">
</span>
";
$r.=' <span class="notice" id="info_'.$p_table_id.'"></span>';
$r.=' <span class="notice" style="display:none" id="info_'.$p_table_id.'"></span>';
return $r;
}
/**
@ -1065,7 +1092,7 @@ class HtmlInput
<input type=\"button\" class=\"smallbutton\" onclick=\"$('lk_".$p_table_id."').value='';filter_table($('lk_".$p_table_id."'), '$p_table_id','$p_col',$start_row );\" value=\"X\">
</span>
";
$r.=' <span class="notice" id="info_'.$p_table_id.'"></span>';
$r.=' <span class="notice" style="display:none" id="info_'.$p_table_id.'"></span>';
return $r;
}
/**
@ -1167,7 +1194,7 @@ class HtmlInput
*/
static function show_receipt_document($p_jr_id, $p_name="")
{
global $cn;
$cn=\Dossier::connect();
$image=$p_name;
// Check the jr_id has a receipt document

View file

@ -0,0 +1,87 @@
<?php
/*
* Copyright (C) 2025 dany
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
* \file
* \brief input of the IBAN Number of a supplier / customer, propose a button to check
*/
class IBan_Number extends \HtmlInput
{
private $itext;
function __construct($name = '', $value = '', $p_id = "")
{
$p_id = ($p_id=="")?uniqid("ibannumber"):$p_id;
$this->itext = new IText($name,$value,$p_id);
$this->itext->title = _("IBAN");
$this->itext->placeholder = "9999999999";
$this->itext->extra = "";
$this->itext->style = ' class="input_text" ';
$this->autofocus = false;
}
function input()
{
if ( $this->readOnly==true) return $this->display();
$return = $this->itext->input();
$return .= $this->button_check_iban();
$return.=sprintf('<div id="info%s" class="notice" style="margin:0px;font-size:80%%;width:auto"></div>',$this->itext->id);
return $return;
}
public function getIText(): IText
{
return $this->itext;
}
public function setIText(IText $itext): IBan_Number
{
$this->itext = $itext;
return $this;
}
function button_check_iban()
{
$button=new \IButton(uniqid());
$button->javascript=sprintf("category_card.check_ibannumber('%s')",
$this->itext->id);
$button->extra='style="padding-bottom:0px"';
$button->label=_("Vérifie");
return $button->input();
}
function display()
{
return $this->itext->display();
}
static function testme()
{
$iban_number=new IBan_Number("av_text13");
echo $iban_number->input();
}
}

View file

@ -105,15 +105,15 @@ class ISmallButton extends IButton
$extra= ( isset($this->extra))?$this->extra:"";
$this->id=($this->id=="")?$this->name:$this->id;
$tab=(isset($this->tabindex))?' tabindex="'.$this->tabindex.'"':"";
$attr=$this->get_node_attribute();
$r='<input type="BUTTON" name="'.$this->name.'"'.
' class="smallbutton" '.
$this->extra.
$tab.
' id="'.$this->id.'"'.
' value="'.$this->label.'"'.
' onClick="'.$this->javascript.'"'.$extra.'>';
$attr=$this->get_js_attr();
$r.=$attr;
' onClick="'.$this->javascript.'"'.$extra." $attr ".'>';
return $r;
}

View file

@ -65,7 +65,7 @@
$W1->set_attribute('typecard','deb');
$W1->extra='deb';
O
// Add the callback function to filter the card on the jrn
$W1->set_callback('filter_card');
@ -158,6 +158,7 @@ class ICard extends HtmlInput
//!< $autocomplete_file , ajax file used for autocompletion (see Ajax.Autocompleter)
private $autocomplete_file;
protected $after_clean; //!< javascript to call after cleaning the INPUT TEXT
function __construct($name="", $value="", $p_id="")
{
parent::__construct($name, $value);
@ -176,8 +177,20 @@ class ICard extends HtmlInput
$this->amount_from_type=''; //!< in the follow up ,when a card is selected you take Prix Vente or Prix Achat
$this->typecard='all';
$this->autocomplete_file="fid_card.php";
$this->after_clean="";
}
/**
public function getAfter_clean()
{
return $this->after_clean;
}
public function setAfter_clean($after_clean)
{
$this->after_clean = $after_clean;
return $this;
}
/**
* Function javascript by default it is update_value called BEFORE the querystring is send in ajax
* @return type
*/
@ -475,8 +488,8 @@ class ICard extends HtmlInput
$this->dblclick=$e;
}
$input='<div class="d-none d-lg-inline">'.
Icon_Action::clean_zone(uniqid("remove"),"$('{$this->id}').value=''").
$input='<div class="d-none d-lg-inline">'.
Icon_Action::clean_zone(uniqid("remove"),"clean_Fid('{$this->id}');{$this->after_clean}").
"</div>";
$input.=sprintf('

View file

@ -272,7 +272,7 @@ class Icon_Action
*/
static function trash($p_id,$p_javascript)
{
$r='<span id="'.$p_id.'" onclick="'.$p_javascript.'" class="smallicon icon">&#xe80f;</span>';
$r='<span id="'.$p_id.'" onclick="'.$p_javascript.'" class="bt-error smallicon icon">&#xe80f;</span>';
return $r;
}
/**
@ -509,5 +509,15 @@ class Icon_Action
);
return $r;
}
static function refresh($p_id,$javascript)
{
$javascript=str_replace('"', '&quot;',$javascript);
//icon-arrows-cw
$r=sprintf('<i id="%s" onclick="%s" class="smallicon icon icon-arrows-cw" style="margin-left:5px"></i>',
$p_id,$javascript
);
return $r;
}
}

View file

@ -63,7 +63,7 @@ class INum extends IText
$r='<INPUT '.$style.' TYPE="TEXT" id="'.
$this->id.'"'.
'NAME="'.$this->name.'" VALUE="'.$this->value.'" '.
'SIZE="'.$this->size.'" '.$this->javascript." $readonly $this->extra >";
'SIZE="'.$this->size.' " '.$this->javascript." $readonly $this->extra >";
/* add tag for column if inside a table */
if ($this->table==1)

View file

@ -0,0 +1,79 @@
<?php
/*
* This file is part of NOALYSS.
*
* NOALYSS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* NOALYSS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NOALYSS; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Copyright Author Dany De Bontridder danydb@aevalys.eu 13/05/24
/*!
* \file
* \brief input of the VAT Number of a supplier / customer, propose a button to check VAT
*/
class IPEPPOL_ID extends HtmlInput
{
private $itext;
function __construct($name = '', $value = '', $p_id = "")
{
$p_id = ($p_id=="")?uniqid("peppol_id"):$p_id;
$this->itext = new IText($name,$value,$p_id);
$this->itext->title = _("PEPPOL_ID");
$this->itext->placeholder = "9999:9999999999";
$this->itext->extra = "";
$this->itext->style = ' class="input_text" ';
$this->autofocus = false;
}
function input()
{
if ( $this->readOnly==true) return $this->display();
$return = $this->itext->input();
$return .= $this->button_check_peppol();
$return.=sprintf('<div id="info%s" class="notice" style="margin:0px;font-size:80%%;width:auto"></div>',$this->itext->id);
return $return;
}
public function getIText(): IText
{
return $this->itext;
}
public function setIText(IText $itext): IPEPPOL_ID
{
$this->itext = $itext;
return $this;
}
function button_check_peppol()
{
$button=new \IButton(uniqid());
$button->javascript=sprintf("category_card.display_search_peppol('%s')",
$this->itext->id);
$button->extra='style="padding-bottom:0px"';
$button->label=_("Vérifie");
return $button->input();
}
function display()
{
return $this->itext->display();
}
}

View file

@ -88,12 +88,12 @@ class IPoste extends HtmlInput
$this->extra2="all";
$this->extra="";
$this->attribute=array();
$this->id=$p_id;
$this->id=$p_id;
$this->nb_row=1;
}
static function ipopup($p_name)
static function ipopup($p_name)
{
$ip=new IPopup($p_name);
$ip->title='Plan comptable';

View file

@ -20,11 +20,20 @@
// Copyright Author Dany De Bontridder danydb@aevalys.eu
/*!
* \file
* \brief Html Input
* \brief Html Input Text
*/
/*!
* \class IText
* \brief Html Input
* \brief Html Input Text
* member :
* - placeholder (string) placeholder
* - title (string) title of the HTML ELT
* - autofocus (bool) true to have an autofocus
* - css_size (string) size in the specified unit ex: 20%
* - pattern (string) pattern for HTML
* - maxlength (int) max length of the fied
* - size (int) size without unit
* - require (bool) is element require
*/
class IText extends HtmlInput
{
@ -33,6 +42,10 @@ class IText extends HtmlInput
var $css_size;
var $pattern; /*!< $pattern HTML pattern */
var $maxlength; /*!< HTML maxlength */
var $require ; /*!< $require (bool)*/
protected $datalist; /*!< $datalist (double array)
* each row has a key (value) and a label used with make_datalist */
function __construct($name='',$value='',$p_id="")
{
parent::__construct($name,$value,$p_id);
@ -45,8 +58,11 @@ class IText extends HtmlInput
$this->css_size="";
$this->pattern="";
$this->maxlength="";
$this->datalist=null;
}
/*!\brief show the html input of the widget*/
/*!
\brief show the html input of the widget
*/
public function input($p_name=null,$p_value=null)
{
$this->name=($p_name==null)?$this->name:$p_name;
@ -63,7 +79,7 @@ class IText extends HtmlInput
$autofocus=($this->autofocus)?" autofocus ":"";
$require=($this->require)?"required":"";
// var $pattern regex to match the INPUT TEXT
// var $pattern regex to match the INPUT TEXT
$pattern="";
if ($this->pattern != "") {
$pattern= sprintf( 'pattern="%s"',$this->pattern);
@ -74,12 +90,12 @@ class IText extends HtmlInput
if ($this->maxlength !="" ) {
$maxlength=sprintf(' maxlength="%s" ',$this->maxlength);
}
$datalist=(empty($this->datalist ))?"":sprintf('list="dl_%s"',$this->id);
if ( ! isset ($this->css_size) || empty ($this->css_size))
{
$r= sprintf('<INPUT TYPE="TEXT" %s id="%s" name="%s" value="%s" placeholder="%s" title="%s"
Size="%s" %s %s %s %s %s %s %s >
size="%s" %s %s %s %s %s %s %s %s>
',$this->style,
$this->id,
$this->name,
@ -93,11 +109,12 @@ class IText extends HtmlInput
$require,
$strAttribute,
$pattern,
$maxlength
$maxlength,
$datalist
);
} else {
$r= sprintf('<INPUT TYPE="TEXT" %s id="%s" name="%s" value="%s" placeholder="%s" title="%s"
style="width:%s;" %s %s %s %s %s %s %s>
style="width:%s ;" %s %s %s %s %s %s>
',$this->style,
$this->id,
$this->name,
@ -111,24 +128,33 @@ class IText extends HtmlInput
$require,
$strAttribute,
$pattern,
$maxlength
$maxlength,
$datalist
);
}
/* add tag for column if inside a table */
if ( $this->table == 1 ) $r='<td>'.$r.'</td>';
$r.=$this->make_datalist();
return $r;
}
/*!\brief print in html the readonly value of the widget*/
public function get_datalist() {
return $this->datalist;
}
public function set_datalist($datalist) {
$this->datalist = $datalist;
return $this;
}
/*!\brief print in html the readonly value of the widget*/
public function display()
{
$t= ((isset($this->title)))?'title="'.$this->title.'" ':' ';
$extra=(isset($this->extra))?$this->extra:"";
$strAttribute=$this->get_node_attribute();
$readonly=" readonly ";
$this->value=htmlentities($this->value??"", ENT_COMPAT|ENT_QUOTES, "UTF-8");
$this->style=' class="input_text_ro" ';
@ -137,16 +163,18 @@ class IText extends HtmlInput
$r='<INPUT '.$this->style.' TYPE="TEXT" id="'.
$this->id.'"'.$t.
'NAME="'.$this->name.'" VALUE="'.$this->value.'" '.
'SIZE="'.$this->size.'" '.$this->javascript." $readonly $this->extra $strAttribute>";
'SIZE="'.$this->size.'" '.$this->javascript." $readonly $this->extra $strAttribute>";
} else {
$r='<INPUT '.$this->style.' TYPE="TEXT" id="'.
$this->id.'"'.$t.
'NAME="'.$this->name.'" VALUE="'.$this->value.'" '.
' style="width:'.$this->css_size.'" '.$this->javascript." $readonly $this->extra $strAttribute>";
' style="width:'.$this->css_size.'" '.$this->javascript." $readonly $this->extra $strAttribute>";
}
/* add tag for column if inside a table */
if ( $this->table == 1 ) $r='<td>'.$r.'</td>';
if ($this->table == 1) {
$r = '<td>' . $r . '</td>';
}
return $r;
@ -158,4 +186,21 @@ class IText extends HtmlInput
static public function test_me()
{
}
/**
* @brief add a datalist
* @param $array (double array) each row has 2 keys 0 => stored value 1=>label
* @return string
*/
protected function make_datalist()
{
if ( empty($this->datalist)) return "";
$r=sprintf('<datalist id="dl_%s"">',$this->id);
foreach ($this->datalist as $item) {
$r.=sprintf('<option value="%s">%s %s</option>'
,$item[0],$item[1]
,htmlentities($item[1]));
}
$r.='</datalist>';
return $r;
}
}

View file

@ -35,6 +35,7 @@ class ITextarea extends HtmlInput
parent::__construct($p_name, $p_value, $p_id);
$this->style=' class="itextarea" ';
$this->enrichText="plain";
$this->heigh=500;
}
/**
@ -49,13 +50,14 @@ class ITextarea extends HtmlInput
/**
* @brief set enrichText to plain or enrich , enrich for WYSIWYG function, plain, plain textarea and choose
* to display a button to switch to a WYSIWYG
* @param mixed $enrich
* @param mixed $enrich plain , enrich (full option) , min (minimum options)
*/
public function set_enrichText($enrich)
{
if ( ! in_array($enrich,['plain','enrich'])) {
throw new \Exception("IT57.Invalid option");
if ( ! in_array($enrich,['enrich','plain','full',"minimal","no-toolbar"])) {
throw new \Exception("IT57.Invalid option [$enrich]");
}
if ( $enrich == 'enrich') $enrich='full';
$this->enrichText = $enrich;
return $this;
}
@ -69,30 +71,26 @@ class ITextarea extends HtmlInput
$this->value=($p_value==null)?$this->value:$p_value;
$this->id=($this->id=="")?$this->name:$this->id;
if ( $this->readOnly==true) return $this->display();
if ( empty($this->id)) $this->id=$this->name;
if ( $this->enrichText == "plain" ) {
$r="";
$r.='<TEXTAREA '.$this->style.' name="'.$this->name.'" id="'.$this->id.'"';
$r.='>';
$r.=$this->value;
$r.="</TEXTAREA>";
} elseif ($this->enrichText=='enrich') {
if ( empty($this->id)) $this->id=$this->name;
} else {
$r=<<<EOF
<textarea name="{$this->name}" id="{$this->id}" {$this->style}>{$this->value}</textarea>
<script type="text/javascript">
(function() {
new nicEditor({
buttonList : ['fontSize','fontFamily','fontFormat','bold','italic','underline',
'strikethrough','subscript','superscript','link','unlink','bgcolor','forecolor','indent','outdent','ol',
'ul','left','center','right','justify','hr','removeformat'],
'iconsPath': 'image/nicEditorIcons.gif'
}).panelInstance('{$this->id}');
noalyss.activate_tinymce('{$this->id}','{$this->enrichText}',{$this->heigh});
})();
</script>
EOF;
}
return $r;
}

View file

@ -61,6 +61,7 @@ class ITva_Popup extends HtmlInput
$this->button = true;
$this->in_table = false;
$this->value = $p_value;
if ($p_id =="") $p_id= uniqid ("vat");
$this->id = $p_id;
$this->filter = 'none';
}
@ -140,7 +141,7 @@ class ITva_Popup extends HtmlInput
$code = $this->code->input();
}
$strAttribut = $this->get_node_attribute();
$get_attribute = $this->get_node_attribute();
// show tva code
if ( self::$vat_code == 1) {
if ( isNumber($this->value ) == 1) {
@ -151,7 +152,7 @@ class ITva_Popup extends HtmlInput
$str = '<input type="TEXT" class="input_text" name="%s" value="%s" id="%s" placeholder="%s" size="6" %s %s
list="dl_tva_%s" autocomplete="off">';
$r = sprintf($str, $this->name, $this->value, $this->id, _("C.TVA"),$this->js, $strAttribut,$this->id);
$r = sprintf($str, $this->name, $this->value, $this->id, _("C.TVA"),$this->js, $get_attribute,$this->id);
$r.=$code;
if ($this->in_table)

View file

@ -0,0 +1,251 @@
<?php
namespace Noalyss;
/*
* This file is part of NOALYSS.
*
* NOALYSS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* NOALYSS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NOALYSS; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Copyright Author Dany De Bontridder danydb@noalyss.eu 21.10.2025
/**
* @file
* @brief configuration email and test PHPMAILER
*/
/*
* CREATE TABLE public.parm_mail_server (
pe_id int4 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START 1 CACHE 1 NO CYCLE) NOT NULL, -- pk
pe_name varchar NULL, -- Config. name
pe_parameter text NOT NULL, -- key for json
pe_value text NULL, -- value of the key
CONSTRAINT param_email_pk PRIMARY KEY (pe_id),
CONSTRAINT parm_email_unique UNIQUE (pe_name, pe_parameter)
);
COMMENT ON TABLE public.parm_mail_server IS 'Parameters for email server';
-- Column comments
COMMENT ON COLUMN public.parm_mail_server.pe_id IS 'pk';
COMMENT ON COLUMN public.parm_mail_server.pe_name IS 'Config. name';
COMMENT ON COLUMN public.parm_mail_server.pe_parameter IS 'key for json';
COMMENT ON COLUMN public.parm_mail_server.pe_value IS 'value of the key';
*/
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
/**
* @class
* @brief configuration email and test PHPMAILER.
* Property :
* - $cn Database conx
* - $name name of the SMTP conx
* - $a_value array
* - smtp_user' username
- 'smtp_password' password
- 'smtp_host' host
- 'smtp_port' port
- 'smtp_replyto' email address to reply
- 'smtp_from' email address sender
- 'smtp_auth' smtp authorisation (always 1)
- 'smtp_type' smtp
- 'smtp_secure' kind of encryption PHPMailer::ENCRYPTION_STARTTLS, or PHPMailer::ENCRYPTION_SMTPS.
- 'smtp_auth_type'SMTP authentication type. Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2.
*
*/
class Mail_Parameter
{
const PARAMETER = [
'smtp_user'
, 'smtp_password'
, 'smtp_host'
, 'smtp_port'
, 'smtp_replyto'
, 'smtp_from'
, 'smtp_auth'
, 'smtp_type'
, 'smtp_secure'
, 'smtp_auth_type'
];
protected $a_value; //!< $a_value array of PARAMETER=>Value
// private $char_set; //!< string character set of message
function __construct(
protected \Database $cn
, protected $name
)
{
$this->load();
}
/**
* @brief set the value in the array $a_value thkx the key
* @param $key (string) key must be in Mail_Parameter::PARAMETER
* @param $value (string) value
* @return Mail_Parameter
* @throws \Exception if the key doesn't exist
*/
function __set($key, $value)
{
if (in_array($key, Mail_Parameter::PARAMETER) == false)
{
throw new \Exception("MP72 : unknown $key");
}
$this->a_value[$key] = $value;
return $this;
}
/**
* @brief get the value in the array $a_value thkx the key
* @param $key (string) key must be in Mail_Parameter::PARAMETER
* @param $value (string) value
* @return a string or null if not found
* @throws \Exception if the key doesn't exist
*/
function __get($key)
{
if (in_array($key, Mail_Parameter::PARAMETER) == false)
{
throw new \Exception("MP79 : unknown $key");
}
if (isset($this->a_value[$key]))
{
return $this->a_value[$key];
}
return null;
}
/**
* @brief save into the database
*/
function save()
{
foreach (self::PARAMETER as $key)
{
$id = $this->cn->get_value("select pe_id from parm_mail_server
where pe_parameter=$1
and pe_name=$2",
[$key, $this->name]);
if ($id == "")
{
$record = new \Parm_Mail_Server_SQL($this->cn);
$record->set("pe_name", $this->name);
$record->set("pe_parameter", $key);
$record->set("pe_value", $this->a_value[$key]);
$record->insert();
} else
{
$record = new \Parm_Mail_Server_SQL($this->cn, $id);
$record->set("pe_value", $this->a_value[$key]);
$record->update();
}
}
}
/**
* @brief load from the database
*/
function load()
{
$a_value = array_column(
$this->cn->get_array("select pe_parameter , pe_value from
public.parm_mail_server
where
pe_name=$1"
, [$this->name])
, "pe_value","pe_parameter"
);
foreach (self::PARAMETER as $key)
{
$this->a_value[$key] = $a_value[$key] ?? "";
}
}
function get($key)
{
return $this->$key;
}
function set($key, $value): Mail_Parameter
{
$this->$key = $value;
return $this;
}
/**
* @brief display a form to input the parameter
*
*/
function input()
{
include NOALYSS_TEMPLATE . "/mail_parameter-input.php";
}
/**
* @brief retrieve information from GET
*/
function from_get()
{
$http = new \HttpInput();
$this->smtp_user = $http->get('smtp_user');
$this->smtp_password = $http->get('smtp_password');
$this->smtp_host = $http->get('smtp_host');
$this->smtp_port = $http->get('smtp_port');
$this->smtp_replyto = $http->get('smtp_replyto');
$this->smtp_from = $http->get('smtp_from');
$this->smtp_type= $http->get('smtp_type');
$this->smtp_secure = $http->get('smtp_secure');
$this->smtp_auth_type = $http->get('smtp_auth_type');
$this->smtp_auth=1;
}
/**
* @brief retrieve information from POST
*/
function from_post()
{
$http = new \HttpInput();
$this->smtp_user = $http->post('smtp_user');
$this->smtp_password = $http->post('smtp_password');
$this->smtp_host = $http->post('smtp_host');
$this->smtp_port = $http->post('smtp_port');
$this->smtp_replyto = $http->post('smtp_replyto');
$this->smtp_from = $http->post('smtp_from');
$this->smtp_type= $http->post('smtp_type');
$this->smtp_secure = $http->post('smtp_secure');
$this->smtp_auth_type = $http->post('smtp_auth_type');
$this->smtp_auth=1;
}
public static function Factory(\Database $cnx,$reply_to="", $blind_copy="")
{
$mail_parameter=new Mail_Parameter($cnx,MAIL_SETTING_NOALYSS);
if ( $mail_parameter->smtp_type=="sendmail") {
return new Sendmail($mail_parameter->smtp_replyto,$mail_parameter->smtp_replyto);
} elseif ($mail_parameter->smtp_type=="smtp") {
$phpmail= new SMTPMail($mail_parameter);
return $phpmail;
}
throw new \Exception("MP212 MAIL NOT CONFIGURED",212);
}
}

View file

@ -218,7 +218,7 @@ class Manage_Table_SQL
*/
function send_header()
{
header('Content-type:text/xml;charset="UTF-8"');
@header('Content-type:text/xml;charset="UTF-8"');
}
/**
@ -1384,6 +1384,7 @@ function check()
ob_start();
echo HtmlInput::title_box($this->getTitle(), $this->dialog_box,"close","","y","y");
print '<div class="content">';
printf('<form id="frm%s_%s" method="POST" onsubmit="%s.save(\'frm%s_%s\');return false;">',
$this->object_name, $this->table->get_pk_value(),
$this->object_name, $this->object_name,
@ -1409,7 +1410,7 @@ function check()
'</li>',
'</ul>';
echo "</form>";
print "</div>";
$html=ob_get_contents();
ob_end_clean();

View file

@ -107,9 +107,9 @@ content[72]="<?php echo htmlspecialchars(_("Pour les journaux FIN, ce sera la fi
content[73]="<?php echo htmlspecialchars(_("Mettre à oui pour un journal dédié uniquement aux notes de crédit ou de débit, il affichera un avertissement si le montant n'est pas en négatif"),ENT_QUOTES);?>";
content[74]="<?php echo htmlspecialchars(_('TVA due ou récupérable quand l\'opération est payée ou exécutée'),ENT_QUOTES)?>";
content[75]="<?php echo htmlspecialchars(_('Journaux Achat ou vente en mode simple, TVA ou détaillé'),ENT_QUOTES)?>";
content[76]="<?php echo htmlspecialchars(_('Il est conseillé d\'avoir un quickcode de moins de 9 car.'),ENT_QUOTES)?>";
content[76]="<?php echo htmlspecialchars(_('Conseil : quickcode de moins de 9 car. commençant pas les 2 ou 3 premiers chiffres du poste comptable'),ENT_QUOTES)?>";
content[77]="<?php echo htmlspecialchars(_("Permet de chercher dans le suivi pour les contacts multiples"),ENT_QUOTES)?>";
<?php $file_too_large=sprintf("Fichier trop grand , taille max = %s mb",(round(MAX_FILE_SIZE/1024/1024,2)));?>
<?php $file_too_large=sprintf("Fichier trop grand , taille max = %s mb total = %s",(round(MAX_FILE_SIZE/1024/1024,2)),ini_get("post_max_size"));?>
content[78]="<?php echo htmlspecialchars($file_too_large,ENT_QUOTES)?>";
content[79]="<?php echo htmlspecialchars(_("Les postes comptables sont entre [] , les fiches entre {} et les postes analytiques entre {{ }}"))?>";

View file

@ -77,11 +77,16 @@ class Noalyss_Csv
}
/***
*@brief Send an header for CSV , the filename is corrected
*@brief Send an header for CSV , the filename is corrected. If TEST_UNIT is defined, the function is called
* from a test file (located in scenario , see manual )and no header are requested
*/
function send_header()
{
$this->correct_name();
if ( defined('TEST_UNIT')) {
return;
}
header('Pragma: public');
header('Content-type: application/csv');
header("Content-Disposition: attachment;filename=\"{$this->filename}\"",
@ -292,5 +297,32 @@ class Noalyss_Csv
$this->size = $size;
return $this;
}
/**
* @brief convert CSV strings (content of a file) into HTML table,
* @param $string CSV files
*/
static function csv2table ($string)
{
$a_field=[';',','];
$sep_field=$a_field[$_SESSION[SESSION_KEY.'csv_fieldsep']];
$a_field=['.',','];
$sep_dec=$a_field[$_SESSION[SESSION_KEY.'csv_decimal']];
$encoding=$_SESSION[SESSION_KEY.'csv_encoding'];
$aRow=explode("\r\n", $string);
echo '<table class="result">';
foreach ($aRow as $row) {
echo '<tr>';
$aCol=explode($sep_field, $row);
foreach ($aCol as $col) {
echo '<td>';
echo h($col);
echo '</td>';
}
echo '</tr>';
}
echo '</table>';
}
}

View file

@ -276,7 +276,7 @@ class Output_Html_Tab
}
/**
* get the CSS class of tabs_selected
* @brief get the CSS class of tabs_selected
* @return mixed
*/
public function get_class_tab_selected()
@ -285,7 +285,7 @@ class Output_Html_Tab
}
/**
* set the CSS class of tabs, default is tabs_selected
* @brief set the CSS class of tabs, default is tabs_selected
* @param mixed $class_tab_selected
*/
public function set_class_tab_selected($class_tab_selected)
@ -295,7 +295,7 @@ class Output_Html_Tab
}
/**
* Build the javascript to change the class name of the selected tab, hide other div and show the selected one
* @brief Build the javascript to change the class name of the selected tab, hide other div and show the selected one
* @param string $p_not_hidden id of the showed tab
* @return javascript string
*/

View file

@ -64,8 +64,8 @@ class PDF_Core extends TFPDF
private $cells=array();
private $bigger;
protected $cells=array();
protected $bigger;
public function __construct ( $orientation = 'P', $unit = 'mm', $format = 'A4')
{
@ -119,7 +119,7 @@ class PDF_Core extends TFPDF
* @param $p_text String
* @param $p_colSize size of the column in User Unit
*/
private function count_nb_row($p_text,$p_colSize)
protected function count_nb_row($p_text,$p_colSize)
{
// If colSize is bigger than the size of the string then it takes 1 line
if ( $this->GetStringWidth($p_text) <= $p_colSize) return 1;
@ -153,7 +153,7 @@ class PDF_Core extends TFPDF
* Check if a page must be added due a MultiCell
* @return boolean
*/
private function check_page_add()
protected function check_page_add()
{
// break on page
$size=count($this->cells);
@ -260,24 +260,65 @@ class PDF_Core extends TFPDF
}
$this->cells=array();
}
private function add_cell(Cellule $Ce)
protected function add_cell(Cellule $Ce)
{
$size=count($this->cells);
$this->cells[$size]=$Ce;
}
function write_cell ($width, $heigh=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='')
/**
* @brief add a cell the text is not cut and don't return to this line if too large
* @param $width width (in PDF unit )
* @param $height height (in PDF unit )
* @param $txt text to print (unicode)
* @param $border border valid values are 1 : border ,0 : no-border, T : top,B : bottom,L : left,R : right
* @param $interline (unit pt ) space between lines
* @param $align text alignment valid values are L : left,R : right
* @param $fill color true or false
* @param $link url
* @return void*/
function write_cell ($width, $height=0, $txt='', $border=0, $interline = 0, $align='', $fill=false, $link='')
{
$this->add_cell(new Cellule($width,$heigh,$txt,$border,$ln,$align,$fill,$link,'C'));
$this->add_cell(new Cellule($width,$height,$txt,$border,$interline,$align,$fill,$link,'C'));
}
function LongLine($width,$heigh,$txt,$border=0,$align='',$fill=false)
/**
* @brief add a cell with automatic return to the line if the text is too long
* @param $width width (in PDF unit )
* @param $interline interline (unit pt)
* @param $txt text to print (unicode)
* @param $border border valid values are 1 : border ,0 : no-border, T : top,B : bottom,L : left,R : right
* @param $align text alignment valid values are L : left,R : right
* @param $fill color true or false
* @return void
*/
function write_multi($width,$interline,$txt,$border=0,$align='',$fill=false)
{
$this->add_cell(new Cellule($width,$heigh,$txt,$border,0,$align,$fill,'','M'));
$this->add_cell(new Cellule($width,$interline,$txt,$border,0,$align,$fill,'','M'));
}
/**
* @brief add a cell with automatic return to the line if the text is too long, deprecated ,
* it calls only PDFCore::write_cell_
* @see PDF_Core::write_multi()
* @param $w width (in PDF unit )
* @param $h interline (in pt)
* @param $txt text to display
* @param $border border valid values are 1 : border ,0 : no-border, T : top,B : bottom,L : left,R : right
* @param $align text align valid values are L : left,R : right
* @param $fill color true or false
* @return void
*@deprecated
*/
function LongLine($w,$h,$txt,$border=0,$align='',$fill=false)
{
$this->write_multi($w,$h,$txt,$border,$align,$fill);
}
/**
* Print all the cell stored and call Ln (new line)
* @brief Print all the cell stored and call Ln (new line)
* @param int $p_step
*/

View file

@ -156,17 +156,17 @@ class Select_Box
{
if ($this->item[$i]['type']=="url")
{
printf('<li><a href="%s">%s</a></li>', $this->item[$i]['url'], $this->item[$i]['label']);
printf('<li><a href="%s"><span class="search-content">%s</span></a></li>', $this->item[$i]['url'], $this->item[$i]['label']);
}
else // For javascript
if ($this->item[$i]['type']=="javascript")
{
printf('<li><a href="javascript:void(0)" onclick="%s">%s</a></li>', $this->item[$i]['javascript'],
printf('<li><a href="javascript:void(0)" onclick="%s"><span class="search-content">%s</span></a></li>', $this->item[$i]['javascript'],
$this->item[$i]['label']);
}
else if ($this->item[$i]['type']=="value")
{
printf('<li><a href="javascript:void(0)" onclick="%s">%s</a></li>', $this->item[$i]['javascript'],
printf('<li><a href="javascript:void(0)" onclick="%s"><span class="search-content">%s</span></a></li>', $this->item[$i]['javascript'],
$this->item[$i]['label']);
}
else if ($this->item[$i]['type']=="input")

View file

@ -164,7 +164,6 @@ class Sendmail_Core
// message PLAIN
$this->content .= "--" . $separator . $eol;
$this->content .= "Content-Type: text/plain; charset=UTF-8" . $eol;
$this->content .= "Content-Transfer-Encoding: 8bit" . $eol.$eol ;
$this->content .= $this->message . $eol ;
} elseif ($this->format == 'HTML') {
@ -200,7 +199,6 @@ eof;
$this->content .= $this->message. $eol ;
$this->content .=" </body> </html>".$eol;
$this->content .= "--" . $separator_second."--" . $eol;
}else {
throw new \Exception('SC172 : unknow format ');

View file

@ -27,22 +27,37 @@ define ('CODE_EXCP_DUPLICATE',901);
/**
* @brief Objec to check a double insert into the database, this duplicate occurs after
* a refresh of the web page
* in
*/
class Single_Record
{
public $name;
public $id;
private $dbconx; //!< database connexion
/**
* Constructor $p_name will be set to $this->name, it is also the name
* @brief Constructor $p_name will be set to $this->name, it is also the name
* of the tag hidden in a form
* @remark $cn Db connexion
* @param $p_name
* @param $p_name (string) name of the HIDDEN INPUT
* @param $dbconx Database connx , if not given; use global $cn;
*/
function __construct($p_name)
function __construct($p_name,$dbconx=-1)
{
$this->name=$p_name;
$this->id=0;
if ( is_numeric($dbconx ) ) {
global $cn;
$this->dbconx=$cn;
}else {
$this->dbconx=$dbconx;
}
}
function __toString(): string {
return "Single_Record[name=" . $this->name
. ", id=" . $this->id
. ", dbconx=" . $this->dbconx
. "]";
}
/**
* @brief return a string with a tag hidden and a uniq value
@ -51,8 +66,7 @@ class Single_Record
*/
function hidden()
{
global $cn;
$this->id=$cn->get_next_seq('uos_pk_seq');
$this->id=$this->dbconx->get_next_seq('uos_pk_seq');
return HtmlInput::hidden($this->name,$this->id);
}
/**
@ -62,19 +76,18 @@ class Single_Record
*/
function save($p_array=null)
{
global $cn;
if ( $p_array == null ) $p_array=$_POST;
$this->id=$p_array[$this->name];
if ( $p_array == null ) $p_array=$_POST;
$this->id=$p_array[$this->name];
$sql="insert into tool_uos(uos_value) values ($1)";
try {
$cn->exec_sql($sql,array($this->id));
$this->dbconx->exec_sql($sql,array($this->id));
} catch (Exception $e)
{
throw new Exception('Duplicate value');
}
}
/**
* Count how many time we have this->id into the table tool_uos
* @brief Count how many time we have this->id into the table tool_uos
* @remark global $cn Database connexion
* @param $p_array is the array where to find the key name, usually it is
* $_POST. The default value is $_POST
@ -85,7 +98,7 @@ class Single_Record
global $cn;
if ( $p_array == null ) $p_array=$_POST;
$this->id=$p_array[$this->name];
$count=$cn->get_value('select count(*) from tool_uos where uos_value=$1',
$count=$this->dbconx->get_value('select count(*) from tool_uos where uos_value=$1',
array($this->id));
return $count;
}
@ -96,7 +109,7 @@ class Single_Record
$this->id=$p_array[$this->name];
try
{
$count=$cn->get_value('select count(*) from tool_uos where uos_value=$1',
$count=$this->dbconx->get_value('select count(*) from tool_uos where uos_value=$1',
array($this->id));
if ($count != 0 ) throw new Exception ('DUPLICATE',CODE_EXCP_DUPLICATE);
}catch (Exception $e)

View file

@ -0,0 +1,160 @@
<?php
/*
* This file is part of NOALYSS.
*
* NOALYSS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* NOALYSS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NOALYSS; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Copyright Author Dany De Bontridder danydb@noalyss.eu 21.10.2025
namespace Noalyss;
/**
* @file
* @brief
*/
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
/**
* @class SMTPMail
* @brief
*/
class SMTPMail
{
protected $phpmailer;
/**
* @param $reply_to
* @param $blind_copy
*/
public function __construct(Mail_Parameter $mail_parameter)
{
$this->phpmailer = new PHPMailer;
$this->phpmailer->CharSet = PHPMailer::CHARSET_UTF8;
//$this->phpmailer->SMTPDebug = SMTP::DEBUG_CONNECTION;
$this->phpmailer->SMTPDebug = SMTP::DEBUG_OFF;
$this->phpmailer->isSMTP(true);
$this->phpmailer->XMailer = "noalyss-email";
$this->phpmailer->Host = $mail_parameter->smtp_host;
$this->phpmailer->Port = $mail_parameter->smtp_port;
$this->phpmailer->Username = $mail_parameter->smtp_user;
$this->phpmailer->Password = $mail_parameter->smtp_password;
$this->phpmailer->SMTPAuth = ($mail_parameter->smtp_auth == 1) ? true : false;
$this->phpmailer->SMTPSecure = $mail_parameter->smtp_secure;
$this->phpmailer->setFrom($mail_parameter->smtp_from);
$this->phpmailer->SMTPSecure = $mail_parameter->smtp_secure;
$this->phpmailer->setFrom($mail_parameter->smtp_from);
// $this->phpmailer->addReplyTo($mail_parameter->smtp_replyto);
// $this->blind_copy = $blind_copy;
$this->phpmailer->isHTML(true);
}
public function getPhpmailer()
{
return $this->phpmailer;
}
public function set_from($from)
{
$this->phpmailer->setFrom($from);
}
public function setPhpmailer($phpmailer): PHPMailer
{
$this->phpmailer = $phpmailer;
return $this;
}
function set_format($format): SMTPMail
{
if (strtolower($format) == 'html')
{
$this->phpmailer->isHTML(true);
return $this;
}
$this->phpmailer->isHTML(false);
return $this;
}
/**
* @param mixed $blind_copy
*/
public function setBlindCopy($blind_copy): SMTPMail
{
$this->phpmailer->addBCC($this->blind_copy);
return $this;
}
/**
* @param mixed $reply_to
*/
public function setReplyTo($reply_to): SMTPMail
{
$this->phpmailer->addReplyTo($reply_to);
return $this;
}
function add_supplemental_header()
{
}
function __toString()
{
}
function mailto($email): SMTPMail
{
$a_email = explode(',', $email);
foreach ($a_email as $item)
{
$this->phpmailer->addAddress($item);
}
return $this;
}
function set_subject($subject): SMTPMail
{
$this->phpmailer->Subject = $subject;
return $this;
}
function set_message($msg): SMTPMail
{
$this->phpmailer->Body = $msg;
$this->phpmailer->AltBody = \strip_tags($msg);
return $this;
}
function add_file(\FileToSend $filename): SMTPMail
{
$this->phpmailer->addAttachment($filename->full_name);
return $this;
}
function compose(): SMTPMail
{
$this->phpmailer->preSend();
return $this;
}
function send(): SMTPMail
{
$this->phpmailer->send();
return $this;
}
}

View file

@ -35,7 +35,7 @@
* - type = array , match between column and type of data
* - default = array of column with a default value
* - date_format = format of the date
*
* - virtual_col
* After you call the parent constructor
* @note the view or the table must include an unique key, otherwise the load
* doesn't work.
@ -83,20 +83,39 @@
}
* @endcode
*
* it is also possible to use set_virtual_col to format data directly in the
* SQL
* @see Data_SQL
@code
$jrn->set_virtual_col("str_date", " to_char(jr_tech_date,'DD/MM/YY HH24:MI')");
@endcode
*/
#[AllowDynamicProperties]
abstract class Table_Data_SQL extends Data_SQL
{
function __construct($p_cn, $p_id=-1)
{
parent::__construct($p_cn, $p_id);
}
public function __toString(): string
{
$ret=" members : ";
foreach ($this->name as $name) {
$ret.="[ $name => {$this->$name} ]";
}
$ret.="| type ".var_export($this->type,true);
$ret.="| default ".var_export($this->default,true);
$ret.="| primary key ".$this->primary_key;
$ret.="| date_format ".$this->date_format;
$ret.="| a_virtual_col".var_export($this->a_virtual_col,true);
return $ret;
}
public function insert()
{
$this->verify();
@ -156,6 +175,9 @@ abstract class Table_Data_SQL extends Data_SQL
return $this;
}
/**
* @brief update the row but not the column with a default value
*/
public function update()
{
$this->verify();
@ -191,22 +213,23 @@ abstract class Table_Data_SQL extends Data_SQL
*/
public function load():bool
{
$sql=$this->build_query();
$pk=$this->primary_key;
// primary cannot be null or empty
if (trim($this->$pk??"")==="" || $this->$pk===null) {
$this->pk=-1;
$this->$pk=-1;
return false;
}
$result=$this->cn->get_array($sql,array ($this->$pk));
$sql=$this->build_query();
$sql.=" where ".$this->primary_key." = $1";
$result=$this->cn->get_row($sql,array ($this->$pk));
if ($this->cn->count()==0)
{
$this->$pk=-1;
return false;
}
foreach ($result[0] as $key=> $value)
foreach ($result as $key=> $value)
{
$this->$key=$value;
}
@ -224,7 +247,8 @@ abstract class Table_Data_SQL extends Data_SQL
*/
function seek($cond='', $p_array=null)
{
$sql="select * from ".$this->table." $cond";
$sql=$this->build_query();
$sql.=" $cond ";
$ret=$this->cn->exec_sql($sql, $p_array);
return $ret;
}
@ -270,12 +294,22 @@ abstract class Table_Data_SQL extends Data_SQL
$sep=",";
}
$pk=$this->primary_key;
/**
* add virtual column
*/
if ( ! empty( $this->a_virtual_col)){
$nb_virtual_col=count($this->a_virtual_col);
$a_col= array_keys($this->a_virtual_col);
for ($x=0;$x<$nb_virtual_col ;$x++) {
$col=$a_col[$x];
$expr=sprintf("$sep %s as %s ",$this->a_virtual_col[$col], $col);
$sql.=" $expr ";
}
}
$sql.=" from ".$this->table;
$sql.=" where ".$this->primary_key." = $1";
return $sql;
}
/**
* @brief Get all the row and use the p_key_code are the key value of array.
* The key column is usually the primary key or any unique key.
@ -316,9 +350,7 @@ abstract class Table_Data_SQL extends Data_SQL
}
catch (Exception $exc)
{
echo $exc->getMessage();
record_log($exc->getMessage());
record_log($exc->getTraceAsString());
record_log($exc);
throw $exc;
}
return $a_result;

View file

@ -101,7 +101,7 @@ function MenuAdmin()
);
}
$menu=ShowItem($item,'H',"nav-item","nav-link",$def,'nav nav-pills nav-fill ');
$menu=show_menu_extension($item,$def);
return $menu;
}