set_pk($p_id); // It is very important to set the name of the javascript variable // Contained in the http_input variable "ctl" $objet->set_object_name($objet_name); // Set the ajax to call $objet->set_callback("ajax.php"); // Build the json object for JS $http=new HttpInput(); $plugin_code=$http->request("plugin_code"); $ac=$http->request("ac"); $sa=$http->request("sa"); $aJson=array("gDossier"=>Dossier::id(), "ac"=>$ac, "plugin_code"=>$plugin_code, "sa"=>$sa, "sb"=>$sb ); $json=json_encode($aJson); $objet->param_set($json); // Display the box header('Content-type: text/xml; charset=UTF-8'); $xml=$objet->ajax_input(); echo $xml->save_XML(); @endcode * @see ManageTable.js * @see ajax_accounting.php * @see sorttable.js * */ class Manage_Table_SQL { protected $table; //!< Object Data_SQL protected $a_label_displaid; //!< Label of the col. of the datarow protected $a_order; //!< order of the col protected $a_prop; //!< property for each col. protected $a_type; //!< Type of the column : date , select ... Only in input protected $a_select; //!< Possible value if a_type is a SELECT protected $object_name; //!< Object_name is used for the javascript protected $row_delete; //!< Flag to indicate if rows can be deleted protected $row_update; //!< Flag to indicate if rows can be updated protected $row_append; //!< Flag to indicate if rows can be added protected $json_parameter; //!< Default parameter to add (gDossier...) protected $aerror; //!< Array containing the error of the input data protected $col_sort; //!< when inserting, it is the column to sort,-1 to disable it and append only protected $a_info; //!< Array with the infotip protected $sort_column; //!< javascript sort , if empty there is no js sort const UPDATABLE=1; const VISIBLE=2; private $icon_mod; //!< place of right or left the icon update or mod, default right, accepted value=left,right,first column for mod private $icon_del; //!< place of right or left the icon update or mod, default right, accepted value=left,right /** * @brief Constructor : set the label to the column name, * the order of the column , set the properties and the * permission for updating or deleting row * @example test_manage_table_sql.php * @example ajax_manage_table_sql.php */ function __construct(Data_SQL $p_table) { $this->table=$p_table; $order=0; foreach ($this->table->name as $key=> $value) { $this->a_label_displaid[$value]=$value; $this->a_order[$order]=$value; $this->a_prop[$value]=self::UPDATABLE|self::VISIBLE; $this->a_type[$value]=$this->table->type[$value]; $this->a_select[$value]=null; $order++; } $this->object_name=uniqid("tbl"); $this->row_delete=TRUE; $this->row_update=TRUE; $this->row_append=TRUE; $this->callback="ajax.php"; $this->json_parameter=json_encode(array("gDossier"=>Dossier::id(), "op"=>"managetable")); $this->aerror=[]; $this->icon_mod="right"; $this->icon_del="right"; $this->col_sort=0; // By default no js sort $this->sort_column=""; } /** * send the XML headers for the ajax call */ function send_header() { header('Content-type:text/xml;charset="UTF-8"'); } /** * When adding an element , it is column we checked to insert before, * @return none */ function get_col_sort() { return $this->col_sort; } /** * Set the info for a column, use Icon_Action::infobulle * the message are in message_javascript.php * @param string $p_key Column name * @param integer $p_comment comment idx * * @see message_javascript.php * @see Icon_Action::infobulle() */ function set_col_tips($p_key,$p_comment) { $this->a_info[$p_key]=$p_comment; } /** * When adding an element ,we place it thanks the DOM Attribute sort_value * set it to -1 if you want one to append * @param numeric $pn_num * @note you must be aware that the icon_mod or icon_del is in the first col, * this column is skipped */ function set_col_sort($p_num) { $this->col_sort=$p_num; } function get_icon_mod() { return $this->icon_mod; } function get_icon_del() { return $this->icon_del; } function get_table() { return $this->table; } function set_table(Data_SQL $p_noalyss_sql) { $this->table=$p_noalyss_sql; } function get_order() { return $this->a_order; } function set_order($p_order) { if (! is_array($p_order) ) throw new Exception("set_order, parameter is not an array"); $this->a_order=$p_order; } /** * @brief set the error message for a wrong input * @param $p_col the column name * @param $p_message the error message * @see check */ function set_error($p_col, $p_message) { $this->aerror[$p_col]=$p_message; } /** * returns the nb of errors found */ function count_error() { return count($this->aerror); } /** * @brief retrieve the error message * @param $p_col column name * @return string with message or empty if no error * @see input */ function get_error($p_col) { if (isset($this->aerror[$p_col])) return $this->aerror[$p_col]; return ""; } /** * This function can be overrided to check the data before * inserting , updating or removing, above an example of an overidden check. * * Usually , you get the row of the table (get_table) , you check the conditions * if an condition is not met then you set the error with $this->set_error * * if there are error (returns false otherwise true * * @see set_error get_error count_error * @return boolean * @code function check() { global $cn; $table=$this->get_table(); $is_error=0; $insert=false; // sect_codename must be unique if ( $table->exist() > 0) { $insert=1; } $count=$cn->get_value(" select count(*) from syndicat.treasurer where tr_login=$1 and sect_id=$2 and tr_id<>$3", array( $table->tr_login, $table->section_full_name, $table->tr_id )); if ($count > 0 ) { $this->set_error("section_full_name",_("Ce trésorier a déjà accès à cette section")); $is_error++; } if ( $is_error > 0 ) return false; return true; } * @endcode */ function check() { return true; } /** * @brief set the type of a column , it will change in the input db box , the * select must supply an array of possible values [val=> , label=>] with * the variable $this->key_name->a_value * @param $p_key col name * @param $p_type is SELECT NUMERIC TEXT or DATE * @param $p_array if type is SELECT an array is expected */ function set_col_type($p_key, $p_value, $p_array=NULL) { if (!isset($this->a_type[$p_key])) throw new Exception("invalid key $p_key"); if (!in_array($p_value, array("text", "numeric", "date", "select", "timestamp"))) throw new Exception("invalid type $p_value"); $this->a_type[$p_key]=$p_value; $this->a_select[$p_key]=$p_array; } /** * @brief return the type of a column * @param $p_key col name * @see set_col_type */ function get_col_type($p_key) { if (!isset($this->a_type[$p_key])) throw new Exception("invalid key"); return $this->a_type[$p_key]; } /** * Get the object name * @details : return the object name , it is useful it * the javascript will return coded without the create_js_script function * @see create_js_script */ function get_js_variable() { return $this->object_name; } /** * Add json parameter to the current one */ function add_json_param($p_attribute,$p_value) { $x=json_decode($this->json_parameter,TRUE); $x[$p_attribute]=$p_value; $this->json_parameter=json_encode($x, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_NUMERIC_CHECK); } function get_json() { return $this->json_parameter; } function get_object_name() { return $this->object_name; } /** * Set the parameter of the object (gDossier, ac, plugin_code...) * @detail By default , only gDossier will be set . The default value * is given in the constructor * @param string with json format $p_json * @deprecated since version 692 * @see set_json */ function param_set($p_json) { $this->set_json($p_json); } /** * Set the parameter of the object (gDossier, ac, plugin_code...) * @detail By default , only gDossier will be set . The default value * is given in the constructor * @param string with json format $p_json */ function set_json($p_json) { $this->json_parameter=$p_json; } /** * @brief set the callback function that is passed to javascript * @param $p_file : callback file by default ajax.php */ function set_callback($p_file) { $this->callback=$p_file; } /** * @brief we must create first the javascript if we want to update, insert * or delete rows. It is the default script . */ function create_js_script() { echo " "; } /** * Set the object_name * @param string $p_object_name name of the JS var, used in ajax response,id * of the part of the id DOMElement to modify */ function set_object_name($p_object_name) { $this->object_name=$p_object_name; } /** * @brief set a column of the data row updatable or not * @param string $p_key data column * @param bool $p_value Boolean False or True */ function set_property_updatable($p_key, $p_value) { if (! isset($this->a_prop[$p_key])) throw new Exception(__FILE__.":".__LINE__."$p_key invalid index"); // if already done returns if ( $this->get_property_updatable($p_key) == $p_value)return; if ($p_value==False) $this->a_prop[$p_key]=$this->a_prop[$p_key]-self::UPDATABLE; elseif ($p_value==True) $this->a_prop[$p_key]=$this->a_prop[$p_key]|self::UPDATABLE; else throw new Exception("set_property_updatable [ $p_value ] incorrect"); } /** * @brief return false if the update of the row is forbidden */ function can_update_row() { return $this->row_update; } /** * Set the icon to modify at the right ,the first col or left of the row * * @param type $pString * @throws Exception */ function set_icon_mod($pString) { if ($pString != "right" && $pString != "left" && $pString!="first") throw new Exception('set_icon_mod invalide '.$pString); $this->icon_mod=$pString; } /** * Set the icon to delete at the right or left of the row * @param type $pString * @throws Exception */ function set_icon_del($pString) { if ($pString != "right" && $pString != "left" ) throw new Exception('set_icon_del invalide '.$pString); $this->icon_del=$pString; } /** * @brief return false if the append of the row is forbidden */ function can_append_row() { return $this->row_append; } /** * @brief Enable or disable the deletion of rows * @param $p_value Boolean : true enable the row to be deleted */ function set_delete_row($p_value) { if ($p_value!==True&&$p_value!==False) throw new Exception("Valeur invalide set_delete_row [$p_value]"); $this->row_delete=$p_value; } /** * @brief Enable or disable the appending of rows * @param $p_value Boolean : true enable the row to be appended */ function set_append_row($p_value) { if ($p_value!==True&&$p_value!==False) throw new Exception("Valeur invalide set_append_row [$p_value]"); $this->row_append=$p_value; } /** * @brief Enable or disable the updating of rows * @param $p_value Boolean : true enable the row to be updated */ function set_update_row($p_value) { if ($p_value!==True&&$p_value!==False) throw new Exception("Valeur invalide set_update_row [$p_value]"); $this->row_update=$p_value; } /** * @brief return false if the delete of the row is forbidden */ function can_delete_row() { return $this->row_delete; } /** * @brief return True if the column is updatable otherwise false * @param $p_key data column */ function get_property_updatable($p_key) { $val=$this->a_prop[$p_key]&self::UPDATABLE; if ($val==self::UPDATABLE) return true; return false; } /** * @brief set a column of the data row visible or not * @param string $p_key data column * @param bool $p_value Boolean False or True */ function set_property_visible($p_key, $p_value) { if (!isset ($this->a_prop[$p_key]) ) throw new Exception(__FILE__.":".__LINE__."$p_key invalid index"); // if already done return if ( $this->get_property_visible($p_key) == $p_value)return; if ($p_value==False) $this->a_prop[$p_key]=$this->a_prop[$p_key]-self::VISIBLE; elseif ($p_value==True) $this->a_prop[$p_key]=$this->a_prop[$p_key]|self::VISIBLE; else throw new Exception("set_property_updatable [ $p_value ] incorrect"); } /** * @brief return True if the column is visible otherwise false * @param $p_key data column */ function get_property_visible($p_key) { $val=$this->a_prop[$p_key]&self::VISIBLE; if ($val===self::VISIBLE) return true; return false; } /** * @brief set the name to display for a column * @param string $p_key data column * @param string $p_display Label to display * */ function set_col_label($p_key, $p_display) { $this->a_label_displaid[$p_key]=$p_display; } /** * @brief get the position of a column * @param $p_key data column */ function get_current_pos($p_key) { $nb_order=count($this->a_order); for ($i=0; $i<$nb_order; $i++) if ($this->a_order[$i]==$p_key) return $i; throw new Exception("COL INVAL ".$p_key); } /** * @brief if we change a column order , the order * of the other columns is impacted. * * With a_order[0,1,2,3]=[x,y,z,a] * if we move the column x (idx=0) to 2 * we must obtain [y,z,x,a] * @param string $p_key data column * @param integer $p_idx new location */ function move($p_key, $p_idx) { // get current position of p_key $cur_pos=$this->get_current_pos($p_key); if ($cur_pos==$p_idx) return; if ($cur_pos<$p_idx) { $nb_order=count($this->a_order); for ($i=0; $i<$nb_order; $i++) { // if col_name is not the searched one we continue if ($this->a_order[$i]!=$p_key) continue; if ($p_idx==$i) continue; // otherwise we swap with i+1 $old=$this->a_order[$i+1]; $this->a_order[$i]=$this->a_order[$i+1]; $this->a_order[$i+1]=$p_key; } } else { $nb_order=count($this->a_order)-1; for ($i=$nb_order; $i>0; $i--) { // if col_name is not the searched one we continue if ($this->a_order[$i]!=$p_key) continue; if ($p_idx==$i) continue; // otherwise we swap with i+1 $old=$this->a_order[$i-1]; $this->a_order[$i]=$this->a_order[$i-1]; $this->a_order[$i-1]=$p_key; } } } /** * @brief display the data of the table * @param $p_order is the cond or order of the rows, * if empty the primary key will be used * @param $p_array array of the bind variables * @note the function create_js_script MUST be called before this function */ function display_table($p_order="", $p_array=NULL) { if ($p_order=="") { $p_order="order by {$this->table->primary_key}"; } $ret=$this->table->seek($p_order, $p_array); $nb=Database::num_row($ret); if ($this->can_append_row()==TRUE) { echo HtmlInput::button_action(" "._("Ajout"), sprintf("%s.input('-1','%s')", $this->object_name, $this->object_name), "xx", "smallbutton", BUTTONADD); } $nb_order=count($this->a_order); $virg=""; $result=""; // filter only on visible column $visible=0; for ($e=0; $e<$nb_order; $e++) { if ($this->get_property_visible($this->a_order[$e])==TRUE) { $result.=$virg."$visible"; $virg=","; $visible++; } } echo _('Cherche')." ".HtmlInput::filter_table("tb".$this->object_name, $result, 1); // Set a sort on a column if sort_column is not empty if ( $this->sort_column =="") { printf('
{$label} {$info} {$error} | "; if ($this->get_property_updatable($key)==TRUE) { echo ""; if ($this->a_type[$key]=="select") { $select=new ISelect($key); $select->value=$this->a_select[$key]; $select->selected=$value; echo $select->input(); } elseif ($this->a_type[$key]=="text") { $text=new IText($key); $text->value=$value; $min_size=(strlen($value)<30)?30:strlen($value)+5; $text->size=$min_size; echo $text->input(); } elseif ($this->a_type[$key]=="numeric") { $text=new INum($key); $text->value=$value; $min_size=(strlen($value)<10)?10:strlen($value)+1; $text->size=$min_size; echo $text->input(); } elseif ($this->a_type[$key]=="date") { $text=new IDate($key); $text->value=$value; $min_size=10; $text->size=$min_size; echo $text->input(); } echo " | "; } else { printf('%s %s | ', h($value), HtmlInput::hidden($key, $value) ); } } echo "