'; // default is localhost $ai_Username = ''; // default is root $ai_Password = ''; // default is empty $ai_DBName = ''; include_once('cookbook/ai.php'); TODO database abstraction automatic jointure */ //default values for the database connection if (!isset($ai_Hostname)) $ai_Hostname = 'localhost'; if (!isset($ai_Username)) $ai_Username='root'; if (!isset($ai_Password)) $ai_Password=''; $ai_debug=FALSE; $ai_demo=TRUE; $ai_structure_file='/web/ai/structure.maq'; // TODO rendre universel $ai_sql_structure=array(); $ai_suppose=array(); $ai_permit=array(); update_sql_structure(); //voir($ai_sql_structure,'struture de la base'); get_sql_structure(); // markup definition to use ai in pmwiki system markup('ai','directive','/\\(:ai\\s*(.*?):\\)/e',"FmtAi($1)"); function fmtai($data) // to furnishes to ai his 6 parameters { global $KPV,$KeepToken; // preparation of data passed par directive $data = preg_replace( "/$KeepToken(\\d+?)$KeepToken/e", '$KPV[$1]', $data); $data = preg_replace( "/>/", ">", $data); $data = preg_replace( "/</", "<", $data); $data = preg_replace( "/<:vspace>/","",$data); $data=explode("\n",$data); // separation of variables line by line; $mode='select'; $orientation='h'; $mask=array(); $header_table=array(); if (trim($data[0])!='') $mode=(trim($data[0])); if (trim($data[1])!='') $SQL=trim($data[1]); if (trim($data[2])!='') $orientation=trim($data[2]); if (trim($data[3])!='') $envelop=explode(',',trim($data[3])); if (trim($data[4])!='') $mask=explode(',',trim($data[4])); if (trim($data[5])!='') $header_table=explode(',',trim($data[5])); $data=array_slice($data,0,-1); // for display only return "[=".sql2html($SQL,$mode,$orientation,$envelop,$mask,$header_table,$data)."=]"; // [= =] to immunise ai production from traitement by pmwiki } /*************** * * * ai system * * * ***************/ $ai_style[0]=array('%s
','%s','%s','%s'); $ai_style[1]=array('%s','
    %s
