* @version 1.1 * @package tableeditor */ //Version 2006-04-21 //Version 2006-05-04 //Version 2006-05-07 //Version 2006-06-08 - add filtering capabilities to the display //Version 2006-06-16 - add file uploads setUploadPath() and fieldname='filename' //Version 2006-07-21 - add ability to autodetect options for enum() fields, and show them as a "; //check for any defaults if(count($this->fieldDefaults)) { foreach($this->fieldDefaults AS $f=>$n) $editdata[$f]=$n; } } else if($action=="edit") { echo "

".i18n("Edit %1",array($this->recordType))."

"; echo ""; echo ""; if($this->classname) $data = new $this->classname($_GET['edit']); if(method_exists($data, 'tableEditorLoad')) { $editdata = $data->tableEditorLoad(); } else { $editdata = $this->defaultLoad(); } } echo ""; echo ""; foreach($this->editfields AS $f=>$n) { $pos = strpos($n, "|"); $n2 = ""; if($pos != false) { $n2 = i18n(substr($n, $pos + 1)).' '; $n = substr($n, 0, $pos); } echo ""; } echo ""; echo "
".i18n($n)."$n2"; /* If we know the input type, assume the user knows what they are doing, else, * try to query it from the databse */ if(isset($this->fieldInputType[$f])) { $inputtype = $this->fieldInputType[$f]; $inputmaxlen = 0; // FIXME $inputsize = 0; // FIXME } else { list($inputtype, $inputmaxlen, $inputsize) = $this->getFieldType($f); } switch($inputtype) { case "text": if($this->fieldInputOptions[$f]) echo "fieldInputOptions[$f]." id=\"$f\" name=\"$f\" value=\"".htmlspecialchars($editdata[$f])."\"/>"; else echo ""; break; case "textarea": $maxlen = ($inputmaxlen > 0) ? " onkeypress=\"return do_maxlength(this, $inputmaxlen);\" " : ''; if($this->fieldInputOptions[$f]) echo ""; else echo ""; break; case "select": if($this->fieldInputOptions[$f]) echo ""; echo "\n"; foreach($this->fieldOptions[$f] AS $opt) { if(is_array($opt)) { if("{$opt['key']}" == "{$editdata[$f]}") $sel="selected=\"selected\""; else $sel=""; echo "\n"; } else { if("{$opt}" == "{$editdata[$f]}") $sel="selected=\"selected\""; else $sel=""; echo "\n"; } } echo ""; break; case "enum": break; case "select_or_text": $optq=$pdo->prepare("SELECT DISTINCT($f) AS $f FROM `{$this->table}` ORDER BY $f"); $optq->execute(); if($this->fieldInputOptions[$f]) echo ""; echo "\n"; if($this->fieldOptions[$f]) { foreach($this->fieldOptions[$f] AS $opt) { if($opt == $editdata[$f]) $sel="selected=\"selected\""; else $sel=""; echo "\n"; } echo ""; } // print_r($this->fieldOptions[$f]); while($opt=$optq->fetch(PDO::FETCH_OBJ)) { if(is_array($this->fieldOptions[$f]) && in_array($opt->$f,$this->fieldOptions[$f])) continue; if($opt->$f == $editdata[$f]) $sel="selected=\"selected\""; else $sel=""; echo "\n"; } echo ""; echo " or "; //only show the input half-sized because its beside the select box which is already taking up space. $inputsize=round($inputsize/2); //input always starts emptpy as well, because we already have it selected in the list if($this->fieldInputOptions[$f]) echo "fieldInputOptions[$f]." id=\"".$f."_text\" name=\"".$f."_text\" value=\"\" />"; else echo ""; break; case "multicheck": $ks = array_keys($this->fieldOptions[$f]); foreach($ks as $k) { $ch = ''; if(is_array($editdata[$f])) { if(array_key_exists($k, $editdata[$f])) { $ch = ' checked=checked '; } } echo " {$this->fieldOptions[$f][$k]}
"; } echo ""; break; case "date": case "datetime": $a = preg_split('/[- :]/',$editdata[$f]); if($inputtype == 'date') { list($yy,$mm,$dd)=$a; $w = 10; } else { list($yy,$mm,$dd,$hh,$mi,$ss)=$a; $w=15; } //if we put a small width here, then it prevents it from expanding to whatever width it feels like. echo ""; echo ""; if($inputtype == 'date') { echo ""; echo "
"; $this->month_selector($f."_month",$mm); echo ""; $this->day_selector($f."_day",$dd); echo ""; $this->year_selector($f."_year",$yy); echo "
"; echo ""; break; } /* Else, fall through, with hh, mi, ss already set */ case "time": if($inputtype == 'time') { list($hh,$mi,$ss)=explode(":",$editdata[$f]); echo ""; echo ""; } /* Common code for time, and datetime */ echo ""; echo "
"; $this->hour_selector($f."_hour",$hh,false,"12hr"); echo ""; $this->minute_selector($f."_minute",$mi); echo "
"; echo ""; break; case "file": if($editdata[$f]) { if(file_exists($this->uploadPath."/".$editdata[$f])) { //only show a link to the file if the upload path is inside the document root if(strstr(realpath($this->uploadPath),$_SERVER['DOCUMENT_ROOT'])) { echo "uploadPath}/{$editdata[$f]}\">{$editdata[$f]}"; } else { echo $editdata[$f]; } echo " (".filesize($this->uploadPath."/".$editdata[$f])." bytes) delete
"; } else { echo $editdata[$f]." (does not exist)
"; } } echo "fieldInputOptions[$f]." id=\"$f\" name=\"$f\" />"; break; default: echo ""; } echo "
"; echo "
"; if($action=="add") echo "recordType))."\">"; else if($action=="edit") echo "recordType))."\">"; echo ""; echo ""; echo "
"; echo ""; echo "
"; echo "
"; echo "
"; } else if($_GET['TableEditorAction']=="export") { //fixme: how to do an export? we cant send headers because its possible that output has already started! } else { $this->displayTable(); } } function defaultGetList() { $sel = array(); $from = array(); $where = array(); foreach($this->listfields AS $f=>$n) $sel[] = "`$f`"; $from[] = "`{$this->table}`"; if(count($this->additionalListTables)) { foreach($this->additionalListTables as $t) { $from[] = "$t "; } } if(count($this->fieldFilterList)) { foreach($this->fieldFilterList AS $k=>$v) { $where[] = ($v == false) ? $k : "`$k`='$v'"; } } return array($sel, $from, $where); } function displayTable() { global $icon_path; global $icon_extension; global $pdo; $query="SELECT SQL_CALC_FOUND_ROWS {$this->primaryKey}"; if(is_callable(array($this->classname, 'tableEditorGetList'))) { list($sel, $from, $where) = call_user_func(array($this->classname, 'tableEditorGetList'), $this); } else { list($sel, $from, $where) = $this->defaultGetList(); } foreach($sel as $s) $query .= ",$s"; $query .= " FROM "; foreach($from as $f) $query .= "$f "; $query .= " WHERE 1 "; if(is_array($where)) { foreach($where as $w) $query .= "AND $w "; } if($this->sortField()) $query.=" ORDER BY ".$this->sortField().""; if($this->rowsPerPage>0) { //first, we treat page 1 as the first page, but really, "row 0" is the first page, so we need //to be careful. //LIMIT offset,number $offset=($this->activePage-1)*$this->rowsPerPage; //just to make sure nothing funky is goin on. if($offset<0) $offset=0; $query.=" LIMIT $offset,$this->rowsPerPage"; } if($this->allowAdding) { echo "".i18n("Add new %1",array($this->recordType))."