','
  • %s
  • ',''); $ai_submit_word="OK"; function hidden($name,$value) { return ''; } $ai_form_envelop='
    %s%s
    '; $ai_sty=0; $ai_default_envelop=$ai_style[$ai_sty]; /*function for abstraction - connect and pass a table of queries - return string for error - connect and return num fields, name and type and table of data (maybe empty) - close */ function sql2html($SQL,$mode='select',$orientation='v',$envelop=array(),$mask=array(),$header_table=array(),$data) { global $sql_tree,$ai_demo,$ai_debug,$ai_form_envelop,$ai_default_envelop,$ai_sql_structure; /*voir($mode,'mode'); voir($SQL,'requête'); voir($SQL,'orientation'); voir($mask,'mask'); voir($envelop,'envelop');voir($header_table,'en-tête de table');*/ if ($envelop==array()) $envelop=$ai_default_envelop; // when no envelop passing if (!in_array($orientation,array('h','v'))) $orientation='h'; //echo "$SQL - orientation=$orientation
    "; if (in_array($mode,array('select','insert','update'))) { $status=ai_SQLresult($SQL,$name,$datatype,$v,0); // without data if ($status=='') { // value table construction $header=$name; if ($SQL[7]=='*') // force completion in case of * abrev $SQL=str_replace('*',implode(',',$name),$SQL); $sql_tree=sql_analyse($SQL); foreach ($sql_tree['select'] as &$c) // field -> table.field foreach ($sql_tree['from'] as &$t) if (isset($ai_sql_structure["$t.$c"])) // if exist $c="$t.$c"; //voir($sql_tree,'sql_tree'); foreach ($sql_tree['select'] as &$c) { list($t,$f)=explode('.',$c); // field and table if (substr($f,0,3)=='id_') // if it is a pointer field { $target=explode('_',$f);$target=$target[1]; // table name if (!in_array($target,$sql_tree['from'])) $sql_tree['from'][]=$target.'s'; // add table $c=$target."s.$target"; // the new field $sql_tree['where'][]=$target."s.id=$t.$f"; //if (isset($target[2])) // for the relation name id_father_relation } } //voir($name); //!voir($sql_tree,'nouvel arbre'); $SQL=sql_synth('sfwogl'); //voir(sql_synth('sfwogl'),'nouvelle requête'); // traitment of the id //$sql_tree=sql_expansion($sql); $status=ai_SQLresult($SQL,$name,$datatype,$v,1); // with data { if ($status=='') $table2work=$sql_tree['from'][0]; // the first table foreach ($header as &$h) $h=$table2work.".$h"; //voir($header,'header'); if ($mode!='select') // encapsulation for the insert/update form mode $envelop[0]=sprintf($ai_form_envelop,$envelop[0],hidden('ai_mode',$mode).hidden('ai_table',$table2work)); if ($header_table==array()) $header_table=$name; // standard automatic headers (as ?) $line=0; if ($mode!='insert') $ai_data=$v; else // insert - prepare table of empty data for ($i = 0; $i < sizeof($name); $i++)//ABSTRACT for ($j = 0; $j < sizeof($v); $j++)//ABSTRACT $ai_data[$j][$i]= ""; if ($mask==array()) // default mask { $mask=array(); for ($i=0;$i',$name[$i]."[]",'%s')); } $resultStr=ai_array2html(ai_arrayWmask($ai_data,$mask,$mode,$name,$datatype),$orientation,$header_table,$envelop); } } else return $status; // mysql error if ($ai_debug) $resultStr.="
    ".verbatim($envelop,'envelop')."".verbatim($mask,'masks')."".serialize($ai_data)."

    Result

    "; if ($ai_demo) $resultStr="
    ".verbatim($data,'code for Ai:')."

    Result:

    $resultStr
    "; return $resultStr; } else return "Error: only select, insert or update are allowed"; } // rend le nombre d'arguments d'une chaine de format, en tenant compte des motifs de r��itions �entuels function ai_nbr_printf_args($s) { // a=nombre de % suivis d'une lettre dans (b|c|d|e|u|f|F|o|s|x|X) // b=le chiffre max au del�de a en avan�nt 1 par 1, pr���d'un % et suivi de \$ et une lettre dans (b|c|d|e|u|f|F|o|s|x|X) //retourner le max(a,b) // remarque: une chaine de format comme "%s %s %5\s" est mal form� et on la consid�era comme n'ayant que 2 arguments $a=preg_match_all('/%(b|c|d|e|u|f|F|o|s|x|X)+/',$s,$M); $b=0; $n=$a+1; while (preg_match("/%$n\\$(b|c|d|e|u|f|F|o|s|x|X)/",$s)) { $b=$n; $n+=1; } return max($a,$b); } function ai_add_mask($mask,&$n=0,$max) { global $test; while (preg_match('/^.*?%[bcdeufFosxX]/',$mask)) // les %s par des %1\$s { $n++; $mask=preg_replace('/^(.*?)%([bcdeufFosxX])/',"$1".chr(1)."$n\$$2",$mask); } $p=$n; for ($t=$max;$t>0;$t--) // incrémenter les %1\$s { $mask=str_replace("%$t\$","%".($t+$p)."\$",$mask,$o); if ($o>0) $n++; //$test.="1 ".htmlentities(serialize($mask))."/
    "; // "mask=$n $t ---> $mask*
    "; } //echo "$mask
    "; //$test.="OUT ".htmlentities(serialize($mask))."/
    "; return str_replace(chr(1),'%',$mask); } function mask_headers($s,$tag,$data) { $s=explode($tag,$s); while (sizeof($s)>1) { $num=ai_nbr_printf_args($s[0]); $s[1]=$s[0].$data[$num].$s[1]; // replacement of {field} $s=array_slice($s,1); } return $s[0]; // } // $mode=1 = ne pas calculer // les paramètres sont normalisés pour correspondre au numéro du champ de data function ai_arrayWmask($T,$mask,$mode='select',$header=array(),$datatype=array()) // renvoie un tableau { $result=array(); $max_args=sizeof($T[0]); $n=0; for ($i=0;$i$title
    ".implode('
    ',$table)."
    "; } function href_edit($n) // __("edit") { global $todo,$table,$ai_webbase; return "
    "; } function textbox($size=60,$length=255) { return ''; } function textarea($cols=40,$rows=3) { return ''; } $simple_mask=array ( '1'=>href_edit('1'), '2'=>href_edit('2'), '3'=>href_edit('3'), '4'=>href_edit('4'), '5'=>href_edit('5'), // pour discriminer la table appelante (jusqu'à 9 tables éditables différentes dans une page) '6'=>href_edit('6'), '7'=>href_edit('7'), '8'=>href_edit('8'), '9'=>href_edit('9'), 'A'=>textarea(40,3), // saisie d'un pav� de texte 'b'=>'%s', // mise en gras 'c'=>'<* checkboxes("{field}","{type}","%s","{id}") *>', // saisie - cases à  cocher 'd'=>$href_del, // appel de destruction 'D'=>'
    ', // bouton download sur l'adresse 'e'=>href_edit('1'), // appel de saisie simple - aliais de '1' 'f'=>'
    %s
    %s
    ', // d�finitions 'g'=>$get_image.$hidden, // saisie - récupère une image 'H'=>'%s', // lien en gros (voir '>') 'h'=>"$hidden", // champ caché 'i'=>('%s'), // italique 'I'=>"
    ".$image."
    ", // image simple centrée 'k'=>'<* listkeys("%s","{field}","{row}") *>', // c'est une liste déroulante 'l'=>textbox(30), 'n'=>textbox(6,6), 'r'=>'<* radios("{field}","{type}","%s","{id}") *>', // saisie - boutons radios 's'=>textbox(80), // saisie -ligne 't'=>$textbox, // saisie - texte standard 'w'=>"%1\$s", '>'=>'%s', // lien internet '='=>'%s ({field})', // contenu brut sans changement '?'=>'type inconnu', // type inconnu ); function mask_expand($masks,$fields,$type) // pour l'instant très simple { global $simple_mask; for ($i=0;$i$s
    ";print_r($tableau);echo "
    "; } /* function request_inflate(&$tree) // fields are still of the form 'table.field' { $field=explode(chr(1),$tree['s']); // a table of fields $table=explode(chr(1),$tree['f']); $where=explode(chr(1),$tree['w']); for ($i=0;$i"; $D=array(); foreach ($T as $table) { //echo $table[0]."
    "; ai_SQLresult("show fields from ".$table[0],$field,$type,$U,1); foreach ($U as $champ) { $D[$table[0].".".$champ[0]]=($champ[1]); if (substr($champ[0],0,3)=='id_') { $ai_suppose[$table[0]][]=substr($champ[0],3,strlen($champ[0])-3).'s'; $ai_permit[substr($champ[0],3,strlen($champ[0])-3).'s'][]=$table[0]; } } } $ai_sql_structure=$D; return $D; } // update imagefile of database structure function update_sql_structure() { global $ai_structure_file; //echo "ai_structure_database=$ai_database_structure"; //echo 'UPDATE STRUCTURE
    '; array2file(sql_structure(),$ai_structure_file); } function get_sql_structure() { global $ai_sql_structure,$ai_structure_file; if (!is_array($ai_sql_structure)) { //echo 'READ STRUCTURE
    '; if (!file_exists($ai_structure_file)) update_sql_structure(); else $ai_sql_structure=file2array($ai_structure_file); } } // pas de retour, instancie simplement la variable globale sql_structure function array2file($T,$name) { //echo 'DEBUT array2file'; //echo "nom=$name"; $f = fopen($name, 'w+'); ftruncate($f, 0); fflush($f); //flock($f, LOCK_UN); fwrite($f,serialize($T)); fclose($f); //echo 'FIN array2file'; } function file2array($name) { //$data = fopen($name, 'r+'); //flock($data, LOCK_EX); $T = unserialize(get_content($name)); //fclose($data); return $T; } function array2sql($table,$ch,$T,$mode) // to put data into sql form { $todo=array(); $nbc=sizeof($ch); if ($mode=='update') for ($l=0;$l'select', // attention au copier/coller �partir de PhpMyAdmin 'f'=>'from', // il utilise des caract�es sp�iaux invisible dans les chaines 'w'=>'where', 'o'=>'order by', 'g'=>'group by', 'l'=>'limit' ); function sql_synth($s) // s est par exemple wfo ou gl { global $sql_tree,$sql_keys; $b=''; foreach (str_split($s) as $l) // for each letter { $v=$sql_keys[$l]; // select for s //echo "v=$v
    "; if ($v=='where') $glu='and'; else $glu=','; if (isset($sql_tree[$v])) // if exists $b.=' '.$v.' '.implode($glu,$sql_tree[$v]); } return $b; } function sql_analyse($query) // an tree with a sql query { global $sql_keys; $t=array(); // to receive the tree $q=balisage($query); $q=str_replace(chr(2).'by',chr(3).'by',$q); $q=explode(chr(2),$q); // to prepare separation between argument and reserved terms $k=array_keys($sql_keys); // indexkeys do { $t[str_replace(chr(3),' ',$q[0])]=explode(chr(1),$q[1]); $q=array_slice($q,2); } while ($q!=array()); return $t; } function balisage($s) // chr(1) in place of comma for separation between parameters { //echo "$s
    "; $s=trim($s); $in=0; $i1=0; $i2=0; for ($i=0;$i"; switch (substr($s,$i,1)) { case "'":{if ($i2==0) $i1=1-$i1;break;} case '"':{if ($i1==0) $i2=1-$i2;break;} case '[': case '{': case '(':{if (($i1+$i2)==0) $in=$in+1;break;} // si pas dans une chaine... case ']': case '}': case ')':{if (($i1+$i2)==0) $in=$in-1;break;} // si pas dans une chaine... case ',':{if (($i1+$i2+$in)==0) $s=substr($s,0,$i).chr(1).substr($s,$i+1,strlen($s)-$i-1); break;} case ' ':{if (($i1+$i2+$in)==0) $s[$i]=chr(2);} } } //voir($s,'balisage'); return $s; } // update traitment if (@$_POST['ai_form_submit']) // get values and fields and pass to array2sql { // retrieve table from sql $ai_table=$_POST['ai_table']; // number of fields passed by the form //voir($_POST,'post'); // on recense les champs à  modifier en filtrant le POST $ai_modify=array_slice(array_keys($_POST),0,-3); // voir($ai_modify); $T=array(); $rg_chp=0; for ($x=0;$x