"; } if($this->DEBUG) echo $query; print("query[$query]"); $q = $pdo->prepare($query); $q->execute(); if($q == false) { echo "Sorry, MYSQL query failed:
$query

"; echo "Error: ".$pdo->errorInfo(); exit; } //put in some paganation stuff here. $foundrowsq=$pdo->prepare("SELECT FOUND_ROWS() AS f"); $foundrowsq->execute(); $foundrowsr=$foundrowsq->fetch(PDO::FETCH_OBJ); $foundrows=$foundrowsr->f; if($foundrows>$this->rowsPerPage) { $numpages=ceil($foundrows/$this->rowsPerPage); if($this->activePage>1) { $prevpage=$this->activePage-1; echo "< Prev"; } else echo "< Prev"; echo " "; if($numpages<10) { //if there's less than 10 pages, lets show links for all the pages for($x=1;$x<=$numpages;$x++) { echo " "; if($x==$this->activePage) echo "$x"; else echo "$x"; echo " "; } } else { //if we have more than 10 pages, lets show the previous 5 ..currentpage.. next 5 //if there's less than 10 pages, lets show links for all the pages $start=$this->activePage-4; $end=$this->activePage+4; if($start<1) { $end+=abs(1-$start); $start=1; } if($end>$numpages) { $start-=abs($numpages-$end); $end=$numpages; } if($start>1) { echo " "; echo "1"; echo " "; echo "..."; } for($x=$start;$x<=$end;$x++) { echo " "; if($x==$this->activePage) echo "$x"; else echo "$x"; echo " "; } if($end<$numpages) { echo "..."; echo " "; echo "$numpages"; echo " "; } } echo " "; if($this->activePage<$numpages) { $nextpage=$this->activePage+1; echo "Next >"; } else echo "Next >"; } // else // echo "no need to paganate, foundrows=$foundrows, rowsPerPage=".$this->rowsPerPage; echo " (Total: $foundrows)\n"; if($q->rowCount()) { echo ""; echo ""; foreach($this->listfields AS $f=>$n) { if($this->sortField()==$f) echo ""; else echo ""; } echo ""; echo ""; while($r=$q->fetch(PDO::FETCH_OBJ)) { echo ""; foreach($this->listfields AS $f=>$n) { //figure out what kind of input this should be $typeq=$pdo->prepare("SHOW COLUMNS FROM `{$this->table}` LIKE '$f'"); $typeq->execute(); $typer=$typeq->fetCh(PDO::fETCH_OBJ); if($typer->Type=="time") echo ""; else if($typer->Type=="date") echo ""; else if($typer->Type=="datetime") echo ""; else if(substr($f,0,8)=="filename" && $this->uploadPath) { echo ""; } else if(substr($f,0,7)=="website") { echo ""; } else { if($this->fieldOptions[$f]) { if(is_array($this->fieldOptions[$f][0])) { //if it is an aray, then we have a key=> and val=> so we need //to lookup the key and display the val $TE_Found_Field=false; foreach($this->fieldOptions[$f] AS $i=>$o) { if($o['key']==$r->$f) { echo ""; $TE_Found_Field=true; break; } } if(!$TE_Found_Field) { echo ""; } } else { //if its not an array, then each element is simply a data value anyways, so we can just show the value echo ""; } } else { echo ""; } } } echo ""; echo ""; } echo "
".i18n($n)."".i18n($n)."".i18n("Actions")."
".$this->format_time($r->$f)."".$this->format_date($r->$f)."".$this->format_datetime($r->$f).""; if($this->downloadLink) { $pk=$this->primaryKey; echo "downloadLink}?{$pk}={$r->$pk}\">{$r->$f}"; } else { //only show a link to the file if the upload path is inside the document root if(strstr(realpath($this->uploadPath),$_SERVER['DOCUMENT_ROOT']) && file_exists($this->uploadPath."/".$editdata[$f])) { echo "uploadPath}/{$r->$f}\">{$r->$f}"; } else { echo $r->$f; } } echo ""; echo "$f}\" target=\"_blank\">{$r->$f}"; echo "{$o['val']}{$r->$f}{$r->$f}"; $pk=$this->primaryKey; //custom action buttons go first if(count($this->actionButtons)) { foreach($this->actionButtons AS $button) { echo "$pk."\">"; echo "  "; } } //now the default action buttons that you cant get rid of :) echo "recordType."\" href=\"{$_SERVER['PHP_SELF']}?TableEditorAction=edit&edit=".$r->$pk."\">"; echo "  "; if($this->deleteTitle) { $title = $this->deleteTitle; } else { $title = "Delete this ".$this->recordType; } echo "recordType))."')\" href=\"{$_SERVER['PHP_SELF']}?TableEditorAction=delete&delete=".$r->$pk."\">"; echo "
"; } echo "
"; } function month_selector($name,$selected="") { echo "\n"; } function year_selector($name,$selected="") { $now=date("Y"); if($this->yearSelectRangeMin) $start=$this->yearSelectRangeMin; else $start=$now-2; if($this->yearSelectRangeMax) $end=$this->yearSelectRangeMax; else $end=$now+3; echo "\n"; } function day_selector($name,$selected="") { echo "\n"; } function hour_selector($name,$selected="", $disabled=false) { echo "\n"; } function minute_selector($name,$selected="",$disabled=false) { if($selected=="") $selected=-1; for($x=0;$x<60;$x++) $mins[]=sprintf("%02d",$x); // $mins=array("00","15","30","45"); echo "\n"; } function format_date($d) { if(!$d) return; list($y,$m,$d)=explode("-",$d); $t=mktime(0,0,0,$m,$d,$y); return date($this->dateformat,$t); } function format_time($t) { if(!$t) return; if($this->timeformat=="12hrs") { list($hh,$mm,$ss)=explode(":",$t); //hack to get rid of leading "0" and turn it into a number $hh++; $hh--; if($hh==0) $ret="12:$mm AM"; else if($hh<12) $ret="$hh:$mm AM"; else if($hh==12) $ret="12:$mm PM"; else $ret=($hh-12).":$mm PM"; } else if($this->timeformat=="24hrs") { $ret=substr($t,0,-3); } return $ret; } function format_datetime($d) { list($d,$t)=explode(' ', $d); $ret = $this->format_date($d).' '.$this->format_time($t); return $ret; } } ?>